aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephane Eranian <eranian@google.com>2014-09-17 05:06:16 -0400
committerIngo Molnar <mingo@kernel.org>2014-09-24 08:48:25 -0400
commit521e8bac67a71a6544274f39d5c61473e0e54ac0 (patch)
treec5612d551c1cdc9423cceb6a5ea9f39331e63c32
parentb10fc1c3e30c44033d1cb1d2900cc2ab06dff342 (diff)
perf/x86/intel/uncore: Update support for client uncore IMC PMU
This patch restructures the memory controller (IMC) uncore PMU support for client SNB/IVB/HSW processors. The main change is that it can now cope with more than one PCI device ID per processor model. There are many flavors of memory controllers for each processor. They have different PCI device ID, yet they behave the same w.r.t. the memory controller PMU that we are interested in. The patch now supports two distinct memory controllers for IVB processors: one for mobile, one for desktop. Signed-off-by: Stephane Eranian <eranian@google.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: http://lkml.kernel.org/r/20140917090616.GA11281@quad Cc: ak@linux.intel.com Cc: kan.liang@intel.com Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c69
-rw-r--r--include/linux/pci_ids.h1
2 files changed, 52 insertions, 18 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c
index e0e934c8ee77..3001015b755c 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c
@@ -460,6 +460,10 @@ static const struct pci_device_id ivb_uncore_pci_ids[] = {
460 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_IMC), 460 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_IMC),
461 .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), 461 .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
462 }, 462 },
463 { /* IMC */
464 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_E3_IMC),
465 .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
466 },
463 { /* end: all zeroes */ }, 467 { /* end: all zeroes */ },
464}; 468};
465 469
@@ -486,34 +490,63 @@ static struct pci_driver hsw_uncore_pci_driver = {
486 .id_table = hsw_uncore_pci_ids, 490 .id_table = hsw_uncore_pci_ids,
487}; 491};
488 492
489int snb_uncore_pci_init(void) 493struct imc_uncore_pci_dev {
494 __u32 pci_id;
495 struct pci_driver *driver;
496};
497#define IMC_DEV(a, d) \
498 { .pci_id = PCI_DEVICE_ID_INTEL_##a, .driver = (d) }
499
500static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = {
501 IMC_DEV(SNB_IMC, &snb_uncore_pci_driver),
502 IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver), /* 3rd Gen Core processor */
503 IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */
504 IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */
505 { /* end marker */ }
506};
507
508
509#define for_each_imc_pci_id(x, t) \
510 for (x = (t); (x)->pci_id; x++)
511
512static struct pci_driver *imc_uncore_find_dev(void)
490{ 513{
491 int ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_SNB_IMC); 514 const struct imc_uncore_pci_dev *p;
492 if (ret) 515 int ret;
493 return ret; 516
494 uncore_pci_uncores = snb_pci_uncores; 517 for_each_imc_pci_id(p, desktop_imc_pci_ids) {
495 uncore_pci_driver = &snb_uncore_pci_driver; 518 ret = snb_pci2phy_map_init(p->pci_id);
496 return 0; 519 if (ret == 0)
520 return p->driver;
521 }
522 return NULL;
497} 523}
498 524
499int ivb_uncore_pci_init(void) 525static int imc_uncore_pci_init(void)
500{ 526{
501 int ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_IVB_IMC); 527 struct pci_driver *imc_drv = imc_uncore_find_dev();
502 if (ret) 528
503 return ret; 529 if (!imc_drv)
530 return -ENODEV;
531
504 uncore_pci_uncores = snb_pci_uncores; 532 uncore_pci_uncores = snb_pci_uncores;
505 uncore_pci_driver = &ivb_uncore_pci_driver; 533 uncore_pci_driver = imc_drv;
534
506 return 0; 535 return 0;
507} 536}
508 537
538int snb_uncore_pci_init(void)
539{
540 return imc_uncore_pci_init();
541}
542
543int ivb_uncore_pci_init(void)
544{
545 return imc_uncore_pci_init();
546}
509int hsw_uncore_pci_init(void) 547int hsw_uncore_pci_init(void)
510{ 548{
511 int ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_HSW_IMC); 549 return imc_uncore_pci_init();
512 if (ret)
513 return ret;
514 uncore_pci_uncores = snb_pci_uncores;
515 uncore_pci_driver = &hsw_uncore_pci_driver;
516 return 0;
517} 550}
518 551
519/* end of Sandy Bridge uncore support */ 552/* end of Sandy Bridge uncore support */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 6ed0bb73a864..3102b7e3b460 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2536,6 +2536,7 @@
2536#define PCI_DEVICE_ID_INTEL_EESSC 0x0008 2536#define PCI_DEVICE_ID_INTEL_EESSC 0x0008
2537#define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100 2537#define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100
2538#define PCI_DEVICE_ID_INTEL_IVB_IMC 0x0154 2538#define PCI_DEVICE_ID_INTEL_IVB_IMC 0x0154
2539#define PCI_DEVICE_ID_INTEL_IVB_E3_IMC 0x0150
2539#define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00 2540#define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00
2540#define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320 2541#define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320
2541#define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321 2542#define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321