ARM: tegra: powermon: Fix copyrights from GPLv3 to GPLv2
[linux-3.10.git] / arch / arm / mach-tegra / tegra14_speedo.c
1 /*
2  * arch/arm/mach-tegra/tegra14_speedo.c
3  *
4  * Copyright (C) 2013 NVIDIA Corporation. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  *
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/io.h>
23 #include <linux/err.h>
24 #include <linux/bug.h>
25
26 #include <mach/tegra_fuse.h>
27 #include <mach/hardware.h>
28 #include <linux/module.h>
29 #include <linux/moduleparam.h>
30
31 #include "fuse.h"
32 #include "iomap.h"
33
34 #define CPU_PROCESS_CORNERS_NUM         2
35 #define CORE_PROCESS_CORNERS_NUM        2
36 #define CPU_IDDQ_BITS                   13
37
38 #define TEGRA148_CPU_SPEEDO 2109
39 #define FUSE_CPU_IDDQ 0x118 /*FIXME: update T148 register*/
40 #define FUSE_CPU_SPEEDO_0 0x114
41 #define FUSE_CORE_SPEEDO_0 0x134
42 #define FUSE_SPARE_BIT_62_0 0x398
43 static int threshold_index;
44 static int cpu_process_id;
45 static int core_process_id;
46 static int cpu_speedo_id;
47 static int cpu_speedo_value;
48 static int soc_speedo_id;
49 static int package_id;
50 static int cpu_iddq_value;
51 static int core_speedo_value;
52
53 static int enable_app_profiles;
54
55 static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
56 /* proc_id  0,     1 */
57         {2070,     UINT_MAX}, /* [0]: threshold_index 0 */
58         {0,        UINT_MAX}, /* [1]: threshold_index 1 */
59 };
60
61 static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
62 /* proc_id  0,  1 */
63         {1295,  UINT_MAX}, /* [0]: threshold_index 0 */
64         {0,     UINT_MAX}, /* [1]: threshold_index 0 */
65 };
66
67 static void rev_sku_to_speedo_ids(int rev, int sku)
68 {
69
70         switch (sku) {
71         case 0x00: /* Eng */
72         case 0x07:
73                 cpu_speedo_id = 0;
74                 soc_speedo_id = 0;
75                 threshold_index = 0;
76                 break;
77
78         case 0x03:
79                 cpu_speedo_id = 1;
80                 soc_speedo_id = 1;
81                 threshold_index = 1;
82                 break;
83
84         default:
85                 pr_err("Tegra14 Unknown SKU %d\n", sku);
86                 cpu_speedo_id = 0;
87                 soc_speedo_id = 0;
88                 threshold_index = 0;
89                 break;
90         }
91 }
92
93 void tegra_init_speedo_data(void)
94 {
95         int i;
96         cpu_speedo_value = 1024 + tegra_fuse_readl(FUSE_CPU_SPEEDO_0);
97         core_speedo_value = tegra_fuse_readl(FUSE_CORE_SPEEDO_0);
98
99         rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id);
100
101         for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) {
102                 if (cpu_speedo_value <
103                         cpu_process_speedos[threshold_index][i]) {
104                         break;
105                 }
106         }
107         cpu_process_id = i;
108
109         cpu_iddq_value = 0;
110         for (i = 0; i < CPU_IDDQ_BITS; i++) {
111                 cpu_iddq_value = (cpu_iddq_value << 1) +
112                 tegra_fuse_readl(FUSE_SPARE_BIT_62_0 - 4*i);
113         }
114
115         if (!cpu_iddq_value)
116                 cpu_iddq_value = tegra_fuse_readl(FUSE_CPU_IDDQ);
117
118
119         for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) {
120                 if (core_speedo_value <
121                         core_process_speedos[threshold_index][i]) {
122                         break;
123                 }
124         }
125
126         core_process_id = i;
127
128         pr_info("Tegra14: CPU Speedo %d, Soc Speedo %d",
129                 cpu_speedo_value, core_speedo_value);
130         pr_info("Tegra14: CPU Speedo ID %d, Soc Speedo ID %d",
131                 cpu_speedo_id, soc_speedo_id);
132 }
133
134 int tegra_cpu_process_id(void)
135 {
136         return cpu_process_id;
137 }
138
139 int tegra_core_process_id(void)
140 {
141         return core_process_id;
142 }
143
144 int tegra_cpu_speedo_id(void)
145 {
146         return cpu_speedo_id;
147 }
148
149 int tegra_soc_speedo_id(void)
150 {
151         return soc_speedo_id;
152 }
153
154 int tegra_package_id(void)
155 {
156         return package_id;
157 }
158
159 int tegra_cpu_speedo_value(void)
160 {
161         return cpu_speedo_value;
162 }
163
164 int tegra_core_speedo_value(void)
165 {
166         return core_speedo_value;
167 }
168
169 /*
170  * CPU and core nominal voltage levels as determined by chip SKU and speedo
171  * (not final - can be lowered by dvfs tables and rail dependencies; the
172  * latter is resolved by the dvfs code)
173  */
174 int tegra_cpu_speedo_mv(void)
175 {
176         /* Not applicable on Tegra148 */
177         return -ENOSYS;
178 }
179
180 int tegra_core_speedo_mv(void)
181 {
182         switch (soc_speedo_id) {
183         case 0:
184                 return 1150;
185         case 1:
186                 return 1230;
187         default:
188                 BUG();
189         }
190 }
191
192 int tegra_get_cpu_iddq_value()
193 {
194         return cpu_iddq_value;
195 }
196
197 static int get_enable_app_profiles(char *val, const struct kernel_param *kp)
198 {
199         return param_get_uint(val, kp);
200 }
201
202 static struct kernel_param_ops tegra_profiles_ops = {
203         .get = get_enable_app_profiles,
204 };
205
206 module_param_cb(tegra_enable_app_profiles,
207         &tegra_profiles_ops, &enable_app_profiles, 0444);