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