ARM: tegra11: dvfs: Update CPU dvfs tables and bins
[linux-3.10.git] / arch / arm / mach-tegra / tegra11_speedo.c
1 /*
2  * arch/arm/mach-tegra/tegra11_speedo.c
3  *
4  * Copyright (C) 2012 NVIDIA Corporation
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 <mach/iomap.h>
27 #include <mach/tegra_fuse.h>
28 #include <mach/hardware.h>
29 #include <linux/module.h>
30 #include <linux/moduleparam.h>
31
32 #include "fuse.h"
33
34 #define CORE_PROCESS_CORNERS_NUM        2
35 #define CPU_PROCESS_CORNERS_NUM         2
36
37 #define FUSE_CPU_SPEEDO_0 0x114
38 #define FUSE_CPU_SPEEDO_1 0x12c
39 #define FUSE_CPU_IDDQ 0x118
40 #define FUSE_CORE_SPEEDO_0 0x134
41 #define FUSE_CORE_SPEEDO_1 0x138
42 #define FUSE_CORE_IDDQ 0x140
43 #define FUSE_FT_REV 0x128
44 #define FUSE_OPT_CPU23_DISABLE 0x26c
45 #define FUSE_OPT_CPU23_REENABLE 0x270
46
47 static int threshold_index;
48
49 static int cpu_process_id;
50 static int core_process_id;
51 static int cpu_speedo_id;
52 static int cpu_speedo_value;
53 static int soc_speedo_id;
54 static int core_speedo_value;
55 static int package_id;
56 static int cpu_iddq_value;
57
58 static int enable_app_profiles;
59
60 static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
61 /* proc_id  0,     1 */
62         {1123,     UINT_MAX}, /* [0]: threshold_index 0 */
63         {0,        UINT_MAX}, /* [1]: threshold_index 1 */
64 };
65
66 static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
67 /* proc_id  0,     1 */
68         {1695,     UINT_MAX}, /* [0]: threshold_index 0 */
69         {0,        UINT_MAX}, /* [1]: threshold_index 1 */
70 };
71
72 static void rev_sku_to_speedo_ids(int rev, int sku)
73 {
74         bool a01 = false;
75         cpu_speedo_id = 0;      /* For A01 rev, regardless of SKU */
76
77         if (rev == TEGRA_REVISION_A01) {
78                 u32 a01p = tegra_fuse_readl(FUSE_OPT_CPU23_REENABLE) << 1;
79                 a01p |= tegra_fuse_readl(FUSE_OPT_CPU23_DISABLE);
80                 if (a01p == 0)
81                         a01 = true;
82         }
83
84         switch (sku) {
85         case 0x00: /* Eng */
86         case 0x10: /* Eng */
87         case 0x05: /* T40S */
88         case 0x06: /* AP40 */
89                 if (!a01)
90                         cpu_speedo_id = 1;
91                 soc_speedo_id = 0;
92                 threshold_index = 0;
93                 break;
94
95         case 0x03: /* T40X */
96         case 0x04: /* T40T */
97                 if (!a01)
98                         cpu_speedo_id = 2;
99                 soc_speedo_id = 1;
100                 threshold_index = 1;
101                 break;
102
103         default:
104                 /* FIXME: replace with BUG() when all SKU's valid */
105                 pr_err("Tegra11 Unknown SKU %d\n", sku);
106                 cpu_speedo_id = 0;
107                 soc_speedo_id = 0;
108                 threshold_index = 0;
109                 break;
110         }
111 }
112
113 void tegra_init_speedo_data(void)
114 {
115         int i;
116         u32 ft_rev, ft_rev_major, ft_rev_minor;
117
118         cpu_speedo_value = 1024 + tegra_fuse_readl(FUSE_CPU_SPEEDO_1);
119         core_speedo_value = tegra_fuse_readl(FUSE_CORE_SPEEDO_0);
120
121         cpu_iddq_value = tegra_fuse_readl(FUSE_CPU_IDDQ);
122
123         ft_rev = tegra_fuse_readl(FUSE_FT_REV);
124         ft_rev_minor = ft_rev & 0x1f;
125         ft_rev_major = (ft_rev >> 5) & 0x3f;
126
127         if ((ft_rev_minor < 5) && (ft_rev_major == 0)) {
128                 /* Implement: cpu_iddq = max(1.3*fused_cpu_iddq, 2 Amps) */
129                 cpu_iddq_value *= 130;
130                 cpu_iddq_value = cpu_iddq_value > 200000 ?
131                         cpu_iddq_value : 200000;
132                 cpu_iddq_value /= 100;
133
134                 pr_warn("Tegra11: CPU IDDQ and speedo may be bogus");
135         }
136
137         rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id);
138
139         pr_info("Tegra11: CPU Speedo ID %d, Soc Speedo ID %d",
140                 cpu_speedo_id, soc_speedo_id);
141         pr_info("Tegra11: CPU Speedo Value %d, Soc Speedo Value %d",
142                 cpu_speedo_value, core_speedo_value);
143
144         for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) {
145                 if (cpu_speedo_value <
146                     cpu_process_speedos[threshold_index][i]) {
147                         break;
148                 }
149         }
150         cpu_process_id = i;
151
152         for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) {
153                 if (core_speedo_value <
154                     core_process_speedos[threshold_index][i]) {
155                         break;
156                 }
157         }
158         core_process_id = i;
159 }
160
161 int tegra_cpu_process_id(void)
162 {
163         return cpu_process_id;
164 }
165
166 int tegra_core_process_id(void)
167 {
168         return core_process_id;
169 }
170
171 int tegra_cpu_speedo_id(void)
172 {
173         return cpu_speedo_id;
174 }
175
176 int tegra_soc_speedo_id(void)
177 {
178         return soc_speedo_id;
179 }
180
181 int tegra_package_id(void)
182 {
183         return package_id;
184 }
185
186 int tegra_cpu_speedo_value(void)
187 {
188         return cpu_speedo_value;
189 }
190
191 /*
192  * CPU and core nominal voltage levels as determined by chip SKU and speedo
193  * (not final - can be lowered by dvfs tables and rail dependencies; the
194  * latter is resolved by the dvfs code)
195  */
196 int tegra_cpu_speedo_mv(void)
197 {
198         /* Not applicable on Tegra11 */
199         return -ENOSYS;
200 }
201
202 int tegra_core_speedo_mv(void)
203 {
204         switch (soc_speedo_id) {
205         case 0:
206                 if (core_process_id == 1)
207                         return 1170;
208         /* fall thru if core_process_id = 0 */
209         case 1:
210                 return 1250;
211         default:
212                 BUG();
213         }
214 }
215
216 int tegra_get_cpu_iddq_value()
217 {
218         return cpu_iddq_value;
219 }
220
221 static int get_enable_app_profiles(char *val, const struct kernel_param *kp)
222 {
223         return param_get_uint(val, kp);
224 }
225
226 static struct kernel_param_ops tegra_profiles_ops = {
227         .get = get_enable_app_profiles,
228 };
229
230 module_param_cb(tegra_enable_app_profiles,
231         &tegra_profiles_ops, &enable_app_profiles, 0444);