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