From 6d0efeb14bbe2350a94ba07b403a686d731c5179 Mon Sep 17 00:00:00 2001 From: Ilia Lin Date: Fri, 3 Jul 2020 10:49:41 +0200 Subject: soc: qcom: Separate kryo l2 accessors from PMU driver The driver provides kernel level API for other drivers to access the MSM8996 L2 cache registers. Separating the L2 access code from the PMU driver and making it public to allow other drivers use it. The accesses must be separated with a single spinlock, maintained in this driver. Signed-off-by: Ilia Lin Signed-off-by: Loic Poulain Link: https://lore.kernel.org/r/1593766185-16346-2-git-send-email-loic.poulain@linaro.org Acked-by: Will Deacon Signed-off-by: Stephen Boyd --- drivers/soc/qcom/Kconfig | 4 +++ drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/kryo-l2-accessors.c | 57 ++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 07bb261a63d2..cdc4f46d64ef 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -53,6 +53,10 @@ config QCOM_LLCC SDM845. This provides interfaces to clients that use the LLCC. Say yes here to enable LLCC slice driver. +config QCOM_KRYO_L2_ACCESSORS + bool + depends on ARCH_QCOM && ARM64 || COMPILE_TEST + config QCOM_MDT_LOADER tristate select QCOM_SCM diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 7d7e2ecbdce6..93392d9dc7f7 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -24,3 +24,4 @@ obj-$(CONFIG_QCOM_APR) += apr.o obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o +obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) += kryo-l2-accessors.o diff --git a/drivers/soc/qcom/kryo-l2-accessors.c b/drivers/soc/qcom/kryo-l2-accessors.c new file mode 100644 index 000000000000..c20cb92077c0 --- /dev/null +++ b/drivers/soc/qcom/kryo-l2-accessors.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6) +#define L2CPUSRDR_EL1 sys_reg(3, 3, 15, 0, 7) + +static DEFINE_RAW_SPINLOCK(l2_access_lock); + +/** + * kryo_l2_set_indirect_reg() - write value to an L2 register + * @reg: Address of L2 register. + * @value: Value to be written to register. + * + * Use architecturally required barriers for ordering between system register + * accesses, and system registers with respect to device memory + */ +void kryo_l2_set_indirect_reg(u64 reg, u64 val) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&l2_access_lock, flags); + write_sysreg_s(reg, L2CPUSRSELR_EL1); + isb(); + write_sysreg_s(val, L2CPUSRDR_EL1); + isb(); + raw_spin_unlock_irqrestore(&l2_access_lock, flags); +} +EXPORT_SYMBOL(kryo_l2_set_indirect_reg); + +/** + * kryo_l2_get_indirect_reg() - read an L2 register value + * @reg: Address of L2 register. + * + * Use architecturally required barriers for ordering between system register + * accesses, and system registers with respect to device memory + */ +u64 kryo_l2_get_indirect_reg(u64 reg) +{ + u64 val; + unsigned long flags; + + raw_spin_lock_irqsave(&l2_access_lock, flags); + write_sysreg_s(reg, L2CPUSRSELR_EL1); + isb(); + val = read_sysreg_s(L2CPUSRDR_EL1); + raw_spin_unlock_irqrestore(&l2_access_lock, flags); + + return val; +} +EXPORT_SYMBOL(kryo_l2_get_indirect_reg); -- cgit