ARM: tegra: init EDP on recalculate for T148
[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             tegra_chip_id == TEGRA_CHIPID_TEGRA14)
832                 init_cpu_edp_limits_calculated();
833 }
834
835 /*
836  * Specify regulator current in mA, e.g. 5000mA
837  * Use 0 for default
838  */
839 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
840 {
841         if (!regulator_mA)
842                 goto end;
843         regulator_cur = regulator_mA + OVERRIDE_DEFAULT;
844
845         switch (tegra_chip_id) {
846         case TEGRA_CHIPID_TEGRA3:
847                 if (init_cpu_edp_limits_lookup() == 0)
848                         return;
849                 break;
850         case TEGRA_CHIPID_TEGRA11:
851         case TEGRA_CHIPID_TEGRA14:
852                 if (init_cpu_edp_limits_calculated() == 0)
853                         return;
854                 break;
855         case TEGRA_CHIPID_TEGRA2:
856         default:
857                 BUG();
858                 break;
859         }
860
861  end:
862         edp_limits = edp_default_limits;
863         edp_limits_size = ARRAY_SIZE(edp_default_limits);
864
865         power_edp_limits = power_edp_default_limits;
866         power_edp_limits_size = ARRAY_SIZE(power_edp_default_limits);
867 }
868
869 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
870 {
871         int cpu_speedo_id = tegra_cpu_speedo_id();
872         int i;
873         unsigned int *e;
874         struct tegra_system_edp_entry *t = tegra_system_edp_map;
875         int tsize = ARRAY_SIZE(tegra_system_edp_map);
876
877         if (!power_limit_mW) {
878                 e = NULL;
879                 goto out;
880         }
881
882         for (i = 0; i < tsize; i++)
883                 if (t[i].speedo_id == cpu_speedo_id)
884                         break;
885
886         if (i >= tsize) {
887                 e = NULL;
888                 goto out;
889         }
890
891         do {
892                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
893                         break;
894                 i++;
895         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
896
897         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
898                 i--; /* No low enough entry in the table, use best possible */
899
900         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
901         BUG_ON(!e);
902
903         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
904         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
905         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
906         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
907
908 out:
909         kfree(system_edp_limits);
910
911         system_edp_limits = e;
912 }
913
914
915 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
916 {
917         *limits = edp_limits;
918         *size = edp_limits_size;
919 }
920
921 void tegra_get_system_edp_limits(const unsigned int **limits)
922 {
923         *limits = system_edp_limits;
924 }
925
926 void tegra_platform_edp_init(struct thermal_trip_info *trips,
927                                 int *num_trips, int margin)
928 {
929         const struct tegra_edp_limits *cpu_edp_limits;
930         struct thermal_trip_info *trip_state;
931         int i, cpu_edp_limits_size;
932
933         if (!trips || !num_trips)
934                 return;
935
936         /* edp capping */
937         tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size);
938
939         if (cpu_edp_limits_size > MAX_THROT_TABLE_SIZE)
940                 BUG();
941
942         for (i = 0; i < cpu_edp_limits_size-1; i++) {
943                 trip_state = &trips[*num_trips];
944
945                 trip_state->cdev_type = "cpu_edp";
946                 trip_state->trip_temp =
947                         (cpu_edp_limits[i].temperature * 1000) - margin;
948                 trip_state->trip_type = THERMAL_TRIP_ACTIVE;
949                 trip_state->upper = trip_state->lower = i + 1;
950
951                 (*num_trips)++;
952
953                 if (*num_trips >= THERMAL_MAX_TRIPS)
954                         BUG();
955         }
956 }
957
958 struct tegra_system_edp_entry *tegra_get_system_edp_entries(int *size)
959 {
960         *size = power_edp_limits_size;
961         return power_edp_limits;
962 }
963
964 #ifdef CONFIG_DEBUG_FS
965
966 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
967 {
968 #ifdef CONFIG_CPU_FREQ
969         seq_printf(s, "%u\n", tegra_get_edp_limit(NULL));
970 #endif
971         return 0;
972 }
973
974 static int edp_debugfs_show(struct seq_file *s, void *data)
975 {
976         int i, th_idx;
977
978 #ifdef CONFIG_CPU_FREQ
979         tegra_get_edp_limit(&th_idx);
980 #else
981         th_idx = 0;
982 #endif
983         seq_printf(s, "-- VDD_CPU %sEDP table (%umA = %umA - %umA) --\n",
984                    edp_limits == edp_default_limits ? "default " : "",
985                    regulator_cur - edp_reg_override_mA,
986                    regulator_cur, edp_reg_override_mA);
987         seq_printf(s, "%6s %10s %10s %10s %10s\n",
988                    " Temp.", "1-core", "2-cores", "3-cores", "4-cores");
989         for (i = 0; i < edp_limits_size; i++) {
990                 seq_printf(s, "%c%3dC: %10u %10u %10u %10u\n",
991                            i == th_idx ? '>' : ' ',
992                            edp_limits[i].temperature,
993                            edp_limits[i].freq_limits[0],
994                            edp_limits[i].freq_limits[1],
995                            edp_limits[i].freq_limits[2],
996                            edp_limits[i].freq_limits[3]);
997         }
998
999         seq_printf(s, "-- VDD_CPU Power EDP table --\n");
1000         seq_printf(s, "%6s %10s %10s %10s %10s\n",
1001                    " Power", "1-core", "2-cores", "3-cores", "4-cores");
1002         for (i = 0; i < power_edp_limits_size; i++) {
1003                 seq_printf(s, "%5dmW: %10u %10u %10u %10u\n",
1004                            power_edp_limits[i].power_limit_100mW * 100,
1005                            power_edp_limits[i].freq_limits[0],
1006                            power_edp_limits[i].freq_limits[1],
1007                            power_edp_limits[i].freq_limits[2],
1008                            power_edp_limits[i].freq_limits[3]);
1009         }
1010
1011         if (system_edp_limits) {
1012                 seq_printf(s, "\n-- System EDP table --\n");
1013                 seq_printf(s, "%10u %10u %10u %10u\n",
1014                            system_edp_limits[0],
1015                            system_edp_limits[1],
1016                            system_edp_limits[2],
1017                            system_edp_limits[3]);
1018         }
1019
1020         return 0;
1021 }
1022
1023 static int edp_reg_override_show(struct seq_file *s, void *data)
1024 {
1025         seq_printf(s, "Limit override: %u mA. Effective limit: %u mA\n",
1026                    edp_reg_override_mA, regulator_cur - edp_reg_override_mA);
1027         return 0;
1028 }
1029
1030 static int edp_reg_override_write(struct file *file,
1031         const char __user *userbuf, size_t count, loff_t *ppos)
1032 {
1033         char buf[32], *end;
1034         unsigned int edp_reg_override_mA_temp;
1035         unsigned int edp_reg_override_mA_prev = edp_reg_override_mA;
1036
1037         if (sizeof(buf) <= count)
1038                 goto override_err;
1039
1040         if (copy_from_user(buf, userbuf, count))
1041                 goto override_err;
1042
1043         /* terminate buffer and trim - white spaces may be appended
1044          *  at the end when invoked from shell command line */
1045         buf[count]='\0';
1046         strim(buf);
1047
1048         edp_reg_override_mA_temp = simple_strtoul(buf, &end, 10);
1049         if (*end != '\0')
1050                 goto override_err;
1051
1052         if (edp_reg_override_mA_temp >= regulator_cur)
1053                 goto override_err;
1054
1055         if (edp_reg_override_mA == edp_reg_override_mA_temp)
1056                 return count;
1057
1058         edp_reg_override_mA = edp_reg_override_mA_temp;
1059         if (init_cpu_edp_limits_calculated()) {
1060                 /* Revert to previous override value if new value fails */
1061                 edp_reg_override_mA = edp_reg_override_mA_prev;
1062                 goto override_err;
1063         }
1064
1065 #ifdef CONFIG_CPU_FREQ
1066         if (tegra_cpu_set_speed_cap(NULL)) {
1067                 pr_err("FAILED: Set CPU freq cap with new VDD_CPU EDP table\n");
1068                 goto override_out;
1069         }
1070
1071         pr_info("Reinitialized VDD_CPU EDP table with regulator current limit"
1072                         " %u mA\n", regulator_cur - edp_reg_override_mA);
1073 #else
1074         pr_err("FAILED: tegra_cpu_set_speed_cap() does not exist, failed to reinitialize VDD_CPU EDP table");
1075 #endif
1076
1077         return count;
1078
1079 override_err:
1080         pr_err("FAILED: Reinitialize VDD_CPU EDP table with override \"%s\"",
1081                buf);
1082 #ifdef CONFIG_CPU_FREQ
1083 override_out:
1084 #endif
1085         return -EINVAL;
1086 }
1087
1088 static int edp_debugfs_open(struct inode *inode, struct file *file)
1089 {
1090         return single_open(file, edp_debugfs_show, inode->i_private);
1091 }
1092
1093 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
1094 {
1095         return single_open(file, edp_limit_debugfs_show, inode->i_private);
1096 }
1097
1098 static int edp_reg_override_open(struct inode *inode, struct file *file)
1099 {
1100         return single_open(file, edp_reg_override_show, inode->i_private);
1101 }
1102
1103 static const struct file_operations edp_debugfs_fops = {
1104         .open           = edp_debugfs_open,
1105         .read           = seq_read,
1106         .llseek         = seq_lseek,
1107         .release        = single_release,
1108 };
1109
1110 static const struct file_operations edp_limit_debugfs_fops = {
1111         .open           = edp_limit_debugfs_open,
1112         .read           = seq_read,
1113         .llseek         = seq_lseek,
1114         .release        = single_release,
1115 };
1116
1117 static const struct file_operations edp_reg_override_debugfs_fops = {
1118         .open           = edp_reg_override_open,
1119         .read           = seq_read,
1120         .write          = edp_reg_override_write,
1121         .llseek         = seq_lseek,
1122         .release        = single_release,
1123 };
1124
1125 #ifdef CONFIG_EDP_FRAMEWORK
1126 static __init struct dentry *tegra_edp_debugfs_dir(void)
1127 {
1128         return edp_debugfs_dir;
1129 }
1130 #else
1131 static __init struct dentry *tegra_edp_debugfs_dir(void)
1132 {
1133         return debugfs_create_dir("edp", NULL);
1134 }
1135 #endif
1136
1137 static int __init tegra_edp_debugfs_init(void)
1138 {
1139         struct dentry *d_edp;
1140         struct dentry *d_edp_limit;
1141         struct dentry *d_edp_reg_override;
1142         struct dentry *edp_dir;
1143         struct dentry *vdd_cpu_dir;
1144
1145         edp_dir = tegra_edp_debugfs_dir();
1146
1147         if (!edp_dir)
1148                 goto edp_dir_err;
1149
1150         vdd_cpu_dir = debugfs_create_dir("vdd_cpu", edp_dir);
1151
1152         if (!vdd_cpu_dir)
1153                 goto vdd_cpu_dir_err;
1154
1155         d_edp = debugfs_create_file("edp", S_IRUGO, vdd_cpu_dir, NULL,
1156                                 &edp_debugfs_fops);
1157
1158         if (!d_edp)
1159                 goto edp_err;
1160
1161         d_edp_limit = debugfs_create_file("edp_limit", S_IRUGO, vdd_cpu_dir,
1162                                 NULL, &edp_limit_debugfs_fops);
1163
1164         if (!d_edp_limit)
1165                 goto edp_limit_err;
1166
1167         d_edp_reg_override = debugfs_create_file("edp_reg_override",
1168                                 S_IRUGO | S_IWUSR, vdd_cpu_dir, NULL,
1169                                 &edp_reg_override_debugfs_fops);
1170
1171         if (!d_edp_reg_override)
1172                 goto edp_reg_override_err;
1173
1174         if (tegra_core_edp_debugfs_init(edp_dir))
1175                 goto edp_reg_override_err;
1176
1177         return 0;
1178
1179 edp_reg_override_err:
1180         debugfs_remove(d_edp_limit);
1181 edp_limit_err:
1182         debugfs_remove(d_edp);
1183 edp_err:
1184         debugfs_remove(vdd_cpu_dir);
1185 vdd_cpu_dir_err:
1186         debugfs_remove(edp_dir);
1187 edp_dir_err:
1188         return -ENOMEM;
1189 }
1190
1191 late_initcall(tegra_edp_debugfs_init);
1192 #endif /* CONFIG_DEBUG_FS */