Merge branch 'linus' into perf/core
[platform/adaptation/renesas_rcar/renesas_kernel.git] / arch / x86 / kernel / cpu / perf_event_intel_uncore.c
index 1fb6c72..34c11ae 100644 (file)
@@ -6,6 +6,8 @@ static struct intel_uncore_type **pci_uncores = empty_uncore;
 /* pci bus to socket mapping */
 static int pcibus_to_physid[256] = { [0 ... 255] = -1, };
 
+static struct pci_dev *extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
+
 static DEFINE_RAW_SPINLOCK(uncore_box_lock);
 
 /* mask of cpus that collect uncore events */
@@ -45,6 +47,24 @@ DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7");
 DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15");
 DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23");
 DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31");
+DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51");
+DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31");
+DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17");
+DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12");
+DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8");
+DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4");
+DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63");
+DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51");
+DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31");
+DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17");
+DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12");
+DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8");
+DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4");
+DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63");
 
 static u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event)
 {
@@ -281,7 +301,7 @@ static struct attribute *snbep_uncore_cbox_formats_attr[] = {
 };
 
 static struct attribute *snbep_uncore_pcu_formats_attr[] = {
-       &format_attr_event.attr,
+       &format_attr_event_ext.attr,
        &format_attr_occ_sel.attr,
        &format_attr_edge.attr,
        &format_attr_inv.attr,
@@ -301,6 +321,24 @@ static struct attribute *snbep_uncore_qpi_formats_attr[] = {
        &format_attr_edge.attr,
        &format_attr_inv.attr,
        &format_attr_thresh8.attr,
+       &format_attr_match_rds.attr,
+       &format_attr_match_rnid30.attr,
+       &format_attr_match_rnid4.attr,
+       &format_attr_match_dnid.attr,
+       &format_attr_match_mc.attr,
+       &format_attr_match_opc.attr,
+       &format_attr_match_vnw.attr,
+       &format_attr_match0.attr,
+       &format_attr_match1.attr,
+       &format_attr_mask_rds.attr,
+       &format_attr_mask_rnid30.attr,
+       &format_attr_mask_rnid4.attr,
+       &format_attr_mask_dnid.attr,
+       &format_attr_mask_mc.attr,
+       &format_attr_mask_opc.attr,
+       &format_attr_mask_vnw.attr,
+       &format_attr_mask0.attr,
+       &format_attr_mask1.attr,
        NULL,
 };
 
@@ -356,13 +394,16 @@ static struct intel_uncore_ops snbep_uncore_msr_ops = {
        SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
 };
 
+#define SNBEP_UNCORE_PCI_OPS_COMMON_INIT()                     \
+       .init_box       = snbep_uncore_pci_init_box,            \
+       .disable_box    = snbep_uncore_pci_disable_box,         \
+       .enable_box     = snbep_uncore_pci_enable_box,          \
+       .disable_event  = snbep_uncore_pci_disable_event,       \
+       .read_counter   = snbep_uncore_pci_read_counter
+
 static struct intel_uncore_ops snbep_uncore_pci_ops = {
-       .init_box       = snbep_uncore_pci_init_box,
-       .disable_box    = snbep_uncore_pci_disable_box,
-       .enable_box     = snbep_uncore_pci_enable_box,
-       .disable_event  = snbep_uncore_pci_disable_event,
-       .enable_event   = snbep_uncore_pci_enable_event,
-       .read_counter   = snbep_uncore_pci_read_counter,
+       SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
+       .enable_event   = snbep_uncore_pci_enable_event,        \
 };
 
 static struct event_constraint snbep_uncore_cbox_constraints[] = {
@@ -726,6 +767,61 @@ static struct intel_uncore_type *snbep_msr_uncores[] = {
        NULL,
 };
 
+enum {
+       SNBEP_PCI_QPI_PORT0_FILTER,
+       SNBEP_PCI_QPI_PORT1_FILTER,
+};
+
+static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+       struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+       if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) {
+               reg1->idx = 0;
+               reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0;
+               reg1->config = event->attr.config1;
+               reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0;
+               reg2->config = event->attr.config2;
+       }
+       return 0;
+}
+
+static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+       struct pci_dev *pdev = box->pci_dev;
+       struct hw_perf_event *hwc = &event->hw;
+       struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+       struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+       if (reg1->idx != EXTRA_REG_NONE) {
+               int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER;
+               struct pci_dev *filter_pdev = extra_pci_dev[box->phys_id][idx];
+               WARN_ON_ONCE(!filter_pdev);
+               if (filter_pdev) {
+                       pci_write_config_dword(filter_pdev, reg1->reg,
+                                               (u32)reg1->config);
+                       pci_write_config_dword(filter_pdev, reg1->reg + 4,
+                                               (u32)(reg1->config >> 32));
+                       pci_write_config_dword(filter_pdev, reg2->reg,
+                                               (u32)reg2->config);
+                       pci_write_config_dword(filter_pdev, reg2->reg + 4,
+                                               (u32)(reg2->config >> 32));
+               }
+       }
+
+       pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static struct intel_uncore_ops snbep_uncore_qpi_ops = {
+       SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
+       .enable_event           = snbep_qpi_enable_event,
+       .hw_config              = snbep_qpi_hw_config,
+       .get_constraint         = uncore_get_constraint,
+       .put_constraint         = uncore_put_constraint,
+};
+
 #define SNBEP_UNCORE_PCI_COMMON_INIT()                         \
        .perf_ctr       = SNBEP_PCI_PMON_CTR0,                  \
        .event_ctl      = SNBEP_PCI_PMON_CTL0,                  \
@@ -755,17 +851,18 @@ static struct intel_uncore_type snbep_uncore_imc = {
 };
 
 static struct intel_uncore_type snbep_uncore_qpi = {
-       .name           = "qpi",
-       .num_counters   = 4,
-       .num_boxes      = 2,
-       .perf_ctr_bits  = 48,
-       .perf_ctr       = SNBEP_PCI_PMON_CTR0,
-       .event_ctl      = SNBEP_PCI_PMON_CTL0,
-       .event_mask     = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
-       .box_ctl        = SNBEP_PCI_PMON_BOX_CTL,
-       .ops            = &snbep_uncore_pci_ops,
-       .event_descs    = snbep_uncore_qpi_events,
-       .format_group   = &snbep_uncore_qpi_format_group,
+       .name                   = "qpi",
+       .num_counters           = 4,
+       .num_boxes              = 2,
+       .perf_ctr_bits          = 48,
+       .perf_ctr               = SNBEP_PCI_PMON_CTR0,
+       .event_ctl              = SNBEP_PCI_PMON_CTL0,
+       .event_mask             = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
+       .box_ctl                = SNBEP_PCI_PMON_BOX_CTL,
+       .num_shared_regs        = 1,
+       .ops                    = &snbep_uncore_qpi_ops,
+       .event_descs            = snbep_uncore_qpi_events,
+       .format_group           = &snbep_uncore_qpi_format_group,
 };
 
 
@@ -807,43 +904,53 @@ static struct intel_uncore_type *snbep_pci_uncores[] = {
 static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = {
        { /* Home Agent */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA),
-               .driver_data = SNBEP_PCI_UNCORE_HA,
+               .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0),
        },
        { /* MC Channel 0 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0),
-               .driver_data = SNBEP_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0),
        },
        { /* MC Channel 1 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1),
-               .driver_data = SNBEP_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1),
        },
        { /* MC Channel 2 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2),
-               .driver_data = SNBEP_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2),
        },
        { /* MC Channel 3 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3),
-               .driver_data = SNBEP_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3),
        },
        { /* QPI Port 0 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0),
-               .driver_data = SNBEP_PCI_UNCORE_QPI,
+               .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0),
        },
        { /* QPI Port 1 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1),
-               .driver_data = SNBEP_PCI_UNCORE_QPI,
+               .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1),
        },
        { /* R2PCIe */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE),
-               .driver_data = SNBEP_PCI_UNCORE_R2PCIE,
+               .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0),
        },
        { /* R3QPI Link 0 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0),
-               .driver_data = SNBEP_PCI_UNCORE_R3QPI,
+               .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0),
        },
        { /* R3QPI Link 1 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1),
-               .driver_data = SNBEP_PCI_UNCORE_R3QPI,
+               .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1),
+       },
+       { /* QPI Port 0 filter  */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86),
+               .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+                                                  SNBEP_PCI_QPI_PORT0_FILTER),
+       },
+       { /* QPI Port 0 filter  */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96),
+               .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+                                                  SNBEP_PCI_QPI_PORT1_FILTER),
        },
        { /* end: all zeroes */ }
 };
