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
448f680b6e6SAlexander Antonov #define ICX_UBOX_DID				0x3450
4492b3b76b5SKan Liang 
4502b3b76b5SKan Liang /* ICX M3UPI*/
4512b3b76b5SKan Liang #define ICX_M3UPI_PCI_PMON_CTL0			0xd8
4522b3b76b5SKan Liang #define ICX_M3UPI_PCI_PMON_CTR0			0xa8
4532b3b76b5SKan Liang #define ICX_M3UPI_PCI_PMON_BOX_CTL		0xa0
4542b3b76b5SKan Liang 
4552b3b76b5SKan Liang /* ICX IMC */
456496a18f0SKan Liang #define ICX_NUMBER_IMC_CHN			3
4572b3b76b5SKan Liang #define ICX_IMC_MEM_STRIDE			0x4
4582b3b76b5SKan Liang 
459949b1138SKan Liang /* SPR */
460949b1138SKan Liang #define SPR_RAW_EVENT_MASK_EXT			0xffffff
4619a3b675cSAlexander Antonov #define SPR_UBOX_DID				0x3250
462949b1138SKan Liang 
463949b1138SKan Liang /* SPR CHA */
464949b1138SKan Liang #define SPR_CHA_PMON_CTL_TID_EN			(1 << 16)
465949b1138SKan Liang #define SPR_CHA_PMON_EVENT_MASK			(SNBEP_PMON_RAW_EVENT_MASK | \
466949b1138SKan Liang 						 SPR_CHA_PMON_CTL_TID_EN)
467949b1138SKan Liang #define SPR_CHA_PMON_BOX_FILTER_TID		0x3ff
468949b1138SKan Liang 
469949b1138SKan Liang #define SPR_C0_MSR_PMON_BOX_FILTER0		0x200e
470949b1138SKan Liang 
471ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
472ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6");
473ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
474ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(use_occ_ctr, use_occ_ctr, "config:7");
475ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
476b3625980SStephane Eranian DEFINE_UNCORE_FORMAT_ATTR(umask_ext, umask, "config:8-15,32-43,45-55");
477210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(umask_ext2, umask, "config:8-15,32-57");
478210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(umask_ext3, umask, "config:8-15,32-39");
4792b3b76b5SKan Liang DEFINE_UNCORE_FORMAT_ATTR(umask_ext4, umask, "config:8-15,32-55");
480ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16");
481ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
482ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
483949b1138SKan Liang DEFINE_UNCORE_FORMAT_ATTR(tid_en2, tid_en, "config:16");
484ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
485cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(thresh9, thresh, "config:24-35");
486ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
487ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(thresh6, thresh, "config:24-29");
488ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28");
489ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15");
490ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30");
491ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51");
492ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_edge_det, occ_edge_det, "config:31");
493cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(ch_mask, ch_mask, "config:36-43");
494210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(ch_mask2, ch_mask, "config:36-47");
495cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(fc_mask, fc_mask, "config:44-46");
496210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(fc_mask2, fc_mask, "config:48-50");
497ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4");
498ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid2, filter_tid, "config1:0");
499ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid3, filter_tid, "config1:0-5");
500ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid4, filter_tid, "config1:0-8");
501210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_tid5, filter_tid, "config1:0-9");
502ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_cid, filter_cid, "config1:5");
503ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8");
504ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_link2, filter_link, "config1:6-8");
505ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_link3, filter_link, "config1:12");
506ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17");
507ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47");
508ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22");
509ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22");
510ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state3, filter_state, "config1:17-23");
511ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state4, filter_state, "config1:18-20");
512cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_state5, filter_state, "config1:17-26");
513cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_rem, filter_rem, "config1:32");
514cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_loc, filter_loc, "config1:33");
515cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_nm, filter_nm, "config1:36");
516cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_not_nm, filter_not_nm, "config1:37");
517ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_local, filter_local, "config1:33");
518ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_all_op, filter_all_op, "config1:35");
519ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nnm, filter_nnm, "config1:37");
520ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31");
521ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60");
522ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_opc3, filter_opc, "config1:41-60");
523cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_opc_0, filter_opc0, "config1:41-50");
524cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_opc_1, filter_opc1, "config1:51-60");
525ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nc, filter_nc, "config1:62");
526ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_c6, filter_c6, "config1:61");
527ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_isoc, filter_isoc, "config1:63");
528ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7");
529ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15");
530ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23");
531ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31");
532ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51");
533ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35");
534ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31");
535ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17");
536ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12");
537ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8");
538ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4");
539ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31");
540ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63");
541ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51");
542ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35");
543ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31");
544ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17");
545ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12");
546ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8");
547ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4");
548ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31");
549ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63");
550ed367e6cSBorislav Petkov 
snbep_uncore_pci_disable_box(struct intel_uncore_box * box)551ed367e6cSBorislav Petkov static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box)
552ed367e6cSBorislav Petkov {
553ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
554ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
555ed367e6cSBorislav Petkov 	u32 config = 0;
556ed367e6cSBorislav Petkov 
557ed367e6cSBorislav Petkov 	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
558ed367e6cSBorislav Petkov 		config |= SNBEP_PMON_BOX_CTL_FRZ;
559ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, box_ctl, config);
560ed367e6cSBorislav Petkov 	}
561ed367e6cSBorislav Petkov }
562ed367e6cSBorislav Petkov 
snbep_uncore_pci_enable_box(struct intel_uncore_box * box)563ed367e6cSBorislav Petkov static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box)
564ed367e6cSBorislav Petkov {
565ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
566ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
567ed367e6cSBorislav Petkov 	u32 config = 0;
568ed367e6cSBorislav Petkov 
569ed367e6cSBorislav Petkov 	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
570ed367e6cSBorislav Petkov 		config &= ~SNBEP_PMON_BOX_CTL_FRZ;
571ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, box_ctl, config);
572ed367e6cSBorislav Petkov 	}
573ed367e6cSBorislav Petkov }
574ed367e6cSBorislav Petkov 
snbep_uncore_pci_enable_event(struct intel_uncore_box * box,struct perf_event * event)575ed367e6cSBorislav Petkov static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
576ed367e6cSBorislav Petkov {
577ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
578ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
579ed367e6cSBorislav Petkov 
580ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
581ed367e6cSBorislav Petkov }
582ed367e6cSBorislav Petkov 
snbep_uncore_pci_disable_event(struct intel_uncore_box * box,struct perf_event * event)583ed367e6cSBorislav Petkov static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event)
584ed367e6cSBorislav Petkov {
585ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
586ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
587ed367e6cSBorislav Petkov 
588ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, hwc->config_base, hwc->config);
589ed367e6cSBorislav Petkov }
590ed367e6cSBorislav Petkov 
snbep_uncore_pci_read_counter(struct intel_uncore_box * box,struct perf_event * event)591ed367e6cSBorislav Petkov static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event)
592ed367e6cSBorislav Petkov {
593ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
594ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
595ed367e6cSBorislav Petkov 	u64 count = 0;
596ed367e6cSBorislav Petkov 
597ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count);
598ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1);
599ed367e6cSBorislav Petkov 
600ed367e6cSBorislav Petkov 	return count;
601ed367e6cSBorislav Petkov }
602ed367e6cSBorislav Petkov 
snbep_uncore_pci_init_box(struct intel_uncore_box * box)603ed367e6cSBorislav Petkov static void snbep_uncore_pci_init_box(struct intel_uncore_box *box)
604ed367e6cSBorislav Petkov {
605ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
606ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
607ed367e6cSBorislav Petkov 
608ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, box_ctl, SNBEP_PMON_BOX_CTL_INT);
609ed367e6cSBorislav Petkov }
610ed367e6cSBorislav Petkov 
snbep_uncore_msr_disable_box(struct intel_uncore_box * box)611ed367e6cSBorislav Petkov static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box)
612ed367e6cSBorislav Petkov {
613ed367e6cSBorislav Petkov 	u64 config;
614ed367e6cSBorislav Petkov 	unsigned msr;
615ed367e6cSBorislav Petkov 
616ed367e6cSBorislav Petkov 	msr = uncore_msr_box_ctl(box);
617ed367e6cSBorislav Petkov 	if (msr) {
618ed367e6cSBorislav Petkov 		rdmsrl(msr, config);
619ed367e6cSBorislav Petkov 		config |= SNBEP_PMON_BOX_CTL_FRZ;
620ed367e6cSBorislav Petkov 		wrmsrl(msr, config);
621ed367e6cSBorislav Petkov 	}
622ed367e6cSBorislav Petkov }
623ed367e6cSBorislav Petkov 
snbep_uncore_msr_enable_box(struct intel_uncore_box * box)624ed367e6cSBorislav Petkov static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box)
625ed367e6cSBorislav Petkov {
626ed367e6cSBorislav Petkov 	u64 config;
627ed367e6cSBorislav Petkov 	unsigned msr;
628ed367e6cSBorislav Petkov 
629ed367e6cSBorislav Petkov 	msr = uncore_msr_box_ctl(box);
630ed367e6cSBorislav Petkov 	if (msr) {
631ed367e6cSBorislav Petkov 		rdmsrl(msr, config);
632ed367e6cSBorislav Petkov 		config &= ~SNBEP_PMON_BOX_CTL_FRZ;
633ed367e6cSBorislav Petkov 		wrmsrl(msr, config);
634ed367e6cSBorislav Petkov 	}
635ed367e6cSBorislav Petkov }
636ed367e6cSBorislav Petkov 
snbep_uncore_msr_enable_event(struct intel_uncore_box * box,struct perf_event * event)637ed367e6cSBorislav Petkov static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
638ed367e6cSBorislav Petkov {
639ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
640ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
641ed367e6cSBorislav Petkov 
642ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE)
643ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg, uncore_shared_reg_config(box, 0));
644ed367e6cSBorislav Petkov 
645ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
646ed367e6cSBorislav Petkov }
647ed367e6cSBorislav Petkov 
snbep_uncore_msr_disable_event(struct intel_uncore_box * box,struct perf_event * event)648ed367e6cSBorislav Petkov static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box,
649ed367e6cSBorislav Petkov 					struct perf_event *event)
650ed367e6cSBorislav Petkov {
651ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
652ed367e6cSBorislav Petkov 
653ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config);
654ed367e6cSBorislav Petkov }
655ed367e6cSBorislav Petkov 
snbep_uncore_msr_init_box(struct intel_uncore_box * box)656ed367e6cSBorislav Petkov static void snbep_uncore_msr_init_box(struct intel_uncore_box *box)
657ed367e6cSBorislav Petkov {
658ed367e6cSBorislav Petkov 	unsigned msr = uncore_msr_box_ctl(box);
659ed367e6cSBorislav Petkov 
660ed367e6cSBorislav Petkov 	if (msr)
661ed367e6cSBorislav Petkov 		wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT);
662ed367e6cSBorislav Petkov }
663ed367e6cSBorislav Petkov 
664ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_formats_attr[] = {
665ed367e6cSBorislav Petkov 	&format_attr_event.attr,
666ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
667ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
668ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
669ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
670ed367e6cSBorislav Petkov 	NULL,
671ed367e6cSBorislav Petkov };
672ed367e6cSBorislav Petkov 
673ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_ubox_formats_attr[] = {
674ed367e6cSBorislav Petkov 	&format_attr_event.attr,
675ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
676ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
677ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
678ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
679ed367e6cSBorislav Petkov 	NULL,
680ed367e6cSBorislav Petkov };
681ed367e6cSBorislav Petkov 
682ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_cbox_formats_attr[] = {
683ed367e6cSBorislav Petkov 	&format_attr_event.attr,
684ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
685ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
686ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
687ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
688ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
689ed367e6cSBorislav Petkov 	&format_attr_filter_tid.attr,
690ed367e6cSBorislav Petkov 	&format_attr_filter_nid.attr,
691ed367e6cSBorislav Petkov 	&format_attr_filter_state.attr,
692ed367e6cSBorislav Petkov 	&format_attr_filter_opc.attr,
693ed367e6cSBorislav Petkov 	NULL,
694ed367e6cSBorislav Petkov };
695ed367e6cSBorislav Petkov 
696ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_pcu_formats_attr[] = {
697cb225252SKan Liang 	&format_attr_event.attr,
698ed367e6cSBorislav Petkov 	&format_attr_occ_sel.attr,
699ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
700ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
701ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
702ed367e6cSBorislav Petkov 	&format_attr_occ_invert.attr,
703ed367e6cSBorislav Petkov 	&format_attr_occ_edge.attr,
704ed367e6cSBorislav Petkov 	&format_attr_filter_band0.attr,
705ed367e6cSBorislav Petkov 	&format_attr_filter_band1.attr,
706ed367e6cSBorislav Petkov 	&format_attr_filter_band2.attr,
707ed367e6cSBorislav Petkov 	&format_attr_filter_band3.attr,
708ed367e6cSBorislav Petkov 	NULL,
709ed367e6cSBorislav Petkov };
710ed367e6cSBorislav Petkov 
711ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_qpi_formats_attr[] = {
712ed367e6cSBorislav Petkov 	&format_attr_event_ext.attr,
713ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
714ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
715ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
716ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
717ed367e6cSBorislav Petkov 	&format_attr_match_rds.attr,
718ed367e6cSBorislav Petkov 	&format_attr_match_rnid30.attr,
719ed367e6cSBorislav Petkov 	&format_attr_match_rnid4.attr,
720ed367e6cSBorislav Petkov 	&format_attr_match_dnid.attr,
721ed367e6cSBorislav Petkov 	&format_attr_match_mc.attr,
722ed367e6cSBorislav Petkov 	&format_attr_match_opc.attr,
723ed367e6cSBorislav Petkov 	&format_attr_match_vnw.attr,
724ed367e6cSBorislav Petkov 	&format_attr_match0.attr,
725ed367e6cSBorislav Petkov 	&format_attr_match1.attr,
726ed367e6cSBorislav Petkov 	&format_attr_mask_rds.attr,
727ed367e6cSBorislav Petkov 	&format_attr_mask_rnid30.attr,
728ed367e6cSBorislav Petkov 	&format_attr_mask_rnid4.attr,
729ed367e6cSBorislav Petkov 	&format_attr_mask_dnid.attr,
730ed367e6cSBorislav Petkov 	&format_attr_mask_mc.attr,
731ed367e6cSBorislav Petkov 	&format_attr_mask_opc.attr,
732ed367e6cSBorislav Petkov 	&format_attr_mask_vnw.attr,
733ed367e6cSBorislav Petkov 	&format_attr_mask0.attr,
734ed367e6cSBorislav Petkov 	&format_attr_mask1.attr,
735ed367e6cSBorislav Petkov 	NULL,
736ed367e6cSBorislav Petkov };
737ed367e6cSBorislav Petkov 
738ed367e6cSBorislav Petkov static struct uncore_event_desc snbep_uncore_imc_events[] = {
739ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0xff,umask=0x00"),
740ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x03"),
741ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
742ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
743ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
744ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
745ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
746ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ },
747ed367e6cSBorislav Petkov };
748ed367e6cSBorislav Petkov 
749ed367e6cSBorislav Petkov static struct uncore_event_desc snbep_uncore_qpi_events[] = {
750ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(clockticks,       "event=0x14"),
751ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"),
752ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(drs_data,         "event=0x102,umask=0x08"),
753ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(ncb_data,         "event=0x103,umask=0x04"),
754ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ },
755ed367e6cSBorislav Petkov };
756ed367e6cSBorislav Petkov 
75745bd07adSArvind Yadav static const struct attribute_group snbep_uncore_format_group = {
758ed367e6cSBorislav Petkov 	.name = "format",
759ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_formats_attr,
760ed367e6cSBorislav Petkov };
761ed367e6cSBorislav Petkov 
76245bd07adSArvind Yadav static const struct attribute_group snbep_uncore_ubox_format_group = {
763ed367e6cSBorislav Petkov 	.name = "format",
764ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_ubox_formats_attr,
765ed367e6cSBorislav Petkov };
766ed367e6cSBorislav Petkov 
76745bd07adSArvind Yadav static const struct attribute_group snbep_uncore_cbox_format_group = {
768ed367e6cSBorislav Petkov 	.name = "format",
769ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_cbox_formats_attr,
770ed367e6cSBorislav Petkov };
771ed367e6cSBorislav Petkov 
77245bd07adSArvind Yadav static const struct attribute_group snbep_uncore_pcu_format_group = {
773ed367e6cSBorislav Petkov 	.name = "format",
774ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_pcu_formats_attr,
775ed367e6cSBorislav Petkov };
776ed367e6cSBorislav Petkov 
77745bd07adSArvind Yadav static const struct attribute_group snbep_uncore_qpi_format_group = {
778ed367e6cSBorislav Petkov 	.name = "format",
779ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_qpi_formats_attr,
780ed367e6cSBorislav Petkov };
781ed367e6cSBorislav Petkov 
782ed367e6cSBorislav Petkov #define __SNBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
783ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_msr_disable_box,		\
784ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_msr_enable_box,		\
785ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_msr_disable_event,	\
786ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_msr_enable_event,	\
787ed367e6cSBorislav Petkov 	.read_counter	= uncore_msr_read_counter
788ed367e6cSBorislav Petkov 
789ed367e6cSBorislav Petkov #define SNBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
790ed367e6cSBorislav Petkov 	__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),			\
791ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_msr_init_box		\
792ed367e6cSBorislav Petkov 
793ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_msr_ops = {
794ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
795ed367e6cSBorislav Petkov };
796ed367e6cSBorislav Petkov 
797ed367e6cSBorislav Petkov #define SNBEP_UNCORE_PCI_OPS_COMMON_INIT()			\
798ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_pci_init_box,		\
799ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,		\
800ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,		\
801ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,	\
802ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter
803ed367e6cSBorislav Petkov 
804ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_pci_ops = {
805ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
806ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_pci_enable_event,	\
807ed367e6cSBorislav Petkov };
808ed367e6cSBorislav Petkov 
809ed367e6cSBorislav Petkov static struct event_constraint snbep_uncore_cbox_constraints[] = {
810ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
811ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
812ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x04, 0x3),
813ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x05, 0x3),
814ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x07, 0x3),
815ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
816ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
817ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
818ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x3),
819ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1b, 0xc),
820ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
821ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
822ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
8231134c2b5SPeter Zijlstra 	UNCORE_EVENT_CONSTRAINT(0x1f, 0xe),
824ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
825ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
826ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
827ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
828ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
829ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
830ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
831ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
832ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
833ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
834ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
835ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
836ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
837ed367e6cSBorislav Petkov };
838ed367e6cSBorislav Petkov 
839ed367e6cSBorislav Petkov static struct event_constraint snbep_uncore_r2pcie_constraints[] = {
840ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
841ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
842ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x1),
843ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
844ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
845ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
846ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
847ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
848ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
849ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
850ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
851ed367e6cSBorislav Petkov };
852ed367e6cSBorislav Petkov 
853ed367e6cSBorislav Petkov static struct event_constraint snbep_uncore_r3qpi_constraints[] = {
854ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
855ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
856ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
857ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
858ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
859ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
860ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
861ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
862ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
863ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
864ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
865ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
866ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
867ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2a, 0x3),
868ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
869ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
870ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
871ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
872ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
873ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x30, 0x3),
874ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
875ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
876ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
877ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
878ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
879ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
880ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
881ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
882ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
883ed367e6cSBorislav Petkov };
884ed367e6cSBorislav Petkov 
885ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_ubox = {
886ed367e6cSBorislav Petkov 	.name		= "ubox",
887ed367e6cSBorislav Petkov 	.num_counters   = 2,
888ed367e6cSBorislav Petkov 	.num_boxes	= 1,
889ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
890ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
891ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_U_MSR_PMON_CTR0,
892ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_U_MSR_PMON_CTL0,
893ed367e6cSBorislav Petkov 	.event_mask	= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
894ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
895ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
896ed367e6cSBorislav Petkov 	.ops		= &snbep_uncore_msr_ops,
897ed367e6cSBorislav Petkov 	.format_group	= &snbep_uncore_ubox_format_group,
898ed367e6cSBorislav Petkov };
899ed367e6cSBorislav Petkov 
900ed367e6cSBorislav Petkov static struct extra_reg snbep_uncore_cbox_extra_regs[] = {
901ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
902ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
903ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
904ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6),
905ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
906ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6),
907ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
908ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6),
909ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6),
910ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8),
911ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8),
912ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xa),
913ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xa),
914ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x2),
915ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x2),
916ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x2),
917ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x2),
918ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x8),
919ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x8),
920ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xa),
921ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xa),
922ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x2),
923ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x2),
924ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x2),
925ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x2),
926ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
927ed367e6cSBorislav Petkov };
928ed367e6cSBorislav Petkov 
snbep_cbox_put_constraint(struct intel_uncore_box * box,struct perf_event * event)929ed367e6cSBorislav Petkov static void snbep_cbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
930ed367e6cSBorislav Petkov {
931ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
932ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
933ed367e6cSBorislav Petkov 	int i;
934ed367e6cSBorislav Petkov 
935ed367e6cSBorislav Petkov 	if (uncore_box_is_fake(box))
936ed367e6cSBorislav Petkov 		return;
937ed367e6cSBorislav Petkov 
938ed367e6cSBorislav Petkov 	for (i = 0; i < 5; i++) {
939ed367e6cSBorislav Petkov 		if (reg1->alloc & (0x1 << i))
940ed367e6cSBorislav Petkov 			atomic_sub(1 << (i * 6), &er->ref);
941ed367e6cSBorislav Petkov 	}
942ed367e6cSBorislav Petkov 	reg1->alloc = 0;
943ed367e6cSBorislav Petkov }
944ed367e6cSBorislav Petkov 
945ed367e6cSBorislav Petkov static struct event_constraint *
__snbep_cbox_get_constraint(struct intel_uncore_box * box,struct perf_event * event,u64 (* cbox_filter_mask)(int fields))946ed367e6cSBorislav Petkov __snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event,
947ed367e6cSBorislav Petkov 			    u64 (*cbox_filter_mask)(int fields))
948ed367e6cSBorislav Petkov {
949ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
950ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
951ed367e6cSBorislav Petkov 	int i, alloc = 0;
952ed367e6cSBorislav Petkov 	unsigned long flags;
953ed367e6cSBorislav Petkov 	u64 mask;
954ed367e6cSBorislav Petkov 
955ed367e6cSBorislav Petkov 	if (reg1->idx == EXTRA_REG_NONE)
956ed367e6cSBorislav Petkov 		return NULL;
957ed367e6cSBorislav Petkov 
958ed367e6cSBorislav Petkov 	raw_spin_lock_irqsave(&er->lock, flags);
959ed367e6cSBorislav Petkov 	for (i = 0; i < 5; i++) {
960ed367e6cSBorislav Petkov 		if (!(reg1->idx & (0x1 << i)))
961ed367e6cSBorislav Petkov 			continue;
962ed367e6cSBorislav Petkov 		if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
963ed367e6cSBorislav Petkov 			continue;
964ed367e6cSBorislav Petkov 
965ed367e6cSBorislav Petkov 		mask = cbox_filter_mask(0x1 << i);
966ed367e6cSBorislav Petkov 		if (!__BITS_VALUE(atomic_read(&er->ref), i, 6) ||
967ed367e6cSBorislav Petkov 		    !((reg1->config ^ er->config) & mask)) {
968ed367e6cSBorislav Petkov 			atomic_add(1 << (i * 6), &er->ref);
969ed367e6cSBorislav Petkov 			er->config &= ~mask;
970ed367e6cSBorislav Petkov 			er->config |= reg1->config & mask;
971ed367e6cSBorislav Petkov 			alloc |= (0x1 << i);
972ed367e6cSBorislav Petkov 		} else {
973ed367e6cSBorislav Petkov 			break;
974ed367e6cSBorislav Petkov 		}
975ed367e6cSBorislav Petkov 	}
976ed367e6cSBorislav Petkov 	raw_spin_unlock_irqrestore(&er->lock, flags);
977ed367e6cSBorislav Petkov 	if (i < 5)
978ed367e6cSBorislav Petkov 		goto fail;
979ed367e6cSBorislav Petkov 
980ed367e6cSBorislav Petkov 	if (!uncore_box_is_fake(box))
981ed367e6cSBorislav Petkov 		reg1->alloc |= alloc;
982ed367e6cSBorislav Petkov 
983ed367e6cSBorislav Petkov 	return NULL;
984ed367e6cSBorislav Petkov fail:
985ed367e6cSBorislav Petkov 	for (; i >= 0; i--) {
986ed367e6cSBorislav Petkov 		if (alloc & (0x1 << i))
987ed367e6cSBorislav Petkov 			atomic_sub(1 << (i * 6), &er->ref);
988ed367e6cSBorislav Petkov 	}
989ed367e6cSBorislav Petkov 	return &uncore_constraint_empty;
990ed367e6cSBorislav Petkov }
991ed367e6cSBorislav Petkov 
snbep_cbox_filter_mask(int fields)992ed367e6cSBorislav Petkov static u64 snbep_cbox_filter_mask(int fields)
993ed367e6cSBorislav Petkov {
994ed367e6cSBorislav Petkov 	u64 mask = 0;
995ed367e6cSBorislav Petkov 
996ed367e6cSBorislav Petkov 	if (fields & 0x1)
997ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_TID;
998ed367e6cSBorislav Petkov 	if (fields & 0x2)
999ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_NID;
1000ed367e6cSBorislav Petkov 	if (fields & 0x4)
1001ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
1002ed367e6cSBorislav Petkov 	if (fields & 0x8)
1003ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
1004ed367e6cSBorislav Petkov 
1005ed367e6cSBorislav Petkov 	return mask;
1006ed367e6cSBorislav Petkov }
1007ed367e6cSBorislav Petkov 
1008ed367e6cSBorislav Petkov static struct event_constraint *
snbep_cbox_get_constraint(struct intel_uncore_box * box,struct perf_event * event)1009ed367e6cSBorislav Petkov snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
1010ed367e6cSBorislav Petkov {
1011ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, snbep_cbox_filter_mask);
1012ed367e6cSBorislav Petkov }
1013ed367e6cSBorislav Petkov 
snbep_cbox_hw_config(struct intel_uncore_box * box,struct perf_event * event)1014ed367e6cSBorislav Petkov static int snbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1015ed367e6cSBorislav Petkov {
1016ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1017ed367e6cSBorislav Petkov 	struct extra_reg *er;
1018ed367e6cSBorislav Petkov 	int idx = 0;
1019ed367e6cSBorislav Petkov 
1020ed367e6cSBorislav Petkov 	for (er = snbep_uncore_cbox_extra_regs; er->msr; er++) {
1021ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
1022ed367e6cSBorislav Petkov 			continue;
1023ed367e6cSBorislav Petkov 		idx |= er->idx;
1024ed367e6cSBorislav Petkov 	}
1025ed367e6cSBorislav Petkov 
1026ed367e6cSBorislav Petkov 	if (idx) {
1027ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
1028ed367e6cSBorislav Petkov 			SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
1029ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & snbep_cbox_filter_mask(idx);
1030ed367e6cSBorislav Petkov 		reg1->idx = idx;
1031ed367e6cSBorislav Petkov 	}
1032ed367e6cSBorislav Petkov 	return 0;
1033ed367e6cSBorislav Petkov }
1034ed367e6cSBorislav Petkov 
1035ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_cbox_ops = {
1036ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1037ed367e6cSBorislav Petkov 	.hw_config		= snbep_cbox_hw_config,
1038ed367e6cSBorislav Petkov 	.get_constraint		= snbep_cbox_get_constraint,
1039ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
1040ed367e6cSBorislav Petkov };
1041ed367e6cSBorislav Petkov 
1042ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_cbox = {
1043ed367e6cSBorislav Petkov 	.name			= "cbox",
1044ed367e6cSBorislav Petkov 	.num_counters		= 4,
1045ed367e6cSBorislav Petkov 	.num_boxes		= 8,
1046ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
1047ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_C0_MSR_PMON_CTL0,
1048ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_C0_MSR_PMON_CTR0,
1049ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
1050ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_C0_MSR_PMON_BOX_CTL,
1051ed367e6cSBorislav Petkov 	.msr_offset		= SNBEP_CBO_MSR_OFFSET,
1052ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1053ed367e6cSBorislav Petkov 	.constraints		= snbep_uncore_cbox_constraints,
1054ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_cbox_ops,
1055ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_cbox_format_group,
1056ed367e6cSBorislav Petkov };
1057ed367e6cSBorislav Petkov 
snbep_pcu_alter_er(struct perf_event * event,int new_idx,bool modify)1058ed367e6cSBorislav Petkov static u64 snbep_pcu_alter_er(struct perf_event *event, int new_idx, bool modify)
1059ed367e6cSBorislav Petkov {
1060ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1061ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1062ed367e6cSBorislav Petkov 	u64 config = reg1->config;
1063ed367e6cSBorislav Petkov 
1064ed367e6cSBorislav Petkov 	if (new_idx > reg1->idx)
1065ed367e6cSBorislav Petkov 		config <<= 8 * (new_idx - reg1->idx);
1066ed367e6cSBorislav Petkov 	else
1067ed367e6cSBorislav Petkov 		config >>= 8 * (reg1->idx - new_idx);
1068ed367e6cSBorislav Petkov 
1069ed367e6cSBorislav Petkov 	if (modify) {
1070ed367e6cSBorislav Petkov 		hwc->config += new_idx - reg1->idx;
1071ed367e6cSBorislav Petkov 		reg1->config = config;
1072ed367e6cSBorislav Petkov 		reg1->idx = new_idx;
1073ed367e6cSBorislav Petkov 	}
1074ed367e6cSBorislav Petkov 	return config;
1075ed367e6cSBorislav Petkov }
1076ed367e6cSBorislav Petkov 
1077ed367e6cSBorislav Petkov static struct event_constraint *
snbep_pcu_get_constraint(struct intel_uncore_box * box,struct perf_event * event)1078ed367e6cSBorislav Petkov snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
1079ed367e6cSBorislav Petkov {
1080ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1081ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
1082ed367e6cSBorislav Petkov 	unsigned long flags;
1083ed367e6cSBorislav Petkov 	int idx = reg1->idx;
1084ed367e6cSBorislav Petkov 	u64 mask, config1 = reg1->config;
1085ed367e6cSBorislav Petkov 	bool ok = false;
1086ed367e6cSBorislav Petkov 
1087ed367e6cSBorislav Petkov 	if (reg1->idx == EXTRA_REG_NONE ||
1088ed367e6cSBorislav Petkov 	    (!uncore_box_is_fake(box) && reg1->alloc))
1089ed367e6cSBorislav Petkov 		return NULL;
1090ed367e6cSBorislav Petkov again:
1091ed367e6cSBorislav Petkov 	mask = 0xffULL << (idx * 8);
1092ed367e6cSBorislav Petkov 	raw_spin_lock_irqsave(&er->lock, flags);
1093ed367e6cSBorislav Petkov 	if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) ||
1094ed367e6cSBorislav Petkov 	    !((config1 ^ er->config) & mask)) {
1095ed367e6cSBorislav Petkov 		atomic_add(1 << (idx * 8), &er->ref);
1096ed367e6cSBorislav Petkov 		er->config &= ~mask;
1097ed367e6cSBorislav Petkov 		er->config |= config1 & mask;
1098ed367e6cSBorislav Petkov 		ok = true;
1099ed367e6cSBorislav Petkov 	}
1100ed367e6cSBorislav Petkov 	raw_spin_unlock_irqrestore(&er->lock, flags);
1101ed367e6cSBorislav Petkov 
1102ed367e6cSBorislav Petkov 	if (!ok) {
1103ed367e6cSBorislav Petkov 		idx = (idx + 1) % 4;
1104ed367e6cSBorislav Petkov 		if (idx != reg1->idx) {
1105ed367e6cSBorislav Petkov 			config1 = snbep_pcu_alter_er(event, idx, false);
1106ed367e6cSBorislav Petkov 			goto again;
1107ed367e6cSBorislav Petkov 		}
1108ed367e6cSBorislav Petkov 		return &uncore_constraint_empty;
1109ed367e6cSBorislav Petkov 	}
1110ed367e6cSBorislav Petkov 
1111ed367e6cSBorislav Petkov 	if (!uncore_box_is_fake(box)) {
1112ed367e6cSBorislav Petkov 		if (idx != reg1->idx)
1113ed367e6cSBorislav Petkov 			snbep_pcu_alter_er(event, idx, true);
1114ed367e6cSBorislav Petkov 		reg1->alloc = 1;
1115ed367e6cSBorislav Petkov 	}
1116ed367e6cSBorislav Petkov 	return NULL;
1117ed367e6cSBorislav Petkov }
1118ed367e6cSBorislav Petkov 
snbep_pcu_put_constraint(struct intel_uncore_box * box,struct perf_event * event)1119ed367e6cSBorislav Petkov static void snbep_pcu_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
1120ed367e6cSBorislav Petkov {
1121ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1122ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
1123ed367e6cSBorislav Petkov 
1124ed367e6cSBorislav Petkov 	if (uncore_box_is_fake(box) || !reg1->alloc)
1125ed367e6cSBorislav Petkov 		return;
1126ed367e6cSBorislav Petkov 
1127ed367e6cSBorislav Petkov 	atomic_sub(1 << (reg1->idx * 8), &er->ref);
1128ed367e6cSBorislav Petkov 	reg1->alloc = 0;
1129ed367e6cSBorislav Petkov }
1130ed367e6cSBorislav Petkov 
snbep_pcu_hw_config(struct intel_uncore_box * box,struct perf_event * event)1131ed367e6cSBorislav Petkov static int snbep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1132ed367e6cSBorislav Petkov {
1133ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1134ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1135ed367e6cSBorislav Petkov 	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
1136ed367e6cSBorislav Petkov 
1137ed367e6cSBorislav Petkov 	if (ev_sel >= 0xb && ev_sel <= 0xe) {
1138ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER;
1139ed367e6cSBorislav Petkov 		reg1->idx = ev_sel - 0xb;
1140ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & (0xff << (reg1->idx * 8));
1141ed367e6cSBorislav Petkov 	}
1142ed367e6cSBorislav Petkov 	return 0;
1143ed367e6cSBorislav Petkov }
1144ed367e6cSBorislav Petkov 
1145ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_pcu_ops = {
1146ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1147ed367e6cSBorislav Petkov 	.hw_config		= snbep_pcu_hw_config,
1148ed367e6cSBorislav Petkov 	.get_constraint		= snbep_pcu_get_constraint,
1149ed367e6cSBorislav Petkov 	.put_constraint		= snbep_pcu_put_constraint,
1150ed367e6cSBorislav Petkov };
1151ed367e6cSBorislav Petkov 
1152ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_pcu = {
1153ed367e6cSBorislav Petkov 	.name			= "pcu",
1154ed367e6cSBorislav Petkov 	.num_counters		= 4,
1155ed367e6cSBorislav Petkov 	.num_boxes		= 1,
1156ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1157ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCU_MSR_PMON_CTR0,
1158ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCU_MSR_PMON_CTL0,
1159ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
1160ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCU_MSR_PMON_BOX_CTL,
1161ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1162ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_pcu_ops,
1163ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_pcu_format_group,
1164ed367e6cSBorislav Petkov };
1165ed367e6cSBorislav Petkov 
1166ed367e6cSBorislav Petkov static struct intel_uncore_type *snbep_msr_uncores[] = {
1167ed367e6cSBorislav Petkov 	&snbep_uncore_ubox,
1168ed367e6cSBorislav Petkov 	&snbep_uncore_cbox,
1169ed367e6cSBorislav Petkov 	&snbep_uncore_pcu,
1170ed367e6cSBorislav Petkov 	NULL,
1171ed367e6cSBorislav Petkov };
1172ed367e6cSBorislav Petkov 
snbep_uncore_cpu_init(void)1173ed367e6cSBorislav Petkov void snbep_uncore_cpu_init(void)
1174ed367e6cSBorislav Petkov {
1175ed367e6cSBorislav Petkov 	if (snbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
1176ed367e6cSBorislav Petkov 		snbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
1177ed367e6cSBorislav Petkov 	uncore_msr_uncores = snbep_msr_uncores;
1178ed367e6cSBorislav Petkov }
1179ed367e6cSBorislav Petkov 
1180ed367e6cSBorislav Petkov enum {
1181ed367e6cSBorislav Petkov 	SNBEP_PCI_QPI_PORT0_FILTER,
1182ed367e6cSBorislav Petkov 	SNBEP_PCI_QPI_PORT1_FILTER,
1183156c8b58SKan Liang 	BDX_PCI_QPI_PORT2_FILTER,
1184ed367e6cSBorislav Petkov };
1185ed367e6cSBorislav Petkov 
snbep_qpi_hw_config(struct intel_uncore_box * box,struct perf_event * event)1186ed367e6cSBorislav Petkov static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1187ed367e6cSBorislav Petkov {
1188ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1189ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1190ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
1191ed367e6cSBorislav Petkov 
1192ed367e6cSBorislav Petkov 	if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) {
1193ed367e6cSBorislav Petkov 		reg1->idx = 0;
1194ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0;
1195ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1;
1196ed367e6cSBorislav Petkov 		reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0;
1197ed367e6cSBorislav Petkov 		reg2->config = event->attr.config2;
1198ed367e6cSBorislav Petkov 	}
1199ed367e6cSBorislav Petkov 	return 0;
1200ed367e6cSBorislav Petkov }
1201ed367e6cSBorislav Petkov 
snbep_qpi_enable_event(struct intel_uncore_box * box,struct perf_event * event)1202ed367e6cSBorislav Petkov static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event)
1203ed367e6cSBorislav Petkov {
1204ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1205ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1206ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1207ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
1208ed367e6cSBorislav Petkov 
1209ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE) {
1210ed367e6cSBorislav Petkov 		int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER;
1211b0529b9cSKan Liang 		int die = box->dieid;
1212b0529b9cSKan Liang 		struct pci_dev *filter_pdev = uncore_extra_pci_dev[die].dev[idx];
1213cf6d445fSThomas Gleixner 
1214ed367e6cSBorislav Petkov 		if (filter_pdev) {
1215ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg1->reg,
1216ed367e6cSBorislav Petkov 						(u32)reg1->config);
1217ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg1->reg + 4,
1218ed367e6cSBorislav Petkov 						(u32)(reg1->config >> 32));
1219ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg2->reg,
1220ed367e6cSBorislav Petkov 						(u32)reg2->config);
1221ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg2->reg + 4,
1222ed367e6cSBorislav Petkov 						(u32)(reg2->config >> 32));
1223ed367e6cSBorislav Petkov 		}
1224ed367e6cSBorislav Petkov 	}
1225ed367e6cSBorislav Petkov 
1226ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
1227ed367e6cSBorislav Petkov }
1228ed367e6cSBorislav Petkov 
1229ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_qpi_ops = {
1230ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
1231ed367e6cSBorislav Petkov 	.enable_event		= snbep_qpi_enable_event,
1232ed367e6cSBorislav Petkov 	.hw_config		= snbep_qpi_hw_config,
1233ed367e6cSBorislav Petkov 	.get_constraint		= uncore_get_constraint,
1234ed367e6cSBorislav Petkov 	.put_constraint		= uncore_put_constraint,
1235ed367e6cSBorislav Petkov };
1236ed367e6cSBorislav Petkov 
1237ed367e6cSBorislav Petkov #define SNBEP_UNCORE_PCI_COMMON_INIT()				\
1238ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,			\
1239ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_PCI_PMON_CTL0,			\
1240ed367e6cSBorislav Petkov 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,		\
1241ed367e6cSBorislav Petkov 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,		\
1242ed367e6cSBorislav Petkov 	.ops		= &snbep_uncore_pci_ops,		\
1243ed367e6cSBorislav Petkov 	.format_group	= &snbep_uncore_format_group
1244ed367e6cSBorislav Petkov 
1245ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_ha = {
1246ed367e6cSBorislav Petkov 	.name		= "ha",
1247ed367e6cSBorislav Petkov 	.num_counters   = 4,
1248ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1249ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1250ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1251ed367e6cSBorislav Petkov };
1252ed367e6cSBorislav Petkov 
1253ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_imc = {
1254ed367e6cSBorislav Petkov 	.name		= "imc",
1255ed367e6cSBorislav Petkov 	.num_counters   = 4,
1256ed367e6cSBorislav Petkov 	.num_boxes	= 4,
1257ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1258ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
1259ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
1260ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
1261ed367e6cSBorislav Petkov 	.event_descs	= snbep_uncore_imc_events,
1262ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1263ed367e6cSBorislav Petkov };
1264ed367e6cSBorislav Petkov 
1265ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_qpi = {
1266ed367e6cSBorislav Petkov 	.name			= "qpi",
1267ed367e6cSBorislav Petkov 	.num_counters		= 4,
1268ed367e6cSBorislav Petkov 	.num_boxes		= 2,
1269ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1270ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
1271ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
1272ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
1273ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
1274ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1275ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_qpi_ops,
1276ed367e6cSBorislav Petkov 	.event_descs		= snbep_uncore_qpi_events,
1277ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_qpi_format_group,
1278ed367e6cSBorislav Petkov };
1279ed367e6cSBorislav Petkov 
1280ed367e6cSBorislav Petkov 
1281ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_r2pcie = {
1282ed367e6cSBorislav Petkov 	.name		= "r2pcie",
1283ed367e6cSBorislav Petkov 	.num_counters   = 4,
1284ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1285ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1286ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r2pcie_constraints,
1287ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1288ed367e6cSBorislav Petkov };
1289ed367e6cSBorislav Petkov 
1290ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_r3qpi = {
1291ed367e6cSBorislav Petkov 	.name		= "r3qpi",
1292ed367e6cSBorislav Petkov 	.num_counters   = 3,
1293ed367e6cSBorislav Petkov 	.num_boxes	= 2,
1294ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1295ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r3qpi_constraints,
1296ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1297ed367e6cSBorislav Petkov };
1298ed367e6cSBorislav Petkov 
1299ed367e6cSBorislav Petkov enum {
1300ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_HA,
1301ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_IMC,
1302ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_QPI,
1303ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_R2PCIE,
1304ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_R3QPI,
1305ed367e6cSBorislav Petkov };
1306ed367e6cSBorislav Petkov 
1307ed367e6cSBorislav Petkov static struct intel_uncore_type *snbep_pci_uncores[] = {
1308ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_HA]		= &snbep_uncore_ha,
1309ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_IMC]		= &snbep_uncore_imc,
1310ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_QPI]		= &snbep_uncore_qpi,
1311ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_R2PCIE]	= &snbep_uncore_r2pcie,
1312ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_R3QPI]	= &snbep_uncore_r3qpi,
1313ed367e6cSBorislav Petkov 	NULL,
1314ed367e6cSBorislav Petkov };
1315ed367e6cSBorislav Petkov 
1316ed367e6cSBorislav Petkov static const struct pci_device_id snbep_uncore_pci_ids[] = {
1317ed367e6cSBorislav Petkov 	{ /* Home Agent */
1318ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA),
1319ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0),
1320ed367e6cSBorislav Petkov 	},
1321ed367e6cSBorislav Petkov 	{ /* MC Channel 0 */
1322ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0),
1323ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0),
1324ed367e6cSBorislav Petkov 	},
1325ed367e6cSBorislav Petkov 	{ /* MC Channel 1 */
1326ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1),
1327ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1),
1328ed367e6cSBorislav Petkov 	},
1329ed367e6cSBorislav Petkov 	{ /* MC Channel 2 */
1330ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2),
1331ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2),
1332ed367e6cSBorislav Petkov 	},
1333ed367e6cSBorislav Petkov 	{ /* MC Channel 3 */
1334ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3),
1335ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3),
1336ed367e6cSBorislav Petkov 	},
1337ed367e6cSBorislav Petkov 	{ /* QPI Port 0 */
1338ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0),
1339ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0),
1340ed367e6cSBorislav Petkov 	},
1341ed367e6cSBorislav Petkov 	{ /* QPI Port 1 */
1342ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1),
1343ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1),
1344ed367e6cSBorislav Petkov 	},
1345ed367e6cSBorislav Petkov 	{ /* R2PCIe */
1346ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE),
1347ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0),
1348ed367e6cSBorislav Petkov 	},
1349ed367e6cSBorislav Petkov 	{ /* R3QPI Link 0 */
1350ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0),
1351ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0),
1352ed367e6cSBorislav Petkov 	},
1353ed367e6cSBorislav Petkov 	{ /* R3QPI Link 1 */
1354ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1),
1355ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1),
1356ed367e6cSBorislav Petkov 	},
1357ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
1358ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86),
1359ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
1360ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT0_FILTER),
1361ed367e6cSBorislav Petkov 	},
1362ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
1363ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96),
1364ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
1365ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT1_FILTER),
1366ed367e6cSBorislav Petkov 	},
1367ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
1368ed367e6cSBorislav Petkov };
1369ed367e6cSBorislav Petkov 
1370ed367e6cSBorislav Petkov static struct pci_driver snbep_uncore_pci_driver = {
1371ed367e6cSBorislav Petkov 	.name		= "snbep_uncore",
1372ed367e6cSBorislav Petkov 	.id_table	= snbep_uncore_pci_ids,
1373ed367e6cSBorislav Petkov };
1374ed367e6cSBorislav Petkov 
13759e63a789SKan Liang #define NODE_ID_MASK	0x7
13769e63a789SKan Liang 
1377c4aebdb3SAlexander Antonov /* Each three bits from 0 to 23 of GIDNIDMAP register correspond Node ID. */
1378c4aebdb3SAlexander Antonov #define GIDNIDMAP(config, id)	(((config) >> (3 * (id))) & 0x7)
1379c4aebdb3SAlexander Antonov 
upi_nodeid_groupid(struct pci_dev * ubox_dev,int nodeid_loc,int idmap_loc,int * nodeid,int * groupid)1380c4aebdb3SAlexander Antonov static int upi_nodeid_groupid(struct pci_dev *ubox_dev, int nodeid_loc, int idmap_loc,
1381c4aebdb3SAlexander Antonov 			      int *nodeid, int *groupid)
1382c4aebdb3SAlexander Antonov {
1383c4aebdb3SAlexander Antonov 	int ret;
1384c4aebdb3SAlexander Antonov 
1385c4aebdb3SAlexander Antonov 	/* get the Node ID of the local register */
1386c4aebdb3SAlexander Antonov 	ret = pci_read_config_dword(ubox_dev, nodeid_loc, nodeid);
1387c4aebdb3SAlexander Antonov 	if (ret)
1388c4aebdb3SAlexander Antonov 		goto err;
1389c4aebdb3SAlexander Antonov 
1390c4aebdb3SAlexander Antonov 	*nodeid = *nodeid & NODE_ID_MASK;
1391c4aebdb3SAlexander Antonov 	/* get the Node ID mapping */
1392c4aebdb3SAlexander Antonov 	ret = pci_read_config_dword(ubox_dev, idmap_loc, groupid);
1393c4aebdb3SAlexander Antonov 	if (ret)
1394c4aebdb3SAlexander Antonov 		goto err;
1395c4aebdb3SAlexander Antonov err:
1396c4aebdb3SAlexander Antonov 	return ret;
1397c4aebdb3SAlexander Antonov }
1398c4aebdb3SAlexander Antonov 
1399ed367e6cSBorislav Petkov /*
1400ed367e6cSBorislav Petkov  * build pci bus to socket mapping
1401ed367e6cSBorislav Petkov  */
snbep_pci2phy_map_init(int devid,int nodeid_loc,int idmap_loc,bool reverse)140268ce4a0dSKan Liang static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool reverse)
1403ed367e6cSBorislav Petkov {
1404ed367e6cSBorislav Petkov 	struct pci_dev *ubox_dev = NULL;
1405ba9506beSSteve Wahl 	int i, bus, nodeid, segment, die_id;
1406ed367e6cSBorislav Petkov 	struct pci2phy_map *map;
1407ed367e6cSBorislav Petkov 	int err = 0;
1408ed367e6cSBorislav Petkov 	u32 config = 0;
1409ed367e6cSBorislav Petkov 
1410ed367e6cSBorislav Petkov 	while (1) {
1411ed367e6cSBorislav Petkov 		/* find the UBOX device */
1412ed367e6cSBorislav Petkov 		ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, ubox_dev);
1413ed367e6cSBorislav Petkov 		if (!ubox_dev)
1414ed367e6cSBorislav Petkov 			break;
1415ed367e6cSBorislav Petkov 		bus = ubox_dev->bus->number;
14169a7832ceSSteve Wahl 		/*
14179a7832ceSSteve Wahl 		 * The nodeid and idmap registers only contain enough
14189a7832ceSSteve Wahl 		 * information to handle 8 nodes.  On systems with more
14199a7832ceSSteve Wahl 		 * than 8 nodes, we need to rely on NUMA information,
14209a7832ceSSteve Wahl 		 * filled in from BIOS supplied information, to determine
14219a7832ceSSteve Wahl 		 * the topology.
14229a7832ceSSteve Wahl 		 */
14239a7832ceSSteve Wahl 		if (nr_node_ids <= 8) {
1424c4aebdb3SAlexander Antonov 			err = upi_nodeid_groupid(ubox_dev, nodeid_loc, idmap_loc,
1425c4aebdb3SAlexander Antonov 						 &nodeid, &config);
1426ed367e6cSBorislav Petkov 			if (err)
1427ed367e6cSBorislav Petkov 				break;
1428ed367e6cSBorislav Petkov 
1429ed367e6cSBorislav Petkov 			segment = pci_domain_nr(ubox_dev->bus);
1430ed367e6cSBorislav Petkov 			raw_spin_lock(&pci2phy_map_lock);
1431ed367e6cSBorislav Petkov 			map = __find_pci2phy_map(segment);
1432ed367e6cSBorislav Petkov 			if (!map) {
1433ed367e6cSBorislav Petkov 				raw_spin_unlock(&pci2phy_map_lock);
1434ed367e6cSBorislav Petkov 				err = -ENOMEM;
1435ed367e6cSBorislav Petkov 				break;
1436ed367e6cSBorislav Petkov 			}
1437ed367e6cSBorislav Petkov 
1438ed367e6cSBorislav Petkov 			/*
1439ed367e6cSBorislav Petkov 			 * every three bits in the Node ID mapping register maps
1440ed367e6cSBorislav Petkov 			 * to a particular node.
1441ed367e6cSBorislav Petkov 			 */
1442ed367e6cSBorislav Petkov 			for (i = 0; i < 8; i++) {
1443c4aebdb3SAlexander Antonov 				if (nodeid == GIDNIDMAP(config, i)) {
1444ba9506beSSteve Wahl 					if (topology_max_die_per_package() > 1)
1445ba9506beSSteve Wahl 						die_id = i;
1446ba9506beSSteve Wahl 					else
1447ba9506beSSteve Wahl 						die_id = topology_phys_to_logical_pkg(i);
14484a0e3ff3SKan Liang 					if (die_id < 0)
14494a0e3ff3SKan Liang 						die_id = -ENODEV;
1450ba9506beSSteve Wahl 					map->pbus_to_dieid[bus] = die_id;
1451ed367e6cSBorislav Petkov 					break;
1452ed367e6cSBorislav Petkov 				}
1453ed367e6cSBorislav Petkov 			}
1454ed367e6cSBorislav Petkov 			raw_spin_unlock(&pci2phy_map_lock);
14559a7832ceSSteve Wahl 		} else {
14569a7832ceSSteve Wahl 			segment = pci_domain_nr(ubox_dev->bus);
14579a7832ceSSteve Wahl 			raw_spin_lock(&pci2phy_map_lock);
14589a7832ceSSteve Wahl 			map = __find_pci2phy_map(segment);
14599a7832ceSSteve Wahl 			if (!map) {
14609a7832ceSSteve Wahl 				raw_spin_unlock(&pci2phy_map_lock);
14619a7832ceSSteve Wahl 				err = -ENOMEM;
14629a7832ceSSteve Wahl 				break;
14639a7832ceSSteve Wahl 			}
14649a7832ceSSteve Wahl 
1465dbf061b2SKan Liang 			map->pbus_to_dieid[bus] = die_id = uncore_device_to_die(ubox_dev);
14669a7832ceSSteve Wahl 
14679a7832ceSSteve Wahl 			raw_spin_unlock(&pci2phy_map_lock);
14689a7832ceSSteve Wahl 
14699a7832ceSSteve Wahl 			if (WARN_ON_ONCE(die_id == -1)) {
14709a7832ceSSteve Wahl 				err = -EINVAL;
14719a7832ceSSteve Wahl 				break;
14729a7832ceSSteve Wahl 			}
14739a7832ceSSteve Wahl 		}
1474ed367e6cSBorislav Petkov 	}
1475ed367e6cSBorislav Petkov 
1476ed367e6cSBorislav Petkov 	if (!err) {
1477ed367e6cSBorislav Petkov 		/*
1478ed367e6cSBorislav Petkov 		 * For PCI bus with no UBOX device, find the next bus
1479ed367e6cSBorislav Petkov 		 * that has UBOX device and use its mapping.
1480ed367e6cSBorislav Petkov 		 */
1481ed367e6cSBorislav Petkov 		raw_spin_lock(&pci2phy_map_lock);
1482ed367e6cSBorislav Petkov 		list_for_each_entry(map, &pci2phy_map_head, list) {
1483ed367e6cSBorislav Petkov 			i = -1;
148468ce4a0dSKan Liang 			if (reverse) {
1485ed367e6cSBorislav Petkov 				for (bus = 255; bus >= 0; bus--) {
14864a0e3ff3SKan Liang 					if (map->pbus_to_dieid[bus] != -1)
1487ba9506beSSteve Wahl 						i = map->pbus_to_dieid[bus];
1488ed367e6cSBorislav Petkov 					else
1489ba9506beSSteve Wahl 						map->pbus_to_dieid[bus] = i;
1490ed367e6cSBorislav Petkov 				}
149168ce4a0dSKan Liang 			} else {
149268ce4a0dSKan Liang 				for (bus = 0; bus <= 255; bus++) {
14934a0e3ff3SKan Liang 					if (map->pbus_to_dieid[bus] != -1)
1494ba9506beSSteve Wahl 						i = map->pbus_to_dieid[bus];
149568ce4a0dSKan Liang 					else
1496ba9506beSSteve Wahl 						map->pbus_to_dieid[bus] = i;
149768ce4a0dSKan Liang 				}
149868ce4a0dSKan Liang 			}
1499ed367e6cSBorislav Petkov 		}
1500ed367e6cSBorislav Petkov 		raw_spin_unlock(&pci2phy_map_lock);
1501ed367e6cSBorislav Petkov 	}
1502ed367e6cSBorislav Petkov 
1503ed367e6cSBorislav Petkov 	pci_dev_put(ubox_dev);
1504ed367e6cSBorislav Petkov 
15052c65477fSIlpo Järvinen 	return pcibios_err_to_errno(err);
1506ed367e6cSBorislav Petkov }
1507ed367e6cSBorislav Petkov 
snbep_uncore_pci_init(void)1508ed367e6cSBorislav Petkov int snbep_uncore_pci_init(void)
1509ed367e6cSBorislav Petkov {
151068ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x3ce0, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
1511ed367e6cSBorislav Petkov 	if (ret)
1512ed367e6cSBorislav Petkov 		return ret;
1513ed367e6cSBorislav Petkov 	uncore_pci_uncores = snbep_pci_uncores;
1514ed367e6cSBorislav Petkov 	uncore_pci_driver = &snbep_uncore_pci_driver;
1515ed367e6cSBorislav Petkov 	return 0;
1516ed367e6cSBorislav Petkov }
1517ed367e6cSBorislav Petkov /* end of Sandy Bridge-EP uncore support */
1518ed367e6cSBorislav Petkov 
1519ed367e6cSBorislav Petkov /* IvyTown uncore support */
ivbep_uncore_msr_init_box(struct intel_uncore_box * box)1520ed367e6cSBorislav Petkov static void ivbep_uncore_msr_init_box(struct intel_uncore_box *box)
1521ed367e6cSBorislav Petkov {
1522ed367e6cSBorislav Petkov 	unsigned msr = uncore_msr_box_ctl(box);
1523ed367e6cSBorislav Petkov 	if (msr)
1524ed367e6cSBorislav Petkov 		wrmsrl(msr, IVBEP_PMON_BOX_CTL_INT);
1525ed367e6cSBorislav Petkov }
1526ed367e6cSBorislav Petkov 
ivbep_uncore_pci_init_box(struct intel_uncore_box * box)1527ed367e6cSBorislav Petkov static void ivbep_uncore_pci_init_box(struct intel_uncore_box *box)
1528ed367e6cSBorislav Petkov {
1529ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1530ed367e6cSBorislav Petkov 
1531ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
1532ed367e6cSBorislav Petkov }
1533ed367e6cSBorislav Petkov 
1534ed367e6cSBorislav Petkov #define IVBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
1535ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_msr_init_box,		\
1536ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_msr_disable_box,		\
1537ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_msr_enable_box,		\
1538ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_msr_disable_event,	\
1539ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_msr_enable_event,	\
1540ed367e6cSBorislav Petkov 	.read_counter	= uncore_msr_read_counter
1541ed367e6cSBorislav Petkov 
1542ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_msr_ops = {
1543ed367e6cSBorislav Petkov 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1544ed367e6cSBorislav Petkov };
1545ed367e6cSBorislav Petkov 
1546ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_pci_ops = {
1547ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_pci_init_box,
1548ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
1549ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
1550ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,
1551ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_pci_enable_event,
1552ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter,
1553ed367e6cSBorislav Petkov };
1554ed367e6cSBorislav Petkov 
1555ed367e6cSBorislav Petkov #define IVBEP_UNCORE_PCI_COMMON_INIT()				\
1556ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,			\
1557ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_PCI_PMON_CTL0,			\
1558ed367e6cSBorislav Petkov 	.event_mask	= IVBEP_PMON_RAW_EVENT_MASK,		\
1559ed367e6cSBorislav Petkov 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,		\
1560ed367e6cSBorislav Petkov 	.ops		= &ivbep_uncore_pci_ops,			\
1561ed367e6cSBorislav Petkov 	.format_group	= &ivbep_uncore_format_group
1562ed367e6cSBorislav Petkov 
1563ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_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_thresh8.attr,
1569ed367e6cSBorislav Petkov 	NULL,
1570ed367e6cSBorislav Petkov };
1571ed367e6cSBorislav Petkov 
1572ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_ubox_formats_attr[] = {
1573ed367e6cSBorislav Petkov 	&format_attr_event.attr,
1574ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
1575ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1576ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
1577ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
1578ed367e6cSBorislav Petkov 	NULL,
1579ed367e6cSBorislav Petkov };
1580ed367e6cSBorislav Petkov 
1581ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_cbox_formats_attr[] = {
1582ed367e6cSBorislav Petkov 	&format_attr_event.attr,
1583ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
1584ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1585ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
1586ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
1587ed367e6cSBorislav Petkov 	&format_attr_filter_tid.attr,
1588ed367e6cSBorislav Petkov 	&format_attr_filter_link.attr,
1589ed367e6cSBorislav Petkov 	&format_attr_filter_state2.attr,
1590ed367e6cSBorislav Petkov 	&format_attr_filter_nid2.attr,
1591ed367e6cSBorislav Petkov 	&format_attr_filter_opc2.attr,
1592ed367e6cSBorislav Petkov 	&format_attr_filter_nc.attr,
1593ed367e6cSBorislav Petkov 	&format_attr_filter_c6.attr,
1594ed367e6cSBorislav Petkov 	&format_attr_filter_isoc.attr,
1595ed367e6cSBorislav Petkov 	NULL,
1596ed367e6cSBorislav Petkov };
1597ed367e6cSBorislav Petkov 
1598ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_pcu_formats_attr[] = {
1599cb225252SKan Liang 	&format_attr_event.attr,
1600ed367e6cSBorislav Petkov 	&format_attr_occ_sel.attr,
1601ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1602ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
1603ed367e6cSBorislav Petkov 	&format_attr_occ_invert.attr,
1604ed367e6cSBorislav Petkov 	&format_attr_occ_edge.attr,
1605ed367e6cSBorislav Petkov 	&format_attr_filter_band0.attr,
1606ed367e6cSBorislav Petkov 	&format_attr_filter_band1.attr,
1607ed367e6cSBorislav Petkov 	&format_attr_filter_band2.attr,
1608ed367e6cSBorislav Petkov 	&format_attr_filter_band3.attr,
1609ed367e6cSBorislav Petkov 	NULL,
1610ed367e6cSBorislav Petkov };
1611ed367e6cSBorislav Petkov 
1612ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_qpi_formats_attr[] = {
1613ed367e6cSBorislav Petkov 	&format_attr_event_ext.attr,
1614ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
1615ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1616ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
1617ed367e6cSBorislav Petkov 	&format_attr_match_rds.attr,
1618ed367e6cSBorislav Petkov 	&format_attr_match_rnid30.attr,
1619ed367e6cSBorislav Petkov 	&format_attr_match_rnid4.attr,
1620ed367e6cSBorislav Petkov 	&format_attr_match_dnid.attr,
1621ed367e6cSBorislav Petkov 	&format_attr_match_mc.attr,
1622ed367e6cSBorislav Petkov 	&format_attr_match_opc.attr,
1623ed367e6cSBorislav Petkov 	&format_attr_match_vnw.attr,
1624ed367e6cSBorislav Petkov 	&format_attr_match0.attr,
1625ed367e6cSBorislav Petkov 	&format_attr_match1.attr,
1626ed367e6cSBorislav Petkov 	&format_attr_mask_rds.attr,
1627ed367e6cSBorislav Petkov 	&format_attr_mask_rnid30.attr,
1628ed367e6cSBorislav Petkov 	&format_attr_mask_rnid4.attr,
1629ed367e6cSBorislav Petkov 	&format_attr_mask_dnid.attr,
1630ed367e6cSBorislav Petkov 	&format_attr_mask_mc.attr,
1631ed367e6cSBorislav Petkov 	&format_attr_mask_opc.attr,
1632ed367e6cSBorislav Petkov 	&format_attr_mask_vnw.attr,
1633ed367e6cSBorislav Petkov 	&format_attr_mask0.attr,
1634ed367e6cSBorislav Petkov 	&format_attr_mask1.attr,
1635ed367e6cSBorislav Petkov 	NULL,
1636ed367e6cSBorislav Petkov };
1637ed367e6cSBorislav Petkov 
163845bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_format_group = {
1639ed367e6cSBorislav Petkov 	.name = "format",
1640ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_formats_attr,
1641ed367e6cSBorislav Petkov };
1642ed367e6cSBorislav Petkov 
164345bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_ubox_format_group = {
1644ed367e6cSBorislav Petkov 	.name = "format",
1645ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_ubox_formats_attr,
1646ed367e6cSBorislav Petkov };
1647ed367e6cSBorislav Petkov 
164845bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_cbox_format_group = {
1649ed367e6cSBorislav Petkov 	.name = "format",
1650ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_cbox_formats_attr,
1651ed367e6cSBorislav Petkov };
1652ed367e6cSBorislav Petkov 
165345bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_pcu_format_group = {
1654ed367e6cSBorislav Petkov 	.name = "format",
1655ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_pcu_formats_attr,
1656ed367e6cSBorislav Petkov };
1657ed367e6cSBorislav Petkov 
165845bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_qpi_format_group = {
1659ed367e6cSBorislav Petkov 	.name = "format",
1660ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_qpi_formats_attr,
1661ed367e6cSBorislav Petkov };
1662ed367e6cSBorislav Petkov 
1663ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_ubox = {
1664ed367e6cSBorislav Petkov 	.name		= "ubox",
1665ed367e6cSBorislav Petkov 	.num_counters   = 2,
1666ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1667ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1668ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
1669ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_U_MSR_PMON_CTR0,
1670ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_U_MSR_PMON_CTL0,
1671ed367e6cSBorislav Petkov 	.event_mask	= IVBEP_U_MSR_PMON_RAW_EVENT_MASK,
1672ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
1673ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
1674ed367e6cSBorislav Petkov 	.ops		= &ivbep_uncore_msr_ops,
1675ed367e6cSBorislav Petkov 	.format_group	= &ivbep_uncore_ubox_format_group,
1676ed367e6cSBorislav Petkov };
1677ed367e6cSBorislav Petkov 
1678ed367e6cSBorislav Petkov static struct extra_reg ivbep_uncore_cbox_extra_regs[] = {
1679ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
1680ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
1681ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2),
1682ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
1683ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc),
1684ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc),
1685ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
1686ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc),
1687ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
1688ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc),
1689ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
1690ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc),
1691ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10),
1692ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
1693ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
1694ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
1695ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
1696ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
1697ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
1698ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
1699ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
1700ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
1701ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
1702ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
1703ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
1704ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
1705ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
1706ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
1707ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
1708ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
1709ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
1710ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
1711ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
1712ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
1713ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
1714ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
1715ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
1716ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
1717ed367e6cSBorislav Petkov };
1718ed367e6cSBorislav Petkov 
ivbep_cbox_filter_mask(int fields)1719ed367e6cSBorislav Petkov static u64 ivbep_cbox_filter_mask(int fields)
1720ed367e6cSBorislav Petkov {
1721ed367e6cSBorislav Petkov 	u64 mask = 0;
1722ed367e6cSBorislav Petkov 
1723ed367e6cSBorislav Petkov 	if (fields & 0x1)
1724ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_TID;
1725ed367e6cSBorislav Petkov 	if (fields & 0x2)
1726ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK;
1727ed367e6cSBorislav Petkov 	if (fields & 0x4)
1728ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
1729ed367e6cSBorislav Petkov 	if (fields & 0x8)
1730ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NID;
1731ed367e6cSBorislav Petkov 	if (fields & 0x10) {
1732ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
1733ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NC;
1734ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_C6;
1735ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
1736ed367e6cSBorislav Petkov 	}
1737ed367e6cSBorislav Petkov 
1738ed367e6cSBorislav Petkov 	return mask;
1739ed367e6cSBorislav Petkov }
1740ed367e6cSBorislav Petkov 
1741ed367e6cSBorislav Petkov static struct event_constraint *
ivbep_cbox_get_constraint(struct intel_uncore_box * box,struct perf_event * event)1742ed367e6cSBorislav Petkov ivbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
1743ed367e6cSBorislav Petkov {
1744ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, ivbep_cbox_filter_mask);
1745ed367e6cSBorislav Petkov }
1746ed367e6cSBorislav Petkov 
ivbep_cbox_hw_config(struct intel_uncore_box * box,struct perf_event * event)1747ed367e6cSBorislav Petkov static int ivbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1748ed367e6cSBorislav Petkov {
1749ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1750ed367e6cSBorislav Petkov 	struct extra_reg *er;
1751ed367e6cSBorislav Petkov 	int idx = 0;
1752ed367e6cSBorislav Petkov 
1753ed367e6cSBorislav Petkov 	for (er = ivbep_uncore_cbox_extra_regs; er->msr; er++) {
1754ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
1755ed367e6cSBorislav Petkov 			continue;
1756ed367e6cSBorislav Petkov 		idx |= er->idx;
1757ed367e6cSBorislav Petkov 	}
1758ed367e6cSBorislav Petkov 
1759ed367e6cSBorislav Petkov 	if (idx) {
1760ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
1761ed367e6cSBorislav Petkov 			SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
1762ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & ivbep_cbox_filter_mask(idx);
1763ed367e6cSBorislav Petkov 		reg1->idx = idx;
1764ed367e6cSBorislav Petkov 	}
1765ed367e6cSBorislav Petkov 	return 0;
1766ed367e6cSBorislav Petkov }
1767ed367e6cSBorislav Petkov 
ivbep_cbox_enable_event(struct intel_uncore_box * box,struct perf_event * event)1768ed367e6cSBorislav Petkov static void ivbep_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event)
1769ed367e6cSBorislav Petkov {
1770ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1771ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1772ed367e6cSBorislav Petkov 
1773ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE) {
1774ed367e6cSBorislav Petkov 		u64 filter = uncore_shared_reg_config(box, 0);
1775ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg, filter & 0xffffffff);
1776ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg + 6, filter >> 32);
1777ed367e6cSBorislav Petkov 	}
1778ed367e6cSBorislav Petkov 
1779ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
1780ed367e6cSBorislav Petkov }
1781ed367e6cSBorislav Petkov 
1782ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_cbox_ops = {
1783ed367e6cSBorislav Petkov 	.init_box		= ivbep_uncore_msr_init_box,
1784ed367e6cSBorislav Petkov 	.disable_box		= snbep_uncore_msr_disable_box,
1785ed367e6cSBorislav Petkov 	.enable_box		= snbep_uncore_msr_enable_box,
1786ed367e6cSBorislav Petkov 	.disable_event		= snbep_uncore_msr_disable_event,
1787ed367e6cSBorislav Petkov 	.enable_event		= ivbep_cbox_enable_event,
1788ed367e6cSBorislav Petkov 	.read_counter		= uncore_msr_read_counter,
1789ed367e6cSBorislav Petkov 	.hw_config		= ivbep_cbox_hw_config,
1790ed367e6cSBorislav Petkov 	.get_constraint		= ivbep_cbox_get_constraint,
1791ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
1792ed367e6cSBorislav Petkov };
1793ed367e6cSBorislav Petkov 
1794ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_cbox = {
1795ed367e6cSBorislav Petkov 	.name			= "cbox",
1796ed367e6cSBorislav Petkov 	.num_counters		= 4,
1797ed367e6cSBorislav Petkov 	.num_boxes		= 15,
1798ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
1799ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_C0_MSR_PMON_CTL0,
1800ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_C0_MSR_PMON_CTR0,
1801ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
1802ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_C0_MSR_PMON_BOX_CTL,
1803ed367e6cSBorislav Petkov 	.msr_offset		= SNBEP_CBO_MSR_OFFSET,
1804ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1805ed367e6cSBorislav Petkov 	.constraints		= snbep_uncore_cbox_constraints,
1806ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_cbox_ops,
1807ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_cbox_format_group,
1808ed367e6cSBorislav Petkov };
1809ed367e6cSBorislav Petkov 
1810ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_pcu_ops = {
1811ed367e6cSBorislav Petkov 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1812ed367e6cSBorislav Petkov 	.hw_config		= snbep_pcu_hw_config,
1813ed367e6cSBorislav Petkov 	.get_constraint		= snbep_pcu_get_constraint,
1814ed367e6cSBorislav Petkov 	.put_constraint		= snbep_pcu_put_constraint,
1815ed367e6cSBorislav Petkov };
1816ed367e6cSBorislav Petkov 
1817ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_pcu = {
1818ed367e6cSBorislav Petkov 	.name			= "pcu",
1819ed367e6cSBorislav Petkov 	.num_counters		= 4,
1820ed367e6cSBorislav Petkov 	.num_boxes		= 1,
1821ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1822ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCU_MSR_PMON_CTR0,
1823ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCU_MSR_PMON_CTL0,
1824ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
1825ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCU_MSR_PMON_BOX_CTL,
1826ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1827ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_pcu_ops,
1828ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_pcu_format_group,
1829ed367e6cSBorislav Petkov };
1830ed367e6cSBorislav Petkov 
1831ed367e6cSBorislav Petkov static struct intel_uncore_type *ivbep_msr_uncores[] = {
1832ed367e6cSBorislav Petkov 	&ivbep_uncore_ubox,
1833ed367e6cSBorislav Petkov 	&ivbep_uncore_cbox,
1834ed367e6cSBorislav Petkov 	&ivbep_uncore_pcu,
1835ed367e6cSBorislav Petkov 	NULL,
1836ed367e6cSBorislav Petkov };
1837ed367e6cSBorislav Petkov 
ivbep_uncore_cpu_init(void)1838ed367e6cSBorislav Petkov void ivbep_uncore_cpu_init(void)
1839ed367e6cSBorislav Petkov {
1840ed367e6cSBorislav Petkov 	if (ivbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
1841ed367e6cSBorislav Petkov 		ivbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
1842ed367e6cSBorislav Petkov 	uncore_msr_uncores = ivbep_msr_uncores;
1843ed367e6cSBorislav Petkov }
1844ed367e6cSBorislav Petkov 
1845ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_ha = {
1846ed367e6cSBorislav Petkov 	.name		= "ha",
1847ed367e6cSBorislav Petkov 	.num_counters   = 4,
1848ed367e6cSBorislav Petkov 	.num_boxes	= 2,
1849ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1850ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1851ed367e6cSBorislav Petkov };
1852ed367e6cSBorislav Petkov 
1853ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_imc = {
1854ed367e6cSBorislav Petkov 	.name		= "imc",
1855ed367e6cSBorislav Petkov 	.num_counters   = 4,
1856ed367e6cSBorislav Petkov 	.num_boxes	= 8,
1857ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1858ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
1859ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
1860ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
1861ed367e6cSBorislav Petkov 	.event_descs	= snbep_uncore_imc_events,
1862ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1863ed367e6cSBorislav Petkov };
1864ed367e6cSBorislav Petkov 
1865ed367e6cSBorislav Petkov /* registers in IRP boxes are not properly aligned */
1866ed367e6cSBorislav Petkov static unsigned ivbep_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4};
1867ed367e6cSBorislav Petkov static unsigned ivbep_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0};
1868ed367e6cSBorislav Petkov 
ivbep_uncore_irp_enable_event(struct intel_uncore_box * box,struct perf_event * event)1869ed367e6cSBorislav Petkov static void ivbep_uncore_irp_enable_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],
1875ed367e6cSBorislav Petkov 			       hwc->config | SNBEP_PMON_CTL_EN);
1876ed367e6cSBorislav Petkov }
1877ed367e6cSBorislav Petkov 
ivbep_uncore_irp_disable_event(struct intel_uncore_box * box,struct perf_event * event)1878ed367e6cSBorislav Petkov static void ivbep_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event)
1879ed367e6cSBorislav Petkov {
1880ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1881ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1882ed367e6cSBorislav Petkov 
1883ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx], hwc->config);
1884ed367e6cSBorislav Petkov }
1885ed367e6cSBorislav Petkov 
ivbep_uncore_irp_read_counter(struct intel_uncore_box * box,struct perf_event * event)1886ed367e6cSBorislav Petkov static u64 ivbep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
1887ed367e6cSBorislav Petkov {
1888ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1889ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1890ed367e6cSBorislav Petkov 	u64 count = 0;
1891ed367e6cSBorislav Petkov 
1892ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
1893ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
1894ed367e6cSBorislav Petkov 
1895ed367e6cSBorislav Petkov 	return count;
1896ed367e6cSBorislav Petkov }
1897ed367e6cSBorislav Petkov 
1898ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_irp_ops = {
1899ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_pci_init_box,
1900ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
1901ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
1902ed367e6cSBorislav Petkov 	.disable_event	= ivbep_uncore_irp_disable_event,
1903ed367e6cSBorislav Petkov 	.enable_event	= ivbep_uncore_irp_enable_event,
1904ed367e6cSBorislav Petkov 	.read_counter	= ivbep_uncore_irp_read_counter,
1905ed367e6cSBorislav Petkov };
1906ed367e6cSBorislav Petkov 
1907ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_irp = {
1908ed367e6cSBorislav Petkov 	.name			= "irp",
1909ed367e6cSBorislav Petkov 	.num_counters		= 4,
1910ed367e6cSBorislav Petkov 	.num_boxes		= 1,
1911ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1912ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_PMON_RAW_EVENT_MASK,
1913ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
1914ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_irp_ops,
1915ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_format_group,
1916ed367e6cSBorislav Petkov };
1917ed367e6cSBorislav Petkov 
1918ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_qpi_ops = {
1919ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_pci_init_box,
1920ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
1921ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
1922ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,
1923ed367e6cSBorislav Petkov 	.enable_event	= snbep_qpi_enable_event,
1924ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter,
1925ed367e6cSBorislav Petkov 	.hw_config	= snbep_qpi_hw_config,
1926ed367e6cSBorislav Petkov 	.get_constraint	= uncore_get_constraint,
1927ed367e6cSBorislav Petkov 	.put_constraint	= uncore_put_constraint,
1928ed367e6cSBorislav Petkov };
1929ed367e6cSBorislav Petkov 
1930ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_qpi = {
1931ed367e6cSBorislav Petkov 	.name			= "qpi",
1932ed367e6cSBorislav Petkov 	.num_counters		= 4,
1933ed367e6cSBorislav Petkov 	.num_boxes		= 3,
1934ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1935ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
1936ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
1937ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
1938ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
1939ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1940ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_qpi_ops,
1941ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_qpi_format_group,
1942ed367e6cSBorislav Petkov };
1943ed367e6cSBorislav Petkov 
1944ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_r2pcie = {
1945ed367e6cSBorislav Petkov 	.name		= "r2pcie",
1946ed367e6cSBorislav Petkov 	.num_counters   = 4,
1947ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1948ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1949ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r2pcie_constraints,
1950ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1951ed367e6cSBorislav Petkov };
1952ed367e6cSBorislav Petkov 
1953ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_r3qpi = {
1954ed367e6cSBorislav Petkov 	.name		= "r3qpi",
1955ed367e6cSBorislav Petkov 	.num_counters   = 3,
1956ed367e6cSBorislav Petkov 	.num_boxes	= 2,
1957ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1958ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r3qpi_constraints,
1959ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1960ed367e6cSBorislav Petkov };
1961ed367e6cSBorislav Petkov 
1962ed367e6cSBorislav Petkov enum {
1963ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_HA,
1964ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_IMC,
1965ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_IRP,
1966ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_QPI,
1967ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_R2PCIE,
1968ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_R3QPI,
1969ed367e6cSBorislav Petkov };
1970ed367e6cSBorislav Petkov 
1971ed367e6cSBorislav Petkov static struct intel_uncore_type *ivbep_pci_uncores[] = {
1972ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_HA]	= &ivbep_uncore_ha,
1973ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_IMC]	= &ivbep_uncore_imc,
1974ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_IRP]	= &ivbep_uncore_irp,
1975ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_QPI]	= &ivbep_uncore_qpi,
1976ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_R2PCIE]	= &ivbep_uncore_r2pcie,
1977ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_R3QPI]	= &ivbep_uncore_r3qpi,
1978ed367e6cSBorislav Petkov 	NULL,
1979ed367e6cSBorislav Petkov };
1980ed367e6cSBorislav Petkov 
1981ed367e6cSBorislav Petkov static const struct pci_device_id ivbep_uncore_pci_ids[] = {
1982ed367e6cSBorislav Petkov 	{ /* Home Agent 0 */
1983ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30),
1984ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 0),
1985ed367e6cSBorislav Petkov 	},
1986ed367e6cSBorislav Petkov 	{ /* Home Agent 1 */
1987ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38),
1988ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 1),
1989ed367e6cSBorislav Petkov 	},
1990ed367e6cSBorislav Petkov 	{ /* MC0 Channel 0 */
1991ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4),
1992ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 0),
1993ed367e6cSBorislav Petkov 	},
1994ed367e6cSBorislav Petkov 	{ /* MC0 Channel 1 */
1995ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5),
1996ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 1),
1997ed367e6cSBorislav Petkov 	},
1998ed367e6cSBorislav Petkov 	{ /* MC0 Channel 3 */
1999ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0),
2000ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 2),
2001ed367e6cSBorislav Petkov 	},
2002ed367e6cSBorislav Petkov 	{ /* MC0 Channel 4 */
2003ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1),
2004ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 3),
2005ed367e6cSBorislav Petkov 	},
2006ed367e6cSBorislav Petkov 	{ /* MC1 Channel 0 */
2007ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4),
2008ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 4),
2009ed367e6cSBorislav Petkov 	},
2010ed367e6cSBorislav Petkov 	{ /* MC1 Channel 1 */
2011ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5),
2012ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 5),
2013ed367e6cSBorislav Petkov 	},
2014ed367e6cSBorislav Petkov 	{ /* MC1 Channel 3 */
2015ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0),
2016ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 6),
2017ed367e6cSBorislav Petkov 	},
2018ed367e6cSBorislav Petkov 	{ /* MC1 Channel 4 */
2019ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1),
2020ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 7),
2021ed367e6cSBorislav Petkov 	},
2022ed367e6cSBorislav Petkov 	{ /* IRP */
2023ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39),
2024ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IRP, 0),
2025ed367e6cSBorislav Petkov 	},
2026ed367e6cSBorislav Petkov 	{ /* QPI0 Port 0 */
2027ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32),
2028ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 0),
2029ed367e6cSBorislav Petkov 	},
2030ed367e6cSBorislav Petkov 	{ /* QPI0 Port 1 */
2031ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33),
2032ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 1),
2033ed367e6cSBorislav Petkov 	},
2034ed367e6cSBorislav Petkov 	{ /* QPI1 Port 2 */
2035ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a),
2036ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 2),
2037ed367e6cSBorislav Petkov 	},
2038ed367e6cSBorislav Petkov 	{ /* R2PCIe */
2039ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34),
2040ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R2PCIE, 0),
2041ed367e6cSBorislav Petkov 	},
2042ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 0 */
2043ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36),
2044ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 0),
2045ed367e6cSBorislav Petkov 	},
2046ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 1 */
2047ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37),
2048ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 1),
2049ed367e6cSBorislav Petkov 	},
2050ed367e6cSBorislav Petkov 	{ /* R3QPI1 Link 2 */
2051ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e),
2052ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 2),
2053ed367e6cSBorislav Petkov 	},
2054ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
2055ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86),
2056ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
2057ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT0_FILTER),
2058ed367e6cSBorislav Petkov 	},
2059ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
2060ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe96),
2061ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
2062ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT1_FILTER),
2063ed367e6cSBorislav Petkov 	},
2064ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
2065ed367e6cSBorislav Petkov };
2066ed367e6cSBorislav Petkov 
2067ed367e6cSBorislav Petkov static struct pci_driver ivbep_uncore_pci_driver = {
2068ed367e6cSBorislav Petkov 	.name		= "ivbep_uncore",
2069ed367e6cSBorislav Petkov 	.id_table	= ivbep_uncore_pci_ids,
2070ed367e6cSBorislav Petkov };
2071ed367e6cSBorislav Petkov 
ivbep_uncore_pci_init(void)2072ed367e6cSBorislav Petkov int ivbep_uncore_pci_init(void)
2073ed367e6cSBorislav Petkov {
207468ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x0e1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
2075ed367e6cSBorislav Petkov 	if (ret)
2076ed367e6cSBorislav Petkov 		return ret;
2077ed367e6cSBorislav Petkov 	uncore_pci_uncores = ivbep_pci_uncores;
2078ed367e6cSBorislav Petkov 	uncore_pci_driver = &ivbep_uncore_pci_driver;
2079ed367e6cSBorislav Petkov 	return 0;
2080ed367e6cSBorislav Petkov }
2081ed367e6cSBorislav Petkov /* end of IvyTown uncore support */
2082ed367e6cSBorislav Petkov 
2083ed367e6cSBorislav Petkov /* KNL uncore support */
2084ed367e6cSBorislav Petkov static struct attribute *knl_uncore_ubox_formats_attr[] = {
2085ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2086ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2087ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2088ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2089ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2090ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
2091ed367e6cSBorislav Petkov 	NULL,
2092ed367e6cSBorislav Petkov };
2093ed367e6cSBorislav Petkov 
209445bd07adSArvind Yadav static const struct attribute_group knl_uncore_ubox_format_group = {
2095ed367e6cSBorislav Petkov 	.name = "format",
2096ed367e6cSBorislav Petkov 	.attrs = knl_uncore_ubox_formats_attr,
2097ed367e6cSBorislav Petkov };
2098ed367e6cSBorislav Petkov 
2099ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_ubox = {
2100ed367e6cSBorislav Petkov 	.name			= "ubox",
2101ed367e6cSBorislav Petkov 	.num_counters		= 2,
2102ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2103ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2104ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2105ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
2106ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
2107ed367e6cSBorislav Petkov 	.event_mask		= KNL_U_MSR_PMON_RAW_EVENT_MASK,
2108ed367e6cSBorislav Petkov 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
2109ed367e6cSBorislav Petkov 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
2110ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_msr_ops,
2111ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_ubox_format_group,
2112ed367e6cSBorislav Petkov };
2113ed367e6cSBorislav Petkov 
2114ed367e6cSBorislav Petkov static struct attribute *knl_uncore_cha_formats_attr[] = {
2115ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2116ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2117ed367e6cSBorislav Petkov 	&format_attr_qor.attr,
2118ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2119ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2120ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2121ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2122ed367e6cSBorislav Petkov 	&format_attr_filter_tid4.attr,
2123ed367e6cSBorislav Petkov 	&format_attr_filter_link3.attr,
2124ed367e6cSBorislav Petkov 	&format_attr_filter_state4.attr,
2125ed367e6cSBorislav Petkov 	&format_attr_filter_local.attr,
2126ed367e6cSBorislav Petkov 	&format_attr_filter_all_op.attr,
2127ed367e6cSBorislav Petkov 	&format_attr_filter_nnm.attr,
2128ed367e6cSBorislav Petkov 	&format_attr_filter_opc3.attr,
2129ed367e6cSBorislav Petkov 	&format_attr_filter_nc.attr,
2130ed367e6cSBorislav Petkov 	&format_attr_filter_isoc.attr,
2131ed367e6cSBorislav Petkov 	NULL,
2132ed367e6cSBorislav Petkov };
2133ed367e6cSBorislav Petkov 
213445bd07adSArvind Yadav static const struct attribute_group knl_uncore_cha_format_group = {
2135ed367e6cSBorislav Petkov 	.name = "format",
2136ed367e6cSBorislav Petkov 	.attrs = knl_uncore_cha_formats_attr,
2137ed367e6cSBorislav Petkov };
2138ed367e6cSBorislav Petkov 
2139ed367e6cSBorislav Petkov static struct event_constraint knl_uncore_cha_constraints[] = {
2140ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
2141ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
2142ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
2143ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
2144ed367e6cSBorislav Petkov };
2145ed367e6cSBorislav Petkov 
2146ed367e6cSBorislav Petkov static struct extra_reg knl_uncore_cha_extra_regs[] = {
2147ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
2148ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
2149ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x3d, 0xff, 0x2),
2150ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x4),
2151ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x4),
2152ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
2153ed367e6cSBorislav Petkov };
2154ed367e6cSBorislav Petkov 
knl_cha_filter_mask(int fields)2155ed367e6cSBorislav Petkov static u64 knl_cha_filter_mask(int fields)
2156ed367e6cSBorislav Petkov {
2157ed367e6cSBorislav Petkov 	u64 mask = 0;
2158ed367e6cSBorislav Petkov 
2159ed367e6cSBorislav Petkov 	if (fields & 0x1)
2160ed367e6cSBorislav Petkov 		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_TID;
2161ed367e6cSBorislav Petkov 	if (fields & 0x2)
2162ed367e6cSBorislav Petkov 		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_STATE;
2163ed367e6cSBorislav Petkov 	if (fields & 0x4)
2164ed367e6cSBorislav Petkov 		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_OP;
2165ed367e6cSBorislav Petkov 	return mask;
2166ed367e6cSBorislav Petkov }
2167ed367e6cSBorislav Petkov 
2168ed367e6cSBorislav Petkov static struct event_constraint *
knl_cha_get_constraint(struct intel_uncore_box * box,struct perf_event * event)2169ed367e6cSBorislav Petkov knl_cha_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
2170ed367e6cSBorislav Petkov {
2171ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, knl_cha_filter_mask);
2172ed367e6cSBorislav Petkov }
2173ed367e6cSBorislav Petkov 
knl_cha_hw_config(struct intel_uncore_box * box,struct perf_event * event)2174ed367e6cSBorislav Petkov static int knl_cha_hw_config(struct intel_uncore_box *box,
2175ed367e6cSBorislav Petkov 			     struct perf_event *event)
2176ed367e6cSBorislav Petkov {
2177ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
2178ed367e6cSBorislav Petkov 	struct extra_reg *er;
2179ed367e6cSBorislav Petkov 	int idx = 0;
2180ed367e6cSBorislav Petkov 
2181ed367e6cSBorislav Petkov 	for (er = knl_uncore_cha_extra_regs; er->msr; er++) {
2182ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
2183ed367e6cSBorislav Petkov 			continue;
2184ed367e6cSBorislav Petkov 		idx |= er->idx;
2185ed367e6cSBorislav Petkov 	}
2186ed367e6cSBorislav Petkov 
2187ed367e6cSBorislav Petkov 	if (idx) {
2188ed367e6cSBorislav Petkov 		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
2189ed367e6cSBorislav Petkov 			    KNL_CHA_MSR_OFFSET * box->pmu->pmu_idx;
2190ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & knl_cha_filter_mask(idx);
2191ec336c87Shchrzani 
2192ec336c87Shchrzani 		reg1->config |= KNL_CHA_MSR_PMON_BOX_FILTER_REMOTE_NODE;
2193ec336c87Shchrzani 		reg1->config |= KNL_CHA_MSR_PMON_BOX_FILTER_LOCAL_NODE;
2194ec336c87Shchrzani 		reg1->config |= KNL_CHA_MSR_PMON_BOX_FILTER_NNC;
2195ed367e6cSBorislav Petkov 		reg1->idx = idx;
2196ed367e6cSBorislav Petkov 	}
2197ed367e6cSBorislav Petkov 	return 0;
2198ed367e6cSBorislav Petkov }
2199ed367e6cSBorislav Petkov 
2200ed367e6cSBorislav Petkov static void hswep_cbox_enable_event(struct intel_uncore_box *box,
2201ed367e6cSBorislav Petkov 				    struct perf_event *event);
2202ed367e6cSBorislav Petkov 
2203ed367e6cSBorislav Petkov static struct intel_uncore_ops knl_uncore_cha_ops = {
2204ed367e6cSBorislav Petkov 	.init_box		= snbep_uncore_msr_init_box,
2205ed367e6cSBorislav Petkov 	.disable_box		= snbep_uncore_msr_disable_box,
2206ed367e6cSBorislav Petkov 	.enable_box		= snbep_uncore_msr_enable_box,
2207ed367e6cSBorislav Petkov 	.disable_event		= snbep_uncore_msr_disable_event,
2208ed367e6cSBorislav Petkov 	.enable_event		= hswep_cbox_enable_event,
2209ed367e6cSBorislav Petkov 	.read_counter		= uncore_msr_read_counter,
2210ed367e6cSBorislav Petkov 	.hw_config		= knl_cha_hw_config,
2211ed367e6cSBorislav Petkov 	.get_constraint		= knl_cha_get_constraint,
2212ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
2213ed367e6cSBorislav Petkov };
2214ed367e6cSBorislav Petkov 
2215ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_cha = {
2216ed367e6cSBorislav Petkov 	.name			= "cha",
2217ed367e6cSBorislav Petkov 	.num_counters		= 4,
2218ed367e6cSBorislav Petkov 	.num_boxes		= 38,
2219ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2220ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
2221ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
2222ed367e6cSBorislav Petkov 	.event_mask		= KNL_CHA_MSR_PMON_RAW_EVENT_MASK,
2223ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
2224ed367e6cSBorislav Petkov 	.msr_offset		= KNL_CHA_MSR_OFFSET,
2225ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2226ed367e6cSBorislav Petkov 	.constraints		= knl_uncore_cha_constraints,
2227ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_cha_ops,
2228ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_cha_format_group,
2229ed367e6cSBorislav Petkov };
2230ed367e6cSBorislav Petkov 
2231ed367e6cSBorislav Petkov static struct attribute *knl_uncore_pcu_formats_attr[] = {
2232ed367e6cSBorislav Petkov 	&format_attr_event2.attr,
2233ed367e6cSBorislav Petkov 	&format_attr_use_occ_ctr.attr,
2234ed367e6cSBorislav Petkov 	&format_attr_occ_sel.attr,
2235ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2236ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2237ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2238ed367e6cSBorislav Petkov 	&format_attr_thresh6.attr,
2239ed367e6cSBorislav Petkov 	&format_attr_occ_invert.attr,
2240ed367e6cSBorislav Petkov 	&format_attr_occ_edge_det.attr,
2241ed367e6cSBorislav Petkov 	NULL,
2242ed367e6cSBorislav Petkov };
2243ed367e6cSBorislav Petkov 
224445bd07adSArvind Yadav static const struct attribute_group knl_uncore_pcu_format_group = {
2245ed367e6cSBorislav Petkov 	.name = "format",
2246ed367e6cSBorislav Petkov 	.attrs = knl_uncore_pcu_formats_attr,
2247ed367e6cSBorislav Petkov };
2248ed367e6cSBorislav Petkov 
2249ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_pcu = {
2250ed367e6cSBorislav Petkov 	.name			= "pcu",
2251ed367e6cSBorislav Petkov 	.num_counters		= 4,
2252ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2253ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2254ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
2255ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
2256ed367e6cSBorislav Petkov 	.event_mask		= KNL_PCU_MSR_PMON_RAW_EVENT_MASK,
2257ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
2258ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_msr_ops,
2259ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_pcu_format_group,
2260ed367e6cSBorislav Petkov };
2261ed367e6cSBorislav Petkov 
2262ed367e6cSBorislav Petkov static struct intel_uncore_type *knl_msr_uncores[] = {
2263ed367e6cSBorislav Petkov 	&knl_uncore_ubox,
2264ed367e6cSBorislav Petkov 	&knl_uncore_cha,
2265ed367e6cSBorislav Petkov 	&knl_uncore_pcu,
2266ed367e6cSBorislav Petkov 	NULL,
2267ed367e6cSBorislav Petkov };
2268ed367e6cSBorislav Petkov 
knl_uncore_cpu_init(void)2269ed367e6cSBorislav Petkov void knl_uncore_cpu_init(void)
2270ed367e6cSBorislav Petkov {
2271ed367e6cSBorislav Petkov 	uncore_msr_uncores = knl_msr_uncores;
2272ed367e6cSBorislav Petkov }
2273ed367e6cSBorislav Petkov 
knl_uncore_imc_enable_box(struct intel_uncore_box * box)2274ed367e6cSBorislav Petkov static void knl_uncore_imc_enable_box(struct intel_uncore_box *box)
2275ed367e6cSBorislav Petkov {
2276ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
2277ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
2278ed367e6cSBorislav Petkov 
2279ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, box_ctl, 0);
2280ed367e6cSBorislav Petkov }
2281ed367e6cSBorislav Petkov 
knl_uncore_imc_enable_event(struct intel_uncore_box * box,struct perf_event * event)2282ed367e6cSBorislav Petkov static void knl_uncore_imc_enable_event(struct intel_uncore_box *box,
2283ed367e6cSBorislav Petkov 					struct perf_event *event)
2284ed367e6cSBorislav Petkov {
2285ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
2286ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2287ed367e6cSBorislav Petkov 
2288ed367e6cSBorislav Petkov 	if ((event->attr.config & SNBEP_PMON_CTL_EV_SEL_MASK)
2289ed367e6cSBorislav Petkov 							== UNCORE_FIXED_EVENT)
2290ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, hwc->config_base,
2291ed367e6cSBorislav Petkov 				       hwc->config | KNL_PMON_FIXED_CTL_EN);
2292ed367e6cSBorislav Petkov 	else
2293ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, hwc->config_base,
2294ed367e6cSBorislav Petkov 				       hwc->config | SNBEP_PMON_CTL_EN);
2295ed367e6cSBorislav Petkov }
2296ed367e6cSBorislav Petkov 
2297ed367e6cSBorislav Petkov static struct intel_uncore_ops knl_uncore_imc_ops = {
2298ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_pci_init_box,
2299ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
2300ed367e6cSBorislav Petkov 	.enable_box	= knl_uncore_imc_enable_box,
2301ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter,
2302ed367e6cSBorislav Petkov 	.enable_event	= knl_uncore_imc_enable_event,
2303ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,
2304ed367e6cSBorislav Petkov };
2305ed367e6cSBorislav Petkov 
2306ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_imc_uclk = {
2307ed367e6cSBorislav Petkov 	.name			= "imc_uclk",
2308ed367e6cSBorislav Petkov 	.num_counters		= 4,
2309ed367e6cSBorislav Petkov 	.num_boxes		= 2,
2310ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2311ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2312ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_UCLK_MSR_PMON_CTR0_LOW,
2313ed367e6cSBorislav Petkov 	.event_ctl		= KNL_UCLK_MSR_PMON_CTL0,
2314ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2315ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW,
2316ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL,
2317ed367e6cSBorislav Petkov 	.box_ctl		= KNL_UCLK_MSR_PMON_BOX_CTL,
2318ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2319ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2320ed367e6cSBorislav Petkov };
2321ed367e6cSBorislav Petkov 
2322ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_imc_dclk = {
2323ed367e6cSBorislav Petkov 	.name			= "imc",
2324ed367e6cSBorislav Petkov 	.num_counters		= 4,
2325ed367e6cSBorislav Petkov 	.num_boxes		= 6,
2326ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2327ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2328ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_MC0_CH0_MSR_PMON_CTR0_LOW,
2329ed367e6cSBorislav Petkov 	.event_ctl		= KNL_MC0_CH0_MSR_PMON_CTL0,
2330ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2331ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_MC0_CH0_MSR_PMON_FIXED_LOW,
2332ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_MC0_CH0_MSR_PMON_FIXED_CTL,
2333ed367e6cSBorislav Petkov 	.box_ctl		= KNL_MC0_CH0_MSR_PMON_BOX_CTL,
2334ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2335ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2336ed367e6cSBorislav Petkov };
2337ed367e6cSBorislav Petkov 
2338ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_edc_uclk = {
2339ed367e6cSBorislav Petkov 	.name			= "edc_uclk",
2340ed367e6cSBorislav Petkov 	.num_counters		= 4,
2341ed367e6cSBorislav Petkov 	.num_boxes		= 8,
2342ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2343ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2344ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_UCLK_MSR_PMON_CTR0_LOW,
2345ed367e6cSBorislav Petkov 	.event_ctl		= KNL_UCLK_MSR_PMON_CTL0,
2346ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2347ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW,
2348ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL,
2349ed367e6cSBorislav Petkov 	.box_ctl		= KNL_UCLK_MSR_PMON_BOX_CTL,
2350ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2351ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2352ed367e6cSBorislav Petkov };
2353ed367e6cSBorislav Petkov 
2354ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_edc_eclk = {
2355ed367e6cSBorislav Petkov 	.name			= "edc_eclk",
2356ed367e6cSBorislav Petkov 	.num_counters		= 4,
2357ed367e6cSBorislav Petkov 	.num_boxes		= 8,
2358ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2359ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2360ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_EDC0_ECLK_MSR_PMON_CTR0_LOW,
2361ed367e6cSBorislav Petkov 	.event_ctl		= KNL_EDC0_ECLK_MSR_PMON_CTL0,
2362ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2363ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_LOW,
2364ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_CTL,
2365ed367e6cSBorislav Petkov 	.box_ctl		= KNL_EDC0_ECLK_MSR_PMON_BOX_CTL,
2366ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2367ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2368ed367e6cSBorislav Petkov };
2369ed367e6cSBorislav Petkov 
2370ed367e6cSBorislav Petkov static struct event_constraint knl_uncore_m2pcie_constraints[] = {
2371ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
2372ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
2373ed367e6cSBorislav Petkov };
2374ed367e6cSBorislav Petkov 
2375ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_m2pcie = {
2376ed367e6cSBorislav Petkov 	.name		= "m2pcie",
2377ed367e6cSBorislav Petkov 	.num_counters   = 4,
2378ed367e6cSBorislav Petkov 	.num_boxes	= 1,
2379ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
2380ed367e6cSBorislav Petkov 	.constraints	= knl_uncore_m2pcie_constraints,
2381ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
2382ed367e6cSBorislav Petkov };
2383ed367e6cSBorislav Petkov 
2384ed367e6cSBorislav Petkov static struct attribute *knl_uncore_irp_formats_attr[] = {
2385ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2386ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2387ed367e6cSBorislav Petkov 	&format_attr_qor.attr,
2388ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2389ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2390ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2391ed367e6cSBorislav Petkov 	NULL,
2392ed367e6cSBorislav Petkov };
2393ed367e6cSBorislav Petkov 
239445bd07adSArvind Yadav static const struct attribute_group knl_uncore_irp_format_group = {
2395ed367e6cSBorislav Petkov 	.name = "format",
2396ed367e6cSBorislav Petkov 	.attrs = knl_uncore_irp_formats_attr,
2397ed367e6cSBorislav Petkov };
2398ed367e6cSBorislav Petkov 
2399ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_irp = {
2400ed367e6cSBorislav Petkov 	.name			= "irp",
2401ed367e6cSBorislav Petkov 	.num_counters		= 2,
2402ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2403ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2404ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
2405ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
2406ed367e6cSBorislav Petkov 	.event_mask		= KNL_IRP_PCI_PMON_RAW_EVENT_MASK,
2407ed367e6cSBorislav Petkov 	.box_ctl		= KNL_IRP_PCI_PMON_BOX_CTL,
2408ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_pci_ops,
2409ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_irp_format_group,
2410ed367e6cSBorislav Petkov };
2411ed367e6cSBorislav Petkov 
2412ed367e6cSBorislav Petkov enum {
2413ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_MC_UCLK,
2414ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_MC_DCLK,
2415ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_EDC_UCLK,
2416ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_EDC_ECLK,
2417ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_M2PCIE,
2418ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_IRP,
2419ed367e6cSBorislav Petkov };
2420ed367e6cSBorislav Petkov 
2421ed367e6cSBorislav Petkov static struct intel_uncore_type *knl_pci_uncores[] = {
2422ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_MC_UCLK]	= &knl_uncore_imc_uclk,
2423ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_MC_DCLK]	= &knl_uncore_imc_dclk,
2424ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_EDC_UCLK]	= &knl_uncore_edc_uclk,
2425ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_EDC_ECLK]	= &knl_uncore_edc_eclk,
2426ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_M2PCIE]		= &knl_uncore_m2pcie,
2427ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_IRP]		= &knl_uncore_irp,
2428ed367e6cSBorislav Petkov 	NULL,
2429ed367e6cSBorislav Petkov };
2430ed367e6cSBorislav Petkov 
2431ed367e6cSBorislav Petkov /*
2432ed367e6cSBorislav Petkov  * KNL uses a common PCI device ID for multiple instances of an Uncore PMU
2433ed367e6cSBorislav Petkov  * device type. prior to KNL, each instance of a PMU device type had a unique
2434ed367e6cSBorislav Petkov  * device ID.
2435ed367e6cSBorislav Petkov  *
2436ed367e6cSBorislav Petkov  *	PCI Device ID	Uncore PMU Devices
2437ed367e6cSBorislav Petkov  *	----------------------------------
2438ed367e6cSBorislav Petkov  *	0x7841		MC0 UClk, MC1 UClk
2439ed367e6cSBorislav Petkov  *	0x7843		MC0 DClk CH 0, MC0 DClk CH 1, MC0 DClk CH 2,
2440ed367e6cSBorislav Petkov  *			MC1 DClk CH 0, MC1 DClk CH 1, MC1 DClk CH 2
2441ed367e6cSBorislav Petkov  *	0x7833		EDC0 UClk, EDC1 UClk, EDC2 UClk, EDC3 UClk,
2442ed367e6cSBorislav Petkov  *			EDC4 UClk, EDC5 UClk, EDC6 UClk, EDC7 UClk
2443ed367e6cSBorislav Petkov  *	0x7835		EDC0 EClk, EDC1 EClk, EDC2 EClk, EDC3 EClk,
2444ed367e6cSBorislav Petkov  *			EDC4 EClk, EDC5 EClk, EDC6 EClk, EDC7 EClk
2445ed367e6cSBorislav Petkov  *	0x7817		M2PCIe
2446ed367e6cSBorislav Petkov  *	0x7814		IRP
2447ed367e6cSBorislav Petkov */
2448ed367e6cSBorislav Petkov 
2449ed367e6cSBorislav Petkov static const struct pci_device_id knl_uncore_pci_ids[] = {
2450a54fa079SKan Liang 	{ /* MC0 UClk */
2451ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7841),
2452a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(10, 0, KNL_PCI_UNCORE_MC_UCLK, 0),
2453ed367e6cSBorislav Petkov 	},
2454a54fa079SKan Liang 	{ /* MC1 UClk */
2455a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7841),
2456a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(11, 0, KNL_PCI_UNCORE_MC_UCLK, 1),
2457a54fa079SKan Liang 	},
2458a54fa079SKan Liang 	{ /* MC0 DClk CH 0 */
2459ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2460a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 2, KNL_PCI_UNCORE_MC_DCLK, 0),
2461ed367e6cSBorislav Petkov 	},
2462a54fa079SKan Liang 	{ /* MC0 DClk CH 1 */
2463a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2464a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 3, KNL_PCI_UNCORE_MC_DCLK, 1),
2465a54fa079SKan Liang 	},
2466a54fa079SKan Liang 	{ /* MC0 DClk CH 2 */
2467a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2468a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 4, KNL_PCI_UNCORE_MC_DCLK, 2),
2469a54fa079SKan Liang 	},
2470a54fa079SKan Liang 	{ /* MC1 DClk CH 0 */
2471a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2472a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 2, KNL_PCI_UNCORE_MC_DCLK, 3),
2473a54fa079SKan Liang 	},
2474a54fa079SKan Liang 	{ /* MC1 DClk CH 1 */
2475a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2476a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 3, KNL_PCI_UNCORE_MC_DCLK, 4),
2477a54fa079SKan Liang 	},
2478a54fa079SKan Liang 	{ /* MC1 DClk CH 2 */
2479a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2480a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 4, KNL_PCI_UNCORE_MC_DCLK, 5),
2481a54fa079SKan Liang 	},
2482a54fa079SKan Liang 	{ /* EDC0 UClk */
2483ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2484a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(15, 0, KNL_PCI_UNCORE_EDC_UCLK, 0),
2485ed367e6cSBorislav Petkov 	},
2486a54fa079SKan Liang 	{ /* EDC1 UClk */
2487a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2488a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(16, 0, KNL_PCI_UNCORE_EDC_UCLK, 1),
2489a54fa079SKan Liang 	},
2490a54fa079SKan Liang 	{ /* EDC2 UClk */
2491a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2492a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(17, 0, KNL_PCI_UNCORE_EDC_UCLK, 2),
2493a54fa079SKan Liang 	},
2494a54fa079SKan Liang 	{ /* EDC3 UClk */
2495a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2496a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 0, KNL_PCI_UNCORE_EDC_UCLK, 3),
2497a54fa079SKan Liang 	},
2498a54fa079SKan Liang 	{ /* EDC4 UClk */
2499a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2500a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(19, 0, KNL_PCI_UNCORE_EDC_UCLK, 4),
2501a54fa079SKan Liang 	},
2502a54fa079SKan Liang 	{ /* EDC5 UClk */
2503a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2504a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(20, 0, KNL_PCI_UNCORE_EDC_UCLK, 5),
2505a54fa079SKan Liang 	},
2506a54fa079SKan Liang 	{ /* EDC6 UClk */
2507a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2508a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 0, KNL_PCI_UNCORE_EDC_UCLK, 6),
2509a54fa079SKan Liang 	},
2510a54fa079SKan Liang 	{ /* EDC7 UClk */
2511a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2512a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(22, 0, KNL_PCI_UNCORE_EDC_UCLK, 7),
2513a54fa079SKan Liang 	},
2514a54fa079SKan Liang 	{ /* EDC0 EClk */
2515ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2516a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(24, 2, KNL_PCI_UNCORE_EDC_ECLK, 0),
2517a54fa079SKan Liang 	},
2518a54fa079SKan Liang 	{ /* EDC1 EClk */
2519a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2520a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(25, 2, KNL_PCI_UNCORE_EDC_ECLK, 1),
2521a54fa079SKan Liang 	},
2522a54fa079SKan Liang 	{ /* EDC2 EClk */
2523a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2524a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(26, 2, KNL_PCI_UNCORE_EDC_ECLK, 2),
2525a54fa079SKan Liang 	},
2526a54fa079SKan Liang 	{ /* EDC3 EClk */
2527a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2528a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(27, 2, KNL_PCI_UNCORE_EDC_ECLK, 3),
2529a54fa079SKan Liang 	},
2530a54fa079SKan Liang 	{ /* EDC4 EClk */
2531a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2532a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(28, 2, KNL_PCI_UNCORE_EDC_ECLK, 4),
2533a54fa079SKan Liang 	},
2534a54fa079SKan Liang 	{ /* EDC5 EClk */
2535a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2536a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(29, 2, KNL_PCI_UNCORE_EDC_ECLK, 5),
2537a54fa079SKan Liang 	},
2538a54fa079SKan Liang 	{ /* EDC6 EClk */
2539a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2540a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(30, 2, KNL_PCI_UNCORE_EDC_ECLK, 6),
2541a54fa079SKan Liang 	},
2542a54fa079SKan Liang 	{ /* EDC7 EClk */
2543a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2544a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(31, 2, KNL_PCI_UNCORE_EDC_ECLK, 7),
2545ed367e6cSBorislav Petkov 	},
2546ed367e6cSBorislav Petkov 	{ /* M2PCIe */
2547ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7817),
2548ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_M2PCIE, 0),
2549ed367e6cSBorislav Petkov 	},
2550ed367e6cSBorislav Petkov 	{ /* IRP */
2551ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7814),
2552ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_IRP, 0),
2553ed367e6cSBorislav Petkov 	},
2554ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
2555ed367e6cSBorislav Petkov };
2556ed367e6cSBorislav Petkov 
2557ed367e6cSBorislav Petkov static struct pci_driver knl_uncore_pci_driver = {
2558ed367e6cSBorislav Petkov 	.name		= "knl_uncore",
2559ed367e6cSBorislav Petkov 	.id_table	= knl_uncore_pci_ids,
2560ed367e6cSBorislav Petkov };
2561ed367e6cSBorislav Petkov 
knl_uncore_pci_init(void)2562ed367e6cSBorislav Petkov int knl_uncore_pci_init(void)
2563ed367e6cSBorislav Petkov {
2564ed367e6cSBorislav Petkov 	int ret;
2565ed367e6cSBorislav Petkov 
2566ed367e6cSBorislav Petkov 	/* All KNL PCI based PMON units are on the same PCI bus except IRP */
2567ed367e6cSBorislav Petkov 	ret = snb_pci2phy_map_init(0x7814); /* IRP */
2568ed367e6cSBorislav Petkov 	if (ret)
2569ed367e6cSBorislav Petkov 		return ret;
2570ed367e6cSBorislav Petkov 	ret = snb_pci2phy_map_init(0x7817); /* M2PCIe */
2571ed367e6cSBorislav Petkov 	if (ret)
2572ed367e6cSBorislav Petkov 		return ret;
2573ed367e6cSBorislav Petkov 	uncore_pci_uncores = knl_pci_uncores;
2574ed367e6cSBorislav Petkov 	uncore_pci_driver = &knl_uncore_pci_driver;
2575ed367e6cSBorislav Petkov 	return 0;
2576ed367e6cSBorislav Petkov }
2577ed367e6cSBorislav Petkov 
2578ed367e6cSBorislav Petkov /* end of KNL uncore support */
2579ed367e6cSBorislav Petkov 
2580ed367e6cSBorislav Petkov /* Haswell-EP uncore support */
2581ed367e6cSBorislav Petkov static struct attribute *hswep_uncore_ubox_formats_attr[] = {
2582ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2583ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2584ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2585ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2586ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
2587ed367e6cSBorislav Petkov 	&format_attr_filter_tid2.attr,
2588ed367e6cSBorislav Petkov 	&format_attr_filter_cid.attr,
2589ed367e6cSBorislav Petkov 	NULL,
2590ed367e6cSBorislav Petkov };
2591ed367e6cSBorislav Petkov 
259245bd07adSArvind Yadav static const struct attribute_group hswep_uncore_ubox_format_group = {
2593ed367e6cSBorislav Petkov 	.name = "format",
2594ed367e6cSBorislav Petkov 	.attrs = hswep_uncore_ubox_formats_attr,
2595ed367e6cSBorislav Petkov };
2596ed367e6cSBorislav Petkov 
hswep_ubox_hw_config(struct intel_uncore_box * box,struct perf_event * event)2597ed367e6cSBorislav Petkov static int hswep_ubox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
2598ed367e6cSBorislav Petkov {
2599ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
2600ed367e6cSBorislav Petkov 	reg1->reg = HSWEP_U_MSR_PMON_FILTER;
2601ed367e6cSBorislav Petkov 	reg1->config = event->attr.config1 & HSWEP_U_MSR_PMON_BOX_FILTER_MASK;
2602ed367e6cSBorislav Petkov 	reg1->idx = 0;
2603ed367e6cSBorislav Petkov 	return 0;
2604ed367e6cSBorislav Petkov }
2605ed367e6cSBorislav Petkov 
2606ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_ubox_ops = {
2607ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
2608ed367e6cSBorislav Petkov 	.hw_config		= hswep_ubox_hw_config,
2609ed367e6cSBorislav Petkov 	.get_constraint		= uncore_get_constraint,
2610ed367e6cSBorislav Petkov 	.put_constraint		= uncore_put_constraint,
2611ed367e6cSBorislav Petkov };
2612ed367e6cSBorislav Petkov 
2613ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_ubox = {
2614ed367e6cSBorislav Petkov 	.name			= "ubox",
2615ed367e6cSBorislav Petkov 	.num_counters		= 2,
2616ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2617ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
2618ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2619ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
2620ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
2621ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
2622ed367e6cSBorislav Petkov 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
2623ed367e6cSBorislav Petkov 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
2624ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2625ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_ubox_ops,
2626ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_ubox_format_group,
2627ed367e6cSBorislav Petkov };
2628ed367e6cSBorislav Petkov 
2629ed367e6cSBorislav Petkov static struct attribute *hswep_uncore_cbox_formats_attr[] = {
2630ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2631ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2632ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2633ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2634ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2635ed367e6cSBorislav Petkov 	&format_attr_filter_tid3.attr,
2636ed367e6cSBorislav Petkov 	&format_attr_filter_link2.attr,
2637ed367e6cSBorislav Petkov 	&format_attr_filter_state3.attr,
2638ed367e6cSBorislav Petkov 	&format_attr_filter_nid2.attr,
2639ed367e6cSBorislav Petkov 	&format_attr_filter_opc2.attr,
2640ed367e6cSBorislav Petkov 	&format_attr_filter_nc.attr,
2641ed367e6cSBorislav Petkov 	&format_attr_filter_c6.attr,
2642ed367e6cSBorislav Petkov 	&format_attr_filter_isoc.attr,
2643ed367e6cSBorislav Petkov 	NULL,
2644ed367e6cSBorislav Petkov };
2645ed367e6cSBorislav Petkov 
264645bd07adSArvind Yadav static const struct attribute_group hswep_uncore_cbox_format_group = {
2647ed367e6cSBorislav Petkov 	.name = "format",
2648ed367e6cSBorislav Petkov 	.attrs = hswep_uncore_cbox_formats_attr,
2649ed367e6cSBorislav Petkov };
2650ed367e6cSBorislav Petkov 
2651ed367e6cSBorislav Petkov static struct event_constraint hswep_uncore_cbox_constraints[] = {
2652ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
2653ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x1),
2654ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
2655ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
2656ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
2657ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
2658ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
2659ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
2660ed367e6cSBorislav Petkov };
2661ed367e6cSBorislav Petkov 
2662ed367e6cSBorislav Petkov static struct extra_reg hswep_uncore_cbox_extra_regs[] = {
2663ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
2664ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
2665ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
2666ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
2667ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
2668ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
2669ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2134, 0xffff, 0x4),
2670ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x4),
2671ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
2672ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4028, 0x40ff, 0x8),
2673ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4032, 0x40ff, 0x8),
2674ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4029, 0x40ff, 0x8),
2675ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4033, 0x40ff, 0x8),
2676ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x402A, 0x40ff, 0x8),
2677ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x12),
2678ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
2679ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
2680ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
2681ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
2682ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
2683ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
2684ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
2685ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
2686ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
2687ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
2688ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
2689ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
2690ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
2691ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
2692ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
2693ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
2694ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
2695ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
2696ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
2697ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
2698ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
2699ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
2700ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
2701ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
2702ed367e6cSBorislav Petkov };
2703ed367e6cSBorislav Petkov 
hswep_cbox_filter_mask(int fields)2704ed367e6cSBorislav Petkov static u64 hswep_cbox_filter_mask(int fields)
2705ed367e6cSBorislav Petkov {
2706ed367e6cSBorislav Petkov 	u64 mask = 0;
2707ed367e6cSBorislav Petkov 	if (fields & 0x1)
2708ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_TID;
2709ed367e6cSBorislav Petkov 	if (fields & 0x2)
2710ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK;
2711ed367e6cSBorislav Petkov 	if (fields & 0x4)
2712ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE;
2713ed367e6cSBorislav Petkov 	if (fields & 0x8)
2714ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NID;
2715ed367e6cSBorislav Petkov 	if (fields & 0x10) {
2716ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC;
2717ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NC;
2718ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_C6;
2719ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
2720ed367e6cSBorislav Petkov 	}
2721ed367e6cSBorislav Petkov 	return mask;
2722ed367e6cSBorislav Petkov }
2723ed367e6cSBorislav Petkov 
2724ed367e6cSBorislav Petkov static struct event_constraint *
hswep_cbox_get_constraint(struct intel_uncore_box * box,struct perf_event * event)2725ed367e6cSBorislav Petkov hswep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
2726ed367e6cSBorislav Petkov {
2727ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, hswep_cbox_filter_mask);
2728ed367e6cSBorislav Petkov }
2729ed367e6cSBorislav Petkov 
hswep_cbox_hw_config(struct intel_uncore_box * box,struct perf_event * event)2730ed367e6cSBorislav Petkov static int hswep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
2731ed367e6cSBorislav Petkov {
2732ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
2733ed367e6cSBorislav Petkov 	struct extra_reg *er;
2734ed367e6cSBorislav Petkov 	int idx = 0;
2735ed367e6cSBorislav Petkov 
2736ed367e6cSBorislav Petkov 	for (er = hswep_uncore_cbox_extra_regs; er->msr; er++) {
2737ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
2738ed367e6cSBorislav Petkov 			continue;
2739ed367e6cSBorislav Petkov 		idx |= er->idx;
2740ed367e6cSBorislav Petkov 	}
2741ed367e6cSBorislav Petkov 
2742ed367e6cSBorislav Petkov 	if (idx) {
2743ed367e6cSBorislav Petkov 		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
2744ed367e6cSBorislav Petkov 			    HSWEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
2745ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & hswep_cbox_filter_mask(idx);
2746ed367e6cSBorislav Petkov 		reg1->idx = idx;
2747ed367e6cSBorislav Petkov 	}
2748ed367e6cSBorislav Petkov 	return 0;
2749ed367e6cSBorislav Petkov }
2750ed367e6cSBorislav Petkov 
hswep_cbox_enable_event(struct intel_uncore_box * box,struct perf_event * event)2751ed367e6cSBorislav Petkov static void hswep_cbox_enable_event(struct intel_uncore_box *box,
2752ed367e6cSBorislav Petkov 				  struct perf_event *event)
2753ed367e6cSBorislav Petkov {
2754ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2755ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
2756ed367e6cSBorislav Petkov 
2757ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE) {
2758ed367e6cSBorislav Petkov 		u64 filter = uncore_shared_reg_config(box, 0);
2759ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg, filter & 0xffffffff);
2760ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg + 1, filter >> 32);
2761ed367e6cSBorislav Petkov 	}
2762ed367e6cSBorislav Petkov 
2763ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
2764ed367e6cSBorislav Petkov }
2765ed367e6cSBorislav Petkov 
2766ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_cbox_ops = {
2767ed367e6cSBorislav Petkov 	.init_box		= snbep_uncore_msr_init_box,
2768ed367e6cSBorislav Petkov 	.disable_box		= snbep_uncore_msr_disable_box,
2769ed367e6cSBorislav Petkov 	.enable_box		= snbep_uncore_msr_enable_box,
2770ed367e6cSBorislav Petkov 	.disable_event		= snbep_uncore_msr_disable_event,
2771ed367e6cSBorislav Petkov 	.enable_event		= hswep_cbox_enable_event,
2772ed367e6cSBorislav Petkov 	.read_counter		= uncore_msr_read_counter,
2773ed367e6cSBorislav Petkov 	.hw_config		= hswep_cbox_hw_config,
2774ed367e6cSBorislav Petkov 	.get_constraint		= hswep_cbox_get_constraint,
2775ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
2776ed367e6cSBorislav Petkov };
2777ed367e6cSBorislav Petkov 
2778ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_cbox = {
2779ed367e6cSBorislav Petkov 	.name			= "cbox",
2780ed367e6cSBorislav Petkov 	.num_counters		= 4,
2781ed367e6cSBorislav Petkov 	.num_boxes		= 18,
2782ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2783ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
2784ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
2785ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
2786ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
2787ed367e6cSBorislav Petkov 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
2788ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2789ed367e6cSBorislav Petkov 	.constraints		= hswep_uncore_cbox_constraints,
2790ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_cbox_ops,
2791ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_cbox_format_group,
2792ed367e6cSBorislav Petkov };
2793ed367e6cSBorislav Petkov 
2794ed367e6cSBorislav Petkov /*
2795ed367e6cSBorislav Petkov  * Write SBOX Initialization register bit by bit to avoid spurious #GPs
2796ed367e6cSBorislav Petkov  */
hswep_uncore_sbox_msr_init_box(struct intel_uncore_box * box)2797ed367e6cSBorislav Petkov static void hswep_uncore_sbox_msr_init_box(struct intel_uncore_box *box)
2798ed367e6cSBorislav Petkov {
2799ed367e6cSBorislav Petkov 	unsigned msr = uncore_msr_box_ctl(box);
2800ed367e6cSBorislav Petkov 
2801ed367e6cSBorislav Petkov 	if (msr) {
2802ed367e6cSBorislav Petkov 		u64 init = SNBEP_PMON_BOX_CTL_INT;
2803ed367e6cSBorislav Petkov 		u64 flags = 0;
2804ed367e6cSBorislav Petkov 		int i;
2805ed367e6cSBorislav Petkov 
2806ed367e6cSBorislav Petkov 		for_each_set_bit(i, (unsigned long *)&init, 64) {
2807ed367e6cSBorislav Petkov 			flags |= (1ULL << i);
2808ed367e6cSBorislav Petkov 			wrmsrl(msr, flags);
2809ed367e6cSBorislav Petkov 		}
2810ed367e6cSBorislav Petkov 	}
2811ed367e6cSBorislav Petkov }
2812ed367e6cSBorislav Petkov 
2813ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_sbox_msr_ops = {
2814ed367e6cSBorislav Petkov 	__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
2815ed367e6cSBorislav Petkov 	.init_box		= hswep_uncore_sbox_msr_init_box
2816ed367e6cSBorislav Petkov };
2817ed367e6cSBorislav Petkov 
2818ed367e6cSBorislav Petkov static struct attribute *hswep_uncore_sbox_formats_attr[] = {
2819ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2820ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2821ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2822ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2823ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2824ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2825ed367e6cSBorislav Petkov 	NULL,
2826ed367e6cSBorislav Petkov };
2827ed367e6cSBorislav Petkov 
282845bd07adSArvind Yadav static const struct attribute_group hswep_uncore_sbox_format_group = {
2829ed367e6cSBorislav Petkov 	.name = "format",
2830ed367e6cSBorislav Petkov 	.attrs = hswep_uncore_sbox_formats_attr,
2831ed367e6cSBorislav Petkov };
2832ed367e6cSBorislav Petkov 
2833ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_sbox = {
2834ed367e6cSBorislav Petkov 	.name			= "sbox",
2835ed367e6cSBorislav Petkov 	.num_counters		= 4,
2836ed367e6cSBorislav Petkov 	.num_boxes		= 4,
2837ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
2838ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_S0_MSR_PMON_CTL0,
2839ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_S0_MSR_PMON_CTR0,
2840ed367e6cSBorislav Petkov 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
2841ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_S0_MSR_PMON_BOX_CTL,
2842ed367e6cSBorislav Petkov 	.msr_offset		= HSWEP_SBOX_MSR_OFFSET,
2843ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_sbox_msr_ops,
2844ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_sbox_format_group,
2845ed367e6cSBorislav Petkov };
2846ed367e6cSBorislav Petkov 
hswep_pcu_hw_config(struct intel_uncore_box * box,struct perf_event * event)2847ed367e6cSBorislav Petkov static int hswep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
2848ed367e6cSBorislav Petkov {
2849ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2850ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
2851ed367e6cSBorislav Petkov 	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
2852ed367e6cSBorislav Petkov 
2853ed367e6cSBorislav Petkov 	if (ev_sel >= 0xb && ev_sel <= 0xe) {
2854ed367e6cSBorislav Petkov 		reg1->reg = HSWEP_PCU_MSR_PMON_BOX_FILTER;
2855ed367e6cSBorislav Petkov 		reg1->idx = ev_sel - 0xb;
2856ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & (0xff << reg1->idx);
2857ed367e6cSBorislav Petkov 	}
2858ed367e6cSBorislav Petkov 	return 0;
2859ed367e6cSBorislav Petkov }
2860ed367e6cSBorislav Petkov 
2861ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_pcu_ops = {
2862ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
2863ed367e6cSBorislav Petkov 	.hw_config		= hswep_pcu_hw_config,
2864ed367e6cSBorislav Petkov 	.get_constraint		= snbep_pcu_get_constraint,
2865ed367e6cSBorislav Petkov 	.put_constraint		= snbep_pcu_put_constraint,
2866ed367e6cSBorislav Petkov };
2867ed367e6cSBorislav Petkov 
2868ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_pcu = {
2869ed367e6cSBorislav Petkov 	.name			= "pcu",
2870ed367e6cSBorislav Petkov 	.num_counters		= 4,
2871ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2872ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2873ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
2874ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
2875ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
2876ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
2877ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2878ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_pcu_ops,
2879ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_pcu_format_group,
2880ed367e6cSBorislav Petkov };
2881ed367e6cSBorislav Petkov 
2882ed367e6cSBorislav Petkov static struct intel_uncore_type *hswep_msr_uncores[] = {
2883ed367e6cSBorislav Petkov 	&hswep_uncore_ubox,
2884ed367e6cSBorislav Petkov 	&hswep_uncore_cbox,
2885ed367e6cSBorislav Petkov 	&hswep_uncore_sbox,
2886ed367e6cSBorislav Petkov 	&hswep_uncore_pcu,
2887ed367e6cSBorislav Petkov 	NULL,
2888ed367e6cSBorislav Petkov };
2889ed367e6cSBorislav Petkov 
28909d480158SKan Liang #define HSWEP_PCU_DID			0x2fc0
28919d480158SKan Liang #define HSWEP_PCU_CAPID4_OFFET		0x94
28929d480158SKan Liang #define hswep_get_chop(_cap)		(((_cap) >> 6) & 0x3)
28939d480158SKan Liang 
hswep_has_limit_sbox(unsigned int device)28949d480158SKan Liang static bool hswep_has_limit_sbox(unsigned int device)
28959d480158SKan Liang {
28969d480158SKan Liang 	struct pci_dev *dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
28979d480158SKan Liang 	u32 capid4;
28989d480158SKan Liang 
28999d480158SKan Liang 	if (!dev)
29009d480158SKan Liang 		return false;
29019d480158SKan Liang 
29029d480158SKan Liang 	pci_read_config_dword(dev, HSWEP_PCU_CAPID4_OFFET, &capid4);
29031ff9dd6eSXiongfeng Wang 	pci_dev_put(dev);
29049d480158SKan Liang 	if (!hswep_get_chop(capid4))
29059d480158SKan Liang 		return true;
29069d480158SKan Liang 
29079d480158SKan Liang 	return false;
29089d480158SKan Liang }
29099d480158SKan Liang 
hswep_uncore_cpu_init(void)2910ed367e6cSBorislav Petkov void hswep_uncore_cpu_init(void)
2911ed367e6cSBorislav Petkov {
2912ed367e6cSBorislav Petkov 	if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
2913ed367e6cSBorislav Petkov 		hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
2914ed367e6cSBorislav Petkov 
2915ed367e6cSBorislav Petkov 	/* Detect 6-8 core systems with only two SBOXes */
29169d480158SKan Liang 	if (hswep_has_limit_sbox(HSWEP_PCU_DID))
2917ed367e6cSBorislav Petkov 		hswep_uncore_sbox.num_boxes = 2;
2918ed367e6cSBorislav Petkov 
2919ed367e6cSBorislav Petkov 	uncore_msr_uncores = hswep_msr_uncores;
2920ed367e6cSBorislav Petkov }
2921ed367e6cSBorislav Petkov 
2922ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_ha = {
2923ed367e6cSBorislav Petkov 	.name		= "ha",
292410e9e7bdSKan Liang 	.num_counters   = 4,
2925ed367e6cSBorislav Petkov 	.num_boxes	= 2,
2926ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
2927ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
2928ed367e6cSBorislav Petkov };
2929ed367e6cSBorislav Petkov 
2930ed367e6cSBorislav Petkov static struct uncore_event_desc hswep_uncore_imc_events[] = {
2931ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0x00,umask=0x00"),
2932ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x03"),
2933ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
2934ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
2935ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
2936ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
2937ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
2938ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ },
2939ed367e6cSBorislav Petkov };
2940ed367e6cSBorislav Petkov 
2941ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_imc = {
2942ed367e6cSBorislav Petkov 	.name		= "imc",
294310e9e7bdSKan Liang 	.num_counters   = 4,
2944ed367e6cSBorislav Petkov 	.num_boxes	= 8,
2945ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
2946ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
2947ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
2948ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
2949ed367e6cSBorislav Petkov 	.event_descs	= hswep_uncore_imc_events,
2950ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
2951ed367e6cSBorislav Petkov };
2952ed367e6cSBorislav Petkov 
2953ed367e6cSBorislav Petkov static unsigned hswep_uncore_irp_ctrs[] = {0xa0, 0xa8, 0xb0, 0xb8};
2954ed367e6cSBorislav Petkov 
hswep_uncore_irp_read_counter(struct intel_uncore_box * box,struct perf_event * event)2955ed367e6cSBorislav Petkov static u64 hswep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
2956ed367e6cSBorislav Petkov {
2957ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
2958ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2959ed367e6cSBorislav Petkov 	u64 count = 0;
2960ed367e6cSBorislav Petkov 
2961ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
2962ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
2963ed367e6cSBorislav Petkov 
2964ed367e6cSBorislav Petkov 	return count;
2965ed367e6cSBorislav Petkov }
2966ed367e6cSBorislav Petkov 
2967ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_irp_ops = {
2968ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_pci_init_box,
2969ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
2970ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
2971ed367e6cSBorislav Petkov 	.disable_event	= ivbep_uncore_irp_disable_event,
2972ed367e6cSBorislav Petkov 	.enable_event	= ivbep_uncore_irp_enable_event,
2973ed367e6cSBorislav Petkov 	.read_counter	= hswep_uncore_irp_read_counter,
2974ed367e6cSBorislav Petkov };
2975ed367e6cSBorislav Petkov 
2976ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_irp = {
2977ed367e6cSBorislav Petkov 	.name			= "irp",
2978ed367e6cSBorislav Petkov 	.num_counters		= 4,
2979ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2980ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2981ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2982ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
2983ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_irp_ops,
2984ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2985ed367e6cSBorislav Petkov };
2986ed367e6cSBorislav Petkov 
2987ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_qpi = {
2988ed367e6cSBorislav Petkov 	.name			= "qpi",
298910e9e7bdSKan Liang 	.num_counters		= 4,
2990ed367e6cSBorislav Petkov 	.num_boxes		= 3,
2991ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2992ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
2993ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
2994ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
2995ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
2996ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2997ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_qpi_ops,
2998ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_qpi_format_group,
2999ed367e6cSBorislav Petkov };
3000ed367e6cSBorislav Petkov 
3001ed367e6cSBorislav Petkov static struct event_constraint hswep_uncore_r2pcie_constraints[] = {
3002ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
3003ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
3004ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
3005ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
3006ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x24, 0x1),
3007ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
3008ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
3009ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x27, 0x1),
3010ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3011ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
3012ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2a, 0x1),
3013ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
3014ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3015ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3016ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
3017ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
3018ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
3019ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
3020ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3021ed367e6cSBorislav Petkov };
3022ed367e6cSBorislav Petkov 
3023ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_r2pcie = {
3024ed367e6cSBorislav Petkov 	.name		= "r2pcie",
3025ed367e6cSBorislav Petkov 	.num_counters   = 4,
3026ed367e6cSBorislav Petkov 	.num_boxes	= 1,
3027ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3028ed367e6cSBorislav Petkov 	.constraints	= hswep_uncore_r2pcie_constraints,
3029ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3030ed367e6cSBorislav Petkov };
3031ed367e6cSBorislav Petkov 
3032ed367e6cSBorislav Petkov static struct event_constraint hswep_uncore_r3qpi_constraints[] = {
3033ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x3),
3034ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
3035ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
3036ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
3037ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
3038ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
3039ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
3040ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
3041ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
3042ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
3043ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
3044ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
3045ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
3046ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
3047ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
3048ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
3049ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
3050ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
3051ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
3052ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3053ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
3054ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3055ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3056ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
3057ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
3058ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
3059ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
3060ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
3061ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
3062ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
3063ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
3064ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
3065ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
3066ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3067ed367e6cSBorislav Petkov };
3068ed367e6cSBorislav Petkov 
3069ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_r3qpi = {
3070ed367e6cSBorislav Petkov 	.name		= "r3qpi",
307110e9e7bdSKan Liang 	.num_counters   = 3,
3072ed367e6cSBorislav Petkov 	.num_boxes	= 3,
3073ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
3074ed367e6cSBorislav Petkov 	.constraints	= hswep_uncore_r3qpi_constraints,
3075ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3076ed367e6cSBorislav Petkov };
3077ed367e6cSBorislav Petkov 
3078ed367e6cSBorislav Petkov enum {
3079ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_HA,
3080ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_IMC,
3081ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_IRP,
3082ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_QPI,
3083ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_R2PCIE,
3084ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_R3QPI,
3085ed367e6cSBorislav Petkov };
3086ed367e6cSBorislav Petkov 
3087ed367e6cSBorislav Petkov static struct intel_uncore_type *hswep_pci_uncores[] = {
3088ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_HA]	= &hswep_uncore_ha,
3089ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_IMC]	= &hswep_uncore_imc,
3090ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_IRP]	= &hswep_uncore_irp,
3091ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_QPI]	= &hswep_uncore_qpi,
3092ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_R2PCIE]	= &hswep_uncore_r2pcie,
3093ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_R3QPI]	= &hswep_uncore_r3qpi,
3094ed367e6cSBorislav Petkov 	NULL,
3095ed367e6cSBorislav Petkov };
3096ed367e6cSBorislav Petkov 
3097ed367e6cSBorislav Petkov static const struct pci_device_id hswep_uncore_pci_ids[] = {
3098ed367e6cSBorislav Petkov 	{ /* Home Agent 0 */
3099ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f30),
3100ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 0),
3101ed367e6cSBorislav Petkov 	},
3102ed367e6cSBorislav Petkov 	{ /* Home Agent 1 */
3103ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f38),
3104ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 1),
3105ed367e6cSBorislav Petkov 	},
3106ed367e6cSBorislav Petkov 	{ /* MC0 Channel 0 */
3107ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb0),
3108ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 0),
3109ed367e6cSBorislav Petkov 	},
3110ed367e6cSBorislav Petkov 	{ /* MC0 Channel 1 */
3111ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb1),
3112ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 1),
3113ed367e6cSBorislav Petkov 	},
3114ed367e6cSBorislav Petkov 	{ /* MC0 Channel 2 */
3115ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb4),
3116ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 2),
3117ed367e6cSBorislav Petkov 	},
3118ed367e6cSBorislav Petkov 	{ /* MC0 Channel 3 */
3119ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb5),
3120ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 3),
3121ed367e6cSBorislav Petkov 	},
3122ed367e6cSBorislav Petkov 	{ /* MC1 Channel 0 */
3123ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd0),
3124ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 4),
3125ed367e6cSBorislav Petkov 	},
3126ed367e6cSBorislav Petkov 	{ /* MC1 Channel 1 */
3127ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd1),
3128ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 5),
3129ed367e6cSBorislav Petkov 	},
3130ed367e6cSBorislav Petkov 	{ /* MC1 Channel 2 */
3131ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd4),
3132ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 6),
3133ed367e6cSBorislav Petkov 	},
3134ed367e6cSBorislav Petkov 	{ /* MC1 Channel 3 */
3135ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd5),
3136ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 7),
3137ed367e6cSBorislav Petkov 	},
3138ed367e6cSBorislav Petkov 	{ /* IRP */
3139ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f39),
3140ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IRP, 0),
3141ed367e6cSBorislav Petkov 	},
3142ed367e6cSBorislav Petkov 	{ /* QPI0 Port 0 */
3143ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f32),
3144ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 0),
3145ed367e6cSBorislav Petkov 	},
3146ed367e6cSBorislav Petkov 	{ /* QPI0 Port 1 */
3147ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f33),
3148ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 1),
3149ed367e6cSBorislav Petkov 	},
3150ed367e6cSBorislav Petkov 	{ /* QPI1 Port 2 */
3151ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3a),
3152ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 2),
3153ed367e6cSBorislav Petkov 	},
3154ed367e6cSBorislav Petkov 	{ /* R2PCIe */
3155ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f34),
3156ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R2PCIE, 0),
3157ed367e6cSBorislav Petkov 	},
3158ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 0 */
3159ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f36),
3160ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 0),
3161ed367e6cSBorislav Petkov 	},
3162ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 1 */
3163ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f37),
3164ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 1),
3165ed367e6cSBorislav Petkov 	},
3166ed367e6cSBorislav Petkov 	{ /* R3QPI1 Link 2 */
3167ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3e),
3168ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 2),
3169ed367e6cSBorislav Petkov 	},
3170ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
3171ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f86),
3172ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3173ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT0_FILTER),
3174ed367e6cSBorislav Petkov 	},
3175ed367e6cSBorislav Petkov 	{ /* QPI Port 1 filter  */
3176ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f96),
3177ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3178ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT1_FILTER),
3179ed367e6cSBorislav Petkov 	},
3180ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
3181ed367e6cSBorislav Petkov };
3182ed367e6cSBorislav Petkov 
3183ed367e6cSBorislav Petkov static struct pci_driver hswep_uncore_pci_driver = {
3184ed367e6cSBorislav Petkov 	.name		= "hswep_uncore",
3185ed367e6cSBorislav Petkov 	.id_table	= hswep_uncore_pci_ids,
3186ed367e6cSBorislav Petkov };
3187ed367e6cSBorislav Petkov 
hswep_uncore_pci_init(void)3188ed367e6cSBorislav Petkov int hswep_uncore_pci_init(void)
3189ed367e6cSBorislav Petkov {
319068ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x2f1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
3191ed367e6cSBorislav Petkov 	if (ret)
3192ed367e6cSBorislav Petkov 		return ret;
3193ed367e6cSBorislav Petkov 	uncore_pci_uncores = hswep_pci_uncores;
3194ed367e6cSBorislav Petkov 	uncore_pci_driver = &hswep_uncore_pci_driver;
3195ed367e6cSBorislav Petkov 	return 0;
3196ed367e6cSBorislav Petkov }
3197ed367e6cSBorislav Petkov /* end of Haswell-EP uncore support */
3198ed367e6cSBorislav Petkov 
3199ed367e6cSBorislav Petkov /* BDX uncore support */
3200ed367e6cSBorislav Petkov 
3201ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_ubox = {
3202ed367e6cSBorislav Petkov 	.name			= "ubox",
3203ed367e6cSBorislav Petkov 	.num_counters		= 2,
3204ed367e6cSBorislav Petkov 	.num_boxes		= 1,
3205ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3206ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
3207ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
3208ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
3209ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
3210ed367e6cSBorislav Petkov 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
3211ed367e6cSBorislav Petkov 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
3212ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
3213ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_msr_ops,
3214ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_ubox_format_group,
3215ed367e6cSBorislav Petkov };
3216ed367e6cSBorislav Petkov 
3217ed367e6cSBorislav Petkov static struct event_constraint bdx_uncore_cbox_constraints[] = {
3218ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
3219ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
3220ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
3221ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
3222ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3223ed367e6cSBorislav Petkov };
3224ed367e6cSBorislav Petkov 
3225ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_cbox = {
3226ed367e6cSBorislav Petkov 	.name			= "cbox",
3227ed367e6cSBorislav Petkov 	.num_counters		= 4,
3228ed367e6cSBorislav Petkov 	.num_boxes		= 24,
3229ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3230ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
3231ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
3232ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
3233ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
3234ed367e6cSBorislav Petkov 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
3235ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
3236ed367e6cSBorislav Petkov 	.constraints		= bdx_uncore_cbox_constraints,
3237ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_cbox_ops,
3238ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_cbox_format_group,
3239ed367e6cSBorislav Petkov };
3240ed367e6cSBorislav Petkov 
3241d7717587SStephane Eranian static struct intel_uncore_type bdx_uncore_sbox = {
3242d7717587SStephane Eranian 	.name			= "sbox",
3243d7717587SStephane Eranian 	.num_counters		= 4,
3244d7717587SStephane Eranian 	.num_boxes		= 4,
3245d7717587SStephane Eranian 	.perf_ctr_bits		= 48,
3246d7717587SStephane Eranian 	.event_ctl		= HSWEP_S0_MSR_PMON_CTL0,
3247d7717587SStephane Eranian 	.perf_ctr		= HSWEP_S0_MSR_PMON_CTR0,
3248d7717587SStephane Eranian 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
3249d7717587SStephane Eranian 	.box_ctl		= HSWEP_S0_MSR_PMON_BOX_CTL,
3250d7717587SStephane Eranian 	.msr_offset		= HSWEP_SBOX_MSR_OFFSET,
3251d7717587SStephane Eranian 	.ops			= &hswep_uncore_sbox_msr_ops,
3252d7717587SStephane Eranian 	.format_group		= &hswep_uncore_sbox_format_group,
3253d7717587SStephane Eranian };
3254d7717587SStephane Eranian 
3255d7717587SStephane Eranian #define BDX_MSR_UNCORE_SBOX	3
3256d7717587SStephane Eranian 
3257ed367e6cSBorislav Petkov static struct intel_uncore_type *bdx_msr_uncores[] = {
3258ed367e6cSBorislav Petkov 	&bdx_uncore_ubox,
3259ed367e6cSBorislav Petkov 	&bdx_uncore_cbox,
3260ed367e6cSBorislav Petkov 	&hswep_uncore_pcu,
3261d7717587SStephane Eranian 	&bdx_uncore_sbox,
3262ed367e6cSBorislav Petkov 	NULL,
3263ed367e6cSBorislav Petkov };
3264ed367e6cSBorislav Petkov 
3265bb9fbe1bSKan Liang /* Bit 7 'Use Occupancy' is not available for counter 0 on BDX */
3266bb9fbe1bSKan Liang static struct event_constraint bdx_uncore_pcu_constraints[] = {
3267bb9fbe1bSKan Liang 	EVENT_CONSTRAINT(0x80, 0xe, 0x80),
3268bb9fbe1bSKan Liang 	EVENT_CONSTRAINT_END
3269bb9fbe1bSKan Liang };
3270bb9fbe1bSKan Liang 
32719d480158SKan Liang #define BDX_PCU_DID			0x6fc0
32729d480158SKan Liang 
bdx_uncore_cpu_init(void)3273ed367e6cSBorislav Petkov void bdx_uncore_cpu_init(void)
3274ed367e6cSBorislav Petkov {
3275ed367e6cSBorislav Petkov 	if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
3276ed367e6cSBorislav Petkov 		bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
3277ed367e6cSBorislav Petkov 	uncore_msr_uncores = bdx_msr_uncores;
3278bb9fbe1bSKan Liang 
327915a3e845SOskar Senft 	/* Detect systems with no SBOXes */
32809d480158SKan Liang 	if ((boot_cpu_data.x86_model == 86) || hswep_has_limit_sbox(BDX_PCU_DID))
32819d480158SKan Liang 		uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
3282d7717587SStephane Eranian 
3283bb9fbe1bSKan Liang 	hswep_uncore_pcu.constraints = bdx_uncore_pcu_constraints;
3284ed367e6cSBorislav Petkov }
3285ed367e6cSBorislav Petkov 
3286ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_ha = {
3287ed367e6cSBorislav Petkov 	.name		= "ha",
3288ed367e6cSBorislav Petkov 	.num_counters   = 4,
3289ed367e6cSBorislav Petkov 	.num_boxes	= 2,
3290ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3291ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3292ed367e6cSBorislav Petkov };
3293ed367e6cSBorislav Petkov 
3294ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_imc = {
3295ed367e6cSBorislav Petkov 	.name		= "imc",
329610e9e7bdSKan Liang 	.num_counters   = 4,
3297ed367e6cSBorislav Petkov 	.num_boxes	= 8,
3298ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3299ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
3300ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
3301ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
3302ed367e6cSBorislav Petkov 	.event_descs	= hswep_uncore_imc_events,
3303ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3304ed367e6cSBorislav Petkov };
3305ed367e6cSBorislav Petkov 
3306ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_irp = {
3307ed367e6cSBorislav Petkov 	.name			= "irp",
3308ed367e6cSBorislav Petkov 	.num_counters		= 4,
3309ed367e6cSBorislav Petkov 	.num_boxes		= 1,
3310ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3311ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
3312ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
3313ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_irp_ops,
3314ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
3315ed367e6cSBorislav Petkov };
3316ed367e6cSBorislav Petkov 
3317ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_qpi = {
3318ed367e6cSBorislav Petkov 	.name			= "qpi",
3319ed367e6cSBorislav Petkov 	.num_counters		= 4,
3320ed367e6cSBorislav Petkov 	.num_boxes		= 3,
3321ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3322ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
3323ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
3324ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
3325ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
3326ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
3327ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_qpi_ops,
3328ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_qpi_format_group,
3329ed367e6cSBorislav Petkov };
3330ed367e6cSBorislav Petkov 
3331ed367e6cSBorislav Petkov static struct event_constraint bdx_uncore_r2pcie_constraints[] = {
3332ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
3333ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
3334ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
3335ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
3336ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
3337ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
3338ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3339ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3340ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3341ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3342ed367e6cSBorislav Petkov };
3343ed367e6cSBorislav Petkov 
3344ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_r2pcie = {
3345ed367e6cSBorislav Petkov 	.name		= "r2pcie",
3346ed367e6cSBorislav Petkov 	.num_counters   = 4,
3347ed367e6cSBorislav Petkov 	.num_boxes	= 1,
3348ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3349ed367e6cSBorislav Petkov 	.constraints	= bdx_uncore_r2pcie_constraints,
3350ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3351ed367e6cSBorislav Petkov };
3352ed367e6cSBorislav Petkov 
3353ed367e6cSBorislav Petkov static struct event_constraint bdx_uncore_r3qpi_constraints[] = {
3354ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x7),
3355ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
3356ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
3357ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
3358ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
3359ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
3360ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
3361ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
3362ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
3363ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
3364ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
3365ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
3366ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
3367ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
3368ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
3369ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
3370ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
3371ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
3372ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3373ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
3374ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3375ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3376ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
3377ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
3378ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
3379ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
3380ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
3381ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
3382ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
3383ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
3384ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3385ed367e6cSBorislav Petkov };
3386ed367e6cSBorislav Petkov 
3387ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_r3qpi = {
3388ed367e6cSBorislav Petkov 	.name		= "r3qpi",
3389ed367e6cSBorislav Petkov 	.num_counters   = 3,
3390ed367e6cSBorislav Petkov 	.num_boxes	= 3,
3391ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3392ed367e6cSBorislav Petkov 	.constraints	= bdx_uncore_r3qpi_constraints,
3393ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3394ed367e6cSBorislav Petkov };
3395ed367e6cSBorislav Petkov 
3396ed367e6cSBorislav Petkov enum {
3397ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_HA,
3398ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_IMC,
3399ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_IRP,
3400ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_QPI,
3401ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_R2PCIE,
3402ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_R3QPI,
3403ed367e6cSBorislav Petkov };
3404ed367e6cSBorislav Petkov 
3405ed367e6cSBorislav Petkov static struct intel_uncore_type *bdx_pci_uncores[] = {
3406ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_HA]	= &bdx_uncore_ha,
3407ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_IMC]	= &bdx_uncore_imc,
3408ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_IRP]	= &bdx_uncore_irp,
3409ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_QPI]	= &bdx_uncore_qpi,
3410ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_R2PCIE]	= &bdx_uncore_r2pcie,
3411ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_R3QPI]	= &bdx_uncore_r3qpi,
3412ed367e6cSBorislav Petkov 	NULL,
3413ed367e6cSBorislav Petkov };
3414ed367e6cSBorislav Petkov 
3415ed367e6cSBorislav Petkov static const struct pci_device_id bdx_uncore_pci_ids[] = {
3416ed367e6cSBorislav Petkov 	{ /* Home Agent 0 */
3417ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f30),
3418ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 0),
3419ed367e6cSBorislav Petkov 	},
3420ed367e6cSBorislav Petkov 	{ /* Home Agent 1 */
3421ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f38),
3422ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 1),
3423ed367e6cSBorislav Petkov 	},
3424ed367e6cSBorislav Petkov 	{ /* MC0 Channel 0 */
3425ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb0),
3426ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 0),
3427ed367e6cSBorislav Petkov 	},
3428ed367e6cSBorislav Petkov 	{ /* MC0 Channel 1 */
3429ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb1),
3430ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 1),
3431ed367e6cSBorislav Petkov 	},
3432ed367e6cSBorislav Petkov 	{ /* MC0 Channel 2 */
3433ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb4),
3434ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 2),
3435ed367e6cSBorislav Petkov 	},
3436ed367e6cSBorislav Petkov 	{ /* MC0 Channel 3 */
3437ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb5),
3438ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 3),
3439ed367e6cSBorislav Petkov 	},
3440ed367e6cSBorislav Petkov 	{ /* MC1 Channel 0 */
3441ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd0),
3442ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 4),
3443ed367e6cSBorislav Petkov 	},
3444ed367e6cSBorislav Petkov 	{ /* MC1 Channel 1 */
3445ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd1),
3446ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 5),
3447ed367e6cSBorislav Petkov 	},
3448ed367e6cSBorislav Petkov 	{ /* MC1 Channel 2 */
3449ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd4),
3450ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 6),
3451ed367e6cSBorislav Petkov 	},
3452ed367e6cSBorislav Petkov 	{ /* MC1 Channel 3 */
3453ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd5),
3454ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 7),
3455ed367e6cSBorislav Petkov 	},
3456ed367e6cSBorislav Petkov 	{ /* IRP */
3457ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f39),
3458ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IRP, 0),
3459ed367e6cSBorislav Petkov 	},
3460ed367e6cSBorislav Petkov 	{ /* QPI0 Port 0 */
3461ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f32),
3462ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 0),
3463ed367e6cSBorislav Petkov 	},
3464ed367e6cSBorislav Petkov 	{ /* QPI0 Port 1 */
3465ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f33),
3466ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 1),
3467ed367e6cSBorislav Petkov 	},
3468ed367e6cSBorislav Petkov 	{ /* QPI1 Port 2 */
3469ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f3a),
3470ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 2),
3471ed367e6cSBorislav Petkov 	},
3472ed367e6cSBorislav Petkov 	{ /* R2PCIe */
3473ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f34),
3474ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R2PCIE, 0),
3475ed367e6cSBorislav Petkov 	},
3476ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 0 */
3477ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f36),
3478ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 0),
3479ed367e6cSBorislav Petkov 	},
3480ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 1 */
3481ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f37),
3482ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 1),
3483ed367e6cSBorislav Petkov 	},
3484ed367e6cSBorislav Petkov 	{ /* R3QPI1 Link 2 */
3485ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f3e),
3486ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 2),
3487ed367e6cSBorislav Petkov 	},
3488ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
3489ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f86),
3490156c8b58SKan Liang 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3491156c8b58SKan Liang 						   SNBEP_PCI_QPI_PORT0_FILTER),
3492ed367e6cSBorislav Petkov 	},
3493ed367e6cSBorislav Petkov 	{ /* QPI Port 1 filter  */
3494ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f96),
3495156c8b58SKan Liang 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3496156c8b58SKan Liang 						   SNBEP_PCI_QPI_PORT1_FILTER),
3497ed367e6cSBorislav Petkov 	},
3498ed367e6cSBorislav Petkov 	{ /* QPI Port 2 filter  */
3499ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f46),
3500156c8b58SKan Liang 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3501156c8b58SKan Liang 						   BDX_PCI_QPI_PORT2_FILTER),
3502ed367e6cSBorislav Petkov 	},
3503ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
3504ed367e6cSBorislav Petkov };
3505ed367e6cSBorislav Petkov 
3506ed367e6cSBorislav Petkov static struct pci_driver bdx_uncore_pci_driver = {
3507ed367e6cSBorislav Petkov 	.name		= "bdx_uncore",
3508ed367e6cSBorislav Petkov 	.id_table	= bdx_uncore_pci_ids,
3509ed367e6cSBorislav Petkov };
3510ed367e6cSBorislav Petkov 
bdx_uncore_pci_init(void)3511ed367e6cSBorislav Petkov int bdx_uncore_pci_init(void)
3512ed367e6cSBorislav Petkov {
351368ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x6f1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
3514ed367e6cSBorislav Petkov 
3515ed367e6cSBorislav Petkov 	if (ret)
3516ed367e6cSBorislav Petkov 		return ret;
3517ed367e6cSBorislav Petkov 	uncore_pci_uncores = bdx_pci_uncores;
3518ed367e6cSBorislav Petkov 	uncore_pci_driver = &bdx_uncore_pci_driver;
3519ed367e6cSBorislav Petkov 	return 0;
3520ed367e6cSBorislav Petkov }
3521ed367e6cSBorislav Petkov 
3522ed367e6cSBorislav Petkov /* end of BDX uncore support */
3523cd34cd97SKan Liang 
3524cd34cd97SKan Liang /* SKX uncore support */
3525cd34cd97SKan Liang 
3526cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_ubox = {
3527cd34cd97SKan Liang 	.name			= "ubox",
3528cd34cd97SKan Liang 	.num_counters		= 2,
3529cd34cd97SKan Liang 	.num_boxes		= 1,
3530cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
3531cd34cd97SKan Liang 	.fixed_ctr_bits		= 48,
3532cd34cd97SKan Liang 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
3533cd34cd97SKan Liang 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
3534cd34cd97SKan Liang 	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
3535cd34cd97SKan Liang 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
3536cd34cd97SKan Liang 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
3537cd34cd97SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
3538cd34cd97SKan Liang 	.format_group		= &ivbep_uncore_ubox_format_group,
3539cd34cd97SKan Liang };
3540cd34cd97SKan Liang 
3541cd34cd97SKan Liang static struct attribute *skx_uncore_cha_formats_attr[] = {
3542cd34cd97SKan Liang 	&format_attr_event.attr,
3543cd34cd97SKan Liang 	&format_attr_umask.attr,
3544cd34cd97SKan Liang 	&format_attr_edge.attr,
3545cd34cd97SKan Liang 	&format_attr_tid_en.attr,
3546cd34cd97SKan Liang 	&format_attr_inv.attr,
3547cd34cd97SKan Liang 	&format_attr_thresh8.attr,
3548cd34cd97SKan Liang 	&format_attr_filter_tid4.attr,
3549cd34cd97SKan Liang 	&format_attr_filter_state5.attr,
3550cd34cd97SKan Liang 	&format_attr_filter_rem.attr,
3551cd34cd97SKan Liang 	&format_attr_filter_loc.attr,
3552cd34cd97SKan Liang 	&format_attr_filter_nm.attr,
3553cd34cd97SKan Liang 	&format_attr_filter_all_op.attr,
3554cd34cd97SKan Liang 	&format_attr_filter_not_nm.attr,
3555cd34cd97SKan Liang 	&format_attr_filter_opc_0.attr,
3556cd34cd97SKan Liang 	&format_attr_filter_opc_1.attr,
3557cd34cd97SKan Liang 	&format_attr_filter_nc.attr,
3558cd34cd97SKan Liang 	&format_attr_filter_isoc.attr,
3559cd34cd97SKan Liang 	NULL,
3560cd34cd97SKan Liang };
3561cd34cd97SKan Liang 
356245bd07adSArvind Yadav static const struct attribute_group skx_uncore_chabox_format_group = {
3563cd34cd97SKan Liang 	.name = "format",
3564cd34cd97SKan Liang 	.attrs = skx_uncore_cha_formats_attr,
3565cd34cd97SKan Liang };
3566cd34cd97SKan Liang 
3567cd34cd97SKan Liang static struct event_constraint skx_uncore_chabox_constraints[] = {
3568cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
3569cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
3570cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
3571cd34cd97SKan Liang };
3572cd34cd97SKan Liang 
3573cd34cd97SKan Liang static struct extra_reg skx_uncore_cha_extra_regs[] = {
3574cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
3575cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
3576cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
3577cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
3578c3f02682SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x3134, 0xffff, 0x4),
3579c3f02682SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x9134, 0xffff, 0x4),
35808aa7b7b4SStephane Eranian 	SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x8),
35818aa7b7b4SStephane Eranian 	SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x8),
3582e340895cSStephane Eranian 	SNBEP_CBO_EVENT_EXTRA_REG(0x38, 0xff, 0x3),
3583ba883b4aSStephane Eranian 	EVENT_EXTRA_END
3584cd34cd97SKan Liang };
3585cd34cd97SKan Liang 
skx_cha_filter_mask(int fields)3586cd34cd97SKan Liang static u64 skx_cha_filter_mask(int fields)
3587cd34cd97SKan Liang {
3588cd34cd97SKan Liang 	u64 mask = 0;
3589cd34cd97SKan Liang 
3590cd34cd97SKan Liang 	if (fields & 0x1)
3591cd34cd97SKan Liang 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_TID;
3592cd34cd97SKan Liang 	if (fields & 0x2)
3593cd34cd97SKan Liang 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_LINK;
3594cd34cd97SKan Liang 	if (fields & 0x4)
3595cd34cd97SKan Liang 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_STATE;
35968aa7b7b4SStephane Eranian 	if (fields & 0x8) {
35978aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_REM;
35988aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_LOC;
35998aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_ALL_OPC;
36008aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NM;
36018aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NOT_NM;
36028aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_OPC0;
36038aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_OPC1;
36048aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NC;
36058aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_ISOC;
36068aa7b7b4SStephane Eranian 	}
3607cd34cd97SKan Liang 	return mask;
3608cd34cd97SKan Liang }
3609cd34cd97SKan Liang 
3610cd34cd97SKan Liang static struct event_constraint *
skx_cha_get_constraint(struct intel_uncore_box * box,struct perf_event * event)3611cd34cd97SKan Liang skx_cha_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
3612cd34cd97SKan Liang {
3613cd34cd97SKan Liang 	return __snbep_cbox_get_constraint(box, event, skx_cha_filter_mask);
3614cd34cd97SKan Liang }
3615cd34cd97SKan Liang 
skx_cha_hw_config(struct intel_uncore_box * box,struct perf_event * event)3616cd34cd97SKan Liang static int skx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
3617cd34cd97SKan Liang {
3618cd34cd97SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
3619cd34cd97SKan Liang 	struct extra_reg *er;
3620cd34cd97SKan Liang 	int idx = 0;
3621e324234eSAlexander Antonov 	/* Any of the CHA events may be filtered by Thread/Core-ID.*/
3622e324234eSAlexander Antonov 	if (event->hw.config & SNBEP_CBO_PMON_CTL_TID_EN)
3623e324234eSAlexander Antonov 		idx = SKX_CHA_MSR_PMON_BOX_FILTER_TID;
3624cd34cd97SKan Liang 
3625cd34cd97SKan Liang 	for (er = skx_uncore_cha_extra_regs; er->msr; er++) {
3626cd34cd97SKan Liang 		if (er->event != (event->hw.config & er->config_mask))
3627cd34cd97SKan Liang 			continue;
3628cd34cd97SKan Liang 		idx |= er->idx;
3629cd34cd97SKan Liang 	}
3630cd34cd97SKan Liang 
3631cd34cd97SKan Liang 	if (idx) {
3632cd34cd97SKan Liang 		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
3633cd34cd97SKan Liang 			    HSWEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
3634cd34cd97SKan Liang 		reg1->config = event->attr.config1 & skx_cha_filter_mask(idx);
3635cd34cd97SKan Liang 		reg1->idx = idx;
3636cd34cd97SKan Liang 	}
3637cd34cd97SKan Liang 	return 0;
3638cd34cd97SKan Liang }
3639cd34cd97SKan Liang 
3640cd34cd97SKan Liang static struct intel_uncore_ops skx_uncore_chabox_ops = {
3641cd34cd97SKan Liang 	/* There is no frz_en for chabox ctl */
3642cd34cd97SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
3643cd34cd97SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
3644cd34cd97SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
3645cd34cd97SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
3646cd34cd97SKan Liang 	.enable_event		= hswep_cbox_enable_event,
3647cd34cd97SKan Liang 	.read_counter		= uncore_msr_read_counter,
3648cd34cd97SKan Liang 	.hw_config		= skx_cha_hw_config,
3649cd34cd97SKan Liang 	.get_constraint		= skx_cha_get_constraint,
3650cd34cd97SKan Liang 	.put_constraint		= snbep_cbox_put_constraint,
3651cd34cd97SKan Liang };
3652cd34cd97SKan Liang 
3653cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_chabox = {
3654cd34cd97SKan Liang 	.name			= "cha",
3655cd34cd97SKan Liang 	.num_counters		= 4,
3656cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
3657cd34cd97SKan Liang 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
3658cd34cd97SKan Liang 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
3659cd34cd97SKan Liang 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
3660cd34cd97SKan Liang 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
3661cd34cd97SKan Liang 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
3662cd34cd97SKan Liang 	.num_shared_regs	= 1,
3663cd34cd97SKan Liang 	.constraints		= skx_uncore_chabox_constraints,
3664cd34cd97SKan Liang 	.ops			= &skx_uncore_chabox_ops,
3665cd34cd97SKan Liang 	.format_group		= &skx_uncore_chabox_format_group,
3666cd34cd97SKan Liang };
3667cd34cd97SKan Liang 
3668cd34cd97SKan Liang static struct attribute *skx_uncore_iio_formats_attr[] = {
3669cd34cd97SKan Liang 	&format_attr_event.attr,
3670cd34cd97SKan Liang 	&format_attr_umask.attr,
3671cd34cd97SKan Liang 	&format_attr_edge.attr,
3672cd34cd97SKan Liang 	&format_attr_inv.attr,
3673cd34cd97SKan Liang 	&format_attr_thresh9.attr,
3674cd34cd97SKan Liang 	&format_attr_ch_mask.attr,
3675cd34cd97SKan Liang 	&format_attr_fc_mask.attr,
3676cd34cd97SKan Liang 	NULL,
3677cd34cd97SKan Liang };
3678cd34cd97SKan Liang 
367945bd07adSArvind Yadav static const struct attribute_group skx_uncore_iio_format_group = {
3680cd34cd97SKan Liang 	.name = "format",
3681cd34cd97SKan Liang 	.attrs = skx_uncore_iio_formats_attr,
3682cd34cd97SKan Liang };
3683cd34cd97SKan Liang 
3684cd34cd97SKan Liang static struct event_constraint skx_uncore_iio_constraints[] = {
3685cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x83, 0x3),
3686cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x88, 0xc),
3687cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x95, 0xc),
3688cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
3689cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc5, 0xc),
3690cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xd4, 0xc),
36913866ae31SAlexander Antonov 	UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
3692cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
3693cd34cd97SKan Liang };
3694cd34cd97SKan Liang 
skx_iio_enable_event(struct intel_uncore_box * box,struct perf_event * event)3695cd34cd97SKan Liang static void skx_iio_enable_event(struct intel_uncore_box *box,
3696cd34cd97SKan Liang 				 struct perf_event *event)
3697cd34cd97SKan Liang {
3698cd34cd97SKan Liang 	struct hw_perf_event *hwc = &event->hw;
3699cd34cd97SKan Liang 
3700cd34cd97SKan Liang 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
3701cd34cd97SKan Liang }
3702cd34cd97SKan Liang 
3703cd34cd97SKan Liang static struct intel_uncore_ops skx_uncore_iio_ops = {
3704cd34cd97SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
3705cd34cd97SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
3706cd34cd97SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
3707cd34cd97SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
3708cd34cd97SKan Liang 	.enable_event		= skx_iio_enable_event,
3709cd34cd97SKan Liang 	.read_counter		= uncore_msr_read_counter,
3710cd34cd97SKan Liang };
3711cd34cd97SKan Liang 
pmu_topology(struct intel_uncore_pmu * pmu,int die)37124d13be8aSAlexander Antonov static struct intel_uncore_topology *pmu_topology(struct intel_uncore_pmu *pmu, int die)
3713bb42b3d3SRoman Sudarikov {
37144d13be8aSAlexander Antonov 	int idx;
37154d13be8aSAlexander Antonov 
37164d13be8aSAlexander Antonov 	for (idx = 0; idx < pmu->type->num_boxes; idx++) {
37174d13be8aSAlexander Antonov 		if (pmu->type->topology[die][idx].pmu_idx == pmu->pmu_idx)
37184d13be8aSAlexander Antonov 			return &pmu->type->topology[die][idx];
37194d13be8aSAlexander Antonov 	}
37204d13be8aSAlexander Antonov 
37214d13be8aSAlexander Antonov 	return NULL;
3722bb42b3d3SRoman Sudarikov }
3723bb42b3d3SRoman Sudarikov 
3724bb42b3d3SRoman Sudarikov static umode_t
pmu_iio_mapping_visible(struct kobject * kobj,struct attribute * attr,int die,int zero_bus_pmu)3725f471fac7SAlexander Antonov pmu_iio_mapping_visible(struct kobject *kobj, struct attribute *attr,
3726f471fac7SAlexander Antonov 			 int die, int zero_bus_pmu)
3727bb42b3d3SRoman Sudarikov {
3728bb42b3d3SRoman Sudarikov 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(kobj_to_dev(kobj));
37294d13be8aSAlexander Antonov 	struct intel_uncore_topology *pmut = pmu_topology(pmu, die);
3730bb42b3d3SRoman Sudarikov 
37314d13be8aSAlexander Antonov 	return (pmut && !pmut->iio->pci_bus_no && pmu->pmu_idx != zero_bus_pmu) ? 0 : attr->mode;
3732f471fac7SAlexander Antonov }
3733f471fac7SAlexander Antonov 
3734f471fac7SAlexander Antonov static umode_t
skx_iio_mapping_visible(struct kobject * kobj,struct attribute * attr,int die)3735f471fac7SAlexander Antonov skx_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
3736f471fac7SAlexander Antonov {
3737f471fac7SAlexander Antonov 	/* Root bus 0x00 is valid only for pmu_idx = 0. */
3738f471fac7SAlexander Antonov 	return pmu_iio_mapping_visible(kobj, attr, die, 0);
3739bb42b3d3SRoman Sudarikov }
3740bb42b3d3SRoman Sudarikov 
skx_iio_mapping_show(struct device * dev,struct device_attribute * attr,char * buf)3741bb42b3d3SRoman Sudarikov static ssize_t skx_iio_mapping_show(struct device *dev,
3742bb42b3d3SRoman Sudarikov 				    struct device_attribute *attr, char *buf)
3743bb42b3d3SRoman Sudarikov {
3744cface032SAlexander Antonov 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(dev);
3745bb42b3d3SRoman Sudarikov 	struct dev_ext_attribute *ea = to_dev_ext_attribute(attr);
3746bb42b3d3SRoman Sudarikov 	long die = (long)ea->var;
37474d13be8aSAlexander Antonov 	struct intel_uncore_topology *pmut = pmu_topology(pmu, die);
3748bb42b3d3SRoman Sudarikov 
37494d13be8aSAlexander Antonov 	return sprintf(buf, "%04x:%02x\n", pmut ? pmut->iio->segment : 0,
37504d13be8aSAlexander Antonov 					   pmut ? pmut->iio->pci_bus_no : 0);
3751bb42b3d3SRoman Sudarikov }
3752bb42b3d3SRoman Sudarikov 
skx_msr_cpu_bus_read(int cpu,u64 * topology)3753bb42b3d3SRoman Sudarikov static int skx_msr_cpu_bus_read(int cpu, u64 *topology)
3754bb42b3d3SRoman Sudarikov {
3755bb42b3d3SRoman Sudarikov 	u64 msr_value;
3756bb42b3d3SRoman Sudarikov 
3757bb42b3d3SRoman Sudarikov 	if (rdmsrl_on_cpu(cpu, SKX_MSR_CPU_BUS_NUMBER, &msr_value) ||
3758bb42b3d3SRoman Sudarikov 			!(msr_value & SKX_MSR_CPU_BUS_VALID_BIT))
3759bb42b3d3SRoman Sudarikov 		return -ENXIO;
3760bb42b3d3SRoman Sudarikov 
3761bb42b3d3SRoman Sudarikov 	*topology = msr_value;
3762bb42b3d3SRoman Sudarikov 
3763bb42b3d3SRoman Sudarikov 	return 0;
3764bb42b3d3SRoman Sudarikov }
3765bb42b3d3SRoman Sudarikov 
die_to_cpu(int die)3766bb42b3d3SRoman Sudarikov static int die_to_cpu(int die)
3767bb42b3d3SRoman Sudarikov {
3768bb42b3d3SRoman Sudarikov 	int res = 0, cpu, current_die;
3769bb42b3d3SRoman Sudarikov 	/*
3770bb42b3d3SRoman Sudarikov 	 * Using cpus_read_lock() to ensure cpu is not going down between
3771bb42b3d3SRoman Sudarikov 	 * looking at cpu_online_mask.
3772bb42b3d3SRoman Sudarikov 	 */
3773bb42b3d3SRoman Sudarikov 	cpus_read_lock();
3774bb42b3d3SRoman Sudarikov 	for_each_online_cpu(cpu) {
3775bb42b3d3SRoman Sudarikov 		current_die = topology_logical_die_id(cpu);
3776bb42b3d3SRoman Sudarikov 		if (current_die == die) {
3777bb42b3d3SRoman Sudarikov 			res = cpu;
3778bb42b3d3SRoman Sudarikov 			break;
3779bb42b3d3SRoman Sudarikov 		}
3780bb42b3d3SRoman Sudarikov 	}
3781bb42b3d3SRoman Sudarikov 	cpus_read_unlock();
3782bb42b3d3SRoman Sudarikov 	return res;
3783bb42b3d3SRoman Sudarikov }
3784bb42b3d3SRoman Sudarikov 
37854d13be8aSAlexander Antonov enum {
37864d13be8aSAlexander Antonov 	IIO_TOPOLOGY_TYPE,
3787cee4eebdSAlexander Antonov 	UPI_TOPOLOGY_TYPE,
37884d13be8aSAlexander Antonov 	TOPOLOGY_MAX
37894d13be8aSAlexander Antonov };
37904d13be8aSAlexander Antonov 
37914d13be8aSAlexander Antonov static const size_t topology_size[TOPOLOGY_MAX] = {
3792cee4eebdSAlexander Antonov 	sizeof(*((struct intel_uncore_topology *)NULL)->iio),
3793cee4eebdSAlexander Antonov 	sizeof(*((struct intel_uncore_topology *)NULL)->upi)
37944d13be8aSAlexander Antonov };
37954d13be8aSAlexander Antonov 
pmu_alloc_topology(struct intel_uncore_type * type,int topology_type)37964d13be8aSAlexander Antonov static int pmu_alloc_topology(struct intel_uncore_type *type, int topology_type)
37974d13be8aSAlexander Antonov {
37984d13be8aSAlexander Antonov 	int die, idx;
37994d13be8aSAlexander Antonov 	struct intel_uncore_topology **topology;
38004d13be8aSAlexander Antonov 
38014d13be8aSAlexander Antonov 	if (!type->num_boxes)
38024d13be8aSAlexander Antonov 		return -EPERM;
38034d13be8aSAlexander Antonov 
38044d13be8aSAlexander Antonov 	topology = kcalloc(uncore_max_dies(), sizeof(*topology), GFP_KERNEL);
38054d13be8aSAlexander Antonov 	if (!topology)
38064d13be8aSAlexander Antonov 		goto err;
38074d13be8aSAlexander Antonov 
38084d13be8aSAlexander Antonov 	for (die = 0; die < uncore_max_dies(); die++) {
38094d13be8aSAlexander Antonov 		topology[die] = kcalloc(type->num_boxes, sizeof(**topology), GFP_KERNEL);
38104d13be8aSAlexander Antonov 		if (!topology[die])
38114d13be8aSAlexander Antonov 			goto clear;
38124d13be8aSAlexander Antonov 		for (idx = 0; idx < type->num_boxes; idx++) {
38134d13be8aSAlexander Antonov 			topology[die][idx].untyped = kcalloc(type->num_boxes,
38144d13be8aSAlexander Antonov 							     topology_size[topology_type],
38154d13be8aSAlexander Antonov 							     GFP_KERNEL);
38164d13be8aSAlexander Antonov 			if (!topology[die][idx].untyped)
38174d13be8aSAlexander Antonov 				goto clear;
38184d13be8aSAlexander Antonov 		}
38194d13be8aSAlexander Antonov 	}
38204d13be8aSAlexander Antonov 
38214d13be8aSAlexander Antonov 	type->topology = topology;
38224d13be8aSAlexander Antonov 
38234d13be8aSAlexander Antonov 	return 0;
38244d13be8aSAlexander Antonov clear:
38254d13be8aSAlexander Antonov 	for (; die >= 0; die--) {
38264d13be8aSAlexander Antonov 		for (idx = 0; idx < type->num_boxes; idx++)
38274d13be8aSAlexander Antonov 			kfree(topology[die][idx].untyped);
38284d13be8aSAlexander Antonov 		kfree(topology[die]);
38294d13be8aSAlexander Antonov 	}
38304d13be8aSAlexander Antonov 	kfree(topology);
38314d13be8aSAlexander Antonov err:
38324d13be8aSAlexander Antonov 	return -ENOMEM;
38334d13be8aSAlexander Antonov }
38344d13be8aSAlexander Antonov 
pmu_free_topology(struct intel_uncore_type * type)38354d13be8aSAlexander Antonov static void pmu_free_topology(struct intel_uncore_type *type)
38364d13be8aSAlexander Antonov {
38374d13be8aSAlexander Antonov 	int die, idx;
38384d13be8aSAlexander Antonov 
38394d13be8aSAlexander Antonov 	if (type->topology) {
38404d13be8aSAlexander Antonov 		for (die = 0; die < uncore_max_dies(); die++) {
38414d13be8aSAlexander Antonov 			for (idx = 0; idx < type->num_boxes; idx++)
38424d13be8aSAlexander Antonov 				kfree(type->topology[die][idx].untyped);
38434d13be8aSAlexander Antonov 			kfree(type->topology[die]);
38444d13be8aSAlexander Antonov 		}
38454d13be8aSAlexander Antonov 		kfree(type->topology);
38464d13be8aSAlexander Antonov 		type->topology = NULL;
38474d13be8aSAlexander Antonov 	}
38484d13be8aSAlexander Antonov }
38494d13be8aSAlexander Antonov 
skx_pmu_get_topology(struct intel_uncore_type * type,int (* topology_cb)(struct intel_uncore_type *,int,int,u64))385007813e2aSAlexander Antonov static int skx_pmu_get_topology(struct intel_uncore_type *type,
385107813e2aSAlexander Antonov 				 int (*topology_cb)(struct intel_uncore_type*, int, int, u64))
3852bb42b3d3SRoman Sudarikov {
3853cface032SAlexander Antonov 	int die, ret = -EPERM;
385407813e2aSAlexander Antonov 	u64 cpu_bus_msr;
3855bb42b3d3SRoman Sudarikov 
3856cface032SAlexander Antonov 	for (die = 0; die < uncore_max_dies(); die++) {
385707813e2aSAlexander Antonov 		ret = skx_msr_cpu_bus_read(die_to_cpu(die), &cpu_bus_msr);
3858cface032SAlexander Antonov 		if (ret)
3859cface032SAlexander Antonov 			break;
3860cface032SAlexander Antonov 
3861cface032SAlexander Antonov 		ret = uncore_die_to_segment(die);
3862cface032SAlexander Antonov 		if (ret < 0)
3863cface032SAlexander Antonov 			break;
3864cface032SAlexander Antonov 
386507813e2aSAlexander Antonov 		ret = topology_cb(type, ret, die, cpu_bus_msr);
386607813e2aSAlexander Antonov 		if (ret)
386707813e2aSAlexander Antonov 			break;
3868cface032SAlexander Antonov 	}
3869cface032SAlexander Antonov 
3870cface032SAlexander Antonov 	return ret;
3871bb42b3d3SRoman Sudarikov }
3872bb42b3d3SRoman Sudarikov 
skx_iio_topology_cb(struct intel_uncore_type * type,int segment,int die,u64 cpu_bus_msr)387307813e2aSAlexander Antonov static int skx_iio_topology_cb(struct intel_uncore_type *type, int segment,
387407813e2aSAlexander Antonov 				int die, u64 cpu_bus_msr)
387507813e2aSAlexander Antonov {
387607813e2aSAlexander Antonov 	int idx;
387707813e2aSAlexander Antonov 	struct intel_uncore_topology *t;
387807813e2aSAlexander Antonov 
387907813e2aSAlexander Antonov 	for (idx = 0; idx < type->num_boxes; idx++) {
388007813e2aSAlexander Antonov 		t = &type->topology[die][idx];
388107813e2aSAlexander Antonov 		t->pmu_idx = idx;
388207813e2aSAlexander Antonov 		t->iio->segment = segment;
388307813e2aSAlexander Antonov 		t->iio->pci_bus_no = (cpu_bus_msr >> (idx * BUS_NUM_STRIDE)) & 0xff;
388407813e2aSAlexander Antonov 	}
388507813e2aSAlexander Antonov 
388607813e2aSAlexander Antonov 	return 0;
388707813e2aSAlexander Antonov }
388807813e2aSAlexander Antonov 
skx_iio_get_topology(struct intel_uncore_type * type)388907813e2aSAlexander Antonov static int skx_iio_get_topology(struct intel_uncore_type *type)
389007813e2aSAlexander Antonov {
389107813e2aSAlexander Antonov 	return skx_pmu_get_topology(type, skx_iio_topology_cb);
389207813e2aSAlexander Antonov }
389307813e2aSAlexander Antonov 
3894bb42b3d3SRoman Sudarikov static struct attribute_group skx_iio_mapping_group = {
3895bb42b3d3SRoman Sudarikov 	.is_visible	= skx_iio_mapping_visible,
3896bb42b3d3SRoman Sudarikov };
3897bb42b3d3SRoman Sudarikov 
3898bb42b3d3SRoman Sudarikov static const struct attribute_group *skx_iio_attr_update[] = {
3899bb42b3d3SRoman Sudarikov 	&skx_iio_mapping_group,
3900bb42b3d3SRoman Sudarikov 	NULL,
3901bb42b3d3SRoman Sudarikov };
3902bb42b3d3SRoman Sudarikov 
pmu_clear_mapping_attr(const struct attribute_group ** groups,struct attribute_group * ag)390365327833SAlexander Antonov static void pmu_clear_mapping_attr(const struct attribute_group **groups,
390465327833SAlexander Antonov 				   struct attribute_group *ag)
390565327833SAlexander Antonov {
390665327833SAlexander Antonov 	int i;
390765327833SAlexander Antonov 
390865327833SAlexander Antonov 	for (i = 0; groups[i]; i++) {
390965327833SAlexander Antonov 		if (groups[i] == ag) {
391065327833SAlexander Antonov 			for (i++; groups[i]; i++)
391165327833SAlexander Antonov 				groups[i - 1] = groups[i];
391265327833SAlexander Antonov 			groups[i - 1] = NULL;
391365327833SAlexander Antonov 			break;
391465327833SAlexander Antonov 		}
391565327833SAlexander Antonov 	}
391665327833SAlexander Antonov }
391765327833SAlexander Antonov 
3918d5b73506SAlexander Antonov static void
pmu_set_mapping(struct intel_uncore_type * type,struct attribute_group * ag,ssize_t (* show)(struct device *,struct device_attribute *,char *),int topology_type)39194d13be8aSAlexander Antonov pmu_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag,
39204d13be8aSAlexander Antonov 		ssize_t (*show)(struct device*, struct device_attribute*, char*),
39214d13be8aSAlexander Antonov 		int topology_type)
3922bb42b3d3SRoman Sudarikov {
3923bb42b3d3SRoman Sudarikov 	char buf[64];
3924bb42b3d3SRoman Sudarikov 	int ret;
3925bb42b3d3SRoman Sudarikov 	long die = -1;
3926bb42b3d3SRoman Sudarikov 	struct attribute **attrs = NULL;
3927bb42b3d3SRoman Sudarikov 	struct dev_ext_attribute *eas = NULL;
3928bb42b3d3SRoman Sudarikov 
39294d13be8aSAlexander Antonov 	ret = pmu_alloc_topology(type, topology_type);
3930cface032SAlexander Antonov 	if (ret < 0)
3931f797f05dSAlexander Antonov 		goto clear_attr_update;
3932f797f05dSAlexander Antonov 
39334d13be8aSAlexander Antonov 	ret = type->get_topology(type);
39344d13be8aSAlexander Antonov 	if (ret < 0)
39354d13be8aSAlexander Antonov 		goto clear_topology;
39364d13be8aSAlexander Antonov 
3937bb42b3d3SRoman Sudarikov 	/* One more for NULL. */
3938bb42b3d3SRoman Sudarikov 	attrs = kcalloc((uncore_max_dies() + 1), sizeof(*attrs), GFP_KERNEL);
3939bb42b3d3SRoman Sudarikov 	if (!attrs)
3940d4ba0b06SKan Liang 		goto clear_topology;
3941bb42b3d3SRoman Sudarikov 
3942bb42b3d3SRoman Sudarikov 	eas = kcalloc(uncore_max_dies(), sizeof(*eas), GFP_KERNEL);
3943bb42b3d3SRoman Sudarikov 	if (!eas)
3944d4ba0b06SKan Liang 		goto clear_attrs;
3945bb42b3d3SRoman Sudarikov 
3946bb42b3d3SRoman Sudarikov 	for (die = 0; die < uncore_max_dies(); die++) {
39474d13be8aSAlexander Antonov 		snprintf(buf, sizeof(buf), "die%ld", die);
3948bb42b3d3SRoman Sudarikov 		sysfs_attr_init(&eas[die].attr.attr);
3949bb42b3d3SRoman Sudarikov 		eas[die].attr.attr.name = kstrdup(buf, GFP_KERNEL);
3950bb42b3d3SRoman Sudarikov 		if (!eas[die].attr.attr.name)
3951bb42b3d3SRoman Sudarikov 			goto err;
3952bb42b3d3SRoman Sudarikov 		eas[die].attr.attr.mode = 0444;
39534d13be8aSAlexander Antonov 		eas[die].attr.show = show;
3954bb42b3d3SRoman Sudarikov 		eas[die].attr.store = NULL;
3955bb42b3d3SRoman Sudarikov 		eas[die].var = (void *)die;
3956bb42b3d3SRoman Sudarikov 		attrs[die] = &eas[die].attr.attr;
3957bb42b3d3SRoman Sudarikov 	}
3958f471fac7SAlexander Antonov 	ag->attrs = attrs;
3959bb42b3d3SRoman Sudarikov 
3960d5b73506SAlexander Antonov 	return;
3961bb42b3d3SRoman Sudarikov err:
3962bb42b3d3SRoman Sudarikov 	for (; die >= 0; die--)
3963bb42b3d3SRoman Sudarikov 		kfree(eas[die].attr.attr.name);
3964bb42b3d3SRoman Sudarikov 	kfree(eas);
3965d4ba0b06SKan Liang clear_attrs:
3966bb42b3d3SRoman Sudarikov 	kfree(attrs);
3967d4ba0b06SKan Liang clear_topology:
39684d13be8aSAlexander Antonov 	pmu_free_topology(type);
3969f797f05dSAlexander Antonov clear_attr_update:
397065327833SAlexander Antonov 	pmu_clear_mapping_attr(type->attr_update, ag);
3971bb42b3d3SRoman Sudarikov }
3972bb42b3d3SRoman Sudarikov 
39733f2cbe38SAlexander Antonov static void
pmu_cleanup_mapping(struct intel_uncore_type * type,struct attribute_group * ag)39744d13be8aSAlexander Antonov pmu_cleanup_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
39753f2cbe38SAlexander Antonov {
39763f2cbe38SAlexander Antonov 	struct attribute **attr = ag->attrs;
39773f2cbe38SAlexander Antonov 
39783f2cbe38SAlexander Antonov 	if (!attr)
39793f2cbe38SAlexander Antonov 		return;
39803f2cbe38SAlexander Antonov 
39813f2cbe38SAlexander Antonov 	for (; *attr; attr++)
39823f2cbe38SAlexander Antonov 		kfree((*attr)->name);
39833f2cbe38SAlexander Antonov 	kfree(attr_to_ext_attr(*ag->attrs));
39843f2cbe38SAlexander Antonov 	kfree(ag->attrs);
39853f2cbe38SAlexander Antonov 	ag->attrs = NULL;
39864d13be8aSAlexander Antonov 	pmu_free_topology(type);
39874d13be8aSAlexander Antonov }
39884d13be8aSAlexander Antonov 
3989d5b73506SAlexander Antonov static void
pmu_iio_set_mapping(struct intel_uncore_type * type,struct attribute_group * ag)39904d13be8aSAlexander Antonov pmu_iio_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
39914d13be8aSAlexander Antonov {
3992d5b73506SAlexander Antonov 	pmu_set_mapping(type, ag, skx_iio_mapping_show, IIO_TOPOLOGY_TYPE);
39933f2cbe38SAlexander Antonov }
39943f2cbe38SAlexander Antonov 
skx_iio_set_mapping(struct intel_uncore_type * type)3995d5b73506SAlexander Antonov static void skx_iio_set_mapping(struct intel_uncore_type *type)
3996f471fac7SAlexander Antonov {
3997d5b73506SAlexander Antonov 	pmu_iio_set_mapping(type, &skx_iio_mapping_group);
3998f471fac7SAlexander Antonov }
3999f471fac7SAlexander Antonov 
skx_iio_cleanup_mapping(struct intel_uncore_type * type)4000bb42b3d3SRoman Sudarikov static void skx_iio_cleanup_mapping(struct intel_uncore_type *type)
4001bb42b3d3SRoman Sudarikov {
40024d13be8aSAlexander Antonov 	pmu_cleanup_mapping(type, &skx_iio_mapping_group);
4003bb42b3d3SRoman Sudarikov }
4004bb42b3d3SRoman Sudarikov 
4005cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_iio = {
4006cd34cd97SKan Liang 	.name			= "iio",
4007cd34cd97SKan Liang 	.num_counters		= 4,
400829b46dfbSKan Liang 	.num_boxes		= 6,
4009cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
4010cd34cd97SKan Liang 	.event_ctl		= SKX_IIO0_MSR_PMON_CTL0,
4011cd34cd97SKan Liang 	.perf_ctr		= SKX_IIO0_MSR_PMON_CTR0,
4012cd34cd97SKan Liang 	.event_mask		= SKX_IIO_PMON_RAW_EVENT_MASK,
4013cd34cd97SKan Liang 	.event_mask_ext		= SKX_IIO_PMON_RAW_EVENT_MASK_EXT,
4014cd34cd97SKan Liang 	.box_ctl		= SKX_IIO0_MSR_PMON_BOX_CTL,
4015cd34cd97SKan Liang 	.msr_offset		= SKX_IIO_MSR_OFFSET,
4016cd34cd97SKan Liang 	.constraints		= skx_uncore_iio_constraints,
4017cd34cd97SKan Liang 	.ops			= &skx_uncore_iio_ops,
4018cd34cd97SKan Liang 	.format_group		= &skx_uncore_iio_format_group,
4019bb42b3d3SRoman Sudarikov 	.attr_update		= skx_iio_attr_update,
4020f471fac7SAlexander Antonov 	.get_topology		= skx_iio_get_topology,
4021bb42b3d3SRoman Sudarikov 	.set_mapping		= skx_iio_set_mapping,
4022bb42b3d3SRoman Sudarikov 	.cleanup_mapping	= skx_iio_cleanup_mapping,
4023cd34cd97SKan Liang };
4024cd34cd97SKan Liang 
40250f519f03SKan Liang enum perf_uncore_iio_freerunning_type_id {
40260f519f03SKan Liang 	SKX_IIO_MSR_IOCLK			= 0,
40270f519f03SKan Liang 	SKX_IIO_MSR_BW				= 1,
40280f519f03SKan Liang 	SKX_IIO_MSR_UTIL			= 2,
40290f519f03SKan Liang 
40300f519f03SKan Liang 	SKX_IIO_FREERUNNING_TYPE_MAX,
40310f519f03SKan Liang };
40320f519f03SKan Liang 
40330f519f03SKan Liang 
40340f519f03SKan Liang static struct freerunning_counters skx_iio_freerunning[] = {
40350f519f03SKan Liang 	[SKX_IIO_MSR_IOCLK]	= { 0xa45, 0x1, 0x20, 1, 36 },
40360f519f03SKan Liang 	[SKX_IIO_MSR_BW]	= { 0xb00, 0x1, 0x10, 8, 36 },
40370f519f03SKan Liang 	[SKX_IIO_MSR_UTIL]	= { 0xb08, 0x1, 0x10, 8, 36 },
40380f519f03SKan Liang };
40390f519f03SKan Liang 
40400f519f03SKan Liang static struct uncore_event_desc skx_uncore_iio_freerunning_events[] = {
40410f519f03SKan Liang 	/* Free-Running IO CLOCKS Counter */
40420f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
40430f519f03SKan Liang 	/* Free-Running IIO BANDWIDTH Counters */
40440f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
40450f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
40460f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
40470f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
40480f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
40490f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
40500f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
40510f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
40520f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
40530f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
40540f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
40550f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
40560f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0,		"event=0xff,umask=0x24"),
40570f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.scale,	"3.814697266e-6"),
40580f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.unit,	"MiB"),
40590f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1,		"event=0xff,umask=0x25"),
40600f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.scale,	"3.814697266e-6"),
40610f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.unit,	"MiB"),
40620f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2,		"event=0xff,umask=0x26"),
40630f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.scale,	"3.814697266e-6"),
40640f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.unit,	"MiB"),
40650f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3,		"event=0xff,umask=0x27"),
40660f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.scale,	"3.814697266e-6"),
40670f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.unit,	"MiB"),
40680f519f03SKan Liang 	/* Free-running IIO UTILIZATION Counters */
40690f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port0,		"event=0xff,umask=0x30"),
40700f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port0,		"event=0xff,umask=0x31"),
40710f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port1,		"event=0xff,umask=0x32"),
40720f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port1,		"event=0xff,umask=0x33"),
40730f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port2,		"event=0xff,umask=0x34"),
40740f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port2,		"event=0xff,umask=0x35"),
40750f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port3,		"event=0xff,umask=0x36"),
40760f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port3,		"event=0xff,umask=0x37"),
40770f519f03SKan Liang 	{ /* end: all zeroes */ },
40780f519f03SKan Liang };
40790f519f03SKan Liang 
40800f519f03SKan Liang static struct intel_uncore_ops skx_uncore_iio_freerunning_ops = {
40810f519f03SKan Liang 	.read_counter		= uncore_msr_read_counter,
4082543ac280SKan Liang 	.hw_config		= uncore_freerunning_hw_config,
40830f519f03SKan Liang };
40840f519f03SKan Liang 
40850f519f03SKan Liang static struct attribute *skx_uncore_iio_freerunning_formats_attr[] = {
40860f519f03SKan Liang 	&format_attr_event.attr,
40870f519f03SKan Liang 	&format_attr_umask.attr,
40880f519f03SKan Liang 	NULL,
40890f519f03SKan Liang };
40900f519f03SKan Liang 
40910f519f03SKan Liang static const struct attribute_group skx_uncore_iio_freerunning_format_group = {
40920f519f03SKan Liang 	.name = "format",
40930f519f03SKan Liang 	.attrs = skx_uncore_iio_freerunning_formats_attr,
40940f519f03SKan Liang };
40950f519f03SKan Liang 
40960f519f03SKan Liang static struct intel_uncore_type skx_uncore_iio_free_running = {
40970f519f03SKan Liang 	.name			= "iio_free_running",
40980f519f03SKan Liang 	.num_counters		= 17,
40990f519f03SKan Liang 	.num_boxes		= 6,
41000f519f03SKan Liang 	.num_freerunning_types	= SKX_IIO_FREERUNNING_TYPE_MAX,
41010f519f03SKan Liang 	.freerunning		= skx_iio_freerunning,
41020f519f03SKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
41030f519f03SKan Liang 	.event_descs		= skx_uncore_iio_freerunning_events,
41040f519f03SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
41050f519f03SKan Liang };
41060f519f03SKan Liang 
4107cd34cd97SKan Liang static struct attribute *skx_uncore_formats_attr[] = {
4108cd34cd97SKan Liang 	&format_attr_event.attr,
4109cd34cd97SKan Liang 	&format_attr_umask.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_uncore_format_group = {
4117cd34cd97SKan Liang 	.name = "format",
4118cd34cd97SKan Liang 	.attrs = skx_uncore_formats_attr,
4119cd34cd97SKan Liang };
4120cd34cd97SKan Liang 
4121cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_irp = {
4122cd34cd97SKan Liang 	.name			= "irp",
4123cd34cd97SKan Liang 	.num_counters		= 2,
412429b46dfbSKan Liang 	.num_boxes		= 6,
4125cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
4126cd34cd97SKan Liang 	.event_ctl		= SKX_IRP0_MSR_PMON_CTL0,
4127cd34cd97SKan Liang 	.perf_ctr		= SKX_IRP0_MSR_PMON_CTR0,
4128cd34cd97SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4129cd34cd97SKan Liang 	.box_ctl		= SKX_IRP0_MSR_PMON_BOX_CTL,
4130cd34cd97SKan Liang 	.msr_offset		= SKX_IRP_MSR_OFFSET,
4131cd34cd97SKan Liang 	.ops			= &skx_uncore_iio_ops,
4132cd34cd97SKan Liang 	.format_group		= &skx_uncore_format_group,
4133cd34cd97SKan Liang };
4134cd34cd97SKan Liang 
4135bab4e569SKan Liang static struct attribute *skx_uncore_pcu_formats_attr[] = {
4136bab4e569SKan Liang 	&format_attr_event.attr,
4137bab4e569SKan Liang 	&format_attr_umask.attr,
4138bab4e569SKan Liang 	&format_attr_edge.attr,
4139bab4e569SKan Liang 	&format_attr_inv.attr,
4140bab4e569SKan Liang 	&format_attr_thresh8.attr,
4141bab4e569SKan Liang 	&format_attr_occ_invert.attr,
4142bab4e569SKan Liang 	&format_attr_occ_edge_det.attr,
4143bab4e569SKan Liang 	&format_attr_filter_band0.attr,
4144bab4e569SKan Liang 	&format_attr_filter_band1.attr,
4145bab4e569SKan Liang 	&format_attr_filter_band2.attr,
4146bab4e569SKan Liang 	&format_attr_filter_band3.attr,
4147bab4e569SKan Liang 	NULL,
4148bab4e569SKan Liang };
4149bab4e569SKan Liang 
4150bab4e569SKan Liang static struct attribute_group skx_uncore_pcu_format_group = {
4151bab4e569SKan Liang 	.name = "format",
4152bab4e569SKan Liang 	.attrs = skx_uncore_pcu_formats_attr,
4153bab4e569SKan Liang };
4154bab4e569SKan Liang 
4155cd34cd97SKan Liang static struct intel_uncore_ops skx_uncore_pcu_ops = {
4156cd34cd97SKan Liang 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
4157cd34cd97SKan Liang 	.hw_config		= hswep_pcu_hw_config,
4158cd34cd97SKan Liang 	.get_constraint		= snbep_pcu_get_constraint,
4159cd34cd97SKan Liang 	.put_constraint		= snbep_pcu_put_constraint,
4160cd34cd97SKan Liang };
4161cd34cd97SKan Liang 
4162cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_pcu = {
4163cd34cd97SKan Liang 	.name			= "pcu",
4164cd34cd97SKan Liang 	.num_counters		= 4,
4165cd34cd97SKan Liang 	.num_boxes		= 1,
4166cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
4167cd34cd97SKan Liang 	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
4168cd34cd97SKan Liang 	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
4169cd34cd97SKan Liang 	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
4170cd34cd97SKan Liang 	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
4171cd34cd97SKan Liang 	.num_shared_regs	= 1,
4172cd34cd97SKan Liang 	.ops			= &skx_uncore_pcu_ops,
4173bab4e569SKan Liang 	.format_group		= &skx_uncore_pcu_format_group,
4174cd34cd97SKan Liang };
4175cd34cd97SKan Liang 
4176cd34cd97SKan Liang static struct intel_uncore_type *skx_msr_uncores[] = {
4177cd34cd97SKan Liang 	&skx_uncore_ubox,
4178cd34cd97SKan Liang 	&skx_uncore_chabox,
4179cd34cd97SKan Liang 	&skx_uncore_iio,
41800f519f03SKan Liang 	&skx_uncore_iio_free_running,
4181cd34cd97SKan Liang 	&skx_uncore_irp,
4182cd34cd97SKan Liang 	&skx_uncore_pcu,
4183cd34cd97SKan Liang 	NULL,
4184cd34cd97SKan Liang };
4185cd34cd97SKan Liang 
4186320b0651SKan Liang /*
4187320b0651SKan Liang  * To determine the number of CHAs, it should read bits 27:0 in the CAPID6
4188320b0651SKan Liang  * register which located at Device 30, Function 3, Offset 0x9C. PCI ID 0x2083.
4189320b0651SKan Liang  */
4190320b0651SKan Liang #define SKX_CAPID6		0x9c
4191320b0651SKan Liang #define SKX_CHA_BIT_MASK	GENMASK(27, 0)
4192320b0651SKan Liang 
skx_count_chabox(void)4193cd34cd97SKan Liang static int skx_count_chabox(void)
4194cd34cd97SKan Liang {
4195320b0651SKan Liang 	struct pci_dev *dev = NULL;
4196320b0651SKan Liang 	u32 val = 0;
4197cd34cd97SKan Liang 
4198320b0651SKan Liang 	dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x2083, dev);
4199320b0651SKan Liang 	if (!dev)
4200320b0651SKan Liang 		goto out;
4201cd34cd97SKan Liang 
4202320b0651SKan Liang 	pci_read_config_dword(dev, SKX_CAPID6, &val);
4203320b0651SKan Liang 	val &= SKX_CHA_BIT_MASK;
4204320b0651SKan Liang out:
4205320b0651SKan Liang 	pci_dev_put(dev);
4206320b0651SKan Liang 	return hweight32(val);
4207cd34cd97SKan Liang }
4208cd34cd97SKan Liang 
skx_uncore_cpu_init(void)4209cd34cd97SKan Liang void skx_uncore_cpu_init(void)
4210cd34cd97SKan Liang {
4211cd34cd97SKan Liang 	skx_uncore_chabox.num_boxes = skx_count_chabox();
4212cd34cd97SKan Liang 	uncore_msr_uncores = skx_msr_uncores;
4213cd34cd97SKan Liang }
4214cd34cd97SKan Liang 
4215cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_imc = {
4216cd34cd97SKan Liang 	.name		= "imc",
4217cd34cd97SKan Liang 	.num_counters   = 4,
4218cd34cd97SKan Liang 	.num_boxes	= 6,
4219cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4220cd34cd97SKan Liang 	.fixed_ctr_bits	= 48,
4221cd34cd97SKan Liang 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
4222cd34cd97SKan Liang 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
4223cd34cd97SKan Liang 	.event_descs	= hswep_uncore_imc_events,
4224cd34cd97SKan Liang 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,
4225cd34cd97SKan Liang 	.event_ctl	= SNBEP_PCI_PMON_CTL0,
4226cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4227cd34cd97SKan Liang 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,
4228cd34cd97SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
4229cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4230cd34cd97SKan Liang };
4231cd34cd97SKan Liang 
4232cd34cd97SKan Liang static struct attribute *skx_upi_uncore_formats_attr[] = {
423331766094SKan Liang 	&format_attr_event.attr,
4234cd34cd97SKan Liang 	&format_attr_umask_ext.attr,
4235cd34cd97SKan Liang 	&format_attr_edge.attr,
4236cd34cd97SKan Liang 	&format_attr_inv.attr,
4237cd34cd97SKan Liang 	&format_attr_thresh8.attr,
4238cd34cd97SKan Liang 	NULL,
4239cd34cd97SKan Liang };
4240cd34cd97SKan Liang 
424145bd07adSArvind Yadav static const struct attribute_group skx_upi_uncore_format_group = {
4242cd34cd97SKan Liang 	.name = "format",
4243cd34cd97SKan Liang 	.attrs = skx_upi_uncore_formats_attr,
4244cd34cd97SKan Liang };
4245cd34cd97SKan Liang 
skx_upi_uncore_pci_init_box(struct intel_uncore_box * box)4246cd34cd97SKan Liang static void skx_upi_uncore_pci_init_box(struct intel_uncore_box *box)
4247cd34cd97SKan Liang {
4248cd34cd97SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4249cd34cd97SKan Liang 
4250cd34cd97SKan Liang 	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
4251cd34cd97SKan Liang 	pci_write_config_dword(pdev, SKX_UPI_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
4252cd34cd97SKan Liang }
4253cd34cd97SKan Liang 
4254cd34cd97SKan Liang static struct intel_uncore_ops skx_upi_uncore_pci_ops = {
4255cd34cd97SKan Liang 	.init_box	= skx_upi_uncore_pci_init_box,
4256cd34cd97SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
4257cd34cd97SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
4258cd34cd97SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
4259cd34cd97SKan Liang 	.enable_event	= snbep_uncore_pci_enable_event,
4260cd34cd97SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
4261cd34cd97SKan Liang };
4262cd34cd97SKan Liang 
42634cfce57fSAlexander Antonov static umode_t
skx_upi_mapping_visible(struct kobject * kobj,struct attribute * attr,int die)42644cfce57fSAlexander Antonov skx_upi_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
42654cfce57fSAlexander Antonov {
42664cfce57fSAlexander Antonov 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(kobj_to_dev(kobj));
42674cfce57fSAlexander Antonov 
42684cfce57fSAlexander Antonov 	return pmu->type->topology[die][pmu->pmu_idx].upi->enabled ? attr->mode : 0;
42694cfce57fSAlexander Antonov }
42704cfce57fSAlexander Antonov 
skx_upi_mapping_show(struct device * dev,struct device_attribute * attr,char * buf)42714cfce57fSAlexander Antonov static ssize_t skx_upi_mapping_show(struct device *dev,
42724cfce57fSAlexander Antonov 				    struct device_attribute *attr, char *buf)
42734cfce57fSAlexander Antonov {
42744cfce57fSAlexander Antonov 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(dev);
42754cfce57fSAlexander Antonov 	struct dev_ext_attribute *ea = to_dev_ext_attribute(attr);
42764cfce57fSAlexander Antonov 	long die = (long)ea->var;
42774cfce57fSAlexander Antonov 	struct uncore_upi_topology *upi = pmu->type->topology[die][pmu->pmu_idx].upi;
42784cfce57fSAlexander Antonov 
42794cfce57fSAlexander Antonov 	return sysfs_emit(buf, "upi_%d,die_%d\n", upi->pmu_idx_to, upi->die_to);
42804cfce57fSAlexander Antonov }
42814cfce57fSAlexander Antonov 
42824cfce57fSAlexander Antonov #define SKX_UPI_REG_DID			0x2058
42834cfce57fSAlexander Antonov #define SKX_UPI_REGS_ADDR_DEVICE_LINK0	0x0e
42844cfce57fSAlexander Antonov #define SKX_UPI_REGS_ADDR_FUNCTION	0x00
42854cfce57fSAlexander Antonov 
42864cfce57fSAlexander Antonov /*
42874cfce57fSAlexander Antonov  * UPI Link Parameter 0
42884cfce57fSAlexander Antonov  * |  Bit  |  Default  |  Description
42894cfce57fSAlexander Antonov  * | 19:16 |     0h    | base_nodeid - The NodeID of the sending socket.
42904cfce57fSAlexander Antonov  * | 12:8  |    00h    | sending_port - The processor die port number of the sending port.
42914cfce57fSAlexander Antonov  */
42924cfce57fSAlexander Antonov #define SKX_KTILP0_OFFSET	0x94
42934cfce57fSAlexander Antonov 
42944cfce57fSAlexander Antonov /*
42954cfce57fSAlexander Antonov  * UPI Pcode Status. This register is used by PCode to store the link training status.
42964cfce57fSAlexander Antonov  * |  Bit  |  Default  |  Description
42974cfce57fSAlexander Antonov  * |   4   |     0h    | ll_status_valid — Bit indicates the valid training status
42984cfce57fSAlexander Antonov  *                       logged from PCode to the BIOS.
42994cfce57fSAlexander Antonov  */
43004cfce57fSAlexander Antonov #define SKX_KTIPCSTS_OFFSET	0x120
43014cfce57fSAlexander Antonov 
upi_fill_topology(struct pci_dev * dev,struct intel_uncore_topology * tp,int pmu_idx)43024cfce57fSAlexander Antonov static int upi_fill_topology(struct pci_dev *dev, struct intel_uncore_topology *tp,
43034cfce57fSAlexander Antonov 			     int pmu_idx)
43044cfce57fSAlexander Antonov {
43054cfce57fSAlexander Antonov 	int ret;
43064cfce57fSAlexander Antonov 	u32 upi_conf;
43074cfce57fSAlexander Antonov 	struct uncore_upi_topology *upi = tp->upi;
43084cfce57fSAlexander Antonov 
43094cfce57fSAlexander Antonov 	tp->pmu_idx = pmu_idx;
43104cfce57fSAlexander Antonov 	ret = pci_read_config_dword(dev, SKX_KTIPCSTS_OFFSET, &upi_conf);
43114cfce57fSAlexander Antonov 	if (ret) {
43124cfce57fSAlexander Antonov 		ret = pcibios_err_to_errno(ret);
43134cfce57fSAlexander Antonov 		goto err;
43144cfce57fSAlexander Antonov 	}
43154cfce57fSAlexander Antonov 	upi->enabled = (upi_conf >> 4) & 1;
43164cfce57fSAlexander Antonov 	if (upi->enabled) {
43174cfce57fSAlexander Antonov 		ret = pci_read_config_dword(dev, SKX_KTILP0_OFFSET,
43184cfce57fSAlexander Antonov 					    &upi_conf);
43194cfce57fSAlexander Antonov 		if (ret) {
43204cfce57fSAlexander Antonov 			ret = pcibios_err_to_errno(ret);
43214cfce57fSAlexander Antonov 			goto err;
43224cfce57fSAlexander Antonov 		}
43234cfce57fSAlexander Antonov 		upi->die_to = (upi_conf >> 16) & 0xf;
43244cfce57fSAlexander Antonov 		upi->pmu_idx_to = (upi_conf >> 8) & 0x1f;
43254cfce57fSAlexander Antonov 	}
43264cfce57fSAlexander Antonov err:
43274cfce57fSAlexander Antonov 	return ret;
43284cfce57fSAlexander Antonov }
43294cfce57fSAlexander Antonov 
skx_upi_topology_cb(struct intel_uncore_type * type,int segment,int die,u64 cpu_bus_msr)43304cfce57fSAlexander Antonov static int skx_upi_topology_cb(struct intel_uncore_type *type, int segment,
43314cfce57fSAlexander Antonov 				int die, u64 cpu_bus_msr)
43324cfce57fSAlexander Antonov {
43334cfce57fSAlexander Antonov 	int idx, ret;
43344cfce57fSAlexander Antonov 	struct intel_uncore_topology *upi;
43354cfce57fSAlexander Antonov 	unsigned int devfn;
43364cfce57fSAlexander Antonov 	struct pci_dev *dev = NULL;
43374cfce57fSAlexander Antonov 	u8 bus = cpu_bus_msr >> (3 * BUS_NUM_STRIDE);
43384cfce57fSAlexander Antonov 
43394cfce57fSAlexander Antonov 	for (idx = 0; idx < type->num_boxes; idx++) {
43404cfce57fSAlexander Antonov 		upi = &type->topology[die][idx];
43414cfce57fSAlexander Antonov 		devfn = PCI_DEVFN(SKX_UPI_REGS_ADDR_DEVICE_LINK0 + idx,
43424cfce57fSAlexander Antonov 				  SKX_UPI_REGS_ADDR_FUNCTION);
43434cfce57fSAlexander Antonov 		dev = pci_get_domain_bus_and_slot(segment, bus, devfn);
43444cfce57fSAlexander Antonov 		if (dev) {
43454cfce57fSAlexander Antonov 			ret = upi_fill_topology(dev, upi, idx);
43464cfce57fSAlexander Antonov 			if (ret)
43474cfce57fSAlexander Antonov 				break;
43484cfce57fSAlexander Antonov 		}
43494cfce57fSAlexander Antonov 	}
43504cfce57fSAlexander Antonov 
43514cfce57fSAlexander Antonov 	pci_dev_put(dev);
43524cfce57fSAlexander Antonov 	return ret;
43534cfce57fSAlexander Antonov }
43544cfce57fSAlexander Antonov 
skx_upi_get_topology(struct intel_uncore_type * type)43554cfce57fSAlexander Antonov static int skx_upi_get_topology(struct intel_uncore_type *type)
43564cfce57fSAlexander Antonov {
43574cfce57fSAlexander Antonov 	/* CPX case is not supported */
43584cfce57fSAlexander Antonov 	if (boot_cpu_data.x86_stepping == 11)
43594cfce57fSAlexander Antonov 		return -EPERM;
43604cfce57fSAlexander Antonov 
43614cfce57fSAlexander Antonov 	return skx_pmu_get_topology(type, skx_upi_topology_cb);
43624cfce57fSAlexander Antonov }
43634cfce57fSAlexander Antonov 
43644cfce57fSAlexander Antonov static struct attribute_group skx_upi_mapping_group = {
43654cfce57fSAlexander Antonov 	.is_visible	= skx_upi_mapping_visible,
43664cfce57fSAlexander Antonov };
43674cfce57fSAlexander Antonov 
43684cfce57fSAlexander Antonov static const struct attribute_group *skx_upi_attr_update[] = {
43694cfce57fSAlexander Antonov 	&skx_upi_mapping_group,
43704cfce57fSAlexander Antonov 	NULL
43714cfce57fSAlexander Antonov };
43724cfce57fSAlexander Antonov 
4373d5b73506SAlexander Antonov static void
pmu_upi_set_mapping(struct intel_uncore_type * type,struct attribute_group * ag)43744cfce57fSAlexander Antonov pmu_upi_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
43754cfce57fSAlexander Antonov {
4376d5b73506SAlexander Antonov 	pmu_set_mapping(type, ag, skx_upi_mapping_show, UPI_TOPOLOGY_TYPE);
43774cfce57fSAlexander Antonov }
43784cfce57fSAlexander Antonov 
skx_upi_set_mapping(struct intel_uncore_type * type)4379d5b73506SAlexander Antonov static void skx_upi_set_mapping(struct intel_uncore_type *type)
43804cfce57fSAlexander Antonov {
4381d5b73506SAlexander Antonov 	pmu_upi_set_mapping(type, &skx_upi_mapping_group);
43824cfce57fSAlexander Antonov }
43834cfce57fSAlexander Antonov 
skx_upi_cleanup_mapping(struct intel_uncore_type * type)43844cfce57fSAlexander Antonov static void skx_upi_cleanup_mapping(struct intel_uncore_type *type)
43854cfce57fSAlexander Antonov {
43864cfce57fSAlexander Antonov 	pmu_cleanup_mapping(type, &skx_upi_mapping_group);
43874cfce57fSAlexander Antonov }
43884cfce57fSAlexander Antonov 
4389cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_upi = {
4390cd34cd97SKan Liang 	.name		= "upi",
4391cd34cd97SKan Liang 	.num_counters   = 4,
4392cd34cd97SKan Liang 	.num_boxes	= 3,
4393cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4394cd34cd97SKan Liang 	.perf_ctr	= SKX_UPI_PCI_PMON_CTR0,
4395cd34cd97SKan Liang 	.event_ctl	= SKX_UPI_PCI_PMON_CTL0,
4396b3625980SStephane Eranian 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4397b3625980SStephane Eranian 	.event_mask_ext = SKX_UPI_CTL_UMASK_EXT,
4398cd34cd97SKan Liang 	.box_ctl	= SKX_UPI_PCI_PMON_BOX_CTL,
4399cd34cd97SKan Liang 	.ops		= &skx_upi_uncore_pci_ops,
4400cd34cd97SKan Liang 	.format_group	= &skx_upi_uncore_format_group,
44014cfce57fSAlexander Antonov 	.attr_update	= skx_upi_attr_update,
44024cfce57fSAlexander Antonov 	.get_topology	= skx_upi_get_topology,
44034cfce57fSAlexander Antonov 	.set_mapping	= skx_upi_set_mapping,
44044cfce57fSAlexander Antonov 	.cleanup_mapping = skx_upi_cleanup_mapping,
4405cd34cd97SKan Liang };
4406cd34cd97SKan Liang 
skx_m2m_uncore_pci_init_box(struct intel_uncore_box * box)4407cd34cd97SKan Liang static void skx_m2m_uncore_pci_init_box(struct intel_uncore_box *box)
4408cd34cd97SKan Liang {
4409cd34cd97SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4410cd34cd97SKan Liang 
4411cd34cd97SKan Liang 	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
4412cd34cd97SKan Liang 	pci_write_config_dword(pdev, SKX_M2M_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
4413cd34cd97SKan Liang }
4414cd34cd97SKan Liang 
4415cd34cd97SKan Liang static struct intel_uncore_ops skx_m2m_uncore_pci_ops = {
4416cd34cd97SKan Liang 	.init_box	= skx_m2m_uncore_pci_init_box,
4417cd34cd97SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
4418cd34cd97SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
4419cd34cd97SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
4420cd34cd97SKan Liang 	.enable_event	= snbep_uncore_pci_enable_event,
4421cd34cd97SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
4422cd34cd97SKan Liang };
4423cd34cd97SKan Liang 
4424cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_m2m = {
4425cd34cd97SKan Liang 	.name		= "m2m",
4426cd34cd97SKan Liang 	.num_counters   = 4,
4427cd34cd97SKan Liang 	.num_boxes	= 2,
4428cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4429cd34cd97SKan Liang 	.perf_ctr	= SKX_M2M_PCI_PMON_CTR0,
4430cd34cd97SKan Liang 	.event_ctl	= SKX_M2M_PCI_PMON_CTL0,
4431cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4432cd34cd97SKan Liang 	.box_ctl	= SKX_M2M_PCI_PMON_BOX_CTL,
4433cd34cd97SKan Liang 	.ops		= &skx_m2m_uncore_pci_ops,
4434cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4435cd34cd97SKan Liang };
4436cd34cd97SKan Liang 
4437cd34cd97SKan Liang static struct event_constraint skx_uncore_m2pcie_constraints[] = {
4438cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
4439cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
4440cd34cd97SKan Liang };
4441cd34cd97SKan Liang 
4442cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_m2pcie = {
4443cd34cd97SKan Liang 	.name		= "m2pcie",
4444cd34cd97SKan Liang 	.num_counters   = 4,
4445cd34cd97SKan Liang 	.num_boxes	= 4,
4446cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4447cd34cd97SKan Liang 	.constraints	= skx_uncore_m2pcie_constraints,
4448cd34cd97SKan Liang 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,
4449cd34cd97SKan Liang 	.event_ctl	= SNBEP_PCI_PMON_CTL0,
4450cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4451cd34cd97SKan Liang 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,
4452cd34cd97SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
4453cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4454cd34cd97SKan Liang };
4455cd34cd97SKan Liang 
4456cd34cd97SKan Liang static struct event_constraint skx_uncore_m3upi_constraints[] = {
4457cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
4458cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
4459cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
4460cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
4461cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
4462cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
4463cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x51, 0x7),
4464cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x52, 0x7),
4465cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
4466cd34cd97SKan Liang };
4467cd34cd97SKan Liang 
4468cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_m3upi = {
4469cd34cd97SKan Liang 	.name		= "m3upi",
4470cd34cd97SKan Liang 	.num_counters   = 3,
4471cd34cd97SKan Liang 	.num_boxes	= 3,
4472cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4473cd34cd97SKan Liang 	.constraints	= skx_uncore_m3upi_constraints,
4474cd34cd97SKan Liang 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,
4475cd34cd97SKan Liang 	.event_ctl	= SNBEP_PCI_PMON_CTL0,
4476cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4477cd34cd97SKan Liang 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,
4478cd34cd97SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
4479cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4480cd34cd97SKan Liang };
4481cd34cd97SKan Liang 
4482cd34cd97SKan Liang enum {
4483cd34cd97SKan Liang 	SKX_PCI_UNCORE_IMC,
4484cd34cd97SKan Liang 	SKX_PCI_UNCORE_M2M,
4485cd34cd97SKan Liang 	SKX_PCI_UNCORE_UPI,
4486cd34cd97SKan Liang 	SKX_PCI_UNCORE_M2PCIE,
4487cd34cd97SKan Liang 	SKX_PCI_UNCORE_M3UPI,
4488cd34cd97SKan Liang };
4489cd34cd97SKan Liang 
4490cd34cd97SKan Liang static struct intel_uncore_type *skx_pci_uncores[] = {
4491cd34cd97SKan Liang 	[SKX_PCI_UNCORE_IMC]	= &skx_uncore_imc,
4492cd34cd97SKan Liang 	[SKX_PCI_UNCORE_M2M]	= &skx_uncore_m2m,
4493cd34cd97SKan Liang 	[SKX_PCI_UNCORE_UPI]	= &skx_uncore_upi,
4494cd34cd97SKan Liang 	[SKX_PCI_UNCORE_M2PCIE]	= &skx_uncore_m2pcie,
4495cd34cd97SKan Liang 	[SKX_PCI_UNCORE_M3UPI]	= &skx_uncore_m3upi,
4496cd34cd97SKan Liang 	NULL,
4497cd34cd97SKan Liang };
4498cd34cd97SKan Liang 
4499cd34cd97SKan Liang static const struct pci_device_id skx_uncore_pci_ids[] = {
4500cd34cd97SKan Liang 	{ /* MC0 Channel 0 */
4501cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2042),
4502cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(10, 2, SKX_PCI_UNCORE_IMC, 0),
4503cd34cd97SKan Liang 	},
4504cd34cd97SKan Liang 	{ /* MC0 Channel 1 */
4505cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2046),
4506cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(10, 6, SKX_PCI_UNCORE_IMC, 1),
4507cd34cd97SKan Liang 	},
4508cd34cd97SKan Liang 	{ /* MC0 Channel 2 */
4509cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204a),
4510cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(11, 2, SKX_PCI_UNCORE_IMC, 2),
4511cd34cd97SKan Liang 	},
4512cd34cd97SKan Liang 	{ /* MC1 Channel 0 */
4513cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2042),
4514cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 2, SKX_PCI_UNCORE_IMC, 3),
4515cd34cd97SKan Liang 	},
4516cd34cd97SKan Liang 	{ /* MC1 Channel 1 */
4517cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2046),
4518cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 6, SKX_PCI_UNCORE_IMC, 4),
4519cd34cd97SKan Liang 	},
4520cd34cd97SKan Liang 	{ /* MC1 Channel 2 */
4521cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204a),
4522cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(13, 2, SKX_PCI_UNCORE_IMC, 5),
4523cd34cd97SKan Liang 	},
4524cd34cd97SKan Liang 	{ /* M2M0 */
4525cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2066),
4526cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 0, SKX_PCI_UNCORE_M2M, 0),
4527cd34cd97SKan Liang 	},
4528cd34cd97SKan Liang 	{ /* M2M1 */
4529cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2066),
4530cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 0, SKX_PCI_UNCORE_M2M, 1),
4531cd34cd97SKan Liang 	},
4532cd34cd97SKan Liang 	{ /* UPI0 Link 0 */
4533cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058),
4534cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(14, 0, SKX_PCI_UNCORE_UPI, 0),
4535cd34cd97SKan Liang 	},
4536cd34cd97SKan Liang 	{ /* UPI0 Link 1 */
4537cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058),
4538cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(15, 0, SKX_PCI_UNCORE_UPI, 1),
4539cd34cd97SKan Liang 	},
4540cd34cd97SKan Liang 	{ /* UPI1 Link 2 */
4541cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058),
4542cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(16, 0, SKX_PCI_UNCORE_UPI, 2),
4543cd34cd97SKan Liang 	},
4544cd34cd97SKan Liang 	{ /* M2PCIe 0 */
4545cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4546cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 1, SKX_PCI_UNCORE_M2PCIE, 0),
4547cd34cd97SKan Liang 	},
4548cd34cd97SKan Liang 	{ /* M2PCIe 1 */
4549cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4550cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(22, 1, SKX_PCI_UNCORE_M2PCIE, 1),
4551cd34cd97SKan Liang 	},
4552cd34cd97SKan Liang 	{ /* M2PCIe 2 */
4553cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4554cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(23, 1, SKX_PCI_UNCORE_M2PCIE, 2),
4555cd34cd97SKan Liang 	},
4556cd34cd97SKan Liang 	{ /* M2PCIe 3 */
4557cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4558cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 5, SKX_PCI_UNCORE_M2PCIE, 3),
4559cd34cd97SKan Liang 	},
4560cd34cd97SKan Liang 	{ /* M3UPI0 Link 0 */
45619d92cfeaSKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204D),
45629d92cfeaSKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 1, SKX_PCI_UNCORE_M3UPI, 0),
4563cd34cd97SKan Liang 	},
4564cd34cd97SKan Liang 	{ /* M3UPI0 Link 1 */
45659d92cfeaSKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204E),
45669d92cfeaSKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 2, SKX_PCI_UNCORE_M3UPI, 1),
4567cd34cd97SKan Liang 	},
4568cd34cd97SKan Liang 	{ /* M3UPI1 Link 2 */
45699d92cfeaSKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204D),
45709d92cfeaSKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 5, SKX_PCI_UNCORE_M3UPI, 2),
4571cd34cd97SKan Liang 	},
4572cd34cd97SKan Liang 	{ /* end: all zeroes */ }
4573cd34cd97SKan Liang };
4574cd34cd97SKan Liang 
4575cd34cd97SKan Liang 
4576cd34cd97SKan Liang static struct pci_driver skx_uncore_pci_driver = {
4577cd34cd97SKan Liang 	.name		= "skx_uncore",
4578cd34cd97SKan Liang 	.id_table	= skx_uncore_pci_ids,
4579cd34cd97SKan Liang };
4580cd34cd97SKan Liang 
skx_uncore_pci_init(void)4581cd34cd97SKan Liang int skx_uncore_pci_init(void)
4582cd34cd97SKan Liang {
4583cd34cd97SKan Liang 	/* need to double check pci address */
4584cd34cd97SKan Liang 	int ret = snbep_pci2phy_map_init(0x2014, SKX_CPUNODEID, SKX_GIDNIDMAP, false);
4585cd34cd97SKan Liang 
4586cd34cd97SKan Liang 	if (ret)
4587cd34cd97SKan Liang 		return ret;
4588cd34cd97SKan Liang 
4589cd34cd97SKan Liang 	uncore_pci_uncores = skx_pci_uncores;
4590cd34cd97SKan Liang 	uncore_pci_driver = &skx_uncore_pci_driver;
4591cd34cd97SKan Liang 	return 0;
4592cd34cd97SKan Liang }
4593cd34cd97SKan Liang 
4594cd34cd97SKan Liang /* end of SKX uncore support */
4595210cc5f9SKan Liang 
4596210cc5f9SKan Liang /* SNR uncore support */
4597210cc5f9SKan Liang 
4598210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_ubox = {
4599210cc5f9SKan Liang 	.name			= "ubox",
4600210cc5f9SKan Liang 	.num_counters		= 2,
4601210cc5f9SKan Liang 	.num_boxes		= 1,
4602210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4603210cc5f9SKan Liang 	.fixed_ctr_bits		= 48,
4604210cc5f9SKan Liang 	.perf_ctr		= SNR_U_MSR_PMON_CTR0,
4605210cc5f9SKan Liang 	.event_ctl		= SNR_U_MSR_PMON_CTL0,
4606210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4607210cc5f9SKan Liang 	.fixed_ctr		= SNR_U_MSR_PMON_UCLK_FIXED_CTR,
4608210cc5f9SKan Liang 	.fixed_ctl		= SNR_U_MSR_PMON_UCLK_FIXED_CTL,
4609210cc5f9SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
4610210cc5f9SKan Liang 	.format_group		= &ivbep_uncore_format_group,
4611210cc5f9SKan Liang };
4612210cc5f9SKan Liang 
4613210cc5f9SKan Liang static struct attribute *snr_uncore_cha_formats_attr[] = {
4614210cc5f9SKan Liang 	&format_attr_event.attr,
4615210cc5f9SKan Liang 	&format_attr_umask_ext2.attr,
4616210cc5f9SKan Liang 	&format_attr_edge.attr,
4617210cc5f9SKan Liang 	&format_attr_tid_en.attr,
4618210cc5f9SKan Liang 	&format_attr_inv.attr,
4619210cc5f9SKan Liang 	&format_attr_thresh8.attr,
4620210cc5f9SKan Liang 	&format_attr_filter_tid5.attr,
4621210cc5f9SKan Liang 	NULL,
4622210cc5f9SKan Liang };
4623210cc5f9SKan Liang static const struct attribute_group snr_uncore_chabox_format_group = {
4624210cc5f9SKan Liang 	.name = "format",
4625210cc5f9SKan Liang 	.attrs = snr_uncore_cha_formats_attr,
4626210cc5f9SKan Liang };
4627210cc5f9SKan Liang 
snr_cha_hw_config(struct intel_uncore_box * box,struct perf_event * event)4628210cc5f9SKan Liang static int snr_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
4629210cc5f9SKan Liang {
4630210cc5f9SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
4631210cc5f9SKan Liang 
4632210cc5f9SKan Liang 	reg1->reg = SNR_C0_MSR_PMON_BOX_FILTER0 +
4633210cc5f9SKan Liang 		    box->pmu->type->msr_offset * box->pmu->pmu_idx;
4634210cc5f9SKan Liang 	reg1->config = event->attr.config1 & SKX_CHA_MSR_PMON_BOX_FILTER_TID;
4635210cc5f9SKan Liang 	reg1->idx = 0;
4636210cc5f9SKan Liang 
4637210cc5f9SKan Liang 	return 0;
4638210cc5f9SKan Liang }
4639210cc5f9SKan Liang 
snr_cha_enable_event(struct intel_uncore_box * box,struct perf_event * event)4640210cc5f9SKan Liang static void snr_cha_enable_event(struct intel_uncore_box *box,
4641210cc5f9SKan Liang 				   struct perf_event *event)
4642210cc5f9SKan Liang {
4643210cc5f9SKan Liang 	struct hw_perf_event *hwc = &event->hw;
4644210cc5f9SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
4645210cc5f9SKan Liang 
4646210cc5f9SKan Liang 	if (reg1->idx != EXTRA_REG_NONE)
4647210cc5f9SKan Liang 		wrmsrl(reg1->reg, reg1->config);
4648210cc5f9SKan Liang 
4649210cc5f9SKan Liang 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
4650210cc5f9SKan Liang }
4651210cc5f9SKan Liang 
4652210cc5f9SKan Liang static struct intel_uncore_ops snr_uncore_chabox_ops = {
4653210cc5f9SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
4654210cc5f9SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
4655210cc5f9SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
4656210cc5f9SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
4657210cc5f9SKan Liang 	.enable_event		= snr_cha_enable_event,
4658210cc5f9SKan Liang 	.read_counter		= uncore_msr_read_counter,
4659210cc5f9SKan Liang 	.hw_config		= snr_cha_hw_config,
4660210cc5f9SKan Liang };
4661210cc5f9SKan Liang 
4662210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_chabox = {
4663210cc5f9SKan Liang 	.name			= "cha",
4664210cc5f9SKan Liang 	.num_counters		= 4,
4665210cc5f9SKan Liang 	.num_boxes		= 6,
4666210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4667210cc5f9SKan Liang 	.event_ctl		= SNR_CHA_MSR_PMON_CTL0,
4668210cc5f9SKan Liang 	.perf_ctr		= SNR_CHA_MSR_PMON_CTR0,
4669210cc5f9SKan Liang 	.box_ctl		= SNR_CHA_MSR_PMON_BOX_CTL,
4670210cc5f9SKan Liang 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
4671210cc5f9SKan Liang 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
4672210cc5f9SKan Liang 	.event_mask_ext		= SNR_CHA_RAW_EVENT_MASK_EXT,
4673210cc5f9SKan Liang 	.ops			= &snr_uncore_chabox_ops,
4674210cc5f9SKan Liang 	.format_group		= &snr_uncore_chabox_format_group,
4675210cc5f9SKan Liang };
4676210cc5f9SKan Liang 
4677210cc5f9SKan Liang static struct attribute *snr_uncore_iio_formats_attr[] = {
4678210cc5f9SKan Liang 	&format_attr_event.attr,
4679210cc5f9SKan Liang 	&format_attr_umask.attr,
4680210cc5f9SKan Liang 	&format_attr_edge.attr,
4681210cc5f9SKan Liang 	&format_attr_inv.attr,
4682210cc5f9SKan Liang 	&format_attr_thresh9.attr,
4683210cc5f9SKan Liang 	&format_attr_ch_mask2.attr,
4684210cc5f9SKan Liang 	&format_attr_fc_mask2.attr,
4685210cc5f9SKan Liang 	NULL,
4686210cc5f9SKan Liang };
4687210cc5f9SKan Liang 
4688210cc5f9SKan Liang static const struct attribute_group snr_uncore_iio_format_group = {
4689210cc5f9SKan Liang 	.name = "format",
4690210cc5f9SKan Liang 	.attrs = snr_uncore_iio_formats_attr,
4691210cc5f9SKan Liang };
4692210cc5f9SKan Liang 
4693c1777be3SAlexander Antonov static umode_t
snr_iio_mapping_visible(struct kobject * kobj,struct attribute * attr,int die)4694c1777be3SAlexander Antonov snr_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
4695c1777be3SAlexander Antonov {
4696c1777be3SAlexander Antonov 	/* Root bus 0x00 is valid only for pmu_idx = 1. */
4697c1777be3SAlexander Antonov 	return pmu_iio_mapping_visible(kobj, attr, die, 1);
4698c1777be3SAlexander Antonov }
4699c1777be3SAlexander Antonov 
4700c1777be3SAlexander Antonov static struct attribute_group snr_iio_mapping_group = {
4701c1777be3SAlexander Antonov 	.is_visible	= snr_iio_mapping_visible,
4702c1777be3SAlexander Antonov };
4703c1777be3SAlexander Antonov 
4704c1777be3SAlexander Antonov static const struct attribute_group *snr_iio_attr_update[] = {
4705c1777be3SAlexander Antonov 	&snr_iio_mapping_group,
4706c1777be3SAlexander Antonov 	NULL,
4707c1777be3SAlexander Antonov };
4708c1777be3SAlexander Antonov 
sad_cfg_iio_topology(struct intel_uncore_type * type,u8 * sad_pmon_mapping)4709c1777be3SAlexander Antonov static int sad_cfg_iio_topology(struct intel_uncore_type *type, u8 *sad_pmon_mapping)
4710c1777be3SAlexander Antonov {
4711c1777be3SAlexander Antonov 	u32 sad_cfg;
4712c1777be3SAlexander Antonov 	int die, stack_id, ret = -EPERM;
4713c1777be3SAlexander Antonov 	struct pci_dev *dev = NULL;
4714c1777be3SAlexander Antonov 
4715c1777be3SAlexander Antonov 	while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, SNR_ICX_MESH2IIO_MMAP_DID, dev))) {
4716c1777be3SAlexander Antonov 		ret = pci_read_config_dword(dev, SNR_ICX_SAD_CONTROL_CFG, &sad_cfg);
4717c1777be3SAlexander Antonov 		if (ret) {
4718c1777be3SAlexander Antonov 			ret = pcibios_err_to_errno(ret);
4719c1777be3SAlexander Antonov 			break;
4720c1777be3SAlexander Antonov 		}
4721c1777be3SAlexander Antonov 
4722c1777be3SAlexander Antonov 		die = uncore_pcibus_to_dieid(dev->bus);
4723c1777be3SAlexander Antonov 		stack_id = SAD_CONTROL_STACK_ID(sad_cfg);
4724c1777be3SAlexander Antonov 		if (die < 0 || stack_id >= type->num_boxes) {
4725c1777be3SAlexander Antonov 			ret = -EPERM;
4726c1777be3SAlexander Antonov 			break;
4727c1777be3SAlexander Antonov 		}
4728c1777be3SAlexander Antonov 
4729c1777be3SAlexander Antonov 		/* Convert stack id from SAD_CONTROL to PMON notation. */
4730c1777be3SAlexander Antonov 		stack_id = sad_pmon_mapping[stack_id];
4731c1777be3SAlexander Antonov 
47324d13be8aSAlexander Antonov 		type->topology[die][stack_id].iio->segment = pci_domain_nr(dev->bus);
47334d13be8aSAlexander Antonov 		type->topology[die][stack_id].pmu_idx = stack_id;
47344d13be8aSAlexander Antonov 		type->topology[die][stack_id].iio->pci_bus_no = dev->bus->number;
4735c1777be3SAlexander Antonov 	}
4736c1777be3SAlexander Antonov 
4737c508eb04SXiongfeng Wang 	pci_dev_put(dev);
4738c508eb04SXiongfeng Wang 
4739c1777be3SAlexander Antonov 	return ret;
4740c1777be3SAlexander Antonov }
4741c1777be3SAlexander Antonov 
4742c1777be3SAlexander Antonov /*
4743c1777be3SAlexander Antonov  * SNR has a static mapping of stack IDs from SAD_CONTROL_CFG notation to PMON
4744c1777be3SAlexander Antonov  */
4745c1777be3SAlexander Antonov enum {
4746c1777be3SAlexander Antonov 	SNR_QAT_PMON_ID,
4747c1777be3SAlexander Antonov 	SNR_CBDMA_DMI_PMON_ID,
4748c1777be3SAlexander Antonov 	SNR_NIS_PMON_ID,
4749c1777be3SAlexander Antonov 	SNR_DLB_PMON_ID,
4750c1777be3SAlexander Antonov 	SNR_PCIE_GEN3_PMON_ID
4751c1777be3SAlexander Antonov };
4752c1777be3SAlexander Antonov 
4753c1777be3SAlexander Antonov static u8 snr_sad_pmon_mapping[] = {
4754c1777be3SAlexander Antonov 	SNR_CBDMA_DMI_PMON_ID,
4755c1777be3SAlexander Antonov 	SNR_PCIE_GEN3_PMON_ID,
4756c1777be3SAlexander Antonov 	SNR_DLB_PMON_ID,
4757c1777be3SAlexander Antonov 	SNR_NIS_PMON_ID,
4758c1777be3SAlexander Antonov 	SNR_QAT_PMON_ID
4759c1777be3SAlexander Antonov };
4760c1777be3SAlexander Antonov 
snr_iio_get_topology(struct intel_uncore_type * type)4761c1777be3SAlexander Antonov static int snr_iio_get_topology(struct intel_uncore_type *type)
4762c1777be3SAlexander Antonov {
4763c1777be3SAlexander Antonov 	return sad_cfg_iio_topology(type, snr_sad_pmon_mapping);
4764c1777be3SAlexander Antonov }
4765c1777be3SAlexander Antonov 
snr_iio_set_mapping(struct intel_uncore_type * type)4766d5b73506SAlexander Antonov static void snr_iio_set_mapping(struct intel_uncore_type *type)
4767c1777be3SAlexander Antonov {
4768d5b73506SAlexander Antonov 	pmu_iio_set_mapping(type, &snr_iio_mapping_group);
4769c1777be3SAlexander Antonov }
4770c1777be3SAlexander Antonov 
snr_iio_cleanup_mapping(struct intel_uncore_type * type)47713f2cbe38SAlexander Antonov static void snr_iio_cleanup_mapping(struct intel_uncore_type *type)
47723f2cbe38SAlexander Antonov {
47734d13be8aSAlexander Antonov 	pmu_cleanup_mapping(type, &snr_iio_mapping_group);
47743f2cbe38SAlexander Antonov }
47753f2cbe38SAlexander Antonov 
4776bdc0feeeSAlexander Antonov static struct event_constraint snr_uncore_iio_constraints[] = {
4777bdc0feeeSAlexander Antonov 	UNCORE_EVENT_CONSTRAINT(0x83, 0x3),
4778bdc0feeeSAlexander Antonov 	UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
4779bdc0feeeSAlexander Antonov 	UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
4780bdc0feeeSAlexander Antonov 	EVENT_CONSTRAINT_END
4781bdc0feeeSAlexander Antonov };
4782bdc0feeeSAlexander Antonov 
4783210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_iio = {
4784210cc5f9SKan Liang 	.name			= "iio",
4785210cc5f9SKan Liang 	.num_counters		= 4,
4786210cc5f9SKan Liang 	.num_boxes		= 5,
4787210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4788210cc5f9SKan Liang 	.event_ctl		= SNR_IIO_MSR_PMON_CTL0,
4789210cc5f9SKan Liang 	.perf_ctr		= SNR_IIO_MSR_PMON_CTR0,
4790210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4791210cc5f9SKan Liang 	.event_mask_ext		= SNR_IIO_PMON_RAW_EVENT_MASK_EXT,
4792210cc5f9SKan Liang 	.box_ctl		= SNR_IIO_MSR_PMON_BOX_CTL,
4793210cc5f9SKan Liang 	.msr_offset		= SNR_IIO_MSR_OFFSET,
4794bdc0feeeSAlexander Antonov 	.constraints		= snr_uncore_iio_constraints,
4795210cc5f9SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
4796210cc5f9SKan Liang 	.format_group		= &snr_uncore_iio_format_group,
4797c1777be3SAlexander Antonov 	.attr_update		= snr_iio_attr_update,
4798c1777be3SAlexander Antonov 	.get_topology		= snr_iio_get_topology,
4799c1777be3SAlexander Antonov 	.set_mapping		= snr_iio_set_mapping,
48003f2cbe38SAlexander Antonov 	.cleanup_mapping	= snr_iio_cleanup_mapping,
4801210cc5f9SKan Liang };
4802210cc5f9SKan Liang 
4803210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_irp = {
4804210cc5f9SKan Liang 	.name			= "irp",
4805210cc5f9SKan Liang 	.num_counters		= 2,
4806210cc5f9SKan Liang 	.num_boxes		= 5,
4807210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4808210cc5f9SKan Liang 	.event_ctl		= SNR_IRP0_MSR_PMON_CTL0,
4809210cc5f9SKan Liang 	.perf_ctr		= SNR_IRP0_MSR_PMON_CTR0,
4810210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4811210cc5f9SKan Liang 	.box_ctl		= SNR_IRP0_MSR_PMON_BOX_CTL,
4812210cc5f9SKan Liang 	.msr_offset		= SNR_IRP_MSR_OFFSET,
4813210cc5f9SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
4814210cc5f9SKan Liang 	.format_group		= &ivbep_uncore_format_group,
4815210cc5f9SKan Liang };
4816210cc5f9SKan Liang 
4817210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_m2pcie = {
4818210cc5f9SKan Liang 	.name		= "m2pcie",
4819210cc5f9SKan Liang 	.num_counters	= 4,
4820210cc5f9SKan Liang 	.num_boxes	= 5,
4821210cc5f9SKan Liang 	.perf_ctr_bits	= 48,
4822210cc5f9SKan Liang 	.event_ctl	= SNR_M2PCIE_MSR_PMON_CTL0,
4823210cc5f9SKan Liang 	.perf_ctr	= SNR_M2PCIE_MSR_PMON_CTR0,
4824210cc5f9SKan Liang 	.box_ctl	= SNR_M2PCIE_MSR_PMON_BOX_CTL,
4825210cc5f9SKan Liang 	.msr_offset	= SNR_M2PCIE_MSR_OFFSET,
4826210cc5f9SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4827210cc5f9SKan Liang 	.ops		= &ivbep_uncore_msr_ops,
4828210cc5f9SKan Liang 	.format_group	= &ivbep_uncore_format_group,
4829210cc5f9SKan Liang };
4830210cc5f9SKan Liang 
snr_pcu_hw_config(struct intel_uncore_box * box,struct perf_event * event)4831210cc5f9SKan Liang static int snr_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
4832210cc5f9SKan Liang {
4833210cc5f9SKan Liang 	struct hw_perf_event *hwc = &event->hw;
4834210cc5f9SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
4835210cc5f9SKan Liang 	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
4836210cc5f9SKan Liang 
4837210cc5f9SKan Liang 	if (ev_sel >= 0xb && ev_sel <= 0xe) {
4838210cc5f9SKan Liang 		reg1->reg = SNR_PCU_MSR_PMON_BOX_FILTER;
4839210cc5f9SKan Liang 		reg1->idx = ev_sel - 0xb;
4840210cc5f9SKan Liang 		reg1->config = event->attr.config1 & (0xff << reg1->idx);
4841210cc5f9SKan Liang 	}
4842210cc5f9SKan Liang 	return 0;
4843210cc5f9SKan Liang }
4844210cc5f9SKan Liang 
4845210cc5f9SKan Liang static struct intel_uncore_ops snr_uncore_pcu_ops = {
4846210cc5f9SKan Liang 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
4847210cc5f9SKan Liang 	.hw_config		= snr_pcu_hw_config,
4848210cc5f9SKan Liang 	.get_constraint		= snbep_pcu_get_constraint,
4849210cc5f9SKan Liang 	.put_constraint		= snbep_pcu_put_constraint,
4850210cc5f9SKan Liang };
4851210cc5f9SKan Liang 
4852210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_pcu = {
4853210cc5f9SKan Liang 	.name			= "pcu",
4854210cc5f9SKan Liang 	.num_counters		= 4,
4855210cc5f9SKan Liang 	.num_boxes		= 1,
4856210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4857210cc5f9SKan Liang 	.perf_ctr		= SNR_PCU_MSR_PMON_CTR0,
4858210cc5f9SKan Liang 	.event_ctl		= SNR_PCU_MSR_PMON_CTL0,
4859210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4860210cc5f9SKan Liang 	.box_ctl		= SNR_PCU_MSR_PMON_BOX_CTL,
4861210cc5f9SKan Liang 	.num_shared_regs	= 1,
4862210cc5f9SKan Liang 	.ops			= &snr_uncore_pcu_ops,
4863210cc5f9SKan Liang 	.format_group		= &skx_uncore_pcu_format_group,
4864210cc5f9SKan Liang };
4865210cc5f9SKan Liang 
4866210cc5f9SKan Liang enum perf_uncore_snr_iio_freerunning_type_id {
4867210cc5f9SKan Liang 	SNR_IIO_MSR_IOCLK,
4868210cc5f9SKan Liang 	SNR_IIO_MSR_BW_IN,
4869210cc5f9SKan Liang 
4870210cc5f9SKan Liang 	SNR_IIO_FREERUNNING_TYPE_MAX,
4871210cc5f9SKan Liang };
4872210cc5f9SKan Liang 
4873210cc5f9SKan Liang static struct freerunning_counters snr_iio_freerunning[] = {
4874210cc5f9SKan Liang 	[SNR_IIO_MSR_IOCLK]	= { 0x1eac, 0x1, 0x10, 1, 48 },
4875210cc5f9SKan Liang 	[SNR_IIO_MSR_BW_IN]	= { 0x1f00, 0x1, 0x10, 8, 48 },
4876210cc5f9SKan Liang };
4877210cc5f9SKan Liang 
4878210cc5f9SKan Liang static struct uncore_event_desc snr_uncore_iio_freerunning_events[] = {
4879210cc5f9SKan Liang 	/* Free-Running IIO CLOCKS Counter */
4880210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
4881210cc5f9SKan Liang 	/* Free-Running IIO BANDWIDTH IN Counters */
4882210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
4883210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
4884210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
4885210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
4886210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
4887210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
4888210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
4889210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
4890210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
4891210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
4892210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
4893210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
4894210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4,		"event=0xff,umask=0x24"),
4895210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale,	"3.814697266e-6"),
4896210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit,	"MiB"),
4897210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5,		"event=0xff,umask=0x25"),
4898210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale,	"3.814697266e-6"),
4899210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit,	"MiB"),
4900210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6,		"event=0xff,umask=0x26"),
4901210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale,	"3.814697266e-6"),
4902210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit,	"MiB"),
4903210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7,		"event=0xff,umask=0x27"),
4904210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale,	"3.814697266e-6"),
4905210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit,	"MiB"),
4906210cc5f9SKan Liang 	{ /* end: all zeroes */ },
4907210cc5f9SKan Liang };
4908210cc5f9SKan Liang 
4909210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_iio_free_running = {
4910210cc5f9SKan Liang 	.name			= "iio_free_running",
4911210cc5f9SKan Liang 	.num_counters		= 9,
4912210cc5f9SKan Liang 	.num_boxes		= 5,
4913210cc5f9SKan Liang 	.num_freerunning_types	= SNR_IIO_FREERUNNING_TYPE_MAX,
4914210cc5f9SKan Liang 	.freerunning		= snr_iio_freerunning,
4915210cc5f9SKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
4916210cc5f9SKan Liang 	.event_descs		= snr_uncore_iio_freerunning_events,
4917210cc5f9SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
4918210cc5f9SKan Liang };
4919210cc5f9SKan Liang 
4920210cc5f9SKan Liang static struct intel_uncore_type *snr_msr_uncores[] = {
4921210cc5f9SKan Liang 	&snr_uncore_ubox,
4922210cc5f9SKan Liang 	&snr_uncore_chabox,
4923210cc5f9SKan Liang 	&snr_uncore_iio,
4924210cc5f9SKan Liang 	&snr_uncore_irp,
4925210cc5f9SKan Liang 	&snr_uncore_m2pcie,
4926210cc5f9SKan Liang 	&snr_uncore_pcu,
4927210cc5f9SKan Liang 	&snr_uncore_iio_free_running,
4928210cc5f9SKan Liang 	NULL,
4929210cc5f9SKan Liang };
4930210cc5f9SKan Liang 
snr_uncore_cpu_init(void)4931210cc5f9SKan Liang void snr_uncore_cpu_init(void)
4932210cc5f9SKan Liang {
4933210cc5f9SKan Liang 	uncore_msr_uncores = snr_msr_uncores;
4934210cc5f9SKan Liang }
4935210cc5f9SKan Liang 
snr_m2m_uncore_pci_init_box(struct intel_uncore_box * box)4936210cc5f9SKan Liang static void snr_m2m_uncore_pci_init_box(struct intel_uncore_box *box)
4937210cc5f9SKan Liang {
4938210cc5f9SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4939210cc5f9SKan Liang 	int box_ctl = uncore_pci_box_ctl(box);
4940210cc5f9SKan Liang 
4941210cc5f9SKan Liang 	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
4942210cc5f9SKan Liang 	pci_write_config_dword(pdev, box_ctl, IVBEP_PMON_BOX_CTL_INT);
4943210cc5f9SKan Liang }
4944210cc5f9SKan Liang 
4945210cc5f9SKan Liang static struct intel_uncore_ops snr_m2m_uncore_pci_ops = {
4946210cc5f9SKan Liang 	.init_box	= snr_m2m_uncore_pci_init_box,
4947210cc5f9SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
4948210cc5f9SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
4949210cc5f9SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
4950210cc5f9SKan Liang 	.enable_event	= snbep_uncore_pci_enable_event,
4951210cc5f9SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
4952210cc5f9SKan Liang };
4953210cc5f9SKan Liang 
4954210cc5f9SKan Liang static struct attribute *snr_m2m_uncore_formats_attr[] = {
4955210cc5f9SKan Liang 	&format_attr_event.attr,
4956210cc5f9SKan Liang 	&format_attr_umask_ext3.attr,
4957210cc5f9SKan Liang 	&format_attr_edge.attr,
4958210cc5f9SKan Liang 	&format_attr_inv.attr,
4959210cc5f9SKan Liang 	&format_attr_thresh8.attr,
4960210cc5f9SKan Liang 	NULL,
4961210cc5f9SKan Liang };
4962210cc5f9SKan Liang 
4963210cc5f9SKan Liang static const struct attribute_group snr_m2m_uncore_format_group = {
4964210cc5f9SKan Liang 	.name = "format",
4965210cc5f9SKan Liang 	.attrs = snr_m2m_uncore_formats_attr,
4966210cc5f9SKan Liang };
4967210cc5f9SKan Liang 
4968210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_m2m = {
4969210cc5f9SKan Liang 	.name		= "m2m",
4970210cc5f9SKan Liang 	.num_counters   = 4,
4971210cc5f9SKan Liang 	.num_boxes	= 1,
4972210cc5f9SKan Liang 	.perf_ctr_bits	= 48,
4973210cc5f9SKan Liang 	.perf_ctr	= SNR_M2M_PCI_PMON_CTR0,
4974210cc5f9SKan Liang 	.event_ctl	= SNR_M2M_PCI_PMON_CTL0,
4975210cc5f9SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4976210cc5f9SKan Liang 	.event_mask_ext	= SNR_M2M_PCI_PMON_UMASK_EXT,
4977210cc5f9SKan Liang 	.box_ctl	= SNR_M2M_PCI_PMON_BOX_CTL,
4978210cc5f9SKan Liang 	.ops		= &snr_m2m_uncore_pci_ops,
4979210cc5f9SKan Liang 	.format_group	= &snr_m2m_uncore_format_group,
4980210cc5f9SKan Liang };
4981210cc5f9SKan Liang 
snr_uncore_pci_enable_event(struct intel_uncore_box * box,struct perf_event * event)4982a3b1e845SKan Liang static void snr_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
4983a3b1e845SKan Liang {
4984a3b1e845SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4985a3b1e845SKan Liang 	struct hw_perf_event *hwc = &event->hw;
4986a3b1e845SKan Liang 
4987a3b1e845SKan Liang 	pci_write_config_dword(pdev, hwc->config_base, (u32)(hwc->config | SNBEP_PMON_CTL_EN));
4988a3b1e845SKan Liang 	pci_write_config_dword(pdev, hwc->config_base + 4, (u32)(hwc->config >> 32));
4989a3b1e845SKan Liang }
4990a3b1e845SKan Liang 
4991a3b1e845SKan Liang static struct intel_uncore_ops snr_pcie3_uncore_pci_ops = {
4992a3b1e845SKan Liang 	.init_box	= snr_m2m_uncore_pci_init_box,
4993a3b1e845SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
4994a3b1e845SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
4995a3b1e845SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
4996a3b1e845SKan Liang 	.enable_event	= snr_uncore_pci_enable_event,
4997a3b1e845SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
4998a3b1e845SKan Liang };
4999a3b1e845SKan Liang 
5000a3b1e845SKan Liang static struct intel_uncore_type snr_uncore_pcie3 = {
5001a3b1e845SKan Liang 	.name		= "pcie3",
5002a3b1e845SKan Liang 	.num_counters	= 4,
5003a3b1e845SKan Liang 	.num_boxes	= 1,
5004a3b1e845SKan Liang 	.perf_ctr_bits	= 48,
5005a3b1e845SKan Liang 	.perf_ctr	= SNR_PCIE3_PCI_PMON_CTR0,
5006a3b1e845SKan Liang 	.event_ctl	= SNR_PCIE3_PCI_PMON_CTL0,
5007a3b1e845SKan Liang 	.event_mask	= SKX_IIO_PMON_RAW_EVENT_MASK,
5008a3b1e845SKan Liang 	.event_mask_ext	= SKX_IIO_PMON_RAW_EVENT_MASK_EXT,
5009a3b1e845SKan Liang 	.box_ctl	= SNR_PCIE3_PCI_PMON_BOX_CTL,
5010a3b1e845SKan Liang 	.ops		= &snr_pcie3_uncore_pci_ops,
5011a3b1e845SKan Liang 	.format_group	= &skx_uncore_iio_format_group,
5012a3b1e845SKan Liang };
5013a3b1e845SKan Liang 
5014210cc5f9SKan Liang enum {
5015210cc5f9SKan Liang 	SNR_PCI_UNCORE_M2M,
5016a3b1e845SKan Liang 	SNR_PCI_UNCORE_PCIE3,
5017210cc5f9SKan Liang };
5018210cc5f9SKan Liang 
5019210cc5f9SKan Liang static struct intel_uncore_type *snr_pci_uncores[] = {
5020210cc5f9SKan Liang 	[SNR_PCI_UNCORE_M2M]		= &snr_uncore_m2m,
5021a3b1e845SKan Liang 	[SNR_PCI_UNCORE_PCIE3]		= &snr_uncore_pcie3,
5022210cc5f9SKan Liang 	NULL,
5023210cc5f9SKan Liang };
5024210cc5f9SKan Liang 
5025210cc5f9SKan Liang static const struct pci_device_id snr_uncore_pci_ids[] = {
5026210cc5f9SKan Liang 	{ /* M2M */
5027210cc5f9SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
5028210cc5f9SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 0, SNR_PCI_UNCORE_M2M, 0),
5029210cc5f9SKan Liang 	},
5030210cc5f9SKan Liang 	{ /* end: all zeroes */ }
5031210cc5f9SKan Liang };
5032210cc5f9SKan Liang 
5033210cc5f9SKan Liang static struct pci_driver snr_uncore_pci_driver = {
5034210cc5f9SKan Liang 	.name		= "snr_uncore",
5035210cc5f9SKan Liang 	.id_table	= snr_uncore_pci_ids,
5036210cc5f9SKan Liang };
5037210cc5f9SKan Liang 
5038a3b1e845SKan Liang static const struct pci_device_id snr_uncore_pci_sub_ids[] = {
5039a3b1e845SKan Liang 	{ /* PCIe3 RP */
5040a3b1e845SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x334a),
5041a3b1e845SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(4, 0, SNR_PCI_UNCORE_PCIE3, 0),
5042a3b1e845SKan Liang 	},
5043a3b1e845SKan Liang 	{ /* end: all zeroes */ }
5044a3b1e845SKan Liang };
5045a3b1e845SKan Liang 
5046a3b1e845SKan Liang static struct pci_driver snr_uncore_pci_sub_driver = {
5047a3b1e845SKan Liang 	.name		= "snr_uncore_sub",
5048a3b1e845SKan Liang 	.id_table	= snr_uncore_pci_sub_ids,
5049a3b1e845SKan Liang };
5050a3b1e845SKan Liang 
snr_uncore_pci_init(void)5051210cc5f9SKan Liang int snr_uncore_pci_init(void)
5052210cc5f9SKan Liang {
5053210cc5f9SKan Liang 	/* SNR UBOX DID */
5054210cc5f9SKan Liang 	int ret = snbep_pci2phy_map_init(0x3460, SKX_CPUNODEID,
5055210cc5f9SKan Liang 					 SKX_GIDNIDMAP, true);
5056210cc5f9SKan Liang 
5057210cc5f9SKan Liang 	if (ret)
5058210cc5f9SKan Liang 		return ret;
5059210cc5f9SKan Liang 
5060210cc5f9SKan Liang 	uncore_pci_uncores = snr_pci_uncores;
5061210cc5f9SKan Liang 	uncore_pci_driver = &snr_uncore_pci_driver;
5062a3b1e845SKan Liang 	uncore_pci_sub_driver = &snr_uncore_pci_sub_driver;
5063210cc5f9SKan Liang 	return 0;
5064210cc5f9SKan Liang }
5065210cc5f9SKan Liang 
50661583971bSKan Liang #define SNR_MC_DEVICE_ID	0x3451
50671583971bSKan Liang 
snr_uncore_get_mc_dev(unsigned int device,int id)50681583971bSKan Liang static struct pci_dev *snr_uncore_get_mc_dev(unsigned int device, int id)
5069ee49532bSKan Liang {
5070ee49532bSKan Liang 	struct pci_dev *mc_dev = NULL;
5071ba9506beSSteve Wahl 	int pkg;
5072ee49532bSKan Liang 
5073ee49532bSKan Liang 	while (1) {
50741583971bSKan Liang 		mc_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, mc_dev);
5075ee49532bSKan Liang 		if (!mc_dev)
5076ee49532bSKan Liang 			break;
5077ba9506beSSteve Wahl 		pkg = uncore_pcibus_to_dieid(mc_dev->bus);
5078ba9506beSSteve Wahl 		if (pkg == id)
5079ee49532bSKan Liang 			break;
5080ee49532bSKan Liang 	}
5081ee49532bSKan Liang 	return mc_dev;
5082ee49532bSKan Liang }
5083ee49532bSKan Liang 
snr_uncore_mmio_map(struct intel_uncore_box * box,unsigned int box_ctl,int mem_offset,unsigned int device)50841583971bSKan Liang static int snr_uncore_mmio_map(struct intel_uncore_box *box,
50851583971bSKan Liang 			       unsigned int box_ctl, int mem_offset,
50861583971bSKan Liang 			       unsigned int device)
5087ee49532bSKan Liang {
50881583971bSKan Liang 	struct pci_dev *pdev = snr_uncore_get_mc_dev(device, box->dieid);
50891b94d31dSKan Liang 	struct intel_uncore_type *type = box->pmu->type;
5090ee49532bSKan Liang 	resource_size_t addr;
5091ee49532bSKan Liang 	u32 pci_dword;
5092ee49532bSKan Liang 
5093ee49532bSKan Liang 	if (!pdev)
50941583971bSKan Liang 		return -ENODEV;
5095ee49532bSKan Liang 
5096ee49532bSKan Liang 	pci_read_config_dword(pdev, SNR_IMC_MMIO_BASE_OFFSET, &pci_dword);
50970b3a8738SColin Ian King 	addr = ((resource_size_t)pci_dword & SNR_IMC_MMIO_BASE_MASK) << 23;
5098ee49532bSKan Liang 
50993442a9ecSKan Liang 	pci_read_config_dword(pdev, mem_offset, &pci_dword);
5100ee49532bSKan Liang 	addr |= (pci_dword & SNR_IMC_MMIO_MEM0_MASK) << 12;
5101ee49532bSKan Liang 
5102ee49532bSKan Liang 	addr += box_ctl;
5103ee49532bSKan Liang 
51048ebd16c1SXiongfeng Wang 	pci_dev_put(pdev);
51058ebd16c1SXiongfeng Wang 
51061b94d31dSKan Liang 	box->io_addr = ioremap(addr, type->mmio_map_size);
51071b94d31dSKan Liang 	if (!box->io_addr) {
51081b94d31dSKan Liang 		pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
51091583971bSKan Liang 		return -EINVAL;
51101b94d31dSKan Liang 	}
5111ee49532bSKan Liang 
51121583971bSKan Liang 	return 0;
51131583971bSKan Liang }
51141583971bSKan Liang 
__snr_uncore_mmio_init_box(struct intel_uncore_box * box,unsigned int box_ctl,int mem_offset,unsigned int device)51151583971bSKan Liang static void __snr_uncore_mmio_init_box(struct intel_uncore_box *box,
51161583971bSKan Liang 				       unsigned int box_ctl, int mem_offset,
51171583971bSKan Liang 				       unsigned int device)
51181583971bSKan Liang {
51191583971bSKan Liang 	if (!snr_uncore_mmio_map(box, box_ctl, mem_offset, device))
5120ee49532bSKan Liang 		writel(IVBEP_PMON_BOX_CTL_INT, box->io_addr);
5121ee49532bSKan Liang }
5122ee49532bSKan Liang 
snr_uncore_mmio_init_box(struct intel_uncore_box * box)51233442a9ecSKan Liang static void snr_uncore_mmio_init_box(struct intel_uncore_box *box)
51243442a9ecSKan Liang {
51253442a9ecSKan Liang 	__snr_uncore_mmio_init_box(box, uncore_mmio_box_ctl(box),
51261583971bSKan Liang 				   SNR_IMC_MMIO_MEM0_OFFSET,
51271583971bSKan Liang 				   SNR_MC_DEVICE_ID);
51283442a9ecSKan Liang }
51293442a9ecSKan Liang 
snr_uncore_mmio_disable_box(struct intel_uncore_box * box)5130ee49532bSKan Liang static void snr_uncore_mmio_disable_box(struct intel_uncore_box *box)
5131ee49532bSKan Liang {
5132ee49532bSKan Liang 	u32 config;
5133ee49532bSKan Liang 
5134ee49532bSKan Liang 	if (!box->io_addr)
5135ee49532bSKan Liang 		return;
5136ee49532bSKan Liang 
5137ee49532bSKan Liang 	config = readl(box->io_addr);
5138ee49532bSKan Liang 	config |= SNBEP_PMON_BOX_CTL_FRZ;
5139ee49532bSKan Liang 	writel(config, box->io_addr);
5140ee49532bSKan Liang }
5141ee49532bSKan Liang 
snr_uncore_mmio_enable_box(struct intel_uncore_box * box)5142ee49532bSKan Liang static void snr_uncore_mmio_enable_box(struct intel_uncore_box *box)
5143ee49532bSKan Liang {
5144ee49532bSKan Liang 	u32 config;
5145ee49532bSKan Liang 
5146ee49532bSKan Liang 	if (!box->io_addr)
5147ee49532bSKan Liang 		return;
5148ee49532bSKan Liang 
5149ee49532bSKan Liang 	config = readl(box->io_addr);
5150ee49532bSKan Liang 	config &= ~SNBEP_PMON_BOX_CTL_FRZ;
5151ee49532bSKan Liang 	writel(config, box->io_addr);
5152ee49532bSKan Liang }
5153ee49532bSKan Liang 
snr_uncore_mmio_enable_event(struct intel_uncore_box * box,struct perf_event * event)5154ee49532bSKan Liang static void snr_uncore_mmio_enable_event(struct intel_uncore_box *box,
5155ee49532bSKan Liang 					   struct perf_event *event)
5156ee49532bSKan Liang {
5157ee49532bSKan Liang 	struct hw_perf_event *hwc = &event->hw;
5158ee49532bSKan Liang 
5159ee49532bSKan Liang 	if (!box->io_addr)
5160ee49532bSKan Liang 		return;
5161ee49532bSKan Liang 
5162f0171973SKan Liang 	if (!uncore_mmio_is_valid_offset(box, hwc->config_base))
5163f0171973SKan Liang 		return;
5164f0171973SKan Liang 
5165ee49532bSKan Liang 	writel(hwc->config | SNBEP_PMON_CTL_EN,
5166ee49532bSKan Liang 	       box->io_addr + hwc->config_base);
5167ee49532bSKan Liang }
5168ee49532bSKan Liang 
snr_uncore_mmio_disable_event(struct intel_uncore_box * box,struct perf_event * event)5169ee49532bSKan Liang static void snr_uncore_mmio_disable_event(struct intel_uncore_box *box,
5170ee49532bSKan Liang 					    struct perf_event *event)
5171ee49532bSKan Liang {
5172ee49532bSKan Liang 	struct hw_perf_event *hwc = &event->hw;
5173ee49532bSKan Liang 
5174ee49532bSKan Liang 	if (!box->io_addr)
5175ee49532bSKan Liang 		return;
5176ee49532bSKan Liang 
5177f0171973SKan Liang 	if (!uncore_mmio_is_valid_offset(box, hwc->config_base))
5178f0171973SKan Liang 		return;
5179f0171973SKan Liang 
5180ee49532bSKan Liang 	writel(hwc->config, box->io_addr + hwc->config_base);
5181ee49532bSKan Liang }
5182ee49532bSKan Liang 
5183ee49532bSKan Liang static struct intel_uncore_ops snr_uncore_mmio_ops = {
5184ee49532bSKan Liang 	.init_box	= snr_uncore_mmio_init_box,
5185ee49532bSKan Liang 	.exit_box	= uncore_mmio_exit_box,
5186ee49532bSKan Liang 	.disable_box	= snr_uncore_mmio_disable_box,
5187ee49532bSKan Liang 	.enable_box	= snr_uncore_mmio_enable_box,
5188ee49532bSKan Liang 	.disable_event	= snr_uncore_mmio_disable_event,
5189ee49532bSKan Liang 	.enable_event	= snr_uncore_mmio_enable_event,
5190ee49532bSKan Liang 	.read_counter	= uncore_mmio_read_counter,
5191ee49532bSKan Liang };
5192ee49532bSKan Liang 
5193ee49532bSKan Liang static struct uncore_event_desc snr_uncore_imc_events[] = {
5194ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0x00,umask=0x00"),
5195ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x0f"),
5196ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
5197ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
5198ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x30"),
5199ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
5200ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
5201ee49532bSKan Liang 	{ /* end: all zeroes */ },
5202ee49532bSKan Liang };
5203ee49532bSKan Liang 
5204ee49532bSKan Liang static struct intel_uncore_type snr_uncore_imc = {
5205ee49532bSKan Liang 	.name		= "imc",
5206ee49532bSKan Liang 	.num_counters   = 4,
5207ee49532bSKan Liang 	.num_boxes	= 2,
5208ee49532bSKan Liang 	.perf_ctr_bits	= 48,
5209ee49532bSKan Liang 	.fixed_ctr_bits	= 48,
5210ee49532bSKan Liang 	.fixed_ctr	= SNR_IMC_MMIO_PMON_FIXED_CTR,
5211ee49532bSKan Liang 	.fixed_ctl	= SNR_IMC_MMIO_PMON_FIXED_CTL,
5212ee49532bSKan Liang 	.event_descs	= snr_uncore_imc_events,
5213ee49532bSKan Liang 	.perf_ctr	= SNR_IMC_MMIO_PMON_CTR0,
5214ee49532bSKan Liang 	.event_ctl	= SNR_IMC_MMIO_PMON_CTL0,
5215ee49532bSKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
5216ee49532bSKan Liang 	.box_ctl	= SNR_IMC_MMIO_PMON_BOX_CTL,
5217ee49532bSKan Liang 	.mmio_offset	= SNR_IMC_MMIO_OFFSET,
52181b94d31dSKan Liang 	.mmio_map_size	= SNR_IMC_MMIO_SIZE,
5219ee49532bSKan Liang 	.ops		= &snr_uncore_mmio_ops,
5220ee49532bSKan Liang 	.format_group	= &skx_uncore_format_group,
5221ee49532bSKan Liang };
5222ee49532bSKan Liang 
5223ee49532bSKan Liang enum perf_uncore_snr_imc_freerunning_type_id {
5224ee49532bSKan Liang 	SNR_IMC_DCLK,
5225ee49532bSKan Liang 	SNR_IMC_DDR,
5226ee49532bSKan Liang 
5227ee49532bSKan Liang 	SNR_IMC_FREERUNNING_TYPE_MAX,
5228ee49532bSKan Liang };
5229ee49532bSKan Liang 
5230ee49532bSKan Liang static struct freerunning_counters snr_imc_freerunning[] = {
5231ee49532bSKan Liang 	[SNR_IMC_DCLK]	= { 0x22b0, 0x0, 0, 1, 48 },
5232ee49532bSKan Liang 	[SNR_IMC_DDR]	= { 0x2290, 0x8, 0, 2, 48 },
5233ee49532bSKan Liang };
5234ee49532bSKan Liang 
5235ee49532bSKan Liang static struct uncore_event_desc snr_uncore_imc_freerunning_events[] = {
5236ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(dclk,		"event=0xff,umask=0x10"),
5237ee49532bSKan Liang 
5238ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(read,		"event=0xff,umask=0x20"),
52398191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(read.scale,	"6.103515625e-5"),
5240ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(read.unit,	"MiB"),
5241ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(write,		"event=0xff,umask=0x21"),
52428191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(write.scale,	"6.103515625e-5"),
5243ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(write.unit,	"MiB"),
5244fa694ae5SKan Liang 	{ /* end: all zeroes */ },
5245ee49532bSKan Liang };
5246ee49532bSKan Liang 
5247ee49532bSKan Liang static struct intel_uncore_ops snr_uncore_imc_freerunning_ops = {
5248ee49532bSKan Liang 	.init_box	= snr_uncore_mmio_init_box,
5249ee49532bSKan Liang 	.exit_box	= uncore_mmio_exit_box,
5250ee49532bSKan Liang 	.read_counter	= uncore_mmio_read_counter,
5251ee49532bSKan Liang 	.hw_config	= uncore_freerunning_hw_config,
5252ee49532bSKan Liang };
5253ee49532bSKan Liang 
5254ee49532bSKan Liang static struct intel_uncore_type snr_uncore_imc_free_running = {
5255ee49532bSKan Liang 	.name			= "imc_free_running",
5256ee49532bSKan Liang 	.num_counters		= 3,
5257ee49532bSKan Liang 	.num_boxes		= 1,
5258ee49532bSKan Liang 	.num_freerunning_types	= SNR_IMC_FREERUNNING_TYPE_MAX,
52591b94d31dSKan Liang 	.mmio_map_size		= SNR_IMC_MMIO_SIZE,
5260ee49532bSKan Liang 	.freerunning		= snr_imc_freerunning,
5261ee49532bSKan Liang 	.ops			= &snr_uncore_imc_freerunning_ops,
5262ee49532bSKan Liang 	.event_descs		= snr_uncore_imc_freerunning_events,
5263ee49532bSKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
5264ee49532bSKan Liang };
5265ee49532bSKan Liang 
5266ee49532bSKan Liang static struct intel_uncore_type *snr_mmio_uncores[] = {
5267ee49532bSKan Liang 	&snr_uncore_imc,
5268ee49532bSKan Liang 	&snr_uncore_imc_free_running,
5269ee49532bSKan Liang 	NULL,
5270ee49532bSKan Liang };
5271ee49532bSKan Liang 
snr_uncore_mmio_init(void)5272ee49532bSKan Liang void snr_uncore_mmio_init(void)
5273ee49532bSKan Liang {
5274ee49532bSKan Liang 	uncore_mmio_uncores = snr_mmio_uncores;
5275ee49532bSKan Liang }
5276ee49532bSKan Liang 
5277210cc5f9SKan Liang /* end of SNR uncore support */
52782b3b76b5SKan Liang 
52792b3b76b5SKan Liang /* ICX uncore support */
52802b3b76b5SKan Liang 
52812b3b76b5SKan Liang static unsigned icx_cha_msr_offsets[] = {
52822b3b76b5SKan Liang 	0x2a0, 0x2ae, 0x2bc, 0x2ca, 0x2d8, 0x2e6, 0x2f4, 0x302, 0x310,
52832b3b76b5SKan Liang 	0x31e, 0x32c, 0x33a, 0x348, 0x356, 0x364, 0x372, 0x380, 0x38e,
52842b3b76b5SKan Liang 	0x3aa, 0x3b8, 0x3c6, 0x3d4, 0x3e2, 0x3f0, 0x3fe, 0x40c, 0x41a,
52852b3b76b5SKan Liang 	0x428, 0x436, 0x444, 0x452, 0x460, 0x46e, 0x47c, 0x0,   0xe,
52862b3b76b5SKan Liang 	0x1c,  0x2a,  0x38,  0x46,
52872b3b76b5SKan Liang };
52882b3b76b5SKan Liang 
icx_cha_hw_config(struct intel_uncore_box * box,struct perf_event * event)52892b3b76b5SKan Liang static int icx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
52902b3b76b5SKan Liang {
52912b3b76b5SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
52922b3b76b5SKan Liang 	bool tie_en = !!(event->hw.config & SNBEP_CBO_PMON_CTL_TID_EN);
52932b3b76b5SKan Liang 
52942b3b76b5SKan Liang 	if (tie_en) {
52952b3b76b5SKan Liang 		reg1->reg = ICX_C34_MSR_PMON_BOX_FILTER0 +
52962b3b76b5SKan Liang 			    icx_cha_msr_offsets[box->pmu->pmu_idx];
52972b3b76b5SKan Liang 		reg1->config = event->attr.config1 & SKX_CHA_MSR_PMON_BOX_FILTER_TID;
52982b3b76b5SKan Liang 		reg1->idx = 0;
52992b3b76b5SKan Liang 	}
53002b3b76b5SKan Liang 
53012b3b76b5SKan Liang 	return 0;
53022b3b76b5SKan Liang }
53032b3b76b5SKan Liang 
53042b3b76b5SKan Liang static struct intel_uncore_ops icx_uncore_chabox_ops = {
53052b3b76b5SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
53062b3b76b5SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
53072b3b76b5SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
53082b3b76b5SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
53092b3b76b5SKan Liang 	.enable_event		= snr_cha_enable_event,
53102b3b76b5SKan Liang 	.read_counter		= uncore_msr_read_counter,
53112b3b76b5SKan Liang 	.hw_config		= icx_cha_hw_config,
53122b3b76b5SKan Liang };
53132b3b76b5SKan Liang 
53142b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_chabox = {
53152b3b76b5SKan Liang 	.name			= "cha",
53162b3b76b5SKan Liang 	.num_counters		= 4,
53172b3b76b5SKan Liang 	.perf_ctr_bits		= 48,
53182b3b76b5SKan Liang 	.event_ctl		= ICX_C34_MSR_PMON_CTL0,
53192b3b76b5SKan Liang 	.perf_ctr		= ICX_C34_MSR_PMON_CTR0,
53202b3b76b5SKan Liang 	.box_ctl		= ICX_C34_MSR_PMON_BOX_CTL,
53212b3b76b5SKan Liang 	.msr_offsets		= icx_cha_msr_offsets,
53222b3b76b5SKan Liang 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
53232b3b76b5SKan Liang 	.event_mask_ext		= SNR_CHA_RAW_EVENT_MASK_EXT,
53242b3b76b5SKan Liang 	.constraints		= skx_uncore_chabox_constraints,
53252b3b76b5SKan Liang 	.ops			= &icx_uncore_chabox_ops,
53262b3b76b5SKan Liang 	.format_group		= &snr_uncore_chabox_format_group,
53272b3b76b5SKan Liang };
53282b3b76b5SKan Liang 
53292b3b76b5SKan Liang static unsigned icx_msr_offsets[] = {
53302b3b76b5SKan Liang 	0x0, 0x20, 0x40, 0x90, 0xb0, 0xd0,
53312b3b76b5SKan Liang };
53322b3b76b5SKan Liang 
53332b3b76b5SKan Liang static struct event_constraint icx_uncore_iio_constraints[] = {
53342b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
53352b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x03, 0x3),
53362b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x83, 0x3),
5337f42e8a60SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x88, 0xc),
53382b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
53392b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc5, 0xc),
5340f42e8a60SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
53412b3b76b5SKan Liang 	EVENT_CONSTRAINT_END
53422b3b76b5SKan Liang };
53432b3b76b5SKan Liang 
534410337e95SAlexander Antonov static umode_t
icx_iio_mapping_visible(struct kobject * kobj,struct attribute * attr,int die)534510337e95SAlexander Antonov icx_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
534610337e95SAlexander Antonov {
534710337e95SAlexander Antonov 	/* Root bus 0x00 is valid only for pmu_idx = 5. */
534810337e95SAlexander Antonov 	return pmu_iio_mapping_visible(kobj, attr, die, 5);
534910337e95SAlexander Antonov }
535010337e95SAlexander Antonov 
535110337e95SAlexander Antonov static struct attribute_group icx_iio_mapping_group = {
535210337e95SAlexander Antonov 	.is_visible	= icx_iio_mapping_visible,
535310337e95SAlexander Antonov };
535410337e95SAlexander Antonov 
535510337e95SAlexander Antonov static const struct attribute_group *icx_iio_attr_update[] = {
535610337e95SAlexander Antonov 	&icx_iio_mapping_group,
535710337e95SAlexander Antonov 	NULL,
535810337e95SAlexander Antonov };
535910337e95SAlexander Antonov 
536010337e95SAlexander Antonov /*
536110337e95SAlexander Antonov  * ICX has a static mapping of stack IDs from SAD_CONTROL_CFG notation to PMON
536210337e95SAlexander Antonov  */
536310337e95SAlexander Antonov enum {
536410337e95SAlexander Antonov 	ICX_PCIE1_PMON_ID,
536510337e95SAlexander Antonov 	ICX_PCIE2_PMON_ID,
536610337e95SAlexander Antonov 	ICX_PCIE3_PMON_ID,
536710337e95SAlexander Antonov 	ICX_PCIE4_PMON_ID,
536810337e95SAlexander Antonov 	ICX_PCIE5_PMON_ID,
536910337e95SAlexander Antonov 	ICX_CBDMA_DMI_PMON_ID
537010337e95SAlexander Antonov };
537110337e95SAlexander Antonov 
537210337e95SAlexander Antonov static u8 icx_sad_pmon_mapping[] = {
537310337e95SAlexander Antonov 	ICX_CBDMA_DMI_PMON_ID,
537410337e95SAlexander Antonov 	ICX_PCIE1_PMON_ID,
537510337e95SAlexander Antonov 	ICX_PCIE2_PMON_ID,
537610337e95SAlexander Antonov 	ICX_PCIE3_PMON_ID,
537710337e95SAlexander Antonov 	ICX_PCIE4_PMON_ID,
537810337e95SAlexander Antonov 	ICX_PCIE5_PMON_ID,
537910337e95SAlexander Antonov };
538010337e95SAlexander Antonov 
icx_iio_get_topology(struct intel_uncore_type * type)538110337e95SAlexander Antonov static int icx_iio_get_topology(struct intel_uncore_type *type)
538210337e95SAlexander Antonov {
538310337e95SAlexander Antonov 	return sad_cfg_iio_topology(type, icx_sad_pmon_mapping);
538410337e95SAlexander Antonov }
538510337e95SAlexander Antonov 
icx_iio_set_mapping(struct intel_uncore_type * type)5386d5b73506SAlexander Antonov static void icx_iio_set_mapping(struct intel_uncore_type *type)
538710337e95SAlexander Antonov {
5388efe06270SAlexander Antonov 	/* Detect ICX-D system. This case is not supported */
5389efe06270SAlexander Antonov 	if (boot_cpu_data.x86_model == INTEL_FAM6_ICELAKE_D) {
5390efe06270SAlexander Antonov 		pmu_clear_mapping_attr(type->attr_update, &icx_iio_mapping_group);
5391d5b73506SAlexander Antonov 		return;
5392efe06270SAlexander Antonov 	}
5393d5b73506SAlexander Antonov 	pmu_iio_set_mapping(type, &icx_iio_mapping_group);
539410337e95SAlexander Antonov }
539510337e95SAlexander Antonov 
icx_iio_cleanup_mapping(struct intel_uncore_type * type)53963f2cbe38SAlexander Antonov static void icx_iio_cleanup_mapping(struct intel_uncore_type *type)
53973f2cbe38SAlexander Antonov {
53984d13be8aSAlexander Antonov 	pmu_cleanup_mapping(type, &icx_iio_mapping_group);
53993f2cbe38SAlexander Antonov }
54003f2cbe38SAlexander Antonov 
54012b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_iio = {
54022b3b76b5SKan Liang 	.name			= "iio",
54032b3b76b5SKan Liang 	.num_counters		= 4,
54042b3b76b5SKan Liang 	.num_boxes		= 6,
54052b3b76b5SKan Liang 	.perf_ctr_bits		= 48,
54062b3b76b5SKan Liang 	.event_ctl		= ICX_IIO_MSR_PMON_CTL0,
54072b3b76b5SKan Liang 	.perf_ctr		= ICX_IIO_MSR_PMON_CTR0,
54082b3b76b5SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
54092b3b76b5SKan Liang 	.event_mask_ext		= SNR_IIO_PMON_RAW_EVENT_MASK_EXT,
54102b3b76b5SKan Liang 	.box_ctl		= ICX_IIO_MSR_PMON_BOX_CTL,
54112b3b76b5SKan Liang 	.msr_offsets		= icx_msr_offsets,
54122b3b76b5SKan Liang 	.constraints		= icx_uncore_iio_constraints,
54132b3b76b5SKan Liang 	.ops			= &skx_uncore_iio_ops,
54142b3b76b5SKan Liang 	.format_group		= &snr_uncore_iio_format_group,
541510337e95SAlexander Antonov 	.attr_update		= icx_iio_attr_update,
541610337e95SAlexander Antonov 	.get_topology		= icx_iio_get_topology,
541710337e95SAlexander Antonov 	.set_mapping		= icx_iio_set_mapping,
54183f2cbe38SAlexander Antonov 	.cleanup_mapping	= icx_iio_cleanup_mapping,
54192b3b76b5SKan Liang };
54202b3b76b5SKan Liang 
54212b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_irp = {
54222b3b76b5SKan Liang 	.name			= "irp",
54232b3b76b5SKan Liang 	.num_counters		= 2,
54242b3b76b5SKan Liang 	.num_boxes		= 6,
54252b3b76b5SKan Liang 	.perf_ctr_bits		= 48,
54262b3b76b5SKan Liang 	.event_ctl		= ICX_IRP0_MSR_PMON_CTL0,
54272b3b76b5SKan Liang 	.perf_ctr		= ICX_IRP0_MSR_PMON_CTR0,
54282b3b76b5SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
54292b3b76b5SKan Liang 	.box_ctl		= ICX_IRP0_MSR_PMON_BOX_CTL,
54302b3b76b5SKan Liang 	.msr_offsets		= icx_msr_offsets,
54312b3b76b5SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
54322b3b76b5SKan Liang 	.format_group		= &ivbep_uncore_format_group,
54332b3b76b5SKan Liang };
54342b3b76b5SKan Liang 
54352b3b76b5SKan Liang static struct event_constraint icx_uncore_m2pcie_constraints[] = {
54362b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
54372b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
54382b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
54392b3b76b5SKan Liang 	EVENT_CONSTRAINT_END
54402b3b76b5SKan Liang };
54412b3b76b5SKan Liang 
54422b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_m2pcie = {
54432b3b76b5SKan Liang 	.name		= "m2pcie",
54442b3b76b5SKan Liang 	.num_counters	= 4,
54452b3b76b5SKan Liang 	.num_boxes	= 6,
54462b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
54472b3b76b5SKan Liang 	.event_ctl	= ICX_M2PCIE_MSR_PMON_CTL0,
54482b3b76b5SKan Liang 	.perf_ctr	= ICX_M2PCIE_MSR_PMON_CTR0,
54492b3b76b5SKan Liang 	.box_ctl	= ICX_M2PCIE_MSR_PMON_BOX_CTL,
54502b3b76b5SKan Liang 	.msr_offsets	= icx_msr_offsets,
54512b3b76b5SKan Liang 	.constraints	= icx_uncore_m2pcie_constraints,
54522b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
54532b3b76b5SKan Liang 	.ops		= &ivbep_uncore_msr_ops,
54542b3b76b5SKan Liang 	.format_group	= &ivbep_uncore_format_group,
54552b3b76b5SKan Liang };
54562b3b76b5SKan Liang 
54572b3b76b5SKan Liang enum perf_uncore_icx_iio_freerunning_type_id {
54582b3b76b5SKan Liang 	ICX_IIO_MSR_IOCLK,
54592b3b76b5SKan Liang 	ICX_IIO_MSR_BW_IN,
54602b3b76b5SKan Liang 
54612b3b76b5SKan Liang 	ICX_IIO_FREERUNNING_TYPE_MAX,
54622b3b76b5SKan Liang };
54632b3b76b5SKan Liang 
54642b3b76b5SKan Liang static unsigned icx_iio_clk_freerunning_box_offsets[] = {
54652b3b76b5SKan Liang 	0x0, 0x20, 0x40, 0x90, 0xb0, 0xd0,
54662b3b76b5SKan Liang };
54672b3b76b5SKan Liang 
54682b3b76b5SKan Liang static unsigned icx_iio_bw_freerunning_box_offsets[] = {
54692b3b76b5SKan Liang 	0x0, 0x10, 0x20, 0x90, 0xa0, 0xb0,
54702b3b76b5SKan Liang };
54712b3b76b5SKan Liang 
54722b3b76b5SKan Liang static struct freerunning_counters icx_iio_freerunning[] = {
54732b3b76b5SKan Liang 	[ICX_IIO_MSR_IOCLK]	= { 0xa55, 0x1, 0x20, 1, 48, icx_iio_clk_freerunning_box_offsets },
54742b3b76b5SKan Liang 	[ICX_IIO_MSR_BW_IN]	= { 0xaa0, 0x1, 0x10, 8, 48, icx_iio_bw_freerunning_box_offsets },
54752b3b76b5SKan Liang };
54762b3b76b5SKan Liang 
54772b3b76b5SKan Liang static struct uncore_event_desc icx_uncore_iio_freerunning_events[] = {
54782b3b76b5SKan Liang 	/* Free-Running IIO CLOCKS Counter */
54792b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
54802b3b76b5SKan Liang 	/* Free-Running IIO BANDWIDTH IN Counters */
54812b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
54822b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
54832b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
54842b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
54852b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
54862b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
54872b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
54882b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
54892b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
54902b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
54912b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
54922b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
54932b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4,		"event=0xff,umask=0x24"),
54942b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale,	"3.814697266e-6"),
54952b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit,	"MiB"),
54962b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5,		"event=0xff,umask=0x25"),
54972b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale,	"3.814697266e-6"),
54982b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit,	"MiB"),
54992b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6,		"event=0xff,umask=0x26"),
55002b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale,	"3.814697266e-6"),
55012b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit,	"MiB"),
55022b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7,		"event=0xff,umask=0x27"),
55032b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale,	"3.814697266e-6"),
55042b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit,	"MiB"),
55052b3b76b5SKan Liang 	{ /* end: all zeroes */ },
55062b3b76b5SKan Liang };
55072b3b76b5SKan Liang 
55082b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_iio_free_running = {
55092b3b76b5SKan Liang 	.name			= "iio_free_running",
55102b3b76b5SKan Liang 	.num_counters		= 9,
55112b3b76b5SKan Liang 	.num_boxes		= 6,
55122b3b76b5SKan Liang 	.num_freerunning_types	= ICX_IIO_FREERUNNING_TYPE_MAX,
55132b3b76b5SKan Liang 	.freerunning		= icx_iio_freerunning,
55142b3b76b5SKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
55152b3b76b5SKan Liang 	.event_descs		= icx_uncore_iio_freerunning_events,
55162b3b76b5SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
55172b3b76b5SKan Liang };
55182b3b76b5SKan Liang 
55192b3b76b5SKan Liang static struct intel_uncore_type *icx_msr_uncores[] = {
55202b3b76b5SKan Liang 	&skx_uncore_ubox,
55212b3b76b5SKan Liang 	&icx_uncore_chabox,
55222b3b76b5SKan Liang 	&icx_uncore_iio,
55232b3b76b5SKan Liang 	&icx_uncore_irp,
55242b3b76b5SKan Liang 	&icx_uncore_m2pcie,
55252b3b76b5SKan Liang 	&skx_uncore_pcu,
55262b3b76b5SKan Liang 	&icx_uncore_iio_free_running,
55272b3b76b5SKan Liang 	NULL,
55282b3b76b5SKan Liang };
55292b3b76b5SKan Liang 
55302b3b76b5SKan Liang /*
55312b3b76b5SKan Liang  * To determine the number of CHAs, it should read CAPID6(Low) and CAPID7 (High)
55322b3b76b5SKan Liang  * registers which located at Device 30, Function 3
55332b3b76b5SKan Liang  */
55342b3b76b5SKan Liang #define ICX_CAPID6		0x9c
55352b3b76b5SKan Liang #define ICX_CAPID7		0xa0
55362b3b76b5SKan Liang 
icx_count_chabox(void)55372b3b76b5SKan Liang static u64 icx_count_chabox(void)
55382b3b76b5SKan Liang {
55392b3b76b5SKan Liang 	struct pci_dev *dev = NULL;
55402b3b76b5SKan Liang 	u64 caps = 0;
55412b3b76b5SKan Liang 
55422b3b76b5SKan Liang 	dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x345b, dev);
55432b3b76b5SKan Liang 	if (!dev)
55442b3b76b5SKan Liang 		goto out;
55452b3b76b5SKan Liang 
55462b3b76b5SKan Liang 	pci_read_config_dword(dev, ICX_CAPID6, (u32 *)&caps);
55472b3b76b5SKan Liang 	pci_read_config_dword(dev, ICX_CAPID7, (u32 *)&caps + 1);
55482b3b76b5SKan Liang out:
55492b3b76b5SKan Liang 	pci_dev_put(dev);
55502b3b76b5SKan Liang 	return hweight64(caps);
55512b3b76b5SKan Liang }
55522b3b76b5SKan Liang 
icx_uncore_cpu_init(void)55532b3b76b5SKan Liang void icx_uncore_cpu_init(void)
55542b3b76b5SKan Liang {
55552b3b76b5SKan Liang 	u64 num_boxes = icx_count_chabox();
55562b3b76b5SKan Liang 
55572b3b76b5SKan Liang 	if (WARN_ON(num_boxes > ARRAY_SIZE(icx_cha_msr_offsets)))
55582b3b76b5SKan Liang 		return;
55592b3b76b5SKan Liang 	icx_uncore_chabox.num_boxes = num_boxes;
55602b3b76b5SKan Liang 	uncore_msr_uncores = icx_msr_uncores;
55612b3b76b5SKan Liang }
55622b3b76b5SKan Liang 
55632b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_m2m = {
55642b3b76b5SKan Liang 	.name		= "m2m",
55652b3b76b5SKan Liang 	.num_counters   = 4,
55662b3b76b5SKan Liang 	.num_boxes	= 4,
55672b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
55682b3b76b5SKan Liang 	.perf_ctr	= SNR_M2M_PCI_PMON_CTR0,
55692b3b76b5SKan Liang 	.event_ctl	= SNR_M2M_PCI_PMON_CTL0,
55702b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
5571848ff376SKan Liang 	.event_mask_ext	= SNR_M2M_PCI_PMON_UMASK_EXT,
55722b3b76b5SKan Liang 	.box_ctl	= SNR_M2M_PCI_PMON_BOX_CTL,
55732b3b76b5SKan Liang 	.ops		= &snr_m2m_uncore_pci_ops,
5574848ff376SKan Liang 	.format_group	= &snr_m2m_uncore_format_group,
55752b3b76b5SKan Liang };
55762b3b76b5SKan Liang 
55772b3b76b5SKan Liang static struct attribute *icx_upi_uncore_formats_attr[] = {
55782b3b76b5SKan Liang 	&format_attr_event.attr,
55792b3b76b5SKan Liang 	&format_attr_umask_ext4.attr,
55802b3b76b5SKan Liang 	&format_attr_edge.attr,
55812b3b76b5SKan Liang 	&format_attr_inv.attr,
55822b3b76b5SKan Liang 	&format_attr_thresh8.attr,
55832b3b76b5SKan Liang 	NULL,
55842b3b76b5SKan Liang };
55852b3b76b5SKan Liang 
55862b3b76b5SKan Liang static const struct attribute_group icx_upi_uncore_format_group = {
55872b3b76b5SKan Liang 	.name = "format",
55882b3b76b5SKan Liang 	.attrs = icx_upi_uncore_formats_attr,
55892b3b76b5SKan Liang };
55902b3b76b5SKan Liang 
5591f680b6e6SAlexander Antonov #define ICX_UPI_REGS_ADDR_DEVICE_LINK0	0x02
5592f680b6e6SAlexander Antonov #define ICX_UPI_REGS_ADDR_FUNCTION	0x01
5593f680b6e6SAlexander Antonov 
discover_upi_topology(struct intel_uncore_type * type,int ubox_did,int dev_link0)5594f680b6e6SAlexander Antonov static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, int dev_link0)
5595f680b6e6SAlexander Antonov {
5596f680b6e6SAlexander Antonov 	struct pci_dev *ubox = NULL;
5597f680b6e6SAlexander Antonov 	struct pci_dev *dev = NULL;
5598f680b6e6SAlexander Antonov 	u32 nid, gid;
5599*bf1bf09eSAlexander Antonov 	int i, idx, lgc_pkg, ret = -EPERM;
5600f680b6e6SAlexander Antonov 	struct intel_uncore_topology *upi;
5601f680b6e6SAlexander Antonov 	unsigned int devfn;
5602f680b6e6SAlexander Antonov 
5603f680b6e6SAlexander Antonov 	/* GIDNIDMAP method supports machines which have less than 8 sockets. */
5604f680b6e6SAlexander Antonov 	if (uncore_max_dies() > 8)
5605f680b6e6SAlexander Antonov 		goto err;
5606f680b6e6SAlexander Antonov 
5607f680b6e6SAlexander Antonov 	while ((ubox = pci_get_device(PCI_VENDOR_ID_INTEL, ubox_did, ubox))) {
5608f680b6e6SAlexander Antonov 		ret = upi_nodeid_groupid(ubox, SKX_CPUNODEID, SKX_GIDNIDMAP, &nid, &gid);
5609f680b6e6SAlexander Antonov 		if (ret) {
5610f680b6e6SAlexander Antonov 			ret = pcibios_err_to_errno(ret);
5611f680b6e6SAlexander Antonov 			break;
5612f680b6e6SAlexander Antonov 		}
5613f680b6e6SAlexander Antonov 
5614f680b6e6SAlexander Antonov 		for (i = 0; i < 8; i++) {
5615f680b6e6SAlexander Antonov 			if (nid != GIDNIDMAP(gid, i))
5616f680b6e6SAlexander Antonov 				continue;
5617*bf1bf09eSAlexander Antonov 			lgc_pkg = topology_phys_to_logical_pkg(i);
5618*bf1bf09eSAlexander Antonov 			if (lgc_pkg < 0) {
5619*bf1bf09eSAlexander Antonov 				ret = -EPERM;
5620*bf1bf09eSAlexander Antonov 				goto err;
5621*bf1bf09eSAlexander Antonov 			}
5622f680b6e6SAlexander Antonov 			for (idx = 0; idx < type->num_boxes; idx++) {
5623*bf1bf09eSAlexander Antonov 				upi = &type->topology[lgc_pkg][idx];
5624f680b6e6SAlexander Antonov 				devfn = PCI_DEVFN(dev_link0 + idx, ICX_UPI_REGS_ADDR_FUNCTION);
5625f680b6e6SAlexander Antonov 				dev = pci_get_domain_bus_and_slot(pci_domain_nr(ubox->bus),
5626f680b6e6SAlexander Antonov 								  ubox->bus->number,
5627f680b6e6SAlexander Antonov 								  devfn);
5628f680b6e6SAlexander Antonov 				if (dev) {
5629f680b6e6SAlexander Antonov 					ret = upi_fill_topology(dev, upi, idx);
5630f680b6e6SAlexander Antonov 					if (ret)
5631f680b6e6SAlexander Antonov 						goto err;
5632f680b6e6SAlexander Antonov 				}
5633f680b6e6SAlexander Antonov 			}
5634*bf1bf09eSAlexander Antonov 			break;
5635f680b6e6SAlexander Antonov 		}
5636f680b6e6SAlexander Antonov 	}
5637f680b6e6SAlexander Antonov err:
5638f680b6e6SAlexander Antonov 	pci_dev_put(ubox);
5639f680b6e6SAlexander Antonov 	pci_dev_put(dev);
5640f680b6e6SAlexander Antonov 	return ret;
5641f680b6e6SAlexander Antonov }
5642f680b6e6SAlexander Antonov 
icx_upi_get_topology(struct intel_uncore_type * type)5643f680b6e6SAlexander Antonov static int icx_upi_get_topology(struct intel_uncore_type *type)
5644f680b6e6SAlexander Antonov {
5645f680b6e6SAlexander Antonov 	return discover_upi_topology(type, ICX_UBOX_DID, ICX_UPI_REGS_ADDR_DEVICE_LINK0);
5646f680b6e6SAlexander Antonov }
5647f680b6e6SAlexander Antonov 
5648f680b6e6SAlexander Antonov static struct attribute_group icx_upi_mapping_group = {
5649f680b6e6SAlexander Antonov 	.is_visible	= skx_upi_mapping_visible,
5650f680b6e6SAlexander Antonov };
5651f680b6e6SAlexander Antonov 
5652f680b6e6SAlexander Antonov static const struct attribute_group *icx_upi_attr_update[] = {
5653f680b6e6SAlexander Antonov 	&icx_upi_mapping_group,
5654f680b6e6SAlexander Antonov 	NULL
5655f680b6e6SAlexander Antonov };
5656f680b6e6SAlexander Antonov 
icx_upi_set_mapping(struct intel_uncore_type * type)5657d5b73506SAlexander Antonov static void icx_upi_set_mapping(struct intel_uncore_type *type)
5658f680b6e6SAlexander Antonov {
5659d5b73506SAlexander Antonov 	pmu_upi_set_mapping(type, &icx_upi_mapping_group);
5660f680b6e6SAlexander Antonov }
5661f680b6e6SAlexander Antonov 
icx_upi_cleanup_mapping(struct intel_uncore_type * type)5662f680b6e6SAlexander Antonov static void icx_upi_cleanup_mapping(struct intel_uncore_type *type)
5663f680b6e6SAlexander Antonov {
5664f680b6e6SAlexander Antonov 	pmu_cleanup_mapping(type, &icx_upi_mapping_group);
5665f680b6e6SAlexander Antonov }
5666f680b6e6SAlexander Antonov 
56672b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_upi = {
56682b3b76b5SKan Liang 	.name		= "upi",
56692b3b76b5SKan Liang 	.num_counters   = 4,
56702b3b76b5SKan Liang 	.num_boxes	= 3,
56712b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
56722b3b76b5SKan Liang 	.perf_ctr	= ICX_UPI_PCI_PMON_CTR0,
56732b3b76b5SKan Liang 	.event_ctl	= ICX_UPI_PCI_PMON_CTL0,
56742b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
56752b3b76b5SKan Liang 	.event_mask_ext = ICX_UPI_CTL_UMASK_EXT,
56762b3b76b5SKan Liang 	.box_ctl	= ICX_UPI_PCI_PMON_BOX_CTL,
56772b3b76b5SKan Liang 	.ops		= &skx_upi_uncore_pci_ops,
56782b3b76b5SKan Liang 	.format_group	= &icx_upi_uncore_format_group,
5679f680b6e6SAlexander Antonov 	.attr_update	= icx_upi_attr_update,
5680f680b6e6SAlexander Antonov 	.get_topology	= icx_upi_get_topology,
5681f680b6e6SAlexander Antonov 	.set_mapping	= icx_upi_set_mapping,
5682f680b6e6SAlexander Antonov 	.cleanup_mapping = icx_upi_cleanup_mapping,
56832b3b76b5SKan Liang };
56842b3b76b5SKan Liang 
56852b3b76b5SKan Liang static struct event_constraint icx_uncore_m3upi_constraints[] = {
56862b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1c, 0x1),
56872b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
56882b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
56892b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
56902b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
56912b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
56922b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
56932b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
56942b3b76b5SKan Liang 	EVENT_CONSTRAINT_END
56952b3b76b5SKan Liang };
56962b3b76b5SKan Liang 
56972b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_m3upi = {
56982b3b76b5SKan Liang 	.name		= "m3upi",
56992b3b76b5SKan Liang 	.num_counters   = 4,
57002b3b76b5SKan Liang 	.num_boxes	= 3,
57012b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
57022b3b76b5SKan Liang 	.perf_ctr	= ICX_M3UPI_PCI_PMON_CTR0,
57032b3b76b5SKan Liang 	.event_ctl	= ICX_M3UPI_PCI_PMON_CTL0,
57042b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
57052b3b76b5SKan Liang 	.box_ctl	= ICX_M3UPI_PCI_PMON_BOX_CTL,
57062b3b76b5SKan Liang 	.constraints	= icx_uncore_m3upi_constraints,
57072b3b76b5SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
57082b3b76b5SKan Liang 	.format_group	= &skx_uncore_format_group,
57092b3b76b5SKan Liang };
57102b3b76b5SKan Liang 
57112b3b76b5SKan Liang enum {
57122b3b76b5SKan Liang 	ICX_PCI_UNCORE_M2M,
57132b3b76b5SKan Liang 	ICX_PCI_UNCORE_UPI,
57142b3b76b5SKan Liang 	ICX_PCI_UNCORE_M3UPI,
57152b3b76b5SKan Liang };
57162b3b76b5SKan Liang 
57172b3b76b5SKan Liang static struct intel_uncore_type *icx_pci_uncores[] = {
57182b3b76b5SKan Liang 	[ICX_PCI_UNCORE_M2M]		= &icx_uncore_m2m,
57192b3b76b5SKan Liang 	[ICX_PCI_UNCORE_UPI]		= &icx_uncore_upi,
57202b3b76b5SKan Liang 	[ICX_PCI_UNCORE_M3UPI]		= &icx_uncore_m3upi,
57212b3b76b5SKan Liang 	NULL,
57222b3b76b5SKan Liang };
57232b3b76b5SKan Liang 
57242b3b76b5SKan Liang static const struct pci_device_id icx_uncore_pci_ids[] = {
57252b3b76b5SKan Liang 	{ /* M2M 0 */
57262b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
57272b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 0, ICX_PCI_UNCORE_M2M, 0),
57282b3b76b5SKan Liang 	},
57292b3b76b5SKan Liang 	{ /* M2M 1 */
57302b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
57312b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(13, 0, ICX_PCI_UNCORE_M2M, 1),
57322b3b76b5SKan Liang 	},
57332b3b76b5SKan Liang 	{ /* M2M 2 */
57342b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
57352b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(14, 0, ICX_PCI_UNCORE_M2M, 2),
57362b3b76b5SKan Liang 	},
57372b3b76b5SKan Liang 	{ /* M2M 3 */
57382b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
57392b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(15, 0, ICX_PCI_UNCORE_M2M, 3),
57402b3b76b5SKan Liang 	},
57412b3b76b5SKan Liang 	{ /* UPI Link 0 */
57422b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441),
57432b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(2, 1, ICX_PCI_UNCORE_UPI, 0),
57442b3b76b5SKan Liang 	},
57452b3b76b5SKan Liang 	{ /* UPI Link 1 */
57462b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441),
57472b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(3, 1, ICX_PCI_UNCORE_UPI, 1),
57482b3b76b5SKan Liang 	},
57492b3b76b5SKan Liang 	{ /* UPI Link 2 */
57502b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441),
57512b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(4, 1, ICX_PCI_UNCORE_UPI, 2),
57522b3b76b5SKan Liang 	},
57532b3b76b5SKan Liang 	{ /* M3UPI Link 0 */
57542b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446),
57552b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(5, 1, ICX_PCI_UNCORE_M3UPI, 0),
57562b3b76b5SKan Liang 	},
57572b3b76b5SKan Liang 	{ /* M3UPI Link 1 */
57582b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446),
57592b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(6, 1, ICX_PCI_UNCORE_M3UPI, 1),
57602b3b76b5SKan Liang 	},
57612b3b76b5SKan Liang 	{ /* M3UPI Link 2 */
57622b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446),
57632b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(7, 1, ICX_PCI_UNCORE_M3UPI, 2),
57642b3b76b5SKan Liang 	},
57652b3b76b5SKan Liang 	{ /* end: all zeroes */ }
57662b3b76b5SKan Liang };
57672b3b76b5SKan Liang 
57682b3b76b5SKan Liang static struct pci_driver icx_uncore_pci_driver = {
57692b3b76b5SKan Liang 	.name		= "icx_uncore",
57702b3b76b5SKan Liang 	.id_table	= icx_uncore_pci_ids,
57712b3b76b5SKan Liang };
57722b3b76b5SKan Liang 
icx_uncore_pci_init(void)57732b3b76b5SKan Liang int icx_uncore_pci_init(void)
57742b3b76b5SKan Liang {
57752b3b76b5SKan Liang 	/* ICX UBOX DID */
57762b3b76b5SKan Liang 	int ret = snbep_pci2phy_map_init(0x3450, SKX_CPUNODEID,
57772b3b76b5SKan Liang 					 SKX_GIDNIDMAP, true);
57782b3b76b5SKan Liang 
57792b3b76b5SKan Liang 	if (ret)
57802b3b76b5SKan Liang 		return ret;
57812b3b76b5SKan Liang 
57822b3b76b5SKan Liang 	uncore_pci_uncores = icx_pci_uncores;
57832b3b76b5SKan Liang 	uncore_pci_driver = &icx_uncore_pci_driver;
57842b3b76b5SKan Liang 	return 0;
57852b3b76b5SKan Liang }
57862b3b76b5SKan Liang 
icx_uncore_imc_init_box(struct intel_uncore_box * box)57872b3b76b5SKan Liang static void icx_uncore_imc_init_box(struct intel_uncore_box *box)
57882b3b76b5SKan Liang {
57892b3b76b5SKan Liang 	unsigned int box_ctl = box->pmu->type->box_ctl +
57902b3b76b5SKan Liang 			       box->pmu->type->mmio_offset * (box->pmu->pmu_idx % ICX_NUMBER_IMC_CHN);
57912b3b76b5SKan Liang 	int mem_offset = (box->pmu->pmu_idx / ICX_NUMBER_IMC_CHN) * ICX_IMC_MEM_STRIDE +
57922b3b76b5SKan Liang 			 SNR_IMC_MMIO_MEM0_OFFSET;
57932b3b76b5SKan Liang 
57941583971bSKan Liang 	__snr_uncore_mmio_init_box(box, box_ctl, mem_offset,
57951583971bSKan Liang 				   SNR_MC_DEVICE_ID);
57962b3b76b5SKan Liang }
57972b3b76b5SKan Liang 
57982b3b76b5SKan Liang static struct intel_uncore_ops icx_uncore_mmio_ops = {
57992b3b76b5SKan Liang 	.init_box	= icx_uncore_imc_init_box,
58002b3b76b5SKan Liang 	.exit_box	= uncore_mmio_exit_box,
58012b3b76b5SKan Liang 	.disable_box	= snr_uncore_mmio_disable_box,
58022b3b76b5SKan Liang 	.enable_box	= snr_uncore_mmio_enable_box,
58032b3b76b5SKan Liang 	.disable_event	= snr_uncore_mmio_disable_event,
58042b3b76b5SKan Liang 	.enable_event	= snr_uncore_mmio_enable_event,
58052b3b76b5SKan Liang 	.read_counter	= uncore_mmio_read_counter,
58062b3b76b5SKan Liang };
58072b3b76b5SKan Liang 
58082b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_imc = {
58092b3b76b5SKan Liang 	.name		= "imc",
58102b3b76b5SKan Liang 	.num_counters   = 4,
5811496a18f0SKan Liang 	.num_boxes	= 12,
58122b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
58132b3b76b5SKan Liang 	.fixed_ctr_bits	= 48,
58142b3b76b5SKan Liang 	.fixed_ctr	= SNR_IMC_MMIO_PMON_FIXED_CTR,
58152b3b76b5SKan Liang 	.fixed_ctl	= SNR_IMC_MMIO_PMON_FIXED_CTL,
581696fd2e89SZhengjun Xing 	.event_descs	= snr_uncore_imc_events,
58172b3b76b5SKan Liang 	.perf_ctr	= SNR_IMC_MMIO_PMON_CTR0,
58182b3b76b5SKan Liang 	.event_ctl	= SNR_IMC_MMIO_PMON_CTL0,
58192b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
58202b3b76b5SKan Liang 	.box_ctl	= SNR_IMC_MMIO_PMON_BOX_CTL,
58212b3b76b5SKan Liang 	.mmio_offset	= SNR_IMC_MMIO_OFFSET,
58221b94d31dSKan Liang 	.mmio_map_size	= SNR_IMC_MMIO_SIZE,
58232b3b76b5SKan Liang 	.ops		= &icx_uncore_mmio_ops,
58242b3b76b5SKan Liang 	.format_group	= &skx_uncore_format_group,
58252b3b76b5SKan Liang };
58262b3b76b5SKan Liang 
58272b3b76b5SKan Liang enum perf_uncore_icx_imc_freerunning_type_id {
58282b3b76b5SKan Liang 	ICX_IMC_DCLK,
58292b3b76b5SKan Liang 	ICX_IMC_DDR,
58302b3b76b5SKan Liang 	ICX_IMC_DDRT,
58312b3b76b5SKan Liang 
58322b3b76b5SKan Liang 	ICX_IMC_FREERUNNING_TYPE_MAX,
58332b3b76b5SKan Liang };
58342b3b76b5SKan Liang 
58352b3b76b5SKan Liang static struct freerunning_counters icx_imc_freerunning[] = {
58362b3b76b5SKan Liang 	[ICX_IMC_DCLK]	= { 0x22b0, 0x0, 0, 1, 48 },
58372b3b76b5SKan Liang 	[ICX_IMC_DDR]	= { 0x2290, 0x8, 0, 2, 48 },
58382b3b76b5SKan Liang 	[ICX_IMC_DDRT]	= { 0x22a0, 0x8, 0, 2, 48 },
58392b3b76b5SKan Liang };
58402b3b76b5SKan Liang 
58412b3b76b5SKan Liang static struct uncore_event_desc icx_uncore_imc_freerunning_events[] = {
58422b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(dclk,			"event=0xff,umask=0x10"),
58432b3b76b5SKan Liang 
58442b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(read,			"event=0xff,umask=0x20"),
58458191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(read.scale,		"6.103515625e-5"),
58462b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(read.unit,		"MiB"),
58472b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(write,			"event=0xff,umask=0x21"),
58488191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(write.scale,		"6.103515625e-5"),
58492b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(write.unit,		"MiB"),
58502b3b76b5SKan Liang 
58512b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_read,		"event=0xff,umask=0x30"),
58528191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_read.scale,	"6.103515625e-5"),
58532b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_read.unit,		"MiB"),
58542b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_write,		"event=0xff,umask=0x31"),
58558191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_write.scale,	"6.103515625e-5"),
58562b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_write.unit,	"MiB"),
58572b3b76b5SKan Liang 	{ /* end: all zeroes */ },
58582b3b76b5SKan Liang };
58592b3b76b5SKan Liang 
icx_uncore_imc_freerunning_init_box(struct intel_uncore_box * box)58602b3b76b5SKan Liang static void icx_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
58612b3b76b5SKan Liang {
58622b3b76b5SKan Liang 	int mem_offset = box->pmu->pmu_idx * ICX_IMC_MEM_STRIDE +
58632b3b76b5SKan Liang 			 SNR_IMC_MMIO_MEM0_OFFSET;
58642b3b76b5SKan Liang 
58651583971bSKan Liang 	snr_uncore_mmio_map(box, uncore_mmio_box_ctl(box),
58661583971bSKan Liang 			    mem_offset, SNR_MC_DEVICE_ID);
58672b3b76b5SKan Liang }
58682b3b76b5SKan Liang 
58692b3b76b5SKan Liang static struct intel_uncore_ops icx_uncore_imc_freerunning_ops = {
58702b3b76b5SKan Liang 	.init_box	= icx_uncore_imc_freerunning_init_box,
58712b3b76b5SKan Liang 	.exit_box	= uncore_mmio_exit_box,
58722b3b76b5SKan Liang 	.read_counter	= uncore_mmio_read_counter,
58732b3b76b5SKan Liang 	.hw_config	= uncore_freerunning_hw_config,
58742b3b76b5SKan Liang };
58752b3b76b5SKan Liang 
58762b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_imc_free_running = {
58772b3b76b5SKan Liang 	.name			= "imc_free_running",
58782b3b76b5SKan Liang 	.num_counters		= 5,
58792b3b76b5SKan Liang 	.num_boxes		= 4,
58802b3b76b5SKan Liang 	.num_freerunning_types	= ICX_IMC_FREERUNNING_TYPE_MAX,
58811b94d31dSKan Liang 	.mmio_map_size		= SNR_IMC_MMIO_SIZE,
58822b3b76b5SKan Liang 	.freerunning		= icx_imc_freerunning,
58832b3b76b5SKan Liang 	.ops			= &icx_uncore_imc_freerunning_ops,
58842b3b76b5SKan Liang 	.event_descs		= icx_uncore_imc_freerunning_events,
58852b3b76b5SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
58862b3b76b5SKan Liang };
58872b3b76b5SKan Liang 
58882b3b76b5SKan Liang static struct intel_uncore_type *icx_mmio_uncores[] = {
58892b3b76b5SKan Liang 	&icx_uncore_imc,
58902b3b76b5SKan Liang 	&icx_uncore_imc_free_running,
58912b3b76b5SKan Liang 	NULL,
58922b3b76b5SKan Liang };
58932b3b76b5SKan Liang 
icx_uncore_mmio_init(void)58942b3b76b5SKan Liang void icx_uncore_mmio_init(void)
58952b3b76b5SKan Liang {
58962b3b76b5SKan Liang 	uncore_mmio_uncores = icx_mmio_uncores;
58972b3b76b5SKan Liang }
58982b3b76b5SKan Liang 
58992b3b76b5SKan Liang /* end of ICX uncore support */
5900c54c53d9SKan Liang 
5901c54c53d9SKan Liang /* SPR uncore support */
5902c54c53d9SKan Liang 
spr_uncore_msr_enable_event(struct intel_uncore_box * box,struct perf_event * event)5903949b1138SKan Liang static void spr_uncore_msr_enable_event(struct intel_uncore_box *box,
5904949b1138SKan Liang 					struct perf_event *event)
5905949b1138SKan Liang {
5906949b1138SKan Liang 	struct hw_perf_event *hwc = &event->hw;
5907949b1138SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
5908949b1138SKan Liang 
5909949b1138SKan Liang 	if (reg1->idx != EXTRA_REG_NONE)
5910949b1138SKan Liang 		wrmsrl(reg1->reg, reg1->config);
5911949b1138SKan Liang 
5912949b1138SKan Liang 	wrmsrl(hwc->config_base, hwc->config);
5913949b1138SKan Liang }
5914949b1138SKan Liang 
spr_uncore_msr_disable_event(struct intel_uncore_box * box,struct perf_event * event)5915949b1138SKan Liang static void spr_uncore_msr_disable_event(struct intel_uncore_box *box,
5916949b1138SKan Liang 					 struct perf_event *event)
5917949b1138SKan Liang {
5918949b1138SKan Liang 	struct hw_perf_event *hwc = &event->hw;
5919949b1138SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
5920949b1138SKan Liang 
5921949b1138SKan Liang 	if (reg1->idx != EXTRA_REG_NONE)
5922949b1138SKan Liang 		wrmsrl(reg1->reg, 0);
5923949b1138SKan Liang 
5924949b1138SKan Liang 	wrmsrl(hwc->config_base, 0);
5925949b1138SKan Liang }
5926949b1138SKan Liang 
spr_cha_hw_config(struct intel_uncore_box * box,struct perf_event * event)5927949b1138SKan Liang static int spr_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
5928949b1138SKan Liang {
5929949b1138SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
5930949b1138SKan Liang 	bool tie_en = !!(event->hw.config & SPR_CHA_PMON_CTL_TID_EN);
5931949b1138SKan Liang 	struct intel_uncore_type *type = box->pmu->type;
5932949b1138SKan Liang 
5933949b1138SKan Liang 	if (tie_en) {
5934949b1138SKan Liang 		reg1->reg = SPR_C0_MSR_PMON_BOX_FILTER0 +
5935949b1138SKan Liang 			    HSWEP_CBO_MSR_OFFSET * type->box_ids[box->pmu->pmu_idx];
5936949b1138SKan Liang 		reg1->config = event->attr.config1 & SPR_CHA_PMON_BOX_FILTER_TID;
5937949b1138SKan Liang 		reg1->idx = 0;
5938949b1138SKan Liang 	}
5939949b1138SKan Liang 
5940949b1138SKan Liang 	return 0;
5941949b1138SKan Liang }
5942949b1138SKan Liang 
5943949b1138SKan Liang static struct intel_uncore_ops spr_uncore_chabox_ops = {
5944949b1138SKan Liang 	.init_box		= intel_generic_uncore_msr_init_box,
5945949b1138SKan Liang 	.disable_box		= intel_generic_uncore_msr_disable_box,
5946949b1138SKan Liang 	.enable_box		= intel_generic_uncore_msr_enable_box,
5947949b1138SKan Liang 	.disable_event		= spr_uncore_msr_disable_event,
5948949b1138SKan Liang 	.enable_event		= spr_uncore_msr_enable_event,
5949949b1138SKan Liang 	.read_counter		= uncore_msr_read_counter,
5950949b1138SKan Liang 	.hw_config		= spr_cha_hw_config,
5951949b1138SKan Liang 	.get_constraint		= uncore_get_constraint,
5952949b1138SKan Liang 	.put_constraint		= uncore_put_constraint,
5953949b1138SKan Liang };
5954949b1138SKan Liang 
5955949b1138SKan Liang static struct attribute *spr_uncore_cha_formats_attr[] = {
5956949b1138SKan Liang 	&format_attr_event.attr,
5957949b1138SKan Liang 	&format_attr_umask_ext4.attr,
5958949b1138SKan Liang 	&format_attr_tid_en2.attr,
5959949b1138SKan Liang 	&format_attr_edge.attr,
5960949b1138SKan Liang 	&format_attr_inv.attr,
5961949b1138SKan Liang 	&format_attr_thresh8.attr,
5962949b1138SKan Liang 	&format_attr_filter_tid5.attr,
5963949b1138SKan Liang 	NULL,
5964949b1138SKan Liang };
5965949b1138SKan Liang static const struct attribute_group spr_uncore_chabox_format_group = {
5966949b1138SKan Liang 	.name = "format",
5967949b1138SKan Liang 	.attrs = spr_uncore_cha_formats_attr,
5968949b1138SKan Liang };
5969949b1138SKan Liang 
alias_show(struct device * dev,struct device_attribute * attr,char * buf)59708053f2d7SKan Liang static ssize_t alias_show(struct device *dev,
59718053f2d7SKan Liang 			  struct device_attribute *attr,
59728053f2d7SKan Liang 			  char *buf)
59738053f2d7SKan Liang {
59748053f2d7SKan Liang 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(dev);
59758053f2d7SKan Liang 	char pmu_name[UNCORE_PMU_NAME_LEN];
59768053f2d7SKan Liang 
59778053f2d7SKan Liang 	uncore_get_alias_name(pmu_name, pmu);
59788053f2d7SKan Liang 	return sysfs_emit(buf, "%s\n", pmu_name);
59798053f2d7SKan Liang }
59808053f2d7SKan Liang 
59818053f2d7SKan Liang static DEVICE_ATTR_RO(alias);
59828053f2d7SKan Liang 
59838053f2d7SKan Liang static struct attribute *uncore_alias_attrs[] = {
59848053f2d7SKan Liang 	&dev_attr_alias.attr,
59858053f2d7SKan Liang 	NULL
59868053f2d7SKan Liang };
59878053f2d7SKan Liang 
59888053f2d7SKan Liang ATTRIBUTE_GROUPS(uncore_alias);
59898053f2d7SKan Liang 
5990949b1138SKan Liang static struct intel_uncore_type spr_uncore_chabox = {
5991949b1138SKan Liang 	.name			= "cha",
5992949b1138SKan Liang 	.event_mask		= SPR_CHA_PMON_EVENT_MASK,
5993949b1138SKan Liang 	.event_mask_ext		= SPR_RAW_EVENT_MASK_EXT,
5994949b1138SKan Liang 	.num_shared_regs	= 1,
59959d756e40SKan Liang 	.constraints		= skx_uncore_chabox_constraints,
5996949b1138SKan Liang 	.ops			= &spr_uncore_chabox_ops,
5997949b1138SKan Liang 	.format_group		= &spr_uncore_chabox_format_group,
59988053f2d7SKan Liang 	.attr_update		= uncore_alias_groups,
5999949b1138SKan Liang };
6000949b1138SKan Liang 
60013ba7095bSKan Liang static struct intel_uncore_type spr_uncore_iio = {
60023ba7095bSKan Liang 	.name			= "iio",
60033ba7095bSKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
60043ba7095bSKan Liang 	.event_mask_ext		= SNR_IIO_PMON_RAW_EVENT_MASK_EXT,
60053ba7095bSKan Liang 	.format_group		= &snr_uncore_iio_format_group,
60068053f2d7SKan Liang 	.attr_update		= uncore_alias_groups,
600767c5d443SKan Liang 	.constraints		= icx_uncore_iio_constraints,
60083ba7095bSKan Liang };
60093ba7095bSKan Liang 
6010e199eb51SKan Liang static struct attribute *spr_uncore_raw_formats_attr[] = {
6011e199eb51SKan Liang 	&format_attr_event.attr,
6012e199eb51SKan Liang 	&format_attr_umask_ext4.attr,
6013e199eb51SKan Liang 	&format_attr_edge.attr,
6014e199eb51SKan Liang 	&format_attr_inv.attr,
6015e199eb51SKan Liang 	&format_attr_thresh8.attr,
6016e199eb51SKan Liang 	NULL,
6017e199eb51SKan Liang };
6018e199eb51SKan Liang 
6019e199eb51SKan Liang static const struct attribute_group spr_uncore_raw_format_group = {
6020e199eb51SKan Liang 	.name			= "format",
6021e199eb51SKan Liang 	.attrs			= spr_uncore_raw_formats_attr,
6022e199eb51SKan Liang };
6023e199eb51SKan Liang 
6024e199eb51SKan Liang #define SPR_UNCORE_COMMON_FORMAT()				\
6025e199eb51SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,	\
6026e199eb51SKan Liang 	.event_mask_ext		= SPR_RAW_EVENT_MASK_EXT,	\
60278053f2d7SKan Liang 	.format_group		= &spr_uncore_raw_format_group,	\
60288053f2d7SKan Liang 	.attr_update		= uncore_alias_groups
6029e199eb51SKan Liang 
6030e199eb51SKan Liang static struct intel_uncore_type spr_uncore_irp = {
6031e199eb51SKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
6032e199eb51SKan Liang 	.name			= "irp",
6033e199eb51SKan Liang 
6034e199eb51SKan Liang };
6035e199eb51SKan Liang 
6036f01d7d55SKan Liang static struct event_constraint spr_uncore_m2pcie_constraints[] = {
6037f01d7d55SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
6038f01d7d55SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
6039f01d7d55SKan Liang 	EVENT_CONSTRAINT_END
6040f01d7d55SKan Liang };
6041f01d7d55SKan Liang 
6042f85ef898SKan Liang static struct intel_uncore_type spr_uncore_m2pcie = {
6043f85ef898SKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
6044f85ef898SKan Liang 	.name			= "m2pcie",
6045f01d7d55SKan Liang 	.constraints		= spr_uncore_m2pcie_constraints,
6046f85ef898SKan Liang };
6047f85ef898SKan Liang 
60480654dfdcSKan Liang static struct intel_uncore_type spr_uncore_pcu = {
60490654dfdcSKan Liang 	.name			= "pcu",
60508053f2d7SKan Liang 	.attr_update		= uncore_alias_groups,
60510654dfdcSKan Liang };
60520654dfdcSKan Liang 
spr_uncore_mmio_enable_event(struct intel_uncore_box * box,struct perf_event * event)605385f2e30fSKan Liang static void spr_uncore_mmio_enable_event(struct intel_uncore_box *box,
605485f2e30fSKan Liang 					 struct perf_event *event)
605585f2e30fSKan Liang {
605685f2e30fSKan Liang 	struct hw_perf_event *hwc = &event->hw;
605785f2e30fSKan Liang 
605885f2e30fSKan Liang 	if (!box->io_addr)
605985f2e30fSKan Liang 		return;
606085f2e30fSKan Liang 
606185f2e30fSKan Liang 	if (uncore_pmc_fixed(hwc->idx))
606285f2e30fSKan Liang 		writel(SNBEP_PMON_CTL_EN, box->io_addr + hwc->config_base);
606385f2e30fSKan Liang 	else
606485f2e30fSKan Liang 		writel(hwc->config, box->io_addr + hwc->config_base);
606585f2e30fSKan Liang }
606685f2e30fSKan Liang 
606785f2e30fSKan Liang static struct intel_uncore_ops spr_uncore_mmio_ops = {
606885f2e30fSKan Liang 	.init_box		= intel_generic_uncore_mmio_init_box,
606985f2e30fSKan Liang 	.exit_box		= uncore_mmio_exit_box,
607085f2e30fSKan Liang 	.disable_box		= intel_generic_uncore_mmio_disable_box,
607185f2e30fSKan Liang 	.enable_box		= intel_generic_uncore_mmio_enable_box,
607285f2e30fSKan Liang 	.disable_event		= intel_generic_uncore_mmio_disable_event,
607385f2e30fSKan Liang 	.enable_event		= spr_uncore_mmio_enable_event,
607485f2e30fSKan Liang 	.read_counter		= uncore_mmio_read_counter,
607585f2e30fSKan Liang };
607685f2e30fSKan Liang 
6077743767d6SStephane Eranian static struct uncore_event_desc spr_uncore_imc_events[] = {
6078743767d6SStephane Eranian 	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0x01,umask=0x00"),
6079743767d6SStephane Eranian 	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x05,umask=0xcf"),
6080743767d6SStephane Eranian 	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
6081743767d6SStephane Eranian 	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
6082743767d6SStephane Eranian 	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x05,umask=0xf0"),
6083743767d6SStephane Eranian 	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
6084743767d6SStephane Eranian 	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
6085743767d6SStephane Eranian 	{ /* end: all zeroes */ },
6086743767d6SStephane Eranian };
6087743767d6SStephane Eranian 
608885f2e30fSKan Liang static struct intel_uncore_type spr_uncore_imc = {
608985f2e30fSKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
609085f2e30fSKan Liang 	.name			= "imc",
609185f2e30fSKan Liang 	.fixed_ctr_bits		= 48,
609285f2e30fSKan Liang 	.fixed_ctr		= SNR_IMC_MMIO_PMON_FIXED_CTR,
609385f2e30fSKan Liang 	.fixed_ctl		= SNR_IMC_MMIO_PMON_FIXED_CTL,
609485f2e30fSKan Liang 	.ops			= &spr_uncore_mmio_ops,
6095743767d6SStephane Eranian 	.event_descs		= spr_uncore_imc_events,
609685f2e30fSKan Liang };
609785f2e30fSKan Liang 
spr_uncore_pci_enable_event(struct intel_uncore_box * box,struct perf_event * event)6098f57191edSKan Liang static void spr_uncore_pci_enable_event(struct intel_uncore_box *box,
6099f57191edSKan Liang 					struct perf_event *event)
6100f57191edSKan Liang {
6101f57191edSKan Liang 	struct pci_dev *pdev = box->pci_dev;
6102f57191edSKan Liang 	struct hw_perf_event *hwc = &event->hw;
6103f57191edSKan Liang 
6104f57191edSKan Liang 	pci_write_config_dword(pdev, hwc->config_base + 4, (u32)(hwc->config >> 32));
6105f57191edSKan Liang 	pci_write_config_dword(pdev, hwc->config_base, (u32)hwc->config);
6106f57191edSKan Liang }
6107f57191edSKan Liang 
6108f57191edSKan Liang static struct intel_uncore_ops spr_uncore_pci_ops = {
6109f57191edSKan Liang 	.init_box		= intel_generic_uncore_pci_init_box,
6110f57191edSKan Liang 	.disable_box		= intel_generic_uncore_pci_disable_box,
6111f57191edSKan Liang 	.enable_box		= intel_generic_uncore_pci_enable_box,
6112f57191edSKan Liang 	.disable_event		= intel_generic_uncore_pci_disable_event,
6113f57191edSKan Liang 	.enable_event		= spr_uncore_pci_enable_event,
6114f57191edSKan Liang 	.read_counter		= intel_generic_uncore_pci_read_counter,
6115f57191edSKan Liang };
6116f57191edSKan Liang 
6117f57191edSKan Liang #define SPR_UNCORE_PCI_COMMON_FORMAT()			\
6118f57191edSKan Liang 	SPR_UNCORE_COMMON_FORMAT(),			\
6119f57191edSKan Liang 	.ops			= &spr_uncore_pci_ops
6120f57191edSKan Liang 
6121f57191edSKan Liang static struct intel_uncore_type spr_uncore_m2m = {
6122f57191edSKan Liang 	SPR_UNCORE_PCI_COMMON_FORMAT(),
6123f57191edSKan Liang 	.name			= "m2m",
6124f57191edSKan Liang };
6125f57191edSKan Liang 
61269a3b675cSAlexander Antonov static struct attribute_group spr_upi_mapping_group = {
61279a3b675cSAlexander Antonov 	.is_visible	= skx_upi_mapping_visible,
61289a3b675cSAlexander Antonov };
61299a3b675cSAlexander Antonov 
61309a3b675cSAlexander Antonov static const struct attribute_group *spr_upi_attr_update[] = {
61319a3b675cSAlexander Antonov 	&uncore_alias_group,
61329a3b675cSAlexander Antonov 	&spr_upi_mapping_group,
61339a3b675cSAlexander Antonov 	NULL
61349a3b675cSAlexander Antonov };
61359a3b675cSAlexander Antonov 
61369a3b675cSAlexander Antonov #define SPR_UPI_REGS_ADDR_DEVICE_LINK0	0x01
61379a3b675cSAlexander Antonov 
spr_upi_set_mapping(struct intel_uncore_type * type)6138d5b73506SAlexander Antonov static void spr_upi_set_mapping(struct intel_uncore_type *type)
61399a3b675cSAlexander Antonov {
6140d5b73506SAlexander Antonov 	pmu_upi_set_mapping(type, &spr_upi_mapping_group);
61419a3b675cSAlexander Antonov }
61429a3b675cSAlexander Antonov 
spr_upi_cleanup_mapping(struct intel_uncore_type * type)61439a3b675cSAlexander Antonov static void spr_upi_cleanup_mapping(struct intel_uncore_type *type)
61449a3b675cSAlexander Antonov {
61459a3b675cSAlexander Antonov 	pmu_cleanup_mapping(type, &spr_upi_mapping_group);
61469a3b675cSAlexander Antonov }
61479a3b675cSAlexander Antonov 
spr_upi_get_topology(struct intel_uncore_type * type)61489a3b675cSAlexander Antonov static int spr_upi_get_topology(struct intel_uncore_type *type)
61499a3b675cSAlexander Antonov {
61509a3b675cSAlexander Antonov 	return discover_upi_topology(type, SPR_UBOX_DID, SPR_UPI_REGS_ADDR_DEVICE_LINK0);
61519a3b675cSAlexander Antonov }
61529a3b675cSAlexander Antonov 
615365248a9aSKan Liang static struct intel_uncore_type spr_uncore_mdf = {
615465248a9aSKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
615565248a9aSKan Liang 	.name			= "mdf",
615665248a9aSKan Liang };
615765248a9aSKan Liang 
615865248a9aSKan Liang #define UNCORE_SPR_NUM_UNCORE_TYPES		12
615938776cc4SKan Liang #define UNCORE_SPR_CHA				0
616065248a9aSKan Liang #define UNCORE_SPR_IIO				1
616165248a9aSKan Liang #define UNCORE_SPR_IMC				6
616265248a9aSKan Liang #define UNCORE_SPR_UPI				8
616365248a9aSKan Liang #define UNCORE_SPR_M3UPI			9
616465248a9aSKan Liang 
616565248a9aSKan Liang /*
616665248a9aSKan Liang  * The uncore units, which are supported by the discovery table,
616765248a9aSKan Liang  * are defined here.
616865248a9aSKan Liang  */
616965248a9aSKan Liang static struct intel_uncore_type *spr_uncores[UNCORE_SPR_NUM_UNCORE_TYPES] = {
617065248a9aSKan Liang 	&spr_uncore_chabox,
617165248a9aSKan Liang 	&spr_uncore_iio,
617265248a9aSKan Liang 	&spr_uncore_irp,
617365248a9aSKan Liang 	&spr_uncore_m2pcie,
617465248a9aSKan Liang 	&spr_uncore_pcu,
617565248a9aSKan Liang 	NULL,
617665248a9aSKan Liang 	&spr_uncore_imc,
617765248a9aSKan Liang 	&spr_uncore_m2m,
617865248a9aSKan Liang 	NULL,
617965248a9aSKan Liang 	NULL,
618065248a9aSKan Liang 	NULL,
618165248a9aSKan Liang 	&spr_uncore_mdf,
618265248a9aSKan Liang };
618365248a9aSKan Liang 
618465248a9aSKan Liang /*
618565248a9aSKan Liang  * The uncore units, which are not supported by the discovery table,
618665248a9aSKan Liang  * are implemented from here.
618765248a9aSKan Liang  */
618865248a9aSKan Liang #define SPR_UNCORE_UPI_NUM_BOXES	4
618965248a9aSKan Liang 
619065248a9aSKan Liang static unsigned int spr_upi_pci_offsets[SPR_UNCORE_UPI_NUM_BOXES] = {
619165248a9aSKan Liang 	0, 0x8000, 0x10000, 0x18000
619265248a9aSKan Liang };
619365248a9aSKan Liang 
6194da5a9156SKan Liang static struct intel_uncore_type spr_uncore_upi = {
61959a3b675cSAlexander Antonov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
61969a3b675cSAlexander Antonov 	.event_mask_ext		= SPR_RAW_EVENT_MASK_EXT,
61979a3b675cSAlexander Antonov 	.format_group		= &spr_uncore_raw_format_group,
61989a3b675cSAlexander Antonov 	.ops			= &spr_uncore_pci_ops,
6199da5a9156SKan Liang 	.name			= "upi",
62009a3b675cSAlexander Antonov 	.attr_update		= spr_upi_attr_update,
62019a3b675cSAlexander Antonov 	.get_topology		= spr_upi_get_topology,
62029a3b675cSAlexander Antonov 	.set_mapping		= spr_upi_set_mapping,
62039a3b675cSAlexander Antonov 	.cleanup_mapping	= spr_upi_cleanup_mapping,
620465248a9aSKan Liang 	.type_id		= UNCORE_SPR_UPI,
620565248a9aSKan Liang 	.num_counters		= 4,
620665248a9aSKan Liang 	.num_boxes		= SPR_UNCORE_UPI_NUM_BOXES,
620765248a9aSKan Liang 	.perf_ctr_bits		= 48,
620865248a9aSKan Liang 	.perf_ctr		= ICX_UPI_PCI_PMON_CTR0,
620965248a9aSKan Liang 	.event_ctl		= ICX_UPI_PCI_PMON_CTL0,
621065248a9aSKan Liang 	.box_ctl		= ICX_UPI_PCI_PMON_BOX_CTL,
621165248a9aSKan Liang 	.pci_offsets		= spr_upi_pci_offsets,
6212da5a9156SKan Liang };
6213da5a9156SKan Liang 
62142a8e51eaSKan Liang static struct intel_uncore_type spr_uncore_m3upi = {
62152a8e51eaSKan Liang 	SPR_UNCORE_PCI_COMMON_FORMAT(),
62162a8e51eaSKan Liang 	.name			= "m3upi",
621765248a9aSKan Liang 	.type_id		= UNCORE_SPR_M3UPI,
621865248a9aSKan Liang 	.num_counters		= 4,
621965248a9aSKan Liang 	.num_boxes		= SPR_UNCORE_UPI_NUM_BOXES,
622065248a9aSKan Liang 	.perf_ctr_bits		= 48,
622165248a9aSKan Liang 	.perf_ctr		= ICX_M3UPI_PCI_PMON_CTR0,
622265248a9aSKan Liang 	.event_ctl		= ICX_M3UPI_PCI_PMON_CTL0,
622365248a9aSKan Liang 	.box_ctl		= ICX_M3UPI_PCI_PMON_BOX_CTL,
622465248a9aSKan Liang 	.pci_offsets		= spr_upi_pci_offsets,
62254034fb20SKan Liang 	.constraints		= icx_uncore_m3upi_constraints,
62262a8e51eaSKan Liang };
62272a8e51eaSKan Liang 
62280378c93aSKan Liang enum perf_uncore_spr_iio_freerunning_type_id {
62290378c93aSKan Liang 	SPR_IIO_MSR_IOCLK,
62300378c93aSKan Liang 	SPR_IIO_MSR_BW_IN,
62310378c93aSKan Liang 	SPR_IIO_MSR_BW_OUT,
62320378c93aSKan Liang 
62330378c93aSKan Liang 	SPR_IIO_FREERUNNING_TYPE_MAX,
62340378c93aSKan Liang };
62350378c93aSKan Liang 
62360378c93aSKan Liang static struct freerunning_counters spr_iio_freerunning[] = {
62370378c93aSKan Liang 	[SPR_IIO_MSR_IOCLK]	= { 0x340e, 0x1, 0x10, 1, 48 },
62380378c93aSKan Liang 	[SPR_IIO_MSR_BW_IN]	= { 0x3800, 0x1, 0x10, 8, 48 },
62390378c93aSKan Liang 	[SPR_IIO_MSR_BW_OUT]	= { 0x3808, 0x1, 0x10, 8, 48 },
62400378c93aSKan Liang };
62410378c93aSKan Liang 
62420378c93aSKan Liang static struct uncore_event_desc spr_uncore_iio_freerunning_events[] = {
62430378c93aSKan Liang 	/* Free-Running IIO CLOCKS Counter */
62440378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
62450378c93aSKan Liang 	/* Free-Running IIO BANDWIDTH IN Counters */
62460378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
62470378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
62480378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
62490378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
62500378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
62510378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
62520378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
62530378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
62540378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
62550378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
62560378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
62570378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
62580378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4,		"event=0xff,umask=0x24"),
62590378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale,	"3.814697266e-6"),
62600378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit,	"MiB"),
62610378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5,		"event=0xff,umask=0x25"),
62620378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale,	"3.814697266e-6"),
62630378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit,	"MiB"),
62640378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6,		"event=0xff,umask=0x26"),
62650378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale,	"3.814697266e-6"),
62660378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit,	"MiB"),
62670378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7,		"event=0xff,umask=0x27"),
62680378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale,	"3.814697266e-6"),
62690378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit,	"MiB"),
62700378c93aSKan Liang 	/* Free-Running IIO BANDWIDTH OUT Counters */
62710378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0,		"event=0xff,umask=0x30"),
62720378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.scale,	"3.814697266e-6"),
62730378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.unit,	"MiB"),
62740378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1,		"event=0xff,umask=0x31"),
62750378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.scale,	"3.814697266e-6"),
62760378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.unit,	"MiB"),
62770378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2,		"event=0xff,umask=0x32"),
62780378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.scale,	"3.814697266e-6"),
62790378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.unit,	"MiB"),
62800378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3,		"event=0xff,umask=0x33"),
62810378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.scale,	"3.814697266e-6"),
62820378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.unit,	"MiB"),
62830378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port4,		"event=0xff,umask=0x34"),
62840378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port4.scale,	"3.814697266e-6"),
62850378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port4.unit,	"MiB"),
62860378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port5,		"event=0xff,umask=0x35"),
62870378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port5.scale,	"3.814697266e-6"),
62880378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port5.unit,	"MiB"),
62890378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port6,		"event=0xff,umask=0x36"),
62900378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port6.scale,	"3.814697266e-6"),
62910378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port6.unit,	"MiB"),
62920378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port7,		"event=0xff,umask=0x37"),
62930378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port7.scale,	"3.814697266e-6"),
62940378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port7.unit,	"MiB"),
62950378c93aSKan Liang 	{ /* end: all zeroes */ },
62960378c93aSKan Liang };
62970378c93aSKan Liang 
62980378c93aSKan Liang static struct intel_uncore_type spr_uncore_iio_free_running = {
62990378c93aSKan Liang 	.name			= "iio_free_running",
63000378c93aSKan Liang 	.num_counters		= 17,
63010378c93aSKan Liang 	.num_freerunning_types	= SPR_IIO_FREERUNNING_TYPE_MAX,
63020378c93aSKan Liang 	.freerunning		= spr_iio_freerunning,
63030378c93aSKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
63040378c93aSKan Liang 	.event_descs		= spr_uncore_iio_freerunning_events,
63050378c93aSKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
63060378c93aSKan Liang };
63070378c93aSKan Liang 
6308c76826a6SKan Liang enum perf_uncore_spr_imc_freerunning_type_id {
6309c76826a6SKan Liang 	SPR_IMC_DCLK,
6310c76826a6SKan Liang 	SPR_IMC_PQ_CYCLES,
6311c76826a6SKan Liang 
6312c76826a6SKan Liang 	SPR_IMC_FREERUNNING_TYPE_MAX,
6313c76826a6SKan Liang };
6314c76826a6SKan Liang 
6315c76826a6SKan Liang static struct freerunning_counters spr_imc_freerunning[] = {
6316c76826a6SKan Liang 	[SPR_IMC_DCLK]		= { 0x22b0, 0x0, 0, 1, 48 },
6317c76826a6SKan Liang 	[SPR_IMC_PQ_CYCLES]	= { 0x2318, 0x8, 0, 2, 48 },
6318c76826a6SKan Liang };
6319c76826a6SKan Liang 
6320c76826a6SKan Liang static struct uncore_event_desc spr_uncore_imc_freerunning_events[] = {
6321c76826a6SKan Liang 	INTEL_UNCORE_EVENT_DESC(dclk,			"event=0xff,umask=0x10"),
6322c76826a6SKan Liang 
6323c76826a6SKan Liang 	INTEL_UNCORE_EVENT_DESC(rpq_cycles,		"event=0xff,umask=0x20"),
6324c76826a6SKan Liang 	INTEL_UNCORE_EVENT_DESC(wpq_cycles,		"event=0xff,umask=0x21"),
6325c76826a6SKan Liang 	{ /* end: all zeroes */ },
6326c76826a6SKan Liang };
6327c76826a6SKan Liang 
6328c76826a6SKan Liang #define SPR_MC_DEVICE_ID	0x3251
6329c76826a6SKan Liang 
spr_uncore_imc_freerunning_init_box(struct intel_uncore_box * box)6330c76826a6SKan Liang static void spr_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
6331c76826a6SKan Liang {
6332c76826a6SKan Liang 	int mem_offset = box->pmu->pmu_idx * ICX_IMC_MEM_STRIDE + SNR_IMC_MMIO_MEM0_OFFSET;
6333c76826a6SKan Liang 
6334c76826a6SKan Liang 	snr_uncore_mmio_map(box, uncore_mmio_box_ctl(box),
6335c76826a6SKan Liang 			    mem_offset, SPR_MC_DEVICE_ID);
6336c76826a6SKan Liang }
6337c76826a6SKan Liang 
6338c76826a6SKan Liang static struct intel_uncore_ops spr_uncore_imc_freerunning_ops = {
6339c76826a6SKan Liang 	.init_box	= spr_uncore_imc_freerunning_init_box,
6340c76826a6SKan Liang 	.exit_box	= uncore_mmio_exit_box,
6341c76826a6SKan Liang 	.read_counter	= uncore_mmio_read_counter,
6342c76826a6SKan Liang 	.hw_config	= uncore_freerunning_hw_config,
6343c76826a6SKan Liang };
6344c76826a6SKan Liang 
6345c76826a6SKan Liang static struct intel_uncore_type spr_uncore_imc_free_running = {
6346c76826a6SKan Liang 	.name			= "imc_free_running",
6347c76826a6SKan Liang 	.num_counters		= 3,
6348c76826a6SKan Liang 	.mmio_map_size		= SNR_IMC_MMIO_SIZE,
6349c76826a6SKan Liang 	.num_freerunning_types	= SPR_IMC_FREERUNNING_TYPE_MAX,
6350c76826a6SKan Liang 	.freerunning		= spr_imc_freerunning,
6351c76826a6SKan Liang 	.ops			= &spr_uncore_imc_freerunning_ops,
6352c76826a6SKan Liang 	.event_descs		= spr_uncore_imc_freerunning_events,
6353c76826a6SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
6354c76826a6SKan Liang };
6355c76826a6SKan Liang 
63560378c93aSKan Liang #define UNCORE_SPR_MSR_EXTRA_UNCORES		1
6357c76826a6SKan Liang #define UNCORE_SPR_MMIO_EXTRA_UNCORES		1
635865248a9aSKan Liang #define UNCORE_SPR_PCI_EXTRA_UNCORES		2
63590378c93aSKan Liang 
63600378c93aSKan Liang static struct intel_uncore_type *spr_msr_uncores[UNCORE_SPR_MSR_EXTRA_UNCORES] = {
63610378c93aSKan Liang 	&spr_uncore_iio_free_running,
63620378c93aSKan Liang };
63630378c93aSKan Liang 
6364c76826a6SKan Liang static struct intel_uncore_type *spr_mmio_uncores[UNCORE_SPR_MMIO_EXTRA_UNCORES] = {
6365c76826a6SKan Liang 	&spr_uncore_imc_free_running,
6366c76826a6SKan Liang };
6367c76826a6SKan Liang 
636865248a9aSKan Liang static struct intel_uncore_type *spr_pci_uncores[UNCORE_SPR_PCI_EXTRA_UNCORES] = {
636965248a9aSKan Liang 	&spr_uncore_upi,
637065248a9aSKan Liang 	&spr_uncore_m3upi
637165248a9aSKan Liang };
637265248a9aSKan Liang 
637365248a9aSKan Liang int spr_uncore_units_ignore[] = {
637465248a9aSKan Liang 	UNCORE_SPR_UPI,
637565248a9aSKan Liang 	UNCORE_SPR_M3UPI,
637665248a9aSKan Liang 	UNCORE_IGNORE_END
637765248a9aSKan Liang };
637865248a9aSKan Liang 
uncore_type_customized_copy(struct intel_uncore_type * to_type,struct intel_uncore_type * from_type)6379c54c53d9SKan Liang static void uncore_type_customized_copy(struct intel_uncore_type *to_type,
6380c54c53d9SKan Liang 					struct intel_uncore_type *from_type)
6381c54c53d9SKan Liang {
6382c54c53d9SKan Liang 	if (!to_type || !from_type)
6383c54c53d9SKan Liang 		return;
6384c54c53d9SKan Liang 
6385c54c53d9SKan Liang 	if (from_type->name)
6386c54c53d9SKan Liang 		to_type->name = from_type->name;
6387c54c53d9SKan Liang 	if (from_type->fixed_ctr_bits)
6388c54c53d9SKan Liang 		to_type->fixed_ctr_bits = from_type->fixed_ctr_bits;
6389c54c53d9SKan Liang 	if (from_type->event_mask)
6390c54c53d9SKan Liang 		to_type->event_mask = from_type->event_mask;
6391c54c53d9SKan Liang 	if (from_type->event_mask_ext)
6392c54c53d9SKan Liang 		to_type->event_mask_ext = from_type->event_mask_ext;
6393c54c53d9SKan Liang 	if (from_type->fixed_ctr)
6394c54c53d9SKan Liang 		to_type->fixed_ctr = from_type->fixed_ctr;
6395c54c53d9SKan Liang 	if (from_type->fixed_ctl)
6396c54c53d9SKan Liang 		to_type->fixed_ctl = from_type->fixed_ctl;
6397c54c53d9SKan Liang 	if (from_type->fixed_ctr_bits)
6398c54c53d9SKan Liang 		to_type->fixed_ctr_bits = from_type->fixed_ctr_bits;
6399c54c53d9SKan Liang 	if (from_type->num_shared_regs)
6400c54c53d9SKan Liang 		to_type->num_shared_regs = from_type->num_shared_regs;
6401c54c53d9SKan Liang 	if (from_type->constraints)
6402c54c53d9SKan Liang 		to_type->constraints = from_type->constraints;
6403c54c53d9SKan Liang 	if (from_type->ops)
6404c54c53d9SKan Liang 		to_type->ops = from_type->ops;
6405c54c53d9SKan Liang 	if (from_type->event_descs)
6406c54c53d9SKan Liang 		to_type->event_descs = from_type->event_descs;
6407c54c53d9SKan Liang 	if (from_type->format_group)
6408c54c53d9SKan Liang 		to_type->format_group = from_type->format_group;
64098053f2d7SKan Liang 	if (from_type->attr_update)
64108053f2d7SKan Liang 		to_type->attr_update = from_type->attr_update;
64119a3b675cSAlexander Antonov 	if (from_type->set_mapping)
64129a3b675cSAlexander Antonov 		to_type->set_mapping = from_type->set_mapping;
64139a3b675cSAlexander Antonov 	if (from_type->get_topology)
64149a3b675cSAlexander Antonov 		to_type->get_topology = from_type->get_topology;
64159a3b675cSAlexander Antonov 	if (from_type->cleanup_mapping)
64169a3b675cSAlexander Antonov 		to_type->cleanup_mapping = from_type->cleanup_mapping;
6417c54c53d9SKan Liang }
6418c54c53d9SKan Liang 
6419c54c53d9SKan Liang static struct intel_uncore_type **
uncore_get_uncores(enum uncore_access_type type_id,int num_extra,struct intel_uncore_type ** extra)64200378c93aSKan Liang uncore_get_uncores(enum uncore_access_type type_id, int num_extra,
64210378c93aSKan Liang 		    struct intel_uncore_type **extra)
6422c54c53d9SKan Liang {
6423c54c53d9SKan Liang 	struct intel_uncore_type **types, **start_types;
64240378c93aSKan Liang 	int i;
6425c54c53d9SKan Liang 
64260378c93aSKan Liang 	start_types = types = intel_uncore_generic_init_uncores(type_id, num_extra);
6427c54c53d9SKan Liang 
6428c54c53d9SKan Liang 	/* Only copy the customized features */
6429c54c53d9SKan Liang 	for (; *types; types++) {
6430c54c53d9SKan Liang 		if ((*types)->type_id >= UNCORE_SPR_NUM_UNCORE_TYPES)
6431c54c53d9SKan Liang 			continue;
6432c54c53d9SKan Liang 		uncore_type_customized_copy(*types, spr_uncores[(*types)->type_id]);
6433c54c53d9SKan Liang 	}
6434c54c53d9SKan Liang 
64350378c93aSKan Liang 	for (i = 0; i < num_extra; i++, types++)
64360378c93aSKan Liang 		*types = extra[i];
64370378c93aSKan Liang 
6438c54c53d9SKan Liang 	return start_types;
6439c54c53d9SKan Liang }
6440c54c53d9SKan Liang 
64410378c93aSKan Liang static struct intel_uncore_type *
uncore_find_type_by_id(struct intel_uncore_type ** types,int type_id)64420378c93aSKan Liang uncore_find_type_by_id(struct intel_uncore_type **types, int type_id)
64430378c93aSKan Liang {
64440378c93aSKan Liang 	for (; *types; types++) {
64450378c93aSKan Liang 		if (type_id == (*types)->type_id)
64460378c93aSKan Liang 			return *types;
64470378c93aSKan Liang 	}
64480378c93aSKan Liang 
64490378c93aSKan Liang 	return NULL;
64500378c93aSKan Liang }
64510378c93aSKan Liang 
uncore_type_max_boxes(struct intel_uncore_type ** types,int type_id)64520378c93aSKan Liang static int uncore_type_max_boxes(struct intel_uncore_type **types,
64530378c93aSKan Liang 				 int type_id)
64540378c93aSKan Liang {
64550378c93aSKan Liang 	struct intel_uncore_type *type;
64560378c93aSKan Liang 	int i, max = 0;
64570378c93aSKan Liang 
64580378c93aSKan Liang 	type = uncore_find_type_by_id(types, type_id);
64590378c93aSKan Liang 	if (!type)
64600378c93aSKan Liang 		return 0;
64610378c93aSKan Liang 
64620378c93aSKan Liang 	for (i = 0; i < type->num_boxes; i++) {
64630378c93aSKan Liang 		if (type->box_ids[i] > max)
64640378c93aSKan Liang 			max = type->box_ids[i];
64650378c93aSKan Liang 	}
64660378c93aSKan Liang 
64670378c93aSKan Liang 	return max + 1;
64680378c93aSKan Liang }
64690378c93aSKan Liang 
647038776cc4SKan Liang #define SPR_MSR_UNC_CBO_CONFIG		0x2FFE
647138776cc4SKan Liang 
spr_uncore_cpu_init(void)6472c54c53d9SKan Liang void spr_uncore_cpu_init(void)
6473c54c53d9SKan Liang {
647438776cc4SKan Liang 	struct intel_uncore_type *type;
647538776cc4SKan Liang 	u64 num_cbo;
647638776cc4SKan Liang 
64770378c93aSKan Liang 	uncore_msr_uncores = uncore_get_uncores(UNCORE_ACCESS_MSR,
64780378c93aSKan Liang 						UNCORE_SPR_MSR_EXTRA_UNCORES,
64790378c93aSKan Liang 						spr_msr_uncores);
64800378c93aSKan Liang 
648138776cc4SKan Liang 	type = uncore_find_type_by_id(uncore_msr_uncores, UNCORE_SPR_CHA);
648238776cc4SKan Liang 	if (type) {
64836f7f984fSKan Liang 		/*
64846f7f984fSKan Liang 		 * The value from the discovery table (stored in the type->num_boxes
64856f7f984fSKan Liang 		 * of UNCORE_SPR_CHA) is incorrect on some SPR variants because of a
64866f7f984fSKan Liang 		 * firmware bug. Using the value from SPR_MSR_UNC_CBO_CONFIG to replace it.
64876f7f984fSKan Liang 		 */
648838776cc4SKan Liang 		rdmsrl(SPR_MSR_UNC_CBO_CONFIG, num_cbo);
64896f7f984fSKan Liang 		/*
64906f7f984fSKan Liang 		 * The MSR doesn't work on the EMR XCC, but the firmware bug doesn't impact
64916f7f984fSKan Liang 		 * the EMR XCC. Don't let the value from the MSR replace the existing value.
64926f7f984fSKan Liang 		 */
64936f7f984fSKan Liang 		if (num_cbo)
649438776cc4SKan Liang 			type->num_boxes = num_cbo;
649538776cc4SKan Liang 	}
64960378c93aSKan Liang 	spr_uncore_iio_free_running.num_boxes = uncore_type_max_boxes(uncore_msr_uncores, UNCORE_SPR_IIO);
6497c54c53d9SKan Liang }
6498c54c53d9SKan Liang 
649965248a9aSKan Liang #define SPR_UNCORE_UPI_PCIID		0x3241
650065248a9aSKan Liang #define SPR_UNCORE_UPI0_DEVFN		0x9
650165248a9aSKan Liang #define SPR_UNCORE_M3UPI_PCIID		0x3246
650265248a9aSKan Liang #define SPR_UNCORE_M3UPI0_DEVFN		0x29
650365248a9aSKan Liang 
spr_update_device_location(int type_id)650465248a9aSKan Liang static void spr_update_device_location(int type_id)
650565248a9aSKan Liang {
650665248a9aSKan Liang 	struct intel_uncore_type *type;
650765248a9aSKan Liang 	struct pci_dev *dev = NULL;
650865248a9aSKan Liang 	u32 device, devfn;
650965248a9aSKan Liang 	u64 *ctls;
651065248a9aSKan Liang 	int die;
651165248a9aSKan Liang 
651265248a9aSKan Liang 	if (type_id == UNCORE_SPR_UPI) {
651365248a9aSKan Liang 		type = &spr_uncore_upi;
651465248a9aSKan Liang 		device = SPR_UNCORE_UPI_PCIID;
651565248a9aSKan Liang 		devfn = SPR_UNCORE_UPI0_DEVFN;
651665248a9aSKan Liang 	} else if (type_id == UNCORE_SPR_M3UPI) {
651765248a9aSKan Liang 		type = &spr_uncore_m3upi;
651865248a9aSKan Liang 		device = SPR_UNCORE_M3UPI_PCIID;
651965248a9aSKan Liang 		devfn = SPR_UNCORE_M3UPI0_DEVFN;
652065248a9aSKan Liang 	} else
652165248a9aSKan Liang 		return;
652265248a9aSKan Liang 
652365248a9aSKan Liang 	ctls = kcalloc(__uncore_max_dies, sizeof(u64), GFP_KERNEL);
652465248a9aSKan Liang 	if (!ctls) {
652565248a9aSKan Liang 		type->num_boxes = 0;
652665248a9aSKan Liang 		return;
652765248a9aSKan Liang 	}
652865248a9aSKan Liang 
652965248a9aSKan Liang 	while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, dev)) != NULL) {
653065248a9aSKan Liang 		if (devfn != dev->devfn)
653165248a9aSKan Liang 			continue;
653265248a9aSKan Liang 
653365248a9aSKan Liang 		die = uncore_device_to_die(dev);
653465248a9aSKan Liang 		if (die < 0)
653565248a9aSKan Liang 			continue;
653665248a9aSKan Liang 
653765248a9aSKan Liang 		ctls[die] = pci_domain_nr(dev->bus) << UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET |
653865248a9aSKan Liang 			    dev->bus->number << UNCORE_DISCOVERY_PCI_BUS_OFFSET |
653965248a9aSKan Liang 			    devfn << UNCORE_DISCOVERY_PCI_DEVFN_OFFSET |
654065248a9aSKan Liang 			    type->box_ctl;
654165248a9aSKan Liang 	}
654265248a9aSKan Liang 
654365248a9aSKan Liang 	type->box_ctls = ctls;
654465248a9aSKan Liang }
654565248a9aSKan Liang 
spr_uncore_pci_init(void)6546c54c53d9SKan Liang int spr_uncore_pci_init(void)
6547c54c53d9SKan Liang {
654865248a9aSKan Liang 	/*
654965248a9aSKan Liang 	 * The discovery table of UPI on some SPR variant is broken,
655065248a9aSKan Liang 	 * which impacts the detection of both UPI and M3UPI uncore PMON.
655165248a9aSKan Liang 	 * Use the pre-defined UPI and M3UPI table to replace.
655265248a9aSKan Liang 	 *
655365248a9aSKan Liang 	 * The accurate location, e.g., domain and BUS number,
655465248a9aSKan Liang 	 * can only be retrieved at load time.
655565248a9aSKan Liang 	 * Update the location of UPI and M3UPI.
655665248a9aSKan Liang 	 */
655765248a9aSKan Liang 	spr_update_device_location(UNCORE_SPR_UPI);
655865248a9aSKan Liang 	spr_update_device_location(UNCORE_SPR_M3UPI);
655965248a9aSKan Liang 	uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI,
656065248a9aSKan Liang 						UNCORE_SPR_PCI_EXTRA_UNCORES,
656165248a9aSKan Liang 						spr_pci_uncores);
6562c54c53d9SKan Liang 	return 0;
6563c54c53d9SKan Liang }
6564c54c53d9SKan Liang 
spr_uncore_mmio_init(void)6565c54c53d9SKan Liang void spr_uncore_mmio_init(void)
6566c54c53d9SKan Liang {
6567c76826a6SKan Liang 	int ret = snbep_pci2phy_map_init(0x3250, SKX_CPUNODEID, SKX_GIDNIDMAP, true);
6568c76826a6SKan Liang 
6569c76826a6SKan Liang 	if (ret)
65700378c93aSKan Liang 		uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL);
6571c76826a6SKan Liang 	else {
6572c76826a6SKan Liang 		uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO,
6573c76826a6SKan Liang 							 UNCORE_SPR_MMIO_EXTRA_UNCORES,
6574c76826a6SKan Liang 							 spr_mmio_uncores);
6575c76826a6SKan Liang 
6576c76826a6SKan Liang 		spr_uncore_imc_free_running.num_boxes = uncore_type_max_boxes(uncore_mmio_uncores, UNCORE_SPR_IMC) / 2;
6577c76826a6SKan Liang 	}
6578c54c53d9SKan Liang }
6579c54c53d9SKan Liang 
6580c54c53d9SKan Liang /* end of SPR uncore support */
6581