diff options
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_uncore.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 6da399943ac6..29c248799ced 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
@@ -997,6 +997,20 @@ static int snbep_pci2phy_map_init(int devid) | |||
997 | } | 997 | } |
998 | } | 998 | } |
999 | 999 | ||
1000 | if (!err) { | ||
1001 | /* | ||
1002 | * For PCI bus with no UBOX device, find the next bus | ||
1003 | * that has UBOX device and use its mapping. | ||
1004 | */ | ||
1005 | i = -1; | ||
1006 | for (bus = 255; bus >= 0; bus--) { | ||
1007 | if (pcibus_to_physid[bus] >= 0) | ||
1008 | i = pcibus_to_physid[bus]; | ||
1009 | else | ||
1010 | pcibus_to_physid[bus] = i; | ||
1011 | } | ||
1012 | } | ||
1013 | |||
1000 | if (ubox_dev) | 1014 | if (ubox_dev) |
1001 | pci_dev_put(ubox_dev); | 1015 | pci_dev_put(ubox_dev); |
1002 | 1016 | ||
@@ -1330,6 +1344,59 @@ static struct intel_uncore_type ivt_uncore_imc = { | |||
1330 | IVT_UNCORE_PCI_COMMON_INIT(), | 1344 | IVT_UNCORE_PCI_COMMON_INIT(), |
1331 | }; | 1345 | }; |
1332 | 1346 | ||
1347 | /* registers in IRP boxes are not properly aligned */ | ||
1348 | static unsigned ivt_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4}; | ||
1349 | static unsigned ivt_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0}; | ||
1350 | |||
1351 | static void ivt_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
1352 | { | ||
1353 | struct pci_dev *pdev = box->pci_dev; | ||
1354 | struct hw_perf_event *hwc = &event->hw; | ||
1355 | |||
1356 | pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], | ||
1357 | hwc->config | SNBEP_PMON_CTL_EN); | ||
1358 | } | ||
1359 | |||
1360 | static void ivt_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
1361 | { | ||
1362 | struct pci_dev *pdev = box->pci_dev; | ||
1363 | struct hw_perf_event *hwc = &event->hw; | ||
1364 | |||
1365 | pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], hwc->config); | ||
1366 | } | ||
1367 | |||
1368 | static u64 ivt_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event) | ||
1369 | { | ||
1370 | struct pci_dev *pdev = box->pci_dev; | ||
1371 | struct hw_perf_event *hwc = &event->hw; | ||
1372 | u64 count = 0; | ||
1373 | |||
1374 | pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx], (u32 *)&count); | ||
1375 | pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1); | ||
1376 | |||
1377 | return count; | ||
1378 | } | ||
1379 | |||
1380 | static struct intel_uncore_ops ivt_uncore_irp_ops = { | ||
1381 | .init_box = ivt_uncore_pci_init_box, | ||
1382 | .disable_box = snbep_uncore_pci_disable_box, | ||
1383 | .enable_box = snbep_uncore_pci_enable_box, | ||
1384 | .disable_event = ivt_uncore_irp_disable_event, | ||
1385 | .enable_event = ivt_uncore_irp_enable_event, | ||
1386 | .read_counter = ivt_uncore_irp_read_counter, | ||
1387 | }; | ||
1388 | |||
1389 | static struct intel_uncore_type ivt_uncore_irp = { | ||
1390 | .name = "irp", | ||
1391 | .num_counters = 4, | ||
1392 | .num_boxes = 1, | ||
1393 | .perf_ctr_bits = 48, | ||
1394 | .event_mask = IVT_PMON_RAW_EVENT_MASK, | ||
1395 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, | ||
1396 | .ops = &ivt_uncore_irp_ops, | ||
1397 | .format_group = &ivt_uncore_format_group, | ||
1398 | }; | ||
1399 | |||
1333 | static struct intel_uncore_ops ivt_uncore_qpi_ops = { | 1400 | static struct intel_uncore_ops ivt_uncore_qpi_ops = { |
1334 | .init_box = ivt_uncore_pci_init_box, | 1401 | .init_box = ivt_uncore_pci_init_box, |
1335 | .disable_box = snbep_uncore_pci_disable_box, | 1402 | .disable_box = snbep_uncore_pci_disable_box, |
@@ -1377,6 +1444,7 @@ static struct intel_uncore_type ivt_uncore_r3qpi = { | |||
1377 | enum { | 1444 | enum { |
1378 | IVT_PCI_UNCORE_HA, | 1445 | IVT_PCI_UNCORE_HA, |
1379 | IVT_PCI_UNCORE_IMC, | 1446 | IVT_PCI_UNCORE_IMC, |
1447 | IVT_PCI_UNCORE_IRP, | ||
1380 | IVT_PCI_UNCORE_QPI, | 1448 | IVT_PCI_UNCORE_QPI, |
1381 | IVT_PCI_UNCORE_R2PCIE, | 1449 | IVT_PCI_UNCORE_R2PCIE, |
1382 | IVT_PCI_UNCORE_R3QPI, | 1450 | IVT_PCI_UNCORE_R3QPI, |
@@ -1385,6 +1453,7 @@ enum { | |||
1385 | static struct intel_uncore_type *ivt_pci_uncores[] = { | 1453 | static struct intel_uncore_type *ivt_pci_uncores[] = { |
1386 | [IVT_PCI_UNCORE_HA] = &ivt_uncore_ha, | 1454 | [IVT_PCI_UNCORE_HA] = &ivt_uncore_ha, |
1387 | [IVT_PCI_UNCORE_IMC] = &ivt_uncore_imc, | 1455 | [IVT_PCI_UNCORE_IMC] = &ivt_uncore_imc, |
1456 | [IVT_PCI_UNCORE_IRP] = &ivt_uncore_irp, | ||
1388 | [IVT_PCI_UNCORE_QPI] = &ivt_uncore_qpi, | 1457 | [IVT_PCI_UNCORE_QPI] = &ivt_uncore_qpi, |
1389 | [IVT_PCI_UNCORE_R2PCIE] = &ivt_uncore_r2pcie, | 1458 | [IVT_PCI_UNCORE_R2PCIE] = &ivt_uncore_r2pcie, |
1390 | [IVT_PCI_UNCORE_R3QPI] = &ivt_uncore_r3qpi, | 1459 | [IVT_PCI_UNCORE_R3QPI] = &ivt_uncore_r3qpi, |
@@ -1432,6 +1501,10 @@ static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { | |||
1432 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1), | 1501 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1), |
1433 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7), | 1502 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7), |
1434 | }, | 1503 | }, |
1504 | { /* IRP */ | ||
1505 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39), | ||
1506 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IRP, 0), | ||
1507 | }, | ||
1435 | { /* QPI0 Port 0 */ | 1508 | { /* QPI0 Port 0 */ |
1436 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32), | 1509 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32), |
1437 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0), | 1510 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0), |