ARM: tegra: build edp table with volt-temp constraints
[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                 .volt_temp_cap = { 70, 1240 },
418         },
419         {
420                 .cpu_speedo_id      = 1, /* A01P+ CPU */
421                 .dyn_consts_n       = { 1091747, 2035205, 2978661, 3922119 },
422                 .leakage_consts_n   = {  538991,  752463,  959441, 1150000 },
423                 .leakage_consts_ijk = {
424                          /* i = 0 */
425                          { {  -42746668,   -5458429,   164998,  -1711, },
426                            {  178262421,   13375684,  -411791,   4590, },
427                            { -228866784,  -10482993,   331248,  -4062, },
428                            {   94301550,    2618719,   -85983,   1193, },
429                          },
430                          /* i = 1 */
431                          { { -256611791,   49677413, -1655785,  14917, },
432                            {  584675433, -132620939,  4541560, -41812, },
433                            { -398106336,  115987156, -4102328,  38737, },
434                            {   68897184,  -33030745,  1217839, -11801, },
435                          },
436                          /* i = 2 */
437                          { {  186324676,  -36019083,  1177969, -10669, },
438                            { -439237936,   98429131, -3276444,  30301, },
439                            {  315060898,  -88635036,  3004777, -28474, },
440                            {  -60854399,   26267188,  -907121,   8844, },
441                          },
442                          /* i = 3 */
443                          { {  -35432997,    6154621,  -202200,   1830, },
444                            {   87402153,  -16908683,   565152,  -5220, },
445                            {  -67775314,   15326770,  -521221,   4927, },
446                            {   15618709,   -4576116,   158401,  -1538, },
447                          },
448                  },
449                 .safety_cap = { 1810500, 1810500, 1606500, 1606500 },
450                 .volt_temp_cap = { 70, 1240 },
451         },
452         {
453                 .cpu_speedo_id      = 2, /* A01P+ fast CPU */
454                 .dyn_consts_n       = { 1091747, 2035205, 2978661, 3922119 },
455                 .leakage_consts_n   = {  538991,  752463,  959441, 1150000 },
456                 .leakage_consts_ijk = {
457                          /* i = 0 */
458                          { {  -42746668,   -5458429,   164998,  -1711, },
459                            {  178262421,   13375684,  -411791,   4590, },
460                            { -228866784,  -10482993,   331248,  -4062, },
461                            {   94301550,    2618719,   -85983,   1193, },
462                          },
463                          /* i = 1 */
464                          { { -256611791,   49677413, -1655785,  14917, },
465                            {  584675433, -132620939,  4541560, -41812, },
466                            { -398106336,  115987156, -4102328,  38737, },
467                            {   68897184,  -33030745,  1217839, -11801, },
468                          },
469                          /* i = 2 */
470                          { {  186324676,  -36019083,  1177969, -10669, },
471                            { -439237936,   98429131, -3276444,  30301, },
472                            {  315060898,  -88635036,  3004777, -28474, },
473                            {  -60854399,   26267188,  -907121,   8844, },
474                          },
475                          /* i = 3 */
476                          { {  -35432997,    6154621,  -202200,   1830, },
477                            {   87402153,  -16908683,   565152,  -5220, },
478                            {  -67775314,   15326770,  -521221,   4927, },
479                            {   15618709,   -4576116,   158401,  -1538, },
480                          },
481                  },
482                 .safety_cap = { 1912500, 1912500, 1912500, 1912500 },
483                 .volt_temp_cap = { 70, 1240 },
484         },
485 };
486 #endif
487
488 static struct tegra_edp_freq_voltage_table *freq_voltage_lut_saved;
489 static unsigned int freq_voltage_lut_size_saved;
490 static struct tegra_edp_freq_voltage_table *freq_voltage_lut;
491 static unsigned int freq_voltage_lut_size;
492
493 static inline s64 edp_pow(s64 val, int pwr)
494 {
495         s64 retval = 1;
496
497         while (pwr) {
498                 if (pwr & 1)
499                         retval *= val;
500                 pwr >>= 1;
501                 if (pwr)
502                         val *= val;
503         }
504
505         return retval;
506 }
507
508 /*
509  * Find the maximum frequency that results in dynamic and leakage current that
510  * is less than the regulator current limit.
511  * temp_C - always valid
512  * power_mW - valid or -1 (infinite)
513  */
514 static unsigned int edp_calculate_maxf(
515                                 struct tegra_edp_cpu_leakage_params *params,
516                                 int temp_C, int power_mW,
517                                 int iddq_mA,
518                                 int n_cores_idx)
519 {
520         unsigned int voltage_mV, freq_KHz;
521         unsigned int cur_effective = regulator_cur - edp_reg_override_mA;
522         int f, i, j, k;
523         s64 leakage_mA, dyn_mA, leakage_calc_step;
524         s64 leakage_mW, dyn_mW;
525
526         for (f = freq_voltage_lut_size - 1; f >= 0; f--) {
527                 freq_KHz = freq_voltage_lut[f].freq / 1000;
528                 voltage_mV = freq_voltage_lut[f].voltage_mV;
529
530                 /* Constrain Volt-Temp. Eg. at Tj >= 70C, no VDD_CPU > 1.24V */
531                 if (temp_C >= params->volt_temp_cap.temperature &&
532                     voltage_mV > params->volt_temp_cap.voltage_limit_mV)
533                         continue;
534
535                 /* Calculate leakage current */
536                 leakage_mA = 0;
537                 for (i = 0; i <= 3; i++) {
538                         for (j = 0; j <= 3; j++) {
539                                 for (k = 0; k <= 3; k++) {
540                                         leakage_calc_step =
541                                                 params->leakage_consts_ijk
542                                                 [i][j][k] * edp_pow(iddq_mA, i);
543                                         /* Convert (mA)^i to (A)^i */
544                                         leakage_calc_step =
545                                                 div64_s64(leakage_calc_step,
546                                                           edp_pow(1000, i));
547                                         leakage_calc_step *=
548                                                 edp_pow(voltage_mV, j);
549                                         /* Convert (mV)^i to (V)^i */
550                                         leakage_calc_step =
551                                                 div64_s64(leakage_calc_step,
552                                                           edp_pow(1000, j));
553                                         leakage_calc_step *=
554                                                 edp_pow(temp_C, k);
555                                         /* leakage_consts_ijk was X 100,000 */
556                                         leakage_calc_step =
557                                                 div64_s64(leakage_calc_step,
558                                                           100000);
559                                         leakage_mA += leakage_calc_step;
560                                 }
561                         }
562                 }
563                 leakage_mA *= params->leakage_consts_n[n_cores_idx];
564                 /* leakage_const_n was pre-multiplied by 1,000,000 */
565                 leakage_mA = div64_s64(leakage_mA, 1000000);
566
567                 /* Calculate dynamic current */
568                 dyn_mA = voltage_mV * freq_KHz / 1000;
569                 /* Convert mV to V */
570                 dyn_mA = div64_s64(dyn_mA, 1000);
571                 dyn_mA *= params->dyn_consts_n[n_cores_idx];
572                 /* dyn_const_n was pre-multiplied by 1,000,000 */
573                 dyn_mA = div64_s64(dyn_mA, 1000000);
574
575                 if (power_mW != -1) {
576                         leakage_mW = leakage_mA * voltage_mV;
577                         dyn_mW = dyn_mA * voltage_mV;
578                         if (div64_s64(leakage_mW + dyn_mW, 1000) <= power_mW)
579                                 return freq_KHz;
580                 } else if ((leakage_mA + dyn_mA) <= cur_effective) {
581                         return freq_KHz;
582                 }
583         }
584         return 0;
585 }
586
587 static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
588                         unsigned int cpu_speedo_idx,
589                         unsigned int freq_volt_lut_size,
590                         struct tegra_edp_freq_voltage_table *freq_volt_lut)
591 {
592         unsigned int i, j, freq;
593         int voltage_mV;
594
595         for (i = 0, j = 0, freq = 0;
596                  i < freq_volt_lut_size;
597                  i++, freq += FREQ_STEP) {
598
599                 /* Predict voltages */
600                 voltage_mV = tegra_dvfs_predict_millivolts(clk_cpu_g, freq);
601                 if (voltage_mV < 0) {
602                         pr_err("%s: couldn't predict voltage: freq %u; err %d",
603                                __func__, freq, voltage_mV);
604                         return -EINVAL;
605                 }
606
607                 /* Cache frequency / voltage / voltage constant relationship */
608                 freq_volt_lut[i].freq = freq;
609                 freq_volt_lut[i].voltage_mV = voltage_mV;
610         }
611         return 0;
612 }
613
614 unsigned int tegra_edp_find_maxf(int volt)
615 {
616         unsigned int i;
617
618         for (i = 0; i < freq_voltage_lut_size_saved; i++) {
619                 if (freq_voltage_lut_saved[i].voltage_mV > volt)
620                         break;
621         }
622         return freq_voltage_lut[i - 1].freq;
623 }
624
625
626 static int edp_find_speedo_idx(int cpu_speedo_id, unsigned int *cpu_speedo_idx)
627 {
628         int i;
629
630         for (i = 0; i < ARRAY_SIZE(leakage_params); i++)
631                 if (cpu_speedo_id == leakage_params[i].cpu_speedo_id) {
632                         *cpu_speedo_idx = i;
633                         return 0;
634                 }
635
636         pr_err("%s: couldn't find cpu speedo id %d in freq/voltage LUT\n",
637                __func__, cpu_speedo_id);
638         return -EINVAL;
639 }
640
641 static int init_cpu_edp_limits_calculated(void)
642 {
643         unsigned int temp_idx, n_cores_idx, pwr_idx;
644         unsigned int cpu_g_minf, cpu_g_maxf;
645         unsigned int iddq_mA;
646         unsigned int cpu_speedo_idx;
647         unsigned int cap, limit;
648         struct tegra_edp_limits *edp_calculated_limits;
649         struct tegra_system_edp_entry *power_edp_calc_limits;
650         struct tegra_edp_cpu_leakage_params *params;
651         int ret;
652         struct clk *clk_cpu_g = tegra_get_clock_by_name("cpu_g");
653         int cpu_speedo_id = tegra_cpu_speedo_id();
654
655         /* Determine all inputs to EDP formula */
656         iddq_mA = tegra_get_cpu_iddq_value();
657         ret = edp_find_speedo_idx(cpu_speedo_id, &cpu_speedo_idx);
658         if (ret)
659                 return ret;
660
661         params = &leakage_params[cpu_speedo_idx];
662
663         edp_calculated_limits = kmalloc(sizeof(struct tegra_edp_limits)
664                                         * ARRAY_SIZE(temperatures), GFP_KERNEL);
665         BUG_ON(!edp_calculated_limits);
666
667         power_edp_calc_limits = kmalloc(sizeof(struct tegra_system_edp_entry)
668                                 * ARRAY_SIZE(power_cap_levels), GFP_KERNEL);
669         BUG_ON(!power_edp_calc_limits);
670
671         cpu_g_minf = 0;
672         cpu_g_maxf = clk_get_max_rate(clk_cpu_g);
673         freq_voltage_lut_size = (cpu_g_maxf - cpu_g_minf) / FREQ_STEP + 1;
674         freq_voltage_lut = kmalloc(sizeof(struct tegra_edp_freq_voltage_table)
675                                    * freq_voltage_lut_size, GFP_KERNEL);
676         if (!freq_voltage_lut) {
677                 pr_err("%s: failed alloc mem for freq/voltage LUT\n", __func__);
678                 kfree(power_edp_calc_limits);
679                 kfree(edp_calculated_limits);
680                 return -ENOMEM;
681         }
682
683         ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx,
684                                 freq_voltage_lut_size, freq_voltage_lut);
685         if (ret) {
686                 kfree(power_edp_calc_limits);
687                 kfree(edp_calculated_limits);
688                 kfree(freq_voltage_lut);
689                 return ret;
690         }
691
692         if (freq_voltage_lut_size != freq_voltage_lut_size_saved) {
693                 /* release previous table if present */
694                 kfree(freq_voltage_lut_saved);
695                 /* create table to save */
696                 freq_voltage_lut_saved =
697                         kmalloc(sizeof(struct tegra_edp_freq_voltage_table) *
698                         freq_voltage_lut_size, GFP_KERNEL);
699                 if (!freq_voltage_lut_saved) {
700                         pr_err("%s: failed alloc mem for freq/voltage LUT\n",
701                                 __func__);
702                         kfree(freq_voltage_lut);
703                         return -ENOMEM;
704                 }
705                 freq_voltage_lut_size_saved = freq_voltage_lut_size;
706         }
707         memcpy(freq_voltage_lut_saved,
708                 freq_voltage_lut,
709                 sizeof(struct tegra_edp_freq_voltage_table) *
710                         freq_voltage_lut_size);
711
712         /* Calculate EDP table */
713         for (n_cores_idx = 0; n_cores_idx < NR_CPUS; n_cores_idx++) {
714                 for (temp_idx = 0;
715                      temp_idx < ARRAY_SIZE(temperatures); temp_idx++) {
716                         edp_calculated_limits[temp_idx].temperature =
717                                 temperatures[temp_idx];
718                         limit = edp_calculate_maxf(params,
719                                                    temperatures[temp_idx],
720                                                    -1,
721                                                    iddq_mA,
722                                                    n_cores_idx);
723                         /* apply safety cap if it is specified */
724                         if (n_cores_idx < 4) {
725                                 cap = params->safety_cap[n_cores_idx];
726                                 if (cap && cap < limit)
727                                         limit = cap;
728                         }
729                         edp_calculated_limits[temp_idx].
730                                 freq_limits[n_cores_idx] = limit;
731                 }
732
733                 for (pwr_idx = 0;
734                      pwr_idx < ARRAY_SIZE(power_cap_levels); pwr_idx++) {
735                         power_edp_calc_limits[pwr_idx].power_limit_100mW =
736                                 power_cap_levels[pwr_idx] / 100;
737                         limit = edp_calculate_maxf(params,
738                                                    90,
739                                                    power_cap_levels[pwr_idx],
740                                                    iddq_mA,
741                                                    n_cores_idx);
742                         power_edp_calc_limits[pwr_idx].
743                                 freq_limits[n_cores_idx] = limit;
744                 }
745         }
746
747         /*
748          * If this is an EDP table update, need to overwrite old table.
749          * The old table's address must remain valid.
750          */
751         if (edp_limits != edp_default_limits) {
752                 memcpy(edp_limits, edp_calculated_limits,
753                        sizeof(struct tegra_edp_limits)
754                        * ARRAY_SIZE(temperatures));
755                 kfree(edp_calculated_limits);
756         }
757         else {
758                 edp_limits = edp_calculated_limits;
759                 edp_limits_size = ARRAY_SIZE(temperatures);
760         }
761
762         if (power_edp_limits != power_edp_default_limits) {
763                 memcpy(power_edp_limits, power_edp_calc_limits,
764                        sizeof(struct tegra_system_edp_entry)
765                        * ARRAY_SIZE(power_cap_levels));
766                 kfree(power_edp_calc_limits);
767         } else {
768                 power_edp_limits = power_edp_calc_limits;
769                 power_edp_limits_size = ARRAY_SIZE(power_cap_levels);
770         }
771
772         kfree(freq_voltage_lut);
773         return 0;
774 }
775
776 static int __init init_cpu_edp_limits_lookup(void)
777 {
778         int i, j;
779         struct tegra_edp_limits *e;
780         struct tegra_edp_vdd_cpu_entry *t;
781         int tsize;
782         int cpu_speedo_id = tegra_cpu_speedo_id();
783
784         t = (struct tegra_edp_vdd_cpu_entry *)tegra_edp_vdd_cpu_map;
785         tsize = sizeof(tegra_edp_vdd_cpu_map)
786                 / sizeof(struct tegra_edp_vdd_cpu_entry);
787
788         for (i = 0; i < tsize; i++) {
789                 if (t[i].speedo_id == cpu_speedo_id &&
790                     t[i].regulator_100mA <= regulator_cur / 100)
791                         break;
792         }
793
794         /* No entry found in tegra_edp_vdd_cpu_map */
795         if (i >= tsize)
796                 return -EINVAL;
797
798         /* Find all rows for this entry */
799         for (j = i + 1; j < tsize; j++) {
800                 if (t[i].speedo_id != t[j].speedo_id ||
801                     t[i].regulator_100mA != t[j].regulator_100mA)
802                         break;
803         }
804
805         edp_limits_size = j - i;
806         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
807                     GFP_KERNEL);
808         BUG_ON(!e);
809
810         for (j = 0; j < edp_limits_size; j++) {
811                 e[j].temperature = (int)t[i+j].temperature;
812                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0]*10000;
813                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1]*10000;
814                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2]*10000;
815                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3]*10000;
816         }
817
818         if (edp_limits != edp_default_limits)
819                 kfree(edp_limits);
820
821         edp_limits = e;
822         return 0;
823 }
824
825 void tegra_recalculate_cpu_edp_limits(void)
826 {
827         if (tegra_chip_id == TEGRA_CHIPID_TEGRA11)
828                 init_cpu_edp_limits_calculated();
829 }
830
831 /*
832  * Specify regulator current in mA, e.g. 5000mA
833  * Use 0 for default
834  */
835 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
836 {
837         if (!regulator_mA)
838                 goto end;
839         regulator_cur = regulator_mA + OVERRIDE_DEFAULT;
840
841         switch (tegra_chip_id) {
842         case TEGRA_CHIPID_TEGRA3:
843                 if (init_cpu_edp_limits_lookup() == 0)
844                         return;
845                 break;
846         case TEGRA_CHIPID_TEGRA11:
847         case TEGRA_CHIPID_TEGRA14:
848                 if (init_cpu_edp_limits_calculated() == 0)
849                         return;
850                 break;
851         case TEGRA_CHIPID_TEGRA2:
852         default:
853                 BUG();
854                 break;
855         }
856
857  end:
858         edp_limits = edp_default_limits;
859         edp_limits_size = ARRAY_SIZE(edp_default_limits);
860
861         power_edp_limits = power_edp_default_limits;
862         power_edp_limits_size = ARRAY_SIZE(power_edp_default_limits);
863 }
864
865 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
866 {
867         int cpu_speedo_id = tegra_cpu_speedo_id();
868         int i;
869         unsigned int *e;
870         struct tegra_system_edp_entry *t = tegra_system_edp_map;
871         int tsize = ARRAY_SIZE(tegra_system_edp_map);
872
873         if (!power_limit_mW) {
874                 e = NULL;
875                 goto out;
876         }
877
878         for (i = 0; i < tsize; i++)
879                 if (t[i].speedo_id == cpu_speedo_id)
880                         break;
881
882         if (i >= tsize) {
883                 e = NULL;
884                 goto out;
885         }
886
887         do {
888                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
889                         break;
890                 i++;
891         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
892
893         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
894                 i--; /* No low enough entry in the table, use best possible */
895
896         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
897         BUG_ON(!e);
898
899         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
900         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
901         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
902         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
903
904 out:
905         kfree(system_edp_limits);
906
907         system_edp_limits = e;
908 }
909
910
911 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
912 {
913         *limits = edp_limits;
914         *size = edp_limits_size;
915 }
916
917 void tegra_get_system_edp_limits(const unsigned int **limits)
918 {
919         *limits = system_edp_limits;
920 }
921
922 void tegra_platform_edp_init(struct thermal_trip_info *trips,
923                                 int *num_trips, int margin)
924 {
925         const struct tegra_edp_limits *cpu_edp_limits;
926         struct thermal_trip_info *trip_state;
927         int i, cpu_edp_limits_size;
928
929         if (!trips || !num_trips)
930                 return;
931
932         /* edp capping */
933         tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size);
934
935         if (cpu_edp_limits_size > MAX_THROT_TABLE_SIZE)
936                 BUG();
937
938         for (i = 0; i < cpu_edp_limits_size-1; i++) {
939                 trip_state = &trips[*num_trips];
940
941                 trip_state->cdev_type = "cpu_edp";
942                 trip_state->trip_temp =
943                         (cpu_edp_limits[i].temperature * 1000) - margin;
944                 trip_state->trip_type = THERMAL_TRIP_ACTIVE;
945                 trip_state->upper = trip_state->lower = i + 1;
946
947                 (*num_trips)++;
948
949                 if (*num_trips >= THERMAL_MAX_TRIPS)
950                         BUG();
951         }
952 }
953
954 struct tegra_system_edp_entry *tegra_get_system_edp_entries(int *size)
955 {
956         *size = power_edp_limits_size;
957         return power_edp_limits;
958 }
959
960 #ifdef CONFIG_DEBUG_FS
961
962 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
963 {
964 #ifdef CONFIG_CPU_FREQ
965         seq_printf(s, "%u\n", tegra_get_edp_limit(NULL));
966 #endif
967         return 0;
968 }
969
970 static int edp_debugfs_show(struct seq_file *s, void *data)
971 {
972         int i, th_idx;
973
974 #ifdef CONFIG_CPU_FREQ
975         tegra_get_edp_limit(&th_idx);
976 #else
977         th_idx = 0;
978 #endif
979         seq_printf(s, "-- VDD_CPU %sEDP table (%umA = %umA - %umA) --\n",
980                    edp_limits == edp_default_limits ? "default " : "",
981                    regulator_cur - edp_reg_override_mA,
982                    regulator_cur, edp_reg_override_mA);
983         seq_printf(s, "%6s %10s %10s %10s %10s\n",
984                    " Temp.", "1-core", "2-cores", "3-cores", "4-cores");
985         for (i = 0; i < edp_limits_size; i++) {
986                 seq_printf(s, "%c%3dC: %10u %10u %10u %10u\n",
987                            i == th_idx ? '>' : ' ',
988                            edp_limits[i].temperature,
989                            edp_limits[i].freq_limits[0],
990                            edp_limits[i].freq_limits[1],
991                            edp_limits[i].freq_limits[2],
992                            edp_limits[i].freq_limits[3]);
993         }
994
995         seq_printf(s, "-- VDD_CPU Power EDP table --\n");
996         seq_printf(s, "%6s %10s %10s %10s %10s\n",
997                    " Power", "1-core", "2-cores", "3-cores", "4-cores");
998         for (i = 0; i < power_edp_limits_size; i++) {
999                 seq_printf(s, "%5dmW: %10u %10u %10u %10u\n",
1000                            power_edp_limits[i].power_limit_100mW * 100,
1001                            power_edp_limits[i].freq_limits[0],
1002                            power_edp_limits[i].freq_limits[1],
1003                            power_edp_limits[i].freq_limits[2],
1004                            power_edp_limits[i].freq_limits[3]);
1005         }
1006
1007         if (system_edp_limits) {
1008                 seq_printf(s, "\n-- System EDP table --\n");
1009                 seq_printf(s, "%10u %10u %10u %10u\n",
1010                            system_edp_limits[0],
1011                            system_edp_limits[1],
1012                            system_edp_limits[2],
1013                            system_edp_limits[3]);
1014         }
1015
1016         return 0;
1017 }
1018
1019 static int edp_reg_override_show(struct seq_file *s, void *data)
1020 {
1021         seq_printf(s, "Limit override: %u mA. Effective limit: %u mA\n",
1022                    edp_reg_override_mA, regulator_cur - edp_reg_override_mA);
1023         return 0;
1024 }
1025
1026 static int edp_reg_override_write(struct file *file,
1027         const char __user *userbuf, size_t count, loff_t *ppos)
1028 {
1029         char buf[32], *end;
1030         unsigned int edp_reg_override_mA_temp;
1031         unsigned int edp_reg_override_mA_prev = edp_reg_override_mA;
1032
1033         if (sizeof(buf) <= count)
1034                 goto override_err;
1035
1036         if (copy_from_user(buf, userbuf, count))
1037                 goto override_err;
1038
1039         /* terminate buffer and trim - white spaces may be appended
1040          *  at the end when invoked from shell command line */
1041         buf[count]='\0';
1042         strim(buf);
1043
1044         edp_reg_override_mA_temp = simple_strtoul(buf, &end, 10);
1045         if (*end != '\0')
1046                 goto override_err;
1047
1048         if (edp_reg_override_mA_temp >= regulator_cur)
1049                 goto override_err;
1050
1051         if (edp_reg_override_mA == edp_reg_override_mA_temp)
1052                 return count;
1053
1054         edp_reg_override_mA = edp_reg_override_mA_temp;
1055         if (init_cpu_edp_limits_calculated()) {
1056                 /* Revert to previous override value if new value fails */
1057                 edp_reg_override_mA = edp_reg_override_mA_prev;
1058                 goto override_err;
1059         }
1060
1061 #ifdef CONFIG_CPU_FREQ
1062         if (tegra_cpu_set_speed_cap(NULL)) {
1063                 pr_err("FAILED: Set CPU freq cap with new VDD_CPU EDP table\n");
1064                 goto override_out;
1065         }
1066
1067         pr_info("Reinitialized VDD_CPU EDP table with regulator current limit"
1068                         " %u mA\n", regulator_cur - edp_reg_override_mA);
1069 #else
1070         pr_err("FAILED: tegra_cpu_set_speed_cap() does not exist, failed to reinitialize VDD_CPU EDP table");
1071 #endif
1072
1073         return count;
1074
1075 override_err:
1076         pr_err("FAILED: Reinitialize VDD_CPU EDP table with override \"%s\"",
1077                buf);
1078 #ifdef CONFIG_CPU_FREQ
1079 override_out:
1080 #endif
1081         return -EINVAL;
1082 }
1083
1084 static int edp_debugfs_open(struct inode *inode, struct file *file)
1085 {
1086         return single_open(file, edp_debugfs_show, inode->i_private);
1087 }
1088
1089 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
1090 {
1091         return single_open(file, edp_limit_debugfs_show, inode->i_private);
1092 }
1093
1094 static int edp_reg_override_open(struct inode *inode, struct file *file)
1095 {
1096         return single_open(file, edp_reg_override_show, inode->i_private);
1097 }
1098
1099 static const struct file_operations edp_debugfs_fops = {
1100         .open           = edp_debugfs_open,
1101         .read           = seq_read,
1102         .llseek         = seq_lseek,
1103         .release        = single_release,
1104 };
1105
1106 static const struct file_operations edp_limit_debugfs_fops = {
1107         .open           = edp_limit_debugfs_open,
1108         .read           = seq_read,
1109         .llseek         = seq_lseek,
1110         .release        = single_release,
1111 };
1112
1113 static const struct file_operations edp_reg_override_debugfs_fops = {
1114         .open           = edp_reg_override_open,
1115         .read           = seq_read,
1116         .write          = edp_reg_override_write,
1117         .llseek         = seq_lseek,
1118         .release        = single_release,
1119 };
1120
1121 #ifdef CONFIG_EDP_FRAMEWORK
1122 static __init struct dentry *tegra_edp_debugfs_dir(void)
1123 {
1124         return edp_debugfs_dir;
1125 }
1126 #else
1127 static __init struct dentry *tegra_edp_debugfs_dir(void)
1128 {
1129         return debugfs_create_dir("edp", NULL);
1130 }
1131 #endif
1132
1133 static int __init tegra_edp_debugfs_init(void)
1134 {
1135         struct dentry *d_edp;
1136         struct dentry *d_edp_limit;
1137         struct dentry *d_edp_reg_override;
1138         struct dentry *edp_dir;
1139         struct dentry *vdd_cpu_dir;
1140
1141         edp_dir = tegra_edp_debugfs_dir();
1142
1143         if (!edp_dir)
1144                 goto edp_dir_err;
1145
1146         vdd_cpu_dir = debugfs_create_dir("vdd_cpu", edp_dir);
1147
1148         if (!vdd_cpu_dir)
1149                 goto vdd_cpu_dir_err;
1150
1151         d_edp = debugfs_create_file("edp", S_IRUGO, vdd_cpu_dir, NULL,
1152                                 &edp_debugfs_fops);
1153
1154         if (!d_edp)
1155                 goto edp_err;
1156
1157         d_edp_limit = debugfs_create_file("edp_limit", S_IRUGO, vdd_cpu_dir,
1158                                 NULL, &edp_limit_debugfs_fops);
1159
1160         if (!d_edp_limit)
1161                 goto edp_limit_err;
1162
1163         d_edp_reg_override = debugfs_create_file("edp_reg_override",
1164                                 S_IRUGO | S_IWUSR, vdd_cpu_dir, NULL,
1165                                 &edp_reg_override_debugfs_fops);
1166
1167         if (!d_edp_reg_override)
1168                 goto edp_reg_override_err;
1169
1170         if (tegra_core_edp_debugfs_init(edp_dir))
1171                 goto edp_reg_override_err;
1172
1173         return 0;
1174
1175 edp_reg_override_err:
1176         debugfs_remove(d_edp_limit);
1177 edp_limit_err:
1178         debugfs_remove(d_edp);
1179 edp_err:
1180         debugfs_remove(vdd_cpu_dir);
1181 vdd_cpu_dir_err:
1182         debugfs_remove(edp_dir);
1183 edp_dir_err:
1184         return -ENOMEM;
1185 }
1186
1187 late_initcall(tegra_edp_debugfs_init);
1188 #endif /* CONFIG_DEBUG_FS */