From: Christian Marangi <ansuelsmth@gmail.com>
To: "Rafael J. Wysocki" <rafael@kernel.org>,
Viresh Kumar <viresh.kumar@linaro.org>,
linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
upstream@airoha.com
Cc: Christian Marangi <ansuelsmth@gmail.com>
Subject: [PATCH v3 2/2] cpufreq: airoha: Add EN7581 Cpufreq SMC driver
Date: Mon, 25 Nov 2024 16:01:12 +0100 [thread overview]
Message-ID: <20241125150200.714-2-ansuelsmth@gmail.com> (raw)
In-Reply-To: <20241125150200.714-1-ansuelsmth@gmail.com>
Add simple CPU Freq driver for Airoha EN7581 SoC that control CPU
frequency scaling with SMC APIs and register a generic "cpufreq-dt"
device.
All CPU share the same frequency and can't be controlled independently.
Current shared CPU frequency is returned by the related SMC command.
Add SoC compatible to cpufreq-dt-plat block list as a dedicated cpufreq
driver is needed with OPP v2 nodes declared in DTS.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
Changes v3:
- Adapt to new cpufreq-dt APIs
- Register cpufreq-dt instead of custom freq driver
Changes v2:
- Fix kernel bot error with missing slab.h and bitfield.h header
- Limit COMPILE_TEST to ARM64 due to smcc 1.2
drivers/cpufreq/Kconfig.arm | 8 +++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/airoha-cpufreq.c | 103 +++++++++++++++++++++++++++
drivers/cpufreq/cpufreq-dt-platdev.c | 2 +
4 files changed, 114 insertions(+)
create mode 100644 drivers/cpufreq/airoha-cpufreq.c
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 5f7e13e60c80..338fc54276f2 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -15,6 +15,14 @@ config ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM
To compile this driver as a module, choose M here: the
module will be called sun50i-cpufreq-nvmem.
+config ARM_AIROHA_SOC_CPUFREQ
+ tristate "Airoha EN7581 SoC CPUFreq support"
+ depends on ARCH_AIROHA || (COMPILE_TEST && ARM64)
+ select PM_OPP
+ default ARCH_AIROHA
+ help
+ This adds the CPUFreq driver for Airoha EN7581 SoCs.
+
config ARM_APPLE_SOC_CPUFREQ
tristate "Apple Silicon SoC CPUFreq support"
depends on ARCH_APPLE || (COMPILE_TEST && 64BIT)
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 0f184031dd12..8e5a37a95d36 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) += amd_freq_sensitivity.o
##################################################################################
# ARM SoC drivers
+obj-$(CONFIG_ARM_AIROHA_SOC_CPUFREQ) += airoha-cpufreq.o
obj-$(CONFIG_ARM_APPLE_SOC_CPUFREQ) += apple-soc-cpufreq.o
obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) += armada-37xx-cpufreq.o
obj-$(CONFIG_ARM_ARMADA_8K_CPUFREQ) += armada-8k-cpufreq.o
diff --git a/drivers/cpufreq/airoha-cpufreq.c b/drivers/cpufreq/airoha-cpufreq.c
new file mode 100644
index 000000000000..52d863a7363a
--- /dev/null
+++ b/drivers/cpufreq/airoha-cpufreq.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/arm-smccc.h>
+#include <linux/bitfield.h>
+#include <linux/cpufreq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "cpufreq-dt.h"
+
+#define AIROHA_SIP_AVS_HANDLE 0x82000301
+#define AIROHA_AVS_OP_BASE 0xddddddd0
+#define AIROHA_AVS_OP_MASK GENMASK(1, 0)
+#define AIROHA_AVS_OP_FREQ_DYN_ADJ (AIROHA_AVS_OP_BASE | \
+ FIELD_PREP(AIROHA_AVS_OP_MASK, 0x1))
+#define AIROHA_AVS_OP_GET_FREQ (AIROHA_AVS_OP_BASE | \
+ FIELD_PREP(AIROHA_AVS_OP_MASK, 0x2))
+
+struct airoha_cpufreq_state {
+ struct platform_device *cpufreq_dt;
+};
+
+static struct airoha_cpufreq_state *airoha_cpufreq_state;
+
+static unsigned int airoha_cpufreq_get(unsigned int cpu)
+{
+ const struct arm_smccc_1_2_regs args = {
+ .a0 = AIROHA_SIP_AVS_HANDLE,
+ .a1 = AIROHA_AVS_OP_GET_FREQ,
+ };
+ struct arm_smccc_1_2_regs res;
+
+ arm_smccc_1_2_smc(&args, &res);
+
+ return (int)(res.a0 * 1000);
+}
+
+static int airoha_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
+{
+ const struct arm_smccc_1_2_regs args = {
+ .a0 = AIROHA_SIP_AVS_HANDLE,
+ .a1 = AIROHA_AVS_OP_FREQ_DYN_ADJ,
+ .a3 = index,
+ };
+ struct arm_smccc_1_2_regs res;
+
+ arm_smccc_1_2_smc(&args, &res);
+
+ /* SMC signal correct apply by unsetting BIT 0 */
+ return res.a0 & BIT(0) ? -EINVAL : 0;
+}
+
+static int __init airoha_cpufreq_driver_init(void)
+{
+ struct cpufreq_dt_platform_data pdata = { };
+ struct platform_device *cpufreq_dt;
+ struct device *cpu_dev;
+ int ret;
+
+ if (!of_machine_is_compatible("airoha,en7581"))
+ return -ENODEV;
+
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev) {
+ dev_err(cpu_dev, "Cannot get CPU\n");
+ return -ENODEV;
+ }
+
+ airoha_cpufreq_state = kzalloc(sizeof(*airoha_cpufreq_state), GFP_KERNEL);
+ if (!airoha_cpufreq_state)
+ return -ENOMEM;
+
+ pdata.no_cpu_clk = true;
+ pdata.target_index = airoha_cpufreq_set_target;
+ pdata.get = airoha_cpufreq_get;
+
+ cpufreq_dt = platform_device_register_data(NULL, "cpufreq-dt", -1, &pdata,
+ sizeof(pdata));
+ ret = PTR_ERR_OR_ZERO(cpufreq_dt);
+ if (ret) {
+ dev_err(cpu_dev,
+ "failed to create cpufreq-dt device: %d\n", ret);
+ kfree(airoha_cpufreq_state);
+ return ret;
+ }
+
+ airoha_cpufreq_state->cpufreq_dt = cpufreq_dt;
+
+ return 0;
+}
+late_initcall(airoha_cpufreq_driver_init);
+
+static void __exit airoha_cpufreq_driver_remove(void)
+{
+ platform_device_unregister(airoha_cpufreq_state->cpufreq_dt);
+ kfree(airoha_cpufreq_state);
+}
+module_exit(airoha_cpufreq_driver_remove);
+
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
+MODULE_DESCRIPTION("CPUfreq driver for Airoha SoCs");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index 18942bfe9c95..5ecd8234bfac 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -103,6 +103,8 @@ static const struct of_device_id allowlist[] __initconst = {
* platforms using "operating-points-v2" property.
*/
static const struct of_device_id blocklist[] __initconst = {
+ { .compatible = "airoha,en7581", },
+
{ .compatible = "allwinner,sun50i-h6", },
{ .compatible = "allwinner,sun50i-h616", },
{ .compatible = "allwinner,sun50i-h618", },
--
2.45.2
prev parent reply other threads:[~2024-11-25 15:02 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-25 15:01 [PATCH v3 1/2] cpufreq: dt: permit defining custom .get and .target_index Christian Marangi
2024-11-25 15:01 ` Christian Marangi [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241125150200.714-2-ansuelsmth@gmail.com \
--to=ansuelsmth@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=upstream@airoha.com \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.