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