ARM: tegra11: dvfs: EDP freq granularity to follow CPU dvfs tables
[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         },
392         {
393                 .cpu_speedo_id      = 2, /* A01P+ fast CPU */
394                 .dyn_consts_n       = { 1091747, 2035205, 2978661, 3922119 },
395                 .leakage_consts_n   = {  538991,  752463,  959441, 1150000 },
396                 .leakage_consts_ijk = {
397                          /* i = 0 */
398                          { {  -42746668,   -5458429,   164998,  -1711, },
399                            {  178262421,   13375684,  -411791,   4590, },
400                            { -228866784,  -10482993,   331248,  -4062, },
401                            {   94301550,    2618719,   -85983,   1193, },
402                          },
403                          /* i = 1 */
404                          { { -256611791,   49677413, -1655785,  14917, },
405                            {  584675433, -132620939,  4541560, -41812, },
406                            { -398106336,  115987156, -4102328,  38737, },
407                            {   68897184,  -33030745,  1217839, -11801, },
408                          },
409                          /* i = 2 */
410                          { {  186324676,  -36019083,  1177969, -10669, },
411                            { -439237936,   98429131, -3276444,  30301, },
412                            {  315060898,  -88635036,  3004777, -28474, },
413                            {  -60854399,   26267188,  -907121,   8844, },
414                          },
415                          /* i = 3 */
416                          { {  -35432997,    6154621,  -202200,   1830, },
417                            {   87402153,  -16908683,   565152,  -5220, },
418                            {  -67775314,   15326770,  -521221,   4927, },
419                            {   15618709,   -4576116,   158401,  -1538, },
420                          },
421                  },
422         },
423 };
424
425 static struct tegra_edp_freq_voltage_table *freq_voltage_lut;
426 static unsigned int freq_voltage_lut_size;
427
428 static inline s64 edp_pow(s64 val, int pwr)
429 {
430         s64 retval = 1;
431
432         while (pwr) {
433                 if (pwr & 1)
434                         retval *= val;
435                 pwr >>= 1;
436                 if (pwr)
437                         val *= val;
438         }
439
440         return retval;
441 }
442
443 /*
444  * Find the maximum frequency that results in dynamic and leakage current that
445  * is less than the regulator current limit.
446  */
447 unsigned int edp_calculate_maxf(struct tegra_edp_cpu_leakage_params *params,
448                                 int temp_C,
449                                 int iddq_mA,
450                                 int n_cores_idx)
451 {
452         unsigned int voltage_mV, freq_KHz;
453         unsigned int cur_effective = regulator_cur - edp_reg_override_mA;
454         int f, i, j, k;
455         s64 leakage_mA, dyn_mA, leakage_calc_step;
456
457         for (f = freq_voltage_lut_size - 1; f >= 0; f--) {
458                 freq_KHz = freq_voltage_lut[f].freq / 1000;
459                 voltage_mV = freq_voltage_lut[f].voltage_mV;
460
461                 /* Calculate leakage current */
462                 leakage_mA = 0;
463                 for (i = 0; i <= 3; i++) {
464                         for (j = 0; j <= 3; j++) {
465                                 for (k = 0; k <= 3; k++) {
466                                         leakage_calc_step =
467                                                 params->leakage_consts_ijk
468                                                 [i][j][k] * edp_pow(iddq_mA, i);
469                                         /* Convert (mA)^i to (A)^i */
470                                         leakage_calc_step =
471                                                 div64_s64(leakage_calc_step,
472                                                           edp_pow(1000, i));
473                                         leakage_calc_step *=
474                                                 edp_pow(voltage_mV, j);
475                                         /* Convert (mV)^i to (V)^i */
476                                         leakage_calc_step =
477                                                 div64_s64(leakage_calc_step,
478                                                           edp_pow(1000, j));
479                                         leakage_calc_step *=
480                                                 edp_pow(temp_C, k);
481                                         /* leakage_consts_ijk was X 100,000 */
482                                         leakage_calc_step =
483                                                 div64_s64(leakage_calc_step,
484                                                           100000);
485                                         leakage_mA += leakage_calc_step;
486                                 }
487                         }
488                 }
489                 leakage_mA *= params->leakage_consts_n[n_cores_idx];
490                 /* leakage_const_n was pre-multiplied by 1,000,000 */
491                 leakage_mA = div64_s64(leakage_mA, 1000000);
492
493                 /* Calculate dynamic current */
494                 dyn_mA = voltage_mV * freq_KHz / 1000;
495                 /* Convert mV to V */
496                 dyn_mA = div64_s64(dyn_mA, 1000);
497                 dyn_mA *= params->dyn_consts_n[n_cores_idx];
498                 /* dyn_const_n was pre-multiplied by 1,000,000 */
499                 dyn_mA = div64_s64(dyn_mA, 1000000);
500
501                 if ((leakage_mA + dyn_mA) <= cur_effective)
502                         return freq_KHz;
503         }
504         return 0;
505 }
506
507 static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
508                                 unsigned int cpu_speedo_idx)
509 {
510         unsigned int i, j, freq;
511         int voltage_mV;
512
513         for (i = 0, j = 0, freq = 0;
514                  i < freq_voltage_lut_size;
515                  i++, freq += FREQ_STEP) {
516
517                 /* Predict voltages */
518                 voltage_mV = tegra_dvfs_predict_millivolts(clk_cpu_g, freq);
519                 if (voltage_mV < 0) {
520                         pr_err("%s: couldn't predict voltage: freq %u; err %d",
521                                __func__, freq, voltage_mV);
522                         return -EINVAL;
523                 }
524
525                 /* Cache frequency / voltage / voltage constant relationship */
526                 freq_voltage_lut[i].freq = freq;
527                 freq_voltage_lut[i].voltage_mV = voltage_mV;
528         }
529         return 0;
530 }
531
532 int edp_find_speedo_idx(int cpu_speedo_id, unsigned int *cpu_speedo_idx)
533 {
534         int i;
535
536         for (i = 0; i < ARRAY_SIZE(leakage_params); i++)
537                 if (cpu_speedo_id == leakage_params[i].cpu_speedo_id) {
538                         *cpu_speedo_idx = i;
539                         return 0;
540                 }
541
542         pr_err("%s: couldn't find cpu speedo id %d in freq/voltage LUT\n",
543                __func__, cpu_speedo_id);
544         return -EINVAL;
545 }
546
547 static int init_cpu_edp_limits_calculated(void)
548 {
549         unsigned int temp_idx, n_cores_idx;
550         unsigned int cpu_g_minf, cpu_g_maxf;
551         unsigned int iddq_mA;
552         unsigned int cpu_speedo_idx;
553         struct tegra_edp_limits *edp_calculated_limits;
554         struct tegra_edp_cpu_leakage_params *params;
555         int ret;
556         struct clk *clk_cpu_g = tegra_get_clock_by_name("cpu_g");
557         int cpu_speedo_id = tegra_cpu_speedo_id();
558
559         /* Determine all inputs to EDP formula */
560         iddq_mA = tegra_get_cpu_iddq_value();
561         ret = edp_find_speedo_idx(cpu_speedo_id, &cpu_speedo_idx);
562         if (ret)
563                 return ret;
564
565         params = &leakage_params[cpu_speedo_idx];
566
567         edp_calculated_limits = kmalloc(sizeof(struct tegra_edp_limits)
568                                         * ARRAY_SIZE(temperatures), GFP_KERNEL);
569         BUG_ON(!edp_calculated_limits);
570
571         cpu_g_minf = 0;
572         cpu_g_maxf = clk_get_max_rate(clk_cpu_g);
573         freq_voltage_lut_size = (cpu_g_maxf - cpu_g_minf) / FREQ_STEP + 1;
574         freq_voltage_lut = kmalloc(sizeof(struct tegra_edp_freq_voltage_table)
575                                    * freq_voltage_lut_size, GFP_KERNEL);
576         if (!freq_voltage_lut) {
577                 pr_err("%s: failed alloc mem for freq/voltage LUT\n", __func__);
578                 return -ENOMEM;
579         }
580
581         ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx);
582         if (ret) {
583                 kfree(freq_voltage_lut);
584                 return ret;
585         }
586
587         /* Calculate EDP table */
588         for (temp_idx = 0; temp_idx < ARRAY_SIZE(temperatures); temp_idx++) {
589                 edp_calculated_limits[temp_idx].
590                         temperature = temperatures[temp_idx];
591                 for (n_cores_idx = 0; n_cores_idx < NR_CPUS; n_cores_idx++)
592                         edp_calculated_limits[temp_idx].
593                                 freq_limits[n_cores_idx] =
594                                 edp_calculate_maxf(params,
595                                                    temperatures[temp_idx],
596                                                    iddq_mA,
597                                                    n_cores_idx);
598         }
599
600         /*
601          * If this is an EDP table update, need to overwrite old table.
602          * The old table's address must remain valid.
603          */
604         if (edp_limits != edp_default_limits) {
605                 memcpy(edp_limits, edp_calculated_limits,
606                        sizeof(struct tegra_edp_limits)
607                        * ARRAY_SIZE(temperatures));
608                 kfree(edp_calculated_limits);
609         }
610         else {
611                 edp_limits = edp_calculated_limits;
612                 edp_limits_size = ARRAY_SIZE(temperatures);
613         }
614
615         kfree(freq_voltage_lut);
616         return 0;
617 }
618
619 static int __init init_cpu_edp_limits_lookup(void)
620 {
621         int i, j;
622         struct tegra_edp_limits *e;
623         struct tegra_edp_vdd_cpu_entry *t;
624         int tsize;
625         int cpu_speedo_id = tegra_cpu_speedo_id();
626
627         t = (struct tegra_edp_vdd_cpu_entry *)tegra_edp_vdd_cpu_map;
628         tsize = sizeof(tegra_edp_vdd_cpu_map)
629                 / sizeof(struct tegra_edp_vdd_cpu_entry);
630
631         for (i = 0; i < tsize; i++) {
632                 if (t[i].speedo_id == cpu_speedo_id &&
633                     t[i].regulator_100mA <= regulator_cur / 100)
634                         break;
635         }
636
637         /* No entry found in tegra_edp_vdd_cpu_map */
638         if (i >= tsize)
639                 return -EINVAL;
640
641         /* Find all rows for this entry */
642         for (j = i + 1; j < tsize; j++) {
643                 if (t[i].speedo_id != t[j].speedo_id ||
644                     t[i].regulator_100mA != t[j].regulator_100mA)
645                         break;
646         }
647
648         edp_limits_size = j - i;
649         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
650                     GFP_KERNEL);
651         BUG_ON(!e);
652
653         for (j = 0; j < edp_limits_size; j++) {
654                 e[j].temperature = (int)t[i+j].temperature;
655                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0]*10000;
656                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1]*10000;
657                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2]*10000;
658                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3]*10000;
659         }
660
661         if (edp_limits != edp_default_limits)
662                 kfree(edp_limits);
663
664         edp_limits = e;
665         return 0;
666 }
667
668 void tegra_recalculate_cpu_edp_limits(void)
669 {
670         if (tegra_chip_id == TEGRA11X)
671                 init_cpu_edp_limits_calculated();
672 }
673
674 /*
675  * Specify regulator current in mA, e.g. 5000mA
676  * Use 0 for default
677  */
678 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
679 {
680         if (!regulator_mA) {
681                 edp_limits = edp_default_limits;
682                 edp_limits_size = ARRAY_SIZE(edp_default_limits);
683                 return;
684         }
685         regulator_cur = regulator_mA + OVERRIDE_DEFAULT;
686
687         switch (tegra_chip_id) {
688         case TEGRA30:
689                 if (init_cpu_edp_limits_lookup() == 0)
690                         return;
691                 break;
692         case TEGRA11X:
693                 if (init_cpu_edp_limits_calculated() == 0)
694                         return;
695                 break;
696         case TEGRA20:
697         default:
698                 BUG();
699                 break;
700         }
701
702         edp_limits = edp_default_limits;
703         edp_limits_size = ARRAY_SIZE(edp_default_limits);
704 }
705
706 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
707 {
708         int cpu_speedo_id = tegra_cpu_speedo_id();
709         int i;
710         unsigned int *e;
711         struct tegra_system_edp_entry *t = tegra_system_edp_map;
712         int tsize = ARRAY_SIZE(tegra_system_edp_map);
713
714         if (!power_limit_mW) {
715                 e = NULL;
716                 goto out;
717         }
718
719         for (i = 0; i < tsize; i++)
720                 if (t[i].speedo_id == cpu_speedo_id)
721                         break;
722
723         if (i >= tsize) {
724                 e = NULL;
725                 goto out;
726         }
727
728         do {
729                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
730                         break;
731                 i++;
732         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
733
734         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
735                 i--; /* No low enough entry in the table, use best possible */
736
737         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
738         BUG_ON(!e);
739
740         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
741         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
742         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
743         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
744
745 out:
746         kfree(system_edp_limits);
747
748         system_edp_limits = e;
749 }
750
751
752 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
753 {
754         *limits = edp_limits;
755         *size = edp_limits_size;
756 }
757
758 void tegra_get_system_edp_limits(const unsigned int **limits)
759 {
760         *limits = system_edp_limits;
761 }
762
763 #ifdef CONFIG_DEBUG_FS
764
765 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
766 {
767         seq_printf(s, "%u\n", tegra_get_edp_limit(NULL));
768         return 0;
769 }
770
771 static int edp_debugfs_show(struct seq_file *s, void *data)
772 {
773         int i, th_idx;
774
775         tegra_get_edp_limit(&th_idx);
776         seq_printf(s, "-- VDD_CPU %sEDP table (%umA = %umA - %umA) --\n",
777                    edp_limits == edp_default_limits ? "default " : "",
778                    regulator_cur - edp_reg_override_mA,
779                    regulator_cur, edp_reg_override_mA);
780         seq_printf(s, "%6s %10s %10s %10s %10s\n",
781                    " Temp.", "1-core", "2-cores", "3-cores", "4-cores");
782         for (i = 0; i < edp_limits_size; i++) {
783                 seq_printf(s, "%c%3dC: %10u %10u %10u %10u\n",
784                            i == th_idx ? '>' : ' ',
785                            edp_limits[i].temperature,
786                            edp_limits[i].freq_limits[0],
787                            edp_limits[i].freq_limits[1],
788                            edp_limits[i].freq_limits[2],
789                            edp_limits[i].freq_limits[3]);
790         }
791
792         if (system_edp_limits) {
793                 seq_printf(s, "\n-- System EDP table --\n");
794                 seq_printf(s, "%10u %10u %10u %10u\n",
795                            system_edp_limits[0],
796                            system_edp_limits[1],
797                            system_edp_limits[2],
798                            system_edp_limits[3]);
799         }
800
801         return 0;
802 }
803
804 static int edp_reg_override_show(struct seq_file *s, void *data)
805 {
806         seq_printf(s, "Limit override: %u mA. Effective limit: %u mA\n",
807                    edp_reg_override_mA, regulator_cur - edp_reg_override_mA);
808         return 0;
809 }
810
811 static int edp_reg_override_write(struct file *file,
812         const char __user *userbuf, size_t count, loff_t *ppos)
813 {
814         char buf[32], *end;
815         unsigned int edp_reg_override_mA_temp;
816         unsigned int edp_reg_override_mA_prev = edp_reg_override_mA;
817
818         if (sizeof(buf) <= count)
819                 goto override_err;
820
821         if (copy_from_user(buf, userbuf, count))
822                 goto override_err;
823
824         /* terminate buffer and trim - white spaces may be appended
825          *  at the end when invoked from shell command line */
826         buf[count]='\0';
827         strim(buf);
828
829         edp_reg_override_mA_temp = simple_strtoul(buf, &end, 10);
830         if (*end != '\0')
831                 goto override_err;
832
833         if (edp_reg_override_mA_temp >= regulator_cur)
834                 goto override_err;
835
836         if (edp_reg_override_mA == edp_reg_override_mA_temp)
837                 return count;
838
839         edp_reg_override_mA = edp_reg_override_mA_temp;
840         if (init_cpu_edp_limits_calculated()) {
841                 /* Revert to previous override value if new value fails */
842                 edp_reg_override_mA = edp_reg_override_mA_prev;
843                 goto override_err;
844         }
845
846         if (tegra_cpu_set_speed_cap(NULL)) {
847                 pr_err("FAILED: Set CPU freq cap with new VDD_CPU EDP table\n");
848                 goto override_out;
849         }
850
851         pr_info("Reinitialized VDD_CPU EDP table with regulator current limit"
852                         " %u mA\n", regulator_cur - edp_reg_override_mA);
853
854         return count;
855
856 override_err:
857         pr_err("FAILED: Reinitialize VDD_CPU EDP table with override \"%s\"",
858                buf);
859 override_out:
860         return -EINVAL;
861 }
862
863 static int edp_debugfs_open(struct inode *inode, struct file *file)
864 {
865         return single_open(file, edp_debugfs_show, inode->i_private);
866 }
867
868 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
869 {
870         return single_open(file, edp_limit_debugfs_show, inode->i_private);
871 }
872
873 static int edp_reg_override_open(struct inode *inode, struct file *file)
874 {
875         return single_open(file, edp_reg_override_show, inode->i_private);
876 }
877
878 static const struct file_operations edp_debugfs_fops = {
879         .open           = edp_debugfs_open,
880         .read           = seq_read,
881         .llseek         = seq_lseek,
882         .release        = single_release,
883 };
884
885 static const struct file_operations edp_limit_debugfs_fops = {
886         .open           = edp_limit_debugfs_open,
887         .read           = seq_read,
888         .llseek         = seq_lseek,
889         .release        = single_release,
890 };
891
892 static const struct file_operations edp_reg_override_debugfs_fops = {
893         .open           = edp_reg_override_open,
894         .read           = seq_read,
895         .write          = edp_reg_override_write,
896         .llseek         = seq_lseek,
897         .release        = single_release,
898 };
899
900 static int __init tegra_edp_debugfs_init(void)
901 {
902         struct dentry *d_edp;
903         struct dentry *d_edp_limit;
904         struct dentry *d_edp_reg_override;
905         struct dentry *edp_dir;
906         struct dentry *vdd_cpu_dir;
907
908         edp_dir = debugfs_create_dir("edp", NULL);
909
910         if (!edp_dir)
911                 goto edp_dir_err;
912
913         vdd_cpu_dir = debugfs_create_dir("vdd_cpu", edp_dir);
914
915         if (!vdd_cpu_dir)
916                 goto vdd_cpu_dir_err;
917
918         d_edp = debugfs_create_file("edp", S_IRUGO, vdd_cpu_dir, NULL,
919                                 &edp_debugfs_fops);
920
921         if (!d_edp)
922                 goto edp_err;
923
924         d_edp_limit = debugfs_create_file("edp_limit", S_IRUGO, vdd_cpu_dir,
925                                 NULL, &edp_limit_debugfs_fops);
926
927         if (!d_edp_limit)
928                 goto edp_limit_err;
929
930         d_edp_reg_override = debugfs_create_file("edp_reg_override",
931                                 S_IRUGO | S_IWUSR, vdd_cpu_dir, NULL,
932                                 &edp_reg_override_debugfs_fops);
933
934         if (!d_edp_reg_override)
935                 goto edp_reg_override_err;
936
937         if (tegra_core_edp_debugfs_init(edp_dir))
938                 goto edp_reg_override_err;
939
940         return 0;
941
942 edp_reg_override_err:
943         debugfs_remove(d_edp_limit);
944 edp_limit_err:
945         debugfs_remove(d_edp);
946 edp_err:
947         debugfs_remove(vdd_cpu_dir);
948 vdd_cpu_dir_err:
949         debugfs_remove(edp_dir);
950 edp_dir_err:
951         return -ENOMEM;
952 }
953
954 late_initcall(tegra_edp_debugfs_init);
955 #endif /* CONFIG_DEBUG_FS */