@@ -1256,71 +1363,71 @@ static struct intel_uncore_type *ivt_pci_uncores[] = {
 static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = {
        { /* Home Agent 0 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30),
-               .driver_data = IVT_PCI_UNCORE_HA,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 0),
        },
        { /* Home Agent 1 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38),
-               .driver_data = IVT_PCI_UNCORE_HA,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 1),
        },
        { /* MC0 Channel 0 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4),
-               .driver_data = IVT_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 0),
        },
        { /* MC0 Channel 1 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5),
-               .driver_data = IVT_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 1),
        },
        { /* MC0 Channel 3 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0),
-               .driver_data = IVT_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 2),
        },
        { /* MC0 Channel 4 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1),
-               .driver_data = IVT_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 3),
        },
        { /* MC1 Channel 0 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4),
-               .driver_data = IVT_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 4),
        },
        { /* MC1 Channel 1 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5),
-               .driver_data = IVT_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 5),
        },
        { /* MC1 Channel 3 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0),
-               .driver_data = IVT_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 6),
        },
        { /* MC1 Channel 4 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1),
-               .driver_data = IVT_PCI_UNCORE_IMC,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7),
        },
        { /* QPI0 Port 0 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32),
-               .driver_data = IVT_PCI_UNCORE_QPI,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0),
        },
        { /* QPI0 Port 1 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33),
-               .driver_data = IVT_PCI_UNCORE_QPI,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 1),
        },
        { /* QPI1 Port 2 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a),
-               .driver_data = IVT_PCI_UNCORE_QPI,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 2),
        },
        { /* R2PCIe */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34),
-               .driver_data = IVT_PCI_UNCORE_R2PCIE,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R2PCIE, 0),
        },
        { /* R3QPI0 Link 0 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36),
-               .driver_data = IVT_PCI_UNCORE_R3QPI,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 0),
        },
        { /* R3QPI0 Link 1 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37),
-               .driver_data = IVT_PCI_UNCORE_R3QPI,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 1),
        },
        { /* R3QPI1 Link 2 */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e),
