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