From 504bad82e01528bdf950cdcc9b3f569ba9a5ec67 Mon Sep 17 00:00:00 2001 From: Sunil V L Date: Thu, 8 Feb 2024 09:14:12 +0530 Subject: [PATCH 1/5] ACPI: RISC-V: Add CPPC driver ANBZ: #22934 commit 30f3ffbee86b576705aabdd9093165a49cd66011 upstream. Add cpufreq driver based on ACPI CPPC for RISC-V. The driver uses either SBI CPPC interfaces or the CSRs to access the CPPC registers as defined by the RISC-V FFH spec. Signed-off-by: Sunil V L Reviewed-by: Pierre Gondois Acked-by: Rafael J. Wysocki Acked-by: Sudeep Holla Link: https://lore.kernel.org/r/20240208034414.22579-2-sunilvl@ventanamicro.com Signed-off-by: Palmer Dabbelt Signed-off-by: Anmeng Zhang --- drivers/acpi/riscv/Makefile | 1 + drivers/acpi/riscv/cppc.c | 157 ++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 drivers/acpi/riscv/cppc.c diff --git a/drivers/acpi/riscv/Makefile b/drivers/acpi/riscv/Makefile index 05d593d4bbb0..6b5940b806ec 100644 --- a/drivers/acpi/riscv/Makefile +++ b/drivers/acpi/riscv/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only obj-y += rhct.o init.o irq.o +obj-$(CONFIG_ACPI_CPPC_LIB) += cppc.o diff --git a/drivers/acpi/riscv/cppc.c b/drivers/acpi/riscv/cppc.c new file mode 100644 index 000000000000..4cdff387deff --- /dev/null +++ b/drivers/acpi/riscv/cppc.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Implement CPPC FFH helper routines for RISC-V. + * + * Copyright (C) 2024 Ventana Micro Systems Inc. + */ + +#include +#include +#include + +#define SBI_EXT_CPPC 0x43505043 + +/* CPPC interfaces defined in SBI spec */ +#define SBI_CPPC_PROBE 0x0 +#define SBI_CPPC_READ 0x1 +#define SBI_CPPC_READ_HI 0x2 +#define SBI_CPPC_WRITE 0x3 + +/* RISC-V FFH definitions from RISC-V FFH spec */ +#define FFH_CPPC_TYPE(r) (((r) & GENMASK_ULL(63, 60)) >> 60) +#define FFH_CPPC_SBI_REG(r) ((r) & GENMASK(31, 0)) +#define FFH_CPPC_CSR_NUM(r) ((r) & GENMASK(11, 0)) + +#define FFH_CPPC_SBI 0x1 +#define FFH_CPPC_CSR 0x2 + +struct sbi_cppc_data { + u64 val; + u32 reg; + struct sbiret ret; +}; + +static bool cppc_ext_present; + +static int __init sbi_cppc_init(void) +{ + if (sbi_spec_version >= sbi_mk_version(2, 0) && + sbi_probe_extension(SBI_EXT_CPPC) > 0) { + pr_info("SBI CPPC extension detected\n"); + cppc_ext_present = true; + } else { + pr_info("SBI CPPC extension NOT detected!!\n"); + cppc_ext_present = false; + } + + return 0; +} +device_initcall(sbi_cppc_init); + +static void sbi_cppc_read(void *read_data) +{ + struct sbi_cppc_data *data = (struct sbi_cppc_data *)read_data; + + data->ret = sbi_ecall(SBI_EXT_CPPC, SBI_CPPC_READ, + data->reg, 0, 0, 0, 0, 0); +} + +static void sbi_cppc_write(void *write_data) +{ + struct sbi_cppc_data *data = (struct sbi_cppc_data *)write_data; + + data->ret = sbi_ecall(SBI_EXT_CPPC, SBI_CPPC_WRITE, + data->reg, data->val, 0, 0, 0, 0); +} + +static void cppc_ffh_csr_read(void *read_data) +{ + struct sbi_cppc_data *data = (struct sbi_cppc_data *)read_data; + + switch (data->reg) { + /* Support only TIME CSR for now */ + case CSR_TIME: + data->ret.value = csr_read(CSR_TIME); + data->ret.error = 0; + break; + default: + data->ret.error = -EINVAL; + break; + } +} + +static void cppc_ffh_csr_write(void *write_data) +{ + struct sbi_cppc_data *data = (struct sbi_cppc_data *)write_data; + + data->ret.error = -EINVAL; +} + +/* + * Refer to drivers/acpi/cppc_acpi.c for the description of the functions + * below. + */ +bool cpc_ffh_supported(void) +{ + return true; +} + +int cpc_read_ffh(int cpu, struct cpc_reg *reg, u64 *val) +{ + struct sbi_cppc_data data; + + if (WARN_ON_ONCE(irqs_disabled())) + return -EPERM; + + if (FFH_CPPC_TYPE(reg->address) == FFH_CPPC_SBI) { + if (!cppc_ext_present) + return -EINVAL; + + data.reg = FFH_CPPC_SBI_REG(reg->address); + + smp_call_function_single(cpu, sbi_cppc_read, &data, 1); + + *val = data.ret.value; + + return (data.ret.error) ? sbi_err_map_linux_errno(data.ret.error) : 0; + } else if (FFH_CPPC_TYPE(reg->address) == FFH_CPPC_CSR) { + data.reg = FFH_CPPC_CSR_NUM(reg->address); + + smp_call_function_single(cpu, cppc_ffh_csr_read, &data, 1); + + *val = data.ret.value; + + return (data.ret.error) ? sbi_err_map_linux_errno(data.ret.error) : 0; + } + + return -EINVAL; +} + +int cpc_write_ffh(int cpu, struct cpc_reg *reg, u64 val) +{ + struct sbi_cppc_data data; + + if (WARN_ON_ONCE(irqs_disabled())) + return -EPERM; + + if (FFH_CPPC_TYPE(reg->address) == FFH_CPPC_SBI) { + if (!cppc_ext_present) + return -EINVAL; + + data.reg = FFH_CPPC_SBI_REG(reg->address); + data.val = val; + + smp_call_function_single(cpu, sbi_cppc_write, &data, 1); + + return (data.ret.error) ? sbi_err_map_linux_errno(data.ret.error) : 0; + } else if (FFH_CPPC_TYPE(reg->address) == FFH_CPPC_CSR) { + data.reg = FFH_CPPC_CSR_NUM(reg->address); + data.val = val; + + smp_call_function_single(cpu, cppc_ffh_csr_write, &data, 1); + + return (data.ret.error) ? sbi_err_map_linux_errno(data.ret.error) : 0; + } + + return -EINVAL; +} -- Gitee From d0bf054e9b9a7d8830129ccd7df1e12895a6f667 Mon Sep 17 00:00:00 2001 From: Sunil V L Date: Thu, 8 Feb 2024 09:14:13 +0530 Subject: [PATCH 2/5] cpufreq: Move CPPC configs to common Kconfig and add RISC-V ANBZ: #22934 commit 7ee1378736f09fceef95d2c9122d2cff14a375da upstream. CPPC related config options are currently defined only in ARM specific file. However, they are required for RISC-V as well. Instead of creating a new Kconfig.riscv file and duplicating them, move them to the common Kconfig file and enable RISC-V too. Signed-off-by: Sunil V L Acked-by: Viresh Kumar Reviewed-by: Pierre Gondois Acked-by: Rafael J. Wysocki Acked-by: Sudeep Holla Link: https://lore.kernel.org/r/20240208034414.22579-3-sunilvl@ventanamicro.com Signed-off-by: Palmer Dabbelt Signed-off-by: Anmeng Zhang --- drivers/cpufreq/Kconfig | 29 +++++++++++++++++++++++++++++ drivers/cpufreq/Kconfig.arm | 26 -------------------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 4c13741a744f..d03d2df7bc15 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -337,4 +337,33 @@ config QORIQ_CPUFREQ which are capable of changing the CPU's frequency dynamically. endif + +config ACPI_CPPC_CPUFREQ + tristate "CPUFreq driver based on the ACPI CPPC spec" + depends on ACPI_PROCESSOR + depends on ARM || ARM64 || RISCV + select ACPI_CPPC_LIB + help + This adds a CPUFreq driver which uses CPPC methods + as described in the ACPIv5.1 spec. CPPC stands for + Collaborative Processor Performance Controls. It + is based on an abstract continuous scale of CPU + performance values which allows the remote power + processor to flexibly optimize for power and + performance. CPPC relies on power management firmware + support for its operation. + + If in doubt, say N. + +config ACPI_CPPC_CPUFREQ_FIE + bool "Frequency Invariance support for CPPC cpufreq driver" + depends on ACPI_CPPC_CPUFREQ && GENERIC_ARCH_TOPOLOGY + depends on ARM || ARM64 || RISCV + default y + help + This extends frequency invariance support in the CPPC cpufreq driver, + by using CPPC delivered and reference performance counters. + + If in doubt, say N. + endmenu diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index c5cecbd89ba9..58829582191b 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -3,32 +3,6 @@ # ARM CPU Frequency scaling drivers # -config ACPI_CPPC_CPUFREQ - tristate "CPUFreq driver based on the ACPI CPPC spec" - depends on ACPI_PROCESSOR - select ACPI_CPPC_LIB - help - This adds a CPUFreq driver which uses CPPC methods - as described in the ACPIv5.1 spec. CPPC stands for - Collaborative Processor Performance Controls. It - is based on an abstract continuous scale of CPU - performance values which allows the remote power - processor to flexibly optimize for power and - performance. CPPC relies on power management firmware - support for its operation. - - If in doubt, say N. - -config ACPI_CPPC_CPUFREQ_FIE - bool "Frequency Invariance support for CPPC cpufreq driver" - depends on ACPI_CPPC_CPUFREQ && GENERIC_ARCH_TOPOLOGY - default y - help - This extends frequency invariance support in the CPPC cpufreq driver, - by using CPPC delivered and reference performance counters. - - If in doubt, say N. - config ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM tristate "Allwinner nvmem based SUN50I CPUFreq driver" depends on ARCH_SUNXI -- Gitee From 02766a5218ff72268be87622f337b9ca417c305f Mon Sep 17 00:00:00 2001 From: Sunil V L Date: Thu, 8 Feb 2024 09:14:14 +0530 Subject: [PATCH 3/5] RISC-V: defconfig: Enable CONFIG_ACPI_CPPC_CPUFREQ ANBZ: #22934 commit 282b9df4e9603bbb5c9cbf3ea60bc393287e8a2f upstream. CONFIG_ACPI_CPPC_CPUFREQ is required to enable CPPC for RISC-V. Signed-off-by: Sunil V L Reviewed-by: Pierre Gondois Acked-by: Rafael J. Wysocki Acked-by: Sudeep Holla Link: https://lore.kernel.org/r/20240208034414.22579-4-sunilvl@ventanamicro.com Signed-off-by: Palmer Dabbelt Signed-off-by: Anmeng Zhang --- arch/riscv/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig index 184e0df48ecd..6aadb6571578 100644 --- a/arch/riscv/configs/defconfig +++ b/arch/riscv/configs/defconfig @@ -37,6 +37,7 @@ CONFIG_SMP=y CONFIG_HOTPLUG_CPU=y CONFIG_PM=y CONFIG_CPU_IDLE=y +CONFIG_ACPI_CPPC_CPUFREQ=m CONFIG_VIRTUALIZATION=y CONFIG_KVM=m CONFIG_ACPI=y -- Gitee From 606ca6adf1663a5304d3c9a4fb9460df23ce7712 Mon Sep 17 00:00:00 2001 From: Sunil V L Date: Thu, 18 Jan 2024 11:59:30 +0530 Subject: [PATCH 4/5] ACPI: Enable ACPI_PROCESSOR for RISC-V ANBZ: #22934 commit 359df7c5be4ba5c57f641010be7237ad9f09ea53 upstream. The ACPI processor driver is not currently enabled for RISC-V. This is required to enable CPU related functionalities like LPI and CPPC. Hence, enable ACPI_PROCESSOR for RISC-V. Signed-off-by: Sunil V L Reviewed-by: Andrew Jones Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20240118062930.245937-4-sunilvl@ventanamicro.com Signed-off-by: Palmer Dabbelt Signed-off-by: Anmeng Zhang --- drivers/acpi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index cee82b473dc5..c7e4ea25d2a0 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -281,7 +281,7 @@ config ACPI_CPPC_LIB config ACPI_PROCESSOR tristate "Processor" - depends on X86 || IA64 || ARM64 || LOONGARCH + depends on X86 || IA64 || ARM64 || LOONGARCH || RISCV select ACPI_PROCESSOR_IDLE select ACPI_CPU_FREQ_PSS if X86 || IA64 || LOONGARCH select THERMAL -- Gitee From edd05b27ebe7cbbf375d3727db465b2d7598cb8c Mon Sep 17 00:00:00 2001 From: Anmeng Zhang Date: Wed, 23 Jul 2025 15:57:46 +0800 Subject: [PATCH 5/5] anolis: riscv: configs: Enable CPPC based cpufreq support ANBZ: #22934 Enable CONFIG_ACPI_PROCESSOR CONFIG_ACPI_CPPC_LIB CONFIG_ACPI_CPPC_CPUFREQ CONFIG_ACPI_HOTPLUG_CPU CONFIG_ACPI_CPPC_CPUFREQ_FIE CONFIG_ACPI_PROCESSOR_IDLE by default for RISC-V. Signed-off-by: Anmeng Zhang --- anolis/configs/L0-MANDATORY/riscv/CONFIG_ACPI_PROCESSOR | 1 - anolis/configs/L1-RECOMMEND/riscv/CONFIG_ACPI_CPPC_CPUFREQ | 1 + anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_CPPC_CPUFREQ_FIE | 1 + anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_CPPC_LIB | 1 - anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_HOTPLUG_CPU | 1 - anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_PROCESSOR_IDLE | 1 - 6 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 anolis/configs/L0-MANDATORY/riscv/CONFIG_ACPI_PROCESSOR create mode 100644 anolis/configs/L1-RECOMMEND/riscv/CONFIG_ACPI_CPPC_CPUFREQ create mode 100644 anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_CPPC_CPUFREQ_FIE delete mode 100644 anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_CPPC_LIB delete mode 100644 anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_HOTPLUG_CPU delete mode 100644 anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_PROCESSOR_IDLE diff --git a/anolis/configs/L0-MANDATORY/riscv/CONFIG_ACPI_PROCESSOR b/anolis/configs/L0-MANDATORY/riscv/CONFIG_ACPI_PROCESSOR deleted file mode 100644 index 71d30f116a41..000000000000 --- a/anolis/configs/L0-MANDATORY/riscv/CONFIG_ACPI_PROCESSOR +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_ACPI_PROCESSOR is not set diff --git a/anolis/configs/L1-RECOMMEND/riscv/CONFIG_ACPI_CPPC_CPUFREQ b/anolis/configs/L1-RECOMMEND/riscv/CONFIG_ACPI_CPPC_CPUFREQ new file mode 100644 index 000000000000..5cc88132a921 --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/riscv/CONFIG_ACPI_CPPC_CPUFREQ @@ -0,0 +1 @@ +CONFIG_ACPI_CPPC_CPUFREQ=m diff --git a/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_CPPC_CPUFREQ_FIE b/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_CPPC_CPUFREQ_FIE new file mode 100644 index 000000000000..da007c591e66 --- /dev/null +++ b/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_CPPC_CPUFREQ_FIE @@ -0,0 +1 @@ +CONFIG_ACPI_CPPC_CPUFREQ_FIE=y diff --git a/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_CPPC_LIB b/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_CPPC_LIB deleted file mode 100644 index 6c1fd1674d77..000000000000 --- a/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_CPPC_LIB +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_ACPI_CPPC_LIB is not set diff --git a/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_HOTPLUG_CPU b/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_HOTPLUG_CPU deleted file mode 100644 index 401c35bd564c..000000000000 --- a/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_HOTPLUG_CPU +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_ACPI_HOTPLUG_CPU is not set diff --git a/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_PROCESSOR_IDLE b/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_PROCESSOR_IDLE deleted file mode 100644 index 6931b739fb89..000000000000 --- a/anolis/configs/L2-OPTIONAL/riscv/CONFIG_ACPI_PROCESSOR_IDLE +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_ACPI_PROCESSOR_IDLE is not set -- Gitee