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