Skip to content

Commit 5a4487f

Browse files
Kan LiangPeter Zijlstra
authored andcommitted
perf/x86/intel/uncore: Add IMC uncore support for ADL
Current ADL uncore code only supports the legacy IMC (memory controller) free-running counters. Besides the free-running counters, ADL also supports several general purpose-counters. The general-purpose counters can also be accessed via MMIO but in a different location. Factor out __uncore_imc_init_box() with offset as a parameter. The function can be shared between ADL and TGL. The event format and the layout of the control registers are a little bit different from other uncore counters. The intel_generic_uncore_mmio_enable_event() can be shared with client IMC uncore. Expose the function. Add more PCI IDs for ADL machines. Fixes: 772ed05 ("perf/x86/intel/uncore: Add Alder Lake support") Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/1642111554-118524-1-git-send-email-kan.liang@linux.intel.com
1 parent 6b19788 commit 5a4487f

File tree

5 files changed

+220
-5
lines changed

5 files changed

+220
-5
lines changed

arch/x86/events/intel/uncore.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1762,7 +1762,7 @@ static const struct intel_uncore_init_fun rkl_uncore_init __initconst = {
17621762

17631763
static const struct intel_uncore_init_fun adl_uncore_init __initconst = {
17641764
.cpu_init = adl_uncore_cpu_init,
1765-
.mmio_init = tgl_uncore_mmio_init,
1765+
.mmio_init = adl_uncore_mmio_init,
17661766
};
17671767

17681768
static const struct intel_uncore_init_fun icx_uncore_init __initconst = {

arch/x86/events/intel/uncore.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,10 +584,11 @@ void snb_uncore_cpu_init(void);
584584
void nhm_uncore_cpu_init(void);
585585
void skl_uncore_cpu_init(void);
586586
void icl_uncore_cpu_init(void);
587-
void adl_uncore_cpu_init(void);
588587
void tgl_uncore_cpu_init(void);
588+
void adl_uncore_cpu_init(void);
589589
void tgl_uncore_mmio_init(void);
590590
void tgl_l_uncore_mmio_init(void);
591+
void adl_uncore_mmio_init(void);
591592
int snb_pci2phy_map_init(int devid);
592593

593594
/* uncore_snbep.c */

arch/x86/events/intel/uncore_discovery.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,8 @@ void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box *box)
494494
writel(0, box->io_addr);
495495
}
496496

497-
static void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box,
498-
struct perf_event *event)
497+
void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box,
498+
struct perf_event *event)
499499
{
500500
struct hw_perf_event *hwc = &event->hw;
501501

arch/x86/events/intel/uncore_discovery.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ void intel_generic_uncore_mmio_disable_box(struct intel_uncore_box *box);
139139
void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box *box);
140140
void intel_generic_uncore_mmio_disable_event(struct intel_uncore_box *box,
141141
struct perf_event *event);
142+
void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box,
143+
struct perf_event *event);
142144

143145
void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box);
144146
void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box);

arch/x86/events/intel/uncore_snb.c

Lines changed: 213 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22
/* Nehalem/SandBridge/Haswell/Broadwell/Skylake uncore support */
33
#include "uncore.h"
4+
#include "uncore_discovery.h"
45

56
/* Uncore IMC PCI IDs */
67
#define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100
@@ -64,6 +65,20 @@
6465
#define PCI_DEVICE_ID_INTEL_RKL_2_IMC 0x4c53
6566
#define PCI_DEVICE_ID_INTEL_ADL_1_IMC 0x4660
6667
#define PCI_DEVICE_ID_INTEL_ADL_2_IMC 0x4641
68+
#define PCI_DEVICE_ID_INTEL_ADL_3_IMC 0x4601
69+
#define PCI_DEVICE_ID_INTEL_ADL_4_IMC 0x4602
70+
#define PCI_DEVICE_ID_INTEL_ADL_5_IMC 0x4609
71+
#define PCI_DEVICE_ID_INTEL_ADL_6_IMC 0x460a
72+
#define PCI_DEVICE_ID_INTEL_ADL_7_IMC 0x4621
73+
#define PCI_DEVICE_ID_INTEL_ADL_8_IMC 0x4623
74+
#define PCI_DEVICE_ID_INTEL_ADL_9_IMC 0x4629
75+
#define PCI_DEVICE_ID_INTEL_ADL_10_IMC 0x4637
76+
#define PCI_DEVICE_ID_INTEL_ADL_11_IMC 0x463b
77+
#define PCI_DEVICE_ID_INTEL_ADL_12_IMC 0x4648
78+
#define PCI_DEVICE_ID_INTEL_ADL_13_IMC 0x4649
79+
#define PCI_DEVICE_ID_INTEL_ADL_14_IMC 0x4650
80+
#define PCI_DEVICE_ID_INTEL_ADL_15_IMC 0x4668
81+
#define PCI_DEVICE_ID_INTEL_ADL_16_IMC 0x4670
6782

6883
/* SNB event control */
6984
#define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff
@@ -155,6 +170,7 @@
155170

