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