summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeon Yu <leoyu@nvidia.com>2019-09-16 00:29:33 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2019-10-11 11:35:07 -0400
commit74a8fe96ec7e89db246ddea8b6794cbbd46dda84 (patch)
tree5a534cf809dcd79e1909dad702e0cdf93d445b0c
parentd6c7740ea2ddd9d5087d938e9ee3b3bc2c9b6d0a (diff)
cpufreq: t194: use CPU to EMC freq mapping helpers
This CL replaces existing CPU to EMC mapping related code with common helpers to eliminate inconsistencies between cpufreq drivers including: 1) different implementations of same functionality 2) different formats of CPU to EMC freq. mapping table This change also prevents one potential bug that existing code only works for mapping table which is sorted in descending order (won't work in ascending order). The helper function to be used don't have such constrain. Bug 200551611 Bug 200512604 Change-Id: I199219b9a9b0bda10f1f6b941101e7ca24f878ac Signed-off-by: Leon Yu <leoyu@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2198539 Reviewed-by: Aaron Tian <atian@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bo Yan <byan@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/cpufreq/tegra194_cpufreq.c80
1 files changed, 7 insertions, 73 deletions
diff --git a/drivers/cpufreq/tegra194_cpufreq.c b/drivers/cpufreq/tegra194_cpufreq.c
index 339f923a2..64455007c 100644
--- a/drivers/cpufreq/tegra194_cpufreq.c
+++ b/drivers/cpufreq/tegra194_cpufreq.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This software is licensed under the terms of the GNU General Public 4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and 5 * License version 2, as published by the Free Software Foundation, and
@@ -38,6 +38,7 @@
38#include <linux/pm_qos.h> 38#include <linux/pm_qos.h>
39#include <linux/workqueue.h> 39#include <linux/workqueue.h>
40#include <linux/tegra-cpufreq.h> 40#include <linux/tegra-cpufreq.h>
41#include "cpufreq_cpu_emc_table.h"
41 42
42/* cpufreq transisition latency */ 43/* cpufreq transisition latency */
43#define TEGRA_CPUFREQ_TRANSITION_LATENCY (300 * 1000) /* unit in nanoseconds */ 44#define TEGRA_CPUFREQ_TRANSITION_LATENCY (300 * 1000) /* unit in nanoseconds */
@@ -53,12 +54,7 @@
53#define LOOP_FOR_EACH_CLUSTER(cl) for (cl = 0; \ 54#define LOOP_FOR_EACH_CLUSTER(cl) for (cl = 0; \
54 cl < MAX_CLUSTERS; cl++) 55 cl < MAX_CLUSTERS; cl++)
55 56
56struct cpu_emc_map { 57static struct cpu_emc_mapping *cpu_emc_map_ptr;
57 uint32_t cpufreq; /* unit in KHz */
58 uint32_t emcfreq; /* unit in KHz */
59};
60static struct cpu_emc_map *cpu_emc_map_ptr;
61static uint16_t cpu_emc_map_num;
62static uint8_t tegra_hypervisor_mode; 58static uint8_t tegra_hypervisor_mode;
63 59
64static int cpufreq_single_policy; 60static int cpufreq_single_policy;
@@ -239,29 +235,12 @@ static unsigned int tegra194_fast_get_speed(uint32_t cpu)
239 return tegra194_get_speed_common(cpu, US_DELAY_MIN); 235 return tegra194_get_speed_common(cpu, US_DELAY_MIN);
240} 236}
241 237
242/**
243 * cluster_cpu_to_emc_freq - return emc freq in cpu_emc_map table corresponding
244 * to cpu rate input
245 * @cpu_rate - cpu rate in KHz
246 * Returns emc freq in KHz
247 */
248static unsigned long cluster_cpu_to_emc_freq(uint32_t cpu_rate)
249{
250 int i;
251
252 for (i = 0; i < cpu_emc_map_num; i++) {
253 if (cpu_rate >= cpu_emc_map_ptr[i].cpufreq)
254 return cpu_emc_map_ptr[i].emcfreq;
255 }
256 return 0;
257}
258
259/* Set emc clock by referring cpu_to_emc freq mapping */ 238/* Set emc clock by referring cpu_to_emc freq mapping */
260static void set_cpufreq_to_emcfreq(enum cluster cl, uint32_t cluster_freq) 239static void set_cpufreq_to_emcfreq(enum cluster cl, uint32_t cluster_freq)
261{ 240{
262 unsigned long emc_freq; 241 unsigned long emc_freq;
263 242
264 emc_freq = cluster_cpu_to_emc_freq(cluster_freq); 243 emc_freq = tegra_cpu_to_emc_freq(cluster_freq, cpu_emc_map_ptr);
265 244
266 tegra_bwmgr_set_emc(tfreq_data.pcluster[cl].bwmgr, 245 tegra_bwmgr_set_emc(tfreq_data.pcluster[cl].bwmgr,
267 emc_freq * KHZ_TO_HZ, TEGRA_BWMGR_SET_EMC_FLOOR); 246 emc_freq * KHZ_TO_HZ, TEGRA_BWMGR_SET_EMC_FLOOR);
@@ -442,32 +421,6 @@ static int set_delay(void *data, u64 val)
442DEFINE_SIMPLE_ATTRIBUTE(freq_compute_fops, get_delay, set_delay, 421DEFINE_SIMPLE_ATTRIBUTE(freq_compute_fops, get_delay, set_delay,
443 "%llu\n"); 422 "%llu\n");
444 423
445static int show_cpu_emc_map(struct seq_file *s, void *data)
446{
447 int i;
448 seq_printf(s, "(cpufreq, emcfreq)\n");
449
450 for (i = 0; i < cpu_emc_map_num; i++) {
451 seq_printf(s, "%u %d\n", cpu_emc_map_ptr[i].cpufreq,
452 cpu_emc_map_ptr[i].emcfreq);
453 }
454
455 return 0;
456}
457
458static int cpu_emc_map_open(struct inode *inode, struct file *file)
459{
460 return single_open(file, show_cpu_emc_map,
461 inode->i_private);
462}
463
464static const struct file_operations cpu_emc_map_fops = {
465 .open = cpu_emc_map_open,
466 .read = seq_read,
467 .llseek = seq_lseek,
468 .release = single_release,
469};
470
471static int freq_get(void *data, u64 *val) 424static int freq_get(void *data, u64 *val)
472{ 425{
473 uint64_t cpu = (uint64_t)data; 426 uint64_t cpu = (uint64_t)data;
@@ -713,10 +666,8 @@ static int __init tegra_cpufreq_debug_init(void)
713 &freq_compute_fops)) 666 &freq_compute_fops))
714 goto err_out; 667 goto err_out;
715 668
716 if (!debugfs_create_file("cpu_emc_map", RO_MODE, 669 if (!tegra_debugfs_create_cpu_emc_map(tegra_cpufreq_debugfs_root,
717 tegra_cpufreq_debugfs_root, 670 cpu_emc_map_ptr))
718 NULL,
719 &cpu_emc_map_fops))
720 goto err_out; 671 goto err_out;
721 672
722 if (cc3_debug_init()) 673 if (cc3_debug_init())
@@ -1079,23 +1030,6 @@ err_out:
1079 return ret; 1030 return ret;
1080} 1031}
1081 1032
1082static void tegra_cpufreq_cpu_emc_map_init(struct device_node *dn)
1083{
1084 struct property *prop;
1085 int len;
1086
1087 prop = of_find_property(dn, "cpu_emc_map", &len);
1088 if (prop) {
1089 len = rounddown(len, sizeof(struct cpu_emc_map));
1090 cpu_emc_map_ptr = kzalloc(len, GFP_KERNEL);
1091 if (cpu_emc_map_ptr) {
1092 of_property_read_u32_array(dn, "cpu_emc_map",
1093 (u32 *)cpu_emc_map_ptr, len / sizeof(uint32_t));
1094 cpu_emc_map_num = len / sizeof(struct cpu_emc_map);
1095 }
1096 }
1097}
1098
1099static bool tegra_cpufreq_single_policy(struct device_node *dn) 1033static bool tegra_cpufreq_single_policy(struct device_node *dn)
1100{ 1034{
1101 struct property *prop; 1035 struct property *prop;
@@ -1114,7 +1048,7 @@ static int __init tegra194_cpufreq_probe(struct platform_device *pdev)
1114 int ret = 0, cl = 0; 1048 int ret = 0, cl = 0;
1115 1049
1116 dn = pdev->dev.of_node; 1050 dn = pdev->dev.of_node;
1117 tegra_cpufreq_cpu_emc_map_init(dn); 1051 cpu_emc_map_ptr = tegra_cpufreq_cpu_emc_map_dt_init(dn);
1118 cpufreq_single_policy = tegra_cpufreq_single_policy(dn); 1052 cpufreq_single_policy = tegra_cpufreq_single_policy(dn);
1119 1053
1120 mutex_init(&tfreq_data.mlock); 1054 mutex_init(&tfreq_data.mlock);