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