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
112c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_1_IMC 0x7d00
113c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_2_IMC 0x7d01
114c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_3_IMC 0x7d02
115c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_4_IMC 0x7d05
116c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_5_IMC 0x7d10
117c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_6_IMC 0x7d14
118c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_7_IMC 0x7d15
119c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_8_IMC 0x7d16
120c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_9_IMC 0x7d21
121c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_10_IMC 0x7d22
122c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_11_IMC 0x7d23
123c828441fSKan Liang #define PCI_DEVICE_ID_INTEL_MTL_12_IMC 0x7d24
124c828441fSKan 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
221c828441fSKan Liang /* MTL Cbo register */
222c828441fSKan Liang #define MTL_UNC_CBO_0_PER_CTR0 0x2448
223c828441fSKan Liang #define MTL_UNC_CBO_0_PERFEVTSEL0 0x2442
224c828441fSKan Liang
225c828441fSKan Liang /* MTL HAC_ARB register */
226c828441fSKan Liang #define MTL_UNC_HAC_ARB_CTR 0x2018
227c828441fSKan Liang #define MTL_UNC_HAC_ARB_CTRL 0x2012
228c828441fSKan Liang
229c828441fSKan Liang /* MTL ARB register */
230c828441fSKan Liang #define MTL_UNC_ARB_CTR 0x2418
231c828441fSKan Liang #define MTL_UNC_ARB_CTRL 0x2412
232c828441fSKan Liang
233c828441fSKan Liang /* MTL cNCU register */
234c828441fSKan Liang #define MTL_UNC_CNCU_FIXED_CTR 0x2408
235c828441fSKan Liang #define MTL_UNC_CNCU_FIXED_CTRL 0x2402
236c828441fSKan Liang #define MTL_UNC_CNCU_BOX_CTL 0x240e
237c828441fSKan Liang
238c828441fSKan Liang /* MTL sNCU register */
239c828441fSKan Liang #define MTL_UNC_SNCU_FIXED_CTR 0x2008
240c828441fSKan Liang #define MTL_UNC_SNCU_FIXED_CTRL 0x2002
241c828441fSKan Liang #define MTL_UNC_SNCU_BOX_CTL 0x200e
242c828441fSKan Liang
243c828441fSKan Liang /* MTL HAC_CBO register */
244c828441fSKan Liang #define MTL_UNC_HBO_CTR 0x2048
245c828441fSKan Liang #define MTL_UNC_HBO_CTRL 0x2042
246c828441fSKan 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");
2559bd7dfe3SKan Liang DEFINE_UNCORE_FORMAT_ATTR(threshold2, threshold, "config:24-31");
25692553e40SBorislav Petkov
25792553e40SBorislav Petkov /* Sandy Bridge uncore support */
snb_uncore_msr_enable_event(struct intel_uncore_box * box,struct perf_event * event)25892553e40SBorislav Petkov static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
25992553e40SBorislav Petkov {
26092553e40SBorislav Petkov struct hw_perf_event *hwc = &event->hw;
26192553e40SBorislav Petkov
26292553e40SBorislav Petkov if (hwc->idx < UNCORE_PMC_IDX_FIXED)
26392553e40SBorislav Petkov wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
26492553e40SBorislav Petkov else
26592553e40SBorislav Petkov wrmsrl(hwc->config_base, SNB_UNC_CTL_EN);
26692553e40SBorislav Petkov }
26792553e40SBorislav Petkov
snb_uncore_msr_disable_event(struct intel_uncore_box * box,struct perf_event * event)26892553e40SBorislav Petkov static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
26992553e40SBorislav Petkov {
27092553e40SBorislav Petkov wrmsrl(event->hw.config_base, 0);
27192553e40SBorislav Petkov }
27292553e40SBorislav Petkov
snb_uncore_msr_init_box(struct intel_uncore_box * box)27392553e40SBorislav Petkov static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
27492553e40SBorislav Petkov {
27592553e40SBorislav Petkov if (box->pmu->pmu_idx == 0) {
27692553e40SBorislav Petkov wrmsrl(SNB_UNC_PERF_GLOBAL_CTL,
27792553e40SBorislav Petkov SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL);
27892553e40SBorislav Petkov }
27992553e40SBorislav Petkov }
28092553e40SBorislav Petkov
snb_uncore_msr_enable_box(struct intel_uncore_box * box)28195f3be79SKan Liang static void snb_uncore_msr_enable_box(struct intel_uncore_box *box)
28295f3be79SKan Liang {
28395f3be79SKan Liang wrmsrl(SNB_UNC_PERF_GLOBAL_CTL,
28495f3be79SKan Liang SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL);
28595f3be79SKan Liang }
28695f3be79SKan Liang
snb_uncore_msr_exit_box(struct intel_uncore_box * box)287a46195f1SThomas Gleixner static void snb_uncore_msr_exit_box(struct intel_uncore_box *box)
288a46195f1SThomas Gleixner {
289a46195f1SThomas Gleixner if (box->pmu->pmu_idx == 0)
290a46195f1SThomas Gleixner wrmsrl(SNB_UNC_PERF_GLOBAL_CTL, 0);
291a46195f1SThomas Gleixner }
292a46195f1SThomas Gleixner
29392553e40SBorislav Petkov static struct uncore_event_desc snb_uncore_events[] = {
29492553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
29592553e40SBorislav Petkov { /* end: all zeroes */ },
29692553e40SBorislav Petkov };
29792553e40SBorislav Petkov
29892553e40SBorislav Petkov static struct attribute *snb_uncore_formats_attr[] = {
29992553e40SBorislav Petkov &format_attr_event.attr,
30092553e40SBorislav Petkov &format_attr_umask.attr,
30192553e40SBorislav Petkov &format_attr_edge.attr,
30292553e40SBorislav Petkov &format_attr_inv.attr,
30392553e40SBorislav Petkov &format_attr_cmask5.attr,
30492553e40SBorislav Petkov NULL,
30592553e40SBorislav Petkov };
30692553e40SBorislav Petkov
30745bd07adSArvind Yadav static const struct attribute_group snb_uncore_format_group = {
30892553e40SBorislav Petkov .name = "format",
30992553e40SBorislav Petkov .attrs = snb_uncore_formats_attr,
31092553e40SBorislav Petkov };
31192553e40SBorislav Petkov
31292553e40SBorislav Petkov static struct intel_uncore_ops snb_uncore_msr_ops = {
31392553e40SBorislav Petkov .init_box = snb_uncore_msr_init_box,
31495f3be79SKan Liang .enable_box = snb_uncore_msr_enable_box,
315a46195f1SThomas Gleixner .exit_box = snb_uncore_msr_exit_box,
31692553e40SBorislav Petkov .disable_event = snb_uncore_msr_disable_event,
31792553e40SBorislav Petkov .enable_event = snb_uncore_msr_enable_event,
31892553e40SBorislav Petkov .read_counter = uncore_msr_read_counter,
31992553e40SBorislav Petkov };
32092553e40SBorislav Petkov
32192553e40SBorislav Petkov static struct event_constraint snb_uncore_arb_constraints[] = {
32292553e40SBorislav Petkov UNCORE_EVENT_CONSTRAINT(0x80, 0x1),
32392553e40SBorislav Petkov UNCORE_EVENT_CONSTRAINT(0x83, 0x1),
32492553e40SBorislav Petkov EVENT_CONSTRAINT_END
32592553e40SBorislav Petkov };
32692553e40SBorislav Petkov
32792553e40SBorislav Petkov static struct intel_uncore_type snb_uncore_cbox = {
32892553e40SBorislav Petkov .name = "cbox",
32992553e40SBorislav Petkov .num_counters = 2,
33092553e40SBorislav Petkov .num_boxes = 4,
33192553e40SBorislav Petkov .perf_ctr_bits = 44,
33292553e40SBorislav Petkov .fixed_ctr_bits = 48,
33392553e40SBorislav Petkov .perf_ctr = SNB_UNC_CBO_0_PER_CTR0,
33492553e40SBorislav Petkov .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0,
33592553e40SBorislav Petkov .fixed_ctr = SNB_UNC_FIXED_CTR,
33692553e40SBorislav Petkov .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL,
33792553e40SBorislav Petkov .single_fixed = 1,
33892553e40SBorislav Petkov .event_mask = SNB_UNC_RAW_EVENT_MASK,
33992553e40SBorislav Petkov .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
34092553e40SBorislav Petkov .ops = &snb_uncore_msr_ops,
34192553e40SBorislav Petkov .format_group = &snb_uncore_format_group,
34292553e40SBorislav Petkov .event_descs = snb_uncore_events,
34392553e40SBorislav Petkov };
34492553e40SBorislav Petkov
34592553e40SBorislav Petkov static struct intel_uncore_type snb_uncore_arb = {
34692553e40SBorislav Petkov .name = "arb",
34792553e40SBorislav Petkov .num_counters = 2,
34892553e40SBorislav Petkov .num_boxes = 1,
34992553e40SBorislav Petkov .perf_ctr_bits = 44,
35092553e40SBorislav Petkov .perf_ctr = SNB_UNC_ARB_PER_CTR0,
35192553e40SBorislav Petkov .event_ctl = SNB_UNC_ARB_PERFEVTSEL0,
35292553e40SBorislav Petkov .event_mask = SNB_UNC_RAW_EVENT_MASK,
35392553e40SBorislav Petkov .msr_offset = SNB_UNC_ARB_MSR_OFFSET,
35492553e40SBorislav Petkov .constraints = snb_uncore_arb_constraints,
35592553e40SBorislav Petkov .ops = &snb_uncore_msr_ops,
35692553e40SBorislav Petkov .format_group = &snb_uncore_format_group,
35792553e40SBorislav Petkov };
35892553e40SBorislav Petkov
35992553e40SBorislav Petkov static struct intel_uncore_type *snb_msr_uncores[] = {
36092553e40SBorislav Petkov &snb_uncore_cbox,
36192553e40SBorislav Petkov &snb_uncore_arb,
36292553e40SBorislav Petkov NULL,
36392553e40SBorislav Petkov };
36492553e40SBorislav Petkov
snb_uncore_cpu_init(void)36592553e40SBorislav Petkov void snb_uncore_cpu_init(void)
36692553e40SBorislav Petkov {
36792553e40SBorislav Petkov uncore_msr_uncores = snb_msr_uncores;
36889b0f15fSThomas Gleixner if (snb_uncore_cbox.num_boxes > topology_num_cores_per_package())
36989b0f15fSThomas Gleixner snb_uncore_cbox.num_boxes = topology_num_cores_per_package();
37092553e40SBorislav Petkov }
37192553e40SBorislav Petkov
skl_uncore_msr_init_box(struct intel_uncore_box * box)37246866b59SKan Liang static void skl_uncore_msr_init_box(struct intel_uncore_box *box)
37346866b59SKan Liang {
37446866b59SKan Liang if (box->pmu->pmu_idx == 0) {
37546866b59SKan Liang wrmsrl(SKL_UNC_PERF_GLOBAL_CTL,
37646866b59SKan Liang SNB_UNC_GLOBAL_CTL_EN | SKL_UNC_GLOBAL_CTL_CORE_ALL);
37746866b59SKan Liang }
3784d47d640SKan Liang
3794d47d640SKan Liang /* The 8th CBOX has different MSR space */
3804d47d640SKan Liang if (box->pmu->pmu_idx == 7)
3814d47d640SKan Liang __set_bit(UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS, &box->flags);
38246866b59SKan Liang }
38346866b59SKan Liang
skl_uncore_msr_enable_box(struct intel_uncore_box * box)38495f3be79SKan Liang static void skl_uncore_msr_enable_box(struct intel_uncore_box *box)
38595f3be79SKan Liang {
38695f3be79SKan Liang wrmsrl(SKL_UNC_PERF_GLOBAL_CTL,
38795f3be79SKan Liang SNB_UNC_GLOBAL_CTL_EN | SKL_UNC_GLOBAL_CTL_CORE_ALL);
38895f3be79SKan Liang }
38995f3be79SKan Liang
skl_uncore_msr_exit_box(struct intel_uncore_box * box)39046866b59SKan Liang static void skl_uncore_msr_exit_box(struct intel_uncore_box *box)
39146866b59SKan Liang {
39246866b59SKan Liang if (box->pmu->pmu_idx == 0)
39346866b59SKan Liang wrmsrl(SKL_UNC_PERF_GLOBAL_CTL, 0);
39446866b59SKan Liang }
39546866b59SKan Liang
39646866b59SKan Liang static struct intel_uncore_ops skl_uncore_msr_ops = {
39746866b59SKan Liang .init_box = skl_uncore_msr_init_box,
39895f3be79SKan Liang .enable_box = skl_uncore_msr_enable_box,
39946866b59SKan Liang .exit_box = skl_uncore_msr_exit_box,
40046866b59SKan Liang .disable_event = snb_uncore_msr_disable_event,
40146866b59SKan Liang .enable_event = snb_uncore_msr_enable_event,
40246866b59SKan Liang .read_counter = uncore_msr_read_counter,
40346866b59SKan Liang };
40446866b59SKan Liang
40546866b59SKan Liang static struct intel_uncore_type skl_uncore_cbox = {
40646866b59SKan Liang .name = "cbox",
40746866b59SKan Liang .num_counters = 4,
4084d47d640SKan Liang .num_boxes = 8,
40946866b59SKan Liang .perf_ctr_bits = 44,
41046866b59SKan Liang .fixed_ctr_bits = 48,
41146866b59SKan Liang .perf_ctr = SNB_UNC_CBO_0_PER_CTR0,
41246866b59SKan Liang .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0,
41346866b59SKan Liang .fixed_ctr = SNB_UNC_FIXED_CTR,
41446866b59SKan Liang .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL,
41546866b59SKan Liang .single_fixed = 1,
41646866b59SKan Liang .event_mask = SNB_UNC_RAW_EVENT_MASK,
41746866b59SKan Liang .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
41846866b59SKan Liang .ops = &skl_uncore_msr_ops,
41946866b59SKan Liang .format_group = &snb_uncore_format_group,
42046866b59SKan Liang .event_descs = snb_uncore_events,
42146866b59SKan Liang };
42246866b59SKan Liang
42346866b59SKan Liang static struct intel_uncore_type *skl_msr_uncores[] = {
42446866b59SKan Liang &skl_uncore_cbox,
42546866b59SKan Liang &snb_uncore_arb,
42646866b59SKan Liang NULL,
42746866b59SKan Liang };
42846866b59SKan Liang
skl_uncore_cpu_init(void)42946866b59SKan Liang void skl_uncore_cpu_init(void)
43046866b59SKan Liang {
43146866b59SKan Liang uncore_msr_uncores = skl_msr_uncores;
43289b0f15fSThomas Gleixner if (skl_uncore_cbox.num_boxes > topology_num_cores_per_package())
43389b0f15fSThomas Gleixner skl_uncore_cbox.num_boxes = topology_num_cores_per_package();
43446866b59SKan Liang snb_uncore_arb.ops = &skl_uncore_msr_ops;
43546866b59SKan Liang }
43646866b59SKan Liang
4378f5d41f3SKan Liang static struct intel_uncore_ops icl_uncore_msr_ops = {
4388f5d41f3SKan Liang .disable_event = snb_uncore_msr_disable_event,
4398f5d41f3SKan Liang .enable_event = snb_uncore_msr_enable_event,
4408f5d41f3SKan Liang .read_counter = uncore_msr_read_counter,
4418f5d41f3SKan Liang };
4428f5d41f3SKan Liang
4436e394376SKan Liang static struct intel_uncore_type icl_uncore_cbox = {
4446e394376SKan Liang .name = "cbox",
445ee139385SKan Liang .num_counters = 2,
4466e394376SKan Liang .perf_ctr_bits = 44,
4476e394376SKan Liang .perf_ctr = ICL_UNC_CBO_0_PER_CTR0,
4486e394376SKan Liang .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0,
4496e394376SKan Liang .event_mask = SNB_UNC_RAW_EVENT_MASK,
4506e394376SKan Liang .msr_offset = ICL_UNC_CBO_MSR_OFFSET,
4518f5d41f3SKan Liang .ops = &icl_uncore_msr_ops,
4526e394376SKan Liang .format_group = &snb_uncore_format_group,
4536e394376SKan Liang };
4546e394376SKan Liang
4556e394376SKan Liang static struct uncore_event_desc icl_uncore_events[] = {
4566e394376SKan Liang INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff"),
4576e394376SKan Liang { /* end: all zeroes */ },
4586e394376SKan Liang };
4596e394376SKan Liang
4606e394376SKan Liang static struct attribute *icl_uncore_clock_formats_attr[] = {
4616e394376SKan Liang &format_attr_event.attr,
4626e394376SKan Liang NULL,
4636e394376SKan Liang };
4646e394376SKan Liang
4656e394376SKan Liang static struct attribute_group icl_uncore_clock_format_group = {
4666e394376SKan Liang .name = "format",
4676e394376SKan Liang .attrs = icl_uncore_clock_formats_attr,
4686e394376SKan Liang };
4696e394376SKan Liang
4706e394376SKan Liang static struct intel_uncore_type icl_uncore_clockbox = {
4716e394376SKan Liang .name = "clock",
4726e394376SKan Liang .num_counters = 1,
4736e394376SKan Liang .num_boxes = 1,
4746e394376SKan Liang .fixed_ctr_bits = 48,
4756e394376SKan Liang .fixed_ctr = SNB_UNC_FIXED_CTR,
4766e394376SKan Liang .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL,
4776e394376SKan Liang .single_fixed = 1,
4786e394376SKan Liang .event_mask = SNB_UNC_CTL_EV_SEL_MASK,
4796e394376SKan Liang .format_group = &icl_uncore_clock_format_group,
4808f5d41f3SKan Liang .ops = &icl_uncore_msr_ops,
4816e394376SKan Liang .event_descs = icl_uncore_events,
4826e394376SKan Liang };
4836e394376SKan Liang
4848f5d41f3SKan Liang static struct intel_uncore_type icl_uncore_arb = {
4858f5d41f3SKan Liang .name = "arb",
4868f5d41f3SKan Liang .num_counters = 1,
4878f5d41f3SKan Liang .num_boxes = 1,
4888f5d41f3SKan Liang .perf_ctr_bits = 44,
4898f5d41f3SKan Liang .perf_ctr = ICL_UNC_ARB_PER_CTR,
4908f5d41f3SKan Liang .event_ctl = ICL_UNC_ARB_PERFEVTSEL,
4918f5d41f3SKan Liang .event_mask = SNB_UNC_RAW_EVENT_MASK,
4928f5d41f3SKan Liang .ops = &icl_uncore_msr_ops,
4938f5d41f3SKan Liang .format_group = &snb_uncore_format_group,
4948f5d41f3SKan Liang };
4958f5d41f3SKan Liang
4966e394376SKan Liang static struct intel_uncore_type *icl_msr_uncores[] = {
4976e394376SKan Liang &icl_uncore_cbox,
4988f5d41f3SKan Liang &icl_uncore_arb,
4996e394376SKan Liang &icl_uncore_clockbox,
5006e394376SKan Liang NULL,
5016e394376SKan Liang };
5026e394376SKan Liang
icl_get_cbox_num(void)5036e394376SKan Liang static int icl_get_cbox_num(void)
5046e394376SKan Liang {
5056e394376SKan Liang u64 num_boxes;
5066e394376SKan Liang
5076e394376SKan Liang rdmsrl(ICL_UNC_CBO_CONFIG, num_boxes);
5086e394376SKan Liang
5096e394376SKan Liang return num_boxes & ICL_UNC_NUM_CBO_MASK;
5106e394376SKan Liang }
5116e394376SKan Liang
icl_uncore_cpu_init(void)5126e394376SKan Liang void icl_uncore_cpu_init(void)
5136e394376SKan Liang {
5146e394376SKan Liang uncore_msr_uncores = icl_msr_uncores;
5156e394376SKan Liang icl_uncore_cbox.num_boxes = icl_get_cbox_num();
5166e394376SKan Liang }
5176e394376SKan Liang
5188abbcfefSKan Liang static struct intel_uncore_type *tgl_msr_uncores[] = {
5198abbcfefSKan Liang &icl_uncore_cbox,
5208abbcfefSKan Liang &snb_uncore_arb,
5218abbcfefSKan Liang &icl_uncore_clockbox,
5228abbcfefSKan Liang NULL,
5238abbcfefSKan Liang };
5248abbcfefSKan Liang
rkl_uncore_msr_init_box(struct intel_uncore_box * box)52543bc103aSKan Liang static void rkl_uncore_msr_init_box(struct intel_uncore_box *box)
52643bc103aSKan Liang {
52743bc103aSKan Liang if (box->pmu->pmu_idx == 0)
52843bc103aSKan Liang wrmsrl(SKL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
52943bc103aSKan Liang }
53043bc103aSKan Liang
tgl_uncore_cpu_init(void)5318abbcfefSKan Liang void tgl_uncore_cpu_init(void)
5328abbcfefSKan Liang {
5338abbcfefSKan Liang uncore_msr_uncores = tgl_msr_uncores;
5348abbcfefSKan Liang icl_uncore_cbox.num_boxes = icl_get_cbox_num();
5358abbcfefSKan Liang icl_uncore_cbox.ops = &skl_uncore_msr_ops;
5368abbcfefSKan Liang icl_uncore_clockbox.ops = &skl_uncore_msr_ops;
5378abbcfefSKan Liang snb_uncore_arb.ops = &skl_uncore_msr_ops;
53843bc103aSKan Liang skl_uncore_msr_ops.init_box = rkl_uncore_msr_init_box;
5398abbcfefSKan Liang }
5408abbcfefSKan Liang
adl_uncore_msr_init_box(struct intel_uncore_box * box)541772ed05fSKan Liang static void adl_uncore_msr_init_box(struct intel_uncore_box *box)
542772ed05fSKan Liang {
543772ed05fSKan Liang if (box->pmu->pmu_idx == 0)
544772ed05fSKan Liang wrmsrl(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
545772ed05fSKan Liang }
546772ed05fSKan Liang
adl_uncore_msr_enable_box(struct intel_uncore_box * box)547772ed05fSKan Liang static void adl_uncore_msr_enable_box(struct intel_uncore_box *box)
548772ed05fSKan Liang {
549772ed05fSKan Liang wrmsrl(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
550772ed05fSKan Liang }
551772ed05fSKan Liang
adl_uncore_msr_disable_box(struct intel_uncore_box * box)552772ed05fSKan Liang static void adl_uncore_msr_disable_box(struct intel_uncore_box *box)
553772ed05fSKan Liang {
554772ed05fSKan Liang if (box->pmu->pmu_idx == 0)
555772ed05fSKan Liang wrmsrl(ADL_UNC_PERF_GLOBAL_CTL, 0);
556772ed05fSKan Liang }
557772ed05fSKan Liang
adl_uncore_msr_exit_box(struct intel_uncore_box * box)558772ed05fSKan Liang static void adl_uncore_msr_exit_box(struct intel_uncore_box *box)
559772ed05fSKan Liang {
560772ed05fSKan Liang if (box->pmu->pmu_idx == 0)
561772ed05fSKan Liang wrmsrl(ADL_UNC_PERF_GLOBAL_CTL, 0);
562772ed05fSKan Liang }
563772ed05fSKan Liang
564772ed05fSKan Liang static struct intel_uncore_ops adl_uncore_msr_ops = {
565772ed05fSKan Liang .init_box = adl_uncore_msr_init_box,
566772ed05fSKan Liang .enable_box = adl_uncore_msr_enable_box,
567772ed05fSKan Liang .disable_box = adl_uncore_msr_disable_box,
568772ed05fSKan Liang .exit_box = adl_uncore_msr_exit_box,
569772ed05fSKan Liang .disable_event = snb_uncore_msr_disable_event,
570772ed05fSKan Liang .enable_event = snb_uncore_msr_enable_event,
571772ed05fSKan Liang .read_counter = uncore_msr_read_counter,
572772ed05fSKan Liang };
573772ed05fSKan Liang
574772ed05fSKan Liang static struct attribute *adl_uncore_formats_attr[] = {
575772ed05fSKan Liang &format_attr_event.attr,
576772ed05fSKan Liang &format_attr_umask.attr,
577772ed05fSKan Liang &format_attr_edge.attr,
578772ed05fSKan Liang &format_attr_inv.attr,
579772ed05fSKan Liang &format_attr_threshold.attr,
580772ed05fSKan Liang NULL,
581772ed05fSKan Liang };
582772ed05fSKan Liang
583772ed05fSKan Liang static const struct attribute_group adl_uncore_format_group = {
584772ed05fSKan Liang .name = "format",
585772ed05fSKan Liang .attrs = adl_uncore_formats_attr,
586772ed05fSKan Liang };
587772ed05fSKan Liang
588772ed05fSKan Liang static struct intel_uncore_type adl_uncore_cbox = {
589772ed05fSKan Liang .name = "cbox",
590772ed05fSKan Liang .num_counters = 2,
591772ed05fSKan Liang .perf_ctr_bits = 44,
592772ed05fSKan Liang .perf_ctr = ADL_UNC_CBO_0_PER_CTR0,
593772ed05fSKan Liang .event_ctl = ADL_UNC_CBO_0_PERFEVTSEL0,
594772ed05fSKan Liang .event_mask = ADL_UNC_RAW_EVENT_MASK,
595772ed05fSKan Liang .msr_offset = ICL_UNC_CBO_MSR_OFFSET,
596772ed05fSKan Liang .ops = &adl_uncore_msr_ops,
597772ed05fSKan Liang .format_group = &adl_uncore_format_group,
598772ed05fSKan Liang };
599772ed05fSKan Liang
600772ed05fSKan Liang static struct intel_uncore_type adl_uncore_arb = {
601772ed05fSKan Liang .name = "arb",
602772ed05fSKan Liang .num_counters = 2,
603772ed05fSKan Liang .num_boxes = 2,
604772ed05fSKan Liang .perf_ctr_bits = 44,
605772ed05fSKan Liang .perf_ctr = ADL_UNC_ARB_PER_CTR0,
606772ed05fSKan Liang .event_ctl = ADL_UNC_ARB_PERFEVTSEL0,
607772ed05fSKan Liang .event_mask = SNB_UNC_RAW_EVENT_MASK,
608772ed05fSKan Liang .msr_offset = ADL_UNC_ARB_MSR_OFFSET,
609772ed05fSKan Liang .constraints = snb_uncore_arb_constraints,
610772ed05fSKan Liang .ops = &adl_uncore_msr_ops,
611772ed05fSKan Liang .format_group = &snb_uncore_format_group,
612772ed05fSKan Liang };
613772ed05fSKan Liang
614772ed05fSKan Liang static struct intel_uncore_type adl_uncore_clockbox = {
615772ed05fSKan Liang .name = "clock",
616772ed05fSKan Liang .num_counters = 1,
617772ed05fSKan Liang .num_boxes = 1,
618772ed05fSKan Liang .fixed_ctr_bits = 48,
619772ed05fSKan Liang .fixed_ctr = ADL_UNC_FIXED_CTR,
620772ed05fSKan Liang .fixed_ctl = ADL_UNC_FIXED_CTR_CTRL,
621772ed05fSKan Liang .single_fixed = 1,
622772ed05fSKan Liang .event_mask = SNB_UNC_CTL_EV_SEL_MASK,
623772ed05fSKan Liang .format_group = &icl_uncore_clock_format_group,
624772ed05fSKan Liang .ops = &adl_uncore_msr_ops,
625772ed05fSKan Liang .event_descs = icl_uncore_events,
626772ed05fSKan Liang };
627772ed05fSKan Liang
628772ed05fSKan Liang static struct intel_uncore_type *adl_msr_uncores[] = {
629772ed05fSKan Liang &adl_uncore_cbox,
630772ed05fSKan Liang &adl_uncore_arb,
631772ed05fSKan Liang &adl_uncore_clockbox,
632772ed05fSKan Liang NULL,
633772ed05fSKan Liang };
634772ed05fSKan Liang
adl_uncore_cpu_init(void)635772ed05fSKan Liang void adl_uncore_cpu_init(void)
636772ed05fSKan Liang {
637772ed05fSKan Liang adl_uncore_cbox.num_boxes = icl_get_cbox_num();
638772ed05fSKan Liang uncore_msr_uncores = adl_msr_uncores;
639772ed05fSKan Liang }
640772ed05fSKan Liang
641c828441fSKan Liang static struct intel_uncore_type mtl_uncore_cbox = {
642c828441fSKan Liang .name = "cbox",
643c828441fSKan Liang .num_counters = 2,
644c828441fSKan Liang .perf_ctr_bits = 48,
645c828441fSKan Liang .perf_ctr = MTL_UNC_CBO_0_PER_CTR0,
646c828441fSKan Liang .event_ctl = MTL_UNC_CBO_0_PERFEVTSEL0,
647c828441fSKan Liang .event_mask = ADL_UNC_RAW_EVENT_MASK,
648c828441fSKan Liang .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
649c828441fSKan Liang .ops = &icl_uncore_msr_ops,
650c828441fSKan Liang .format_group = &adl_uncore_format_group,
651c828441fSKan Liang };
652c828441fSKan Liang
653c828441fSKan Liang static struct intel_uncore_type mtl_uncore_hac_arb = {
654c828441fSKan Liang .name = "hac_arb",
655c828441fSKan Liang .num_counters = 2,
656c828441fSKan Liang .num_boxes = 2,
657c828441fSKan Liang .perf_ctr_bits = 48,
658c828441fSKan Liang .perf_ctr = MTL_UNC_HAC_ARB_CTR,
659c828441fSKan Liang .event_ctl = MTL_UNC_HAC_ARB_CTRL,
660c828441fSKan Liang .event_mask = ADL_UNC_RAW_EVENT_MASK,
661c828441fSKan Liang .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
662c828441fSKan Liang .ops = &icl_uncore_msr_ops,
663c828441fSKan Liang .format_group = &adl_uncore_format_group,
664c828441fSKan Liang };
665c828441fSKan Liang
666c828441fSKan Liang static struct intel_uncore_type mtl_uncore_arb = {
667c828441fSKan Liang .name = "arb",
668c828441fSKan Liang .num_counters = 2,
669c828441fSKan Liang .num_boxes = 2,
670c828441fSKan Liang .perf_ctr_bits = 48,
671c828441fSKan Liang .perf_ctr = MTL_UNC_ARB_CTR,
672c828441fSKan Liang .event_ctl = MTL_UNC_ARB_CTRL,
673c828441fSKan Liang .event_mask = ADL_UNC_RAW_EVENT_MASK,
674c828441fSKan Liang .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
675c828441fSKan Liang .ops = &icl_uncore_msr_ops,
676c828441fSKan Liang .format_group = &adl_uncore_format_group,
677c828441fSKan Liang };
678c828441fSKan Liang
679c828441fSKan Liang static struct intel_uncore_type mtl_uncore_hac_cbox = {
680c828441fSKan Liang .name = "hac_cbox",
681c828441fSKan Liang .num_counters = 2,
682c828441fSKan Liang .num_boxes = 2,
683c828441fSKan Liang .perf_ctr_bits = 48,
684c828441fSKan Liang .perf_ctr = MTL_UNC_HBO_CTR,
685c828441fSKan Liang .event_ctl = MTL_UNC_HBO_CTRL,
686c828441fSKan Liang .event_mask = ADL_UNC_RAW_EVENT_MASK,
687c828441fSKan Liang .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
688c828441fSKan Liang .ops = &icl_uncore_msr_ops,
689c828441fSKan Liang .format_group = &adl_uncore_format_group,
690c828441fSKan Liang };
691c828441fSKan Liang
mtl_uncore_msr_init_box(struct intel_uncore_box * box)692c828441fSKan Liang static void mtl_uncore_msr_init_box(struct intel_uncore_box *box)
693c828441fSKan Liang {
694c828441fSKan Liang wrmsrl(uncore_msr_box_ctl(box), SNB_UNC_GLOBAL_CTL_EN);
695c828441fSKan Liang }
696c828441fSKan Liang
697c828441fSKan Liang static struct intel_uncore_ops mtl_uncore_msr_ops = {
698c828441fSKan Liang .init_box = mtl_uncore_msr_init_box,
699c828441fSKan Liang .disable_event = snb_uncore_msr_disable_event,
700c828441fSKan Liang .enable_event = snb_uncore_msr_enable_event,
701c828441fSKan Liang .read_counter = uncore_msr_read_counter,
702c828441fSKan Liang };
703c828441fSKan Liang
704c828441fSKan Liang static struct intel_uncore_type mtl_uncore_cncu = {
705c828441fSKan Liang .name = "cncu",
706c828441fSKan Liang .num_counters = 1,
707c828441fSKan Liang .num_boxes = 1,
708c828441fSKan Liang .box_ctl = MTL_UNC_CNCU_BOX_CTL,
709c828441fSKan Liang .fixed_ctr_bits = 48,
710c828441fSKan Liang .fixed_ctr = MTL_UNC_CNCU_FIXED_CTR,
711c828441fSKan Liang .fixed_ctl = MTL_UNC_CNCU_FIXED_CTRL,
712c828441fSKan Liang .single_fixed = 1,
713c828441fSKan Liang .event_mask = SNB_UNC_CTL_EV_SEL_MASK,
714c828441fSKan Liang .format_group = &icl_uncore_clock_format_group,
715c828441fSKan Liang .ops = &mtl_uncore_msr_ops,
716c828441fSKan Liang .event_descs = icl_uncore_events,
717c828441fSKan Liang };
718c828441fSKan Liang
719c828441fSKan Liang static struct intel_uncore_type mtl_uncore_sncu = {
720c828441fSKan Liang .name = "sncu",
721c828441fSKan Liang .num_counters = 1,
722c828441fSKan Liang .num_boxes = 1,
723c828441fSKan Liang .box_ctl = MTL_UNC_SNCU_BOX_CTL,
724c828441fSKan Liang .fixed_ctr_bits = 48,
725c828441fSKan Liang .fixed_ctr = MTL_UNC_SNCU_FIXED_CTR,
726c828441fSKan Liang .fixed_ctl = MTL_UNC_SNCU_FIXED_CTRL,
727c828441fSKan Liang .single_fixed = 1,
728c828441fSKan Liang .event_mask = SNB_UNC_CTL_EV_SEL_MASK,
729c828441fSKan Liang .format_group = &icl_uncore_clock_format_group,
730c828441fSKan Liang .ops = &mtl_uncore_msr_ops,
731c828441fSKan Liang .event_descs = icl_uncore_events,
732c828441fSKan Liang };
733c828441fSKan Liang
734c828441fSKan Liang static struct intel_uncore_type *mtl_msr_uncores[] = {
735c828441fSKan Liang &mtl_uncore_cbox,
736c828441fSKan Liang &mtl_uncore_hac_arb,
737c828441fSKan Liang &mtl_uncore_arb,
738c828441fSKan Liang &mtl_uncore_hac_cbox,
739c828441fSKan Liang &mtl_uncore_cncu,
740c828441fSKan Liang &mtl_uncore_sncu,
741c828441fSKan Liang NULL
742c828441fSKan Liang };
743c828441fSKan Liang
mtl_uncore_cpu_init(void)744c828441fSKan Liang void mtl_uncore_cpu_init(void)
745c828441fSKan Liang {
746c828441fSKan Liang mtl_uncore_cbox.num_boxes = icl_get_cbox_num();
747c828441fSKan Liang uncore_msr_uncores = mtl_msr_uncores;
748c828441fSKan Liang }
749c828441fSKan Liang
7509bd7dfe3SKan Liang static struct intel_uncore_type *lnl_msr_uncores[] = {
7519bd7dfe3SKan Liang &mtl_uncore_cbox,
7529bd7dfe3SKan Liang &mtl_uncore_arb,
7539bd7dfe3SKan Liang NULL
7549bd7dfe3SKan Liang };
7559bd7dfe3SKan Liang
7569bd7dfe3SKan Liang #define LNL_UNC_MSR_GLOBAL_CTL 0x240e
7579bd7dfe3SKan Liang
lnl_uncore_msr_init_box(struct intel_uncore_box * box)7589bd7dfe3SKan Liang static void lnl_uncore_msr_init_box(struct intel_uncore_box *box)
7599bd7dfe3SKan Liang {
7609bd7dfe3SKan Liang if (box->pmu->pmu_idx == 0)
7619bd7dfe3SKan Liang wrmsrl(LNL_UNC_MSR_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
7629bd7dfe3SKan Liang }
7639bd7dfe3SKan Liang
7649bd7dfe3SKan Liang static struct intel_uncore_ops lnl_uncore_msr_ops = {
7659bd7dfe3SKan Liang .init_box = lnl_uncore_msr_init_box,
7669bd7dfe3SKan Liang .disable_event = snb_uncore_msr_disable_event,
7679bd7dfe3SKan Liang .enable_event = snb_uncore_msr_enable_event,
7689bd7dfe3SKan Liang .read_counter = uncore_msr_read_counter,
7699bd7dfe3SKan Liang };
7709bd7dfe3SKan Liang
lnl_uncore_cpu_init(void)7719bd7dfe3SKan Liang void lnl_uncore_cpu_init(void)
7729bd7dfe3SKan Liang {
7739bd7dfe3SKan Liang mtl_uncore_cbox.num_boxes = 4;
7749bd7dfe3SKan Liang mtl_uncore_cbox.ops = &lnl_uncore_msr_ops;
7759bd7dfe3SKan Liang uncore_msr_uncores = lnl_msr_uncores;
7769bd7dfe3SKan Liang }
7779bd7dfe3SKan Liang
77892553e40SBorislav Petkov enum {
77992553e40SBorislav Petkov SNB_PCI_UNCORE_IMC,
78092553e40SBorislav Petkov };
78192553e40SBorislav Petkov
78292553e40SBorislav Petkov static struct uncore_event_desc snb_uncore_imc_events[] = {
78392553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(data_reads, "event=0x01"),
78492553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(data_reads.scale, "6.103515625e-5"),
78592553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(data_reads.unit, "MiB"),
78692553e40SBorislav Petkov
78792553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(data_writes, "event=0x02"),
78892553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(data_writes.scale, "6.103515625e-5"),
78992553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(data_writes.unit, "MiB"),
79092553e40SBorislav Petkov
79124633d90SVaibhav Shankar INTEL_UNCORE_EVENT_DESC(gt_requests, "event=0x03"),
79224633d90SVaibhav Shankar INTEL_UNCORE_EVENT_DESC(gt_requests.scale, "6.103515625e-5"),
79324633d90SVaibhav Shankar INTEL_UNCORE_EVENT_DESC(gt_requests.unit, "MiB"),
79424633d90SVaibhav Shankar
79524633d90SVaibhav Shankar INTEL_UNCORE_EVENT_DESC(ia_requests, "event=0x04"),
79624633d90SVaibhav Shankar INTEL_UNCORE_EVENT_DESC(ia_requests.scale, "6.103515625e-5"),
79724633d90SVaibhav Shankar INTEL_UNCORE_EVENT_DESC(ia_requests.unit, "MiB"),
79824633d90SVaibhav Shankar
79924633d90SVaibhav Shankar INTEL_UNCORE_EVENT_DESC(io_requests, "event=0x05"),
80024633d90SVaibhav Shankar INTEL_UNCORE_EVENT_DESC(io_requests.scale, "6.103515625e-5"),
80124633d90SVaibhav Shankar INTEL_UNCORE_EVENT_DESC(io_requests.unit, "MiB"),
80224633d90SVaibhav Shankar
80392553e40SBorislav Petkov { /* end: all zeroes */ },
80492553e40SBorislav Petkov };
80592553e40SBorislav Petkov
80692553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_EVENT_MASK 0xff
80792553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_BAR_OFFSET 0x48
80892553e40SBorislav Petkov
80992553e40SBorislav Petkov /* page size multiple covering all config regs */
81092553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_MAP_SIZE 0x6000
81192553e40SBorislav Petkov
81292553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_DATA_READS 0x1
81392553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_DATA_READS_BASE 0x5050
81492553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_DATA_WRITES 0x2
81592553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE 0x5054
81692553e40SBorislav Petkov #define SNB_UNCORE_PCI_IMC_CTR_BASE SNB_UNCORE_PCI_IMC_DATA_READS_BASE
81792553e40SBorislav Petkov
81824633d90SVaibhav Shankar /* BW break down- legacy counters */
81924633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_GT_REQUESTS 0x3
82024633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_GT_REQUESTS_BASE 0x5040
82124633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_IA_REQUESTS 0x4
82224633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_IA_REQUESTS_BASE 0x5044
82324633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_IO_REQUESTS 0x5
82424633d90SVaibhav Shankar #define SNB_UNCORE_PCI_IMC_IO_REQUESTS_BASE 0x5048
82524633d90SVaibhav Shankar
8269aae1780SKan Liang enum perf_snb_uncore_imc_freerunning_types {
82724633d90SVaibhav Shankar SNB_PCI_UNCORE_IMC_DATA_READS = 0,
82824633d90SVaibhav Shankar SNB_PCI_UNCORE_IMC_DATA_WRITES,
82924633d90SVaibhav Shankar SNB_PCI_UNCORE_IMC_GT_REQUESTS,
83024633d90SVaibhav Shankar SNB_PCI_UNCORE_IMC_IA_REQUESTS,
83124633d90SVaibhav Shankar SNB_PCI_UNCORE_IMC_IO_REQUESTS,
83224633d90SVaibhav Shankar
8339aae1780SKan Liang SNB_PCI_UNCORE_IMC_FREERUNNING_TYPE_MAX,
8349aae1780SKan Liang };
8359aae1780SKan Liang
8369aae1780SKan Liang static struct freerunning_counters snb_uncore_imc_freerunning[] = {
83724633d90SVaibhav Shankar [SNB_PCI_UNCORE_IMC_DATA_READS] = { SNB_UNCORE_PCI_IMC_DATA_READS_BASE,
83824633d90SVaibhav Shankar 0x0, 0x0, 1, 32 },
8391a8cfa24SArnd Bergmann [SNB_PCI_UNCORE_IMC_DATA_WRITES] = { SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE,
84024633d90SVaibhav Shankar 0x0, 0x0, 1, 32 },
84124633d90SVaibhav Shankar [SNB_PCI_UNCORE_IMC_GT_REQUESTS] = { SNB_UNCORE_PCI_IMC_GT_REQUESTS_BASE,
84224633d90SVaibhav Shankar 0x0, 0x0, 1, 32 },
84324633d90SVaibhav Shankar [SNB_PCI_UNCORE_IMC_IA_REQUESTS] = { SNB_UNCORE_PCI_IMC_IA_REQUESTS_BASE,
84424633d90SVaibhav Shankar 0x0, 0x0, 1, 32 },
84524633d90SVaibhav Shankar [SNB_PCI_UNCORE_IMC_IO_REQUESTS] = { SNB_UNCORE_PCI_IMC_IO_REQUESTS_BASE,
84624633d90SVaibhav Shankar 0x0, 0x0, 1, 32 },
8479aae1780SKan Liang };
8489aae1780SKan Liang
84992553e40SBorislav Petkov static struct attribute *snb_uncore_imc_formats_attr[] = {
85092553e40SBorislav Petkov &format_attr_event.attr,
85192553e40SBorislav Petkov NULL,
85292553e40SBorislav Petkov };
85392553e40SBorislav Petkov
85445bd07adSArvind Yadav static const struct attribute_group snb_uncore_imc_format_group = {
85592553e40SBorislav Petkov .name = "format",
85692553e40SBorislav Petkov .attrs = snb_uncore_imc_formats_attr,
85792553e40SBorislav Petkov };
85892553e40SBorislav Petkov
snb_uncore_imc_init_box(struct intel_uncore_box * box)85992553e40SBorislav Petkov static void snb_uncore_imc_init_box(struct intel_uncore_box *box)
86092553e40SBorislav Petkov {
8611b94d31dSKan Liang struct intel_uncore_type *type = box->pmu->type;
86292553e40SBorislav Petkov struct pci_dev *pdev = box->pci_dev;
86392553e40SBorislav Petkov int where = SNB_UNCORE_PCI_IMC_BAR_OFFSET;
86492553e40SBorislav Petkov resource_size_t addr;
86592553e40SBorislav Petkov u32 pci_dword;
86692553e40SBorislav Petkov
86792553e40SBorislav Petkov pci_read_config_dword(pdev, where, &pci_dword);
86892553e40SBorislav Petkov addr = pci_dword;
86992553e40SBorislav Petkov
87092553e40SBorislav Petkov #ifdef CONFIG_PHYS_ADDR_T_64BIT
87192553e40SBorislav Petkov pci_read_config_dword(pdev, where + 4, &pci_dword);
87292553e40SBorislav Petkov addr |= ((resource_size_t)pci_dword << 32);
87392553e40SBorislav Petkov #endif
87492553e40SBorislav Petkov
87592553e40SBorislav Petkov addr &= ~(PAGE_SIZE - 1);
87692553e40SBorislav Petkov
8771b94d31dSKan Liang box->io_addr = ioremap(addr, type->mmio_map_size);
8781b94d31dSKan Liang if (!box->io_addr)
8791b94d31dSKan Liang pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
8801b94d31dSKan Liang
88192553e40SBorislav Petkov box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL;
88292553e40SBorislav Petkov }
88392553e40SBorislav Petkov
snb_uncore_imc_enable_box(struct intel_uncore_box * box)88492553e40SBorislav Petkov static void snb_uncore_imc_enable_box(struct intel_uncore_box *box)
88592553e40SBorislav Petkov {}
88692553e40SBorislav Petkov
snb_uncore_imc_disable_box(struct intel_uncore_box * box)88792553e40SBorislav Petkov static void snb_uncore_imc_disable_box(struct intel_uncore_box *box)
88892553e40SBorislav Petkov {}
88992553e40SBorislav Petkov
snb_uncore_imc_enable_event(struct intel_uncore_box * box,struct perf_event * event)89092553e40SBorislav Petkov static void snb_uncore_imc_enable_event(struct intel_uncore_box *box, struct perf_event *event)
89192553e40SBorislav Petkov {}
89292553e40SBorislav Petkov
snb_uncore_imc_disable_event(struct intel_uncore_box * box,struct perf_event * event)89392553e40SBorislav Petkov static void snb_uncore_imc_disable_event(struct intel_uncore_box *box, struct perf_event *event)
89492553e40SBorislav Petkov {}
89592553e40SBorislav Petkov
89692553e40SBorislav Petkov /*
8979aae1780SKan Liang * Keep the custom event_init() function compatible with old event
8989aae1780SKan Liang * encoding for free running counters.
89992553e40SBorislav Petkov */
snb_uncore_imc_event_init(struct perf_event * event)90092553e40SBorislav Petkov static int snb_uncore_imc_event_init(struct perf_event *event)
90192553e40SBorislav Petkov {
90292553e40SBorislav Petkov struct intel_uncore_pmu *pmu;
90392553e40SBorislav Petkov struct intel_uncore_box *box;
90492553e40SBorislav Petkov struct hw_perf_event *hwc = &event->hw;
90592553e40SBorislav Petkov u64 cfg = event->attr.config & SNB_UNCORE_PCI_IMC_EVENT_MASK;
90692553e40SBorislav Petkov int idx, base;
90792553e40SBorislav Petkov
90892553e40SBorislav Petkov if (event->attr.type != event->pmu->type)
90992553e40SBorislav Petkov return -ENOENT;
91092553e40SBorislav Petkov
91192553e40SBorislav Petkov pmu = uncore_event_to_pmu(event);
91292553e40SBorislav Petkov /* no device found for this pmu */
91392553e40SBorislav Petkov if (pmu->func_id < 0)
91492553e40SBorislav Petkov return -ENOENT;
91592553e40SBorislav Petkov
91692553e40SBorislav Petkov /* Sampling not supported yet */
91792553e40SBorislav Petkov if (hwc->sample_period)
91892553e40SBorislav Petkov return -EINVAL;
91992553e40SBorislav Petkov
92092553e40SBorislav Petkov /* unsupported modes and filters */
9212ff40250SAndrew Murray if (event->attr.sample_period) /* no sampling */
92292553e40SBorislav Petkov return -EINVAL;
92392553e40SBorislav Petkov
92492553e40SBorislav Petkov /*
92592553e40SBorislav Petkov * Place all uncore events for a particular physical package
92692553e40SBorislav Petkov * onto a single cpu
92792553e40SBorislav Petkov */
92892553e40SBorislav Petkov if (event->cpu < 0)
92992553e40SBorislav Petkov return -EINVAL;
93092553e40SBorislav Petkov
93192553e40SBorislav Petkov /* check only supported bits are set */
93292553e40SBorislav Petkov if (event->attr.config & ~SNB_UNCORE_PCI_IMC_EVENT_MASK)
93392553e40SBorislav Petkov return -EINVAL;
93492553e40SBorislav Petkov
93592553e40SBorislav Petkov box = uncore_pmu_to_box(pmu, event->cpu);
93692553e40SBorislav Petkov if (!box || box->cpu < 0)
93792553e40SBorislav Petkov return -EINVAL;
93892553e40SBorislav Petkov
93992553e40SBorislav Petkov event->cpu = box->cpu;
9401f2569faSThomas Gleixner event->pmu_private = box;
94192553e40SBorislav Petkov
942e64cd6f7SDavid Carrillo-Cisneros event->event_caps |= PERF_EV_CAP_READ_ACTIVE_PKG;
943e64cd6f7SDavid Carrillo-Cisneros
94492553e40SBorislav Petkov event->hw.idx = -1;
94592553e40SBorislav Petkov event->hw.last_tag = ~0ULL;
94692553e40SBorislav Petkov event->hw.extra_reg.idx = EXTRA_REG_NONE;
94792553e40SBorislav Petkov event->hw.branch_reg.idx = EXTRA_REG_NONE;
94892553e40SBorislav Petkov /*
94992553e40SBorislav Petkov * check event is known (whitelist, determines counter)
95092553e40SBorislav Petkov */
95192553e40SBorislav Petkov switch (cfg) {
95292553e40SBorislav Petkov case SNB_UNCORE_PCI_IMC_DATA_READS:
95392553e40SBorislav Petkov base = SNB_UNCORE_PCI_IMC_DATA_READS_BASE;
9549aae1780SKan Liang idx = UNCORE_PMC_IDX_FREERUNNING;
95592553e40SBorislav Petkov break;
95692553e40SBorislav Petkov case SNB_UNCORE_PCI_IMC_DATA_WRITES:
95792553e40SBorislav Petkov base = SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE;
9589aae1780SKan Liang idx = UNCORE_PMC_IDX_FREERUNNING;
95992553e40SBorislav Petkov break;
96024633d90SVaibhav Shankar case SNB_UNCORE_PCI_IMC_GT_REQUESTS:
96124633d90SVaibhav Shankar base = SNB_UNCORE_PCI_IMC_GT_REQUESTS_BASE;
96224633d90SVaibhav Shankar idx = UNCORE_PMC_IDX_FREERUNNING;
96324633d90SVaibhav Shankar break;
96424633d90SVaibhav Shankar case SNB_UNCORE_PCI_IMC_IA_REQUESTS:
96524633d90SVaibhav Shankar base = SNB_UNCORE_PCI_IMC_IA_REQUESTS_BASE;
96624633d90SVaibhav Shankar idx = UNCORE_PMC_IDX_FREERUNNING;
96724633d90SVaibhav Shankar break;
96824633d90SVaibhav Shankar case SNB_UNCORE_PCI_IMC_IO_REQUESTS:
96924633d90SVaibhav Shankar base = SNB_UNCORE_PCI_IMC_IO_REQUESTS_BASE;
97024633d90SVaibhav Shankar idx = UNCORE_PMC_IDX_FREERUNNING;
97124633d90SVaibhav Shankar break;
97292553e40SBorislav Petkov default:
97392553e40SBorislav Petkov return -EINVAL;
97492553e40SBorislav Petkov }
97592553e40SBorislav Petkov
97692553e40SBorislav Petkov /* must be done before validate_group */
97792553e40SBorislav Petkov event->hw.event_base = base;
97892553e40SBorislav Petkov event->hw.idx = idx;
97992553e40SBorislav Petkov
9808041ffd3SKan Liang /* Convert to standard encoding format for freerunning counters */
9818041ffd3SKan Liang event->hw.config = ((cfg - 1) << 8) | 0x10ff;
9828041ffd3SKan Liang
98392553e40SBorislav Petkov /* no group validation needed, we have free running counters */
98492553e40SBorislav Petkov
98592553e40SBorislav Petkov return 0;
98692553e40SBorislav Petkov }
98792553e40SBorislav Petkov
snb_uncore_imc_hw_config(struct intel_uncore_box * box,struct perf_event * event)98892553e40SBorislav Petkov static int snb_uncore_imc_hw_config(struct intel_uncore_box *box, struct perf_event *event)
98992553e40SBorislav Petkov {
99092553e40SBorislav Petkov return 0;
99192553e40SBorislav Petkov }
99292553e40SBorislav Petkov
snb_pci2phy_map_init(int devid)99392553e40SBorislav Petkov int snb_pci2phy_map_init(int devid)
99492553e40SBorislav Petkov {
99592553e40SBorislav Petkov struct pci_dev *dev = NULL;
99692553e40SBorislav Petkov struct pci2phy_map *map;
99792553e40SBorislav Petkov int bus, segment;
99892553e40SBorislav Petkov
99992553e40SBorislav Petkov dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, dev);
100092553e40SBorislav Petkov if (!dev)
100192553e40SBorislav Petkov return -ENOTTY;
100292553e40SBorislav Petkov
100392553e40SBorislav Petkov bus = dev->bus->number;
100492553e40SBorislav Petkov segment = pci_domain_nr(dev->bus);
100592553e40SBorislav Petkov
100692553e40SBorislav Petkov raw_spin_lock(&pci2phy_map_lock);
100792553e40SBorislav Petkov map = __find_pci2phy_map(segment);
100892553e40SBorislav Petkov if (!map) {
100992553e40SBorislav Petkov raw_spin_unlock(&pci2phy_map_lock);
101092553e40SBorislav Petkov pci_dev_put(dev);
101192553e40SBorislav Petkov return -ENOMEM;
101292553e40SBorislav Petkov }
1013ba9506beSSteve Wahl map->pbus_to_dieid[bus] = 0;
101492553e40SBorislav Petkov raw_spin_unlock(&pci2phy_map_lock);
101592553e40SBorislav Petkov
101692553e40SBorislav Petkov pci_dev_put(dev);
101792553e40SBorislav Petkov
101892553e40SBorislav Petkov return 0;
101992553e40SBorislav Petkov }
102092553e40SBorislav Petkov
snb_uncore_imc_read_counter(struct intel_uncore_box * box,struct perf_event * event)102111745ecfSStephane Eranian static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event)
102211745ecfSStephane Eranian {
102311745ecfSStephane Eranian struct hw_perf_event *hwc = &event->hw;
102411745ecfSStephane Eranian
102511745ecfSStephane Eranian /*
102611745ecfSStephane Eranian * SNB IMC counters are 32-bit and are laid out back to back
102711745ecfSStephane Eranian * in MMIO space. Therefore we must use a 32-bit accessor function
102811745ecfSStephane Eranian * using readq() from uncore_mmio_read_counter() causes problems
102911745ecfSStephane Eranian * because it is reading 64-bit at a time. This is okay for the
103011745ecfSStephane Eranian * uncore_perf_event_update() function because it drops the upper
103111745ecfSStephane Eranian * 32-bits but not okay for plain uncore_read_counter() as invoked
103211745ecfSStephane Eranian * in uncore_pmu_event_start().
103311745ecfSStephane Eranian */
103411745ecfSStephane Eranian return (u64)readl(box->io_addr + hwc->event_base);
103511745ecfSStephane Eranian }
103611745ecfSStephane Eranian
103792553e40SBorislav Petkov static struct pmu snb_uncore_imc_pmu = {
103892553e40SBorislav Petkov .task_ctx_nr = perf_invalid_context,
103992553e40SBorislav Petkov .event_init = snb_uncore_imc_event_init,
10409aae1780SKan Liang .add = uncore_pmu_event_add,
10419aae1780SKan Liang .del = uncore_pmu_event_del,
10429aae1780SKan Liang .start = uncore_pmu_event_start,
10439aae1780SKan Liang .stop = uncore_pmu_event_stop,
10449aae1780SKan Liang .read = uncore_pmu_event_read,
10452ff40250SAndrew Murray .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
104692553e40SBorislav Petkov };
104792553e40SBorislav Petkov
104892553e40SBorislav Petkov static struct intel_uncore_ops snb_uncore_imc_ops = {
104992553e40SBorislav Petkov .init_box = snb_uncore_imc_init_box,
105007ce734dSKan Liang .exit_box = uncore_mmio_exit_box,
105192553e40SBorislav Petkov .enable_box = snb_uncore_imc_enable_box,
105292553e40SBorislav Petkov .disable_box = snb_uncore_imc_disable_box,
105392553e40SBorislav Petkov .disable_event = snb_uncore_imc_disable_event,
105492553e40SBorislav Petkov .enable_event = snb_uncore_imc_enable_event,
105592553e40SBorislav Petkov .hw_config = snb_uncore_imc_hw_config,
105611745ecfSStephane Eranian .read_counter = snb_uncore_imc_read_counter,
105792553e40SBorislav Petkov };
105892553e40SBorislav Petkov
105992553e40SBorislav Petkov static struct intel_uncore_type snb_uncore_imc = {
106092553e40SBorislav Petkov .name = "imc",
106124633d90SVaibhav Shankar .num_counters = 5,
106292553e40SBorislav Petkov .num_boxes = 1,
10639aae1780SKan Liang .num_freerunning_types = SNB_PCI_UNCORE_IMC_FREERUNNING_TYPE_MAX,
10641b94d31dSKan Liang .mmio_map_size = SNB_UNCORE_PCI_IMC_MAP_SIZE,
10659aae1780SKan Liang .freerunning = snb_uncore_imc_freerunning,
106692553e40SBorislav Petkov .event_descs = snb_uncore_imc_events,
106792553e40SBorislav Petkov .format_group = &snb_uncore_imc_format_group,
106892553e40SBorislav Petkov .ops = &snb_uncore_imc_ops,
106992553e40SBorislav Petkov .pmu = &snb_uncore_imc_pmu,
107092553e40SBorislav Petkov };
107192553e40SBorislav Petkov
107292553e40SBorislav Petkov static struct intel_uncore_type *snb_pci_uncores[] = {
107392553e40SBorislav Petkov [SNB_PCI_UNCORE_IMC] = &snb_uncore_imc,
107492553e40SBorislav Petkov NULL,
107592553e40SBorislav Petkov };
107692553e40SBorislav Petkov
107792553e40SBorislav Petkov static const struct pci_device_id snb_uncore_pci_ids[] = {
1078e5ae168eSKan Liang IMC_UNCORE_DEV(SNB),
107992553e40SBorislav Petkov { /* end: all zeroes */ },
108092553e40SBorislav Petkov };
108192553e40SBorislav Petkov
108292553e40SBorislav Petkov static const struct pci_device_id ivb_uncore_pci_ids[] = {
1083e5ae168eSKan Liang IMC_UNCORE_DEV(IVB),
1084e5ae168eSKan Liang IMC_UNCORE_DEV(IVB_E3),
108592553e40SBorislav Petkov { /* end: all zeroes */ },
108692553e40SBorislav Petkov };
108792553e40SBorislav Petkov
108892553e40SBorislav Petkov static const struct pci_device_id hsw_uncore_pci_ids[] = {
1089e5ae168eSKan Liang IMC_UNCORE_DEV(HSW),
1090e5ae168eSKan Liang IMC_UNCORE_DEV(HSW_U),
109192553e40SBorislav Petkov { /* end: all zeroes */ },
109292553e40SBorislav Petkov };
109392553e40SBorislav Petkov
109492553e40SBorislav Petkov static const struct pci_device_id bdw_uncore_pci_ids[] = {
1095e5ae168eSKan Liang IMC_UNCORE_DEV(BDW),
109692553e40SBorislav Petkov { /* end: all zeroes */ },
109792553e40SBorislav Petkov };
109892553e40SBorislav Petkov
109992553e40SBorislav Petkov static const struct pci_device_id skl_uncore_pci_ids[] = {
1100e5ae168eSKan Liang IMC_UNCORE_DEV(SKL_Y),
1101e5ae168eSKan Liang IMC_UNCORE_DEV(SKL_U),
1102e5ae168eSKan Liang IMC_UNCORE_DEV(SKL_HD),
1103e5ae168eSKan Liang IMC_UNCORE_DEV(SKL_HQ),
1104e5ae168eSKan Liang IMC_UNCORE_DEV(SKL_SD),
1105e5ae168eSKan Liang IMC_UNCORE_DEV(SKL_SQ),
1106e5ae168eSKan Liang IMC_UNCORE_DEV(SKL_E3),
1107e5ae168eSKan Liang IMC_UNCORE_DEV(KBL_Y),
1108e5ae168eSKan Liang IMC_UNCORE_DEV(KBL_U),
1109e5ae168eSKan Liang IMC_UNCORE_DEV(KBL_UQ),
1110e5ae168eSKan Liang IMC_UNCORE_DEV(KBL_SD),
1111e5ae168eSKan Liang IMC_UNCORE_DEV(KBL_SQ),
1112e5ae168eSKan Liang IMC_UNCORE_DEV(KBL_HQ),
1113e5ae168eSKan Liang IMC_UNCORE_DEV(KBL_WQ),
1114e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_2U),
1115e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_4U),
1116e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_4H),
1117e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_6H),
1118e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_2S_D),
1119e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_4S_D),
1120e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_6S_D),
1121e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_8S_D),
1122e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_4S_W),
1123e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_6S_W),
1124e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_8S_W),
1125e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_4S_S),
1126e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_6S_S),
1127e5ae168eSKan Liang IMC_UNCORE_DEV(CFL_8S_S),
1128e5ae168eSKan Liang IMC_UNCORE_DEV(AML_YD),
1129e5ae168eSKan Liang IMC_UNCORE_DEV(AML_YQ),
1130e5ae168eSKan Liang IMC_UNCORE_DEV(WHL_UQ),
1131e5ae168eSKan Liang IMC_UNCORE_DEV(WHL_4_UQ),
1132e5ae168eSKan Liang IMC_UNCORE_DEV(WHL_UD),
1133e5ae168eSKan Liang IMC_UNCORE_DEV(CML_H1),
1134e5ae168eSKan Liang IMC_UNCORE_DEV(CML_H2),
1135e5ae168eSKan Liang IMC_UNCORE_DEV(CML_H3),
1136e5ae168eSKan Liang IMC_UNCORE_DEV(CML_U1),
1137e5ae168eSKan Liang IMC_UNCORE_DEV(CML_U2),
1138e5ae168eSKan Liang IMC_UNCORE_DEV(CML_U3),
1139e5ae168eSKan Liang IMC_UNCORE_DEV(CML_S1),
1140e5ae168eSKan Liang IMC_UNCORE_DEV(CML_S2),
1141e5ae168eSKan Liang IMC_UNCORE_DEV(CML_S3),
1142e5ae168eSKan Liang IMC_UNCORE_DEV(CML_S4),
1143e5ae168eSKan Liang IMC_UNCORE_DEV(CML_S5),
114492553e40SBorislav Petkov { /* end: all zeroes */ },
114592553e40SBorislav Petkov };
114692553e40SBorislav Petkov
11476e394376SKan Liang static const struct pci_device_id icl_uncore_pci_ids[] = {
1148e5ae168eSKan Liang IMC_UNCORE_DEV(ICL_U),
1149e5ae168eSKan Liang IMC_UNCORE_DEV(ICL_U2),
1150e5ae168eSKan Liang IMC_UNCORE_DEV(RKL_1),
1151e5ae168eSKan Liang IMC_UNCORE_DEV(RKL_2),
11526e394376SKan Liang { /* end: all zeroes */ },
11536e394376SKan Liang };
11546e394376SKan Liang
115592553e40SBorislav Petkov static struct pci_driver snb_uncore_pci_driver = {
115692553e40SBorislav Petkov .name = "snb_uncore",
115792553e40SBorislav Petkov .id_table = snb_uncore_pci_ids,
115892553e40SBorislav Petkov };
115992553e40SBorislav Petkov
116092553e40SBorislav Petkov static struct pci_driver ivb_uncore_pci_driver = {
116192553e40SBorislav Petkov .name = "ivb_uncore",
116292553e40SBorislav Petkov .id_table = ivb_uncore_pci_ids,
116392553e40SBorislav Petkov };
116492553e40SBorislav Petkov
116592553e40SBorislav Petkov static struct pci_driver hsw_uncore_pci_driver = {
116692553e40SBorislav Petkov .name = "hsw_uncore",
116792553e40SBorislav Petkov .id_table = hsw_uncore_pci_ids,
116892553e40SBorislav Petkov };
116992553e40SBorislav Petkov
117092553e40SBorislav Petkov static struct pci_driver bdw_uncore_pci_driver = {
117192553e40SBorislav Petkov .name = "bdw_uncore",
117292553e40SBorislav Petkov .id_table = bdw_uncore_pci_ids,
117392553e40SBorislav Petkov };
117492553e40SBorislav Petkov
117592553e40SBorislav Petkov static struct pci_driver skl_uncore_pci_driver = {
117692553e40SBorislav Petkov .name = "skl_uncore",
117792553e40SBorislav Petkov .id_table = skl_uncore_pci_ids,
117892553e40SBorislav Petkov };
117992553e40SBorislav Petkov
11806e394376SKan Liang static struct pci_driver icl_uncore_pci_driver = {
11816e394376SKan Liang .name = "icl_uncore",
11826e394376SKan Liang .id_table = icl_uncore_pci_ids,
11836e394376SKan Liang };
11846e394376SKan Liang
118592553e40SBorislav Petkov struct imc_uncore_pci_dev {
118692553e40SBorislav Petkov __u32 pci_id;
118792553e40SBorislav Petkov struct pci_driver *driver;
118892553e40SBorislav Petkov };
118992553e40SBorislav Petkov #define IMC_DEV(a, d) \
119092553e40SBorislav Petkov { .pci_id = PCI_DEVICE_ID_INTEL_##a, .driver = (d) }
119192553e40SBorislav Petkov
119292553e40SBorislav Petkov static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = {
119392553e40SBorislav Petkov IMC_DEV(SNB_IMC, &snb_uncore_pci_driver),
119492553e40SBorislav Petkov IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver), /* 3rd Gen Core processor */
119592553e40SBorislav Petkov IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */
119692553e40SBorislav Petkov IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */
119792553e40SBorislav Petkov IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core ULT Mobile Processor */
119892553e40SBorislav Petkov IMC_DEV(BDW_IMC, &bdw_uncore_pci_driver), /* 5th Gen Core U */
1199d786810bSKan Liang IMC_DEV(SKL_Y_IMC, &skl_uncore_pci_driver), /* 6th Gen Core Y */
120046866b59SKan Liang IMC_DEV(SKL_U_IMC, &skl_uncore_pci_driver), /* 6th Gen Core U */
1201d786810bSKan Liang IMC_DEV(SKL_HD_IMC, &skl_uncore_pci_driver), /* 6th Gen Core H Dual Core */
1202d786810bSKan Liang IMC_DEV(SKL_HQ_IMC, &skl_uncore_pci_driver), /* 6th Gen Core H Quad Core */
1203d786810bSKan Liang IMC_DEV(SKL_SD_IMC, &skl_uncore_pci_driver), /* 6th Gen Core S Dual Core */
1204d786810bSKan Liang IMC_DEV(SKL_SQ_IMC, &skl_uncore_pci_driver), /* 6th Gen Core S Quad Core */
1205e7438304SKan Liang IMC_DEV(SKL_E3_IMC, &skl_uncore_pci_driver), /* Xeon E3 V5 Gen Core processor */
1206c10a8de0SKan Liang IMC_DEV(KBL_Y_IMC, &skl_uncore_pci_driver), /* 7th Gen Core Y */
1207c10a8de0SKan Liang IMC_DEV(KBL_U_IMC, &skl_uncore_pci_driver), /* 7th Gen Core U */
1208c10a8de0SKan Liang IMC_DEV(KBL_UQ_IMC, &skl_uncore_pci_driver), /* 7th Gen Core U Quad Core */
1209c10a8de0SKan Liang IMC_DEV(KBL_SD_IMC, &skl_uncore_pci_driver), /* 7th Gen Core S Dual Core */
1210c10a8de0SKan Liang IMC_DEV(KBL_SQ_IMC, &skl_uncore_pci_driver), /* 7th Gen Core S Quad Core */
12116e86d3dbSGayatri Kammela IMC_DEV(KBL_HQ_IMC, &skl_uncore_pci_driver), /* 7th Gen Core H Quad Core */
12126e86d3dbSGayatri Kammela IMC_DEV(KBL_WQ_IMC, &skl_uncore_pci_driver), /* 7th Gen Core S 4 cores Work Station */
1213c10a8de0SKan Liang IMC_DEV(CFL_2U_IMC, &skl_uncore_pci_driver), /* 8th Gen Core U 2 Cores */
1214c10a8de0SKan Liang IMC_DEV(CFL_4U_IMC, &skl_uncore_pci_driver), /* 8th Gen Core U 4 Cores */
1215c10a8de0SKan Liang IMC_DEV(CFL_4H_IMC, &skl_uncore_pci_driver), /* 8th Gen Core H 4 Cores */
1216c10a8de0SKan Liang IMC_DEV(CFL_6H_IMC, &skl_uncore_pci_driver), /* 8th Gen Core H 6 Cores */
1217c10a8de0SKan Liang IMC_DEV(CFL_2S_D_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 2 Cores Desktop */
1218c10a8de0SKan Liang IMC_DEV(CFL_4S_D_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 4 Cores Desktop */
1219c10a8de0SKan Liang IMC_DEV(CFL_6S_D_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 6 Cores Desktop */
1220c10a8de0SKan Liang IMC_DEV(CFL_8S_D_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 8 Cores Desktop */
1221c10a8de0SKan Liang IMC_DEV(CFL_4S_W_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 4 Cores Work Station */
1222c10a8de0SKan Liang IMC_DEV(CFL_6S_W_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 6 Cores Work Station */
1223c10a8de0SKan Liang IMC_DEV(CFL_8S_W_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 8 Cores Work Station */
1224c10a8de0SKan Liang IMC_DEV(CFL_4S_S_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 4 Cores Server */
1225c10a8de0SKan Liang IMC_DEV(CFL_6S_S_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 6 Cores Server */
1226c10a8de0SKan Liang IMC_DEV(CFL_8S_S_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 8 Cores Server */
12276e86d3dbSGayatri Kammela IMC_DEV(AML_YD_IMC, &skl_uncore_pci_driver), /* 8th Gen Core Y Mobile Dual Core */
12286e86d3dbSGayatri Kammela IMC_DEV(AML_YQ_IMC, &skl_uncore_pci_driver), /* 8th Gen Core Y Mobile Quad Core */
12296e86d3dbSGayatri Kammela IMC_DEV(WHL_UQ_IMC, &skl_uncore_pci_driver), /* 8th Gen Core U Mobile Quad Core */
12306e86d3dbSGayatri Kammela IMC_DEV(WHL_4_UQ_IMC, &skl_uncore_pci_driver), /* 8th Gen Core U Mobile Quad Core */
12316e86d3dbSGayatri Kammela IMC_DEV(WHL_UD_IMC, &skl_uncore_pci_driver), /* 8th Gen Core U Mobile Dual Core */
1232bb85429aSKan Liang IMC_DEV(CML_H1_IMC, &skl_uncore_pci_driver),
1233bb85429aSKan Liang IMC_DEV(CML_H2_IMC, &skl_uncore_pci_driver),
1234bb85429aSKan Liang IMC_DEV(CML_H3_IMC, &skl_uncore_pci_driver),
1235bb85429aSKan Liang IMC_DEV(CML_U1_IMC, &skl_uncore_pci_driver),
1236bb85429aSKan Liang IMC_DEV(CML_U2_IMC, &skl_uncore_pci_driver),
1237bb85429aSKan Liang IMC_DEV(CML_U3_IMC, &skl_uncore_pci_driver),
1238bb85429aSKan Liang IMC_DEV(CML_S1_IMC, &skl_uncore_pci_driver),
1239bb85429aSKan Liang IMC_DEV(CML_S2_IMC, &skl_uncore_pci_driver),
1240bb85429aSKan Liang IMC_DEV(CML_S3_IMC, &skl_uncore_pci_driver),
1241bb85429aSKan Liang IMC_DEV(CML_S4_IMC, &skl_uncore_pci_driver),
1242bb85429aSKan Liang IMC_DEV(CML_S5_IMC, &skl_uncore_pci_driver),
12436e394376SKan Liang IMC_DEV(ICL_U_IMC, &icl_uncore_pci_driver), /* 10th Gen Core Mobile */
12446e394376SKan Liang IMC_DEV(ICL_U2_IMC, &icl_uncore_pci_driver), /* 10th Gen Core Mobile */
124543bc103aSKan Liang IMC_DEV(RKL_1_IMC, &icl_uncore_pci_driver),
124643bc103aSKan Liang IMC_DEV(RKL_2_IMC, &icl_uncore_pci_driver),
124792553e40SBorislav Petkov { /* end marker */ }
124892553e40SBorislav Petkov };
124992553e40SBorislav Petkov
125092553e40SBorislav Petkov
125192553e40SBorislav Petkov #define for_each_imc_pci_id(x, t) \
125292553e40SBorislav Petkov for (x = (t); (x)->pci_id; x++)
125392553e40SBorislav Petkov
imc_uncore_find_dev(void)125492553e40SBorislav Petkov static struct pci_driver *imc_uncore_find_dev(void)
125592553e40SBorislav Petkov {
125692553e40SBorislav Petkov const struct imc_uncore_pci_dev *p;
125792553e40SBorislav Petkov int ret;
125892553e40SBorislav Petkov
125992553e40SBorislav Petkov for_each_imc_pci_id(p, desktop_imc_pci_ids) {
126092553e40SBorislav Petkov ret = snb_pci2phy_map_init(p->pci_id);
126192553e40SBorislav Petkov if (ret == 0)
126292553e40SBorislav Petkov return p->driver;
126392553e40SBorislav Petkov }
126492553e40SBorislav Petkov return NULL;
126592553e40SBorislav Petkov }
126692553e40SBorislav Petkov
imc_uncore_pci_init(void)126792553e40SBorislav Petkov static int imc_uncore_pci_init(void)
126892553e40SBorislav Petkov {
126992553e40SBorislav Petkov struct pci_driver *imc_drv = imc_uncore_find_dev();
127092553e40SBorislav Petkov
127192553e40SBorislav Petkov if (!imc_drv)
127292553e40SBorislav Petkov return -ENODEV;
127392553e40SBorislav Petkov
127492553e40SBorislav Petkov uncore_pci_uncores = snb_pci_uncores;
127592553e40SBorislav Petkov uncore_pci_driver = imc_drv;
127692553e40SBorislav Petkov
127792553e40SBorislav Petkov return 0;
127892553e40SBorislav Petkov }
127992553e40SBorislav Petkov
snb_uncore_pci_init(void)128092553e40SBorislav Petkov int snb_uncore_pci_init(void)
128192553e40SBorislav Petkov {
128292553e40SBorislav Petkov return imc_uncore_pci_init();
128392553e40SBorislav Petkov }
128492553e40SBorislav Petkov
ivb_uncore_pci_init(void)128592553e40SBorislav Petkov int ivb_uncore_pci_init(void)
128692553e40SBorislav Petkov {
128792553e40SBorislav Petkov return imc_uncore_pci_init();
128892553e40SBorislav Petkov }
hsw_uncore_pci_init(void)128992553e40SBorislav Petkov int hsw_uncore_pci_init(void)
129092553e40SBorislav Petkov {
129192553e40SBorislav Petkov return imc_uncore_pci_init();
129292553e40SBorislav Petkov }
129392553e40SBorislav Petkov
bdw_uncore_pci_init(void)129492553e40SBorislav Petkov int bdw_uncore_pci_init(void)
129592553e40SBorislav Petkov {
129692553e40SBorislav Petkov return imc_uncore_pci_init();
129792553e40SBorislav Petkov }
129892553e40SBorislav Petkov
skl_uncore_pci_init(void)129992553e40SBorislav Petkov int skl_uncore_pci_init(void)
130092553e40SBorislav Petkov {
130192553e40SBorislav Petkov return imc_uncore_pci_init();
130292553e40SBorislav Petkov }
130392553e40SBorislav Petkov
130492553e40SBorislav Petkov /* end of Sandy Bridge uncore support */
130592553e40SBorislav Petkov
130692553e40SBorislav Petkov /* Nehalem uncore support */
nhm_uncore_msr_disable_box(struct intel_uncore_box * box)130792553e40SBorislav Petkov static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box)
130892553e40SBorislav Petkov {
130992553e40SBorislav Petkov wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0);
131092553e40SBorislav Petkov }
131192553e40SBorislav Petkov
nhm_uncore_msr_enable_box(struct intel_uncore_box * box)131292553e40SBorislav Petkov static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box)
131392553e40SBorislav Petkov {
131492553e40SBorislav Petkov wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC);
131592553e40SBorislav Petkov }
131692553e40SBorislav Petkov
nhm_uncore_msr_enable_event(struct intel_uncore_box * box,struct perf_event * event)131792553e40SBorislav Petkov static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
131892553e40SBorislav Petkov {
131992553e40SBorislav Petkov struct hw_perf_event *hwc = &event->hw;
132092553e40SBorislav Petkov
132192553e40SBorislav Petkov if (hwc->idx < UNCORE_PMC_IDX_FIXED)
132292553e40SBorislav Petkov wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
132392553e40SBorislav Petkov else
132492553e40SBorislav Petkov wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN);
132592553e40SBorislav Petkov }
132692553e40SBorislav Petkov
132792553e40SBorislav Petkov static struct attribute *nhm_uncore_formats_attr[] = {
132892553e40SBorislav Petkov &format_attr_event.attr,
132992553e40SBorislav Petkov &format_attr_umask.attr,
133092553e40SBorislav Petkov &format_attr_edge.attr,
133192553e40SBorislav Petkov &format_attr_inv.attr,
133292553e40SBorislav Petkov &format_attr_cmask8.attr,
133392553e40SBorislav Petkov NULL,
133492553e40SBorislav Petkov };
133592553e40SBorislav Petkov
133645bd07adSArvind Yadav static const struct attribute_group nhm_uncore_format_group = {
133792553e40SBorislav Petkov .name = "format",
133892553e40SBorislav Petkov .attrs = nhm_uncore_formats_attr,
133992553e40SBorislav Petkov };
134092553e40SBorislav Petkov
134192553e40SBorislav Petkov static struct uncore_event_desc nhm_uncore_events[] = {
134292553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
134392553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any, "event=0x2f,umask=0x0f"),
134492553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any, "event=0x2c,umask=0x0f"),
134592553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads, "event=0x20,umask=0x01"),
134692553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes, "event=0x20,umask=0x02"),
134792553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads, "event=0x20,umask=0x04"),
134892553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"),
134992553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads, "event=0x20,umask=0x10"),
135092553e40SBorislav Petkov INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes, "event=0x20,umask=0x20"),
135192553e40SBorislav Petkov { /* end: all zeroes */ },
135292553e40SBorislav Petkov };
135392553e40SBorislav Petkov
135492553e40SBorislav Petkov static struct intel_uncore_ops nhm_uncore_msr_ops = {
135592553e40SBorislav Petkov .disable_box = nhm_uncore_msr_disable_box,
135692553e40SBorislav Petkov .enable_box = nhm_uncore_msr_enable_box,
135792553e40SBorislav Petkov .disable_event = snb_uncore_msr_disable_event,
135892553e40SBorislav Petkov .enable_event = nhm_uncore_msr_enable_event,
135992553e40SBorislav Petkov .read_counter = uncore_msr_read_counter,
136092553e40SBorislav Petkov };
136192553e40SBorislav Petkov
136292553e40SBorislav Petkov static struct intel_uncore_type nhm_uncore = {
136392553e40SBorislav Petkov .name = "",
136492553e40SBorislav Petkov .num_counters = 8,
136592553e40SBorislav Petkov .num_boxes = 1,
136692553e40SBorislav Petkov .perf_ctr_bits = 48,
136792553e40SBorislav Petkov .fixed_ctr_bits = 48,
136892553e40SBorislav Petkov .event_ctl = NHM_UNC_PERFEVTSEL0,
136992553e40SBorislav Petkov .perf_ctr = NHM_UNC_UNCORE_PMC0,
137092553e40SBorislav Petkov .fixed_ctr = NHM_UNC_FIXED_CTR,
137192553e40SBorislav Petkov .fixed_ctl = NHM_UNC_FIXED_CTR_CTRL,
137292553e40SBorislav Petkov .event_mask = NHM_UNC_RAW_EVENT_MASK,
137392553e40SBorislav Petkov .event_descs = nhm_uncore_events,
137492553e40SBorislav Petkov .ops = &nhm_uncore_msr_ops,
137592553e40SBorislav Petkov .format_group = &nhm_uncore_format_group,
137692553e40SBorislav Petkov };
137792553e40SBorislav Petkov
137892553e40SBorislav Petkov static struct intel_uncore_type *nhm_msr_uncores[] = {
137992553e40SBorislav Petkov &nhm_uncore,
138092553e40SBorislav Petkov NULL,
138192553e40SBorislav Petkov };
138292553e40SBorislav Petkov
nhm_uncore_cpu_init(void)138392553e40SBorislav Petkov void nhm_uncore_cpu_init(void)
138492553e40SBorislav Petkov {
138592553e40SBorislav Petkov uncore_msr_uncores = nhm_msr_uncores;
138692553e40SBorislav Petkov }
138792553e40SBorislav Petkov
138892553e40SBorislav Petkov /* end of Nehalem uncore support */
1389fdb64822SKan Liang
1390fdb64822SKan Liang /* Tiger Lake MMIO uncore support */
1391fdb64822SKan Liang
1392fdb64822SKan Liang static const struct pci_device_id tgl_uncore_pci_ids[] = {
1393e5ae168eSKan Liang IMC_UNCORE_DEV(TGL_U1),
1394e5ae168eSKan Liang IMC_UNCORE_DEV(TGL_U2),
1395e5ae168eSKan Liang IMC_UNCORE_DEV(TGL_U3),
1396e5ae168eSKan Liang IMC_UNCORE_DEV(TGL_U4),
1397e5ae168eSKan Liang IMC_UNCORE_DEV(TGL_H),
1398e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_1),
1399e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_2),
1400e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_3),
1401e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_4),
1402e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_5),
1403e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_6),
1404e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_7),
1405e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_8),
1406e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_9),
1407e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_10),
1408e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_11),
1409e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_12),
1410e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_13),
1411e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_14),
1412e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_15),
1413e5ae168eSKan Liang IMC_UNCORE_DEV(ADL_16),
1414f758bc5aSKan Liang IMC_UNCORE_DEV(ADL_17),
1415f758bc5aSKan Liang IMC_UNCORE_DEV(ADL_18),
1416f758bc5aSKan Liang IMC_UNCORE_DEV(ADL_19),
1417f758bc5aSKan Liang IMC_UNCORE_DEV(ADL_20),
1418f758bc5aSKan Liang IMC_UNCORE_DEV(ADL_21),
1419e5ae168eSKan Liang IMC_UNCORE_DEV(RPL_1),
1420e5ae168eSKan Liang IMC_UNCORE_DEV(RPL_2),
1421e5ae168eSKan Liang IMC_UNCORE_DEV(RPL_3),
1422e5ae168eSKan Liang IMC_UNCORE_DEV(RPL_4),
1423f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_5),
1424f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_6),
1425f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_7),
1426f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_8),
1427f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_9),
1428f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_10),
1429f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_11),
1430f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_12),
1431f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_13),
1432f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_14),
1433f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_15),
1434f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_16),
1435f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_17),
1436f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_18),
1437f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_19),
1438f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_20),
1439f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_21),
1440f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_22),
1441f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_23),
1442f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_24),
1443f758bc5aSKan Liang IMC_UNCORE_DEV(RPL_25),
1444c828441fSKan Liang IMC_UNCORE_DEV(MTL_1),
1445c828441fSKan Liang IMC_UNCORE_DEV(MTL_2),
1446c828441fSKan Liang IMC_UNCORE_DEV(MTL_3),
1447c828441fSKan Liang IMC_UNCORE_DEV(MTL_4),
1448c828441fSKan Liang IMC_UNCORE_DEV(MTL_5),
1449c828441fSKan Liang IMC_UNCORE_DEV(MTL_6),
1450c828441fSKan Liang IMC_UNCORE_DEV(MTL_7),
1451c828441fSKan Liang IMC_UNCORE_DEV(MTL_8),
1452c828441fSKan Liang IMC_UNCORE_DEV(MTL_9),
1453c828441fSKan Liang IMC_UNCORE_DEV(MTL_10),
1454c828441fSKan Liang IMC_UNCORE_DEV(MTL_11),
1455c828441fSKan Liang IMC_UNCORE_DEV(MTL_12),
1456c828441fSKan Liang IMC_UNCORE_DEV(MTL_13),
1457fdb64822SKan Liang { /* end: all zeroes */ }
1458fdb64822SKan Liang };
1459fdb64822SKan Liang
1460fdb64822SKan Liang enum perf_tgl_uncore_imc_freerunning_types {
1461fdb64822SKan Liang TGL_MMIO_UNCORE_IMC_DATA_TOTAL,
1462fdb64822SKan Liang TGL_MMIO_UNCORE_IMC_DATA_READ,
1463fdb64822SKan Liang TGL_MMIO_UNCORE_IMC_DATA_WRITE,
1464fdb64822SKan Liang TGL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX
1465fdb64822SKan Liang };
1466fdb64822SKan Liang
1467fdb64822SKan Liang static struct freerunning_counters tgl_l_uncore_imc_freerunning[] = {
1468fdb64822SKan Liang [TGL_MMIO_UNCORE_IMC_DATA_TOTAL] = { 0x5040, 0x0, 0x0, 1, 64 },
1469fdb64822SKan Liang [TGL_MMIO_UNCORE_IMC_DATA_READ] = { 0x5058, 0x0, 0x0, 1, 64 },
1470fdb64822SKan Liang [TGL_MMIO_UNCORE_IMC_DATA_WRITE] = { 0x50A0, 0x0, 0x0, 1, 64 },
1471fdb64822SKan Liang };
1472fdb64822SKan Liang
1473fdb64822SKan Liang static struct freerunning_counters tgl_uncore_imc_freerunning[] = {
1474fdb64822SKan Liang [TGL_MMIO_UNCORE_IMC_DATA_TOTAL] = { 0xd840, 0x0, 0x0, 1, 64 },
1475fdb64822SKan Liang [TGL_MMIO_UNCORE_IMC_DATA_READ] = { 0xd858, 0x0, 0x0, 1, 64 },
1476fdb64822SKan Liang [TGL_MMIO_UNCORE_IMC_DATA_WRITE] = { 0xd8A0, 0x0, 0x0, 1, 64 },
1477fdb64822SKan Liang };
1478fdb64822SKan Liang
1479fdb64822SKan Liang static struct uncore_event_desc tgl_uncore_imc_events[] = {
1480fdb64822SKan Liang INTEL_UNCORE_EVENT_DESC(data_total, "event=0xff,umask=0x10"),
1481fdb64822SKan Liang INTEL_UNCORE_EVENT_DESC(data_total.scale, "6.103515625e-5"),
1482fdb64822SKan Liang INTEL_UNCORE_EVENT_DESC(data_total.unit, "MiB"),
1483fdb64822SKan Liang
1484fdb64822SKan Liang INTEL_UNCORE_EVENT_DESC(data_read, "event=0xff,umask=0x20"),
1485fdb64822SKan Liang INTEL_UNCORE_EVENT_DESC(data_read.scale, "6.103515625e-5"),
1486fdb64822SKan Liang INTEL_UNCORE_EVENT_DESC(data_read.unit, "MiB"),
1487fdb64822SKan Liang
1488fdb64822SKan Liang INTEL_UNCORE_EVENT_DESC(data_write, "event=0xff,umask=0x30"),
1489fdb64822SKan Liang INTEL_UNCORE_EVENT_DESC(data_write.scale, "6.103515625e-5"),
1490fdb64822SKan Liang INTEL_UNCORE_EVENT_DESC(data_write.unit, "MiB"),
1491fdb64822SKan Liang
1492fdb64822SKan Liang { /* end: all zeroes */ }
1493fdb64822SKan Liang };
1494fdb64822SKan Liang
tgl_uncore_get_mc_dev(void)1495fdb64822SKan Liang static struct pci_dev *tgl_uncore_get_mc_dev(void)
1496fdb64822SKan Liang {
1497fdb64822SKan Liang const struct pci_device_id *ids = tgl_uncore_pci_ids;
1498fdb64822SKan Liang struct pci_dev *mc_dev = NULL;
1499fdb64822SKan Liang
1500fdb64822SKan Liang while (ids && ids->vendor) {
1501fdb64822SKan Liang mc_dev = pci_get_device(PCI_VENDOR_ID_INTEL, ids->device, NULL);
1502fdb64822SKan Liang if (mc_dev)
1503fdb64822SKan Liang return mc_dev;
1504fdb64822SKan Liang ids++;
1505fdb64822SKan Liang }
1506fdb64822SKan Liang
1507*aaad0e2aSZhenyu Wang /* Just try to grab 00:00.0 device */
1508*aaad0e2aSZhenyu Wang if (!mc_dev)
1509*aaad0e2aSZhenyu Wang mc_dev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
1510*aaad0e2aSZhenyu Wang
1511fdb64822SKan Liang return mc_dev;
1512fdb64822SKan Liang }
1513fdb64822SKan Liang
1514fdb64822SKan Liang #define TGL_UNCORE_MMIO_IMC_MEM_OFFSET 0x10000
15152af834f1SKan Liang #define TGL_UNCORE_PCI_IMC_MAP_SIZE 0xe000
1516fdb64822SKan Liang
1517efb0c9c0SKan Liang static void
uncore_get_box_mmio_addr(struct intel_uncore_box * box,unsigned int base_offset,int bar_offset,int step)1518efb0c9c0SKan Liang uncore_get_box_mmio_addr(struct intel_uncore_box *box,
1519efb0c9c0SKan Liang unsigned int base_offset,
1520efb0c9c0SKan Liang int bar_offset, int step)
1521fdb64822SKan Liang {
1522fdb64822SKan Liang struct pci_dev *pdev = tgl_uncore_get_mc_dev();
1523fdb64822SKan Liang struct intel_uncore_pmu *pmu = box->pmu;
15241b94d31dSKan Liang struct intel_uncore_type *type = pmu->type;
1525fdb64822SKan Liang resource_size_t addr;
1526efb0c9c0SKan Liang u32 bar;
1527fdb64822SKan Liang
1528fdb64822SKan Liang if (!pdev) {
1529fdb64822SKan Liang pr_warn("perf uncore: Cannot find matched IMC device.\n");
1530fdb64822SKan Liang return;
1531fdb64822SKan Liang }
1532fdb64822SKan Liang
1533efb0c9c0SKan Liang pci_read_config_dword(pdev, bar_offset, &bar);
1534efb0c9c0SKan Liang if (!(bar & BIT(0))) {
1535efb0c9c0SKan Liang pr_warn("perf uncore: BAR 0x%x is disabled. Failed to map %s counters.\n",
1536efb0c9c0SKan Liang bar_offset, type->name);
153717b8d847SXiongfeng Wang pci_dev_put(pdev);
1538fdb64822SKan Liang return;
1539fdb64822SKan Liang }
1540efb0c9c0SKan Liang bar &= ~BIT(0);
1541efb0c9c0SKan Liang addr = (resource_size_t)(bar + step * pmu->pmu_idx);
1542fdb64822SKan Liang
1543fdb64822SKan Liang #ifdef CONFIG_PHYS_ADDR_T_64BIT
1544efb0c9c0SKan Liang pci_read_config_dword(pdev, bar_offset + 4, &bar);
1545efb0c9c0SKan Liang addr |= ((resource_size_t)bar << 32);
1546fdb64822SKan Liang #endif
1547fdb64822SKan Liang
15485a4487f9SKan Liang addr += base_offset;
15491b94d31dSKan Liang box->io_addr = ioremap(addr, type->mmio_map_size);
15501b94d31dSKan Liang if (!box->io_addr)
15511b94d31dSKan Liang pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
155217b8d847SXiongfeng Wang
155317b8d847SXiongfeng Wang pci_dev_put(pdev);
1554fdb64822SKan Liang }
1555fdb64822SKan Liang
__uncore_imc_init_box(struct intel_uncore_box * box,unsigned int base_offset)1556efb0c9c0SKan Liang static void __uncore_imc_init_box(struct intel_uncore_box *box,
1557efb0c9c0SKan Liang unsigned int base_offset)
1558efb0c9c0SKan Liang {
1559efb0c9c0SKan Liang uncore_get_box_mmio_addr(box, base_offset,
1560efb0c9c0SKan Liang SNB_UNCORE_PCI_IMC_BAR_OFFSET,
1561efb0c9c0SKan Liang TGL_UNCORE_MMIO_IMC_MEM_OFFSET);
1562efb0c9c0SKan Liang }
1563efb0c9c0SKan Liang
tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box * box)15645a4487f9SKan Liang static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
15655a4487f9SKan Liang {
15665a4487f9SKan Liang __uncore_imc_init_box(box, 0);
15675a4487f9SKan Liang }
15685a4487f9SKan Liang
1569fdb64822SKan Liang static struct intel_uncore_ops tgl_uncore_imc_freerunning_ops = {
1570fdb64822SKan Liang .init_box = tgl_uncore_imc_freerunning_init_box,
1571fdb64822SKan Liang .exit_box = uncore_mmio_exit_box,
1572fdb64822SKan Liang .read_counter = uncore_mmio_read_counter,
1573fdb64822SKan Liang .hw_config = uncore_freerunning_hw_config,
1574fdb64822SKan Liang };
1575fdb64822SKan Liang
1576fdb64822SKan Liang static struct attribute *tgl_uncore_imc_formats_attr[] = {
1577fdb64822SKan Liang &format_attr_event.attr,
1578fdb64822SKan Liang &format_attr_umask.attr,
1579fdb64822SKan Liang NULL
1580fdb64822SKan Liang };
1581fdb64822SKan Liang
1582fdb64822SKan Liang static const struct attribute_group tgl_uncore_imc_format_group = {
1583fdb64822SKan Liang .name = "format",
1584fdb64822SKan Liang .attrs = tgl_uncore_imc_formats_attr,
1585fdb64822SKan Liang };
1586fdb64822SKan Liang
1587fdb64822SKan Liang static struct intel_uncore_type tgl_uncore_imc_free_running = {
1588fdb64822SKan Liang .name = "imc_free_running",
1589fdb64822SKan Liang .num_counters = 3,
1590fdb64822SKan Liang .num_boxes = 2,
1591fdb64822SKan Liang .num_freerunning_types = TGL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX,
15921b94d31dSKan Liang .mmio_map_size = TGL_UNCORE_PCI_IMC_MAP_SIZE,
1593fdb64822SKan Liang .freerunning = tgl_uncore_imc_freerunning,
1594fdb64822SKan Liang .ops = &tgl_uncore_imc_freerunning_ops,
1595fdb64822SKan Liang .event_descs = tgl_uncore_imc_events,
1596fdb64822SKan Liang .format_group = &tgl_uncore_imc_format_group,
1597fdb64822SKan Liang };
1598fdb64822SKan Liang
1599fdb64822SKan Liang static struct intel_uncore_type *tgl_mmio_uncores[] = {
1600fdb64822SKan Liang &tgl_uncore_imc_free_running,
1601fdb64822SKan Liang NULL
1602fdb64822SKan Liang };
1603fdb64822SKan Liang
tgl_l_uncore_mmio_init(void)1604fdb64822SKan Liang void tgl_l_uncore_mmio_init(void)
1605fdb64822SKan Liang {
1606fdb64822SKan Liang tgl_uncore_imc_free_running.freerunning = tgl_l_uncore_imc_freerunning;
1607fdb64822SKan Liang uncore_mmio_uncores = tgl_mmio_uncores;
1608fdb64822SKan Liang }
1609fdb64822SKan Liang
tgl_uncore_mmio_init(void)1610fdb64822SKan Liang void tgl_uncore_mmio_init(void)
1611fdb64822SKan Liang {
1612fdb64822SKan Liang uncore_mmio_uncores = tgl_mmio_uncores;
1613fdb64822SKan Liang }
1614fdb64822SKan Liang
1615fdb64822SKan Liang /* end of Tiger Lake MMIO uncore support */
16165a4487f9SKan Liang
16175a4487f9SKan Liang /* Alder Lake MMIO uncore support */
16185a4487f9SKan Liang #define ADL_UNCORE_IMC_BASE 0xd900
16195a4487f9SKan Liang #define ADL_UNCORE_IMC_MAP_SIZE 0x200
16205a4487f9SKan Liang #define ADL_UNCORE_IMC_CTR 0xe8
16215a4487f9SKan Liang #define ADL_UNCORE_IMC_CTRL 0xd0
16225a4487f9SKan Liang #define ADL_UNCORE_IMC_GLOBAL_CTL 0xc0
16235a4487f9SKan Liang #define ADL_UNCORE_IMC_BOX_CTL 0xc4
16245a4487f9SKan Liang #define ADL_UNCORE_IMC_FREERUNNING_BASE 0xd800
16255a4487f9SKan Liang #define ADL_UNCORE_IMC_FREERUNNING_MAP_SIZE 0x100
16265a4487f9SKan Liang
16275a4487f9SKan Liang #define ADL_UNCORE_IMC_CTL_FRZ (1 << 0)
16285a4487f9SKan Liang #define ADL_UNCORE_IMC_CTL_RST_CTRL (1 << 1)
16295a4487f9SKan Liang #define ADL_UNCORE_IMC_CTL_RST_CTRS (1 << 2)
16305a4487f9SKan Liang #define ADL_UNCORE_IMC_CTL_INT (ADL_UNCORE_IMC_CTL_RST_CTRL | \
16315a4487f9SKan Liang ADL_UNCORE_IMC_CTL_RST_CTRS)
16325a4487f9SKan Liang
adl_uncore_imc_init_box(struct intel_uncore_box * box)16335a4487f9SKan Liang static void adl_uncore_imc_init_box(struct intel_uncore_box *box)
16345a4487f9SKan Liang {
16355a4487f9SKan Liang __uncore_imc_init_box(box, ADL_UNCORE_IMC_BASE);
16365a4487f9SKan Liang
16375a4487f9SKan Liang /* The global control in MC1 can control both MCs. */
16385a4487f9SKan Liang if (box->io_addr && (box->pmu->pmu_idx == 1))
16395a4487f9SKan Liang writel(ADL_UNCORE_IMC_CTL_INT, box->io_addr + ADL_UNCORE_IMC_GLOBAL_CTL);
16405a4487f9SKan Liang }
16415a4487f9SKan Liang
adl_uncore_mmio_disable_box(struct intel_uncore_box * box)16425a4487f9SKan Liang static void adl_uncore_mmio_disable_box(struct intel_uncore_box *box)
16435a4487f9SKan Liang {
16445a4487f9SKan Liang if (!box->io_addr)
16455a4487f9SKan Liang return;
16465a4487f9SKan Liang
16475a4487f9SKan Liang writel(ADL_UNCORE_IMC_CTL_FRZ, box->io_addr + uncore_mmio_box_ctl(box));
16485a4487f9SKan Liang }
16495a4487f9SKan Liang
adl_uncore_mmio_enable_box(struct intel_uncore_box * box)16505a4487f9SKan Liang static void adl_uncore_mmio_enable_box(struct intel_uncore_box *box)
16515a4487f9SKan Liang {
16525a4487f9SKan Liang if (!box->io_addr)
16535a4487f9SKan Liang return;
16545a4487f9SKan Liang
16555a4487f9SKan Liang writel(0, box->io_addr + uncore_mmio_box_ctl(box));
16565a4487f9SKan Liang }
16575a4487f9SKan Liang
1658efb0c9c0SKan Liang #define MMIO_UNCORE_COMMON_OPS() \
1659efb0c9c0SKan Liang .exit_box = uncore_mmio_exit_box, \
1660efb0c9c0SKan Liang .disable_box = adl_uncore_mmio_disable_box, \
1661efb0c9c0SKan Liang .enable_box = adl_uncore_mmio_enable_box, \
1662efb0c9c0SKan Liang .disable_event = intel_generic_uncore_mmio_disable_event, \
1663efb0c9c0SKan Liang .enable_event = intel_generic_uncore_mmio_enable_event, \
1664efb0c9c0SKan Liang .read_counter = uncore_mmio_read_counter,
1665efb0c9c0SKan Liang
16665a4487f9SKan Liang static struct intel_uncore_ops adl_uncore_mmio_ops = {
16675a4487f9SKan Liang .init_box = adl_uncore_imc_init_box,
1668efb0c9c0SKan Liang MMIO_UNCORE_COMMON_OPS()
16695a4487f9SKan Liang };
16705a4487f9SKan Liang
16715a4487f9SKan Liang #define ADL_UNC_CTL_CHMASK_MASK 0x00000f00
16725a4487f9SKan Liang #define ADL_UNC_IMC_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \
16735a4487f9SKan Liang ADL_UNC_CTL_CHMASK_MASK | \
16745a4487f9SKan Liang SNB_UNC_CTL_EDGE_DET)
16755a4487f9SKan Liang
16765a4487f9SKan Liang static struct attribute *adl_uncore_imc_formats_attr[] = {
16775a4487f9SKan Liang &format_attr_event.attr,
16785a4487f9SKan Liang &format_attr_chmask.attr,
16795a4487f9SKan Liang &format_attr_edge.attr,
16805a4487f9SKan Liang NULL,
16815a4487f9SKan Liang };
16825a4487f9SKan Liang
16835a4487f9SKan Liang static const struct attribute_group adl_uncore_imc_format_group = {
16845a4487f9SKan Liang .name = "format",
16855a4487f9SKan Liang .attrs = adl_uncore_imc_formats_attr,
16865a4487f9SKan Liang };
16875a4487f9SKan Liang
16885a4487f9SKan Liang static struct intel_uncore_type adl_uncore_imc = {
16895a4487f9SKan Liang .name = "imc",
16905a4487f9SKan Liang .num_counters = 5,
16915a4487f9SKan Liang .num_boxes = 2,
16925a4487f9SKan Liang .perf_ctr_bits = 64,
16935a4487f9SKan Liang .perf_ctr = ADL_UNCORE_IMC_CTR,
16945a4487f9SKan Liang .event_ctl = ADL_UNCORE_IMC_CTRL,
16955a4487f9SKan Liang .event_mask = ADL_UNC_IMC_EVENT_MASK,
16965a4487f9SKan Liang .box_ctl = ADL_UNCORE_IMC_BOX_CTL,
16975a4487f9SKan Liang .mmio_offset = 0,
16985a4487f9SKan Liang .mmio_map_size = ADL_UNCORE_IMC_MAP_SIZE,
16995a4487f9SKan Liang .ops = &adl_uncore_mmio_ops,
17005a4487f9SKan Liang .format_group = &adl_uncore_imc_format_group,
17015a4487f9SKan Liang };
17025a4487f9SKan Liang
17035a4487f9SKan Liang enum perf_adl_uncore_imc_freerunning_types {
17045a4487f9SKan Liang ADL_MMIO_UNCORE_IMC_DATA_TOTAL,
17055a4487f9SKan Liang ADL_MMIO_UNCORE_IMC_DATA_READ,
17065a4487f9SKan Liang ADL_MMIO_UNCORE_IMC_DATA_WRITE,
17075a4487f9SKan Liang ADL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX
17085a4487f9SKan Liang };
17095a4487f9SKan Liang
17105a4487f9SKan Liang static struct freerunning_counters adl_uncore_imc_freerunning[] = {
17115a4487f9SKan Liang [ADL_MMIO_UNCORE_IMC_DATA_TOTAL] = { 0x40, 0x0, 0x0, 1, 64 },
17125a4487f9SKan Liang [ADL_MMIO_UNCORE_IMC_DATA_READ] = { 0x58, 0x0, 0x0, 1, 64 },
17135a4487f9SKan Liang [ADL_MMIO_UNCORE_IMC_DATA_WRITE] = { 0xA0, 0x0, 0x0, 1, 64 },
17145a4487f9SKan Liang };
17155a4487f9SKan Liang
adl_uncore_imc_freerunning_init_box(struct intel_uncore_box * box)17165a4487f9SKan Liang static void adl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
17175a4487f9SKan Liang {
17185a4487f9SKan Liang __uncore_imc_init_box(box, ADL_UNCORE_IMC_FREERUNNING_BASE);
17195a4487f9SKan Liang }
17205a4487f9SKan Liang
17215a4487f9SKan Liang static struct intel_uncore_ops adl_uncore_imc_freerunning_ops = {
17225a4487f9SKan Liang .init_box = adl_uncore_imc_freerunning_init_box,
17235a4487f9SKan Liang .exit_box = uncore_mmio_exit_box,
17245a4487f9SKan Liang .read_counter = uncore_mmio_read_counter,
17255a4487f9SKan Liang .hw_config = uncore_freerunning_hw_config,
17265a4487f9SKan Liang };
17275a4487f9SKan Liang
17285a4487f9SKan Liang static struct intel_uncore_type adl_uncore_imc_free_running = {
17295a4487f9SKan Liang .name = "imc_free_running",
17305a4487f9SKan Liang .num_counters = 3,
17315a4487f9SKan Liang .num_boxes = 2,
17325a4487f9SKan Liang .num_freerunning_types = ADL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX,
17335a4487f9SKan Liang .mmio_map_size = ADL_UNCORE_IMC_FREERUNNING_MAP_SIZE,
17345a4487f9SKan Liang .freerunning = adl_uncore_imc_freerunning,
17355a4487f9SKan Liang .ops = &adl_uncore_imc_freerunning_ops,
17365a4487f9SKan Liang .event_descs = tgl_uncore_imc_events,
17375a4487f9SKan Liang .format_group = &tgl_uncore_imc_format_group,
17385a4487f9SKan Liang };
17395a4487f9SKan Liang
17405a4487f9SKan Liang static struct intel_uncore_type *adl_mmio_uncores[] = {
17415a4487f9SKan Liang &adl_uncore_imc,
17425a4487f9SKan Liang &adl_uncore_imc_free_running,
17435a4487f9SKan Liang NULL
17445a4487f9SKan Liang };
17455a4487f9SKan Liang
adl_uncore_mmio_init(void)17465a4487f9SKan Liang void adl_uncore_mmio_init(void)
17475a4487f9SKan Liang {
17485a4487f9SKan Liang uncore_mmio_uncores = adl_mmio_uncores;
17495a4487f9SKan Liang }
17505a4487f9SKan Liang
17515a4487f9SKan Liang /* end of Alder Lake MMIO uncore support */
17529bd7dfe3SKan Liang
17539bd7dfe3SKan Liang /* Lunar Lake MMIO uncore support */
17549bd7dfe3SKan Liang #define LNL_UNCORE_PCI_SAFBAR_OFFSET 0x68
17559bd7dfe3SKan Liang #define LNL_UNCORE_MAP_SIZE 0x1000
17569bd7dfe3SKan Liang #define LNL_UNCORE_SNCU_BASE 0xE4B000
17579bd7dfe3SKan Liang #define LNL_UNCORE_SNCU_CTR 0x390
17589bd7dfe3SKan Liang #define LNL_UNCORE_SNCU_CTRL 0x398
17599bd7dfe3SKan Liang #define LNL_UNCORE_SNCU_BOX_CTL 0x380
17609bd7dfe3SKan Liang #define LNL_UNCORE_GLOBAL_CTL 0x700
17619bd7dfe3SKan Liang #define LNL_UNCORE_HBO_BASE 0xE54000
17629bd7dfe3SKan Liang #define LNL_UNCORE_HBO_OFFSET -4096
17639bd7dfe3SKan Liang #define LNL_UNCORE_HBO_CTR 0x570
17649bd7dfe3SKan Liang #define LNL_UNCORE_HBO_CTRL 0x550
17659bd7dfe3SKan Liang #define LNL_UNCORE_HBO_BOX_CTL 0x548
17669bd7dfe3SKan Liang
17679bd7dfe3SKan Liang #define LNL_UNC_CTL_THRESHOLD 0xff000000
17689bd7dfe3SKan Liang #define LNL_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \
17699bd7dfe3SKan Liang SNB_UNC_CTL_UMASK_MASK | \
17709bd7dfe3SKan Liang SNB_UNC_CTL_EDGE_DET | \
17719bd7dfe3SKan Liang SNB_UNC_CTL_INVERT | \
17729bd7dfe3SKan Liang LNL_UNC_CTL_THRESHOLD)
17739bd7dfe3SKan Liang
17749bd7dfe3SKan Liang static struct attribute *lnl_uncore_formats_attr[] = {
17759bd7dfe3SKan Liang &format_attr_event.attr,
17769bd7dfe3SKan Liang &format_attr_umask.attr,
17779bd7dfe3SKan Liang &format_attr_edge.attr,
17789bd7dfe3SKan Liang &format_attr_inv.attr,
17799bd7dfe3SKan Liang &format_attr_threshold2.attr,
17809bd7dfe3SKan Liang NULL
17819bd7dfe3SKan Liang };
17829bd7dfe3SKan Liang
17839bd7dfe3SKan Liang static const struct attribute_group lnl_uncore_format_group = {
17849bd7dfe3SKan Liang .name = "format",
17859bd7dfe3SKan Liang .attrs = lnl_uncore_formats_attr,
17869bd7dfe3SKan Liang };
17879bd7dfe3SKan Liang
lnl_uncore_hbo_init_box(struct intel_uncore_box * box)17889bd7dfe3SKan Liang static void lnl_uncore_hbo_init_box(struct intel_uncore_box *box)
17899bd7dfe3SKan Liang {
17909bd7dfe3SKan Liang uncore_get_box_mmio_addr(box, LNL_UNCORE_HBO_BASE,
17919bd7dfe3SKan Liang LNL_UNCORE_PCI_SAFBAR_OFFSET,
17929bd7dfe3SKan Liang LNL_UNCORE_HBO_OFFSET);
17939bd7dfe3SKan Liang }
17949bd7dfe3SKan Liang
17959bd7dfe3SKan Liang static struct intel_uncore_ops lnl_uncore_hbo_ops = {
17969bd7dfe3SKan Liang .init_box = lnl_uncore_hbo_init_box,
17979bd7dfe3SKan Liang MMIO_UNCORE_COMMON_OPS()
17989bd7dfe3SKan Liang };
17999bd7dfe3SKan Liang
18009bd7dfe3SKan Liang static struct intel_uncore_type lnl_uncore_hbo = {
18019bd7dfe3SKan Liang .name = "hbo",
18029bd7dfe3SKan Liang .num_counters = 4,
18039bd7dfe3SKan Liang .num_boxes = 2,
18049bd7dfe3SKan Liang .perf_ctr_bits = 64,
18059bd7dfe3SKan Liang .perf_ctr = LNL_UNCORE_HBO_CTR,
18069bd7dfe3SKan Liang .event_ctl = LNL_UNCORE_HBO_CTRL,
18079bd7dfe3SKan Liang .event_mask = LNL_UNC_RAW_EVENT_MASK,
18089bd7dfe3SKan Liang .box_ctl = LNL_UNCORE_HBO_BOX_CTL,
18099bd7dfe3SKan Liang .mmio_map_size = LNL_UNCORE_MAP_SIZE,
18109bd7dfe3SKan Liang .ops = &lnl_uncore_hbo_ops,
18119bd7dfe3SKan Liang .format_group = &lnl_uncore_format_group,
18129bd7dfe3SKan Liang };
18139bd7dfe3SKan Liang
lnl_uncore_sncu_init_box(struct intel_uncore_box * box)18149bd7dfe3SKan Liang static void lnl_uncore_sncu_init_box(struct intel_uncore_box *box)
18159bd7dfe3SKan Liang {
18169bd7dfe3SKan Liang uncore_get_box_mmio_addr(box, LNL_UNCORE_SNCU_BASE,
18179bd7dfe3SKan Liang LNL_UNCORE_PCI_SAFBAR_OFFSET,
18189bd7dfe3SKan Liang 0);
18199bd7dfe3SKan Liang
18209bd7dfe3SKan Liang if (box->io_addr)
18219bd7dfe3SKan Liang writel(ADL_UNCORE_IMC_CTL_INT, box->io_addr + LNL_UNCORE_GLOBAL_CTL);
18229bd7dfe3SKan Liang }
18239bd7dfe3SKan Liang
18249bd7dfe3SKan Liang static struct intel_uncore_ops lnl_uncore_sncu_ops = {
18259bd7dfe3SKan Liang .init_box = lnl_uncore_sncu_init_box,
18269bd7dfe3SKan Liang MMIO_UNCORE_COMMON_OPS()
18279bd7dfe3SKan Liang };
18289bd7dfe3SKan Liang
18299bd7dfe3SKan Liang static struct intel_uncore_type lnl_uncore_sncu = {
18309bd7dfe3SKan Liang .name = "sncu",
18319bd7dfe3SKan Liang .num_counters = 2,
18329bd7dfe3SKan Liang .num_boxes = 1,
18339bd7dfe3SKan Liang .perf_ctr_bits = 64,
18349bd7dfe3SKan Liang .perf_ctr = LNL_UNCORE_SNCU_CTR,
18359bd7dfe3SKan Liang .event_ctl = LNL_UNCORE_SNCU_CTRL,
18369bd7dfe3SKan Liang .event_mask = LNL_UNC_RAW_EVENT_MASK,
18379bd7dfe3SKan Liang .box_ctl = LNL_UNCORE_SNCU_BOX_CTL,
18389bd7dfe3SKan Liang .mmio_map_size = LNL_UNCORE_MAP_SIZE,
18399bd7dfe3SKan Liang .ops = &lnl_uncore_sncu_ops,
18409bd7dfe3SKan Liang .format_group = &lnl_uncore_format_group,
18419bd7dfe3SKan Liang };
18429bd7dfe3SKan Liang
18439bd7dfe3SKan Liang static struct intel_uncore_type *lnl_mmio_uncores[] = {
18449bd7dfe3SKan Liang &adl_uncore_imc,
18459bd7dfe3SKan Liang &lnl_uncore_hbo,
18469bd7dfe3SKan Liang &lnl_uncore_sncu,
18479ac57c45SZhenyu Wang &adl_uncore_imc_free_running,
18489bd7dfe3SKan Liang NULL
18499bd7dfe3SKan Liang };
18509bd7dfe3SKan Liang
lnl_uncore_mmio_init(void)18519bd7dfe3SKan Liang void lnl_uncore_mmio_init(void)
18529bd7dfe3SKan Liang {
18539bd7dfe3SKan Liang uncore_mmio_uncores = lnl_mmio_uncores;
18549bd7dfe3SKan Liang }
18559bd7dfe3SKan Liang
18569bd7dfe3SKan Liang /* end of Lunar Lake MMIO uncore support */
1857