Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf/x86: Add Intel Tiger Lake uncore support

For MSR type of uncore units, there is no difference between Ice Lake
and Tiger Lake. Share the same code with Ice Lake.

Tiger Lake has two MCs. Both of them are located at 0:0:0. The BAR
offset is still 0x48. The offset of the two MCs is 0x10000.
Each MC has three counters to count every read/write/total issued by the
Memory Controller to DRAM. The counters can be accessed by MMIO.
They are free-running counters.

The offset of counters are different for TIGERLAKE_L and TIGERLAKE.
Add separated mmio_init() functions.

Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Link: https://lkml.kernel.org/r/20200206161527.3529-1-kan.liang@linux.intel.com

authored by

Kan Liang and committed by
Ingo Molnar
fdb64822 db278b90

+173
+12
arch/x86/events/intel/uncore.c
··· 1470 1470 .pci_init = skl_uncore_pci_init, 1471 1471 }; 1472 1472 1473 + static const struct intel_uncore_init_fun tgl_uncore_init __initconst = { 1474 + .cpu_init = icl_uncore_cpu_init, 1475 + .mmio_init = tgl_uncore_mmio_init, 1476 + }; 1477 + 1478 + static const struct intel_uncore_init_fun tgl_l_uncore_init __initconst = { 1479 + .cpu_init = icl_uncore_cpu_init, 1480 + .mmio_init = tgl_l_uncore_mmio_init, 1481 + }; 1482 + 1473 1483 static const struct intel_uncore_init_fun snr_uncore_init __initconst = { 1474 1484 .cpu_init = snr_uncore_cpu_init, 1475 1485 .pci_init = snr_uncore_pci_init, ··· 1515 1505 X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_L, icl_uncore_init), 1516 1506 X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_NNPI, icl_uncore_init), 1517 1507 X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE, icl_uncore_init), 1508 + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_TIGERLAKE_L, tgl_l_uncore_init), 1509 + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_TIGERLAKE, tgl_uncore_init), 1518 1510 X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ATOM_TREMONT_D, snr_uncore_init), 1519 1511 {}, 1520 1512 };
+2
arch/x86/events/intel/uncore.h
··· 527 527 void nhm_uncore_cpu_init(void); 528 528 void skl_uncore_cpu_init(void); 529 529 void icl_uncore_cpu_init(void); 530 + void tgl_uncore_mmio_init(void); 531 + void tgl_l_uncore_mmio_init(void); 530 532 int snb_pci2phy_map_init(int devid); 531 533 532 534 /* uncore_snbep.c */
+159
arch/x86/events/intel/uncore_snb.c
··· 44 44 #define PCI_DEVICE_ID_INTEL_WHL_UD_IMC 0x3e35 45 45 #define PCI_DEVICE_ID_INTEL_ICL_U_IMC 0x8a02 46 46 #define PCI_DEVICE_ID_INTEL_ICL_U2_IMC 0x8a12 47 + #define PCI_DEVICE_ID_INTEL_TGL_U1_IMC 0x9a02 48 + #define PCI_DEVICE_ID_INTEL_TGL_U2_IMC 0x9a04 49 + #define PCI_DEVICE_ID_INTEL_TGL_U3_IMC 0x9a12 50 + #define PCI_DEVICE_ID_INTEL_TGL_U4_IMC 0x9a14 51 + #define PCI_DEVICE_ID_INTEL_TGL_H_IMC 0x9a36 47 52 48 53 49 54 /* SNB event control */ ··· 1007 1002 } 1008 1003 1009 1004 /* end of Nehalem uncore support */ 1005 + 1006 + /* Tiger Lake MMIO uncore support */ 1007 + 1008 + static const struct pci_device_id tgl_uncore_pci_ids[] = { 1009 + { /* IMC */ 1010 + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGL_U1_IMC), 1011 + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), 1012 + }, 1013 + { /* IMC */ 1014 + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGL_U2_IMC), 1015 + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), 1016 + }, 1017 + { /* IMC */ 1018 + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGL_U3_IMC), 1019 + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), 1020 + }, 1021 + { /* IMC */ 1022 + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGL_U4_IMC), 1023 + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), 1024 + }, 1025 + { /* IMC */ 1026 + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGL_H_IMC), 1027 + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), 1028 + }, 1029 + { /* end: all zeroes */ } 1030 + }; 1031 + 1032 + enum perf_tgl_uncore_imc_freerunning_types { 1033 + TGL_MMIO_UNCORE_IMC_DATA_TOTAL, 1034 + TGL_MMIO_UNCORE_IMC_DATA_READ, 1035 + TGL_MMIO_UNCORE_IMC_DATA_WRITE, 1036 + TGL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX 1037 + }; 1038 + 1039 + static struct freerunning_counters tgl_l_uncore_imc_freerunning[] = { 1040 + [TGL_MMIO_UNCORE_IMC_DATA_TOTAL] = { 0x5040, 0x0, 0x0, 1, 64 }, 1041 + [TGL_MMIO_UNCORE_IMC_DATA_READ] = { 0x5058, 0x0, 0x0, 1, 64 }, 1042 + [TGL_MMIO_UNCORE_IMC_DATA_WRITE] = { 0x50A0, 0x0, 0x0, 1, 64 }, 1043 + }; 1044 + 1045 + static struct freerunning_counters tgl_uncore_imc_freerunning[] = { 1046 + [TGL_MMIO_UNCORE_IMC_DATA_TOTAL] = { 0xd840, 0x0, 0x0, 1, 64 }, 1047 + [TGL_MMIO_UNCORE_IMC_DATA_READ] = { 0xd858, 0x0, 0x0, 1, 64 }, 1048 + [TGL_MMIO_UNCORE_IMC_DATA_WRITE] = { 0xd8A0, 0x0, 0x0, 1, 64 }, 1049 + }; 1050 + 1051 + static struct uncore_event_desc tgl_uncore_imc_events[] = { 1052 + INTEL_UNCORE_EVENT_DESC(data_total, "event=0xff,umask=0x10"), 1053 + INTEL_UNCORE_EVENT_DESC(data_total.scale, "6.103515625e-5"), 1054 + INTEL_UNCORE_EVENT_DESC(data_total.unit, "MiB"), 1055 + 1056 + INTEL_UNCORE_EVENT_DESC(data_read, "event=0xff,umask=0x20"), 1057 + INTEL_UNCORE_EVENT_DESC(data_read.scale, "6.103515625e-5"), 1058 + INTEL_UNCORE_EVENT_DESC(data_read.unit, "MiB"), 1059 + 1060 + INTEL_UNCORE_EVENT_DESC(data_write, "event=0xff,umask=0x30"), 1061 + INTEL_UNCORE_EVENT_DESC(data_write.scale, "6.103515625e-5"), 1062 + INTEL_UNCORE_EVENT_DESC(data_write.unit, "MiB"), 1063 + 1064 + { /* end: all zeroes */ } 1065 + }; 1066 + 1067 + static struct pci_dev *tgl_uncore_get_mc_dev(void) 1068 + { 1069 + const struct pci_device_id *ids = tgl_uncore_pci_ids; 1070 + struct pci_dev *mc_dev = NULL; 1071 + 1072 + while (ids && ids->vendor) { 1073 + mc_dev = pci_get_device(PCI_VENDOR_ID_INTEL, ids->device, NULL); 1074 + if (mc_dev) 1075 + return mc_dev; 1076 + ids++; 1077 + } 1078 + 1079 + return mc_dev; 1080 + } 1081 + 1082 + #define TGL_UNCORE_MMIO_IMC_MEM_OFFSET 0x10000 1083 + 1084 + static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box) 1085 + { 1086 + struct pci_dev *pdev = tgl_uncore_get_mc_dev(); 1087 + struct intel_uncore_pmu *pmu = box->pmu; 1088 + resource_size_t addr; 1089 + u32 mch_bar; 1090 + 1091 + if (!pdev) { 1092 + pr_warn("perf uncore: Cannot find matched IMC device.\n"); 1093 + return; 1094 + } 1095 + 1096 + pci_read_config_dword(pdev, SNB_UNCORE_PCI_IMC_BAR_OFFSET, &mch_bar); 1097 + /* MCHBAR is disabled */ 1098 + if (!(mch_bar & BIT(0))) { 1099 + pr_warn("perf uncore: MCHBAR is disabled. Failed to map IMC free-running counters.\n"); 1100 + return; 1101 + } 1102 + mch_bar &= ~BIT(0); 1103 + addr = (resource_size_t)(mch_bar + TGL_UNCORE_MMIO_IMC_MEM_OFFSET * pmu->pmu_idx); 1104 + 1105 + #ifdef CONFIG_PHYS_ADDR_T_64BIT 1106 + pci_read_config_dword(pdev, SNB_UNCORE_PCI_IMC_BAR_OFFSET + 4, &mch_bar); 1107 + addr |= ((resource_size_t)mch_bar << 32); 1108 + #endif 1109 + 1110 + box->io_addr = ioremap(addr, SNB_UNCORE_PCI_IMC_MAP_SIZE); 1111 + } 1112 + 1113 + static struct intel_uncore_ops tgl_uncore_imc_freerunning_ops = { 1114 + .init_box = tgl_uncore_imc_freerunning_init_box, 1115 + .exit_box = uncore_mmio_exit_box, 1116 + .read_counter = uncore_mmio_read_counter, 1117 + .hw_config = uncore_freerunning_hw_config, 1118 + }; 1119 + 1120 + static struct attribute *tgl_uncore_imc_formats_attr[] = { 1121 + &format_attr_event.attr, 1122 + &format_attr_umask.attr, 1123 + NULL 1124 + }; 1125 + 1126 + static const struct attribute_group tgl_uncore_imc_format_group = { 1127 + .name = "format", 1128 + .attrs = tgl_uncore_imc_formats_attr, 1129 + }; 1130 + 1131 + static struct intel_uncore_type tgl_uncore_imc_free_running = { 1132 + .name = "imc_free_running", 1133 + .num_counters = 3, 1134 + .num_boxes = 2, 1135 + .num_freerunning_types = TGL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX, 1136 + .freerunning = tgl_uncore_imc_freerunning, 1137 + .ops = &tgl_uncore_imc_freerunning_ops, 1138 + .event_descs = tgl_uncore_imc_events, 1139 + .format_group = &tgl_uncore_imc_format_group, 1140 + }; 1141 + 1142 + static struct intel_uncore_type *tgl_mmio_uncores[] = { 1143 + &tgl_uncore_imc_free_running, 1144 + NULL 1145 + }; 1146 + 1147 + void tgl_l_uncore_mmio_init(void) 1148 + { 1149 + tgl_uncore_imc_free_running.freerunning = tgl_l_uncore_imc_freerunning; 1150 + uncore_mmio_uncores = tgl_mmio_uncores; 1151 + } 1152 + 1153 + void tgl_uncore_mmio_init(void) 1154 + { 1155 + uncore_mmio_uncores = tgl_mmio_uncores; 1156 + } 1157 + 1158 + /* end of Tiger Lake MMIO uncore support */