From: Dmitry Osipenko <digetx@gmail.com>
To: Thierry Reding <thierry.reding@gmail.com>,
Jonathan Hunter <jonathanh@nvidia.com>,
Paul Fertser <fercerpav@gmail.com>,
Matt Merhar <mattmerhar@protonmail.com>,
Peter Geis <pgwipeout@gmail.com>,
Nicolas Chauvet <kwizart@gmail.com>,
Viresh Kumar <vireshk@kernel.org>,
Stephen Boyd <sboyd@kernel.org>,
Krzysztof Kozlowski <krzk@kernel.org>
Cc: linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v1 1/1] soc/tegra: Add devm_tegra_core_dev_init_opp_table()
Date: Sun, 16 May 2021 23:51:38 +0300 [thread overview]
Message-ID: <20210516205138.22501-2-digetx@gmail.com> (raw)
In-Reply-To: <20210516205138.22501-1-digetx@gmail.com>
Add common helper which initializes OPP table for Tegra SoC core devices.
Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/soc/tegra/common.c | 112 +++++++++++++++++++++++++++++++++++++
include/soc/tegra/common.h | 30 ++++++++++
2 files changed, 142 insertions(+)
diff --git a/drivers/soc/tegra/common.c b/drivers/soc/tegra/common.c
index 3dc54f59cafe..c3fd2facfc2d 100644
--- a/drivers/soc/tegra/common.c
+++ b/drivers/soc/tegra/common.c
@@ -3,9 +3,16 @@
* Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
*/
+#define dev_fmt(fmt) "tegra-soc: " fmt
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/export.h>
#include <linux/of.h>
+#include <linux/pm_opp.h>
#include <soc/tegra/common.h>
+#include <soc/tegra/fuse.h>
static const struct of_device_id tegra_machine_match[] = {
{ .compatible = "nvidia,tegra20", },
@@ -31,3 +38,108 @@ bool soc_is_tegra(void)
return match != NULL;
}
+
+static int tegra_core_dev_init_opp_state(struct device *dev)
+{
+ struct dev_pm_opp *opp;
+ unsigned long rate;
+ struct clk *clk;
+ int err;
+
+ clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(dev, "failed to get clk: %pe\n", clk);
+ return PTR_ERR(clk);
+ }
+
+ rate = clk_get_rate(clk);
+ if (!rate) {
+ dev_err(dev, "failed to get clk rate\n");
+ return -EINVAL;
+ }
+
+ opp = dev_pm_opp_find_freq_ceil(dev, &rate);
+
+ if (opp == ERR_PTR(-ERANGE))
+ opp = dev_pm_opp_find_freq_floor(dev, &rate);
+
+ err = PTR_ERR_OR_ZERO(opp);
+ if (err) {
+ dev_err(dev, "failed to get OPP for %ld Hz: %d\n",
+ rate, err);
+ return err;
+ }
+
+ dev_pm_opp_put(opp);
+
+ /* first dummy rate-setting initializes voltage vote */
+ err = dev_pm_opp_set_rate(dev, rate);
+ if (err) {
+ dev_err(dev, "failed to initialize OPP clock: %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+/**
+ * devm_tegra_core_dev_init_opp_table() - initialize OPP table
+ * @dev: device for which OPP table is initialized
+ * @params: pointer to the OPP table configuration
+ *
+ * This function will initialize OPP table and sync OPP state of a Tegra SoC
+ * core device.
+ *
+ * Return: 0 on success or errorno.
+ */
+int devm_tegra_core_dev_init_opp_table(struct device *dev,
+ struct tegra_core_opp_params *params)
+{
+ u32 hw_version;
+ int err;
+
+ err = devm_pm_opp_set_clkname(dev, NULL);
+ if (err) {
+ dev_err(dev, "failed to set OPP clk: %d\n", err);
+ return err;
+ }
+
+ /* Tegra114+ doesn't support OPP yet */
+ if (!of_machine_is_compatible("nvidia,tegra20") &&
+ !of_machine_is_compatible("nvidia,tegra30"))
+ return -ENODEV;
+
+ if (of_machine_is_compatible("nvidia,tegra20"))
+ hw_version = BIT(tegra_sku_info.soc_process_id);
+ else
+ hw_version = BIT(tegra_sku_info.soc_speedo_id);
+
+ err = devm_pm_opp_set_supported_hw(dev, &hw_version, 1);
+ if (err) {
+ dev_err(dev, "failed to set OPP supported HW: %d\n", err);
+ return err;
+ }
+
+ /*
+ * Older device-trees have an empty OPP table, we will get
+ * -ENODEV from devm_pm_opp_of_add_table() in this case.
+ */
+ err = devm_pm_opp_of_add_table(dev);
+ if (err) {
+ if (err == -ENODEV)
+ dev_err_once(dev, "OPP table not found, please update device-tree\n");
+ else
+ dev_err(dev, "failed to add OPP table: %d\n", err);
+
+ return err;
+ }
+
+ if (params->init_state) {
+ err = tegra_core_dev_init_opp_state(dev);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(devm_tegra_core_dev_init_opp_table);
diff --git a/include/soc/tegra/common.h b/include/soc/tegra/common.h
index 98027a76ce3d..e8eab13aa199 100644
--- a/include/soc/tegra/common.h
+++ b/include/soc/tegra/common.h
@@ -6,6 +6,36 @@
#ifndef __SOC_TEGRA_COMMON_H__
#define __SOC_TEGRA_COMMON_H__
+#include <linux/errno.h>
+#include <linux/types.h>
+
+struct device;
+
+/**
+ * Tegra SoC core device OPP table configuration
+ *
+ * @init_state: pre-initialize OPP state of a device
+ */
+struct tegra_core_opp_params {
+ bool init_state;
+};
+
+#ifdef CONFIG_ARCH_TEGRA
bool soc_is_tegra(void);
+int devm_tegra_core_dev_init_opp_table(struct device *dev,
+ struct tegra_core_opp_params *params);
+#else
+static inline bool soc_is_tegra(void)
+{
+ return false;
+}
+
+static inline int
+devm_tegra_core_dev_init_opp_table(struct device *dev,
+ struct tegra_core_opp_params *params)
+{
+ return -ENODEV;
+}
+#endif
#endif /* __SOC_TEGRA_COMMON_H__ */
--
2.30.2
next prev parent reply other threads:[~2021-05-16 20:52 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-16 20:51 [PATCH v1 0/1] Add devm_tegra_core_dev_init_opp_table() helper Dmitry Osipenko
2021-05-16 20:51 ` Dmitry Osipenko [this message]
2021-05-17 3:37 ` [PATCH v1 1/1] soc/tegra: Add devm_tegra_core_dev_init_opp_table() Viresh Kumar
2021-05-17 14:09 ` Dmitry Osipenko
2021-05-18 3:26 ` Viresh Kumar
2021-05-17 11:43 ` Krzysztof Kozlowski
2021-05-17 14:47 ` Dmitry Osipenko
2021-05-17 14:52 ` Krzysztof Kozlowski
2021-05-17 15:23 ` Dmitry Osipenko
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=20210516205138.22501-2-digetx@gmail.com \
--to=digetx@gmail.com \
--cc=fercerpav@gmail.com \
--cc=jonathanh@nvidia.com \
--cc=krzk@kernel.org \
--cc=kwizart@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=mattmerhar@protonmail.com \
--cc=pgwipeout@gmail.com \
--cc=sboyd@kernel.org \
--cc=thierry.reding@gmail.com \
--cc=vireshk@kernel.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.