[PATCH RFC] soc: fujitsu: Add cache driver code
tan.shaopeng
tan.shaopeng at jp.fujitsu.com
Wed Mar 3 09:38:23 GMT 2021
From: "tan.shaopeng" <tan.shaopeng at jp.fujitsu.com>
This driver offers cache functions(including hardware prefetch function
and sector cache function) for A64FX system.
When built as a module, this will be called as "fujitsu_cache".
Signed-off-by: tan.shaopeng <tan.shaopeng at jp.fujitsu.com>
---
MAINTAINERS | 6 ++
arch/arm64/Kconfig.platforms | 5 +
drivers/soc/Kconfig | 1 +
drivers/soc/Makefile | 1 +
drivers/soc/fujitsu/Kconfig | 26 +++++
drivers/soc/fujitsu/fujitsu_cache.c | 183 ++++++++++++++++++++++++++++++++++++
6 files changed, 222 insertions(+)
create mode 100644 drivers/soc/fujitsu/Kconfig
create mode 100644 drivers/soc/fujitsu/fujitsu_cache.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 6eff4f7..93da2f9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1508,6 +1508,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
F: arch/arm/mach-*/
F: arch/arm/plat-*/
+ARM/A64FX SOC SUPPORT
+M: SHAOPENG TAN <tan.shaopeng at jp.fujitsu.com>
+L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: drivers/soc/fujitsu/
+
ARM/ACTIONS SEMI ARCHITECTURE
M: Andreas Färber <afaerber at suse.de>
M: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 6eecdef..41fb214 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -1,6 +1,11 @@
# SPDX-License-Identifier: GPL-2.0-only
menu "Platform selection"
+config ARCH_A64FX
+ bool "Fujitsu A64FX Platforms"
+ help
+ This enables support for Fujitsu A64FX SoC family.
+
config ARCH_ACTIONS
bool "Actions Semi Platforms"
select OWL_TIMER
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index d097d07..7a52b5d 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -7,6 +7,7 @@ source "drivers/soc/aspeed/Kconfig"
source "drivers/soc/atmel/Kconfig"
source "drivers/soc/bcm/Kconfig"
source "drivers/soc/fsl/Kconfig"
+source "drivers/soc/fujitsu/Kconfig"
source "drivers/soc/imx/Kconfig"
source "drivers/soc/ixp4xx/Kconfig"
source "drivers/soc/litex/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 699b758..57c0ddd 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -10,6 +10,7 @@ obj-y += bcm/
obj-$(CONFIG_ARCH_DOVE) += dove/
obj-$(CONFIG_MACH_DOVE) += dove/
obj-y += fsl/
+obj-y += fujitsu/
obj-$(CONFIG_ARCH_GEMINI) += gemini/
obj-y += imx/
obj-$(CONFIG_ARCH_IXP4XX) += ixp4xx/
diff --git a/drivers/soc/fujitsu/Kconfig b/drivers/soc/fujitsu/Kconfig
new file mode 100644
index 0000000..7754fb5
--- /dev/null
+++ b/drivers/soc/fujitsu/Kconfig
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# FUJITSU SoC drivers
+#
+menuconfig SOC_FUJITSU
+ bool "FUJITSU SoC drivers"
+ depends on ARCH_A64FX || COMPILE_TEST
+
+if SOC_FUJITSU
+
+config FUJITSU_CACHE
+ tristate "FUJITSU Cache Driver"
+ depends on ARM64_VHE || COMPILE_TEST
+ help
+ FUJITSU Cache Driver
+
+ This driver offers cache functions for A64FX system.
+ Loading this cache driver, control registers will be set to enable
+ these functions, and advanced settings registers will be set by default
+ values. After loading this driver, you can use the default values of the
+ advanced settings registers or set the advanced settings registers
+ from EL0. Unloading this driver, control registers will be clear to
+ disable these functions.
+ When built as a module, this will be called as "fujitsu_cache".
+
+endif # SOC_FUJITSU
diff --git a/drivers/soc/fujitsu/fujitsu_cache.c b/drivers/soc/fujitsu/fujitsu_cache.c
new file mode 100644
index 0000000..852fe1c
--- /dev/null
+++ b/drivers/soc/fujitsu/fujitsu_cache.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2021 FUJITSU LIMITED
+ *
+ * This driver enables HPC tag address override function &
+ * hardware prefetch assist function & sector cache function on A64FX.
+ *
+ * After loading this driver, detail settings of these functions
+ * can be made from EL0
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/cpuhotplug.h>
+#include <asm/cputype.h>
+#include <asm/sysreg.h>
+
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+#define pr_fmt(fmt) "[%s:%s:%d] " fmt, KBUILD_MODNAME, __func__, __LINE__
+
+#define TAG_ADDRESS_CTRL_EL1_ENABLE GENMASK(31, 0)
+#define HWPF_CTRL_EL1_ENABLE GENMASK(63, 0)
+#define SEC_CTRL_EL1_ENABLE GENMASK(63, 62)
+#define SEC_ASSIGN_EL1_DEFAULT ((u64)0)
+#define SEC_SET0_L2_EL1_DEFAULT GENMASK(63, 0)
+#define SEC_SET1_L2_EL1_DEFAULT GENMASK(63, 0)
+
+/* hpc tag address */
+#define IMP_FJ_TAG_ADDRESS_CTRL_EL1 sys_reg(3, 0, 11, 2, 0)
+
+/* hardware prefetch assist */
+#define IMP_PF_CTRL_EL1 sys_reg(3, 0, 11, 4, 0)
+#define IMP_PF_STREAM_DETECT_CTRL_EL0 sys_reg(3, 3, 11, 4, 0)
+#define IMP_PF_INJECTION_CTRL0_EL0 sys_reg(3, 3, 11, 6, 0)
+#define IMP_PF_INJECTION_CTRL1_EL0 sys_reg(3, 3, 11, 6, 1)
+#define IMP_PF_INJECTION_CTRL2_EL0 sys_reg(3, 3, 11, 6, 2)
+#define IMP_PF_INJECTION_CTRL3_EL0 sys_reg(3, 3, 11, 6, 3)
+#define IMP_PF_INJECTION_CTRL4_EL0 sys_reg(3, 3, 11, 6, 4)
+#define IMP_PF_INJECTION_CTRL5_EL0 sys_reg(3, 3, 11, 6, 5)
+#define IMP_PF_INJECTION_CTRL6_EL0 sys_reg(3, 3, 11, 6, 6)
+#define IMP_PF_INJECTION_CTRL7_EL0 sys_reg(3, 3, 11, 6, 7)
+#define IMP_PF_INJECTION_DISTANCE0_EL0 sys_reg(3, 3, 11, 7, 0)
+#define IMP_PF_INJECTION_DISTANCE1_EL0 sys_reg(3, 3, 11, 7, 1)
+#define IMP_PF_INJECTION_DISTANCE2_EL0 sys_reg(3, 3, 11, 7, 2)
+#define IMP_PF_INJECTION_DISTANCE3_EL0 sys_reg(3, 3, 11, 7, 3)
+#define IMP_PF_INJECTION_DISTANCE4_EL0 sys_reg(3, 3, 11, 7, 4)
+#define IMP_PF_INJECTION_DISTANCE5_EL0 sys_reg(3, 3, 11, 7, 5)
+#define IMP_PF_INJECTION_DISTANCE6_EL0 sys_reg(3, 3, 11, 7, 6)
+#define IMP_PF_INJECTION_DISTANCE7_EL0 sys_reg(3, 3, 11, 7, 7)
+
+/* sector cache */
+#define IMP_SCCR_CTRL_EL1 sys_reg(3, 0, 11, 8, 0)
+#define IMP_SCCR_ASSIGN_EL1 sys_reg(3, 0, 11, 8, 1)
+#define IMP_SCCR_L1_EL0 sys_reg(3, 3, 11, 8, 2)
+#define IMP_SCCR_SET0_L2_EL1 sys_reg(3, 0, 15, 8, 2)
+#define IMP_SCCR_SET1_L2_EL1 sys_reg(3, 0, 15, 8, 3)
+#define IMP_SCCR_VSCCR_L2_EL0 sys_reg(3, 3, 15, 8, 2)
+
+static unsigned long tagaddr_ctrl_reg = TAG_ADDRESS_CTRL_EL1_ENABLE;
+static unsigned long hwpf_ctrl_reg = HWPF_CTRL_EL1_ENABLE;
+static unsigned long sec_ctrl_reg = SEC_CTRL_EL1_ENABLE;
+static unsigned long sec_assign_reg = SEC_ASSIGN_EL1_DEFAULT;
+static unsigned long sec_set0_l2_reg = SEC_SET0_L2_EL1_DEFAULT;
+static unsigned long sec_set1_l2_reg = SEC_SET1_L2_EL1_DEFAULT;
+
+module_param(tagaddr_ctrl_reg, ulong, 0444);
+MODULE_PARM_DESC(tagaddr_ctrl_reg, "HPC tag address override control register");
+module_param(hwpf_ctrl_reg, ulong, 0444);
+MODULE_PARM_DESC(hwpf_ctrl_reg, "hardware prefetch assist control register");
+module_param(sec_ctrl_reg, ulong, 0444);
+MODULE_PARM_DESC(sec_ctrl_reg, "sector cache control register");
+module_param(sec_assign_reg, ulong, 0444);
+MODULE_PARM_DESC(sec_assign_reg, "sector cache assign register");
+module_param(sec_set0_l2_reg, ulong, 0444);
+MODULE_PARM_DESC(sec_set0_l2_reg, "sector cache L2 way register(sector=0,1)");
+module_param(sec_set1_l2_reg, ulong, 0444);
+MODULE_PARM_DESC(sec_set1_l2_reg, "sector cache L2 way register(sector=2,3)");
+
+static enum cpuhp_state _hp_state;
+
+static void fujitsu_hwpf_setting_regs_clear(void)
+{
+ write_sysreg_s(0, IMP_PF_STREAM_DETECT_CTRL_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_CTRL0_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_CTRL1_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_CTRL2_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_CTRL3_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_CTRL4_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_CTRL5_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_CTRL6_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_CTRL7_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_DISTANCE0_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_DISTANCE1_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_DISTANCE2_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_DISTANCE3_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_DISTANCE4_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_DISTANCE5_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_DISTANCE6_EL0);
+ write_sysreg_s(0, IMP_PF_INJECTION_DISTANCE7_EL0);
+}
+
+static void fujitsu_sec_setting_regs_clear(void)
+{
+ write_sysreg_s(0, IMP_SCCR_L1_EL0);
+ write_sysreg_s(0, IMP_SCCR_VSCCR_L2_EL0);
+}
+
+static void fujitsu_cache_destroy(void *none)
+{
+ /* just clear the values of all registers */
+ write_sysreg_s(0, IMP_FJ_TAG_ADDRESS_CTRL_EL1);
+
+ write_sysreg_s(0, IMP_PF_CTRL_EL1);
+ fujitsu_hwpf_setting_regs_clear();
+
+ write_sysreg_s(0, IMP_SCCR_CTRL_EL1);
+ write_sysreg_s(0, IMP_SCCR_ASSIGN_EL1);
+ write_sysreg_s(0, IMP_SCCR_SET0_L2_EL1);
+ write_sysreg_s(0, IMP_SCCR_SET1_L2_EL1);
+ fujitsu_sec_setting_regs_clear();
+}
+
+static int fujitsu_cache_init(unsigned int cpu)
+{
+ /* Enabled HPC tag address override,
+ * and then hardware prefetch assist & sector cache can be customized.
+ * Default values can be changed by module parameters.
+ */
+ write_sysreg_s(tagaddr_ctrl_reg, IMP_FJ_TAG_ADDRESS_CTRL_EL1);
+
+ /* hardware prefetch assist */
+ write_sysreg_s(hwpf_ctrl_reg, IMP_PF_CTRL_EL1);
+ fujitsu_hwpf_setting_regs_clear();
+
+ /* sector cache */
+ write_sysreg_s(sec_ctrl_reg, IMP_SCCR_CTRL_EL1);
+ write_sysreg_s(sec_assign_reg, IMP_SCCR_ASSIGN_EL1);
+ write_sysreg_s(sec_set0_l2_reg, IMP_SCCR_SET0_L2_EL1);
+ write_sysreg_s(sec_set1_l2_reg, IMP_SCCR_SET1_L2_EL1);
+ fujitsu_sec_setting_regs_clear();
+
+ return 0;
+}
+
+static int __init fujitsu_drv_init(void)
+{
+ int ret;
+
+ if (read_cpuid_implementor() != ARM_CPU_IMP_FUJITSU)
+ return -ENODEV;
+ if (read_cpuid_part_number() != FUJITSU_CPU_PART_A64FX)
+ return -ENODEV;
+
+ /* register initialize */
+ ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "soc/fujitsu_cache:online",
+ fujitsu_cache_init, NULL);
+ if (ret < 0) {
+ pr_err("cpuhp setup failed: %d\n", ret);
+ return ret;
+ }
+
+ _hp_state = ret;
+
+ return 0;
+}
+
+static void __exit fujitsu_drv_exit(void)
+{
+ cpuhp_remove_state(_hp_state);
+ /* register reset */
+ on_each_cpu_mask(cpu_online_mask, fujitsu_cache_destroy, NULL, 1);
+}
+
+module_init(fujitsu_drv_init);
+module_exit(fujitsu_drv_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("FUJITSU LIMITED");
+MODULE_DESCRIPTION("Fujitsu HPC HardWare Prefetch Assist, Hardware Prefetch, Sector Cache Driver");
--
1.8.3.1
More information about the linux-arm-kernel
mailing list