Commit c76826a6 authored by Kan Liang's avatar Kan Liang Committed by Peter Zijlstra
Browse files

perf/x86/intel/uncore: Support IMC free-running counters on Sapphire Rapids server



Several free-running counters for IMC uncore blocks are supported on
Sapphire Rapids server.

They are not enumerated in the discovery tables. The number of the
free-running counter boxes is calculated from the number of
corresponding standard boxes.

The snbep_pci2phy_map_init() is invoked to setup the mapping from a PCI
BUS to a Die ID, which is used to locate the corresponding MC device of
a IMC uncore unit in the spr_uncore_imc_freerunning_init_box().

Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarAndi Kleen <ak@linux.intel.com>
Link: https://lore.kernel.org/r/1625087320-194204-16-git-send-email-kan.liang@linux.intel.com
parent 0378c93a
Loading
Loading
Loading
Loading
+65 −1
Original line number Diff line number Diff line
@@ -5753,6 +5753,7 @@ static struct intel_uncore_type spr_uncore_mdf = {

#define UNCORE_SPR_NUM_UNCORE_TYPES		12
#define UNCORE_SPR_IIO				1
#define UNCORE_SPR_IMC				6

static struct intel_uncore_type *spr_uncores[UNCORE_SPR_NUM_UNCORE_TYPES] = {
	&spr_uncore_chabox,
@@ -5849,12 +5850,65 @@ static struct intel_uncore_type spr_uncore_iio_free_running = {
	.format_group		= &skx_uncore_iio_freerunning_format_group,
};

enum perf_uncore_spr_imc_freerunning_type_id {
	SPR_IMC_DCLK,
	SPR_IMC_PQ_CYCLES,

	SPR_IMC_FREERUNNING_TYPE_MAX,
};

static struct freerunning_counters spr_imc_freerunning[] = {
	[SPR_IMC_DCLK]		= { 0x22b0, 0x0, 0, 1, 48 },
	[SPR_IMC_PQ_CYCLES]	= { 0x2318, 0x8, 0, 2, 48 },
};

static struct uncore_event_desc spr_uncore_imc_freerunning_events[] = {
	INTEL_UNCORE_EVENT_DESC(dclk,			"event=0xff,umask=0x10"),

	INTEL_UNCORE_EVENT_DESC(rpq_cycles,		"event=0xff,umask=0x20"),
	INTEL_UNCORE_EVENT_DESC(wpq_cycles,		"event=0xff,umask=0x21"),
	{ /* end: all zeroes */ },
};

#define SPR_MC_DEVICE_ID	0x3251

static void spr_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
{
	int mem_offset = box->pmu->pmu_idx * ICX_IMC_MEM_STRIDE + SNR_IMC_MMIO_MEM0_OFFSET;

	snr_uncore_mmio_map(box, uncore_mmio_box_ctl(box),
			    mem_offset, SPR_MC_DEVICE_ID);
}

static struct intel_uncore_ops spr_uncore_imc_freerunning_ops = {
	.init_box	= spr_uncore_imc_freerunning_init_box,
	.exit_box	= uncore_mmio_exit_box,
	.read_counter	= uncore_mmio_read_counter,
	.hw_config	= uncore_freerunning_hw_config,
};

static struct intel_uncore_type spr_uncore_imc_free_running = {
	.name			= "imc_free_running",
	.num_counters		= 3,
	.mmio_map_size		= SNR_IMC_MMIO_SIZE,
	.num_freerunning_types	= SPR_IMC_FREERUNNING_TYPE_MAX,
	.freerunning		= spr_imc_freerunning,
	.ops			= &spr_uncore_imc_freerunning_ops,
	.event_descs		= spr_uncore_imc_freerunning_events,
	.format_group		= &skx_uncore_iio_freerunning_format_group,
};

#define UNCORE_SPR_MSR_EXTRA_UNCORES		1
#define UNCORE_SPR_MMIO_EXTRA_UNCORES		1

static struct intel_uncore_type *spr_msr_uncores[UNCORE_SPR_MSR_EXTRA_UNCORES] = {
	&spr_uncore_iio_free_running,
};

static struct intel_uncore_type *spr_mmio_uncores[UNCORE_SPR_MMIO_EXTRA_UNCORES] = {
	&spr_uncore_imc_free_running,
};

static void uncore_type_customized_copy(struct intel_uncore_type *to_type,
					struct intel_uncore_type *from_type)
{
@@ -5957,7 +6011,17 @@ int spr_uncore_pci_init(void)

void spr_uncore_mmio_init(void)
{
	int ret = snbep_pci2phy_map_init(0x3250, SKX_CPUNODEID, SKX_GIDNIDMAP, true);

	if (ret)
		uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL);
	else {
		uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO,
							 UNCORE_SPR_MMIO_EXTRA_UNCORES,
							 spr_mmio_uncores);

		spr_uncore_imc_free_running.num_boxes = uncore_type_max_boxes(uncore_mmio_uncores, UNCORE_SPR_IMC) / 2;
	}
}

/* end of SPR uncore support */