ARM: tegra: EDP: adjust cpu power limit table
[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 it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/seq_file.h>
22 #include <linux/slab.h>
23 #include <linux/module.h>
24 #include <linux/uaccess.h>
25 #include <linux/edp.h>
26
27 #include <mach/edp.h>
28 #include <mach/hardware.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
340 static const int power_cap_levels[] = { /* milliwatts (mW) */
341           500,  1000,  1500,  2000,  2500,  3000,  3500,
342          4000,  4500,  5000,  5500,  6000,  6500,  7000,
343          7500,  8000,  8500,  9000,  9500, 10000, 10500,
344         11000, 11500, 12000, 12500, 13000, 13500, 14000,
345         14500, 15000, 15500, 16000, 16500, 17000
346 };
347
348 static struct tegra_edp_freq_voltage_table *freq_voltage_lut_saved;
349 static unsigned int freq_voltage_lut_size_saved;
350 static struct tegra_edp_freq_voltage_table *freq_voltage_lut;
351 static unsigned int freq_voltage_lut_size;
352
353 static inline s64 edp_pow(s64 val, int pwr)
354 {
355         s64 retval = 1;
356
357         while (val && pwr) {
358                 if (pwr & 1)
359                         retval *= val;
360                 pwr >>= 1;
361                 if (pwr)
362                         val *= val;
363         }
364
365         return retval;
366 }
367
368 /*
369  * Find the maximum frequency that results in dynamic and leakage current that
370  * is less than the regulator current limit.
371  * temp_C - always valid
372  * power_mW - valid or -1 (infinite)
373  */
374 static unsigned int edp_calculate_maxf(
375                                 struct tegra_edp_cpu_leakage_params *params,
376                                 int temp_C, int power_mW,
377                                 int iddq_mA,
378                                 int n_cores_idx)
379 {
380         unsigned int voltage_mV, freq_KHz;
381         unsigned int cur_effective = regulator_cur - edp_reg_override_mA;
382         int f, i, j, k;
383         s64 leakage_mA, dyn_mA, leakage_calc_step;
384         s64 leakage_mW, dyn_mW;
385
386         for (f = freq_voltage_lut_size - 1; f >= 0; f--) {
387                 freq_KHz = freq_voltage_lut[f].freq / 1000;
388                 voltage_mV = freq_voltage_lut[f].voltage_mV;
389
390                 /* Constrain Volt-Temp */
391                 if (params->volt_temp_cap.temperature &&
392                     temp_C > params->volt_temp_cap.temperature &&
393                     params->volt_temp_cap.voltage_limit_mV &&
394                     voltage_mV > params->volt_temp_cap.voltage_limit_mV)
395                         continue;
396
397                 /* Calculate leakage current */
398                 leakage_mA = 0;
399                 for (i = 0; i <= 3; i++) {
400                         for (j = 0; j <= 3; j++) {
401                                 for (k = 0; k <= 3; k++) {
402                                         leakage_calc_step =
403                                                 params->leakage_consts_ijk
404                                                 [i][j][k] * edp_pow(iddq_mA, i);
405                                         /* Convert (mA)^i to (A)^i */
406                                         leakage_calc_step =
407                                                 div64_s64(leakage_calc_step,
408                                                           edp_pow(1000, i));
409                                         leakage_calc_step *=
410                                                 edp_pow(voltage_mV, j);
411                                         /* Convert (mV)^j to (V)^j */
412                                         leakage_calc_step =
413                                                 div64_s64(leakage_calc_step,
414                                                           edp_pow(1000, j));
415                                         leakage_calc_step *=
416                                                 edp_pow(temp_C, k);
417                                         /* Convert (C)^k to (scaled_C)^k */
418                                         leakage_calc_step =
419                                                 div64_s64(leakage_calc_step,
420                                                 edp_pow(params->temp_scaled,
421                                                         k));
422                                         /* leakage_consts_ijk was scaled */
423                                         leakage_calc_step =
424                                                 div64_s64(leakage_calc_step,
425                                                           params->ijk_scaled);
426                                         leakage_mA += leakage_calc_step;
427                                 }
428                         }
429                 }
430
431                 /* if specified, set floor for leakage current */
432                 if (params->leakage_min && leakage_mA <= params->leakage_min)
433                         leakage_mA = params->leakage_min;
434
435                 /* leakage cannot be negative => leakage model has error */
436                 if (leakage_mA <= 0) {
437                         pr_err("VDD_CPU EDP failed: IDDQ too high (%d mA)\n",
438                                iddq_mA);
439                         return -EINVAL;
440                 }
441
442                 leakage_mA *= params->leakage_consts_n[n_cores_idx];
443
444                 /* leakage_const_n was scaled */
445                 leakage_mA = div64_s64(leakage_mA, params->consts_scaled);
446
447                 /* Calculate dynamic current */
448                 dyn_mA = voltage_mV * freq_KHz / 1000;
449                 /* Convert mV to V */
450                 dyn_mA = div64_s64(dyn_mA, 1000);
451                 dyn_mA *= params->dyn_consts_n[n_cores_idx];
452                 /* dyn_const_n was scaled */
453                 dyn_mA = div64_s64(dyn_mA, params->dyn_scaled);
454
455                 if (power_mW != -1) {
456                         leakage_mW = leakage_mA * voltage_mV;
457                         dyn_mW = dyn_mA * voltage_mV;
458                         if (div64_s64(leakage_mW + dyn_mW, 1000) <= power_mW)
459                                 return freq_KHz;
460                 } else if ((leakage_mA + dyn_mA) <= cur_effective) {
461                         return freq_KHz;
462                 }
463         }
464         return 0;
465 }
466
467 static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
468                         unsigned int cpu_speedo_idx,
469                         unsigned int freq_volt_lut_size,
470                         struct tegra_edp_freq_voltage_table *freq_volt_lut)
471 {
472         unsigned int i, j, freq;
473         int voltage_mV;
474
475         for (i = 0, j = 0, freq = 0;
476                  i < freq_volt_lut_size;
477                  i++, freq += FREQ_STEP) {
478
479                 /* Predict voltages */
480                 voltage_mV = tegra_dvfs_predict_millivolts(clk_cpu_g, freq);
481                 if (voltage_mV < 0) {
482                         pr_err("%s: couldn't predict voltage: freq %u; err %d",
483                                __func__, freq, voltage_mV);
484                         return -EINVAL;
485                 }
486
487                 /* Cache frequency / voltage / voltage constant relationship */
488                 freq_volt_lut[i].freq = freq;
489                 freq_volt_lut[i].voltage_mV = voltage_mV;
490         }
491         return 0;
492 }
493
494 unsigned int tegra_edp_find_maxf(int volt)
495 {
496         unsigned int i;
497
498         for (i = 0; i < freq_voltage_lut_size_saved; i++) {
499                 if (freq_voltage_lut_saved[i].voltage_mV > volt)
500                         break;
501         }
502         return freq_voltage_lut[i - 1].freq;
503 }
504
505
506 static int edp_find_speedo_idx(int cpu_speedo_id, unsigned int *cpu_speedo_idx)
507 {
508         int i, array_size;
509         struct tegra_edp_cpu_leakage_params *params;
510
511         switch (tegra_chip_id) {
512         case TEGRA_CHIPID_TEGRA11:
513                 params = tegra11x_get_leakage_params(0, &array_size);
514                 break;
515         case TEGRA_CHIPID_TEGRA14:
516                 params = tegra14x_get_leakage_params(0, &array_size);
517                 break;
518         case TEGRA_CHIPID_TEGRA3:
519         case TEGRA_CHIPID_TEGRA2:
520         default:
521                 array_size = 0;
522                 break;
523         }
524
525         for (i = 0; i < array_size; i++)
526                 if (cpu_speedo_id == params[i].cpu_speedo_id) {
527                         *cpu_speedo_idx = i;
528                         return 0;
529                 }
530
531         pr_err("%s: couldn't find cpu speedo id %d in freq/voltage LUT\n",
532                __func__, cpu_speedo_id);
533         return -EINVAL;
534 }
535
536 static int init_cpu_edp_limits_calculated(void)
537 {
538         unsigned int temp_idx, n_cores_idx, pwr_idx;
539         unsigned int cpu_g_minf, cpu_g_maxf;
540         unsigned int iddq_mA;
541         unsigned int cpu_speedo_idx;
542         unsigned int cap, limit;
543         struct tegra_edp_limits *edp_calculated_limits;
544         struct tegra_system_edp_entry *power_edp_calc_limits;
545         struct tegra_edp_cpu_leakage_params *params;
546         int ret;
547         struct clk *clk_cpu_g = tegra_get_clock_by_name("cpu_g");
548         int cpu_speedo_id = tegra_cpu_speedo_id();
549
550         /* Determine all inputs to EDP formula */
551         iddq_mA = tegra_get_cpu_iddq_value();
552         ret = edp_find_speedo_idx(cpu_speedo_id, &cpu_speedo_idx);
553         if (ret)
554                 return ret;
555
556         switch (tegra_chip_id) {
557         case TEGRA_CHIPID_TEGRA11:
558                 params = tegra11x_get_leakage_params(cpu_speedo_idx, NULL);
559                 break;
560         case TEGRA_CHIPID_TEGRA14:
561                 params = tegra14x_get_leakage_params(cpu_speedo_idx, NULL);
562                 break;
563         case TEGRA_CHIPID_TEGRA3:
564         case TEGRA_CHIPID_TEGRA2:
565         default:
566                 return -EINVAL;
567         }
568
569         edp_calculated_limits = kmalloc(sizeof(struct tegra_edp_limits)
570                                         * ARRAY_SIZE(temperatures), GFP_KERNEL);
571         BUG_ON(!edp_calculated_limits);
572
573         power_edp_calc_limits = kmalloc(sizeof(struct tegra_system_edp_entry)
574                                 * ARRAY_SIZE(power_cap_levels), GFP_KERNEL);
575         BUG_ON(!power_edp_calc_limits);
576
577         cpu_g_minf = 0;
578         cpu_g_maxf = clk_get_max_rate(clk_cpu_g);
579         freq_voltage_lut_size = (cpu_g_maxf - cpu_g_minf) / FREQ_STEP + 1;
580         freq_voltage_lut = kmalloc(sizeof(struct tegra_edp_freq_voltage_table)
581                                    * freq_voltage_lut_size, GFP_KERNEL);
582         if (!freq_voltage_lut) {
583                 pr_err("%s: failed alloc mem for freq/voltage LUT\n", __func__);
584                 kfree(power_edp_calc_limits);
585                 kfree(edp_calculated_limits);
586                 return -ENOMEM;
587         }
588
589         ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx,
590                                 freq_voltage_lut_size, freq_voltage_lut);
591         if (ret) {
592                 kfree(power_edp_calc_limits);
593                 kfree(edp_calculated_limits);
594                 kfree(freq_voltage_lut);
595                 return ret;
596         }
597
598         if (freq_voltage_lut_size != freq_voltage_lut_size_saved) {
599                 /* release previous table if present */
600                 kfree(freq_voltage_lut_saved);
601                 /* create table to save */
602                 freq_voltage_lut_saved =
603                         kmalloc(sizeof(struct tegra_edp_freq_voltage_table) *
604                         freq_voltage_lut_size, GFP_KERNEL);
605                 if (!freq_voltage_lut_saved) {
606                         pr_err("%s: failed alloc mem for freq/voltage LUT\n",
607                                 __func__);
608                         kfree(freq_voltage_lut);
609                         return -ENOMEM;
610                 }
611                 freq_voltage_lut_size_saved = freq_voltage_lut_size;
612         }
613         memcpy(freq_voltage_lut_saved,
614                 freq_voltage_lut,
615                 sizeof(struct tegra_edp_freq_voltage_table) *
616                         freq_voltage_lut_size);
617
618         /* Calculate EDP table */
619         for (n_cores_idx = 0; n_cores_idx < NR_CPUS; n_cores_idx++) {
620                 for (temp_idx = 0;
621                      temp_idx < ARRAY_SIZE(temperatures); temp_idx++) {
622                         edp_calculated_limits[temp_idx].temperature =
623                                 temperatures[temp_idx];
624                         limit = edp_calculate_maxf(params,
625                                                    temperatures[temp_idx],
626                                                    -1,
627                                                    iddq_mA,
628                                                    n_cores_idx);
629                         /* apply safety cap if it is specified */
630                         if (n_cores_idx < 4) {
631                                 cap = params->safety_cap[n_cores_idx];
632                                 if (cap && cap < limit)
633                                         limit = cap;
634                         }
635                         edp_calculated_limits[temp_idx].
636                                 freq_limits[n_cores_idx] = limit;
637                 }
638
639                 for (pwr_idx = 0;
640                      pwr_idx < ARRAY_SIZE(power_cap_levels); pwr_idx++) {
641                         power_edp_calc_limits[pwr_idx].power_limit_100mW =
642                                 power_cap_levels[pwr_idx] / 100;
643                         limit = edp_calculate_maxf(params,
644                                                    90,
645                                                    power_cap_levels[pwr_idx],
646                                                    iddq_mA,
647                                                    n_cores_idx);
648                         power_edp_calc_limits[pwr_idx].
649                                 freq_limits[n_cores_idx] = limit;
650                 }
651         }
652
653         /*
654          * If this is an EDP table update, need to overwrite old table.
655          * The old table's address must remain valid.
656          */
657         if (edp_limits != edp_default_limits) {
658                 memcpy(edp_limits, edp_calculated_limits,
659                        sizeof(struct tegra_edp_limits)
660                        * ARRAY_SIZE(temperatures));
661                 kfree(edp_calculated_limits);
662         }
663         else {
664                 edp_limits = edp_calculated_limits;
665                 edp_limits_size = ARRAY_SIZE(temperatures);
666         }
667
668         if (power_edp_limits != power_edp_default_limits) {
669                 memcpy(power_edp_limits, power_edp_calc_limits,
670                        sizeof(struct tegra_system_edp_entry)
671                        * ARRAY_SIZE(power_cap_levels));
672                 kfree(power_edp_calc_limits);
673         } else {
674                 power_edp_limits = power_edp_calc_limits;
675                 power_edp_limits_size = ARRAY_SIZE(power_cap_levels);
676         }
677
678         kfree(freq_voltage_lut);
679         return 0;
680 }
681
682 static int __init init_cpu_edp_limits_lookup(void)
683 {
684         int i, j;
685         struct tegra_edp_limits *e;
686         struct tegra_edp_vdd_cpu_entry *t;
687         int tsize;
688         int cpu_speedo_id = tegra_cpu_speedo_id();
689
690         t = (struct tegra_edp_vdd_cpu_entry *)tegra_edp_vdd_cpu_map;
691         tsize = sizeof(tegra_edp_vdd_cpu_map)
692                 / sizeof(struct tegra_edp_vdd_cpu_entry);
693
694         for (i = 0; i < tsize; i++) {
695                 if (t[i].speedo_id == cpu_speedo_id &&
696                     t[i].regulator_100mA <= regulator_cur / 100)
697                         break;
698         }
699
700         /* No entry found in tegra_edp_vdd_cpu_map */
701         if (i >= tsize)
702                 return -EINVAL;
703
704         /* Find all rows for this entry */
705         for (j = i + 1; j < tsize; j++) {
706                 if (t[i].speedo_id != t[j].speedo_id ||
707                     t[i].regulator_100mA != t[j].regulator_100mA)
708                         break;
709         }
710
711         edp_limits_size = j - i;
712         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
713                     GFP_KERNEL);
714         BUG_ON(!e);
715
716         for (j = 0; j < edp_limits_size; j++) {
717                 e[j].temperature = (int)t[i+j].temperature;
718                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0]*10000;
719                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1]*10000;
720                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2]*10000;
721                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3]*10000;
722         }
723
724         if (edp_limits != edp_default_limits)
725                 kfree(edp_limits);
726
727         edp_limits = e;
728         return 0;
729 }
730
731 void tegra_recalculate_cpu_edp_limits(void)
732 {
733         if (tegra_chip_id == TEGRA_CHIPID_TEGRA11 ||
734             tegra_chip_id == TEGRA_CHIPID_TEGRA14)
735                 init_cpu_edp_limits_calculated();
736 }
737
738 /*
739  * Specify regulator current in mA, e.g. 5000mA
740  * Use 0 for default
741  */
742 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
743 {
744         if (!regulator_mA)
745                 goto end;
746         regulator_cur = regulator_mA + OVERRIDE_DEFAULT;
747
748         switch (tegra_chip_id) {
749         case TEGRA_CHIPID_TEGRA3:
750                 if (init_cpu_edp_limits_lookup() == 0)
751                         return;
752                 break;
753         case TEGRA_CHIPID_TEGRA11:
754         case TEGRA_CHIPID_TEGRA14:
755                 if (init_cpu_edp_limits_calculated() == 0)
756                         return;
757                 break;
758         case TEGRA_CHIPID_TEGRA2:
759         default:
760                 BUG();
761                 break;
762         }
763
764  end:
765         edp_limits = edp_default_limits;
766         edp_limits_size = ARRAY_SIZE(edp_default_limits);
767
768         power_edp_limits = power_edp_default_limits;
769         power_edp_limits_size = ARRAY_SIZE(power_edp_default_limits);
770 }
771
772 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
773 {
774         int cpu_speedo_id = tegra_cpu_speedo_id();
775         int i;
776         unsigned int *e;
777         struct tegra_system_edp_entry *t = tegra_system_edp_map;
778         int tsize = ARRAY_SIZE(tegra_system_edp_map);
779
780         if (!power_limit_mW) {
781                 e = NULL;
782                 goto out;
783         }
784
785         for (i = 0; i < tsize; i++)
786                 if (t[i].speedo_id == cpu_speedo_id)
787                         break;
788
789         if (i >= tsize) {
790                 e = NULL;
791                 goto out;
792         }
793
794         do {
795                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
796                         break;
797                 i++;
798         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
799
800         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
801                 i--; /* No low enough entry in the table, use best possible */
802
803         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
804         BUG_ON(!e);
805
806         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
807         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
808         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
809         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
810
811 out:
812         kfree(system_edp_limits);
813
814         system_edp_limits = e;
815 }
816
817
818 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
819 {
820         *limits = edp_limits;
821         *size = edp_limits_size;
822 }
823
824 void tegra_get_system_edp_limits(const unsigned int **limits)
825 {
826         *limits = system_edp_limits;
827 }
828
829 void tegra_platform_edp_init(struct thermal_trip_info *trips,
830                                 int *num_trips, int margin)
831 {
832         const struct tegra_edp_limits *cpu_edp_limits;
833         struct thermal_trip_info *trip_state;
834         int i, cpu_edp_limits_size;
835
836         if (!trips || !num_trips)
837                 return;
838
839         /* edp capping */
840         tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size);
841
842         if (cpu_edp_limits_size > MAX_THROT_TABLE_SIZE)
843                 BUG();
844
845         for (i = 0; i < cpu_edp_limits_size-1; i++) {
846                 trip_state = &trips[*num_trips];
847
848                 trip_state->cdev_type = "cpu_edp";
849                 trip_state->trip_temp =
850                         (cpu_edp_limits[i].temperature * 1000) - margin;
851                 trip_state->trip_type = THERMAL_TRIP_ACTIVE;
852                 trip_state->upper = trip_state->lower = i + 1;
853
854                 (*num_trips)++;
855
856                 if (*num_trips >= THERMAL_MAX_TRIPS)
857                         BUG();
858         }
859 }
860
861 struct tegra_system_edp_entry *tegra_get_system_edp_entries(int *size)
862 {
863         *size = power_edp_limits_size;
864         return power_edp_limits;
865 }
866
867 #ifdef CONFIG_DEBUG_FS
868
869 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
870 {
871 #ifdef CONFIG_CPU_FREQ
872         seq_printf(s, "%u\n", tegra_get_edp_limit(NULL));
873 #endif
874         return 0;
875 }
876
877 static int edp_debugfs_show(struct seq_file *s, void *data)
878 {
879         int i, th_idx;
880
881 #ifdef CONFIG_CPU_FREQ
882         tegra_get_edp_limit(&th_idx);
883 #else
884         th_idx = 0;
885 #endif
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 #ifdef CONFIG_CPU_FREQ
969         if (tegra_cpu_set_speed_cap(NULL)) {
970                 pr_err("FAILED: Set CPU freq cap with new VDD_CPU EDP table\n");
971                 goto override_out;
972         }
973
974         pr_info("Reinitialized VDD_CPU EDP table with regulator current limit"
975                         " %u mA\n", regulator_cur - edp_reg_override_mA);
976 #else
977         pr_err("FAILED: tegra_cpu_set_speed_cap() does not exist, failed to reinitialize VDD_CPU EDP table");
978 #endif
979
980         return count;
981
982 override_err:
983         pr_err("FAILED: Reinitialize VDD_CPU EDP table with override \"%s\"",
984                buf);
985 #ifdef CONFIG_CPU_FREQ
986 override_out:
987 #endif
988         return -EINVAL;
989 }
990
991 static int edp_debugfs_open(struct inode *inode, struct file *file)
992 {
993         return single_open(file, edp_debugfs_show, inode->i_private);
994 }
995
996 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
997 {
998         return single_open(file, edp_limit_debugfs_show, inode->i_private);
999 }
1000
1001 static int edp_reg_override_open(struct inode *inode, struct file *file)
1002 {
1003         return single_open(file, edp_reg_override_show, inode->i_private);
1004 }
1005
1006 static const struct file_operations edp_debugfs_fops = {
1007         .open           = edp_debugfs_open,
1008         .read           = seq_read,
1009         .llseek         = seq_lseek,
1010         .release        = single_release,
1011 };
1012
1013 static const struct file_operations edp_limit_debugfs_fops = {
1014         .open           = edp_limit_debugfs_open,
1015         .read           = seq_read,
1016         .llseek         = seq_lseek,
1017         .release        = single_release,
1018 };
1019
1020 static const struct file_operations edp_reg_override_debugfs_fops = {
1021         .open           = edp_reg_override_open,
1022         .read           = seq_read,
1023         .write          = edp_reg_override_write,
1024         .llseek         = seq_lseek,
1025         .release        = single_release,
1026 };
1027
1028 #ifdef CONFIG_EDP_FRAMEWORK
1029 static __init struct dentry *tegra_edp_debugfs_dir(void)
1030 {
1031         return edp_debugfs_dir;
1032 }
1033 #else
1034 static __init struct dentry *tegra_edp_debugfs_dir(void)
1035 {
1036         return debugfs_create_dir("edp", NULL);
1037 }
1038 #endif
1039
1040 static int __init tegra_edp_debugfs_init(void)
1041 {
1042         struct dentry *d_edp;
1043         struct dentry *d_edp_limit;
1044         struct dentry *d_edp_reg_override;
1045         struct dentry *edp_dir;
1046         struct dentry *vdd_cpu_dir;
1047
1048         edp_dir = tegra_edp_debugfs_dir();
1049
1050         if (!edp_dir)
1051                 goto edp_dir_err;
1052
1053         vdd_cpu_dir = debugfs_create_dir("vdd_cpu", edp_dir);
1054
1055         if (!vdd_cpu_dir)
1056                 goto vdd_cpu_dir_err;
1057
1058         d_edp = debugfs_create_file("edp", S_IRUGO, vdd_cpu_dir, NULL,
1059                                 &edp_debugfs_fops);
1060
1061         if (!d_edp)
1062                 goto edp_err;
1063
1064         d_edp_limit = debugfs_create_file("edp_limit", S_IRUGO, vdd_cpu_dir,
1065                                 NULL, &edp_limit_debugfs_fops);
1066
1067         if (!d_edp_limit)
1068                 goto edp_limit_err;
1069
1070         d_edp_reg_override = debugfs_create_file("edp_reg_override",
1071                                 S_IRUGO | S_IWUSR, vdd_cpu_dir, NULL,
1072                                 &edp_reg_override_debugfs_fops);
1073
1074         if (!d_edp_reg_override)
1075                 goto edp_reg_override_err;
1076
1077         if (tegra_core_edp_debugfs_init(edp_dir))
1078                 goto edp_reg_override_err;
1079
1080         return 0;
1081
1082 edp_reg_override_err:
1083         debugfs_remove(d_edp_limit);
1084 edp_limit_err:
1085         debugfs_remove(d_edp);
1086 edp_err:
1087         debugfs_remove(vdd_cpu_dir);
1088 vdd_cpu_dir_err:
1089         debugfs_remove(edp_dir);
1090 edp_dir_err:
1091         return -ENOMEM;
1092 }
1093
1094 late_initcall(tegra_edp_debugfs_init);
1095 #endif /* CONFIG_DEBUG_FS */