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