-               .driver_data = IVT_PCI_UNCORE_R3QPI,
+               .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 2),
        },
        { /* end: all zeroes */ }
 };
@@ -3167,16 +3274,24 @@ static bool pcidrv_registered;
 /*
  * add a pci uncore device
  */
-static int uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev)
+static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        struct intel_uncore_pmu *pmu;
        struct intel_uncore_box *box;
-       int i, phys_id;
+       struct intel_uncore_type *type;
+       int phys_id;
 
        phys_id = pcibus_to_physid[pdev->bus->number];
        if (phys_id < 0)
                return -ENODEV;
 
+       if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) {
+               extra_pci_dev[phys_id][UNCORE_PCI_DEV_IDX(id->driver_data)] = pdev;
+               pci_set_drvdata(pdev, NULL);
+               return 0;
+       }
+
+       type = pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)];
        box = uncore_alloc_box(type, 0);
        if (!box)
                return -ENOMEM;
@@ -3185,21 +3300,11 @@ static int uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev)
         * for performance monitoring unit with multiple boxes,
         * each box has a different function id.
         */
-       for (i = 0; i < type->num_boxes; i++) {
-               pmu = &type->pmus[i];
-               if (pmu->func_id == pdev->devfn)
-                       break;
-               if (pmu->func_id < 0) {
-                       pmu->func_id = pdev->devfn;
-                       break;
-               }
-               pmu = NULL;
-       }
-
-       if (!pmu) {
-               kfree(box);
-               return -EINVAL;
-       }
+       pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)];
+       if (pmu->func_id < 0)
+               pmu->func_id = pdev->devfn;
+       else
+               WARN_ON_ONCE(pmu->func_id != pdev->devfn);
 
        box->phys_id = phys_id;
        box->pci_dev = pdev;
@@ -3217,9 +3322,22 @@ static int uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev)
 static void uncore_pci_remove(struct pci_dev *pdev)
 {
        struct intel_uncore_box *box = pci_get_drvdata(pdev);
-       struct intel_uncore_pmu *pmu = box->pmu;
-       int cpu, phys_id = pcibus_to_physid[pdev->bus->number];
+       struct intel_uncore_pmu *pmu;
+       int i, cpu, phys_id = pcibus_to_physid[pdev->bus->number];
 
+       box = pci_get_drvdata(pdev);
+       if (!box) {
+               for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) {
+                       if (extra_pci_dev[phys_id][i] == pdev) {
+                               extra_pci_dev[phys_id][i] = NULL;
+                               break;
+                       }
+               }
+               WARN_ON_ONCE(i >= UNCORE_EXTRA_PCI_DEV_MAX);
+               return;
+       }
+
+       pmu = box->pmu;
        if (WARN_ON_ONCE(phys_id != box->phys_id))
                return;
 
@@ -3240,12 +3358,6 @@ static void uncore_pci_remove(struct pci_dev *pdev)
        kfree(box);
 }
 
-static int uncore_pci_probe(struct pci_dev *pdev,
-                           const struct pci_device_id *id)
-{
-       return uncore_pci_add(pci_uncores[id->driver_data], pdev);
-}
-
 static int __init uncore_pci_init(void)
 {
        int ret;