2 * arch/arm/mach-tegra/tegra11_speedo.c
4 * Copyright (C) 2012-2013, NVIDIA Corporation. All rights reserved.
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.
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
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.
21 #include <linux/kernel.h>
23 #include <linux/err.h>
24 #include <linux/bug.h> /* For BUG_ON. */
26 #include <linux/tegra-soc.h>
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/tegra-fuse.h>
34 #define CORE_PROCESS_CORNERS_NUM 2
35 #define CPU_PROCESS_CORNERS_NUM 2
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
47 static int threshold_index;
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;
58 static int enable_app_profiles;
60 static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
62 {1123, UINT_MAX}, /* [0]: threshold_index 0 */
63 {0, UINT_MAX}, /* [1]: threshold_index 1 */
66 static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
68 {1695, UINT_MAX}, /* [0]: threshold_index 0 */
69 {0, UINT_MAX}, /* [1]: threshold_index 1 */
72 static void rev_sku_to_speedo_ids(int rev, int sku)
75 cpu_speedo_id = 0; /* For A01 rev, regardless of SKU */
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);
89 case 0x20: /* T40DC */
104 case 0x08: /* AP40X */
112 /* FIXME: replace with BUG() when all SKU's valid */
113 pr_err("Tegra11 Unknown SKU %d\n", sku);
121 void tegra_init_speedo_data(void)
124 u32 ft_rev, ft_rev_major, ft_rev_minor;
126 cpu_speedo_value = 1024 + tegra_fuse_readl(FUSE_CPU_SPEEDO_1);
127 core_speedo_value = tegra_fuse_readl(FUSE_CORE_SPEEDO_0);
129 cpu_iddq_value = tegra_fuse_readl(FUSE_CPU_IDDQ);
131 ft_rev = tegra_fuse_readl(FUSE_FT_REV);
132 ft_rev_minor = ft_rev & 0x1f;
133 ft_rev_major = (ft_rev >> 5) & 0x3f;
135 if ((ft_rev_minor < 5) && (ft_rev_major == 0)) {
136 /* Implement: cpu_iddq = max(1.3*fused_cpu_iddq, 2 Amps) */
137 cpu_iddq_value *= 130;
138 cpu_iddq_value = cpu_iddq_value > 200000 ?
139 cpu_iddq_value : 200000;
140 cpu_iddq_value /= 100;
142 pr_warn("Tegra11: CPU IDDQ and speedo may be bogus");
145 rev_sku_to_speedo_ids(tegra_revision, tegra_get_sku_id());
147 pr_info("Tegra11: CPU Speedo ID %d, Soc Speedo ID %d",
148 cpu_speedo_id, soc_speedo_id);
149 pr_info("Tegra11: CPU Speedo Value %d, Soc Speedo Value %d",
150 cpu_speedo_value, core_speedo_value);
152 for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) {
153 if (cpu_speedo_value <
154 cpu_process_speedos[threshold_index][i]) {
160 for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) {
161 if (core_speedo_value <
162 core_process_speedos[threshold_index][i]) {
169 int tegra_cpu_process_id(void)
171 return cpu_process_id;
174 int tegra_core_process_id(void)
176 return core_process_id;
179 int tegra_cpu_speedo_id(void)
181 return cpu_speedo_id;
184 int tegra_soc_speedo_id(void)
186 return soc_speedo_id;
189 int tegra_package_id(void)
194 int tegra_cpu_speedo_value(void)
196 return cpu_speedo_value;
200 * CPU and core nominal voltage levels as determined by chip SKU and speedo
201 * (not final - can be lowered by dvfs tables and rail dependencies; the
202 * latter is resolved by the dvfs code)
204 int tegra_cpu_speedo_mv(void)
206 /* Not applicable on Tegra11 */
210 int tegra_core_speedo_mv(void)
214 tegra_sku_id = tegra_get_sku_id();
215 switch (soc_speedo_id) {
217 if (core_process_id == 1)
219 /* fall thru if core_process_id = 0 */
221 if ((tegra_sku_id == 0x4) || (tegra_sku_id == 0x8))
229 int tegra_get_cpu_iddq_value()
231 return cpu_iddq_value;
234 static int get_enable_app_profiles(char *val, const struct kernel_param *kp)
236 return param_get_uint(val, kp);
239 static struct kernel_param_ops tegra_profiles_ops = {
240 .get = get_enable_app_profiles,
243 module_param_cb(tegra_enable_app_profiles,
244 &tegra_profiles_ops, &enable_app_profiles, 0444);