156171
DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
157172
DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
173+
DEFINE_UNCORE_FORMAT_ATTR(chmask, chmask, "config:8-11");
158174
DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
159175
DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
160176
DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28");
@@ -1334,6 +1350,62 @@ static const struct pci_device_id tgl_uncore_pci_ids[] = {
13341350
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_2_IMC),
13351351
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
13361352
},
1353+
{ /* IMC */
1354+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_3_IMC),
1355+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1356+
},
1357+
{ /* IMC */
1358+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_4_IMC),
1359+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1360+
},
1361+
{ /* IMC */
1362+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_5_IMC),
1363+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1364+
},
1365+
{ /* IMC */
1366+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_6_IMC),
1367+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1368+
},
1369+
{ /* IMC */
1370+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_7_IMC),
1371+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1372+
},
1373+
{ /* IMC */
1374+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_8_IMC),
1375+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1376+
},
1377+
{ /* IMC */
1378+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_9_IMC),
1379+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1380+
},
1381+
{ /* IMC */
1382+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_10_IMC),
1383+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1384+
},
1385+
{ /* IMC */
1386+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_11_IMC),
1387+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1388+
},
1389+
{ /* IMC */
1390+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_12_IMC),
1391+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1392+
},
1393+
{ /* IMC */
1394+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_13_IMC),
1395+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1396+
},
1397+
{ /* IMC */
1398+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_14_IMC),
1399+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1400+
},
1401+
{ /* IMC */
1402+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_15_IMC),
1403+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1404+
},
1405+
{ /* IMC */
1406+
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_16_IMC),
1407+
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
1408+
},
13371409
{ /* end: all zeroes */ }
13381410
};
13391411

@@ -1390,7 +1462,8 @@ static struct pci_dev *tgl_uncore_get_mc_dev(void)
13901462
#define TGL_UNCORE_MMIO_IMC_MEM_OFFSET 0x10000
13911463
#define TGL_UNCORE_PCI_IMC_MAP_SIZE 0xe000
13921464

1393-
static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
1465+
static void __uncore_imc_init_box(struct intel_uncore_box *box,
1466+
unsigned int base_offset)
13941467
{
13951468
struct pci_dev *pdev = tgl_uncore_get_mc_dev();
13961469
struct intel_uncore_pmu *pmu = box->pmu;
@@ -1417,11 +1490,17 @@ static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
14171490
addr |= ((resource_size_t)mch_bar << 32);
14181491
#endif
14191492

1493+
addr += base_offset;
14201494
box->io_addr = ioremap(addr, type->mmio_map_size);
14211495
if (!box->io_addr)
14221496
pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
14231497
}
14241498

1499+
static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
1500+
{
1501+
__uncore_imc_init_box(box, 0);
1502+
}
1503+
14251504
static struct intel_uncore_ops tgl_uncore_imc_freerunning_ops = {
14261505
.init_box = tgl_uncore_imc_freerunning_init_box,
14271506
.exit_box = uncore_mmio_exit_box,
@@ -1469,3 +1548,136 @@ void tgl_uncore_mmio_init(void)
14691548
}
14701549

