xref: /openbmc/linux/arch/x86/events/intel/uncore_snb.c (revision c828441f)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
246866b59SKan Liang /* Nehalem/SandBridge/Haswell/Broadwell/Skylake uncore support */
392553e40SBorislav Petkov #include "uncore.h"
45a4487f9SKan Liang #include "uncore_discovery.h"
592553e40SBorislav Petkov 
692553e40SBorislav Petkov /* Uncore IMC PCI IDs */
792553e40SBorislav Petkov #define PCI_DEVICE_ID_INTEL_SNB_IMC		0x0100
892553e40SBorislav Petkov #define PCI_DEVICE_ID_INTEL_IVB_IMC		0x0154
992553e40SBorislav Petkov #define PCI_DEVICE_ID_INTEL_IVB_E3_IMC		0x0150
1092553e40SBorislav Petkov #define PCI_DEVICE_ID_INTEL_HSW_IMC		0x0c00
1192553e40SBorislav Petkov #define PCI_DEVICE_ID_INTEL_HSW_U_IMC		0x0a04
1292553e40SBorislav Petkov #define PCI_DEVICE_ID_INTEL_BDW_IMC		0x1604
13d786810bSKan Liang #define PCI_DEVICE_ID_INTEL_SKL_U_IMC		0x1904
14d786810bSKan Liang #define PCI_DEVICE_ID_INTEL_SKL_Y_IMC		0x190c
15d786810bSKan Liang #define PCI_DEVICE_ID_INTEL_SKL_HD_IMC		0x1900
16d786810bSKan Liang #define PCI_DEVICE_ID_INTEL_SKL_HQ_IMC		0x1910
17d786810bSKan Liang #define PCI_DEVICE_ID_INTEL_SKL_SD_IMC		0x190f
18d786810bSKan Liang #define PCI_DEVICE_ID_INTEL_SKL_SQ_IMC		0x191f
19e7438304SKan Liang #define PCI_DEVICE_ID_INTEL_SKL_E3_IMC		0x1918
20c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_KBL_Y_IMC		0x590c
21c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_KBL_U_IMC		0x5904
22c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_KBL_UQ_IMC		0x5914
23c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_KBL_SD_IMC		0x590f
24c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_KBL_SQ_IMC		0x591f
256e86d3dbSGayatri Kammela #define PCI_DEVICE_ID_INTEL_KBL_HQ_IMC		0x5910
266e86d3dbSGayatri Kammela #define PCI_DEVICE_ID_INTEL_KBL_WQ_IMC		0x5918
27c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_2U_IMC		0x3ecc
28c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_4U_IMC		0x3ed0
29c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_4H_IMC		0x3e10
30c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_6H_IMC		0x3ec4
31c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_2S_D_IMC	0x3e0f
32c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_4S_D_IMC	0x3e1f
33c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_6S_D_IMC	0x3ec2
34c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_8S_D_IMC	0x3e30
35c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_4S_W_IMC	0x3e18
36c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_6S_W_IMC	0x3ec6
37c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_8S_W_IMC	0x3e31
38c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_4S_S_IMC	0x3e33
39c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_6S_S_IMC	0x3eca
40c10a8de0SKan Liang #define PCI_DEVICE_ID_INTEL_CFL_8S_S_IMC	0x3e32
416e86d3dbSGayatri Kammela #define PCI_DEVICE_ID_INTEL_AML_YD_IMC		0x590c
426e86d3dbSGayatri Kammela #define PCI_DEVICE_ID_INTEL_AML_YQ_IMC		0x590d
436e86d3dbSGayatri Kammela #define PCI_DEVICE_ID_INTEL_WHL_UQ_IMC		0x3ed0
446e86d3dbSGayatri Kammela #define PCI_DEVICE_ID_INTEL_WHL_4_UQ_IMC	0x3e34
456e86d3dbSGayatri Kammela #define PCI_DEVICE_ID_INTEL_WHL_UD_IMC		0x3e35
46bb85429aSKan Liang #define PCI_DEVICE_ID_INTEL_CML_H1_IMC		0x9b44
47bb85429aSKan Liang #define PCI_DEVICE_ID_INTEL_CML_H2_IMC		0x9b54
48bb85429aSKan Liang #define PCI_DEVICE_ID_INTEL_CML_H3_IMC		0x9b64
49bb85429aSKan Liang #define PCI_DEVICE_ID_INTEL_CML_U1_IMC		0x9b51
50bb85429aSKan Liang #define PCI_DEVICE_ID_INTEL_CML_U2_IMC		0x9b61
51bb85429aSKan Liang #define PCI_DEVICE_ID_INTEL_CML_U3_IMC		0x9b71
52bb85429aSKan Liang #define PCI_DEVICE_ID_INTEL_CML_S1_IMC		0x9b33
53bb85429aSKan Liang #define PCI_DEVICE_ID_INTEL_CML_S2_IMC		0x9b43
54bb85429aSKan Liang #define PCI_DEVICE_ID_INTEL_CML_S3_IMC		0x9b53
55bb85429aSKan Liang #define PCI_DEVICE_ID_INTEL_CML_S4_IMC		0x9b63
56bb85429aSKan Liang #define PCI_DEVICE_ID_INTEL_CML_S5_IMC		0x9b73
576e394376SKan Liang #define PCI_DEVICE_ID_INTEL_ICL_U_IMC		0x8a02
586e394376SKan Liang #define PCI_DEVICE_ID_INTEL_ICL_U2_IMC		0x8a12
59fdb64822SKan Liang #define PCI_DEVICE_ID_INTEL_TGL_U1_IMC		0x9a02
60fdb64822SKan Liang #define PCI_DEVICE_ID_INTEL_TGL_U2_IMC		0x9a04
61fdb64822SKan Liang #define PCI_DEVICE_ID_INTEL_TGL_U3_IMC		0x9a12
62fdb64822SKan Liang #define PCI_DEVICE_ID_INTEL_TGL_U4_IMC		0x9a14
63fdb64822SKan Liang #define PCI_DEVICE_ID_INTEL_TGL_H_IMC		0x9a36
6443bc103aSKan Liang #define PCI_DEVICE_ID_INTEL_RKL_1_IMC		0x4c43
6543bc103aSKan Liang #define PCI_DEVICE_ID_INTEL_RKL_2_IMC		0x4c53
66772ed05fSKan Liang #define PCI_DEVICE_ID_INTEL_ADL_1_IMC		0x4660
67772ed05fSKan Liang #define PCI_DEVICE_ID_INTEL_ADL_2_IMC		0x4641
685a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_3_IMC		0x4601
695a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_4_IMC		0x4602
705a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_5_IMC		0x4609
715a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_6_IMC		0x460a
725a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_7_IMC		0x4621
735a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_8_IMC		0x4623
745a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_9_IMC		0x4629
755a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_10_IMC		0x4637
765a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_11_IMC		0x463b
775a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_12_IMC		0x4648
785a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_13_IMC		0x4649
795a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_14_IMC		0x4650
805a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_15_IMC		0x4668
815a4487f9SKan Liang #define PCI_DEVICE_ID_INTEL_ADL_16_IMC		0x4670
82f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_ADL_17_IMC		0x4614
83f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_ADL_18_IMC		0x4617
84f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_ADL_19_IMC		0x4618
85f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_ADL_20_IMC		0x461B
86f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_ADL_21_IMC		0x461C
87ad4878d4SKan Liang #define PCI_DEVICE_ID_INTEL_RPL_1_IMC		0xA700
88ad4878d4SKan Liang #define PCI_DEVICE_ID_INTEL_RPL_2_IMC		0xA702
89ad4878d4SKan Liang #define PCI_DEVICE_ID_INTEL_RPL_3_IMC		0xA706
90ad4878d4SKan Liang #define PCI_DEVICE_ID_INTEL_RPL_4_IMC		0xA709
91f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_5_IMC		0xA701
92f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_6_IMC		0xA703
93f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_7_IMC		0xA704
94f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_8_IMC		0xA705
95f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_9_IMC		0xA706
96f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_10_IMC		0xA707
97f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_11_IMC		0xA708
98f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_12_IMC		0xA709
99f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_13_IMC		0xA70a
100f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_14_IMC		0xA70b
101f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_15_IMC		0xA715
102f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_16_IMC		0xA716
103f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_17_IMC		0xA717
104f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_18_IMC		0xA718
105f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_19_IMC		0xA719
106f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_20_IMC		0xA71A
107f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_21_IMC		0xA71B
108f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_22_IMC		0xA71C
109f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_23_IMC		0xA728
110f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_24_IMC		0xA729
111f758bc5aSKan Liang #define PCI_DEVICE_ID_INTEL_RPL_25_IMC		0xA72A
112*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_1_IMC		0x7d00
113*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_2_IMC		0x7d01
114*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_3_IMC		0x7d02
115*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_4_IMC		0x7d05
116*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_5_IMC		0x7d10
117*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_6_IMC		0x7d14
118*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_7_IMC		0x7d15
119*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_8_IMC		0x7d16
120*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_9_IMC		0x7d21
121*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_10_IMC		0x7d22
122*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_11_IMC		0x7d23
123*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_12_IMC		0x7d24
124*c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_13_IMC		0x7d28
1256e86d3dbSGayatri Kammela 
126e5ae168eSKan Liang 
127e5ae168eSKan Liang #define IMC_UNCORE_DEV(a)						\
128e5ae168eSKan Liang {									\
129e5ae168eSKan Liang 	PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_##a##_IMC),	\
130e5ae168eSKan Liang 	.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),	\
131e5ae168eSKan Liang }
132e5ae168eSKan Liang 
13392553e40SBorislav Petkov /* SNB event control */
13492553e40SBorislav Petkov #define SNB_UNC_CTL_EV_SEL_MASK			0x000000ff
13592553e40SBorislav Petkov #define SNB_UNC_CTL_UMASK_MASK			0x0000ff00
13692553e40SBorislav Petkov #define SNB_UNC_CTL_EDGE_DET			(1 << 18)
13792553e40SBorislav Petkov #define SNB_UNC_CTL_EN				(1 << 22)
13892553e40SBorislav Petkov #define SNB_UNC_CTL_INVERT			(1 << 23)
13992553e40SBorislav Petkov #define SNB_UNC_CTL_CMASK_MASK			0x1f000000
14092553e40SBorislav Petkov #define NHM_UNC_CTL_CMASK_MASK			0xff000000
14192553e40SBorislav Petkov #define NHM_UNC_FIXED_CTR_CTL_EN		(1 << 0)
14292553e40SBorislav Petkov 
14392553e40SBorislav Petkov #define SNB_UNC_RAW_EVENT_MASK			(SNB_UNC_CTL_EV_SEL_MASK | \
14492553e40SBorislav Petkov 						 SNB_UNC_CTL_UMASK_MASK | \
14592553e40SBorislav Petkov 						 SNB_UNC_CTL_EDGE_DET | \
14692553e40SBorislav Petkov 						 SNB_UNC_CTL_INVERT | \
14792553e40SBorislav Petkov 						 SNB_UNC_CTL_CMASK_MASK)
14892553e40SBorislav Petkov 
14992553e40SBorislav Petkov #define NHM_UNC_RAW_EVENT_MASK			(SNB_UNC_CTL_EV_SEL_MASK | \
15092553e40SBorislav Petkov 						 SNB_UNC_CTL_UMASK_MASK | \
15192553e40SBorislav Petkov 						 SNB_UNC_CTL_EDGE_DET | \
15292553e40SBorislav Petkov 						 SNB_UNC_CTL_INVERT | \
15392553e40SBorislav Petkov 						 NHM_UNC_CTL_CMASK_MASK)
15492553e40SBorislav Petkov 
15592553e40SBorislav Petkov /* SNB global control register */
15692553e40SBorislav Petkov #define SNB_UNC_PERF_GLOBAL_CTL                 0x391
15792553e40SBorislav Petkov #define SNB_UNC_FIXED_CTR_CTRL                  0x394
15892553e40SBorislav Petkov #define SNB_UNC_FIXED_CTR                       0x395
15992553e40SBorislav Petkov 
16092553e40SBorislav Petkov /* SNB uncore global control */
16192553e40SBorislav Petkov #define SNB_UNC_GLOBAL_CTL_CORE_ALL             ((1 << 4) - 1)
16292553e40SBorislav Petkov #define SNB_UNC_GLOBAL_CTL_EN                   (1 << 29)
16392553e40SBorislav Petkov 
16492553e40SBorislav Petkov /* SNB Cbo register */
16592553e40SBorislav Petkov #define SNB_UNC_CBO_0_PERFEVTSEL0               0x700
16692553e40SBorislav Petkov #define SNB_UNC_CBO_0_PER_CTR0                  0x706
16792553e40SBorislav Petkov #define SNB_UNC_CBO_MSR_OFFSET                  0x10
16892553e40SBorislav Petkov 
16992553e40SBorislav Petkov /* SNB ARB register */
17092553e40SBorislav Petkov #define SNB_UNC_ARB_PER_CTR0			0x3b0
17192553e40SBorislav Petkov #define SNB_UNC_ARB_PERFEVTSEL0			0x3b2
17292553e40SBorislav Petkov #define SNB_UNC_ARB_MSR_OFFSET			0x10
17392553e40SBorislav Petkov 
17492553e40SBorislav Petkov /* NHM global control register */
17592553e40SBorislav Petkov #define NHM_UNC_PERF_GLOBAL_CTL                 0x391
17692553e40SBorislav Petkov #define NHM_UNC_FIXED_CTR                       0x394
17792553e40SBorislav Petkov #define NHM_UNC_FIXED_CTR_CTRL                  0x395
17892553e40SBorislav Petkov 
17992553e40SBorislav Petkov /* NHM uncore global control */
18092553e40SBorislav Petkov #define NHM_UNC_GLOBAL_CTL_EN_PC_ALL            ((1ULL << 8) - 1)
18192553e40SBorislav Petkov #define NHM_UNC_GLOBAL_CTL_EN_FC                (1ULL << 32)
18292553e40SBorislav Petkov 
18392553e40SBorislav Petkov /* NHM uncore register */
18492553e40SBorislav Petkov #define NHM_UNC_PERFEVTSEL0                     0x3c0
18592553e40SBorislav Petkov #define NHM_UNC_UNCORE_PMC0                     0x3b0
18692553e40SBorislav Petkov 
18746866b59SKan Liang /* SKL uncore global control */
18846866b59SKan Liang #define SKL_UNC_PERF_GLOBAL_CTL			0xe01
18946866b59SKan Liang #define SKL_UNC_GLOBAL_CTL_CORE_ALL		((1 << 5) - 1)
19046866b59SKan Liang 
1916e394376SKan Liang /* ICL Cbo register */
1926e394376SKan Liang #define ICL_UNC_CBO_CONFIG			0x396
1936e394376SKan Liang #define ICL_UNC_NUM_CBO_MASK			0xf
1946e394376SKan Liang #define ICL_UNC_CBO_0_PER_CTR0			0x702
1956e394376SKan Liang #define ICL_UNC_CBO_MSR_OFFSET			0x8
1966e394376SKan Liang 
1978f5d41f3SKan Liang /* ICL ARB register */
1988f5d41f3SKan Liang #define ICL_UNC_ARB_PER_CTR			0x3b1
1998f5d41f3SKan Liang #define ICL_UNC_ARB_PERFEVTSEL			0x3b3
2008f5d41f3SKan Liang 
201772ed05fSKan Liang /* ADL uncore global control */
202772ed05fSKan Liang #define ADL_UNC_PERF_GLOBAL_CTL			0x2ff0
203772ed05fSKan Liang #define ADL_UNC_FIXED_CTR_CTRL                  0x2fde
204772ed05fSKan Liang #define ADL_UNC_FIXED_CTR                       0x2fdf
205772ed05fSKan Liang 
206772ed05fSKan Liang /* ADL Cbo register */
207772ed05fSKan Liang #define ADL_UNC_CBO_0_PER_CTR0			0x2002
208772ed05fSKan Liang #define ADL_UNC_CBO_0_PERFEVTSEL0		0x2000
209772ed05fSKan Liang #define ADL_UNC_CTL_THRESHOLD			0x3f000000
210772ed05fSKan Liang #define ADL_UNC_RAW_EVENT_MASK			(SNB_UNC_CTL_EV_SEL_MASK | \
211772ed05fSKan Liang 						 SNB_UNC_CTL_UMASK_MASK | \
212772ed05fSKan Liang 						 SNB_UNC_CTL_EDGE_DET | \
213772ed05fSKan Liang 						 SNB_UNC_CTL_INVERT | \
214772ed05fSKan Liang 						 ADL_UNC_CTL_THRESHOLD)
215772ed05fSKan Liang 
216772ed05fSKan Liang /* ADL ARB register */
217772ed05fSKan Liang #define ADL_UNC_ARB_PER_CTR0			0x2FD2
218772ed05fSKan Liang #define ADL_UNC_ARB_PERFEVTSEL0			0x2FD0
219772ed05fSKan Liang #define ADL_UNC_ARB_MSR_OFFSET			0x8
220772ed05fSKan Liang 
221*c828441fSKan Liang /* MTL Cbo register */
222*c828441fSKan Liang #define MTL_UNC_CBO_0_PER_CTR0			0x2448
223*c828441fSKan Liang #define MTL_UNC_CBO_0_PERFEVTSEL0		0x2442
224*c828441fSKan Liang 
225*c828441fSKan Liang /* MTL HAC_ARB register */
226*c828441fSKan Liang #define MTL_UNC_HAC_ARB_CTR			0x2018
227*c828441fSKan Liang #define MTL_UNC_HAC_ARB_CTRL			0x2012
228*c828441fSKan Liang 
229*c828441fSKan Liang /* MTL ARB register */
230*c828441fSKan Liang #define MTL_UNC_ARB_CTR				0x2418
231*c828441fSKan Liang #define MTL_UNC_ARB_CTRL			0x2412
232*c828441fSKan Liang 
233*c828441fSKan Liang /* MTL cNCU register */
234*c828441fSKan Liang #define MTL_UNC_CNCU_FIXED_CTR			0x2408
235*c828441fSKan Liang #define MTL_UNC_CNCU_FIXED_CTRL			0x2402
236*c828441fSKan Liang #define MTL_UNC_CNCU_BOX_CTL			0x240e
237*c828441fSKan Liang 
238*c828441fSKan Liang /* MTL sNCU register */
239*c828441fSKan Liang #define MTL_UNC_SNCU_FIXED_CTR			0x2008
240*c828441fSKan Liang #define MTL_UNC_SNCU_FIXED_CTRL			0x2002
241*c828441fSKan Liang #define MTL_UNC_SNCU_BOX_CTL			0x200e
242*c828441fSKan Liang 
243*c828441fSKan Liang /* MTL HAC_CBO register */
244*c828441fSKan Liang #define MTL_UNC_HBO_CTR				0x2048
245*c828441fSKan Liang #define MTL_UNC_HBO_CTRL			0x2042
246*c828441fSKan Liang 
24792553e40SBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
24892553e40SBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
2495a4487f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(chmask, chmask, "config:8-11");
25092553e40SBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
25192553e40SBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
25292553e40SBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28");
25392553e40SBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31");
254772ed05fSKan Liang DEFINE_UNCORE_FORMAT_ATTR(threshold, threshold, "config:24-29");
25592553e40SBorislav Petkov 
25692553e40SBorislav Petkov /* Sandy Bridge uncore support */
snb_uncore_msr_enable_event(struct intel_uncore_box * box,struct perf_event * event)25792553e40SBorislav Petkov static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
25892553e40SBorislav Petkov {
25992553e40SBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
26092553e40SBorislav Petkov 
26192553e40SBorislav Petkov 	if (hwc->idx < UNCORE_PMC_IDX_FIXED)
26292553e40SBorislav Petkov 		wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
26392553e40SBorislav Petkov 	else
26492553e40SBorislav Petkov 		wrmsrl(hwc->config_base, SNB_UNC_CTL_EN);
26592553e40SBorislav Petkov }
26692553e40SBorislav Petkov 
snb_uncore_msr_disable_event(struct intel_uncore_box * box,struct perf_event * event)26792553e40SBorislav Petkov static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
26892553e40SBorislav Petkov {
26992553e40SBorislav Petkov 	wrmsrl(event->hw.config_base, 0);
27092553e40SBorislav Petkov }
27192553e40SBorislav Petkov 
snb_uncore_msr_init_box(struct intel_uncore_box * box)27292553e40SBorislav Petkov static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
27392553e40SBorislav Petkov {
27492553e40SBorislav Petkov 	if (box->pmu->pmu_idx == 0) {
27592553e40SBorislav Petkov 		wrmsrl(SNB_UNC_PERF_GLOBAL_CTL,
27692553e40SBorislav Petkov 			SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL);
27792553e40SBorislav Petkov 	}
27892553e40SBorislav Petkov }
27992553e40SBorislav Petkov 
snb_uncore_msr_enable_box(struct intel_uncore_box * box)28095f3be79SKan Liang static void snb_uncore_msr_enable_box(struct intel_uncore_box *box)
28195f3be79SKan Liang {
28295f3be79SKan Liang 	wrmsrl(SNB_UNC_PERF_GLOBAL_CTL,
28395f3be79SKan Liang 		SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL);
28495f3be79SKan Liang }
28595f3be79SKan Liang 
snb_uncore_msr_exit_box(struct intel_uncore_box * box)286a46195f1SThomas Gleixner static void snb_uncore_msr_exit_box(struct intel_uncore_box *box)
287a46195f1SThomas Gleixner {
288a46195f1SThomas Gleixner 	if (box->pmu->pmu_idx == 0)
289a46195f1SThomas Gleixner 		wrmsrl(SNB_UNC_PERF_GLOBAL_CTL, 0);
290a46195f1SThomas Gleixner }
291a46195f1SThomas Gleixner 
29292553e40SBorislav Petkov static struct uncore_event_desc snb_uncore_events[] = {
29392553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
29492553e40SBorislav Petkov 	{ /* end: all zeroes */ },
29592553e40SBorislav Petkov };
29692553e40SBorislav Petkov 
29792553e40SBorislav Petkov static struct attribute *snb_uncore_formats_attr[] = {
29892553e40SBorislav Petkov 	&format_attr_event.attr,
29992553e40SBorislav Petkov 	&format_attr_umask.attr,
30092553e40SBorislav Petkov 	&format_attr_edge.attr,
30192553e40SBorislav Petkov 	&format_attr_inv.attr,
30292553e40SBorislav Petkov 	&format_attr_cmask5.attr,
30392553e40SBorislav Petkov 	NULL,
30492553e40SBorislav Petkov };
30592553e40SBorislav Petkov 
30645bd07adSArvind Yadav static const struct attribute_group snb_uncore_format_group = {
30792553e40SBorislav Petkov 	.name		= "format",
30892553e40SBorislav Petkov 	.attrs		= snb_uncore_formats_attr,
30992553e40SBorislav Petkov };
31092553e40SBorislav Petkov 
31192553e40SBorislav Petkov static struct intel_uncore_ops snb_uncore_msr_ops = {
31292553e40SBorislav Petkov 	.init_box	= snb_uncore_msr_init_box,
31395f3be79SKan Liang 	.enable_box	= snb_uncore_msr_enable_box,
314a46195f1SThomas Gleixner 	.exit_box	= snb_uncore_msr_exit_box,
31592553e40SBorislav Petkov 	.disable_event	= snb_uncore_msr_disable_event,
31692553e40SBorislav Petkov 	.enable_event	= snb_uncore_msr_enable_event,
31792553e40SBorislav Petkov 	.read_counter	= uncore_msr_read_counter,
31892553e40SBorislav Petkov };
31992553e40SBorislav Petkov 
32092553e40SBorislav Petkov static struct event_constraint snb_uncore_arb_constraints[] = {
32192553e40SBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x80, 0x1),
32292553e40SBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x83, 0x1),
32392553e40SBorislav Petkov 	EVENT_CONSTRAINT_END
32492553e40SBorislav Petkov };
32592553e40SBorislav Petkov 
32692553e40SBorislav Petkov static struct intel_uncore_type snb_uncore_cbox = {
32792553e40SBorislav Petkov 	.name		= "cbox",
32892553e40SBorislav Petkov 	.num_counters   = 2,
32992553e40SBorislav Petkov 	.num_boxes	= 4,
33092553e40SBorislav Petkov 	.perf_ctr_bits	= 44,
33192553e40SBorislav Petkov 	.fixed_ctr_bits	= 48,
33292553e40SBorislav Petkov 	.perf_ctr	= SNB_UNC_CBO_0_PER_CTR0,
33392553e40SBorislav Petkov 	.event_ctl	= SNB_UNC_CBO_0_PERFEVTSEL0,
33492553e40SBorislav Petkov 	.fixed_ctr	= SNB_UNC_FIXED_CTR,
33592553e40SBorislav Petkov 	.fixed_ctl	= SNB_UNC_FIXED_CTR_CTRL,
33692553e40SBorislav Petkov 	.single_fixed	= 1,
33792553e40SBorislav Petkov 	.event_mask	= SNB_UNC_RAW_EVENT_MASK,
33892553e40SBorislav Petkov 	.msr_offset	= SNB_UNC_CBO_MSR_OFFSET,
33992553e40SBorislav Petkov 	.ops		= &snb_uncore_msr_ops,
34092553e40SBorislav Petkov 	.format_group	= &snb_uncore_format_group,
34192553e40SBorislav Petkov 	.event_descs	= snb_uncore_events,
34292553e40SBorislav Petkov };
34392553e40SBorislav Petkov 
34492553e40SBorislav Petkov static struct intel_uncore_type snb_uncore_arb = {
34592553e40SBorislav Petkov 	.name		= "arb",
34692553e40SBorislav Petkov 	.num_counters   = 2,
34792553e40SBorislav Petkov 	.num_boxes	= 1,
34892553e40SBorislav Petkov 	.perf_ctr_bits	= 44,
34992553e40SBorislav Petkov 	.perf_ctr	= SNB_UNC_ARB_PER_CTR0,
35092553e40SBorislav Petkov 	.event_ctl	= SNB_UNC_ARB_PERFEVTSEL0,
35192553e40SBorislav Petkov 	.event_mask	= SNB_UNC_RAW_EVENT_MASK,
35292553e40SBorislav Petkov 	.msr_offset	= SNB_UNC_ARB_MSR_OFFSET,
35392553e40SBorislav Petkov 	.constraints	= snb_uncore_arb_constraints,
35492553e40SBorislav Petkov 	.ops		= &snb_uncore_msr_ops,
35592553e40SBorislav Petkov 	.format_group	= &snb_uncore_format_group,
35692553e40SBorislav Petkov };
35792553e40SBorislav Petkov 
35892553e40SBorislav Petkov static struct intel_uncore_type *snb_msr_uncores[] = {
35992553e40SBorislav Petkov 	&snb_uncore_cbox,
36092553e40SBorislav Petkov 	&snb_uncore_arb,
36192553e40SBorislav Petkov 	NULL,
36292553e40SBorislav Petkov };
36392553e40SBorislav Petkov 
snb_uncore_cpu_init(void)36492553e40SBorislav Petkov void snb_uncore_cpu_init(void)
36592553e40SBorislav Petkov {
36692553e40SBorislav Petkov 	uncore_msr_uncores = snb_msr_uncores;
36792553e40SBorislav Petkov 	if (snb_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
36892553e40SBorislav Petkov 		snb_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
36992553e40SBorislav Petkov }
37092553e40SBorislav Petkov 
skl_uncore_msr_init_box(struct intel_uncore_box * box)37146866b59SKan Liang static void skl_uncore_msr_init_box(struct intel_uncore_box *box)
37246866b59SKan Liang {
37346866b59SKan Liang 	if (box->pmu->pmu_idx == 0) {
37446866b59SKan Liang 		wrmsrl(SKL_UNC_PERF_GLOBAL_CTL,
37546866b59SKan Liang 			SNB_UNC_GLOBAL_CTL_EN | SKL_UNC_GLOBAL_CTL_CORE_ALL);
37646866b59SKan Liang 	}
3774d47d640SKan Liang 
3784d47d640SKan Liang 	/* The 8th CBOX has different MSR space */
3794d47d640SKan Liang 	if (box->pmu->pmu_idx == 7)
3804d47d640SKan Liang 		__set_bit(UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS, &box->flags);
38146866b59SKan Liang }
38246866b59SKan Liang 
skl_uncore_msr_enable_box(struct intel_uncore_box * box)38395f3be79SKan Liang static void skl_uncore_msr_enable_box(struct intel_uncore_box *box)
38495f3be79SKan Liang {
38595f3be79SKan Liang 	wrmsrl(SKL_UNC_PERF_GLOBAL_CTL,
38695f3be79SKan Liang 		SNB_UNC_GLOBAL_CTL_EN | SKL_UNC_GLOBAL_CTL_CORE_ALL);
38795f3be79SKan Liang }
38895f3be79SKan Liang 
skl_uncore_msr_exit_box(struct intel_uncore_box * box)38946866b59SKan Liang static void skl_uncore_msr_exit_box(struct intel_uncore_box *box)
39046866b59SKan Liang {
39146866b59SKan Liang 	if (box->pmu->pmu_idx == 0)
39246866b59SKan Liang 		wrmsrl(SKL_UNC_PERF_GLOBAL_CTL, 0);
39346866b59SKan Liang }
39446866b59SKan Liang 
39546866b59SKan Liang static struct intel_uncore_ops skl_uncore_msr_ops = {
39646866b59SKan Liang 	.init_box	= skl_uncore_msr_init_box,
39795f3be79SKan Liang 	.enable_box	= skl_uncore_msr_enable_box,
39846866b59SKan Liang 	.exit_box	= skl_uncore_msr_exit_box,
39946866b59SKan Liang 	.disable_event	= snb_uncore_msr_disable_event,
40046866b59SKan Liang 	.enable_event	= snb_uncore_msr_enable_event,
40146866b59SKan Liang 	.read_counter	= uncore_msr_read_counter,
40246866b59SKan Liang };
40346866b59SKan Liang 
40446866b59SKan Liang static struct intel_uncore_type skl_uncore_cbox = {
40546866b59SKan Liang 	.name		= "cbox",
40646866b59SKan Liang 	.num_counters   = 4,
4074d47d640SKan Liang 	.num_boxes	= 8,
40846866b59SKan Liang 	.perf_ctr_bits	= 44,
40946866b59SKan Liang 	.fixed_ctr_bits	= 48,
41046866b59SKan Liang 	.perf_ctr	= SNB_UNC_CBO_0_PER_CTR0,
41146866b59SKan Liang 	.event_ctl	= SNB_UNC_CBO_0_PERFEVTSEL0,
41246866b59SKan Liang 	.fixed_ctr	= SNB_UNC_FIXED_CTR,
41346866b59SKan Liang 	.fixed_ctl	= SNB_UNC_FIXED_CTR_CTRL,
41446866b59SKan Liang 	.single_fixed	= 1,
41546866b59SKan Liang 	.event_mask	= SNB_UNC_RAW_EVENT_MASK,
41646866b59SKan Liang 	.msr_offset	= SNB_UNC_CBO_MSR_OFFSET,
41746866b59SKan Liang 	.ops		= &skl_uncore_msr_ops,
41846866b59SKan Liang 	.format_group	= &snb_uncore_format_group,
41946866b59SKan Liang 	.event_descs	= snb_uncore_events,
42046866b59SKan Liang };
42146866b59SKan Liang 
42246866b59SKan Liang static struct intel_uncore_type *skl_msr_uncores[] = {
42346866b59SKan Liang 	&skl_uncore_cbox,
42446866b59SKan Liang 	&snb_uncore_arb,
42546866b59SKan Liang 	NULL,
42646866b59SKan Liang };
42746866b59SKan Liang 
skl_uncore_cpu_init(void)42846866b59SKan Liang void skl_uncore_cpu_init(void)
42946866b59SKan Liang {
43046866b59SKan Liang 	uncore_msr_uncores = skl_msr_uncores;
43146866b59SKan Liang 	if (skl_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
43246866b59SKan Liang 		skl_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
43346866b59SKan Liang 	snb_uncore_arb.ops = &skl_uncore_msr_ops;
43446866b59SKan Liang }
43546866b59SKan Liang 
4368f5d41f3SKan Liang static struct intel_uncore_ops icl_uncore_msr_ops = {
4378f5d41f3SKan Liang 	.disable_event	= snb_uncore_msr_disable_event,
4388f5d41f3SKan Liang 	.enable_event	= snb_uncore_msr_enable_event,
4398f5d41f3SKan Liang 	.read_counter	= uncore_msr_read_counter,
4408f5d41f3SKan Liang };
4418f5d41f3SKan Liang 
4426e394376SKan Liang static struct intel_uncore_type icl_uncore_cbox = {
4436e394376SKan Liang 	.name		= "cbox",
444ee139385SKan Liang 	.num_counters   = 2,
4456e394376SKan Liang 	.perf_ctr_bits	= 44,
4466e394376SKan Liang 	.perf_ctr	= ICL_UNC_CBO_0_PER_CTR0,
4476e394376SKan Liang 	.event_ctl	= SNB_UNC_CBO_0_PERFEVTSEL0,
4486e394376SKan Liang 	.event_mask	= SNB_UNC_RAW_EVENT_MASK,
4496e394376SKan Liang 	.msr_offset	= ICL_UNC_CBO_MSR_OFFSET,
4508f5d41f3SKan Liang 	.ops		= &icl_uncore_msr_ops,
4516e394376SKan Liang 	.format_group	= &snb_uncore_format_group,
4526e394376SKan Liang };
4536e394376SKan Liang 
4546e394376SKan Liang static struct uncore_event_desc icl_uncore_events[] = {
4556e394376SKan Liang 	INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff"),
4566e394376SKan Liang 	{ /* end: all zeroes */ },
4576e394376SKan Liang };
4586e394376SKan Liang 
4596e394376SKan Liang static struct attribute *icl_uncore_clock_formats_attr[] = {
4606e394376SKan Liang 	&format_attr_event.attr,
4616e394376SKan Liang 	NULL,
4626e394376SKan Liang };
4636e394376SKan Liang 
4646e394376SKan Liang static struct attribute_group icl_uncore_clock_format_group = {
4656e394376SKan Liang 	.name = "format",
4666e394376SKan Liang 	.attrs = icl_uncore_clock_formats_attr,
4676e394376SKan Liang };
4686e394376SKan Liang 
4696e394376SKan Liang static struct intel_uncore_type icl_uncore_clockbox = {
4706e394376SKan Liang 	.name		= "clock",
4716e394376SKan Liang 	.num_counters	= 1,
4726e394376SKan Liang 	.num_boxes	= 1,
4736e394376SKan Liang 	.fixed_ctr_bits	= 48,
4746e394376SKan Liang 	.fixed_ctr	= SNB_UNC_FIXED_CTR,
4756e394376SKan Liang 	.fixed_ctl	= SNB_UNC_FIXED_CTR_CTRL,
4766e394376SKan Liang 	.single_fixed	= 1,
4776e394376SKan Liang 	.event_mask	= SNB_UNC_CTL_EV_SEL_MASK,
4786e394376SKan Liang 	.format_group	= &icl_uncore_clock_format_group,
4798f5d41f3SKan Liang 	.ops		= &icl_uncore_msr_ops,
4806e394376SKan Liang 	.event_descs	= icl_uncore_events,
4816e394376SKan Liang };
4826e394376SKan Liang 
4838f5d41f3SKan Liang static struct intel_uncore_type icl_uncore_arb = {
4848f5d41f3SKan Liang 	.name		= "arb",
4858f5d41f3SKan Liang 	.num_counters   = 1,
4868f5d41f3SKan Liang 	.num_boxes	= 1,
4878f5d41f3SKan Liang 	.perf_ctr_bits	= 44,
4888f5d41f3SKan Liang 	.perf_ctr	= ICL_UNC_ARB_PER_CTR,
4898f5d41f3SKan Liang 	.event_ctl	= ICL_UNC_ARB_PERFEVTSEL,
4908f5d41f3SKan Liang 	.event_mask	= SNB_UNC_RAW_EVENT_MASK,
4918f5d41f3SKan Liang 	.ops		= &icl_uncore_msr_ops,
4928f5d41f3SKan Liang 	.format_group	= &snb_uncore_format_group,
4938f5d41f3SKan Liang };
4948f5d41f3SKan Liang 
4956e394376SKan Liang static struct intel_uncore_type *icl_msr_uncores[] = {
4966e394376SKan Liang 	&icl_uncore_cbox,
4978f5d41f3SKan Liang 	&icl_uncore_arb,
4986e394376SKan Liang 	&icl_uncore_clockbox,
4996e394376SKan Liang 	NULL,
5006e394376SKan Liang };
5016e394376SKan Liang 
icl_get_cbox_num(void)5026e394376SKan Liang static int icl_get_cbox_num(void)
5036e394376SKan Liang {
5046e394376SKan Liang 	u64 num_boxes;
5056e394376SKan Liang 
5066e394376SKan Liang 	rdmsrl(ICL_UNC_CBO_CONFIG, num_boxes);
5076e394376SKan Liang 
5086e394376SKan Liang 	return num_boxes & ICL_UNC_NUM_CBO_MASK;
5096e394376SKan Liang }
5106e394376SKan Liang 
icl_uncore_cpu_init(void)5116e394376SKan Liang void icl_uncore_cpu_init(void)
5126e394376SKan Liang {
5136e394376SKan Liang 	uncore_msr_uncores = icl_msr_uncores;
5146e394376SKan Liang 	icl_uncore_cbox.num_boxes = icl_get_cbox_num();
5156e394376SKan Liang }
5166e394376SKan Liang 
5178abbcfefSKan Liang static struct intel_uncore_type *tgl_msr_uncores[] = {
5188abbcfefSKan Liang 	&icl_uncore_cbox,
5198abbcfefSKan Liang 	&snb_uncore_arb,
5208abbcfefSKan Liang 	&icl_uncore_clockbox,
5218abbcfefSKan Liang 	NULL,
5228abbcfefSKan Liang };
5238abbcfefSKan Liang 
rkl_uncore_msr_init_box(struct intel_uncore_box * box)52443bc103aSKan Liang static void rkl_uncore_msr_init_box(struct intel_uncore_box *box)
52543bc103aSKan Liang {
52643bc103aSKan Liang 	if (box->pmu->pmu_idx == 0)
52743bc103aSKan Liang 		wrmsrl(SKL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
52843bc103aSKan Liang }
52943bc103aSKan Liang 
tgl_uncore_cpu_init(void)5308abbcfefSKan Liang void tgl_uncore_cpu_init(void)
5318abbcfefSKan Liang {
5328abbcfefSKan Liang 	uncore_msr_uncores = tgl_msr_uncores;
5338abbcfefSKan Liang 	icl_uncore_cbox.num_boxes = icl_get_cbox_num();
5348abbcfefSKan Liang 	icl_uncore_cbox.ops = &skl_uncore_msr_ops;
5358abbcfefSKan Liang 	icl_uncore_clockbox.ops = &skl_uncore_msr_ops;
5368abbcfefSKan Liang 	snb_uncore_arb.ops = &skl_uncore_msr_ops;
53743bc103aSKan Liang 	skl_uncore_msr_ops.init_box = rkl_uncore_msr_init_box;
5388abbcfefSKan Liang }
5398abbcfefSKan Liang 
adl_uncore_msr_init_box(struct intel_uncore_box * box)540772ed05fSKan Liang static void adl_uncore_msr_init_box(struct intel_uncore_box *box)
541772ed05fSKan Liang {
542772ed05fSKan Liang 	if (box->pmu->pmu_idx == 0)
543772ed05fSKan Liang 		wrmsrl(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
544772ed05fSKan Liang }
545772ed05fSKan Liang 
adl_uncore_msr_enable_box(struct intel_uncore_box * box)546772ed05fSKan Liang static void adl_uncore_msr_enable_box(struct intel_uncore_box *box)
547772ed05fSKan Liang {
548772ed05fSKan Liang 	wrmsrl(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
549772ed05fSKan Liang }
550772ed05fSKan Liang 
adl_uncore_msr_disable_box(struct intel_uncore_box * box)551772ed05fSKan Liang static void adl_uncore_msr_disable_box(struct intel_uncore_box *box)
552772ed05fSKan Liang {
553772ed05fSKan Liang 	if (box->pmu->pmu_idx == 0)
554772ed05fSKan Liang 		wrmsrl(ADL_UNC_PERF_GLOBAL_CTL, 0);
555772ed05fSKan Liang }
556772ed05fSKan Liang 
adl_uncore_msr_exit_box(struct intel_uncore_box * box)557772ed05fSKan Liang static void adl_uncore_msr_exit_box(struct intel_uncore_box *box)
558772ed05fSKan Liang {
559772ed05fSKan Liang 	if (box->pmu->pmu_idx == 0)
560772ed05fSKan Liang 		wrmsrl(ADL_UNC_PERF_GLOBAL_CTL, 0);
561772ed05fSKan Liang }
562772ed05fSKan Liang 
563772ed05fSKan Liang static struct intel_uncore_ops adl_uncore_msr_ops = {
564772ed05fSKan Liang 	.init_box	= adl_uncore_msr_init_box,
565772ed05fSKan Liang 	.enable_box	= adl_uncore_msr_enable_box,
566772ed05fSKan Liang 	.disable_box	= adl_uncore_msr_disable_box,
567772ed05fSKan Liang 	.exit_box	= adl_uncore_msr_exit_box,
568772ed05fSKan Liang 	.disable_event	= snb_uncore_msr_disable_event,
569772ed05fSKan Liang 	.enable_event	= snb_uncore_msr_enable_event,
570772ed05fSKan Liang 	.read_counter	= uncore_msr_read_counter,
571772ed05fSKan Liang };
572772ed05fSKan Liang 
573772ed05fSKan Liang static struct attribute *adl_uncore_formats_attr[] = {
574772ed05fSKan Liang 	&format_attr_event.attr,
575772ed05fSKan Liang 	&format_attr_umask.attr,
576772ed05fSKan Liang 	&format_attr_edge.attr,
577772ed05fSKan Liang 	&format_attr_inv.attr,
578772ed05fSKan Liang 	&format_attr_threshold.attr,
579772ed05fSKan Liang 	NULL,
580772ed05fSKan Liang };
581772ed05fSKan Liang 
582772ed05fSKan Liang static const struct attribute_group adl_uncore_format_group = {
583772ed05fSKan Liang 	.name		= "format",
584772ed05fSKan Liang 	.attrs		= adl_uncore_formats_attr,
585772ed05fSKan Liang };
586772ed05fSKan Liang 
587772ed05fSKan Liang static struct intel_uncore_type adl_uncore_cbox = {
588772ed05fSKan Liang 	.name		= "cbox",
589772ed05fSKan Liang 	.num_counters   = 2,
590772ed05fSKan Liang 	.perf_ctr_bits	= 44,
591772ed05fSKan Liang 	.perf_ctr	= ADL_UNC_CBO_0_PER_CTR0,
592772ed05fSKan Liang 	.event_ctl	= ADL_UNC_CBO_0_PERFEVTSEL0,
593772ed05fSKan Liang 	.event_mask	= ADL_UNC_RAW_EVENT_MASK,
594772ed05fSKan Liang 	.msr_offset	= ICL_UNC_CBO_MSR_OFFSET,
595772ed05fSKan Liang 	.ops		= &adl_uncore_msr_ops,
596772ed05fSKan Liang 	.format_group	= &adl_uncore_format_group,
597772ed05fSKan Liang };
598772ed05fSKan Liang 
599772ed05fSKan Liang static struct intel_uncore_type adl_uncore_arb = {
600772ed05fSKan Liang 	.name		= "arb",
601772ed05fSKan Liang 	.num_counters   = 2,
602772ed05fSKan Liang 	.num_boxes	= 2,
603772ed05fSKan Liang 	.perf_ctr_bits	= 44,
604772ed05fSKan Liang 	.perf_ctr	= ADL_UNC_ARB_PER_CTR0,
605772ed05fSKan Liang 	.event_ctl	= ADL_UNC_ARB_PERFEVTSEL0,
606772ed05fSKan Liang 	.event_mask	= SNB_UNC_RAW_EVENT_MASK,
607772ed05fSKan Liang 	.msr_offset	= ADL_UNC_ARB_MSR_OFFSET,
608772ed05fSKan Liang 	.constraints	= snb_uncore_arb_constraints,
609772ed05fSKan Liang 	.ops		= &adl_uncore_msr_ops,
610772ed05fSKan Liang 	.format_group	= &snb_uncore_format_group,
611772ed05fSKan Liang };
612772ed05fSKan Liang 
613772ed05fSKan Liang static struct intel_uncore_type adl_uncore_clockbox = {
614772ed05fSKan Liang 	.name		= "clock",
615772ed05fSKan Liang 	.num_counters	= 1,
616772ed05fSKan Liang 	.num_boxes	= 1,
617772ed05fSKan Liang 	.fixed_ctr_bits	= 48,
618772ed05fSKan Liang 	.fixed_ctr	= ADL_UNC_FIXED_CTR,
619772ed05fSKan Liang 	.fixed_ctl	= ADL_UNC_FIXED_CTR_CTRL,
620772ed05fSKan Liang 	.single_fixed	= 1,
621772ed05fSKan Liang 	.event_mask	= SNB_UNC_CTL_EV_SEL_MASK,
622772ed05fSKan Liang 	.format_group	= &icl_uncore_clock_format_group,
623772ed05fSKan Liang 	.ops		= &adl_uncore_msr_ops,
624772ed05fSKan Liang 	.event_descs	= icl_uncore_events,
625772ed05fSKan Liang };
626772ed05fSKan Liang 
627772ed05fSKan Liang static struct intel_uncore_type *adl_msr_uncores[] = {
628772ed05fSKan Liang 	&adl_uncore_cbox,
629772ed05fSKan Liang 	&adl_uncore_arb,
630772ed05fSKan Liang 	&adl_uncore_clockbox,
631772ed05fSKan Liang 	NULL,
632772ed05fSKan Liang };
633772ed05fSKan Liang 
adl_uncore_cpu_init(void)634772ed05fSKan Liang void adl_uncore_cpu_init(void)
635772ed05fSKan Liang {
636772ed05fSKan Liang 	adl_uncore_cbox.num_boxes = icl_get_cbox_num();
637772ed05fSKan Liang 	uncore_msr_uncores = adl_msr_uncores;
638772ed05fSKan Liang }
639772ed05fSKan Liang 
640*c828441fSKan Liang static struct intel_uncore_type mtl_uncore_cbox = {
641*c828441fSKan Liang 	.name		= "cbox",
642*c828441fSKan Liang 	.num_counters   = 2,
643*c828441fSKan Liang 	.perf_ctr_bits	= 48,
644*c828441fSKan Liang 	.perf_ctr	= MTL_UNC_CBO_0_PER_CTR0,
645*c828441fSKan Liang 	.event_ctl	= MTL_UNC_CBO_0_PERFEVTSEL0,
646*c828441fSKan Liang 	.event_mask	= ADL_UNC_RAW_EVENT_MASK,
647*c828441fSKan Liang 	.msr_offset	= SNB_UNC_CBO_MSR_OFFSET,
648*c828441fSKan Liang 	.ops		= &icl_uncore_msr_ops,
649*c828441fSKan Liang 	.format_group	= &adl_uncore_format_group,
650*c828441fSKan Liang };
651*c828441fSKan Liang 
652*c828441fSKan Liang static struct intel_uncore_type mtl_uncore_hac_arb = {
653*c828441fSKan Liang 	.name		= "hac_arb",
654*c828441fSKan Liang 	.num_counters   = 2,
655*c828441fSKan Liang 	.num_boxes	= 2,
656*c828441fSKan Liang 	.perf_ctr_bits	= 48,
657*c828441fSKan Liang 	.perf_ctr	= MTL_UNC_HAC_ARB_CTR,
658*c828441fSKan Liang 	.event_ctl	= MTL_UNC_HAC_ARB_CTRL,
659*c828441fSKan Liang 	.event_mask	= ADL_UNC_RAW_EVENT_MASK,
660*c828441fSKan Liang 	.msr_offset	= SNB_UNC_CBO_MSR_OFFSET,
661*c828441fSKan Liang 	.ops		= &icl_uncore_msr_ops,
662*c828441fSKan Liang 	.format_group	= &adl_uncore_format_group,
663*c828441fSKan Liang };
664*c828441fSKan Liang 
665*c828441fSKan Liang static struct intel_uncore_type mtl_uncore_arb = {
666*c828441fSKan Liang 	.name		= "arb",
667*c828441fSKan Liang 	.num_counters   = 2,
668*c828441fSKan Liang 	.num_boxes	= 2,
669*c828441fSKan Liang 	.perf_ctr_bits	= 48,
670*c828441fSKan Liang 	.perf_ctr	= MTL_UNC_ARB_CTR,
671*c828441fSKan Liang 	.event_ctl	= MTL_UNC_ARB_CTRL,
672*c828441fSKan Liang 	.event_mask	= ADL_UNC_RAW_EVENT_MASK,
673*c828441fSKan Liang 	.msr_offset	= SNB_UNC_CBO_MSR_OFFSET,
674*c828441fSKan Liang 	.ops		= &icl_uncore_msr_ops,
675*c828441fSKan Liang 	.format_group	= &adl_uncore_format_group,
676*c828441fSKan Liang };
677*c828441fSKan Liang 
678*c828441fSKan Liang static struct intel_uncore_type mtl_uncore_hac_cbox = {
679*c828441fSKan Liang 	.name		= "hac_cbox",
680*c828441fSKan Liang 	.num_counters   = 2,
681*c828441fSKan Liang 	.num_boxes	= 2,
682*c828441fSKan Liang 	.perf_ctr_bits	= 48,
683*c828441fSKan Liang 	.perf_ctr	= MTL_UNC_HBO_CTR,
684*c828441fSKan Liang 	.event_ctl	= MTL_UNC_HBO_CTRL,
685*c828441fSKan Liang 	.event_mask	= ADL_UNC_RAW_EVENT_MASK,
686*c828441fSKan Liang 	.msr_offset	= SNB_UNC_CBO_MSR_OFFSET,
687*c828441fSKan Liang 	.ops		= &icl_uncore_msr_ops,
688*c828441fSKan Liang 	.format_group	= &adl_uncore_format_group,
689*c828441fSKan Liang };
690*c828441fSKan Liang 
mtl_uncore_msr_init_box(struct intel_uncore_box * box)691*c828441fSKan Liang static void mtl_uncore_msr_init_box(struct intel_uncore_box *box)
692*c828441fSKan Liang {
693*c828441fSKan Liang 	wrmsrl(uncore_msr_box_ctl(box), SNB_UNC_GLOBAL_CTL_EN);
694*c828441fSKan Liang }
695*c828441fSKan Liang 
696*c828441fSKan Liang static struct intel_uncore_ops mtl_uncore_msr_ops = {
697*c828441fSKan Liang 	.init_box	= mtl_uncore_msr_init_box,
698*c828441fSKan Liang 	.disable_event	= snb_uncore_msr_disable_event,
699*c828441fSKan Liang 	.enable_event	= snb_uncore_msr_enable_event,
700*c828441fSKan Liang 	.read_counter	= uncore_msr_read_counter,
701*c828441fSKan Liang };
702*c828441fSKan Liang 
703*c828441fSKan Liang static struct intel_uncore_type mtl_uncore_cncu = {
704*c828441fSKan Liang 	.name		= "cncu",
705*c828441fSKan Liang 	.num_counters   = 1,
706*c828441fSKan Liang 	.num_boxes	= 1,
707*c828441fSKan Liang 	.box_ctl	= MTL_UNC_CNCU_BOX_CTL,
708*c828441fSKan Liang 	.fixed_ctr_bits = 48,
709*c828441fSKan Liang 	.fixed_ctr	= MTL_UNC_CNCU_FIXED_CTR,
710*c828441fSKan Liang 	.fixed_ctl	= MTL_UNC_CNCU_FIXED_CTRL,
711*c828441fSKan Liang 	.single_fixed	= 1,
712*c828441fSKan Liang 	.event_mask	= SNB_UNC_CTL_EV_SEL_MASK,
713*c828441fSKan Liang 	.format_group	= &icl_uncore_clock_format_group,
714*c828441fSKan Liang 	.ops		= &mtl_uncore_msr_ops,
715*c828441fSKan Liang 	.event_descs	= icl_uncore_events,
716*c828441fSKan Liang };
717*c828441fSKan Liang 
718*c828441fSKan Liang static struct intel_uncore_type mtl_uncore_sncu = {
719*c828441fSKan Liang 	.name		= "sncu",
720*c828441fSKan Liang 	.num_counters   = 1,
721*c828441fSKan Liang 	.num_boxes	= 1,
722*c828441fSKan Liang 	.box_ctl	= MTL_UNC_SNCU_BOX_CTL,
723*c828441fSKan Liang 	.fixed_ctr_bits	= 48,
724*c828441fSKan Liang 	.fixed_ctr	= MTL_UNC_SNCU_FIXED_CTR,
725*c828441fSKan Liang 	.fixed_ctl	= MTL_UNC_SNCU_FIXED_CTRL,
726*c828441fSKan Liang 	.single_fixed	= 1,
727*c828441fSKan Liang 	.event_mask	= SNB_UNC_CTL_EV_SEL_MASK,
728*c828441fSKan Liang 	.format_group	= &icl_uncore_clock_format_group,
729*c828441fSKan Liang 	.ops		= &mtl_uncore_msr_ops,
730*c828441fSKan Liang 	.event_descs	= icl_uncore_events,
731*c828441fSKan Liang };
732*c828441fSKan Liang 
733*c828441fSKan Liang static struct intel_uncore_type *mtl_msr_uncores[] = {
734*c828441fSKan Liang 	&mtl_uncore_cbox,
735*c828441fSKan Liang 	&mtl_uncore_hac_arb,
736*c828441fSKan Liang 	&mtl_uncore_arb,
737*c828441fSKan Liang 	&mtl_uncore_hac_cbox,
738*c828441fSKan Liang 	&mtl_uncore_cncu,
739*c828441fSKan Liang 	&mtl_uncore_sncu,
740*c828441fSKan Liang 	NULL
741*c828441fSKan Liang };
742*c828441fSKan Liang 
mtl_uncore_cpu_init(void)743*c828441fSKan Liang void mtl_uncore_cpu_init(void)
744*c828441fSKan Liang {
745*c828441fSKan Liang 	mtl_uncore_cbox.num_boxes = icl_get_cbox_num();
746*c828441fSKan Liang 	uncore_msr_uncores = mtl_msr_uncores;
747*c828441fSKan Liang }
748*c828441fSKan Liang 
74992553e40SBorislav Petkov enum {
75092553e40SBorislav Petkov 	SNB_PCI_UNCORE_IMC,
75192553e40SBorislav Petkov };
75292553e40SBorislav Petkov 
75392553e40SBorislav Petkov static struct uncore_event_desc snb_uncore_imc_events[] = {
75492553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(data_reads,  "event=0x01"),
75592553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(data_reads.scale, "6.103515625e-5"),
75692553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(data_reads.unit, "MiB"),
75792553e40SBorislav Petkov 
75892553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(data_writes, "event=0x02"),
75992553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(data_writes.scale, "6.103515625e-5"),
76092553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(data_writes.unit, "MiB"),
76192553e40SBorislav Petkov 
76224633d90SVaibhav Shankar 	INTEL_UNCORE_EVENT_DESC(gt_requests, "event=0x03"),
76324633d90SVaibhav Shankar 	INTEL_UNCORE_EVENT_DESC(gt_requests.scale, "6.103515625e-5"),
76424633d90SVaibhav Shankar 	INTEL_UNCORE_EVENT_DESC(gt_requests.unit, "MiB"),
76524633d90SVaibhav Shankar 
76624633d90SVaibhav Shankar 	INTEL_UNCORE_EVENT_DESC(ia_requests, "event=0x04"),
76724633d90SVaibhav Shankar 	INTEL_UNCORE_EVENT_DESC(ia_requests.scale, "6.103515625e-5"),
76824633d90SVaibhav Shankar 	INTEL_UNCORE_EVENT_DESC(ia_requests.unit, "MiB"),
76924633d90SVaibhav Shankar 
77024633d90SVaibhav Shankar 	INTEL_UNCORE_EVENT_DESC(io_requests, "event=0x05"),
77124633d90SVaibhav Shankar 	INTEL_UNCORE_EVENT_DESC(io_requests.scale, "6.103515625e-5"),
77224633d90SVaibhav Shankar 	INTEL_UNCORE_EVENT_DESC(io_requests.unit, "MiB"),
77324633d90SVaibhav Shankar 
77492553e40SBorislav Petkov 	{ /* end: all zeroes */ },
77592553e40SBorislav Petkov };
77692553e40SBorislav Petkov 
77792553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_EVENT_MASK		0xff
77892553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_BAR_OFFSET		0x48
77992553e40SBorislav Petkov 
78092553e40SBorislav Petkov /* page size multiple covering all config regs */
78192553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_MAP_SIZE		0x6000
78292553e40SBorislav Petkov 
78392553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_DATA_READS		0x1
78492553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_DATA_READS_BASE	0x5050
78592553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_DATA_WRITES		0x2
78692553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE	0x5054
78792553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_CTR_BASE		SNB_UNCORE_PCI_IMC_DATA_READS_BASE
78892553e40SBorislav Petkov 
78924633d90SVaibhav Shankar /* BW break down- legacy counters */
79024633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_GT_REQUESTS		0x3
79124633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_GT_REQUESTS_BASE	0x5040
79224633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_IA_REQUESTS		0x4
79324633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_IA_REQUESTS_BASE	0x5044
79424633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_IO_REQUESTS		0x5
79524633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_IO_REQUESTS_BASE	0x5048
79624633d90SVaibhav Shankar 
7979aae1780SKan Liang enum perf_snb_uncore_imc_freerunning_types {
79824633d90SVaibhav Shankar 	SNB_PCI_UNCORE_IMC_DATA_READS		= 0,
79924633d90SVaibhav Shankar 	SNB_PCI_UNCORE_IMC_DATA_WRITES,
80024633d90SVaibhav Shankar 	SNB_PCI_UNCORE_IMC_GT_REQUESTS,
80124633d90SVaibhav Shankar 	SNB_PCI_UNCORE_IMC_IA_REQUESTS,
80224633d90SVaibhav Shankar 	SNB_PCI_UNCORE_IMC_IO_REQUESTS,
80324633d90SVaibhav Shankar 
8049aae1780SKan Liang 	SNB_PCI_UNCORE_IMC_FREERUNNING_TYPE_MAX,
8059aae1780SKan Liang };
8069aae1780SKan Liang 
8079aae1780SKan Liang static struct freerunning_counters snb_uncore_imc_freerunning[] = {
80824633d90SVaibhav Shankar 	[SNB_PCI_UNCORE_IMC_DATA_READS]		= { SNB_UNCORE_PCI_IMC_DATA_READS_BASE,
80924633d90SVaibhav Shankar 							0x0, 0x0, 1, 32 },
8101a8cfa24SArnd Bergmann 	[SNB_PCI_UNCORE_IMC_DATA_WRITES]	= { SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE,
81124633d90SVaibhav Shankar 							0x0, 0x0, 1, 32 },
81224633d90SVaibhav Shankar 	[SNB_PCI_UNCORE_IMC_GT_REQUESTS]	= { SNB_UNCORE_PCI_IMC_GT_REQUESTS_BASE,
81324633d90SVaibhav Shankar 							0x0, 0x0, 1, 32 },
81424633d90SVaibhav Shankar 	[SNB_PCI_UNCORE_IMC_IA_REQUESTS]	= { SNB_UNCORE_PCI_IMC_IA_REQUESTS_BASE,
81524633d90SVaibhav Shankar 							0x0, 0x0, 1, 32 },
81624633d90SVaibhav Shankar 	[SNB_PCI_UNCORE_IMC_IO_REQUESTS]	= { SNB_UNCORE_PCI_IMC_IO_REQUESTS_BASE,
81724633d90SVaibhav Shankar 							0x0, 0x0, 1, 32 },
8189aae1780SKan Liang };
8199aae1780SKan Liang 
82092553e40SBorislav Petkov static struct attribute *snb_uncore_imc_formats_attr[] = {
82192553e40SBorislav Petkov 	&format_attr_event.attr,
82292553e40SBorislav Petkov 	NULL,
82392553e40SBorislav Petkov };
82492553e40SBorislav Petkov 
82545bd07adSArvind Yadav static const struct attribute_group snb_uncore_imc_format_group = {
82692553e40SBorislav Petkov 	.name = "format",
82792553e40SBorislav Petkov 	.attrs = snb_uncore_imc_formats_attr,
82892553e40SBorislav Petkov };
82992553e40SBorislav Petkov 
snb_uncore_imc_init_box(struct intel_uncore_box * box)83092553e40SBorislav Petkov static void snb_uncore_imc_init_box(struct intel_uncore_box *box)
83192553e40SBorislav Petkov {
8321b94d31dSKan Liang 	struct intel_uncore_type *type = box->pmu->type;
83392553e40SBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
83492553e40SBorislav Petkov 	int where = SNB_UNCORE_PCI_IMC_BAR_OFFSET;
83592553e40SBorislav Petkov 	resource_size_t addr;
83692553e40SBorislav Petkov 	u32 pci_dword;
83792553e40SBorislav Petkov 
83892553e40SBorislav Petkov 	pci_read_config_dword(pdev, where, &pci_dword);
83992553e40SBorislav Petkov 	addr = pci_dword;
84092553e40SBorislav Petkov 
84192553e40SBorislav Petkov #ifdef CONFIG_PHYS_ADDR_T_64BIT
84292553e40SBorislav Petkov 	pci_read_config_dword(pdev, where + 4, &pci_dword);
84392553e40SBorislav Petkov 	addr |= ((resource_size_t)pci_dword << 32);
84492553e40SBorislav Petkov #endif
84592553e40SBorislav Petkov 
84692553e40SBorislav Petkov 	addr &= ~(PAGE_SIZE - 1);
84792553e40SBorislav Petkov 
8481b94d31dSKan Liang 	box->io_addr = ioremap(addr, type->mmio_map_size);
8491b94d31dSKan Liang 	if (!box->io_addr)
8501b94d31dSKan Liang 		pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
8511b94d31dSKan Liang 
85292553e40SBorislav Petkov 	box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL;
85392553e40SBorislav Petkov }
85492553e40SBorislav Petkov 
snb_uncore_imc_enable_box(struct intel_uncore_box * box)85592553e40SBorislav Petkov static void snb_uncore_imc_enable_box(struct intel_uncore_box *box)
85692553e40SBorislav Petkov {}
85792553e40SBorislav Petkov 
snb_uncore_imc_disable_box(struct intel_uncore_box * box)85892553e40SBorislav Petkov static void snb_uncore_imc_disable_box(struct intel_uncore_box *box)
85992553e40SBorislav Petkov {}
86092553e40SBorislav Petkov 
snb_uncore_imc_enable_event(struct intel_uncore_box * box,struct perf_event * event)86192553e40SBorislav Petkov static void snb_uncore_imc_enable_event(struct intel_uncore_box *box, struct perf_event *event)
86292553e40SBorislav Petkov {}
86392553e40SBorislav Petkov 
snb_uncore_imc_disable_event(struct intel_uncore_box * box,struct perf_event * event)86492553e40SBorislav Petkov static void snb_uncore_imc_disable_event(struct intel_uncore_box *box, struct perf_event *event)
86592553e40SBorislav Petkov {}
86692553e40SBorislav Petkov 
86792553e40SBorislav Petkov /*
8689aae1780SKan Liang  * Keep the custom event_init() function compatible with old event
8699aae1780SKan Liang  * encoding for free running counters.
87092553e40SBorislav Petkov  */
snb_uncore_imc_event_init(struct perf_event * event)87192553e40SBorislav Petkov static int snb_uncore_imc_event_init(struct perf_event *event)
87292553e40SBorislav Petkov {
87392553e40SBorislav Petkov 	struct intel_uncore_pmu *pmu;
87492553e40SBorislav Petkov 	struct intel_uncore_box *box;
87592553e40SBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
87692553e40SBorislav Petkov 	u64 cfg = event->attr.config & SNB_UNCORE_PCI_IMC_EVENT_MASK;
87792553e40SBorislav Petkov 	int idx, base;
87892553e40SBorislav Petkov 
87992553e40SBorislav Petkov 	if (event->attr.type != event->pmu->type)
88092553e40SBorislav Petkov 		return -ENOENT;
88192553e40SBorislav Petkov 
88292553e40SBorislav Petkov 	pmu = uncore_event_to_pmu(event);
88392553e40SBorislav Petkov 	/* no device found for this pmu */
88492553e40SBorislav Petkov 	if (pmu->func_id < 0)
88592553e40SBorislav Petkov 		return -ENOENT;
88692553e40SBorislav Petkov 
88792553e40SBorislav Petkov 	/* Sampling not supported yet */
88892553e40SBorislav Petkov 	if (hwc->sample_period)
88992553e40SBorislav Petkov 		return -EINVAL;
89092553e40SBorislav Petkov 
89192553e40SBorislav Petkov 	/* unsupported modes and filters */
8922ff40250SAndrew Murray 	if (event->attr.sample_period) /* no sampling */
89392553e40SBorislav Petkov 		return -EINVAL;
89492553e40SBorislav Petkov 
89592553e40SBorislav Petkov 	/*
89692553e40SBorislav Petkov 	 * Place all uncore events for a particular physical package
89792553e40SBorislav Petkov 	 * onto a single cpu
89892553e40SBorislav Petkov 	 */
89992553e40SBorislav Petkov 	if (event->cpu < 0)
90092553e40SBorislav Petkov 		return -EINVAL;
90192553e40SBorislav Petkov 
90292553e40SBorislav Petkov 	/* check only supported bits are set */
90392553e40SBorislav Petkov 	if (event->attr.config & ~SNB_UNCORE_PCI_IMC_EVENT_MASK)
90492553e40SBorislav Petkov 		return -EINVAL;
90592553e40SBorislav Petkov 
90692553e40SBorislav Petkov 	box = uncore_pmu_to_box(pmu, event->cpu);
90792553e40SBorislav Petkov 	if (!box || box->cpu < 0)
90892553e40SBorislav Petkov 		return -EINVAL;
90992553e40SBorislav Petkov 
91092553e40SBorislav Petkov 	event->cpu = box->cpu;
9111f2569faSThomas Gleixner 	event->pmu_private = box;
91292553e40SBorislav Petkov 
913e64cd6f7SDavid Carrillo-Cisneros 	event->event_caps |= PERF_EV_CAP_READ_ACTIVE_PKG;
914e64cd6f7SDavid Carrillo-Cisneros 
91592553e40SBorislav Petkov 	event->hw.idx = -1;
91692553e40SBorislav Petkov 	event->hw.last_tag = ~0ULL;
91792553e40SBorislav Petkov 	event->hw.extra_reg.idx = EXTRA_REG_NONE;
91892553e40SBorislav Petkov 	event->hw.branch_reg.idx = EXTRA_REG_NONE;
91992553e40SBorislav Petkov 	/*
92092553e40SBorislav Petkov 	 * check event is known (whitelist, determines counter)
92192553e40SBorislav Petkov 	 */
92292553e40SBorislav Petkov 	switch (cfg) {
92392553e40SBorislav Petkov 	case SNB_UNCORE_PCI_IMC_DATA_READS:
92492553e40SBorislav Petkov 		base = SNB_UNCORE_PCI_IMC_DATA_READS_BASE;
9259aae1780SKan Liang 		idx = UNCORE_PMC_IDX_FREERUNNING;
92692553e40SBorislav Petkov 		break;
92792553e40SBorislav Petkov 	case SNB_UNCORE_PCI_IMC_DATA_WRITES:
92892553e40SBorislav Petkov 		base = SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE;
9299aae1780SKan Liang 		idx = UNCORE_PMC_IDX_FREERUNNING;
93092553e40SBorislav Petkov 		break;
93124633d90SVaibhav Shankar 	case SNB_UNCORE_PCI_IMC_GT_REQUESTS:
93224633d90SVaibhav Shankar 		base = SNB_UNCORE_PCI_IMC_GT_REQUESTS_BASE;
93324633d90SVaibhav Shankar 		idx = UNCORE_PMC_IDX_FREERUNNING;
93424633d90SVaibhav Shankar 		break;
93524633d90SVaibhav Shankar 	case SNB_UNCORE_PCI_IMC_IA_REQUESTS:
93624633d90SVaibhav Shankar 		base = SNB_UNCORE_PCI_IMC_IA_REQUESTS_BASE;
93724633d90SVaibhav Shankar 		idx = UNCORE_PMC_IDX_FREERUNNING;
93824633d90SVaibhav Shankar 		break;
93924633d90SVaibhav Shankar 	case SNB_UNCORE_PCI_IMC_IO_REQUESTS:
94024633d90SVaibhav Shankar 		base = SNB_UNCORE_PCI_IMC_IO_REQUESTS_BASE;
94124633d90SVaibhav Shankar 		idx = UNCORE_PMC_IDX_FREERUNNING;
94224633d90SVaibhav Shankar 		break;
94392553e40SBorislav Petkov 	default:
94492553e40SBorislav Petkov 		return -EINVAL;
94592553e40SBorislav Petkov 	}
94692553e40SBorislav Petkov 
94792553e40SBorislav Petkov 	/* must be done before validate_group */
94892553e40SBorislav Petkov 	event->hw.event_base = base;
94992553e40SBorislav Petkov 	event->hw.idx = idx;
95092553e40SBorislav Petkov 
9518041ffd3SKan Liang 	/* Convert to standard encoding format for freerunning counters */
9528041ffd3SKan Liang 	event->hw.config = ((cfg - 1) << 8) | 0x10ff;
9538041ffd3SKan Liang 
95492553e40SBorislav Petkov 	/* no group validation needed, we have free running counters */
95592553e40SBorislav Petkov 
95692553e40SBorislav Petkov 	return 0;
95792553e40SBorislav Petkov }
95892553e40SBorislav Petkov 
snb_uncore_imc_hw_config(struct intel_uncore_box * box,struct perf_event * event)95992553e40SBorislav Petkov static int snb_uncore_imc_hw_config(struct intel_uncore_box *box, struct perf_event *event)
96092553e40SBorislav Petkov {
96192553e40SBorislav Petkov 	return 0;
96292553e40SBorislav Petkov }
96392553e40SBorislav Petkov 
snb_pci2phy_map_init(int devid)96492553e40SBorislav Petkov int snb_pci2phy_map_init(int devid)
96592553e40SBorislav Petkov {
96692553e40SBorislav Petkov 	struct pci_dev *dev = NULL;
96792553e40SBorislav Petkov 	struct pci2phy_map *map;
96892553e40SBorislav Petkov 	int bus, segment;
96992553e40SBorislav Petkov 
97092553e40SBorislav Petkov 	dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, dev);
97192553e40SBorislav Petkov 	if (!dev)
97292553e40SBorislav Petkov 		return -ENOTTY;
97392553e40SBorislav Petkov 
97492553e40SBorislav Petkov 	bus = dev->bus->number;
97592553e40SBorislav Petkov 	segment = pci_domain_nr(dev->bus);
97692553e40SBorislav Petkov 
97792553e40SBorislav Petkov 	raw_spin_lock(&pci2phy_map_lock);
97892553e40SBorislav Petkov 	map = __find_pci2phy_map(segment);
97992553e40SBorislav Petkov 	if (!map) {
98092553e40SBorislav Petkov 		raw_spin_unlock(&pci2phy_map_lock);
98192553e40SBorislav Petkov 		pci_dev_put(dev);
98292553e40SBorislav Petkov 		return -ENOMEM;
98392553e40SBorislav Petkov 	}
984ba9506beSSteve Wahl 	map->pbus_to_dieid[bus] = 0;
98592553e40SBorislav Petkov 	raw_spin_unlock(&pci2phy_map_lock);
98692553e40SBorislav Petkov 
98792553e40SBorislav Petkov 	pci_dev_put(dev);
98892553e40SBorislav Petkov 
98992553e40SBorislav Petkov 	return 0;
99092553e40SBorislav Petkov }
99192553e40SBorislav Petkov 
snb_uncore_imc_read_counter(struct intel_uncore_box * box,struct perf_event * event)99211745ecfSStephane Eranian static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event)
99311745ecfSStephane Eranian {
99411745ecfSStephane Eranian 	struct hw_perf_event *hwc = &event->hw;
99511745ecfSStephane Eranian 
99611745ecfSStephane Eranian 	/*
99711745ecfSStephane Eranian 	 * SNB IMC counters are 32-bit and are laid out back to back
99811745ecfSStephane Eranian 	 * in MMIO space. Therefore we must use a 32-bit accessor function
99911745ecfSStephane Eranian 	 * using readq() from uncore_mmio_read_counter() causes problems
100011745ecfSStephane Eranian 	 * because it is reading 64-bit at a time. This is okay for the
100111745ecfSStephane Eranian 	 * uncore_perf_event_update() function because it drops the upper
100211745ecfSStephane Eranian 	 * 32-bits but not okay for plain uncore_read_counter() as invoked
100311745ecfSStephane Eranian 	 * in uncore_pmu_event_start().
100411745ecfSStephane Eranian 	 */
100511745ecfSStephane Eranian 	return (u64)readl(box->io_addr + hwc->event_base);
100611745ecfSStephane Eranian }
100711745ecfSStephane Eranian 
100892553e40SBorislav Petkov static struct pmu snb_uncore_imc_pmu = {
100992553e40SBorislav Petkov 	.task_ctx_nr	= perf_invalid_context,
101092553e40SBorislav Petkov 	.event_init	= snb_uncore_imc_event_init,
10119aae1780SKan Liang 	.add		= uncore_pmu_event_add,
10129aae1780SKan Liang 	.del		= uncore_pmu_event_del,
10139aae1780SKan Liang 	.start		= uncore_pmu_event_start,
10149aae1780SKan Liang 	.stop		= uncore_pmu_event_stop,
10159aae1780SKan Liang 	.read		= uncore_pmu_event_read,
10162ff40250SAndrew Murray 	.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
101792553e40SBorislav Petkov };
101892553e40SBorislav Petkov 
101992553e40SBorislav Petkov static struct intel_uncore_ops snb_uncore_imc_ops = {
102092553e40SBorislav Petkov 	.init_box	= snb_uncore_imc_init_box,
102107ce734dSKan Liang 	.exit_box	= uncore_mmio_exit_box,
102292553e40SBorislav Petkov 	.enable_box	= snb_uncore_imc_enable_box,
102392553e40SBorislav Petkov 	.disable_box	= snb_uncore_imc_disable_box,
102492553e40SBorislav Petkov 	.disable_event	= snb_uncore_imc_disable_event,
102592553e40SBorislav Petkov 	.enable_event	= snb_uncore_imc_enable_event,
102692553e40SBorislav Petkov 	.hw_config	= snb_uncore_imc_hw_config,
102711745ecfSStephane Eranian 	.read_counter	= snb_uncore_imc_read_counter,
102892553e40SBorislav Petkov };
102992553e40SBorislav Petkov 
103092553e40SBorislav Petkov static struct intel_uncore_type snb_uncore_imc = {
103192553e40SBorislav Petkov 	.name		= "imc",
103224633d90SVaibhav Shankar 	.num_counters   = 5,
103392553e40SBorislav Petkov 	.num_boxes	= 1,
10349aae1780SKan Liang 	.num_freerunning_types	= SNB_PCI_UNCORE_IMC_FREERUNNING_TYPE_MAX,
10351b94d31dSKan Liang 	.mmio_map_size	= SNB_UNCORE_PCI_IMC_MAP_SIZE,
10369aae1780SKan Liang 	.freerunning	= snb_uncore_imc_freerunning,
103792553e40SBorislav Petkov 	.event_descs	= snb_uncore_imc_events,
103892553e40SBorislav Petkov 	.format_group	= &snb_uncore_imc_format_group,
103992553e40SBorislav Petkov 	.ops		= &snb_uncore_imc_ops,
104092553e40SBorislav Petkov 	.pmu		= &snb_uncore_imc_pmu,
104192553e40SBorislav Petkov };
104292553e40SBorislav Petkov 
104392553e40SBorislav Petkov static struct intel_uncore_type *snb_pci_uncores[] = {
104492553e40SBorislav Petkov 	[SNB_PCI_UNCORE_IMC]	= &snb_uncore_imc,
104592553e40SBorislav Petkov 	NULL,
104692553e40SBorislav Petkov };
104792553e40SBorislav Petkov 
104892553e40SBorislav Petkov static const struct pci_device_id snb_uncore_pci_ids[] = {
1049e5ae168eSKan Liang 	IMC_UNCORE_DEV(SNB),
105092553e40SBorislav Petkov 	{ /* end: all zeroes */ },
105192553e40SBorislav Petkov };
105292553e40SBorislav Petkov 
105392553e40SBorislav Petkov static const struct pci_device_id ivb_uncore_pci_ids[] = {
1054e5ae168eSKan Liang 	IMC_UNCORE_DEV(IVB),
1055e5ae168eSKan Liang 	IMC_UNCORE_DEV(IVB_E3),
105692553e40SBorislav Petkov 	{ /* end: all zeroes */ },
105792553e40SBorislav Petkov };
105892553e40SBorislav Petkov 
105992553e40SBorislav Petkov static const struct pci_device_id hsw_uncore_pci_ids[] = {
1060e5ae168eSKan Liang 	IMC_UNCORE_DEV(HSW),
1061e5ae168eSKan Liang 	IMC_UNCORE_DEV(HSW_U),
106292553e40SBorislav Petkov 	{ /* end: all zeroes */ },
106392553e40SBorislav Petkov };
106492553e40SBorislav Petkov 
106592553e40SBorislav Petkov static const struct pci_device_id bdw_uncore_pci_ids[] = {
1066e5ae168eSKan Liang 	IMC_UNCORE_DEV(BDW),
106792553e40SBorislav Petkov 	{ /* end: all zeroes */ },
106892553e40SBorislav Petkov };
106992553e40SBorislav Petkov 
107092553e40SBorislav Petkov static const struct pci_device_id skl_uncore_pci_ids[] = {
1071e5ae168eSKan Liang 	IMC_UNCORE_DEV(SKL_Y),
1072e5ae168eSKan Liang 	IMC_UNCORE_DEV(SKL_U),
1073e5ae168eSKan Liang 	IMC_UNCORE_DEV(SKL_HD),
1074e5ae168eSKan Liang 	IMC_UNCORE_DEV(SKL_HQ),
1075e5ae168eSKan Liang 	IMC_UNCORE_DEV(SKL_SD),
1076e5ae168eSKan Liang 	IMC_UNCORE_DEV(SKL_SQ),
1077e5ae168eSKan Liang 	IMC_UNCORE_DEV(SKL_E3),
1078e5ae168eSKan Liang 	IMC_UNCORE_DEV(KBL_Y),
1079e5ae168eSKan Liang 	IMC_UNCORE_DEV(KBL_U),
1080e5ae168eSKan Liang 	IMC_UNCORE_DEV(KBL_UQ),
1081e5ae168eSKan Liang 	IMC_UNCORE_DEV(KBL_SD),
1082e5ae168eSKan Liang 	IMC_UNCORE_DEV(KBL_SQ),
1083e5ae168eSKan Liang 	IMC_UNCORE_DEV(KBL_HQ),
1084e5ae168eSKan Liang 	IMC_UNCORE_DEV(KBL_WQ),
1085e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_2U),
1086e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_4U),
1087e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_4H),
1088e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_6H),
1089e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_2S_D),
1090e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_4S_D),
1091e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_6S_D),
1092e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_8S_D),
1093e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_4S_W),
1094e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_6S_W),
1095e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_8S_W),
1096e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_4S_S),
1097e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_6S_S),
1098e5ae168eSKan Liang 	IMC_UNCORE_DEV(CFL_8S_S),
1099e5ae168eSKan Liang 	IMC_UNCORE_DEV(AML_YD),
1100e5ae168eSKan Liang 	IMC_UNCORE_DEV(AML_YQ),
1101e5ae168eSKan Liang 	IMC_UNCORE_DEV(WHL_UQ),
1102e5ae168eSKan Liang 	IMC_UNCORE_DEV(WHL_4_UQ),
1103e5ae168eSKan Liang 	IMC_UNCORE_DEV(WHL_UD),
1104e5ae168eSKan Liang 	IMC_UNCORE_DEV(CML_H1),
1105e5ae168eSKan Liang 	IMC_UNCORE_DEV(CML_H2),
1106e5ae168eSKan Liang 	IMC_UNCORE_DEV(CML_H3),
1107e5ae168eSKan Liang 	IMC_UNCORE_DEV(CML_U1),
1108e5ae168eSKan Liang 	IMC_UNCORE_DEV(CML_U2),
1109e5ae168eSKan Liang 	IMC_UNCORE_DEV(CML_U3),
1110e5ae168eSKan Liang 	IMC_UNCORE_DEV(CML_S1),
1111e5ae168eSKan Liang 	IMC_UNCORE_DEV(CML_S2),
1112e5ae168eSKan Liang 	IMC_UNCORE_DEV(CML_S3),
1113e5ae168eSKan Liang 	IMC_UNCORE_DEV(CML_S4),
1114e5ae168eSKan Liang 	IMC_UNCORE_DEV(CML_S5),
111592553e40SBorislav Petkov 	{ /* end: all zeroes */ },
111692553e40SBorislav Petkov };
111792553e40SBorislav Petkov 
11186e394376SKan Liang static const struct pci_device_id icl_uncore_pci_ids[] = {
1119e5ae168eSKan Liang 	IMC_UNCORE_DEV(ICL_U),
1120e5ae168eSKan Liang 	IMC_UNCORE_DEV(ICL_U2),
1121e5ae168eSKan Liang 	IMC_UNCORE_DEV(RKL_1),
1122e5ae168eSKan Liang 	IMC_UNCORE_DEV(RKL_2),
11236e394376SKan Liang 	{ /* end: all zeroes */ },
11246e394376SKan Liang };
11256e394376SKan Liang 
112692553e40SBorislav Petkov static struct pci_driver snb_uncore_pci_driver = {
112792553e40SBorislav Petkov 	.name		= "snb_uncore",
112892553e40SBorislav Petkov 	.id_table	= snb_uncore_pci_ids,
112992553e40SBorislav Petkov };
113092553e40SBorislav Petkov 
113192553e40SBorislav Petkov static struct pci_driver ivb_uncore_pci_driver = {
113292553e40SBorislav Petkov 	.name		= "ivb_uncore",
113392553e40SBorislav Petkov 	.id_table	= ivb_uncore_pci_ids,
113492553e40SBorislav Petkov };
113592553e40SBorislav Petkov 
113692553e40SBorislav Petkov static struct pci_driver hsw_uncore_pci_driver = {
113792553e40SBorislav Petkov 	.name		= "hsw_uncore",
113892553e40SBorislav Petkov 	.id_table	= hsw_uncore_pci_ids,
113992553e40SBorislav Petkov };
114092553e40SBorislav Petkov 
114192553e40SBorislav Petkov static struct pci_driver bdw_uncore_pci_driver = {
114292553e40SBorislav Petkov 	.name		= "bdw_uncore",
114392553e40SBorislav Petkov 	.id_table	= bdw_uncore_pci_ids,
114492553e40SBorislav Petkov };
114592553e40SBorislav Petkov 
114692553e40SBorislav Petkov static struct pci_driver skl_uncore_pci_driver = {
114792553e40SBorislav Petkov 	.name		= "skl_uncore",
114892553e40SBorislav Petkov 	.id_table	= skl_uncore_pci_ids,
114992553e40SBorislav Petkov };
115092553e40SBorislav Petkov 
11516e394376SKan Liang static struct pci_driver icl_uncore_pci_driver = {
11526e394376SKan Liang 	.name		= "icl_uncore",
11536e394376SKan Liang 	.id_table	= icl_uncore_pci_ids,
11546e394376SKan Liang };
11556e394376SKan Liang 
115692553e40SBorislav Petkov struct imc_uncore_pci_dev {
115792553e40SBorislav Petkov 	__u32 pci_id;
115892553e40SBorislav Petkov 	struct pci_driver *driver;
115992553e40SBorislav Petkov };
116092553e40SBorislav Petkov #define IMC_DEV(a, d) \
116192553e40SBorislav Petkov 	{ .pci_id = PCI_DEVICE_ID_INTEL_##a, .driver = (d) }
116292553e40SBorislav Petkov 
116392553e40SBorislav Petkov static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = {
116492553e40SBorislav Petkov 	IMC_DEV(SNB_IMC, &snb_uncore_pci_driver),
116592553e40SBorislav Petkov 	IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver),    /* 3rd Gen Core processor */
116692553e40SBorislav Petkov 	IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */
116792553e40SBorislav Petkov 	IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver),    /* 4th Gen Core Processor */
116892553e40SBorislav Petkov 	IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver),  /* 4th Gen Core ULT Mobile Processor */
116992553e40SBorislav Petkov 	IMC_DEV(BDW_IMC, &bdw_uncore_pci_driver),    /* 5th Gen Core U */
1170d786810bSKan Liang 	IMC_DEV(SKL_Y_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core Y */
117146866b59SKan Liang 	IMC_DEV(SKL_U_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core U */
1172d786810bSKan Liang 	IMC_DEV(SKL_HD_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core H Dual Core */
1173d786810bSKan Liang 	IMC_DEV(SKL_HQ_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core H Quad Core */
1174d786810bSKan Liang 	IMC_DEV(SKL_SD_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core S Dual Core */
1175d786810bSKan Liang 	IMC_DEV(SKL_SQ_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core S Quad Core */
1176e7438304SKan Liang 	IMC_DEV(SKL_E3_IMC, &skl_uncore_pci_driver),  /* Xeon E3 V5 Gen Core processor */
1177c10a8de0SKan Liang 	IMC_DEV(KBL_Y_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core Y */
1178c10a8de0SKan Liang 	IMC_DEV(KBL_U_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core U */
1179c10a8de0SKan Liang 	IMC_DEV(KBL_UQ_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core U Quad Core */
1180c10a8de0SKan Liang 	IMC_DEV(KBL_SD_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core S Dual Core */
1181c10a8de0SKan Liang 	IMC_DEV(KBL_SQ_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core S Quad Core */
11826e86d3dbSGayatri Kammela 	IMC_DEV(KBL_HQ_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core H Quad Core */
11836e86d3dbSGayatri Kammela 	IMC_DEV(KBL_WQ_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core S 4 cores Work Station */
1184c10a8de0SKan Liang 	IMC_DEV(CFL_2U_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core U 2 Cores */
1185c10a8de0SKan Liang 	IMC_DEV(CFL_4U_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core U 4 Cores */
1186c10a8de0SKan Liang 	IMC_DEV(CFL_4H_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core H 4 Cores */
1187c10a8de0SKan Liang 	IMC_DEV(CFL_6H_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core H 6 Cores */
1188c10a8de0SKan Liang 	IMC_DEV(CFL_2S_D_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 2 Cores Desktop */
1189c10a8de0SKan Liang 	IMC_DEV(CFL_4S_D_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 4 Cores Desktop */
1190c10a8de0SKan Liang 	IMC_DEV(CFL_6S_D_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 6 Cores Desktop */
1191c10a8de0SKan Liang 	IMC_DEV(CFL_8S_D_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 8 Cores Desktop */
1192c10a8de0SKan Liang 	IMC_DEV(CFL_4S_W_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 4 Cores Work Station */
1193c10a8de0SKan Liang 	IMC_DEV(CFL_6S_W_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 6 Cores Work Station */
1194c10a8de0SKan Liang 	IMC_DEV(CFL_8S_W_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 8 Cores Work Station */
1195c10a8de0SKan Liang 	IMC_DEV(CFL_4S_S_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 4 Cores Server */
1196c10a8de0SKan Liang 	IMC_DEV(CFL_6S_S_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 6 Cores Server */
1197c10a8de0SKan Liang 	IMC_DEV(CFL_8S_S_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 8 Cores Server */
11986e86d3dbSGayatri Kammela 	IMC_DEV(AML_YD_IMC, &skl_uncore_pci_driver),	/* 8th Gen Core Y Mobile Dual Core */
11996e86d3dbSGayatri Kammela 	IMC_DEV(AML_YQ_IMC, &skl_uncore_pci_driver),	/* 8th Gen Core Y Mobile Quad Core */
12006e86d3dbSGayatri Kammela 	IMC_DEV(WHL_UQ_IMC, &skl_uncore_pci_driver),	/* 8th Gen Core U Mobile Quad Core */
12016e86d3dbSGayatri Kammela 	IMC_DEV(WHL_4_UQ_IMC, &skl_uncore_pci_driver),	/* 8th Gen Core U Mobile Quad Core */
12026e86d3dbSGayatri Kammela 	IMC_DEV(WHL_UD_IMC, &skl_uncore_pci_driver),	/* 8th Gen Core U Mobile Dual Core */
1203bb85429aSKan Liang 	IMC_DEV(CML_H1_IMC, &skl_uncore_pci_driver),
1204bb85429aSKan Liang 	IMC_DEV(CML_H2_IMC, &skl_uncore_pci_driver),
1205bb85429aSKan Liang 	IMC_DEV(CML_H3_IMC, &skl_uncore_pci_driver),
1206bb85429aSKan Liang 	IMC_DEV(CML_U1_IMC, &skl_uncore_pci_driver),
1207bb85429aSKan Liang 	IMC_DEV(CML_U2_IMC, &skl_uncore_pci_driver),
1208bb85429aSKan Liang 	IMC_DEV(CML_U3_IMC, &skl_uncore_pci_driver),
1209bb85429aSKan Liang 	IMC_DEV(CML_S1_IMC, &skl_uncore_pci_driver),
1210bb85429aSKan Liang 	IMC_DEV(CML_S2_IMC, &skl_uncore_pci_driver),
1211bb85429aSKan Liang 	IMC_DEV(CML_S3_IMC, &skl_uncore_pci_driver),
1212bb85429aSKan Liang 	IMC_DEV(CML_S4_IMC, &skl_uncore_pci_driver),
1213bb85429aSKan Liang 	IMC_DEV(CML_S5_IMC, &skl_uncore_pci_driver),
12146e394376SKan Liang 	IMC_DEV(ICL_U_IMC, &icl_uncore_pci_driver),	/* 10th Gen Core Mobile */
12156e394376SKan Liang 	IMC_DEV(ICL_U2_IMC, &icl_uncore_pci_driver),	/* 10th Gen Core Mobile */
121643bc103aSKan Liang 	IMC_DEV(RKL_1_IMC, &icl_uncore_pci_driver),
121743bc103aSKan Liang 	IMC_DEV(RKL_2_IMC, &icl_uncore_pci_driver),
121892553e40SBorislav Petkov 	{  /* end marker */ }
121992553e40SBorislav Petkov };
122092553e40SBorislav Petkov 
122192553e40SBorislav Petkov 
122292553e40SBorislav Petkov #define for_each_imc_pci_id(x, t) \
122392553e40SBorislav Petkov 	for (x = (t); (x)->pci_id; x++)
122492553e40SBorislav Petkov 
imc_uncore_find_dev(void)122592553e40SBorislav Petkov static struct pci_driver *imc_uncore_find_dev(void)
122692553e40SBorislav Petkov {
122792553e40SBorislav Petkov 	const struct imc_uncore_pci_dev *p;
122892553e40SBorislav Petkov 	int ret;
122992553e40SBorislav Petkov 
123092553e40SBorislav Petkov 	for_each_imc_pci_id(p, desktop_imc_pci_ids) {
123192553e40SBorislav Petkov 		ret = snb_pci2phy_map_init(p->pci_id);
123292553e40SBorislav Petkov 		if (ret == 0)
123392553e40SBorislav Petkov 			return p->driver;
123492553e40SBorislav Petkov 	}
123592553e40SBorislav Petkov 	return NULL;
123692553e40SBorislav Petkov }
123792553e40SBorislav Petkov 
imc_uncore_pci_init(void)123892553e40SBorislav Petkov static int imc_uncore_pci_init(void)
123992553e40SBorislav Petkov {
124092553e40SBorislav Petkov 	struct pci_driver *imc_drv = imc_uncore_find_dev();
124192553e40SBorislav Petkov 
124292553e40SBorislav Petkov 	if (!imc_drv)
124392553e40SBorislav Petkov 		return -ENODEV;
124492553e40SBorislav Petkov 
124592553e40SBorislav Petkov 	uncore_pci_uncores = snb_pci_uncores;
124692553e40SBorislav Petkov 	uncore_pci_driver = imc_drv;
124792553e40SBorislav Petkov 
124892553e40SBorislav Petkov 	return 0;
124992553e40SBorislav Petkov }
125092553e40SBorislav Petkov 
snb_uncore_pci_init(void)125192553e40SBorislav Petkov int snb_uncore_pci_init(void)
125292553e40SBorislav Petkov {
125392553e40SBorislav Petkov 	return imc_uncore_pci_init();
125492553e40SBorislav Petkov }
125592553e40SBorislav Petkov 
ivb_uncore_pci_init(void)125692553e40SBorislav Petkov int ivb_uncore_pci_init(void)
125792553e40SBorislav Petkov {
125892553e40SBorislav Petkov 	return imc_uncore_pci_init();
125992553e40SBorislav Petkov }
hsw_uncore_pci_init(void)126092553e40SBorislav Petkov int hsw_uncore_pci_init(void)
126192553e40SBorislav Petkov {
126292553e40SBorislav Petkov 	return imc_uncore_pci_init();
126392553e40SBorislav Petkov }
126492553e40SBorislav Petkov 
bdw_uncore_pci_init(void)126592553e40SBorislav Petkov int bdw_uncore_pci_init(void)
126692553e40SBorislav Petkov {
126792553e40SBorislav Petkov 	return imc_uncore_pci_init();
126892553e40SBorislav Petkov }
126992553e40SBorislav Petkov 
skl_uncore_pci_init(void)127092553e40SBorislav Petkov int skl_uncore_pci_init(void)
127192553e40SBorislav Petkov {
127292553e40SBorislav Petkov 	return imc_uncore_pci_init();
127392553e40SBorislav Petkov }
127492553e40SBorislav Petkov 
127592553e40SBorislav Petkov /* end of Sandy Bridge uncore support */
127692553e40SBorislav Petkov 
127792553e40SBorislav Petkov /* Nehalem uncore support */
nhm_uncore_msr_disable_box(struct intel_uncore_box * box)127892553e40SBorislav Petkov static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box)
127992553e40SBorislav Petkov {
128092553e40SBorislav Petkov 	wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0);
128192553e40SBorislav Petkov }
128292553e40SBorislav Petkov 
nhm_uncore_msr_enable_box(struct intel_uncore_box * box)128392553e40SBorislav Petkov static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box)
128492553e40SBorislav Petkov {
128592553e40SBorislav Petkov 	wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC);
128692553e40SBorislav Petkov }
128792553e40SBorislav Petkov 
nhm_uncore_msr_enable_event(struct intel_uncore_box * box,struct perf_event * event)128892553e40SBorislav Petkov static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
128992553e40SBorislav Petkov {
129092553e40SBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
129192553e40SBorislav Petkov 
129292553e40SBorislav Petkov 	if (hwc->idx < UNCORE_PMC_IDX_FIXED)
129392553e40SBorislav Petkov 		wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
129492553e40SBorislav Petkov 	else
129592553e40SBorislav Petkov 		wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN);
129692553e40SBorislav Petkov }
129792553e40SBorislav Petkov 
129892553e40SBorislav Petkov static struct attribute *nhm_uncore_formats_attr[] = {
129992553e40SBorislav Petkov 	&format_attr_event.attr,
130092553e40SBorislav Petkov 	&format_attr_umask.attr,
130192553e40SBorislav Petkov 	&format_attr_edge.attr,
130292553e40SBorislav Petkov 	&format_attr_inv.attr,
130392553e40SBorislav Petkov 	&format_attr_cmask8.attr,
130492553e40SBorislav Petkov 	NULL,
130592553e40SBorislav Petkov };
130692553e40SBorislav Petkov 
130745bd07adSArvind Yadav static const struct attribute_group nhm_uncore_format_group = {
130892553e40SBorislav Petkov 	.name = "format",
130992553e40SBorislav Petkov 	.attrs = nhm_uncore_formats_attr,
131092553e40SBorislav Petkov };
131192553e40SBorislav Petkov 
131292553e40SBorislav Petkov static struct uncore_event_desc nhm_uncore_events[] = {
131392553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(clockticks,                "event=0xff,umask=0x00"),
131492553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any,       "event=0x2f,umask=0x0f"),
131592553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any,      "event=0x2c,umask=0x0f"),
131692553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads,     "event=0x20,umask=0x01"),
131792553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes,    "event=0x20,umask=0x02"),
131892553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads,  "event=0x20,umask=0x04"),
131992553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"),
132092553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads,   "event=0x20,umask=0x10"),
132192553e40SBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes,  "event=0x20,umask=0x20"),
132292553e40SBorislav Petkov 	{ /* end: all zeroes */ },
132392553e40SBorislav Petkov };
132492553e40SBorislav Petkov 
132592553e40SBorislav Petkov static struct intel_uncore_ops nhm_uncore_msr_ops = {
132692553e40SBorislav Petkov 	.disable_box	= nhm_uncore_msr_disable_box,
132792553e40SBorislav Petkov 	.enable_box	= nhm_uncore_msr_enable_box,
132892553e40SBorislav Petkov 	.disable_event	= snb_uncore_msr_disable_event,
132992553e40SBorislav Petkov 	.enable_event	= nhm_uncore_msr_enable_event,
133092553e40SBorislav Petkov 	.read_counter	= uncore_msr_read_counter,
133192553e40SBorislav Petkov };
133292553e40SBorislav Petkov 
133392553e40SBorislav Petkov static struct intel_uncore_type nhm_uncore = {
133492553e40SBorislav Petkov 	.name		= "",
133592553e40SBorislav Petkov 	.num_counters   = 8,
133692553e40SBorislav Petkov 	.num_boxes	= 1,
133792553e40SBorislav Petkov 	.perf_ctr_bits	= 48,
133892553e40SBorislav Petkov 	.fixed_ctr_bits	= 48,
133992553e40SBorislav Petkov 	.event_ctl	= NHM_UNC_PERFEVTSEL0,
134092553e40SBorislav Petkov 	.perf_ctr	= NHM_UNC_UNCORE_PMC0,
134192553e40SBorislav Petkov 	.fixed_ctr	= NHM_UNC_FIXED_CTR,
134292553e40SBorislav Petkov 	.fixed_ctl	= NHM_UNC_FIXED_CTR_CTRL,
134392553e40SBorislav Petkov 	.event_mask	= NHM_UNC_RAW_EVENT_MASK,
134492553e40SBorislav Petkov 	.event_descs	= nhm_uncore_events,
134592553e40SBorislav Petkov 	.ops		= &nhm_uncore_msr_ops,
134692553e40SBorislav Petkov 	.format_group	= &nhm_uncore_format_group,
134792553e40SBorislav Petkov };
134892553e40SBorislav Petkov 
134992553e40SBorislav Petkov static struct intel_uncore_type *nhm_msr_uncores[] = {
135092553e40SBorislav Petkov 	&nhm_uncore,
135192553e40SBorislav Petkov 	NULL,
135292553e40SBorislav Petkov };
135392553e40SBorislav Petkov 
nhm_uncore_cpu_init(void)135492553e40SBorislav Petkov void nhm_uncore_cpu_init(void)
135592553e40SBorislav Petkov {
135692553e40SBorislav Petkov 	uncore_msr_uncores = nhm_msr_uncores;
135792553e40SBorislav Petkov }
135892553e40SBorislav Petkov 
135992553e40SBorislav Petkov /* end of Nehalem uncore support */
1360fdb64822SKan Liang 
1361fdb64822SKan Liang /* Tiger Lake MMIO uncore support */
1362fdb64822SKan Liang 
1363fdb64822SKan Liang static const struct pci_device_id tgl_uncore_pci_ids[] = {
1364e5ae168eSKan Liang 	IMC_UNCORE_DEV(TGL_U1),
1365e5ae168eSKan Liang 	IMC_UNCORE_DEV(TGL_U2),
1366e5ae168eSKan Liang 	IMC_UNCORE_DEV(TGL_U3),
1367e5ae168eSKan Liang 	IMC_UNCORE_DEV(TGL_U4),
1368e5ae168eSKan Liang 	IMC_UNCORE_DEV(TGL_H),
1369e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_1),
1370e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_2),
1371e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_3),
1372e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_4),
1373e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_5),
1374e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_6),
1375e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_7),
1376e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_8),
1377e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_9),
1378e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_10),
1379e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_11),
1380e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_12),
1381e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_13),
1382e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_14),
1383e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_15),
1384e5ae168eSKan Liang 	IMC_UNCORE_DEV(ADL_16),
1385f758bc5aSKan Liang 	IMC_UNCORE_DEV(ADL_17),
1386f758bc5aSKan Liang 	IMC_UNCORE_DEV(ADL_18),
1387f758bc5aSKan Liang 	IMC_UNCORE_DEV(ADL_19),
1388f758bc5aSKan Liang 	IMC_UNCORE_DEV(ADL_20),
1389f758bc5aSKan Liang 	IMC_UNCORE_DEV(ADL_21),
1390e5ae168eSKan Liang 	IMC_UNCORE_DEV(RPL_1),
1391e5ae168eSKan Liang 	IMC_UNCORE_DEV(RPL_2),
1392e5ae168eSKan Liang 	IMC_UNCORE_DEV(RPL_3),
1393e5ae168eSKan Liang 	IMC_UNCORE_DEV(RPL_4),
1394f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_5),
1395f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_6),
1396f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_7),
1397f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_8),
1398f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_9),
1399f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_10),
1400f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_11),
1401f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_12),
1402f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_13),
1403f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_14),
1404f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_15),
1405f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_16),
1406f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_17),
1407f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_18),
1408f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_19),
1409f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_20),
1410f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_21),
1411f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_22),
1412f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_23),
1413f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_24),
1414f758bc5aSKan Liang 	IMC_UNCORE_DEV(RPL_25),
1415*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_1),
1416*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_2),
1417*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_3),
1418*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_4),
1419*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_5),
1420*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_6),
1421*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_7),
1422*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_8),
1423*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_9),
1424*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_10),
1425*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_11),
1426*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_12),
1427*c828441fSKan Liang 	IMC_UNCORE_DEV(MTL_13),
1428fdb64822SKan Liang 	{ /* end: all zeroes */ }
1429fdb64822SKan Liang };
1430fdb64822SKan Liang 
1431fdb64822SKan Liang enum perf_tgl_uncore_imc_freerunning_types {
1432fdb64822SKan Liang 	TGL_MMIO_UNCORE_IMC_DATA_TOTAL,
1433fdb64822SKan Liang 	TGL_MMIO_UNCORE_IMC_DATA_READ,
1434fdb64822SKan Liang 	TGL_MMIO_UNCORE_IMC_DATA_WRITE,
1435fdb64822SKan Liang 	TGL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX
1436fdb64822SKan Liang };
1437fdb64822SKan Liang 
1438fdb64822SKan Liang static struct freerunning_counters tgl_l_uncore_imc_freerunning[] = {
1439fdb64822SKan Liang 	[TGL_MMIO_UNCORE_IMC_DATA_TOTAL]	= { 0x5040, 0x0, 0x0, 1, 64 },
1440fdb64822SKan Liang 	[TGL_MMIO_UNCORE_IMC_DATA_READ]		= { 0x5058, 0x0, 0x0, 1, 64 },
1441fdb64822SKan Liang 	[TGL_MMIO_UNCORE_IMC_DATA_WRITE]	= { 0x50A0, 0x0, 0x0, 1, 64 },
1442fdb64822SKan Liang };
1443fdb64822SKan Liang 
1444fdb64822SKan Liang static struct freerunning_counters tgl_uncore_imc_freerunning[] = {
1445fdb64822SKan Liang 	[TGL_MMIO_UNCORE_IMC_DATA_TOTAL]	= { 0xd840, 0x0, 0x0, 1, 64 },
1446fdb64822SKan Liang 	[TGL_MMIO_UNCORE_IMC_DATA_READ]		= { 0xd858, 0x0, 0x0, 1, 64 },
1447fdb64822SKan Liang 	[TGL_MMIO_UNCORE_IMC_DATA_WRITE]	= { 0xd8A0, 0x0, 0x0, 1, 64 },
1448fdb64822SKan Liang };
1449fdb64822SKan Liang 
1450fdb64822SKan Liang static struct uncore_event_desc tgl_uncore_imc_events[] = {
1451fdb64822SKan Liang 	INTEL_UNCORE_EVENT_DESC(data_total,         "event=0xff,umask=0x10"),
1452fdb64822SKan Liang 	INTEL_UNCORE_EVENT_DESC(data_total.scale,   "6.103515625e-5"),
1453fdb64822SKan Liang 	INTEL_UNCORE_EVENT_DESC(data_total.unit,    "MiB"),
1454fdb64822SKan Liang 
1455fdb64822SKan Liang 	INTEL_UNCORE_EVENT_DESC(data_read,         "event=0xff,umask=0x20"),
1456fdb64822SKan Liang 	INTEL_UNCORE_EVENT_DESC(data_read.scale,   "6.103515625e-5"),
1457fdb64822SKan Liang 	INTEL_UNCORE_EVENT_DESC(data_read.unit,    "MiB"),
1458fdb64822SKan Liang 
1459fdb64822SKan Liang 	INTEL_UNCORE_EVENT_DESC(data_write,        "event=0xff,umask=0x30"),
1460fdb64822SKan Liang 	INTEL_UNCORE_EVENT_DESC(data_write.scale,  "6.103515625e-5"),
1461fdb64822SKan Liang 	INTEL_UNCORE_EVENT_DESC(data_write.unit,   "MiB"),
1462fdb64822SKan Liang 
1463fdb64822SKan Liang 	{ /* end: all zeroes */ }
1464fdb64822SKan Liang };
1465fdb64822SKan Liang 
tgl_uncore_get_mc_dev(void)1466fdb64822SKan Liang static struct pci_dev *tgl_uncore_get_mc_dev(void)
1467fdb64822SKan Liang {
1468fdb64822SKan Liang 	const struct pci_device_id *ids = tgl_uncore_pci_ids;
1469fdb64822SKan Liang 	struct pci_dev *mc_dev = NULL;
1470fdb64822SKan Liang 
1471fdb64822SKan Liang 	while (ids && ids->vendor) {
1472fdb64822SKan Liang 		mc_dev = pci_get_device(PCI_VENDOR_ID_INTEL, ids->device, NULL);
1473fdb64822SKan Liang 		if (mc_dev)
1474fdb64822SKan Liang 			return mc_dev;
1475fdb64822SKan Liang 		ids++;
1476fdb64822SKan Liang 	}
1477fdb64822SKan Liang 
1478fdb64822SKan Liang 	return mc_dev;
1479fdb64822SKan Liang }
1480fdb64822SKan Liang 
1481fdb64822SKan Liang #define TGL_UNCORE_MMIO_IMC_MEM_OFFSET		0x10000
14822af834f1SKan Liang #define TGL_UNCORE_PCI_IMC_MAP_SIZE		0xe000
1483fdb64822SKan Liang 
__uncore_imc_init_box(struct intel_uncore_box * box,unsigned int base_offset)14845a4487f9SKan Liang static void __uncore_imc_init_box(struct intel_uncore_box *box,
14855a4487f9SKan Liang 				  unsigned int base_offset)
1486fdb64822SKan Liang {
1487fdb64822SKan Liang 	struct pci_dev *pdev = tgl_uncore_get_mc_dev();
1488fdb64822SKan Liang 	struct intel_uncore_pmu *pmu = box->pmu;
14891b94d31dSKan Liang 	struct intel_uncore_type *type = pmu->type;
1490fdb64822SKan Liang 	resource_size_t addr;
1491fdb64822SKan Liang 	u32 mch_bar;
1492fdb64822SKan Liang 
1493fdb64822SKan Liang 	if (!pdev) {
1494fdb64822SKan Liang 		pr_warn("perf uncore: Cannot find matched IMC device.\n");
1495fdb64822SKan Liang 		return;
1496fdb64822SKan Liang 	}
1497fdb64822SKan Liang 
1498fdb64822SKan Liang 	pci_read_config_dword(pdev, SNB_UNCORE_PCI_IMC_BAR_OFFSET, &mch_bar);
1499fdb64822SKan Liang 	/* MCHBAR is disabled */
1500fdb64822SKan Liang 	if (!(mch_bar & BIT(0))) {
1501fdb64822SKan Liang 		pr_warn("perf uncore: MCHBAR is disabled. Failed to map IMC free-running counters.\n");
150217b8d847SXiongfeng Wang 		pci_dev_put(pdev);
1503fdb64822SKan Liang 		return;
1504fdb64822SKan Liang 	}
1505fdb64822SKan Liang 	mch_bar &= ~BIT(0);
1506fdb64822SKan Liang 	addr = (resource_size_t)(mch_bar + TGL_UNCORE_MMIO_IMC_MEM_OFFSET * pmu->pmu_idx);
1507fdb64822SKan Liang 
1508fdb64822SKan Liang #ifdef CONFIG_PHYS_ADDR_T_64BIT
1509fdb64822SKan Liang 	pci_read_config_dword(pdev, SNB_UNCORE_PCI_IMC_BAR_OFFSET + 4, &mch_bar);
1510fdb64822SKan Liang 	addr |= ((resource_size_t)mch_bar << 32);
1511fdb64822SKan Liang #endif
1512fdb64822SKan Liang 
15135a4487f9SKan Liang 	addr += base_offset;
15141b94d31dSKan Liang 	box->io_addr = ioremap(addr, type->mmio_map_size);
15151b94d31dSKan Liang 	if (!box->io_addr)
15161b94d31dSKan Liang 		pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
151717b8d847SXiongfeng Wang 
151817b8d847SXiongfeng Wang 	pci_dev_put(pdev);
1519fdb64822SKan Liang }
1520fdb64822SKan Liang 
tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box * box)15215a4487f9SKan Liang static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
15225a4487f9SKan Liang {
15235a4487f9SKan Liang 	__uncore_imc_init_box(box, 0);
15245a4487f9SKan Liang }
15255a4487f9SKan Liang 
1526fdb64822SKan Liang static struct intel_uncore_ops tgl_uncore_imc_freerunning_ops = {
1527fdb64822SKan Liang 	.init_box	= tgl_uncore_imc_freerunning_init_box,
1528fdb64822SKan Liang 	.exit_box	= uncore_mmio_exit_box,
1529fdb64822SKan Liang 	.read_counter	= uncore_mmio_read_counter,
1530fdb64822SKan Liang 	.hw_config	= uncore_freerunning_hw_config,
1531fdb64822SKan Liang };
1532fdb64822SKan Liang 
1533fdb64822SKan Liang static struct attribute *tgl_uncore_imc_formats_attr[] = {
1534fdb64822SKan Liang 	&format_attr_event.attr,
1535fdb64822SKan Liang 	&format_attr_umask.attr,
1536fdb64822SKan Liang 	NULL
1537fdb64822SKan Liang };
1538fdb64822SKan Liang 
1539fdb64822SKan Liang static const struct attribute_group tgl_uncore_imc_format_group = {
1540fdb64822SKan Liang 	.name = "format",
1541fdb64822SKan Liang 	.attrs = tgl_uncore_imc_formats_attr,
1542fdb64822SKan Liang };
1543fdb64822SKan Liang 
1544fdb64822SKan Liang static struct intel_uncore_type tgl_uncore_imc_free_running = {
1545fdb64822SKan Liang 	.name			= "imc_free_running",
1546fdb64822SKan Liang 	.num_counters		= 3,
1547fdb64822SKan Liang 	.num_boxes		= 2,
1548fdb64822SKan Liang 	.num_freerunning_types	= TGL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX,
15491b94d31dSKan Liang 	.mmio_map_size		= TGL_UNCORE_PCI_IMC_MAP_SIZE,
1550fdb64822SKan Liang 	.freerunning		= tgl_uncore_imc_freerunning,
1551fdb64822SKan Liang 	.ops			= &tgl_uncore_imc_freerunning_ops,
1552fdb64822SKan Liang 	.event_descs		= tgl_uncore_imc_events,
1553fdb64822SKan Liang 	.format_group		= &tgl_uncore_imc_format_group,
1554fdb64822SKan Liang };
1555fdb64822SKan Liang 
1556fdb64822SKan Liang static struct intel_uncore_type *tgl_mmio_uncores[] = {
1557fdb64822SKan Liang 	&tgl_uncore_imc_free_running,
1558fdb64822SKan Liang 	NULL
1559fdb64822SKan Liang };
1560fdb64822SKan Liang 
tgl_l_uncore_mmio_init(void)1561fdb64822SKan Liang void tgl_l_uncore_mmio_init(void)
1562fdb64822SKan Liang {
1563fdb64822SKan Liang 	tgl_uncore_imc_free_running.freerunning = tgl_l_uncore_imc_freerunning;
1564fdb64822SKan Liang 	uncore_mmio_uncores = tgl_mmio_uncores;
1565fdb64822SKan Liang }
1566fdb64822SKan Liang 
tgl_uncore_mmio_init(void)1567fdb64822SKan Liang void tgl_uncore_mmio_init(void)
1568fdb64822SKan Liang {
1569fdb64822SKan Liang 	uncore_mmio_uncores = tgl_mmio_uncores;
1570fdb64822SKan Liang }
1571fdb64822SKan Liang 
1572fdb64822SKan Liang /* end of Tiger Lake MMIO uncore support */
15735a4487f9SKan Liang 
15745a4487f9SKan Liang /* Alder Lake MMIO uncore support */
15755a4487f9SKan Liang #define ADL_UNCORE_IMC_BASE			0xd900
15765a4487f9SKan Liang #define ADL_UNCORE_IMC_MAP_SIZE			0x200
15775a4487f9SKan Liang #define ADL_UNCORE_IMC_CTR			0xe8
15785a4487f9SKan Liang #define ADL_UNCORE_IMC_CTRL			0xd0
15795a4487f9SKan Liang #define ADL_UNCORE_IMC_GLOBAL_CTL		0xc0
15805a4487f9SKan Liang #define ADL_UNCORE_IMC_BOX_CTL			0xc4
15815a4487f9SKan Liang #define ADL_UNCORE_IMC_FREERUNNING_BASE		0xd800
15825a4487f9SKan Liang #define ADL_UNCORE_IMC_FREERUNNING_MAP_SIZE	0x100
15835a4487f9SKan Liang 
15845a4487f9SKan Liang #define ADL_UNCORE_IMC_CTL_FRZ			(1 << 0)
15855a4487f9SKan Liang #define ADL_UNCORE_IMC_CTL_RST_CTRL		(1 << 1)
15865a4487f9SKan Liang #define ADL_UNCORE_IMC_CTL_RST_CTRS		(1 << 2)
15875a4487f9SKan Liang #define ADL_UNCORE_IMC_CTL_INT			(ADL_UNCORE_IMC_CTL_RST_CTRL | \
15885a4487f9SKan Liang 						ADL_UNCORE_IMC_CTL_RST_CTRS)
15895a4487f9SKan Liang 
adl_uncore_imc_init_box(struct intel_uncore_box * box)15905a4487f9SKan Liang static void adl_uncore_imc_init_box(struct intel_uncore_box *box)
15915a4487f9SKan Liang {
15925a4487f9SKan Liang 	__uncore_imc_init_box(box, ADL_UNCORE_IMC_BASE);
15935a4487f9SKan Liang 
15945a4487f9SKan Liang 	/* The global control in MC1 can control both MCs. */
15955a4487f9SKan Liang 	if (box->io_addr && (box->pmu->pmu_idx == 1))
15965a4487f9SKan Liang 		writel(ADL_UNCORE_IMC_CTL_INT, box->io_addr + ADL_UNCORE_IMC_GLOBAL_CTL);
15975a4487f9SKan Liang }
15985a4487f9SKan Liang 
adl_uncore_mmio_disable_box(struct intel_uncore_box * box)15995a4487f9SKan Liang static void adl_uncore_mmio_disable_box(struct intel_uncore_box *box)
16005a4487f9SKan Liang {
16015a4487f9SKan Liang 	if (!box->io_addr)
16025a4487f9SKan Liang 		return;
16035a4487f9SKan Liang 
16045a4487f9SKan Liang 	writel(ADL_UNCORE_IMC_CTL_FRZ, box->io_addr + uncore_mmio_box_ctl(box));
16055a4487f9SKan Liang }
16065a4487f9SKan Liang 
adl_uncore_mmio_enable_box(struct intel_uncore_box * box)16075a4487f9SKan Liang static void adl_uncore_mmio_enable_box(struct intel_uncore_box *box)
16085a4487f9SKan Liang {
16095a4487f9SKan Liang 	if (!box->io_addr)
16105a4487f9SKan Liang 		return;
16115a4487f9SKan Liang 
16125a4487f9SKan Liang 	writel(0, box->io_addr + uncore_mmio_box_ctl(box));
16135a4487f9SKan Liang }
16145a4487f9SKan Liang 
16155a4487f9SKan Liang static struct intel_uncore_ops adl_uncore_mmio_ops = {
16165a4487f9SKan Liang 	.init_box	= adl_uncore_imc_init_box,
16175a4487f9SKan Liang 	.exit_box	= uncore_mmio_exit_box,
16185a4487f9SKan Liang 	.disable_box	= adl_uncore_mmio_disable_box,
16195a4487f9SKan Liang 	.enable_box	= adl_uncore_mmio_enable_box,
16205a4487f9SKan Liang 	.disable_event	= intel_generic_uncore_mmio_disable_event,
16215a4487f9SKan Liang 	.enable_event	= intel_generic_uncore_mmio_enable_event,
16225a4487f9SKan Liang 	.read_counter	= uncore_mmio_read_counter,
16235a4487f9SKan Liang };
16245a4487f9SKan Liang 
16255a4487f9SKan Liang #define ADL_UNC_CTL_CHMASK_MASK			0x00000f00
16265a4487f9SKan Liang #define ADL_UNC_IMC_EVENT_MASK			(SNB_UNC_CTL_EV_SEL_MASK | \
16275a4487f9SKan Liang 						 ADL_UNC_CTL_CHMASK_MASK | \
16285a4487f9SKan Liang 						 SNB_UNC_CTL_EDGE_DET)
16295a4487f9SKan Liang 
16305a4487f9SKan Liang static struct attribute *adl_uncore_imc_formats_attr[] = {
16315a4487f9SKan Liang 	&format_attr_event.attr,
16325a4487f9SKan Liang 	&format_attr_chmask.attr,
16335a4487f9SKan Liang 	&format_attr_edge.attr,
16345a4487f9SKan Liang 	NULL,
16355a4487f9SKan Liang };
16365a4487f9SKan Liang 
16375a4487f9SKan Liang static const struct attribute_group adl_uncore_imc_format_group = {
16385a4487f9SKan Liang 	.name		= "format",
16395a4487f9SKan Liang 	.attrs		= adl_uncore_imc_formats_attr,
16405a4487f9SKan Liang };
16415a4487f9SKan Liang 
16425a4487f9SKan Liang static struct intel_uncore_type adl_uncore_imc = {
16435a4487f9SKan Liang 	.name		= "imc",
16445a4487f9SKan Liang 	.num_counters   = 5,
16455a4487f9SKan Liang 	.num_boxes	= 2,
16465a4487f9SKan Liang 	.perf_ctr_bits	= 64,
16475a4487f9SKan Liang 	.perf_ctr	= ADL_UNCORE_IMC_CTR,
16485a4487f9SKan Liang 	.event_ctl	= ADL_UNCORE_IMC_CTRL,
16495a4487f9SKan Liang 	.event_mask	= ADL_UNC_IMC_EVENT_MASK,
16505a4487f9SKan Liang 	.box_ctl	= ADL_UNCORE_IMC_BOX_CTL,
16515a4487f9SKan Liang 	.mmio_offset	= 0,
16525a4487f9SKan Liang 	.mmio_map_size	= ADL_UNCORE_IMC_MAP_SIZE,
16535a4487f9SKan Liang 	.ops		= &adl_uncore_mmio_ops,
16545a4487f9SKan Liang 	.format_group	= &adl_uncore_imc_format_group,
16555a4487f9SKan Liang };
16565a4487f9SKan Liang 
16575a4487f9SKan Liang enum perf_adl_uncore_imc_freerunning_types {
16585a4487f9SKan Liang 	ADL_MMIO_UNCORE_IMC_DATA_TOTAL,
16595a4487f9SKan Liang 	ADL_MMIO_UNCORE_IMC_DATA_READ,
16605a4487f9SKan Liang 	ADL_MMIO_UNCORE_IMC_DATA_WRITE,
16615a4487f9SKan Liang 	ADL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX
16625a4487f9SKan Liang };
16635a4487f9SKan Liang 
16645a4487f9SKan Liang static struct freerunning_counters adl_uncore_imc_freerunning[] = {
16655a4487f9SKan Liang 	[ADL_MMIO_UNCORE_IMC_DATA_TOTAL]	= { 0x40, 0x0, 0x0, 1, 64 },
16665a4487f9SKan Liang 	[ADL_MMIO_UNCORE_IMC_DATA_READ]		= { 0x58, 0x0, 0x0, 1, 64 },
16675a4487f9SKan Liang 	[ADL_MMIO_UNCORE_IMC_DATA_WRITE]	= { 0xA0, 0x0, 0x0, 1, 64 },
16685a4487f9SKan Liang };
16695a4487f9SKan Liang 
adl_uncore_imc_freerunning_init_box(struct intel_uncore_box * box)16705a4487f9SKan Liang static void adl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
16715a4487f9SKan Liang {
16725a4487f9SKan Liang 	__uncore_imc_init_box(box, ADL_UNCORE_IMC_FREERUNNING_BASE);
16735a4487f9SKan Liang }
16745a4487f9SKan Liang 
16755a4487f9SKan Liang static struct intel_uncore_ops adl_uncore_imc_freerunning_ops = {
16765a4487f9SKan Liang 	.init_box	= adl_uncore_imc_freerunning_init_box,
16775a4487f9SKan Liang 	.exit_box	= uncore_mmio_exit_box,
16785a4487f9SKan Liang 	.read_counter	= uncore_mmio_read_counter,
16795a4487f9SKan Liang 	.hw_config	= uncore_freerunning_hw_config,
16805a4487f9SKan Liang };
16815a4487f9SKan Liang 
16825a4487f9SKan Liang static struct intel_uncore_type adl_uncore_imc_free_running = {
16835a4487f9SKan Liang 	.name			= "imc_free_running",
16845a4487f9SKan Liang 	.num_counters		= 3,
16855a4487f9SKan Liang 	.num_boxes		= 2,
16865a4487f9SKan Liang 	.num_freerunning_types	= ADL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX,
16875a4487f9SKan Liang 	.mmio_map_size		= ADL_UNCORE_IMC_FREERUNNING_MAP_SIZE,
16885a4487f9SKan Liang 	.freerunning		= adl_uncore_imc_freerunning,
16895a4487f9SKan Liang 	.ops			= &adl_uncore_imc_freerunning_ops,
16905a4487f9SKan Liang 	.event_descs		= tgl_uncore_imc_events,
16915a4487f9SKan Liang 	.format_group		= &tgl_uncore_imc_format_group,
16925a4487f9SKan Liang };
16935a4487f9SKan Liang 
16945a4487f9SKan Liang static struct intel_uncore_type *adl_mmio_uncores[] = {
16955a4487f9SKan Liang 	&adl_uncore_imc,
16965a4487f9SKan Liang 	&adl_uncore_imc_free_running,
16975a4487f9SKan Liang 	NULL
16985a4487f9SKan Liang };
16995a4487f9SKan Liang 
adl_uncore_mmio_init(void)17005a4487f9SKan Liang void adl_uncore_mmio_init(void)
17015a4487f9SKan Liang {
17025a4487f9SKan Liang 	uncore_mmio_uncores = adl_mmio_uncores;
17035a4487f9SKan Liang }
17045a4487f9SKan Liang 
17055a4487f9SKan Liang /* end of Alder Lake MMIO uncore support */
1706