ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / tegra12_speedo.c
1 /*
2  * arch/arm/mach-tegra/tegra12_speedo.c
3  *
4  * Copyright (C) 2013-2014 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>                  /* For BUG_ON.  */
25
26 #include <linux/tegra-soc.h>
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/tegra-fuse.h>
30
31 #include "iomap.h"
32 #include "common.h"
33
34 #define TEGRA124_CPU_SPEEDO 2271 /* FIXME: Get Correct Value */
35
36 #define CPU_PROCESS_CORNERS_NUM         2
37 #define GPU_PROCESS_CORNERS_NUM         2
38 #define CORE_PROCESS_CORNERS_NUM                2
39
40 #define FUSE_CPU_SPEEDO_0       0x114
41 #define FUSE_CPU_SPEEDO_1       0x12c
42 #define FUSE_CPU_SPEEDO_2       0x130
43 #define FUSE_SOC_SPEEDO_0       0x134
44 #define FUSE_SOC_SPEEDO_1       0x138
45 #define FUSE_SOC_SPEEDO_2       0x13c
46 #define FUSE_CPU_IDDQ           0x118
47 #define FUSE_SOC_IDDQ           0x140
48 #define FUSE_GPU_IDDQ           0x228
49 #define FUSE_FT_REV             0x128
50
51 static int threshold_index;
52 static int cpu_process_id;
53 static int core_process_id;
54 static int gpu_process_id;
55 static int cpu_speedo_id;
56 static int cpu_speedo_value;
57 static int soc_speedo_id;
58 static int gpu_speedo_id;
59 static int package_id;
60 static int cpu_iddq_value;
61 static int gpu_iddq_value;
62 static int soc_iddq_value;
63
64 static int cpu_speedo_0_value;
65 static int cpu_speedo_1_value;
66 static int soc_speedo_0_value;
67 static int soc_speedo_1_value;
68 static int soc_speedo_2_value;
69
70 static int gpu_speedo_value;
71
72 static int enable_app_profiles;
73
74 static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
75 /* proc_id  0,     1 */
76         {UINT_MAX, UINT_MAX}, /* [0]: threshold_index 0 */
77         {0,        UINT_MAX}, /* [1]: threshold_index 1 */
78 };
79
80 static const u32 gpu_process_speedos[][GPU_PROCESS_CORNERS_NUM] = {
81 /* proc_id  0,     1 */
82         {UINT_MAX, UINT_MAX}, /* [0]: threshold_index 0 */
83         {0,        UINT_MAX}, /* [1]: threshold_index 1 */
84 };
85
86 static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
87 /* proc_id  0,  1 */
88         {2061,  UINT_MAX}, /* [0]: threshold_index 0 */
89         {0,     UINT_MAX}, /* [1]: threshold_index 1 */
90 };
91
92 static void rev_sku_to_speedo_ids(int rev, int sku)
93 {
94         int can_boost = tegra_get_sku_override();
95
96         switch (sku) {
97         case 0x00: /* Engg sku */
98         case 0x0F:
99         case 0x83:
100         case 0x23:
101                 cpu_speedo_id = sku == 0x83 ? 2 : 0;
102                 soc_speedo_id = 0;
103                 gpu_speedo_id = 0;
104                 threshold_index = 0;
105                 break;
106         case 0x1F:
107         case 0x87:
108         case 0x27:
109                 cpu_speedo_id = 5;
110                 soc_speedo_id = 0;
111                 gpu_speedo_id = 1;
112                 threshold_index = 0;
113                 break;
114         case 0x07:
115                 if (can_boost) {
116                         cpu_speedo_id = 3;
117                         soc_speedo_id = 1;
118                         gpu_speedo_id = 2;
119                         threshold_index = 1;
120                         break;
121                 }
122                 /* fall thru */
123         case 0x81:
124         case 0x21:
125                 cpu_speedo_id = 1;
126                 soc_speedo_id = 1;
127                 gpu_speedo_id = 1;
128                 threshold_index = 1;
129                 break;
130         default:
131                 pr_warn("Tegra12: Unknown SKU %d\n", sku);
132                 cpu_speedo_id = 0;
133                 soc_speedo_id = 0;
134                 gpu_speedo_id = 0;
135                 threshold_index = 0;
136                 break;
137         }
138 }
139
140 void tegra_init_speedo_data(void)
141 {
142         int i;
143
144         if (!tegra_platform_is_silicon()) {
145                 cpu_process_id  =  0;
146                 core_process_id =  0;
147                 gpu_process_id  = 0;
148                 cpu_speedo_id   = 0;
149                 soc_speedo_id   = 0;
150                 gpu_speedo_id   = 0;
151                 package_id = -1;
152                 cpu_speedo_value = 1777;
153                 cpu_speedo_0_value = 0;
154                 cpu_speedo_1_value = 0;
155                 soc_speedo_0_value = 0;
156                 soc_speedo_1_value = 0;
157                 soc_speedo_2_value = 0;
158                 soc_iddq_value = 0;
159                 gpu_iddq_value = 0;
160                 return;
161         }
162
163         cpu_speedo_0_value = tegra_fuse_readl(FUSE_CPU_SPEEDO_0);
164         cpu_speedo_1_value = tegra_fuse_readl(FUSE_CPU_SPEEDO_1);
165
166         /* GPU Speedo is stored in CPU_SPEEDO_2 */
167         gpu_speedo_value = tegra_fuse_readl(FUSE_CPU_SPEEDO_2);
168
169         soc_speedo_0_value = tegra_fuse_readl(FUSE_SOC_SPEEDO_0);
170         soc_speedo_1_value = tegra_fuse_readl(FUSE_SOC_SPEEDO_1);
171         soc_speedo_2_value = tegra_fuse_readl(FUSE_SOC_SPEEDO_2);
172
173         cpu_iddq_value = tegra_fuse_readl(FUSE_CPU_IDDQ);
174         soc_iddq_value = tegra_fuse_readl(FUSE_SOC_IDDQ);
175         gpu_iddq_value = tegra_fuse_readl(FUSE_GPU_IDDQ);
176
177         /* cpu_speedo_value = TEGRA124_CPU_SPEEDO; */
178         cpu_speedo_value = cpu_speedo_0_value;
179
180         if (cpu_speedo_value == 0) {
181                 cpu_speedo_value = 1900;
182                 pr_warn("Tegra12: Warning: Speedo value not fused. PLEASE FIX!!!!!!!!!!!\n");
183                 pr_warn("Tegra12: Warning: PLEASE USE BOARD WITH FUSED SPEEDO VALUE !!!!\n");
184         }
185
186
187         rev_sku_to_speedo_ids(tegra_revision, tegra_get_sku_id());
188
189         for (i = 0; i < GPU_PROCESS_CORNERS_NUM; i++) {
190                 if (gpu_speedo_value <
191                         gpu_process_speedos[threshold_index][i]) {
192                         break;
193                 }
194         }
195         gpu_process_id = i;
196
197         for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) {
198                 if (cpu_speedo_value <
199                         cpu_process_speedos[threshold_index][i]) {
200                         break;
201                 }
202         }
203         cpu_process_id = i;
204
205         for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) {
206                 if (soc_speedo_0_value <
207                         core_process_speedos[threshold_index][i]) {
208                         break;
209                 }
210         }
211         core_process_id = i;
212
213         pr_info("Tegra12: CPU Speedo value %d, Soc Speedo value %d, Gpu Speedo value %d\n",
214                 cpu_speedo_value, soc_speedo_0_value, gpu_speedo_value);
215         pr_info("Tegra12: CPU Speedo ID %d, Soc Speedo ID %d, Gpu Speedo ID %d\n",
216                 cpu_speedo_id, soc_speedo_id, gpu_speedo_id);
217         pr_info("Tegra12: CPU Process ID %d,Soc Process ID %d,Gpu Process ID %d\n",
218                  cpu_process_id, core_process_id, gpu_process_id);
219 }
220
221 int tegra_cpu_process_id(void)
222 {
223         return cpu_process_id;
224 }
225
226 int tegra_core_process_id(void)
227 {
228         return core_process_id;
229 }
230
231 int tegra_gpu_process_id(void)
232 {
233         return gpu_process_id;
234 }
235
236 int tegra_cpu_speedo_id(void)
237 {
238         return cpu_speedo_id;
239 }
240
241 int tegra_soc_speedo_id(void)
242 {
243         return soc_speedo_id;
244 }
245
246 int tegra_gpu_speedo_id(void)
247 {
248         return gpu_speedo_id;
249 }
250
251 int tegra_package_id(void)
252 {
253         return package_id;
254 }
255
256 int tegra_cpu_speedo_value(void)
257 {
258         return cpu_speedo_value;
259 }
260
261 int tegra_cpu_speedo_0_value(void)
262 {
263         return cpu_speedo_0_value;
264 }
265
266 int tegra_cpu_speedo_1_value(void)
267 {
268         return cpu_speedo_1_value;
269 }
270
271 int tegra_gpu_speedo_value(void)
272 {
273         return gpu_speedo_value;
274 }
275
276 int tegra_soc_speedo_0_value(void)
277 {
278         return soc_speedo_0_value;
279 }
280
281 int tegra_soc_speedo_1_value(void)
282 {
283         return soc_speedo_1_value;
284 }
285
286 int tegra_soc_speedo_2_value(void)
287 {
288         return soc_speedo_2_value;
289 }
290 /*
291  * CPU and core nominal voltage levels as determined by chip SKU and speedo
292  * (not final - can be lowered by dvfs tables and rail dependencies; the
293  * latter is resolved by the dvfs code)
294  */
295 int tegra_cpu_speedo_mv(void)
296 {
297         /* Not applicable on Tegra12 */
298         return -ENOSYS;
299 }
300
301 int tegra_core_speedo_mv(void)
302 {
303         switch (soc_speedo_id) {
304         case 0:
305                 return 1150;
306         case 1:
307                 return 1150;
308         default:
309                 BUG();
310         }
311 }
312
313 int tegra_get_cpu_iddq_value(void)
314 {
315         return cpu_iddq_value;
316 }
317
318 int tegra_get_soc_iddq_value(void)
319 {
320         return soc_iddq_value;
321 }
322
323 int tegra_get_gpu_iddq_value(void)
324 {
325         return gpu_iddq_value;
326 }
327
328 static int get_enable_app_profiles(char *val, const struct kernel_param *kp)
329 {
330         return param_get_uint(val, kp);
331 }
332
333 static struct kernel_param_ops tegra_profiles_ops = {
334         .get = get_enable_app_profiles,
335 };
336
337 module_param_cb(tegra_enable_app_profiles,
338         &tegra_profiles_ops, &enable_app_profiles, 0444);