arm: tegra: power: enable dynamic VDD_CPU EDP capping
[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 10000000
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_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 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 /*
328  * Constants for EDP calculations
329  */
330 int temps_lut[] = { 23, 40, 50, 60, 70, 75, 80, 85, 90, 95 };
331
332 /* TODO: This struct will get large for 13 speedo IDs... relocate. */
333 struct edp_constants_lut_t {
334         int cpu_speedo_id;
335         /* All constants are pre-multiplied by 1,000,000 */
336         int leakage_consts_ijk[64];
337         int leakage_consts_n[NR_CPUS];
338         int dyn_consts_n[NR_CPUS];
339 } edp_constants_lut[] = {
340         {
341                 .cpu_speedo_id = -1,
342                 .leakage_consts_n = {
343                         641026,
344                         757576,
345                         878500,
346                         1000000
347                 },
348                 /* Constants order: C(i,j,k), i,j,k = {0,1,2,3}, with k
349                  * being the least significant index and i being the most
350                  * significant index */
351                 .leakage_consts_ijk =  {
352                         0,
353                         -21481846,
354                         519650,
355                         -3254,
356                         0,
357                         65678948,
358                         -1572498,
359                         9850,
360                         0,
361                         -65988168,
362                         1565063,
363                         -9808,
364                         0,
365                         22109316,
366                         -522158,
367                         3281,
368                         0,
369                         24840561,
370                         -565618,
371                         5196,
372                         0,
373                         -65603470,
374                         1592186,
375                         -13823,
376                         0,
377                         56585242,
378                         -1488977,
379                         12944,
380                         0,
381                         -14740016,
382                         470284,
383                         -3670,
384                         0,
385                         -7050232,
386                         244771,
387                         -1779,
388                         0,
389                         20985919,
390                         -701848,
391                         5008,
392                         0,
393                         -20478304,
394                         677782,
395                         -4766,
396                         0,
397                         7093793,
398                         -218579,
399                         1454,
400                         0,
401                         942881,
402                         -29599,
403                         203,
404                         0,
405                         -2750253,
406                         84116,
407                         -569,
408                         0,
409                         2643026,
410                         -80080,
411                         536,
412                         0,
413                         -868855,
414                         25062,
415                         -161,
416                 }, /* consts_ijk */
417                 .dyn_consts_n = {
418                         1560207,
419                         2378136,
420                         3196066,
421                         4013995
422                 }
423         }
424 };
425
426 struct freq_voltage_lut_t {
427         unsigned int freq;
428         int voltage_mV;
429 } *freq_voltage_lut = 0;
430 unsigned int freq_voltage_lut_size;
431
432 static inline s64 edp_pow(s64 val, int pwr)
433 {
434         s64 retval = 1;
435
436         while (pwr) {
437                 if (pwr & 1)
438                         retval *= val;
439                 pwr >>= 1;
440                 if (pwr)
441                         val *= val;
442         }
443
444         return retval;
445 }
446
447 /*
448  * Find the maximum frequency that results in dynamic and leakage current that
449  * is less than the regulator current limit.
450  */
451 unsigned int edp_calculate_maxf(struct edp_constants_lut_t  *edp_constants,
452                                 int temp_C,
453                                 int iddq_mA,
454                                 int n_cores_idx)
455 {
456         unsigned int voltage_mV, freq_MHz;
457         unsigned int regulator_cur_effective = regulator_cur - edp_reg_override_mA;
458         int f_v_pair, i, j, k, leakage_const_n, dyn_const_n;
459         int *leakage_consts_ijk;
460         s64 leakage_mA, dyn_mA, leakage_calc_step;
461         /* WAR for GCC 4.4.3 bug 43949 - compiler throws an array bounds warning
462          * if these arrays are dereferenced in the calling function*/
463         leakage_consts_ijk = edp_constants->leakage_consts_ijk;
464         dyn_const_n = edp_constants->dyn_consts_n[n_cores_idx];
465         leakage_const_n = edp_constants->leakage_consts_n[n_cores_idx];
466
467         for (f_v_pair = freq_voltage_lut_size - 1; f_v_pair  >= 0; f_v_pair--) {
468                 freq_MHz = freq_voltage_lut[f_v_pair].freq / 1000000;
469                 voltage_mV = freq_voltage_lut[f_v_pair].voltage_mV;
470
471                 /*
472                  * Calculate leakage current
473                  */
474                 leakage_mA = 0;
475                 for (i = 0; i <= 3; i++)
476                         for (j = 0; j <= 3; j++)
477                                 for (k = 0; k <= 3; k++) {
478                                         leakage_calc_step =
479                                              leakage_consts_ijk[i*16 + j*4 + k]
480                                                 * edp_pow(iddq_mA, i);
481                                         /* Convert (mA)^i to (A)^i */
482                                         leakage_calc_step =
483                                                 div64_s64(leakage_calc_step,
484                                                           edp_pow(1000, i));
485                                         leakage_calc_step *=
486                                                 edp_pow(voltage_mV, j);
487                                         /* Convert (mV)^i to (V)^i */
488                                         leakage_calc_step =
489                                                 div64_s64(leakage_calc_step,
490                                                           edp_pow(1000, j));
491                                         leakage_calc_step *=
492                                                 edp_pow(temp_C, k);
493                                         /* const_ijk was X 1,000,000 */
494                                         leakage_calc_step =
495                                                 div64_s64(leakage_calc_step,
496                                                           1000000);
497                                         leakage_mA += leakage_calc_step;
498                                 }
499
500                 leakage_mA *= leakage_const_n;
501                 /* leakage_const_n was pre-multiplied by 1,000,000 */
502                 leakage_mA = div64_s64(leakage_mA, 1000000);
503
504                 /*
505                  * Calculate dynamic current
506                  */
507                 dyn_mA = voltage_mV * freq_MHz;
508                 /* Convert mV to V */
509                 dyn_mA = div64_s64(dyn_mA, 1000);
510                 dyn_mA *= dyn_const_n;
511                 /* dyn_const_n was pre-multiplied by 1,000,000 */
512                 dyn_mA = div64_s64(dyn_mA, 1000000);
513
514                 if ((leakage_mA + dyn_mA) <= regulator_cur_effective)
515                         return freq_MHz * 1000;
516         }
517         return 0;
518 }
519
520 static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
521                                 unsigned int cpu_speedo_idx)
522 {
523         unsigned int i, j, freq;
524         int voltage_mV;
525
526         for (i = 0, j = 0, freq = clk_get_min_rate(clk_cpu_g);
527                  i < freq_voltage_lut_size;
528                  i++, freq += FREQ_STEP) {
529
530                 /* Predict voltages */
531                 voltage_mV = tegra_dvfs_predict_millivolts(clk_cpu_g, freq);
532                 if (voltage_mV < 0) {
533                         pr_err("%s: couldn't predict voltage for freq %u, err %d",
534                                __func__, freq, voltage_mV);
535                         return -EINVAL;
536                 }
537
538                 /* Cache frequency / voltage / voltage constant relationship */
539                 freq_voltage_lut[i].freq = freq;
540                 freq_voltage_lut[i].voltage_mV = voltage_mV;
541         }
542         return 0;
543 }
544
545 int edp_find_speedo_idx(int cpu_speedo_id, unsigned int *cpu_speedo_idx)
546 {
547         int i;
548
549         for (i = 0; i < ARRAY_SIZE(edp_constants_lut); i++)
550                 if (cpu_speedo_id == edp_constants_lut[i].cpu_speedo_id) {
551                         *cpu_speedo_idx = i;
552                         return 0;
553                 }
554
555         pr_err("%s: couldn't find cpu speedo id %d in freq/voltage LUT\n",
556                __func__, cpu_speedo_id);
557         return -EINVAL;
558 }
559
560 int init_cpu_edp_limits_calculated(int cpu_speedo_id)
561 {
562         unsigned int temp_idx, n_cores_idx;
563         unsigned int cpu_g_minf, cpu_g_maxf;
564         unsigned int iddq_mA;
565         unsigned int cpu_speedo_idx;
566         struct tegra_edp_limits *edp_calculated_limits;
567         struct edp_constants_lut_t *edp_constants;
568         int ret;
569         struct clk *clk_cpu_g = tegra_get_clock_by_name("cpu_g");
570
571         /* Determine all inputs to EDP formula */
572         iddq_mA = tegra_get_cpu_iddq_value();
573         ret = edp_find_speedo_idx(cpu_speedo_id, &cpu_speedo_idx);
574         if (ret)
575                 return ret;
576
577         edp_constants = &edp_constants_lut[cpu_speedo_idx];
578
579         edp_calculated_limits =
580                 kmalloc(sizeof(struct tegra_edp_limits) * ARRAY_SIZE(temps_lut),
581                                 GFP_KERNEL);
582         BUG_ON(!edp_calculated_limits);
583
584         cpu_g_minf = clk_get_min_rate(clk_cpu_g);
585         cpu_g_maxf = clk_get_max_rate(clk_cpu_g);
586         freq_voltage_lut_size = (cpu_g_maxf - cpu_g_minf) / FREQ_STEP + 1;
587         freq_voltage_lut =
588                 kmalloc(sizeof(struct freq_voltage_lut_t)*freq_voltage_lut_size,
589                                 GFP_KERNEL);
590         if (!freq_voltage_lut) {
591                 pr_err("%s: failed alloc mem for freq/voltage LUT\n", __func__);
592                 return -ENOMEM;
593         }
594
595         ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx);
596         if (ret) {
597                 kfree(freq_voltage_lut);
598                 return ret;
599         }
600
601         /* Calculate EDP table */
602         for (temp_idx = 0; temp_idx < ARRAY_SIZE(temps_lut); temp_idx++) {
603                 edp_calculated_limits[temp_idx].temperature = temps_lut[temp_idx];
604
605                 for (n_cores_idx = 0; n_cores_idx < NR_CPUS; n_cores_idx++)
606                         edp_calculated_limits[temp_idx].
607                                 freq_limits[n_cores_idx] =
608                                 edp_calculate_maxf(edp_constants,
609                                                 temps_lut[temp_idx],
610                                                 iddq_mA,
611                                                 n_cores_idx);
612         }
613
614         /*
615          * If this is an EDP table update, need to overwrite old table.
616          * The old table's address must remain valid.
617          */
618         if (edp_limits != edp_default_limits) {
619                 memcpy(edp_limits, edp_calculated_limits,
620                        sizeof(struct tegra_edp_limits) * ARRAY_SIZE(temps_lut));
621                 kfree(edp_calculated_limits);
622         }
623         else {
624                 edp_limits = edp_calculated_limits;
625                 edp_limits_size = ARRAY_SIZE(temps_lut);
626         }
627
628         kfree(freq_voltage_lut);
629         return 0;
630 }
631
632 int __init init_cpu_edp_limits_lookup(int cpu_speedo_id)
633 {
634         int i, j;
635         struct tegra_edp_limits *e;
636         struct tegra_edp_entry *t = (struct tegra_edp_entry *)tegra_edp_map;
637         int tsize = sizeof(tegra_edp_map)/sizeof(struct tegra_edp_entry);
638
639         for (i = 0; i < tsize; i++) {
640                 if (t[i].speedo_id == cpu_speedo_id &&
641                     t[i].regulator_100mA <= regulator_cur / 100)
642                         break;
643         }
644
645         /* No entry found in tegra_edp_map */
646         if (i >= tsize)
647                 return -EINVAL;
648
649         /* Find all rows for this entry */
650         for (j = i + 1; j < tsize; j++) {
651                 if (t[i].speedo_id != t[j].speedo_id ||
652                     t[i].regulator_100mA != t[j].regulator_100mA)
653                         break;
654         }
655
656         edp_limits_size = j - i;
657         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
658                     GFP_KERNEL);
659         BUG_ON(!e);
660
661         for (j = 0; j < edp_limits_size; j++) {
662                 e[j].temperature = (int)t[i+j].temperature;
663                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0]*10000;
664                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1]*10000;
665                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2]*10000;
666                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3]*10000;
667         }
668
669         if (edp_limits != edp_default_limits)
670                 kfree(edp_limits);
671
672         edp_limits = e;
673         return 0;
674 }
675
676 /*
677  * Specify regulator current in mA, e.g. 5000mA
678  * Use 0 for default
679  */
680 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
681 {
682         int cpu_speedo_id = tegra_cpu_speedo_id();
683
684         if (!regulator_mA) {
685                 edp_limits = edp_default_limits;
686                 edp_limits_size = ARRAY_SIZE(edp_default_limits);
687                 return;
688         }
689         regulator_cur = regulator_mA + OVERRIDE_DEFAULT;
690
691         if (init_cpu_edp_limits_lookup(cpu_speedo_id) == 0)
692                 return;
693
694         if (init_cpu_edp_limits_calculated(cpu_speedo_id) == 0)
695                 return;
696
697         edp_limits = edp_default_limits;
698         edp_limits_size = ARRAY_SIZE(edp_default_limits);
699 }
700
701 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
702 {
703         int cpu_speedo_id = tegra_cpu_speedo_id();
704         int i;
705         unsigned int *e;
706         struct system_edp_entry *t =
707                 (struct system_edp_entry *)tegra_system_edp_map;
708         int tsize = sizeof(tegra_system_edp_map) /
709                 sizeof(struct system_edp_entry);
710
711         if (!power_limit_mW) {
712                 e = NULL;
713                 goto out;
714         }
715
716         for (i = 0; i < tsize; i++)
717                 if (t[i].speedo_id == cpu_speedo_id)
718                         break;
719
720         if (i >= tsize) {
721                 e = NULL;
722                 goto out;
723         }
724
725         do {
726                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
727                         break;
728                 i++;
729         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
730
731         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
732                 i--; /* No low enough entry in the table, use best possible */
733
734         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
735         BUG_ON(!e);
736
737         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
738         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
739         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
740         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
741
742 out:
743         kfree(system_edp_limits);
744
745         system_edp_limits = e;
746 }
747
748
749 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
750 {
751         *limits = edp_limits;
752         *size = edp_limits_size;
753 }
754
755 void tegra_get_system_edp_limits(const unsigned int **limits)
756 {
757         *limits = system_edp_limits;
758 }
759
760 #ifdef CONFIG_EDP_FRAMEWORK
761
762 static struct edp_manager battery_edp_manager = {
763         .name = "battery"
764 };
765
766 void __init tegra_battery_edp_init(unsigned int cap)
767 {
768         struct edp_governor *g;
769         int r;
770
771         battery_edp_manager.imax = cap;
772         r = edp_register_manager(&battery_edp_manager);
773         if (r)
774                 goto err_ret;
775
776         /* start with priority governor */
777         g = edp_get_governor("priority");
778         if (!g) {
779                 r = -EFAULT;
780                 goto err_ret;
781         }
782
783         r = edp_set_governor(&battery_edp_manager, g);
784         if (r)
785                 goto err_ret;
786
787         return;
788
789 err_ret:
790         pr_err("Battery EDP init failed with error %d\n", r);
791         WARN_ON(1);
792 }
793
794 #endif
795
796 #ifdef CONFIG_DEBUG_FS
797
798 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
799 {
800         seq_printf(s, "%u\n", tegra_get_edp_limit(NULL));
801         return 0;
802 }
803
804 static int edp_debugfs_show(struct seq_file *s, void *data)
805 {
806         int i, th_idx;
807
808         tegra_get_edp_limit(&th_idx);
809         seq_printf(s, "-- VDD_CPU %sEDP table (%umA = %umA - %umA) --\n",
810                    edp_limits == edp_default_limits ? "default " : "",
811                    regulator_cur - edp_reg_override_mA,
812                    regulator_cur, edp_reg_override_mA);
813         seq_printf(s, "%6s %10s %10s %10s %10s\n",
814                    " Temp.", "1-core", "2-cores", "3-cores", "4-cores");
815         for (i = 0; i < edp_limits_size; i++) {
816                 seq_printf(s, "%c%3dC: %10u %10u %10u %10u\n",
817                            i == th_idx ? '>' : ' ',
818                            edp_limits[i].temperature,
819                            edp_limits[i].freq_limits[0],
820                            edp_limits[i].freq_limits[1],
821                            edp_limits[i].freq_limits[2],
822                            edp_limits[i].freq_limits[3]);
823         }
824
825         if (system_edp_limits) {
826                 seq_printf(s, "\n-- System EDP table --\n");
827                 seq_printf(s, "%10u %10u %10u %10u\n",
828                            system_edp_limits[0],
829                            system_edp_limits[1],
830                            system_edp_limits[2],
831                            system_edp_limits[3]);
832         }
833
834         return 0;
835 }
836
837 static int edp_reg_override_show(struct seq_file *s, void *data)
838 {
839         seq_printf(s, "Regulator limit override: %u mA. Effective regulator limit: %u mA\n",
840                    edp_reg_override_mA, regulator_cur - edp_reg_override_mA);
841         return 0;
842 }
843
844 static int edp_reg_override_write(struct file *file,
845         const char __user *userbuf, size_t count, loff_t *ppos)
846 {
847         char buf[32], *end;
848         unsigned int edp_reg_override_mA_temp;
849         unsigned int edp_reg_override_mA_prev = edp_reg_override_mA;
850         int cpu_speedo_id;
851
852         if (sizeof(buf) <= count)
853                 goto override_err;
854
855         if (copy_from_user(buf, userbuf, count))
856                 goto override_err;
857
858         /* terminate buffer and trim - white spaces may be appended
859          *  at the end when invoked from shell command line */
860         buf[count]='\0';
861         strim(buf);
862
863         edp_reg_override_mA_temp = simple_strtoul(buf, &end, 10);
864         if (*end != '\0')
865                 goto override_err;
866
867         if (edp_reg_override_mA_temp >= regulator_cur)
868                 goto override_err;
869
870         edp_reg_override_mA = edp_reg_override_mA_temp;
871         cpu_speedo_id = tegra_cpu_speedo_id();
872         if(init_cpu_edp_limits_calculated(cpu_speedo_id)) {
873                 /* Revert to previous override value if new value fails */
874                 edp_reg_override_mA = edp_reg_override_mA_prev;
875                 goto override_err;
876         }
877
878         if (tegra_cpu_set_speed_cap(NULL)) {
879                 pr_err("Failed to apply CPU freq cap using new VDD_CPU EDP table.\n");
880                 goto override_out;
881         }
882
883         pr_info("Reinitialized VDD_CPU EDP table with regulator current limit"
884                         " %u mA\n", regulator_cur - edp_reg_override_mA);
885
886         return count;
887
888 override_err:
889         pr_err("Failed to reinitialized VDD_CPU EDP table with override \"%s\"",
890                buf);
891 override_out:
892         return -EINVAL;
893
894 }
895
896 static int edp_debugfs_open(struct inode *inode, struct file *file)
897 {
898         return single_open(file, edp_debugfs_show, inode->i_private);
899 }
900
901 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
902 {
903         return single_open(file, edp_limit_debugfs_show, inode->i_private);
904 }
905
906 static int edp_reg_override_open(struct inode *inode, struct file *file)
907 {
908         return single_open(file, edp_reg_override_show, inode->i_private);
909 }
910
911 static const struct file_operations edp_debugfs_fops = {
912         .open           = edp_debugfs_open,
913         .read           = seq_read,
914         .llseek         = seq_lseek,
915         .release        = single_release,
916 };
917
918 static const struct file_operations edp_limit_debugfs_fops = {
919         .open           = edp_limit_debugfs_open,
920         .read           = seq_read,
921         .llseek         = seq_lseek,
922         .release        = single_release,
923 };
924
925 static const struct file_operations edp_reg_override_debugfs_fops = {
926         .open           = edp_reg_override_open,
927         .read           = seq_read,
928         .write          = edp_reg_override_write,
929         .llseek         = seq_lseek,
930         .release        = single_release,
931 };
932
933 static int __init tegra_edp_debugfs_init(void)
934 {
935         struct dentry *d_edp;
936         struct dentry *d_edp_limit;
937         struct dentry *d_edp_reg_override;
938         struct dentry *edp_dir;
939         struct dentry *vdd_cpu_dir;
940
941         edp_dir = debugfs_create_dir("edp", NULL);
942
943         if (!edp_dir)
944                 goto edp_dir_err;
945
946         vdd_cpu_dir = debugfs_create_dir("vdd_cpu", edp_dir);
947
948         if (!vdd_cpu_dir)
949                 goto vdd_cpu_dir_err;
950
951         d_edp = debugfs_create_file("edp", S_IRUGO, vdd_cpu_dir, NULL,
952                                 &edp_debugfs_fops);
953
954         if (!d_edp)
955                 goto edp_err;
956
957         d_edp_limit = debugfs_create_file("edp_limit", S_IRUGO, vdd_cpu_dir,
958                                 NULL, &edp_limit_debugfs_fops);
959
960         if (!d_edp_limit)
961                 goto edp_limit_err;
962
963         d_edp_reg_override = debugfs_create_file("edp_reg_override",
964                                 S_IRUGO | S_IWUSR, vdd_cpu_dir, NULL,
965                                 &edp_reg_override_debugfs_fops);
966
967         if (!d_edp_reg_override)
968                 goto edp_reg_override_err;
969
970         return 0;
971
972 edp_reg_override_err:
973         debugfs_remove(d_edp_limit);
974 edp_limit_err:
975         debugfs_remove(d_edp);
976 edp_err:
977         debugfs_remove(vdd_cpu_dir);
978 vdd_cpu_dir_err:
979         debugfs_remove(edp_dir);
980 edp_dir_err:
981         return -ENOMEM;
982 }
983
984 late_initcall(tegra_edp_debugfs_init);
985 #endif /* CONFIG_DEBUG_FS */