mirror of
https://github.com/openwrt/openwrt.git
synced 2025-02-14 14:42:08 +00:00
Replace cpufreq patch with new version requested upstream. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
202 lines
5.8 KiB
Diff
202 lines
5.8 KiB
Diff
From 76e4e6ce9aaae897f80e375345bf0095e1b09ff2 Mon Sep 17 00:00:00 2001
|
|
From: Christian Marangi <ansuelsmth@gmail.com>
|
|
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 <ansuelsmth@gmail.com>
|
|
---
|
|
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 <ansuelsmth@gmail.com>");
|
|
+MODULE_DESCRIPTION("CPU PM domain driver for Airoha SoCs");
|
|
+MODULE_LICENSE("GPL");
|