Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb8f9ffc authored by Suzuki K Poulose's avatar Suzuki K Poulose Committed by Raghavendra Rao Ananta
Browse files

perf: ARM DynamIQ Shared Unit PMU support



Add support for the Cluster PMU part of the ARM DynamIQ Shared Unit (DSU).
The DSU integrates one or more cores with an L3 memory system, control
logic, and external interfaces to form a multicore cluster. The PMU
allows counting the various events related to L3, SCU etc, along with
providing a cycle counter.

The PMU can be accessed via system registers, which are common
to the cores in the same cluster. The PMU registers follow the
semantics of the ARMv8 PMU, mostly, with the exception that
the counters record the cluster wide events.

This driver is mostly based on the ARMv8 and CCI PMU drivers.
The driver only supports ARM64 at the moment. It can be extended
to support ARM32 by providing register accessors like we do in
arch/arm64/include/arm_dsu_pmu.h.

Change-Id: I8fde43843168df7575ef4d11b61e627f5204f00d
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Git-commit: 7520fa99246dade7ab6dde1573a146beed632abd
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


[rananta@codeaurora@org: resolved trivial merge conflicts]
Signed-off-by: default avatarRaghavendra Rao Ananta <rananta@codeaurora.org>
parent 2ff8629f
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
ARM DynamIQ Shared Unit (DSU) PMU
==================================

ARM DynamIQ Shared Unit integrates one or more cores with an L3 memory system,
control logic and external interfaces to form a multicore cluster. The PMU
allows counting the various events related to the L3 cache, Snoop Control Unit
etc, using 32bit independent counters. It also provides a 64bit cycle counter.

The PMU can only be accessed via CPU system registers and are common to the
cores connected to the same DSU. Like most of the other uncore PMUs, DSU
PMU doesn't support process specific events and cannot be used in sampling mode.

The DSU provides a bitmap for a subset of implemented events via hardware
registers. There is no way for the driver to determine if the other events
are available or not. Hence the driver exposes only those events advertised
by the DSU, in "events" directory under :

  /sys/bus/event_sources/devices/arm_dsu_<N>/

The user should refer to the TRM of the product to figure out the supported events
and use the raw event code for the unlisted events.

The driver also exposes the CPUs connected to the DSU instance in "associated_cpus".


e.g usage :

	perf stat -a -e arm_dsu_0/cycles/
+129 −0
Original line number Diff line number Diff line
/*
 * ARM DynamIQ Shared Unit (DSU) PMU Low level register access routines.
 *
 * Copyright (C) ARM Limited, 2017.
 *
 * Author: Suzuki K Poulose <suzuki.poulose@arm.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2, as published by the Free Software Foundation.
 */

#include <linux/bitops.h>
#include <linux/build_bug.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <asm/barrier.h>
#include <asm/sysreg.h>


#define CLUSTERPMCR_EL1			sys_reg(3, 0, 15, 5, 0)
#define CLUSTERPMCNTENSET_EL1		sys_reg(3, 0, 15, 5, 1)
#define CLUSTERPMCNTENCLR_EL1		sys_reg(3, 0, 15, 5, 2)
#define CLUSTERPMOVSSET_EL1		sys_reg(3, 0, 15, 5, 3)
#define CLUSTERPMOVSCLR_EL1		sys_reg(3, 0, 15, 5, 4)
#define CLUSTERPMSELR_EL1		sys_reg(3, 0, 15, 5, 5)
#define CLUSTERPMINTENSET_EL1		sys_reg(3, 0, 15, 5, 6)
#define CLUSTERPMINTENCLR_EL1		sys_reg(3, 0, 15, 5, 7)
#define CLUSTERPMCCNTR_EL1		sys_reg(3, 0, 15, 6, 0)
#define CLUSTERPMXEVTYPER_EL1		sys_reg(3, 0, 15, 6, 1)
#define CLUSTERPMXEVCNTR_EL1		sys_reg(3, 0, 15, 6, 2)
#define CLUSTERPMMDCR_EL1		sys_reg(3, 0, 15, 6, 3)
#define CLUSTERPMCEID0_EL1		sys_reg(3, 0, 15, 6, 4)
#define CLUSTERPMCEID1_EL1		sys_reg(3, 0, 15, 6, 5)