14711550
/* end of Tiger Lake MMIO uncore support */
1551+
1552+
/* Alder Lake MMIO uncore support */
1553+
#define ADL_UNCORE_IMC_BASE 0xd900
1554+
#define ADL_UNCORE_IMC_MAP_SIZE 0x200
1555+
#define ADL_UNCORE_IMC_CTR 0xe8
1556+
#define ADL_UNCORE_IMC_CTRL 0xd0
1557+
#define ADL_UNCORE_IMC_GLOBAL_CTL 0xc0
1558+
#define ADL_UNCORE_IMC_BOX_CTL 0xc4
1559+
#define ADL_UNCORE_IMC_FREERUNNING_BASE 0xd800
1560+
#define ADL_UNCORE_IMC_FREERUNNING_MAP_SIZE 0x100
1561+
1562+
#define ADL_UNCORE_IMC_CTL_FRZ (1 << 0)
1563+
#define ADL_UNCORE_IMC_CTL_RST_CTRL (1 << 1)
1564+
#define ADL_UNCORE_IMC_CTL_RST_CTRS (1 << 2)
1565+
#define ADL_UNCORE_IMC_CTL_INT (ADL_UNCORE_IMC_CTL_RST_CTRL | \
1566+
ADL_UNCORE_IMC_CTL_RST_CTRS)
1567+
1568+
static void adl_uncore_imc_init_box(struct intel_uncore_box *box)
1569+
{
1570+
__uncore_imc_init_box(box, ADL_UNCORE_IMC_BASE);
1571+
1572+
/* The global control in MC1 can control both MCs. */
1573+
if (box->io_addr && (box->pmu->pmu_idx == 1))
1574+
writel(ADL_UNCORE_IMC_CTL_INT, box->io_addr + ADL_UNCORE_IMC_GLOBAL_CTL);
1575+
}
1576+
1577+
static void adl_uncore_mmio_disable_box(struct intel_uncore_box *box)
1578+
{
1579+
if (!box->io_addr)
1580+
return;
1581+
1582+
writel(ADL_UNCORE_IMC_CTL_FRZ, box->io_addr + uncore_mmio_box_ctl(box));
1583+
}
1584+
1585+
static void adl_uncore_mmio_enable_box(struct intel_uncore_box *box)
1586+
{
1587+
if (!box->io_addr)
1588+
return;
1589+
1590+
writel(0, box->io_addr + uncore_mmio_box_ctl(box));
1591+
}
1592+
1593+
static struct intel_uncore_ops adl_uncore_mmio_ops = {
1594+
.init_box = adl_uncore_imc_init_box,
1595+
.exit_box = uncore_mmio_exit_box,
1596+
.disable_box = adl_uncore_mmio_disable_box,
1597+
.enable_box = adl_uncore_mmio_enable_box,
1598+
.disable_event = intel_generic_uncore_mmio_disable_event,
1599+
.enable_event = intel_generic_uncore_mmio_enable_event,
1600+
.read_counter = uncore_mmio_read_counter,
1601+
};
1602+
1603+
#define ADL_UNC_CTL_CHMASK_MASK 0x00000f00
1604+
#define ADL_UNC_IMC_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \
1605+
ADL_UNC_CTL_CHMASK_MASK | \
1606+
SNB_UNC_CTL_EDGE_DET)
1607+
1608+
static struct attribute *adl_uncore_imc_formats_attr[] = {
1609+
&format_attr_event.attr,
1610+
&format_attr_chmask.attr,
1611+
&format_attr_edge.attr,
1612+
NULL,
1613+
};
1614+
1615+
static const struct attribute_group adl_uncore_imc_format_group = {
1616+
.name = "format",
1617+
.attrs = adl_uncore_imc_formats_attr,
1618+
};
1619+
1620+
static struct intel_uncore_type adl_uncore_imc = {
1621+
.name = "imc",
1622+
.num_counters = 5,
1623+
.num_boxes = 2,
1624+
.perf_ctr_bits = 64,
1625+
.perf_ctr = ADL_UNCORE_IMC_CTR,
1626+
.event_ctl = ADL_UNCORE_IMC_CTRL,
1627+
.event_mask = ADL_UNC_IMC_EVENT_MASK,
1628+
.box_ctl = ADL_UNCORE_IMC_BOX_CTL,
1629+
.mmio_offset = 0,
1630+
.mmio_map_size = ADL_UNCORE_IMC_MAP_SIZE,
1631+
.ops = &adl_uncore_mmio_ops,
1632+
.format_group = &adl_uncore_imc_format_group,
1633+
};
1634+
1635+
enum perf_adl_uncore_imc_freerunning_types {
1636+
ADL_MMIO_UNCORE_IMC_DATA_TOTAL,
1637+
ADL_MMIO_UNCORE_IMC_DATA_READ,
1638+
ADL_MMIO_UNCORE_IMC_DATA_WRITE,
1639+
ADL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX
1640+
};
1641+
1642+
static struct freerunning_counters adl_uncore_imc_freerunning[] = {
1643+
[ADL_MMIO_UNCORE_IMC_DATA_TOTAL] = { 0x40, 0x0, 0x0, 1, 64 },
1644+
[ADL_MMIO_UNCORE_IMC_DATA_READ] = { 0x58, 0x0, 0x0, 1, 64 },
1645+
[ADL_MMIO_UNCORE_IMC_DATA_WRITE] = { 0xA0, 0x0, 0x0, 1, 64 },
1646+
};
1647+
1648+
static void adl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
1649+
{
1650+
__uncore_imc_init_box(box, ADL_UNCORE_IMC_FREERUNNING_BASE);
1651+
}
1652+
1653+
static struct intel_uncore_ops adl_uncore_imc_freerunning_ops = {
1654+
.init_box = adl_uncore_imc_freerunning_init_box,
1655+
.exit_box = uncore_mmio_exit_box,
1656+
.read_counter = uncore_mmio_read_counter,
1657+
.hw_config = uncore_freerunning_hw_config,
1658+
};
1659+
1660+
static struct intel_uncore_type adl_uncore_imc_free_running = {
1661+
.name = "imc_free_running",
1662+
.num_counters = 3,
1663+
.num_boxes = 2,
1664+
.num_freerunning_types = ADL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX,
1665+
.mmio_map_size = ADL_UNCORE_IMC_FREERUNNING_MAP_SIZE,
1666+
.freerunning = adl_uncore_imc_freerunning,
1667+
.ops = &adl_uncore_imc_freerunning_ops,
1668+
.event_descs = tgl_uncore_imc_events,
1669+
.format_group = &tgl_uncore_imc_format_group,
1670+
};
1671+
1672+
static struct intel_uncore_type *adl_mmio_uncores[] = {
1673+
&adl_uncore_imc,
1674+
&adl_uncore_imc_free_running,
1675+
NULL
1676+
};
1677+
1678+
void adl_uncore_mmio_init(void)
1679+
{
1680+
uncore_mmio_uncores = adl_mmio_uncores;
1681+
}
1682+
1683+
/* end of Alder Lake MMIO uncore support */

0 commit comments

Comments
 (0)