ARM: tegra: apply volt-temp constraints only if non-zero
[linux-3.10.git] / arch / arm / mach-tegra / edp.c
1 /*
2  * arch/arm/mach-tegra/edp.c
3  *
4  * Copyright (C) 2011-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 version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18  * 02111-1307, USA
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/init.h>
23 #include <linux/seq_file.h>
24 #include <linux/slab.h>
25 #include <linux/module.h>
26 #include <linux/uaccess.h>
27 #include <linux/edp.h>
28
29 #include <mach/edp.h>
30 #include <mach/hardware.h>
31
32 #include "fuse.h"
33 #include "dvfs.h"
34 #include "clock.h"
35 #include "cpu-tegra.h"
36
37 #define FREQ_STEP 12750000
38 #define OVERRIDE_DEFAULT 6000
39
40 static struct tegra_edp_limits *edp_limits;
41 static int edp_limits_size;
42 static unsigned int regulator_cur;
43 /* Value to subtract from regulator current limit */
44 static unsigned int edp_reg_override_mA = OVERRIDE_DEFAULT;
45
46 static const unsigned int *system_edp_limits;
47
48 static struct tegra_system_edp_entry *power_edp_limits;
49 static int power_edp_limits_size;
50
51 /*
52  * Temperature step size cannot be less than 4C because of hysteresis
53  * delta
54  * Code assumes different temperatures for the same speedo_id /
55  * regulator_cur are adjacent in the table, and higest regulator_cur
56  * comes first
57  */
58 static char __initdata tegra_edp_vdd_cpu_map[] = {
59         0x00, 0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x00,
60         0x2f, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f,
61         0x3c, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x4b,
62         0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x55, 0x82,
63         0x78, 0x78, 0x78, 0x00, 0x28, 0x17, 0x7d, 0x73,
64         0x73, 0x73, 0x00, 0x28, 0x2d, 0x82, 0x78, 0x78,
65         0x78, 0x00, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78,
66         0x00, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x00,
67         0x28, 0x55, 0x82, 0x78, 0x78, 0x69, 0x00, 0x23,
68         0x17, 0x7d, 0x73, 0x73, 0x73, 0x00, 0x23, 0x2d,
69         0x82, 0x78, 0x78, 0x78, 0x00, 0x23, 0x3c, 0x82,
70         0x78, 0x78, 0x6e, 0x00, 0x23, 0x4b, 0x82, 0x78,
71         0x78, 0x64, 0x00, 0x23, 0x55, 0x82, 0x78, 0x6e,
72         0x5a, 0x00, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64,
73         0x00, 0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x00,
74         0x1e, 0x3c, 0x82, 0x78, 0x78, 0x64, 0x00, 0x1e,
75         0x4b, 0x82, 0x78, 0x6e, 0x5a, 0x00, 0x1e, 0x55,
76         0x82, 0x78, 0x64, 0x50, 0x00, 0x19, 0x17, 0x7d,
77         0x73, 0x69, 0x55, 0x00, 0x19, 0x2d, 0x82, 0x78,
78         0x6e, 0x5a, 0x00, 0x19, 0x3c, 0x82, 0x78, 0x69,
79         0x55, 0x00, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b,
80         0x00, 0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x01,
81         0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x01, 0x2f,
82         0x2d, 0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x3c,
83         0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x4b, 0x82,
84         0x78, 0x78, 0x78, 0x01, 0x2f, 0x55, 0x82, 0x78,
85         0x78, 0x78, 0x01, 0x28, 0x17, 0x7d, 0x73, 0x73,
86         0x73, 0x01, 0x28, 0x2d, 0x82, 0x78, 0x78, 0x78,
87         0x01, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x01,
88         0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x01, 0x28,
89         0x55, 0x82, 0x78, 0x78, 0x69, 0x01, 0x23, 0x17,
90         0x7d, 0x73, 0x73, 0x73, 0x01, 0x23, 0x2d, 0x82,
91         0x78, 0x78, 0x78, 0x01, 0x23, 0x3c, 0x82, 0x78,
92         0x78, 0x6e, 0x01, 0x23, 0x4b, 0x82, 0x78, 0x78,
93         0x64, 0x01, 0x23, 0x55, 0x82, 0x78, 0x6e, 0x5a,
94         0x01, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64, 0x01,
95         0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x01, 0x1e,
96         0x3c, 0x82, 0x78, 0x78, 0x64, 0x01, 0x1e, 0x4b,
97         0x82, 0x78, 0x6e, 0x5a, 0x01, 0x1e, 0x55, 0x82,
98         0x78, 0x64, 0x50, 0x01, 0x19, 0x17, 0x7d, 0x73,
99         0x69, 0x55, 0x01, 0x19, 0x2d, 0x82, 0x78, 0x6e,
100         0x5a, 0x01, 0x19, 0x3c, 0x82, 0x78, 0x69, 0x55,
101         0x01, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b, 0x01,
102         0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x02, 0x3d,
103         0x17, 0x87, 0x7d, 0x7d, 0x7d, 0x02, 0x3d, 0x2d,
104         0x8c, 0x82, 0x82, 0x82, 0x02, 0x3d, 0x3c, 0x8c,
105         0x82, 0x82, 0x82, 0x02, 0x3d, 0x4b, 0x8c, 0x82,
106         0x82, 0x82, 0x02, 0x3d, 0x55, 0x8c, 0x82, 0x82,
107         0x82, 0x02, 0x32, 0x17, 0x87, 0x7d, 0x7d, 0x7d,
108         0x02, 0x32, 0x2d, 0x8c, 0x82, 0x82, 0x82, 0x02,
109         0x32, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x02, 0x32,
110         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x02, 0x32, 0x55,
111         0x8c, 0x82, 0x82, 0x6e, 0x02, 0x28, 0x17, 0x87,
112         0x7d, 0x7d, 0x73, 0x02, 0x28, 0x2d, 0x8c, 0x82,
113         0x82, 0x78, 0x02, 0x28, 0x3c, 0x8c, 0x82, 0x82,
114         0x73, 0x02, 0x28, 0x4b, 0x8c, 0x82, 0x78, 0x69,
115         0x02, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a, 0x02,
116         0x23, 0x17, 0x87, 0x7d, 0x7d, 0x69, 0x02, 0x23,
117         0x2d, 0x8c, 0x82, 0x82, 0x6e, 0x02, 0x23, 0x3c,
118         0x8c, 0x82, 0x78, 0x69, 0x02, 0x23, 0x4b, 0x8c,
119         0x82, 0x6e, 0x5a, 0x02, 0x23, 0x55, 0x8c, 0x82,
120         0x64, 0x50, 0x03, 0x3d, 0x17, 0x87, 0x7d, 0x7d,
121         0x7d, 0x03, 0x3d, 0x2d, 0x8c, 0x82, 0x82, 0x82,
122         0x03, 0x3d, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x03,
123         0x3d, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x3d,
124         0x55, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x32, 0x17,
125         0x87, 0x7d, 0x7d, 0x7d, 0x03, 0x32, 0x2d, 0x8c,
126         0x82, 0x82, 0x82, 0x03, 0x32, 0x3c, 0x8c, 0x82,
127         0x82, 0x82, 0x03, 0x32, 0x4b, 0x8c, 0x82, 0x82,
128         0x78, 0x03, 0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e,
129         0x03, 0x28, 0x17, 0x87, 0x7d, 0x7d, 0x73, 0x03,
130         0x28, 0x2d, 0x8c, 0x82, 0x82, 0x78, 0x03, 0x28,
131         0x3c, 0x8c, 0x82, 0x82, 0x73, 0x03, 0x28, 0x4b,
132         0x8c, 0x82, 0x78, 0x69, 0x03, 0x28, 0x55, 0x8c,
133         0x82, 0x6e, 0x5a, 0x03, 0x23, 0x17, 0x87, 0x7d,
134         0x7d, 0x69, 0x03, 0x23, 0x2d, 0x8c, 0x82, 0x82,
135         0x6e, 0x03, 0x23, 0x3c, 0x8c, 0x82, 0x78, 0x69,
136         0x03, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x03,
137         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x04, 0x32,
138         0x17, 0x91, 0x87, 0x87, 0x87, 0x04, 0x32, 0x2d,
139         0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x3c, 0x96,
140         0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x46, 0x96, 0x8c,
141         0x8c, 0x8c, 0x04, 0x32, 0x4b, 0x82, 0x78, 0x78,
142         0x78, 0x04, 0x32, 0x55, 0x82, 0x78, 0x78, 0x78,
143         0x04, 0x2f, 0x17, 0x91, 0x87, 0x87, 0x87, 0x04,
144         0x2f, 0x2d, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f,
145         0x3c, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f, 0x46,
146         0x96, 0x8c, 0x8c, 0x82, 0x04, 0x2f, 0x4b, 0x82,
147         0x78, 0x78, 0x78, 0x04, 0x2f, 0x55, 0x82, 0x78,
148         0x78, 0x78, 0x04, 0x28, 0x17, 0x91, 0x87, 0x87,
149         0x87, 0x04, 0x28, 0x2d, 0x96, 0x8c, 0x8c, 0x82,
150         0x04, 0x28, 0x3c, 0x96, 0x8c, 0x8c, 0x82, 0x04,
151         0x28, 0x46, 0x96, 0x8c, 0x8c, 0x78, 0x04, 0x28,
152         0x4b, 0x82, 0x78, 0x78, 0x78, 0x04, 0x28, 0x55,
153         0x82, 0x78, 0x78, 0x6e, 0x04, 0x23, 0x17, 0x91,
154         0x87, 0x87, 0x73, 0x04, 0x23, 0x2d, 0x96, 0x8c,
155         0x8c, 0x78, 0x04, 0x23, 0x3c, 0x96, 0x8c, 0x82,
156         0x78, 0x04, 0x23, 0x46, 0x96, 0x8c, 0x82, 0x6e,
157         0x04, 0x23, 0x4b, 0x82, 0x78, 0x78, 0x6e, 0x04,
158         0x23, 0x55, 0x82, 0x78, 0x78, 0x64, 0x04, 0x1e,
159         0x17, 0x91, 0x87, 0x7d, 0x69, 0x04, 0x1e, 0x2d,
160         0x96, 0x8c, 0x82, 0x6e, 0x04, 0x1e, 0x3c, 0x96,
161         0x8c, 0x78, 0x64, 0x04, 0x1e, 0x46, 0x96, 0x8c,
162         0x78, 0x5a, 0x04, 0x1e, 0x4b, 0x82, 0x78, 0x78,
163         0x5a, 0x04, 0x1e, 0x55, 0x82, 0x78, 0x64, 0x50,
164         0x04, 0x19, 0x17, 0x91, 0x87, 0x69, 0x55, 0x04,
165         0x19, 0x2d, 0x96, 0x8c, 0x6e, 0x5a, 0x04, 0x19,
166         0x3c, 0x96, 0x82, 0x6e, 0x55, 0x04, 0x19, 0x46,
167         0x96, 0x82, 0x64, 0x50, 0x04, 0x19, 0x4b, 0x82,
168         0x78, 0x64, 0x50, 0x04, 0x19, 0x55, 0x82, 0x78,
169         0x55, 0x3c, 0x05, 0x64, 0x17, 0xa5, 0x9b, 0x9b,
170         0x9b, 0x05, 0x64, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
171         0x05, 0x64, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x05,
172         0x64, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x05, 0x64,
173         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x64, 0x55,
174         0x8c, 0x82, 0x82, 0x82, 0x05, 0x50, 0x17, 0xa5,
175         0x9b, 0x9b, 0x9b, 0x05, 0x50, 0x2d, 0xaa, 0xa0,
176         0xa0, 0xa0, 0x05, 0x50, 0x3c, 0xaa, 0xa0, 0xa0,
177         0x96, 0x05, 0x50, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
178         0x05, 0x50, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05,
179         0x50, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x3c,
180         0x17, 0xa5, 0x9b, 0x9b, 0x87, 0x05, 0x3c, 0x2d,
181         0xaa, 0xa0, 0xa0, 0x8c, 0x05, 0x3c, 0x3c, 0xaa,
182         0xa0, 0x96, 0x82, 0x05, 0x3c, 0x46, 0xaa, 0xa0,
183         0x96, 0x78, 0x05, 0x3c, 0x4b, 0x8c, 0x82, 0x82,
184         0x78, 0x05, 0x3c, 0x55, 0x8c, 0x82, 0x82, 0x6e,
185         0x05, 0x28, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x05,
186         0x28, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x05, 0x28,
187         0x3c, 0xaa, 0x96, 0x78, 0x64, 0x05, 0x28, 0x46,
188         0xaa, 0x8c, 0x6e, 0x5a, 0x05, 0x28, 0x4b, 0x8c,
189         0x82, 0x6e, 0x5a, 0x05, 0x28, 0x55, 0x8c, 0x82,
190         0x64, 0x50, 0x06, 0x3d, 0x17, 0xa5, 0x9b, 0x7d,
191         0x7d, 0x06, 0x3d, 0x2d, 0xaa, 0xa0, 0x82, 0x82,
192         0x06, 0x3d, 0x3c, 0xaa, 0xa0, 0x82, 0x82, 0x06,
193         0x3d, 0x46, 0xaa, 0xa0, 0x82, 0x82, 0x06, 0x3d,
194         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x06, 0x3d, 0x55,
195         0x8c, 0x82, 0x82, 0x82, 0x06, 0x32, 0x17, 0xa5,
196         0x9b, 0x7d, 0x7d, 0x06, 0x32, 0x2d, 0xaa, 0xa0,
197         0x82, 0x82, 0x06, 0x32, 0x3c, 0xaa, 0xa0, 0x82,
198         0x82, 0x06, 0x32, 0x46, 0xaa, 0xa0, 0x82, 0x78,
199         0x06, 0x32, 0x4b, 0x8c, 0x82, 0x82, 0x78, 0x06,
200         0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e, 0x06, 0x28,
201         0x17, 0xa5, 0x9b, 0x7d, 0x73, 0x06, 0x28, 0x2d,
202         0xaa, 0xa0, 0x82, 0x78, 0x06, 0x28, 0x3c, 0xaa,
203         0x96, 0x82, 0x73, 0x06, 0x28, 0x46, 0xaa, 0x96,
204         0x78, 0x69, 0x06, 0x28, 0x4b, 0x8c, 0x82, 0x78,
205         0x69, 0x06, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a,
206         0x06, 0x23, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x06,
207         0x23, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x06, 0x23,
208         0x3c, 0xaa, 0x96, 0x78, 0x69, 0x06, 0x23, 0x46,
209         0xaa, 0x8c, 0x6e, 0x5a, 0x06, 0x23, 0x4b, 0x8c,
210         0x82, 0x6e, 0x5a, 0x06, 0x23, 0x55, 0x8c, 0x82,
211         0x64, 0x50, 0x07, 0x3b, 0x17, 0x7d, 0x73, 0x73,
212         0x73, 0x07, 0x3b, 0x2d, 0x82, 0x78, 0x78, 0x78,
213         0x07, 0x3b, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x07,
214         0x3b, 0x4b, 0x82, 0x78, 0x78, 0x78, 0x07, 0x3b,
215         0x5a, 0x82, 0x78, 0x78, 0x78, 0x07, 0x32, 0x17,
216         0x7d, 0x73, 0x73, 0x73, 0x07, 0x32, 0x2d, 0x82,
217         0x78, 0x78, 0x78, 0x07, 0x32, 0x3c, 0x82, 0x78,
218         0x78, 0x78, 0x07, 0x32, 0x4b, 0x82, 0x78, 0x78,
219         0x78, 0x07, 0x32, 0x5a, 0x82, 0x78, 0x6e, 0x64,
220         0x07, 0x28, 0x17, 0x7d, 0x73, 0x73, 0x69, 0x07,
221         0x28, 0x2d, 0x82, 0x78, 0x78, 0x6e, 0x07, 0x28,
222         0x3c, 0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x4b,
223         0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x5a, 0x82,
224         0x78, 0x64, 0x50, 0x07, 0x23, 0x17, 0x7d, 0x73,
225         0x73, 0x5f, 0x07, 0x23, 0x2d, 0x82, 0x78, 0x78,
226         0x64, 0x07, 0x23, 0x3c, 0x82, 0x78, 0x78, 0x64,
227         0x07, 0x23, 0x4b, 0x82, 0x78, 0x64, 0x50, 0x07,
228         0x23, 0x5a, 0x82, 0x78, 0x5a, 0x46, 0x08, 0x3b,
229         0x17, 0x7d, 0x73, 0x73, 0x73, 0x08, 0x3b, 0x2d,
230         0x82, 0x78, 0x78, 0x78, 0x08, 0x3b, 0x3c, 0x82,
231         0x78, 0x78, 0x78, 0x08, 0x3b, 0x4b, 0x82, 0x78,
232         0x78, 0x78, 0x08, 0x3b, 0x5a, 0x82, 0x78, 0x78,
233         0x78, 0x08, 0x32, 0x17, 0x7d, 0x73, 0x73, 0x73,
234         0x08, 0x32, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x08,
235         0x32, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32,
236         0x4b, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32, 0x5a,
237         0x82, 0x78, 0x6e, 0x64, 0x08, 0x28, 0x17, 0x7d,
238         0x73, 0x73, 0x69, 0x08, 0x28, 0x2d, 0x82, 0x78,
239         0x78, 0x6e, 0x08, 0x28, 0x3c, 0x82, 0x78, 0x78,
240         0x64, 0x08, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x64,
241         0x08, 0x28, 0x5a, 0x82, 0x78, 0x64, 0x50, 0x08,
242         0x23, 0x17, 0x7d, 0x73, 0x73, 0x5f, 0x08, 0x23,
243         0x2d, 0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x3c,
244         0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x4b, 0x82,
245         0x78, 0x64, 0x50, 0x08, 0x23, 0x5a, 0x82, 0x78,
246         0x5a, 0x46, 0x0c, 0x52, 0x17, 0xa5, 0x9b, 0x9b,
247         0x9b, 0x0c, 0x52, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
248         0x0c, 0x52, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c,
249         0x52, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c, 0x52,
250         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x52, 0x55,
251         0x8c, 0x82, 0x82, 0x82, 0x0c, 0x42, 0x17, 0xa5,
252         0x9b, 0x9b, 0x91, 0x0c, 0x42, 0x2d, 0xaa, 0xa0,
253         0xa0, 0x96, 0x0c, 0x42, 0x3c, 0xaa, 0xa0, 0xa0,
254         0x96, 0x0c, 0x42, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
255         0x0c, 0x42, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c,
256         0x42, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x3d,
257         0x17, 0xa5, 0x9b, 0x9b, 0x91, 0x0c, 0x3d, 0x2d,
258         0xaa, 0xa0, 0xa0, 0x96, 0x0c, 0x3d, 0x3c, 0xaa,
259         0xa0, 0xa0, 0x8c, 0x0c, 0x3d, 0x46, 0xaa, 0xa0,
260         0x96, 0x8c, 0x0c, 0x3d, 0x4b, 0x8c, 0x82, 0x82,
261         0x82, 0x0c, 0x3d, 0x55, 0x8c, 0x82, 0x82, 0x82,
262         0x0c, 0x32, 0x17, 0xa5, 0x9b, 0x91, 0x87, 0x0c,
263         0x32, 0x2d, 0xaa, 0xa0, 0x96, 0x8c, 0x0c, 0x32,
264         0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0c, 0x32, 0x46,
265         0xaa, 0xa0, 0x8c, 0x78, 0x0c, 0x32, 0x4b, 0x8c,
266         0x82, 0x82, 0x78, 0x0c, 0x32, 0x55, 0x8c, 0x82,
267         0x82, 0x6e, 0x0c, 0x28, 0x17, 0xa5, 0x9b, 0x87,
268         0x73, 0x0c, 0x28, 0x2d, 0xaa, 0xa0, 0x8c, 0x78,
269         0x0c, 0x28, 0x3c, 0xaa, 0x96, 0x82, 0x73, 0x0c,
270         0x28, 0x46, 0xaa, 0x96, 0x78, 0x69, 0x0c, 0x28,
271         0x4b, 0x8c, 0x82, 0x78, 0x69, 0x0c, 0x28, 0x55,
272         0x8c, 0x82, 0x6e, 0x5a, 0x0c, 0x23, 0x17, 0xa5,
273         0x91, 0x7d, 0x69, 0x0c, 0x23, 0x2d, 0xaa, 0x96,
274         0x82, 0x6e, 0x0c, 0x23, 0x3c, 0xaa, 0x96, 0x78,
275         0x69, 0x0c, 0x23, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
276         0x0c, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0c,
277         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x0d, 0x64,
278         0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d, 0x64, 0x2d,
279         0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x3c, 0xaa,
280         0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x46, 0xaa, 0xa0,
281         0xa0, 0xa0, 0x0d, 0x64, 0x4b, 0x8c, 0x82, 0x82,
282         0x82, 0x0d, 0x64, 0x55, 0x8c, 0x82, 0x82, 0x82,
283         0x0d, 0x50, 0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d,
284         0x50, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x50,
285         0x3c, 0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x46,
286         0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x4b, 0x8c,
287         0x82, 0x82, 0x82, 0x0d, 0x50, 0x55, 0x8c, 0x82,
288         0x82, 0x82, 0x0d, 0x3c, 0x17, 0xa5, 0x9b, 0x9b,
289         0x87, 0x0d, 0x3c, 0x2d, 0xaa, 0xa0, 0xa0, 0x8c,
290         0x0d, 0x3c, 0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0d,
291         0x3c, 0x46, 0xaa, 0xa0, 0x96, 0x78, 0x0d, 0x3c,
292         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x0d, 0x3c, 0x55,
293         0x8c, 0x82, 0x82, 0x6e, 0x0d, 0x28, 0x17, 0xa5,
294         0x91, 0x7d, 0x69, 0x0d, 0x28, 0x2d, 0xaa, 0x96,
295         0x82, 0x6e, 0x0d, 0x28, 0x3c, 0xaa, 0x96, 0x78,
296         0x64, 0x0d, 0x28, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
297         0x0d, 0x28, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0d,
298         0x28, 0x55, 0x8c, 0x82, 0x64, 0x50,
299 };
300
301
302 static struct tegra_system_edp_entry __initdata tegra_system_edp_map[] = {
303
304 /* {SKU, power-limit (in 100mW), {freq limits (in 10Mhz)} } */
305
306         {  1,  49, {130, 120, 120, 120} },
307         {  1,  44, {130, 120, 120, 110} },
308         {  1,  37, {130, 120, 110, 100} },
309         {  1,  35, {130, 120, 110,  90} },
310         {  1,  29, {130, 120, 100,  80} },
311         {  1,  27, {130, 120,  90,  80} },
312         {  1,  25, {130, 110,  80,  60} },
313         {  1,  21, {130, 100,  80,  40} },
314
315         {  4,  49, {130, 120, 120, 120} },
316         {  4,  44, {130, 120, 120, 110} },
317         {  4,  37, {130, 120, 110, 100} },
318         {  4,  35, {130, 120, 110,  90} },
319         {  4,  29, {130, 120, 100,  80} },
320         {  4,  27, {130, 120,  90,  80} },
321         {  4,  25, {130, 110,  80,  60} },
322         {  4,  21, {130, 100,  80,  40} },
323 };
324
325 /*
326  * "Safe entry" to be used when no match for speedo_id /
327  * regulator_cur is found; must be the last one
328  */
329 static struct tegra_edp_limits edp_default_limits[] = {
330         {85, {1000000, 1000000, 1000000, 1000000} },
331 };
332
333 static struct tegra_system_edp_entry power_edp_default_limits[] = {
334         {0, 20, {1000000, 1000000, 1000000, 1000000} },
335 };
336
337 /* Constants for EDP calculations */
338 static const int temperatures[] = { /* degree celcius (C) */
339         23, 40, 50, 60, 70, 74, 78, 82, 86, 90, 94, 98, 102,
340 };
341
342 static const int power_cap_levels[] = { /* milliwatts (mW) */
343           700,  1700,  2700,  3700,  3800,  3900,  4500,  4600,
344          4700,  4800,  4900,  5200,  5300,  5400,  5500,  5800,
345          5900,  6200,  6400,  6500,  6800,  7200,  7500,  8200,
346          8500,  9200,  9500, 10200, 10500, 11200, 11500, 12200,
347         12500, 13200, 13500, 14200, 14500, 15200, 15500, 16500,
348         17500
349 };
350
351 #ifdef CONFIG_ARCH_TEGRA_14x_SOC
352 static struct tegra_edp_cpu_leakage_params leakage_params[] = {
353         {
354                 .cpu_speedo_id      = 0, /* A01 CPU */
355                 .dyn_consts_n       = {  643724,  908655, 1173586, 1438517 },
356                 .leakage_consts_n   = {  524409,  699606,  874803, 1050000 },
357                 .leakage_consts_ijk = {
358                         /* i = 0 */
359                         { {   0,   -5346808,   97234,   -464, },
360                           {   0,   16803984, -307162,   1481, },
361                           {   0,  -17730060,  322460,  -1546, },
362                           {   0,    6489900, -118190,    564, },
363                         },
364                         /* i = 1 */
365                         { {   0,   -7166070,   16144,  -2495, },
366                           {   0,   22733881,  -62339,   7849, },
367                           {   0,  -22851718,   17626,  -7211, },
368                           {   0,    8845764,   -3232,   2668, },
369                         },
370                         /* i = 2 */
371                         { {   0,  -13755297,   88228,    194, },
372                           {   0,   43058825, -281494,   -604, },
373                           {   0,  -45854189,  328873,    337, },
374                           {   0,   17332703, -123100,   -128, },
375                         },
376                         /* i = 3 */
377                         { {   0,    1950888,   -8210,    -62, },
378                           {   0,   -6086732,   26052,    197, },
379                           {   0,    6462190,  -32222,   -161, },
380                           {   0,   -2416618,   11593,     62, },
381                         },
382                  },
383                 /* .volt_temp_cap = { 70, 1240 }, - TODO for T148 */
384         },
385 };
386 #else
387 static struct tegra_edp_cpu_leakage_params leakage_params[] = {
388         {
389                 .cpu_speedo_id      = 0, /* A01 CPU */
390                 .dyn_consts_n       = { 1091747, 2035205, 2978661, 3922119 },
391                 .leakage_consts_n   = {  538991,  752463,  959441, 1150000 },
392                 .leakage_consts_ijk = {
393                          /* i = 0 */
394                          { {  -42746668,   -5458429,   164998,  -1711, },
395                            {  178262421,   13375684,  -411791,   4590, },
396                            { -228866784,  -10482993,   331248,  -4062, },
397                            {   94301550,    2618719,   -85983,   1193, },
398                          },
399                          /* i = 1 */
400                          { { -256611791,   49677413, -1655785,  14917, },
401                            {  584675433, -132620939,  4541560, -41812, },
402                            { -398106336,  115987156, -4102328,  38737, },
403                            {   68897184,  -33030745,  1217839, -11801, },
404                          },
405                          /* i = 2 */
406                          { {  186324676,  -36019083,  1177969, -10669, },
407                            { -439237936,   98429131, -3276444,  30301, },
408                            {  315060898,  -88635036,  3004777, -28474, },
409                            {  -60854399,   26267188,  -907121,   8844, },
410                          },
411                          /* i = 3 */
412                          { {  -35432997,    6154621,  -202200,   1830, },
413                            {   87402153,  -16908683,   565152,  -5220, },
414                            {  -67775314,   15326770,  -521221,   4927, },
415                            {   15618709,   -4576116,   158401,  -1538, },
416                          },
417                  },
418                 .volt_temp_cap = { 70, 1240 },
419         },
420         {
421                 .cpu_speedo_id      = 1, /* A01P+ CPU */
422                 .dyn_consts_n       = { 1091747, 2035205, 2978661, 3922119 },
423                 .leakage_consts_n   = {  538991,  752463,  959441, 1150000 },
424                 .leakage_consts_ijk = {
425                          /* i = 0 */
426                          { {  -42746668,   -5458429,   164998,  -1711, },
427                            {  178262421,   13375684,  -411791,   4590, },
428                            { -228866784,  -10482993,   331248,  -4062, },
429                            {   94301550,    2618719,   -85983,   1193, },
430                          },
431                          /* i = 1 */
432                          { { -256611791,   49677413, -1655785,  14917, },
433                            {  584675433, -132620939,  4541560, -41812, },
434                            { -398106336,  115987156, -4102328,  38737, },
435                            {   68897184,  -33030745,  1217839, -11801, },
436                          },
437                          /* i = 2 */
438                          { {  186324676,  -36019083,  1177969, -10669, },
439                            { -439237936,   98429131, -3276444,  30301, },
440                            {  315060898,  -88635036,  3004777, -28474, },
441                            {  -60854399,   26267188,  -907121,   8844, },
442                          },
443                          /* i = 3 */
444                          { {  -35432997,    6154621,  -202200,   1830, },
445                            {   87402153,  -16908683,   565152,  -5220, },
446                            {  -67775314,   15326770,  -521221,   4927, },
447                            {   15618709,   -4576116,   158401,  -1538, },
448                          },
449                  },
450                 .safety_cap = { 1810500, 1810500, 1606500, 1606500 },
451                 .volt_temp_cap = { 70, 1240 },
452         },
453         {
454                 .cpu_speedo_id      = 2, /* A01P+ fast CPU */
455                 .dyn_consts_n       = { 1091747, 2035205, 2978661, 3922119 },
456                 .leakage_consts_n   = {  538991,  752463,  959441, 1150000 },
457                 .leakage_consts_ijk = {
458                          /* i = 0 */
459                          { {  -42746668,   -5458429,   164998,  -1711, },
460                            {  178262421,   13375684,  -411791,   4590, },
461                            { -228866784,  -10482993,   331248,  -4062, },
462                            {   94301550,    2618719,   -85983,   1193, },
463                          },
464                          /* i = 1 */
465                          { { -256611791,   49677413, -1655785,  14917, },
466                            {  584675433, -132620939,  4541560, -41812, },
467                            { -398106336,  115987156, -4102328,  38737, },
468                            {   68897184,  -33030745,  1217839, -11801, },
469                          },
470                          /* i = 2 */
471                          { {  186324676,  -36019083,  1177969, -10669, },
472                            { -439237936,   98429131, -3276444,  30301, },
473                            {  315060898,  -88635036,  3004777, -28474, },
474                            {  -60854399,   26267188,  -907121,   8844, },
475                          },
476                          /* i = 3 */
477                          { {  -35432997,    6154621,  -202200,   1830, },
478                            {   87402153,  -16908683,   565152,  -5220, },
479                            {  -67775314,   15326770,  -521221,   4927, },
480                            {   15618709,   -4576116,   158401,  -1538, },
481                          },
482                  },
483                 .safety_cap = { 1912500, 1912500, 1912500, 1912500 },
484                 .volt_temp_cap = { 70, 1240 },
485         },
486 };
487 #endif
488
489 static struct tegra_edp_freq_voltage_table *freq_voltage_lut_saved;
490 static unsigned int freq_voltage_lut_size_saved;
491 static struct tegra_edp_freq_voltage_table *freq_voltage_lut;
492 static unsigned int freq_voltage_lut_size;
493
494 static inline s64 edp_pow(s64 val, int pwr)
495 {
496         s64 retval = 1;
497
498         while (pwr) {
499                 if (pwr & 1)
500                         retval *= val;
501                 pwr >>= 1;
502                 if (pwr)
503                         val *= val;
504         }
505
506         return retval;
507 }
508
509 /*
510  * Find the maximum frequency that results in dynamic and leakage current that
511  * is less than the regulator current limit.
512  * temp_C - always valid
513  * power_mW - valid or -1 (infinite)
514  */
515 static unsigned int edp_calculate_maxf(
516                                 struct tegra_edp_cpu_leakage_params *params,
517                                 int temp_C, int power_mW,
518                                 int iddq_mA,
519                                 int n_cores_idx)
520 {
521         unsigned int voltage_mV, freq_KHz;
522         unsigned int cur_effective = regulator_cur - edp_reg_override_mA;
523         int f, i, j, k;
524         s64 leakage_mA, dyn_mA, leakage_calc_step;
525         s64 leakage_mW, dyn_mW;
526
527         for (f = freq_voltage_lut_size - 1; f >= 0; f--) {
528                 freq_KHz = freq_voltage_lut[f].freq / 1000;
529                 voltage_mV = freq_voltage_lut[f].voltage_mV;
530
531                 /* Constrain Volt-Temp */
532                 if (params->volt_temp_cap.temperature &&
533                     temp_C > params->volt_temp_cap.temperature &&
534                     params->volt_temp_cap.voltage_limit_mV &&
535                     voltage_mV > params->volt_temp_cap.voltage_limit_mV)
536                         continue;
537
538                 /* Calculate leakage current */
539                 leakage_mA = 0;
540                 for (i = 0; i <= 3; i++) {
541                         for (j = 0; j <= 3; j++) {
542                                 for (k = 0; k <= 3; k++) {
543                                         leakage_calc_step =
544                                                 params->leakage_consts_ijk
545                                                 [i][j][k] * edp_pow(iddq_mA, i);
546                                         /* Convert (mA)^i to (A)^i */
547                                         leakage_calc_step =
548                                                 div64_s64(leakage_calc_step,
549                                                           edp_pow(1000, i));
550                                         leakage_calc_step *=
551                                                 edp_pow(voltage_mV, j);
552                                         /* Convert (mV)^i to (V)^i */
553                                         leakage_calc_step =
554                                                 div64_s64(leakage_calc_step,
555                                                           edp_pow(1000, j));
556                                         leakage_calc_step *=
557                                                 edp_pow(temp_C, k);
558                                         /* leakage_consts_ijk was X 100,000 */
559                                         leakage_calc_step =
560                                                 div64_s64(leakage_calc_step,
561                                                           100000);
562                                         leakage_mA += leakage_calc_step;
563                                 }
564                         }
565                 }
566                 leakage_mA *= params->leakage_consts_n[n_cores_idx];
567                 /* leakage_const_n was pre-multiplied by 1,000,000 */
568                 leakage_mA = div64_s64(leakage_mA, 1000000);
569
570                 /* Calculate dynamic current */
571                 dyn_mA = voltage_mV * freq_KHz / 1000;
572                 /* Convert mV to V */
573                 dyn_mA = div64_s64(dyn_mA, 1000);
574                 dyn_mA *= params->dyn_consts_n[n_cores_idx];
575                 /* dyn_const_n was pre-multiplied by 1,000,000 */
576                 dyn_mA = div64_s64(dyn_mA, 1000000);
577
578                 if (power_mW != -1) {
579                         leakage_mW = leakage_mA * voltage_mV;
580                         dyn_mW = dyn_mA * voltage_mV;
581                         if (div64_s64(leakage_mW + dyn_mW, 1000) <= power_mW)
582                                 return freq_KHz;
583                 } else if ((leakage_mA + dyn_mA) <= cur_effective) {
584                         return freq_KHz;
585                 }
586         }
587         return 0;
588 }
589
590 static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
591                         unsigned int cpu_speedo_idx,
592                         unsigned int freq_volt_lut_size,
593                         struct tegra_edp_freq_voltage_table *freq_volt_lut)
594 {
595         unsigned int i, j, freq;
596         int voltage_mV;
597
598         for (i = 0, j = 0, freq = 0;
599                  i < freq_volt_lut_size;
600                  i++, freq += FREQ_STEP) {
601
602                 /* Predict voltages */
603                 voltage_mV = tegra_dvfs_predict_millivolts(clk_cpu_g, freq);
604                 if (voltage_mV < 0) {
605                         pr_err("%s: couldn't predict voltage: freq %u; err %d",
606                                __func__, freq, voltage_mV);
607                         return -EINVAL;
608                 }
609
610                 /* Cache frequency / voltage / voltage constant relationship */
611                 freq_volt_lut[i].freq = freq;
612                 freq_volt_lut[i].voltage_mV = voltage_mV;
613         }
614         return 0;
615 }
616
617 unsigned int tegra_edp_find_maxf(int volt)
618 {
619         unsigned int i;
620
621         for (i = 0; i < freq_voltage_lut_size_saved; i++) {
622                 if (freq_voltage_lut_saved[i].voltage_mV > volt)
623                         break;
624         }
625         return freq_voltage_lut[i - 1].freq;
626 }
627
628
629 static int edp_find_speedo_idx(int cpu_speedo_id, unsigned int *cpu_speedo_idx)
630 {
631         int i;
632
633         for (i = 0; i < ARRAY_SIZE(leakage_params); i++)
634                 if (cpu_speedo_id == leakage_params[i].cpu_speedo_id) {
635                         *cpu_speedo_idx = i;
636                         return 0;
637                 }
638
639         pr_err("%s: couldn't find cpu speedo id %d in freq/voltage LUT\n",
640                __func__, cpu_speedo_id);
641         return -EINVAL;
642 }
643
644 static int init_cpu_edp_limits_calculated(void)
645 {
646         unsigned int temp_idx, n_cores_idx, pwr_idx;
647         unsigned int cpu_g_minf, cpu_g_maxf;
648         unsigned int iddq_mA;
649         unsigned int cpu_speedo_idx;
650         unsigned int cap, limit;
651         struct tegra_edp_limits *edp_calculated_limits;
652         struct tegra_system_edp_entry *power_edp_calc_limits;
653         struct tegra_edp_cpu_leakage_params *params;
654         int ret;
655         struct clk *clk_cpu_g = tegra_get_clock_by_name("cpu_g");
656         int cpu_speedo_id = tegra_cpu_speedo_id();
657
658         /* Determine all inputs to EDP formula */
659         iddq_mA = tegra_get_cpu_iddq_value();
660         ret = edp_find_speedo_idx(cpu_speedo_id, &cpu_speedo_idx);
661         if (ret)
662                 return ret;
663
664         params = &leakage_params[cpu_speedo_idx];
665
666         edp_calculated_limits = kmalloc(sizeof(struct tegra_edp_limits)
667                                         * ARRAY_SIZE(temperatures), GFP_KERNEL);
668         BUG_ON(!edp_calculated_limits);
669
670         power_edp_calc_limits = kmalloc(sizeof(struct tegra_system_edp_entry)
671                                 * ARRAY_SIZE(power_cap_levels), GFP_KERNEL);
672         BUG_ON(!power_edp_calc_limits);
673
674         cpu_g_minf = 0;
675         cpu_g_maxf = clk_get_max_rate(clk_cpu_g);
676         freq_voltage_lut_size = (cpu_g_maxf - cpu_g_minf) / FREQ_STEP + 1;
677         freq_voltage_lut = kmalloc(sizeof(struct tegra_edp_freq_voltage_table)
678                                    * freq_voltage_lut_size, GFP_KERNEL);
679         if (!freq_voltage_lut) {
680                 pr_err("%s: failed alloc mem for freq/voltage LUT\n", __func__);
681                 kfree(power_edp_calc_limits);
682                 kfree(edp_calculated_limits);
683                 return -ENOMEM;
684         }
685
686         ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx,
687                                 freq_voltage_lut_size, freq_voltage_lut);
688         if (ret) {
689                 kfree(power_edp_calc_limits);
690                 kfree(edp_calculated_limits);
691                 kfree(freq_voltage_lut);
692                 return ret;
693         }
694
695         if (freq_voltage_lut_size != freq_voltage_lut_size_saved) {
696                 /* release previous table if present */
697                 kfree(freq_voltage_lut_saved);
698                 /* create table to save */
699                 freq_voltage_lut_saved =
700                         kmalloc(sizeof(struct tegra_edp_freq_voltage_table) *
701                         freq_voltage_lut_size, GFP_KERNEL);
702                 if (!freq_voltage_lut_saved) {
703                         pr_err("%s: failed alloc mem for freq/voltage LUT\n",
704                                 __func__);
705                         kfree(freq_voltage_lut);
706                         return -ENOMEM;
707                 }
708                 freq_voltage_lut_size_saved = freq_voltage_lut_size;
709         }
710         memcpy(freq_voltage_lut_saved,
711                 freq_voltage_lut,
712                 sizeof(struct tegra_edp_freq_voltage_table) *
713                         freq_voltage_lut_size);
714
715         /* Calculate EDP table */
716         for (n_cores_idx = 0; n_cores_idx < NR_CPUS; n_cores_idx++) {
717                 for (temp_idx = 0;
718                      temp_idx < ARRAY_SIZE(temperatures); temp_idx++) {
719                         edp_calculated_limits[temp_idx].temperature =
720                                 temperatures[temp_idx];
721                         limit = edp_calculate_maxf(params,
722                                                    temperatures[temp_idx],
723                                                    -1,
724                                                    iddq_mA,
725                                                    n_cores_idx);
726                         /* apply safety cap if it is specified */
727                         if (n_cores_idx < 4) {
728                                 cap = params->safety_cap[n_cores_idx];
729                                 if (cap && cap < limit)
730                                         limit = cap;
731                         }
732                         edp_calculated_limits[temp_idx].
733                                 freq_limits[n_cores_idx] = limit;
734                 }
735
736                 for (pwr_idx = 0;
737                      pwr_idx < ARRAY_SIZE(power_cap_levels); pwr_idx++) {
738                         power_edp_calc_limits[pwr_idx].power_limit_100mW =
739                                 power_cap_levels[pwr_idx] / 100;
740                         limit = edp_calculate_maxf(params,
741                                                    90,
742                                                    power_cap_levels[pwr_idx],
743                                                    iddq_mA,
744                                                    n_cores_idx);
745                         power_edp_calc_limits[pwr_idx].
746                                 freq_limits[n_cores_idx] = limit;
747                 }
748         }
749
750         /*
751          * If this is an EDP table update, need to overwrite old table.
752          * The old table's address must remain valid.
753          */
754         if (edp_limits != edp_default_limits) {
755                 memcpy(edp_limits, edp_calculated_limits,
756                        sizeof(struct tegra_edp_limits)
757                        * ARRAY_SIZE(temperatures));
758                 kfree(edp_calculated_limits);
759         }
760         else {
761                 edp_limits = edp_calculated_limits;
762                 edp_limits_size = ARRAY_SIZE(temperatures);
763         }
764
765         if (power_edp_limits != power_edp_default_limits) {
766                 memcpy(power_edp_limits, power_edp_calc_limits,
767                        sizeof(struct tegra_system_edp_entry)
768                        * ARRAY_SIZE(power_cap_levels));
769                 kfree(power_edp_calc_limits);
770         } else {
771                 power_edp_limits = power_edp_calc_limits;
772                 power_edp_limits_size = ARRAY_SIZE(power_cap_levels);
773         }
774
775         kfree(freq_voltage_lut);
776         return 0;
777 }
778
779 static int __init init_cpu_edp_limits_lookup(void)
780 {
781         int i, j;
782         struct tegra_edp_limits *e;
783         struct tegra_edp_vdd_cpu_entry *t;
784         int tsize;
785         int cpu_speedo_id = tegra_cpu_speedo_id();
786
787         t = (struct tegra_edp_vdd_cpu_entry *)tegra_edp_vdd_cpu_map;
788         tsize = sizeof(tegra_edp_vdd_cpu_map)
789                 / sizeof(struct tegra_edp_vdd_cpu_entry);
790
791         for (i = 0; i < tsize; i++) {
792                 if (t[i].speedo_id == cpu_speedo_id &&
793                     t[i].regulator_100mA <= regulator_cur / 100)
794                         break;
795         }
796
797         /* No entry found in tegra_edp_vdd_cpu_map */
798         if (i >= tsize)
799                 return -EINVAL;
800
801         /* Find all rows for this entry */
802         for (j = i + 1; j < tsize; j++) {
803                 if (t[i].speedo_id != t[j].speedo_id ||
804                     t[i].regulator_100mA != t[j].regulator_100mA)
805                         break;
806         }
807
808         edp_limits_size = j - i;
809         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
810                     GFP_KERNEL);
811         BUG_ON(!e);
812
813         for (j = 0; j < edp_limits_size; j++) {
814                 e[j].temperature = (int)t[i+j].temperature;
815                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0]*10000;
816                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1]*10000;
817                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2]*10000;
818                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3]*10000;
819         }
820
821         if (edp_limits != edp_default_limits)
822                 kfree(edp_limits);
823
824         edp_limits = e;
825         return 0;
826 }
827
828 void tegra_recalculate_cpu_edp_limits(void)
829 {
830         if (tegra_chip_id == TEGRA_CHIPID_TEGRA11)
831                 init_cpu_edp_limits_calculated();
832 }
833
834 /*
835  * Specify regulator current in mA, e.g. 5000mA
836  * Use 0 for default
837  */
838 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
839 {
840         if (!regulator_mA)
841                 goto end;
842         regulator_cur = regulator_mA + OVERRIDE_DEFAULT;
843
844         switch (tegra_chip_id) {
845         case TEGRA_CHIPID_TEGRA3:
846                 if (init_cpu_edp_limits_lookup() == 0)
847                         return;
848                 break;
849         case TEGRA_CHIPID_TEGRA11:
850         case TEGRA_CHIPID_TEGRA14:
851                 if (init_cpu_edp_limits_calculated() == 0)
852                         return;
853                 break;
854         case TEGRA_CHIPID_TEGRA2:
855         default:
856                 BUG();
857                 break;
858         }
859
860  end:
861         edp_limits = edp_default_limits;
862         edp_limits_size = ARRAY_SIZE(edp_default_limits);
863
864         power_edp_limits = power_edp_default_limits;
865         power_edp_limits_size = ARRAY_SIZE(power_edp_default_limits);
866 }
867
868 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
869 {
870         int cpu_speedo_id = tegra_cpu_speedo_id();
871         int i;
872         unsigned int *e;
873         struct tegra_system_edp_entry *t = tegra_system_edp_map;
874         int tsize = ARRAY_SIZE(tegra_system_edp_map);
875
876         if (!power_limit_mW) {
877                 e = NULL;
878                 goto out;
879         }
880
881         for (i = 0; i < tsize; i++)
882                 if (t[i].speedo_id == cpu_speedo_id)
883                         break;
884
885         if (i >= tsize) {
886                 e = NULL;
887                 goto out;
888         }
889
890         do {
891                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
892                         break;
893                 i++;
894         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
895
896         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
897                 i--; /* No low enough entry in the table, use best possible */
898
899         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
900         BUG_ON(!e);
901
902         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
903         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
904         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
905         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
906
907 out:
908         kfree(system_edp_limits);
909
910         system_edp_limits = e;
911 }
912
913
914 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
915 {
916         *limits = edp_limits;
917         *size = edp_limits_size;
918 }
919
920 void tegra_get_system_edp_limits(const unsigned int **limits)
921 {
922         *limits = system_edp_limits;
923 }
924
925 void tegra_platform_edp_init(struct thermal_trip_info *trips,
926                                 int *num_trips, int margin)
927 {
928         const struct tegra_edp_limits *cpu_edp_limits;
929         struct thermal_trip_info *trip_state;
930         int i, cpu_edp_limits_size;
931
932         if (!trips || !num_trips)
933                 return;
934
935         /* edp capping */
936         tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size);
937
938         if (cpu_edp_limits_size > MAX_THROT_TABLE_SIZE)
939                 BUG();
940
941         for (i = 0; i < cpu_edp_limits_size-1; i++) {
942                 trip_state = &trips[*num_trips];
943
944                 trip_state->cdev_type = "cpu_edp";
945                 trip_state->trip_temp =
946                         (cpu_edp_limits[i].temperature * 1000) - margin;
947                 trip_state->trip_type = THERMAL_TRIP_ACTIVE;
948                 trip_state->upper = trip_state->lower = i + 1;
949
950                 (*num_trips)++;
951
952                 if (*num_trips >= THERMAL_MAX_TRIPS)
953                         BUG();
954         }
955 }
956
957 struct tegra_system_edp_entry *tegra_get_system_edp_entries(int *size)
958 {
959         *size = power_edp_limits_size;
960         return power_edp_limits;
961 }
962
963 #ifdef CONFIG_DEBUG_FS
964
965 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
966 {
967 #ifdef CONFIG_CPU_FREQ
968         seq_printf(s, "%u\n", tegra_get_edp_limit(NULL));
969 #endif
970         return 0;
971 }
972
973 static int edp_debugfs_show(struct seq_file *s, void *data)
974 {
975         int i, th_idx;
976
977 #ifdef CONFIG_CPU_FREQ
978         tegra_get_edp_limit(&th_idx);
979 #else
980         th_idx = 0;
981 #endif
982         seq_printf(s, "-- VDD_CPU %sEDP table (%umA = %umA - %umA) --\n",
983                    edp_limits == edp_default_limits ? "default " : "",
984                    regulator_cur - edp_reg_override_mA,
985                    regulator_cur, edp_reg_override_mA);
986         seq_printf(s, "%6s %10s %10s %10s %10s\n",
987                    " Temp.", "1-core", "2-cores", "3-cores", "4-cores");
988         for (i = 0; i < edp_limits_size; i++) {
989                 seq_printf(s, "%c%3dC: %10u %10u %10u %10u\n",
990                            i == th_idx ? '>' : ' ',
991                            edp_limits[i].temperature,
992                            edp_limits[i].freq_limits[0],
993                            edp_limits[i].freq_limits[1],
994                            edp_limits[i].freq_limits[2],
995                            edp_limits[i].freq_limits[3]);
996         }
997
998         seq_printf(s, "-- VDD_CPU Power EDP table --\n");
999         seq_printf(s, "%6s %10s %10s %10s %10s\n",
1000                    " Power", "1-core", "2-cores", "3-cores", "4-cores");
1001         for (i = 0; i < power_edp_limits_size; i++) {
1002                 seq_printf(s, "%5dmW: %10u %10u %10u %10u\n",
1003                            power_edp_limits[i].power_limit_100mW * 100,
1004                            power_edp_limits[i].freq_limits[0],
1005                            power_edp_limits[i].freq_limits[1],
1006                            power_edp_limits[i].freq_limits[2],
1007                            power_edp_limits[i].freq_limits[3]);
1008         }
1009
1010         if (system_edp_limits) {
1011                 seq_printf(s, "\n-- System EDP table --\n");
1012                 seq_printf(s, "%10u %10u %10u %10u\n",
1013                            system_edp_limits[0],
1014                            system_edp_limits[1],
1015                            system_edp_limits[2],
1016                            system_edp_limits[3]);
1017         }
1018
1019         return 0;
1020 }
1021
1022 static int edp_reg_override_show(struct seq_file *s, void *data)
1023 {
1024         seq_printf(s, "Limit override: %u mA. Effective limit: %u mA\n",
1025                    edp_reg_override_mA, regulator_cur - edp_reg_override_mA);
1026         return 0;
1027 }
1028
1029 static int edp_reg_override_write(struct file *file,
1030         const char __user *userbuf, size_t count, loff_t *ppos)
1031 {
1032         char buf[32], *end;
1033         unsigned int edp_reg_override_mA_temp;
1034         unsigned int edp_reg_override_mA_prev = edp_reg_override_mA;
1035
1036         if (sizeof(buf) <= count)
1037                 goto override_err;
1038
1039         if (copy_from_user(buf, userbuf, count))
1040                 goto override_err;
1041
1042         /* terminate buffer and trim - white spaces may be appended
1043          *  at the end when invoked from shell command line */
1044         buf[count]='\0';
1045         strim(buf);
1046
1047         edp_reg_override_mA_temp = simple_strtoul(buf, &end, 10);
1048         if (*end != '\0')
1049                 goto override_err;
1050
1051         if (edp_reg_override_mA_temp >= regulator_cur)
1052                 goto override_err;
1053
1054         if (edp_reg_override_mA == edp_reg_override_mA_temp)
1055                 return count;
1056
1057         edp_reg_override_mA = edp_reg_override_mA_temp;
1058         if (init_cpu_edp_limits_calculated()) {
1059                 /* Revert to previous override value if new value fails */
1060                 edp_reg_override_mA = edp_reg_override_mA_prev;
1061                 goto override_err;
1062         }
1063
1064 #ifdef CONFIG_CPU_FREQ
1065         if (tegra_cpu_set_speed_cap(NULL)) {
1066                 pr_err("FAILED: Set CPU freq cap with new VDD_CPU EDP table\n");
1067                 goto override_out;
1068         }
1069
1070         pr_info("Reinitialized VDD_CPU EDP table with regulator current limit"
1071                         " %u mA\n", regulator_cur - edp_reg_override_mA);
1072 #else
1073         pr_err("FAILED: tegra_cpu_set_speed_cap() does not exist, failed to reinitialize VDD_CPU EDP table");
1074 #endif
1075
1076         return count;
1077
1078 override_err:
1079         pr_err("FAILED: Reinitialize VDD_CPU EDP table with override \"%s\"",
1080                buf);
1081 #ifdef CONFIG_CPU_FREQ
1082 override_out:
1083 #endif
1084         return -EINVAL;
1085 }
1086
1087 static int edp_debugfs_open(struct inode *inode, struct file *file)
1088 {
1089         return single_open(file, edp_debugfs_show, inode->i_private);
1090 }
1091
1092 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
1093 {
1094         return single_open(file, edp_limit_debugfs_show, inode->i_private);
1095 }
1096
1097 static int edp_reg_override_open(struct inode *inode, struct file *file)
1098 {
1099         return single_open(file, edp_reg_override_show, inode->i_private);
1100 }
1101
1102 static const struct file_operations edp_debugfs_fops = {
1103         .open           = edp_debugfs_open,
1104         .read           = seq_read,
1105         .llseek         = seq_lseek,
1106         .release        = single_release,
1107 };
1108
1109 static const struct file_operations edp_limit_debugfs_fops = {
1110         .open           = edp_limit_debugfs_open,
1111         .read           = seq_read,
1112         .llseek         = seq_lseek,
1113         .release        = single_release,
1114 };
1115
1116 static const struct file_operations edp_reg_override_debugfs_fops = {
1117         .open           = edp_reg_override_open,
1118         .read           = seq_read,
1119         .write          = edp_reg_override_write,
1120         .llseek         = seq_lseek,
1121         .release        = single_release,
1122 };
1123
1124 #ifdef CONFIG_EDP_FRAMEWORK
1125 static __init struct dentry *tegra_edp_debugfs_dir(void)
1126 {
1127         return edp_debugfs_dir;
1128 }
1129 #else
1130 static __init struct dentry *tegra_edp_debugfs_dir(void)
1131 {
1132         return debugfs_create_dir("edp", NULL);
1133 }
1134 #endif
1135
1136 static int __init tegra_edp_debugfs_init(void)
1137 {
1138         struct dentry *d_edp;
1139         struct dentry *d_edp_limit;
1140         struct dentry *d_edp_reg_override;
1141         struct dentry *edp_dir;
1142         struct dentry *vdd_cpu_dir;
1143
1144         edp_dir = tegra_edp_debugfs_dir();
1145
1146         if (!edp_dir)
1147                 goto edp_dir_err;
1148
1149         vdd_cpu_dir = debugfs_create_dir("vdd_cpu", edp_dir);
1150
1151         if (!vdd_cpu_dir)
1152                 goto vdd_cpu_dir_err;
1153
1154         d_edp = debugfs_create_file("edp", S_IRUGO, vdd_cpu_dir, NULL,
1155                                 &edp_debugfs_fops);
1156
1157         if (!d_edp)
1158                 goto edp_err;
1159
1160         d_edp_limit = debugfs_create_file("edp_limit", S_IRUGO, vdd_cpu_dir,
1161                                 NULL, &edp_limit_debugfs_fops);
1162
1163         if (!d_edp_limit)
1164                 goto edp_limit_err;
1165
1166         d_edp_reg_override = debugfs_create_file("edp_reg_override",
1167                                 S_IRUGO | S_IWUSR, vdd_cpu_dir, NULL,
1168                                 &edp_reg_override_debugfs_fops);
1169
1170         if (!d_edp_reg_override)
1171                 goto edp_reg_override_err;
1172
1173         if (tegra_core_edp_debugfs_init(edp_dir))
1174                 goto edp_reg_override_err;
1175
1176         return 0;
1177
1178 edp_reg_override_err:
1179         debugfs_remove(d_edp_limit);
1180 edp_limit_err:
1181         debugfs_remove(d_edp);
1182 edp_err:
1183         debugfs_remove(vdd_cpu_dir);
1184 vdd_cpu_dir_err:
1185         debugfs_remove(edp_dir);
1186 edp_dir_err:
1187         return -ENOMEM;
1188 }
1189
1190 late_initcall(tegra_edp_debugfs_init);
1191 #endif /* CONFIG_DEBUG_FS */