forked from openwrt/openwrt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
airoha: an7581: replace cpufreq patch with new version
Replace cpufreq patch with new version requested upstream. Signed-off-by: Christian Marangi <[email protected]>
- Loading branch information
Showing
3 changed files
with
454 additions
and
247 deletions.
There are no files selected for viewing
201 changes: 201 additions & 0 deletions
201
...et/linux/airoha/patches-6.6/100-01-pmdomain-airoha-Add-Airoha-CPU-PM-Domain-support.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
From 76e4e6ce9aaae897f80e375345bf0095e1b09ff2 Mon Sep 17 00:00:00 2001 | ||
From: Christian Marangi <[email protected]> | ||
Date: Sat, 4 Jan 2025 19:03:09 +0100 | ||
Subject: [PATCH v9 1/2] pmdomain: airoha: Add Airoha CPU PM Domain support | ||
|
||
Add Airoha CPU PM Domain support to control frequency and power of CPU | ||
present on Airoha EN7581 SoC. | ||
|
||
Frequency and power can be controlled with the use of the SMC command by | ||
passing the performance state. The driver also expose a read-only clock | ||
that expose the current CPU frequency with SMC command. | ||
|
||
Signed-off-by: Christian Marangi <[email protected]> | ||
--- | ||
Changes v9: | ||
- Fix compile error targetting wrong branch (remove_new change) | ||
Changes v8: | ||
- Add this patch | ||
- Use SMC invoke instead of 1.2 | ||
|
||
drivers/pmdomain/mediatek/Kconfig | 11 ++ | ||
drivers/pmdomain/mediatek/Makefile | 1 + | ||
.../pmdomain/mediatek/airoha-cpu-pmdomain.c | 144 ++++++++++++++++++ | ||
3 files changed, 156 insertions(+) | ||
create mode 100644 drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c | ||
|
||
--- a/drivers/soc/mediatek/Kconfig | ||
+++ b/drivers/soc/mediatek/Kconfig | ||
@@ -72,6 +72,17 @@ config MTK_SCPSYS_PM_DOMAINS | ||
Control Processor System (SCPSYS) has several power management related | ||
tasks in the system. | ||
|
||
+config AIROHA_CPU_PM_DOMAIN | ||
+ tristate "Airoha CPU power domain" | ||
+ default ARCH_AIROHA | ||
+ depends on PM | ||
+ select PM_GENERIC_DOMAINS | ||
+ help | ||
+ Say y here to enable CPU power domain support for Airoha SoC. | ||
+ | ||
+ CPU frequency and power is controlled by ATF with SMC command to | ||
+ set performance states. | ||
+ | ||
config MTK_MMSYS | ||
tristate "MediaTek MMSYS Support" | ||
default ARCH_MEDIATEK | ||
--- a/drivers/pmdomain/mediatek/Makefile | ||
+++ b/drivers/pmdomain/mediatek/Makefile | ||
@@ -1,3 +1,4 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o | ||
obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o | ||
+obj-$(CONFIG_AIROHA_CPU_PM_DOMAIN) += airoha-cpu-pmdomain.o | ||
--- /dev/null | ||
+++ b/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c | ||
@@ -0,0 +1,145 @@ | ||
+// SPDX-License-Identifier: GPL-2.0 | ||
+ | ||
+#include <linux/arm-smccc.h> | ||
+#include <linux/bitfield.h> | ||
+#include <linux/clk-provider.h> | ||
+#include <linux/module.h> | ||
+#include <linux/platform_device.h> | ||
+#include <linux/pm_domain.h> | ||
+#include <linux/slab.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_cpu_pmdomain_priv { | ||
+ struct clk_hw hw; | ||
+ struct generic_pm_domain pd; | ||
+}; | ||
+ | ||
+static long airoha_cpu_pmdomain_clk_round(struct clk_hw *hw, unsigned long rate, | ||
+ unsigned long *parent_rate) | ||
+{ | ||
+ return rate; | ||
+} | ||
+ | ||
+static unsigned long airoha_cpu_pmdomain_clk_get(struct clk_hw *hw, | ||
+ unsigned long parent_rate) | ||
+{ | ||
+ struct arm_smccc_res res; | ||
+ | ||
+ arm_smccc_1_1_invoke(AIROHA_SIP_AVS_HANDLE, AIROHA_AVS_OP_GET_FREQ, | ||
+ 0, 0, 0, 0, 0, 0, &res); | ||
+ | ||
+ /* SMCCC returns freq in MHz */ | ||
+ return (int)(res.a0 * 1000 * 1000); | ||
+} | ||
+ | ||
+/* Airoha CPU clk SMCC is always enabled */ | ||
+static int airoha_cpu_pmdomain_clk_is_enabled(struct clk_hw *hw) | ||
+{ | ||
+ return true; | ||
+} | ||
+ | ||
+static const struct clk_ops airoha_cpu_pmdomain_clk_ops = { | ||
+ .recalc_rate = airoha_cpu_pmdomain_clk_get, | ||
+ .is_enabled = airoha_cpu_pmdomain_clk_is_enabled, | ||
+ .round_rate = airoha_cpu_pmdomain_clk_round, | ||
+}; | ||
+ | ||
+static int airoha_cpu_pmdomain_set_performance_state(struct generic_pm_domain *domain, | ||
+ unsigned int state) | ||
+{ | ||
+ struct arm_smccc_res res; | ||
+ | ||
+ arm_smccc_1_1_invoke(AIROHA_SIP_AVS_HANDLE, AIROHA_AVS_OP_FREQ_DYN_ADJ, | ||
+ 0, state, 0, 0, 0, 0, &res); | ||
+ | ||
+ /* SMC signal correct apply by unsetting BIT 0 */ | ||
+ return res.a0 & BIT(0) ? -EINVAL : 0; | ||
+} | ||
+ | ||
+static int airoha_cpu_pmdomain_probe(struct platform_device *pdev) | ||
+{ | ||
+ struct airoha_cpu_pmdomain_priv *priv; | ||
+ struct device *dev = &pdev->dev; | ||
+ struct clk_init_data init = { }; | ||
+ struct generic_pm_domain *pd; | ||
+ struct clk_hw *hw; | ||
+ int ret; | ||
+ | ||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
+ if (!priv) | ||
+ return -ENOMEM; | ||
+ | ||
+ /* Init and register a get-only clk for Cpufreq */ | ||
+ init.name = "cpu"; | ||
+ init.ops = &airoha_cpu_pmdomain_clk_ops; | ||
+ /* Clock with no set_rate, can't cache */ | ||
+ init.flags = CLK_GET_RATE_NOCACHE; | ||
+ | ||
+ hw = &priv->hw; | ||
+ hw->init = &init; | ||
+ ret = devm_clk_hw_register(dev, hw); | ||
+ if (ret) | ||
+ return ret; | ||
+ | ||
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw); | ||
+ if (ret) | ||
+ return ret; | ||
+ | ||
+ /* Init and register a PD for CPU */ | ||
+ pd = &priv->pd; | ||
+ pd->name = "cpu_pd"; | ||
+ pd->flags = GENPD_FLAG_ALWAYS_ON; | ||
+ pd->set_performance_state = airoha_cpu_pmdomain_set_performance_state; | ||
+ | ||
+ ret = pm_genpd_init(pd, NULL, false); | ||
+ if (ret) | ||
+ return ret; | ||
+ | ||
+ ret = of_genpd_add_provider_simple(dev->of_node, pd); | ||
+ if (ret) | ||
+ goto err_add_provider; | ||
+ | ||
+ platform_set_drvdata(pdev, priv); | ||
+ | ||
+ return 0; | ||
+ | ||
+err_add_provider: | ||
+ pm_genpd_remove(pd); | ||
+ | ||
+ return ret; | ||
+} | ||
+ | ||
+static void airoha_cpu_pmdomain_remove(struct platform_device *pdev) | ||
+{ | ||
+ struct airoha_cpu_pmdomain_priv *priv = platform_get_drvdata(pdev); | ||
+ | ||
+ of_genpd_del_provider(pdev->dev.of_node); | ||
+ pm_genpd_remove(&priv->pd); | ||
+} | ||
+ | ||
+static const struct of_device_id airoha_cpu_pmdomain_of_match[] = { | ||
+ { .compatible = "airoha,en7581-cpufreq" }, | ||
+ { }, | ||
+}; | ||
+MODULE_DEVICE_TABLE(of, airoha_cpu_pmdomain_of_match); | ||
+ | ||
+static struct platform_driver airoha_cpu_pmdomain_driver = { | ||
+ .probe = airoha_cpu_pmdomain_probe, | ||
+ .remove_new = airoha_cpu_pmdomain_remove, | ||
+ .driver = { | ||
+ .name = "airoha-cpu-pmdomain", | ||
+ .of_match_table = airoha_cpu_pmdomain_of_match, | ||
+ }, | ||
+}; | ||
+module_platform_driver(airoha_cpu_pmdomain_driver); | ||
+ | ||
+MODULE_AUTHOR("Christian Marangi <[email protected]>"); | ||
+MODULE_DESCRIPTION("CPU PM domain driver for Airoha SoCs"); | ||
+MODULE_LICENSE("GPL"); |
Oops, something went wrong.