aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2013-10-31 01:36:55 -0400
committerIngo Molnar <mingo@kernel.org>2013-11-06 06:34:31 -0500
commitf891d8cfb8372eb9cfe9d0d4ca61c75bafeaae37 (patch)
treeae3b266e611589af98fddb11b5c8d074a6a657c5 /arch
parentd1e8f4a8365d16fd179cb8cad5b4d20aafd0a695 (diff)
perf/x86/intel: Add Ivy Bridge-EP uncore IRP box support
Unlike other uncore boxes, IRP boxes live in PCI buses with no UBOX device. For PCI bus without UBOX device, we find the next bus that has UBOX device and use its 'bus to socket' mapping. Besides the counter/control registers in IRP boxes are not properly aligned. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Cc: eranian@google.com Cc: "Yan Zheng" <zheng.z.yan@intel.com> Link: http://lkml.kernel.org/r/1383197815-17706-2-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.c73
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 */
1348static unsigned ivt_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4};
1349static unsigned ivt_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0};
1350
1351static 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
1360static 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
1368static 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
1380static 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
1389static 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
1333static struct intel_uncore_ops ivt_uncore_qpi_ops = { 1400static 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 = {
1377enum { 1444enum {
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 {
1385static struct intel_uncore_type *ivt_pci_uncores[] = { 1453static 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),