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>
This commit is contained in:
Родитель
d1e8f4a836
Коммит
f891d8cfb8
|
@ -997,6 +997,20 @@ static int snbep_pci2phy_map_init(int devid)
|
|||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
/*
|
||||
* For PCI bus with no UBOX device, find the next bus
|
||||
* that has UBOX device and use its mapping.
|
||||
*/
|
||||
i = -1;
|
||||
for (bus = 255; bus >= 0; bus--) {
|
||||
if (pcibus_to_physid[bus] >= 0)
|
||||
i = pcibus_to_physid[bus];
|
||||
else
|
||||
pcibus_to_physid[bus] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (ubox_dev)
|
||||
pci_dev_put(ubox_dev);
|
||||
|
||||
|
@ -1330,6 +1344,59 @@ static struct intel_uncore_type ivt_uncore_imc = {
|
|||
IVT_UNCORE_PCI_COMMON_INIT(),
|
||||
};
|
||||
|
||||
/* registers in IRP boxes are not properly aligned */
|
||||
static unsigned ivt_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4};
|
||||
static unsigned ivt_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0};
|
||||
|
||||
static void ivt_uncore_irp_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;
|
||||
|
||||
pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx],
|
||||
hwc->config | SNBEP_PMON_CTL_EN);
|
||||
}
|
||||
|
||||
static void ivt_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event)
|
||||
{
|
||||
struct pci_dev *pdev = box->pci_dev;
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
|
||||
pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], hwc->config);
|
||||
}
|
||||
|
||||
static u64 ivt_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
|
||||
{
|
||||
struct pci_dev *pdev = box->pci_dev;
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
u64 count = 0;
|
||||
|
||||
pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
|
||||
pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct intel_uncore_ops ivt_uncore_irp_ops = {
|
||||
.init_box = ivt_uncore_pci_init_box,
|
||||
.disable_box = snbep_uncore_pci_disable_box,
|
||||
.enable_box = snbep_uncore_pci_enable_box,
|
||||
.disable_event = ivt_uncore_irp_disable_event,
|
||||
.enable_event = ivt_uncore_irp_enable_event,
|
||||
.read_counter = ivt_uncore_irp_read_counter,
|
||||
};
|
||||
|
||||
static struct intel_uncore_type ivt_uncore_irp = {
|
||||
.name = "irp",
|
||||
.num_counters = 4,
|
||||
.num_boxes = 1,
|
||||
.perf_ctr_bits = 48,
|
||||
.event_mask = IVT_PMON_RAW_EVENT_MASK,
|
||||
.box_ctl = SNBEP_PCI_PMON_BOX_CTL,
|
||||
.ops = &ivt_uncore_irp_ops,
|
||||
.format_group = &ivt_uncore_format_group,
|
||||
};
|
||||
|
||||
static struct intel_uncore_ops ivt_uncore_qpi_ops = {
|
||||
.init_box = ivt_uncore_pci_init_box,
|
||||
.disable_box = snbep_uncore_pci_disable_box,
|
||||
|
@ -1377,6 +1444,7 @@ static struct intel_uncore_type ivt_uncore_r3qpi = {
|
|||
enum {
|
||||
IVT_PCI_UNCORE_HA,
|
||||
IVT_PCI_UNCORE_IMC,
|
||||
IVT_PCI_UNCORE_IRP,
|
||||
IVT_PCI_UNCORE_QPI,
|
||||
IVT_PCI_UNCORE_R2PCIE,
|
||||
IVT_PCI_UNCORE_R3QPI,
|
||||
|
@ -1385,6 +1453,7 @@ enum {
|
|||
static struct intel_uncore_type *ivt_pci_uncores[] = {
|
||||
[IVT_PCI_UNCORE_HA] = &ivt_uncore_ha,
|
||||
[IVT_PCI_UNCORE_IMC] = &ivt_uncore_imc,
|
||||
[IVT_PCI_UNCORE_IRP] = &ivt_uncore_irp,
|
||||
[IVT_PCI_UNCORE_QPI] = &ivt_uncore_qpi,
|
||||
[IVT_PCI_UNCORE_R2PCIE] = &ivt_uncore_r2pcie,
|
||||
[IVT_PCI_UNCORE_R3QPI] = &ivt_uncore_r3qpi,
|
||||
|
@ -1432,6 +1501,10 @@ static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = {
|
|||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1),
|
||||
.driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7),
|
||||
},
|
||||
{ /* IRP */
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39),
|
||||
.driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IRP, 0),
|
||||
},
|
||||
{ /* QPI0 Port 0 */
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32),
|
||||
.driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0),
|
||||
|
|
Загрузка…
Ссылка в новой задаче