From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp
---
kernel/drivers/cpufreq/tegra124-cpufreq.c | 99 ++++++++++++++++++++++++++++---------------------
1 files changed, 57 insertions(+), 42 deletions(-)
diff --git a/kernel/drivers/cpufreq/tegra124-cpufreq.c b/kernel/drivers/cpufreq/tegra124-cpufreq.c
index 4bb154f..7a1ea6f 100644
--- a/kernel/drivers/cpufreq/tegra124-cpufreq.c
+++ b/kernel/drivers/cpufreq/tegra124-cpufreq.c
@@ -1,19 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Tegra 124 cpufreq driver
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/clk.h>
+#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -22,11 +15,9 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
-#include <linux/regulator/consumer.h>
#include <linux/types.h>
struct tegra124_cpufreq_priv {
- struct regulator *vdd_cpu_reg;
struct clk *cpu_clk;
struct clk *pllp_clk;
struct clk *pllx_clk;
@@ -60,14 +51,6 @@
return ret;
}
-static void tegra124_cpu_switch_to_pllx(struct tegra124_cpufreq_priv *priv)
-{
- clk_set_parent(priv->cpu_clk, priv->pllp_clk);
- clk_disable_unprepare(priv->dfll_clk);
- regulator_sync_voltage(priv->vdd_cpu_reg);
- clk_set_parent(priv->cpu_clk, priv->pllx_clk);
-}
-
static int tegra124_cpufreq_probe(struct platform_device *pdev)
{
struct tegra124_cpufreq_priv *priv;
@@ -88,16 +71,10 @@
if (!np)
return -ENODEV;
- priv->vdd_cpu_reg = regulator_get(cpu_dev, "vdd-cpu");
- if (IS_ERR(priv->vdd_cpu_reg)) {
- ret = PTR_ERR(priv->vdd_cpu_reg);
- goto out_put_np;
- }
-
priv->cpu_clk = of_clk_get_by_name(np, "cpu_g");
if (IS_ERR(priv->cpu_clk)) {
ret = PTR_ERR(priv->cpu_clk);
- goto out_put_vdd_cpu_reg;
+ goto out_put_np;
}
priv->dfll_clk = of_clk_get_by_name(np, "dfll");
@@ -129,7 +106,7 @@
platform_device_register_full(&cpufreq_dt_devinfo);
if (IS_ERR(priv->cpufreq_dt_pdev)) {
ret = PTR_ERR(priv->cpufreq_dt_pdev);
- goto out_switch_to_pllx;
+ goto out_put_pllp_clk;
}
platform_set_drvdata(pdev, priv);
@@ -138,8 +115,6 @@
return 0;
-out_switch_to_pllx:
- tegra124_cpu_switch_to_pllx(priv);
out_put_pllp_clk:
clk_put(priv->pllp_clk);
out_put_pllx_clk:
@@ -148,34 +123,73 @@
clk_put(priv->dfll_clk);
out_put_cpu_clk:
clk_put(priv->cpu_clk);
-out_put_vdd_cpu_reg:
- regulator_put(priv->vdd_cpu_reg);
out_put_np:
of_node_put(np);
return ret;
}
-static int tegra124_cpufreq_remove(struct platform_device *pdev)
+static int __maybe_unused tegra124_cpufreq_suspend(struct device *dev)
{
- struct tegra124_cpufreq_priv *priv = platform_get_drvdata(pdev);
+ struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+ int err;
- platform_device_unregister(priv->cpufreq_dt_pdev);
- tegra124_cpu_switch_to_pllx(priv);
+ /*
+ * PLLP rate 408Mhz is below the CPU Fmax at Vmin and is safe to
+ * use during suspend and resume. So, switch the CPU clock source
+ * to PLLP and disable DFLL.
+ */
+ err = clk_set_parent(priv->cpu_clk, priv->pllp_clk);
+ if (err < 0) {
+ dev_err(dev, "failed to reparent to PLLP: %d\n", err);
+ return err;
+ }
- clk_put(priv->pllp_clk);
- clk_put(priv->pllx_clk);
- clk_put(priv->dfll_clk);
- clk_put(priv->cpu_clk);
- regulator_put(priv->vdd_cpu_reg);
+ clk_disable_unprepare(priv->dfll_clk);
return 0;
}
+static int __maybe_unused tegra124_cpufreq_resume(struct device *dev)
+{
+ struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+ int err;
+
+ /*
+ * Warmboot code powers up the CPU with PLLP clock source.
+ * Enable DFLL clock and switch CPU clock source back to DFLL.
+ */
+ err = clk_prepare_enable(priv->dfll_clk);
+ if (err < 0) {
+ dev_err(dev, "failed to enable DFLL clock for CPU: %d\n", err);
+ goto disable_cpufreq;
+ }
+
+ err = clk_set_parent(priv->cpu_clk, priv->dfll_clk);
+ if (err < 0) {
+ dev_err(dev, "failed to reparent to DFLL clock: %d\n", err);
+ goto disable_dfll;
+ }
+
+ return 0;
+
+disable_dfll:
+ clk_disable_unprepare(priv->dfll_clk);
+disable_cpufreq:
+ disable_cpufreq();
+
+ return err;
+}
+
+static const struct dev_pm_ops tegra124_cpufreq_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(tegra124_cpufreq_suspend,
+ tegra124_cpufreq_resume)
+};
+
static struct platform_driver tegra124_cpufreq_platdrv = {
.driver.name = "cpufreq-tegra124",
+ .driver.pm = &tegra124_cpufreq_pm_ops,
.probe = tegra124_cpufreq_probe,
- .remove = tegra124_cpufreq_remove,
};
static int __init tegra_cpufreq_init(void)
@@ -183,7 +197,8 @@
int ret;
struct platform_device *pdev;
- if (!of_machine_is_compatible("nvidia,tegra124"))
+ if (!(of_machine_is_compatible("nvidia,tegra124") ||
+ of_machine_is_compatible("nvidia,tegra210")))
return -ENODEV;
/*
--
Gitblit v1.6.2