static inline u32 __dsu_pmu_read_pmcr(void)
{
	return read_sysreg_s(CLUSTERPMCR_EL1);
}

static inline void __dsu_pmu_write_pmcr(u32 val)
{
	write_sysreg_s(val, CLUSTERPMCR_EL1);
	isb();
}

static inline u32 __dsu_pmu_get_reset_overflow(void)
{
	u32 val = read_sysreg_s(CLUSTERPMOVSCLR_EL1);
	/* Clear the bit */
	write_sysreg_s(val, CLUSTERPMOVSCLR_EL1);
	isb();
	return val;
}

static inline void __dsu_pmu_select_counter(int counter)
{
	write_sysreg_s(counter, CLUSTERPMSELR_EL1);
	isb();
}

static inline u64 __dsu_pmu_read_counter(int counter)
{
	__dsu_pmu_select_counter(counter);
	return read_sysreg_s(CLUSTERPMXEVCNTR_EL1);
}

static inline void __dsu_pmu_write_counter(int counter, u64 val)
{
	__dsu_pmu_select_counter(counter);
	write_sysreg_s(val, CLUSTERPMXEVCNTR_EL1);
	isb();
}

static inline void __dsu_pmu_set_event(int counter, u32 event)
{
	__dsu_pmu_select_counter(counter);
	write_sysreg_s(event, CLUSTERPMXEVTYPER_EL1);
	isb();
}

static inline u64 __dsu_pmu_read_pmccntr(void)
{
	return read_sysreg_s(CLUSTERPMCCNTR_EL1);
}

static inline void __dsu_pmu_write_pmccntr(u64 val)
{
	write_sysreg_s(val, CLUSTERPMCCNTR_EL1);
	isb();
}

static inline void __dsu_pmu_disable_counter(int counter)
{
	write_sysreg_s(BIT(counter), CLUSTERPMCNTENCLR_EL1);
	isb();
}

static inline void __dsu_pmu_enable_counter(int counter)
{
	write_sysreg_s(BIT(counter), CLUSTERPMCNTENSET_EL1);
	isb();
}

static inline void __dsu_pmu_counter_interrupt_enable(int counter)
{
	write_sysreg_s(BIT(counter), CLUSTERPMINTENSET_EL1);
	isb();
}

static inline void __dsu_pmu_counter_interrupt_disable(int counter)
{
	write_sysreg_s(BIT(counter), CLUSTERPMINTENCLR_EL1);
	isb();
}


static inline u32 __dsu_pmu_read_pmceid(int n)
{
	switch (n) {
	case 0:
		return read_sysreg_s(CLUSTERPMCEID0_EL1);
	case 1:
		return read_sysreg_s(CLUSTERPMCEID1_EL1);
	default:
		BUILD_BUG();
		return 0;
	}
}
+9 −0
Original line number Diff line number Diff line
@@ -17,6 +17,15 @@ config ARM_PMU_ACPI
	depends on ARM_PMU && ACPI
	def_bool y

config ARM_DSU_PMU
       tristate "ARM DynamIQ Shared Unit (DSU) PMU"
       depends on ARM64
         help
         Provides support for performance monitor unit in ARM DynamIQ Shared
         Unit (DSU). The DSU integrates one or more cores with an L3 memory
         system, control logic. The PMU allows counting various events related
         to DSU.

config QCOM_L2_PMU
	bool "Qualcomm Technologies L2-cache PMU"
	depends on ARCH_QCOM && ARM64 && ACPI
+1 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_ARM_DSU_PMU) += arm_dsu_pmu.o
obj-$(CONFIG_ARM_PMU) += arm_pmu.o arm_pmu_platform.o
obj-$(CONFIG_ARM_PMU_ACPI) += arm_pmu_acpi.o
obj-$(CONFIG_QCOM_L2_PMU)	+= qcom_l2_pmu.o
+843 −0

File added.

Preview size limit exceeded, changes collapsed.