summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);