From: Jon Hunter <jonathanh@nvidia.com>
To: "Rafael J . Wysocki" <rjw@rjwysocki.net>,
Viresh Kumar <viresh.kumar@linaro.org>,
Thierry Reding <thierry.reding@gmail.com>
Cc: <linux-pm@vger.kernel.org>, <linux-tegra@vger.kernel.org>,
Sumit Gupta <sumitg@nvidia.com>,
Jon Hunter <jonathanh@nvidia.com>
Subject: [PATCH 2/4] cpufreq: tegra186: Simplify cluster information lookup
Date: Wed, 2 Dec 2020 09:14:17 +0000 [thread overview]
Message-ID: <20201202091419.307192-3-jonathanh@nvidia.com> (raw)
In-Reply-To: <20201202091419.307192-1-jonathanh@nvidia.com>
The CPUFREQ driver framework references each individual CPUs when
getting and setting the speed. Tegra186 has 3 clusters of A57 CPUs and
1 cluster of Denver CPUs. Hence, the Tegra186 CPUFREQ driver need to
know which cluster a given CPU belongs to. The logic in the Tegra186
driver can be greatly simplified by storing the cluster ID associated
with each CPU in the tegra186_cpufreq_cpu structure. This allow us to
completely remove the Tegra cluster info structure from the driver and
simplifiy the code.
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
drivers/cpufreq/tegra186-cpufreq.c | 85 +++++++-----------------------
1 file changed, 20 insertions(+), 65 deletions(-)
diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c
index 98b5f32eb0be..e566ea298b59 100644
--- a/drivers/cpufreq/tegra186-cpufreq.c
+++ b/drivers/cpufreq/tegra186-cpufreq.c
@@ -12,6 +12,7 @@
#include <soc/tegra/bpmp.h>
#include <soc/tegra/bpmp-abi.h>
+#define TEGRA186_NUM_CLUSTERS 2
#define EDVD_OFFSET_A57(core) ((SZ_64K * 6) + (0x20 + (core) * 0x4))
#define EDVD_OFFSET_DENVER(core) ((SZ_64K * 7) + (0x20 + (core) * 0x4))
#define EDVD_CORE_VOLT_FREQ_F_SHIFT 0
@@ -19,58 +20,44 @@
#define EDVD_CORE_VOLT_FREQ_V_SHIFT 16
struct tegra186_cpufreq_cpu {
+ unsigned int bpmp_cluster_id;
unsigned int edvd_offset;
};
static const struct tegra186_cpufreq_cpu tegra186_cpus[] = {
/* CPU0 - A57 Cluster */
{
+ .bpmp_cluster_id = 1,
.edvd_offset = EDVD_OFFSET_A57(0)
},
/* CPU1 - Denver Cluster */
{
+ .bpmp_cluster_id = 0,
.edvd_offset = EDVD_OFFSET_DENVER(0)
},
/* CPU2 - Denver Cluster */
{
+ .bpmp_cluster_id = 0,
.edvd_offset = EDVD_OFFSET_DENVER(1)
},
/* CPU3 - A57 Cluster */
{
+ .bpmp_cluster_id = 1,
.edvd_offset = EDVD_OFFSET_A57(1)
},
/* CPU4 - A57 Cluster */
{
+ .bpmp_cluster_id = 1,
.edvd_offset = EDVD_OFFSET_A57(2)
},
/* CPU5 - A57 Cluster */
{
- .edvd_offset = EDVD_OFFSET_A57(3)
- },
-
-};
-
-struct tegra186_cpufreq_cluster_info {
- int cpus[4];
- unsigned int bpmp_cluster_id;
-};
-
-#define NO_CPU -1
-static const struct tegra186_cpufreq_cluster_info tegra186_clusters[] = {
- /* Denver cluster */
- {
- .cpus = { 1, 2, NO_CPU, NO_CPU },
- .bpmp_cluster_id = 0,
- },
- /* A57 cluster */
- {
- .cpus = { 0, 3, 4, 5 },
.bpmp_cluster_id = 1,
+ .edvd_offset = EDVD_OFFSET_A57(3)
},
};
struct tegra186_cpufreq_cluster {
- const struct tegra186_cpufreq_cluster_info *info;
struct cpufreq_frequency_table *table;
u32 ref_clk_khz;
u32 div;
@@ -78,8 +65,6 @@ struct tegra186_cpufreq_cluster {
struct tegra186_cpufreq_data {
void __iomem *regs;
-
- size_t num_clusters;
struct tegra186_cpufreq_cluster *clusters;
const struct tegra186_cpufreq_cpu *cpus;
};
@@ -87,25 +72,9 @@ struct tegra186_cpufreq_data {
static int tegra186_cpufreq_init(struct cpufreq_policy *policy)
{
struct tegra186_cpufreq_data *data = cpufreq_get_driver_data();
- unsigned int i;
-
- for (i = 0; i < data->num_clusters; i++) {
- struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
- const struct tegra186_cpufreq_cluster_info *info =
- cluster->info;
- int core;
-
- for (core = 0; core < ARRAY_SIZE(info->cpus); core++) {
- if (info->cpus[core] == policy->cpu)
- break;
- }
- if (core == ARRAY_SIZE(info->cpus))
- continue;
-
- policy->freq_table = cluster->table;
- break;
- }
+ unsigned int cluster = data->cpus[policy->cpu].bpmp_cluster_id;
+ policy->freq_table = data->clusters[cluster].table;
policy->cpuinfo.transition_latency = 300 * 1000;
policy->driver_data = NULL;
@@ -128,8 +97,9 @@ static int tegra186_cpufreq_set_target(struct cpufreq_policy *policy,
static unsigned int tegra186_cpufreq_get(unsigned int cpu)
{
struct tegra186_cpufreq_data *data = cpufreq_get_driver_data();
+ struct tegra186_cpufreq_cluster *cluster;
struct cpufreq_policy *policy;
- unsigned int i, edvd_offset, freq = 0;
+ unsigned int edvd_offset, cluster_id;
u32 ndiv;
policy = cpufreq_cpu_get(cpu);
@@ -138,24 +108,11 @@ static unsigned int tegra186_cpufreq_get(unsigned int cpu)
edvd_offset = data->cpus[policy->cpu].edvd_offset;
ndiv = readl(data->regs + edvd_offset) & EDVD_CORE_VOLT_FREQ_F_MASK;
-
- for (i = 0; i < data->num_clusters; i++) {
- struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
- int core;
-
- for (core = 0; core < ARRAY_SIZE(cluster->info->cpus); core++) {
- if (cluster->info->cpus[core] != policy->cpu)
- continue;
-
- freq = (cluster->ref_clk_khz * ndiv) / cluster->div;
- goto out;
- }
- }
-
-out:
+ cluster_id = data->cpus[policy->cpu].bpmp_cluster_id;
+ cluster = &data->clusters[cluster_id];
cpufreq_cpu_put(policy);
- return freq;
+ return (cluster->ref_clk_khz * ndiv) / cluster->div;
}
static struct cpufreq_driver tegra186_cpufreq_driver = {
@@ -171,7 +128,7 @@ static struct cpufreq_driver tegra186_cpufreq_driver = {
static struct cpufreq_frequency_table *init_vhint_table(
struct platform_device *pdev, struct tegra_bpmp *bpmp,
- struct tegra186_cpufreq_cluster *cluster)
+ struct tegra186_cpufreq_cluster *cluster, unsigned int cluster_id)
{
struct cpufreq_frequency_table *table;
struct mrq_cpu_vhint_request req;
@@ -190,7 +147,7 @@ static struct cpufreq_frequency_table *init_vhint_table(
memset(&req, 0, sizeof(req));
req.addr = phys;
- req.cluster_id = cluster->info->bpmp_cluster_id;
+ req.cluster_id = cluster_id;
memset(&msg, 0, sizeof(msg));
msg.mrq = MRQ_CPU_VHINT;
@@ -264,12 +221,11 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;
- data->clusters = devm_kcalloc(&pdev->dev, ARRAY_SIZE(tegra186_clusters),
+ data->clusters = devm_kcalloc(&pdev->dev, TEGRA186_NUM_CLUSTERS,
sizeof(*data->clusters), GFP_KERNEL);
if (!data->clusters)
return -ENOMEM;
- data->num_clusters = ARRAY_SIZE(tegra186_clusters);
data->cpus = tegra186_cpus;
bpmp = tegra_bpmp_get(&pdev->dev);
@@ -282,11 +238,10 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)
goto put_bpmp;
}
- for (i = 0; i < data->num_clusters; i++) {
+ for (i = 0; i < TEGRA186_NUM_CLUSTERS; i++) {
struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
- cluster->info = &tegra186_clusters[i];
- cluster->table = init_vhint_table(pdev, bpmp, cluster);
+ cluster->table = init_vhint_table(pdev, bpmp, cluster, i);
if (IS_ERR(cluster->table)) {
err = PTR_ERR(cluster->table);
goto put_bpmp;
--
2.25.1
next prev parent reply other threads:[~2020-12-02 9:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-02 9:14 [PATCH 0/4] CPUFREQ clean-ups for Tegra186 and Tegra194 Jon Hunter
2020-12-02 9:14 ` [PATCH 1/4] cpufreq: tegra186: Fix sparse 'incorrect type in assignment' warning Jon Hunter
2020-12-02 9:14 ` Jon Hunter [this message]
2020-12-02 9:14 ` [PATCH 3/4] cpufreq: tegra194: Remove unnecessary frequency calculation Jon Hunter
2020-12-02 9:14 ` [PATCH 4/4] cpufreq: tegra194: Rename tegra194_get_speed_common function Jon Hunter
2020-12-07 7:33 ` [PATCH 0/4] CPUFREQ clean-ups for Tegra186 and Tegra194 Viresh Kumar
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=20201202091419.307192-3-jonathanh@nvidia.com \
--to=jonathanh@nvidia.com \
--cc=linux-pm@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=rjw@rjwysocki.net \
--cc=sumitg@nvidia.com \
--cc=thierry.reding@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).