arm: tegra: power: Updated EDP table to latest spec
[linux-3.10.git] / arch / arm / mach-tegra / edp.c
1 /*
2  * arch/arm/mach-tegra/edp.c
3  *
4  * Copyright (C) 2011 NVIDIA, Inc.
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 <mach/edp.h>
26
27 #include "fuse.h"
28
29 static const struct tegra_edp_limits *edp_limits;
30 static int edp_limits_size;
31 static unsigned int regulator_cur;
32
33 static const unsigned int *system_edp_limits;
34
35 /*
36  * Temperature step size cannot be less than 4C because of hysteresis
37  * delta
38  * Code assumes different temperatures for the same speedo_id /
39  * regulator_cur are adjacent in the table, and higest regulator_cur
40  * comes first
41  */
42 static char __initdata tegra_edp_map[] = {
43         0x00, 0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x00,
44         0x2f, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f,
45         0x3c, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x4b,
46         0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x55, 0x82,
47         0x78, 0x78, 0x78, 0x00, 0x28, 0x17, 0x7d, 0x73,
48         0x73, 0x73, 0x00, 0x28, 0x2d, 0x82, 0x78, 0x78,
49         0x78, 0x00, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78,
50         0x00, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x00,
51         0x28, 0x55, 0x82, 0x78, 0x78, 0x69, 0x00, 0x23,
52         0x17, 0x7d, 0x73, 0x73, 0x73, 0x00, 0x23, 0x2d,
53         0x82, 0x78, 0x78, 0x78, 0x00, 0x23, 0x3c, 0x82,
54         0x78, 0x78, 0x6e, 0x00, 0x23, 0x4b, 0x82, 0x78,
55         0x78, 0x64, 0x00, 0x23, 0x55, 0x82, 0x78, 0x6e,
56         0x5a, 0x00, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64,
57         0x00, 0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x00,
58         0x1e, 0x3c, 0x82, 0x78, 0x78, 0x64, 0x00, 0x1e,
59         0x4b, 0x82, 0x78, 0x6e, 0x5a, 0x00, 0x1e, 0x55,
60         0x82, 0x78, 0x64, 0x50, 0x00, 0x19, 0x17, 0x7d,
61         0x73, 0x69, 0x55, 0x00, 0x19, 0x2d, 0x82, 0x78,
62         0x6e, 0x5a, 0x00, 0x19, 0x3c, 0x82, 0x78, 0x69,
63         0x55, 0x00, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b,
64         0x00, 0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x01,
65         0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x01, 0x2f,
66         0x2d, 0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x3c,
67         0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x4b, 0x82,
68         0x78, 0x78, 0x78, 0x01, 0x2f, 0x55, 0x82, 0x78,
69         0x78, 0x78, 0x01, 0x28, 0x17, 0x7d, 0x73, 0x73,
70         0x73, 0x01, 0x28, 0x2d, 0x82, 0x78, 0x78, 0x78,
71         0x01, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x01,
72         0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x01, 0x28,
73         0x55, 0x82, 0x78, 0x78, 0x69, 0x01, 0x23, 0x17,
74         0x7d, 0x73, 0x73, 0x73, 0x01, 0x23, 0x2d, 0x82,
75         0x78, 0x78, 0x78, 0x01, 0x23, 0x3c, 0x82, 0x78,
76         0x78, 0x6e, 0x01, 0x23, 0x4b, 0x82, 0x78, 0x78,
77         0x64, 0x01, 0x23, 0x55, 0x82, 0x78, 0x6e, 0x5a,
78         0x01, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64, 0x01,
79         0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x01, 0x1e,
80         0x3c, 0x82, 0x78, 0x78, 0x64, 0x01, 0x1e, 0x4b,
81         0x82, 0x78, 0x6e, 0x5a, 0x01, 0x1e, 0x55, 0x82,
82         0x78, 0x64, 0x50, 0x01, 0x19, 0x17, 0x7d, 0x73,
83         0x69, 0x55, 0x01, 0x19, 0x2d, 0x82, 0x78, 0x6e,
84         0x5a, 0x01, 0x19, 0x3c, 0x82, 0x78, 0x69, 0x55,
85         0x01, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b, 0x01,
86         0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x02, 0x3d,
87         0x17, 0x87, 0x7d, 0x7d, 0x7d, 0x02, 0x3d, 0x2d,
88         0x8c, 0x82, 0x82, 0x82, 0x02, 0x3d, 0x3c, 0x8c,
89         0x82, 0x82, 0x82, 0x02, 0x3d, 0x4b, 0x8c, 0x82,
90         0x82, 0x82, 0x02, 0x3d, 0x55, 0x8c, 0x82, 0x82,
91         0x82, 0x02, 0x32, 0x17, 0x87, 0x7d, 0x7d, 0x7d,
92         0x02, 0x32, 0x2d, 0x8c, 0x82, 0x82, 0x82, 0x02,
93         0x32, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x02, 0x32,
94         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x02, 0x32, 0x55,
95         0x8c, 0x82, 0x82, 0x6e, 0x02, 0x28, 0x17, 0x87,
96         0x7d, 0x7d, 0x73, 0x02, 0x28, 0x2d, 0x8c, 0x82,
97         0x82, 0x78, 0x02, 0x28, 0x3c, 0x8c, 0x82, 0x82,
98         0x73, 0x02, 0x28, 0x4b, 0x8c, 0x82, 0x78, 0x69,
99         0x02, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a, 0x02,
100         0x23, 0x17, 0x87, 0x7d, 0x7d, 0x69, 0x02, 0x23,
101         0x2d, 0x8c, 0x82, 0x82, 0x6e, 0x02, 0x23, 0x3c,
102         0x8c, 0x82, 0x78, 0x69, 0x02, 0x23, 0x4b, 0x8c,
103         0x82, 0x6e, 0x5a, 0x02, 0x23, 0x55, 0x8c, 0x82,
104         0x64, 0x50, 0x03, 0x3d, 0x17, 0x87, 0x7d, 0x7d,
105         0x7d, 0x03, 0x3d, 0x2d, 0x8c, 0x82, 0x82, 0x82,
106         0x03, 0x3d, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x03,
107         0x3d, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x3d,
108         0x55, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x32, 0x17,
109         0x87, 0x7d, 0x7d, 0x7d, 0x03, 0x32, 0x2d, 0x8c,
110         0x82, 0x82, 0x82, 0x03, 0x32, 0x3c, 0x8c, 0x82,
111         0x82, 0x82, 0x03, 0x32, 0x4b, 0x8c, 0x82, 0x82,
112         0x78, 0x03, 0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e,
113         0x03, 0x28, 0x17, 0x87, 0x7d, 0x7d, 0x73, 0x03,
114         0x28, 0x2d, 0x8c, 0x82, 0x82, 0x78, 0x03, 0x28,
115         0x3c, 0x8c, 0x82, 0x82, 0x73, 0x03, 0x28, 0x4b,
116         0x8c, 0x82, 0x78, 0x69, 0x03, 0x28, 0x55, 0x8c,
117         0x82, 0x6e, 0x5a, 0x03, 0x23, 0x17, 0x87, 0x7d,
118         0x7d, 0x69, 0x03, 0x23, 0x2d, 0x8c, 0x82, 0x82,
119         0x6e, 0x03, 0x23, 0x3c, 0x8c, 0x82, 0x78, 0x69,
120         0x03, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x03,
121         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x04, 0x32,
122         0x17, 0x91, 0x87, 0x87, 0x87, 0x04, 0x32, 0x2d,
123         0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x3c, 0x96,
124         0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x46, 0x96, 0x8c,
125         0x8c, 0x8c, 0x04, 0x32, 0x4b, 0x82, 0x78, 0x78,
126         0x78, 0x04, 0x32, 0x55, 0x82, 0x78, 0x78, 0x78,
127         0x04, 0x2f, 0x17, 0x91, 0x87, 0x87, 0x87, 0x04,
128         0x2f, 0x2d, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f,
129         0x3c, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f, 0x46,
130         0x96, 0x8c, 0x8c, 0x82, 0x04, 0x2f, 0x4b, 0x82,
131         0x78, 0x78, 0x78, 0x04, 0x2f, 0x55, 0x82, 0x78,
132         0x78, 0x78, 0x04, 0x28, 0x17, 0x91, 0x87, 0x87,
133         0x87, 0x04, 0x28, 0x2d, 0x96, 0x8c, 0x8c, 0x82,
134         0x04, 0x28, 0x3c, 0x96, 0x8c, 0x8c, 0x82, 0x04,
135         0x28, 0x46, 0x96, 0x8c, 0x8c, 0x78, 0x04, 0x28,
136         0x4b, 0x82, 0x78, 0x78, 0x78, 0x04, 0x28, 0x55,
137         0x82, 0x78, 0x78, 0x6e, 0x04, 0x23, 0x17, 0x91,
138         0x87, 0x87, 0x73, 0x04, 0x23, 0x2d, 0x96, 0x8c,
139         0x8c, 0x78, 0x04, 0x23, 0x3c, 0x96, 0x8c, 0x82,
140         0x78, 0x04, 0x23, 0x46, 0x96, 0x8c, 0x82, 0x6e,
141         0x04, 0x23, 0x4b, 0x82, 0x78, 0x78, 0x6e, 0x04,
142         0x23, 0x55, 0x82, 0x78, 0x78, 0x64, 0x04, 0x1e,
143         0x17, 0x91, 0x87, 0x7d, 0x69, 0x04, 0x1e, 0x2d,
144         0x96, 0x8c, 0x82, 0x6e, 0x04, 0x1e, 0x3c, 0x96,
145         0x8c, 0x78, 0x64, 0x04, 0x1e, 0x46, 0x96, 0x8c,
146         0x78, 0x5a, 0x04, 0x1e, 0x4b, 0x82, 0x78, 0x78,
147         0x5a, 0x04, 0x1e, 0x55, 0x82, 0x78, 0x64, 0x50,
148         0x04, 0x19, 0x17, 0x91, 0x87, 0x69, 0x55, 0x04,
149         0x19, 0x2d, 0x96, 0x8c, 0x6e, 0x5a, 0x04, 0x19,
150         0x3c, 0x96, 0x82, 0x6e, 0x55, 0x04, 0x19, 0x46,
151         0x96, 0x82, 0x64, 0x50, 0x04, 0x19, 0x4b, 0x82,
152         0x78, 0x64, 0x50, 0x04, 0x19, 0x55, 0x82, 0x78,
153         0x55, 0x3c, 0x05, 0x64, 0x17, 0xa5, 0x9b, 0x9b,
154         0x9b, 0x05, 0x64, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
155         0x05, 0x64, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x05,
156         0x64, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x05, 0x64,
157         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x64, 0x55,
158         0x8c, 0x82, 0x82, 0x82, 0x05, 0x50, 0x17, 0xa5,
159         0x9b, 0x9b, 0x9b, 0x05, 0x50, 0x2d, 0xaa, 0xa0,
160         0xa0, 0xa0, 0x05, 0x50, 0x3c, 0xaa, 0xa0, 0xa0,
161         0x96, 0x05, 0x50, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
162         0x05, 0x50, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05,
163         0x50, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x3c,
164         0x17, 0xa5, 0x9b, 0x9b, 0x87, 0x05, 0x3c, 0x2d,
165         0xaa, 0xa0, 0xa0, 0x8c, 0x05, 0x3c, 0x3c, 0xaa,
166         0xa0, 0x96, 0x82, 0x05, 0x3c, 0x46, 0xaa, 0xa0,
167         0x96, 0x78, 0x05, 0x3c, 0x4b, 0x8c, 0x82, 0x82,
168         0x78, 0x05, 0x3c, 0x55, 0x8c, 0x82, 0x82, 0x6e,
169         0x05, 0x28, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x05,
170         0x28, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x05, 0x28,
171         0x3c, 0xaa, 0x96, 0x78, 0x64, 0x05, 0x28, 0x46,
172         0xaa, 0x8c, 0x6e, 0x5a, 0x05, 0x28, 0x4b, 0x8c,
173         0x82, 0x6e, 0x5a, 0x05, 0x28, 0x55, 0x8c, 0x82,
174         0x64, 0x50, 0x06, 0x3d, 0x17, 0xa5, 0x9b, 0x7d,
175         0x7d, 0x06, 0x3d, 0x2d, 0xaa, 0xa0, 0x82, 0x82,
176         0x06, 0x3d, 0x3c, 0xaa, 0xa0, 0x82, 0x82, 0x06,
177         0x3d, 0x46, 0xaa, 0xa0, 0x82, 0x82, 0x06, 0x3d,
178         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x06, 0x3d, 0x55,
179         0x8c, 0x82, 0x82, 0x82, 0x06, 0x32, 0x17, 0xa5,
180         0x9b, 0x7d, 0x7d, 0x06, 0x32, 0x2d, 0xaa, 0xa0,
181         0x82, 0x82, 0x06, 0x32, 0x3c, 0xaa, 0xa0, 0x82,
182         0x82, 0x06, 0x32, 0x46, 0xaa, 0xa0, 0x82, 0x78,
183         0x06, 0x32, 0x4b, 0x8c, 0x82, 0x82, 0x78, 0x06,
184         0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e, 0x06, 0x28,
185         0x17, 0xa5, 0x9b, 0x7d, 0x73, 0x06, 0x28, 0x2d,
186         0xaa, 0xa0, 0x82, 0x78, 0x06, 0x28, 0x3c, 0xaa,
187         0x96, 0x82, 0x73, 0x06, 0x28, 0x46, 0xaa, 0x96,
188         0x78, 0x69, 0x06, 0x28, 0x4b, 0x8c, 0x82, 0x78,
189         0x69, 0x06, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a,
190         0x06, 0x23, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x06,
191         0x23, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x06, 0x23,
192         0x3c, 0xaa, 0x96, 0x78, 0x69, 0x06, 0x23, 0x46,
193         0xaa, 0x8c, 0x6e, 0x5a, 0x06, 0x23, 0x4b, 0x8c,
194         0x82, 0x6e, 0x5a, 0x06, 0x23, 0x55, 0x8c, 0x82,
195         0x64, 0x50, 0x07, 0x3b, 0x17, 0x7d, 0x73, 0x73,
196         0x73, 0x07, 0x3b, 0x2d, 0x82, 0x78, 0x78, 0x78,
197         0x07, 0x3b, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x07,
198         0x3b, 0x4b, 0x82, 0x78, 0x78, 0x78, 0x07, 0x3b,
199         0x5a, 0x82, 0x78, 0x78, 0x78, 0x07, 0x32, 0x17,
200         0x7d, 0x73, 0x73, 0x73, 0x07, 0x32, 0x2d, 0x82,
201         0x78, 0x78, 0x78, 0x07, 0x32, 0x3c, 0x82, 0x78,
202         0x78, 0x78, 0x07, 0x32, 0x4b, 0x82, 0x78, 0x78,
203         0x78, 0x07, 0x32, 0x5a, 0x82, 0x78, 0x6e, 0x64,
204         0x07, 0x28, 0x17, 0x7d, 0x73, 0x73, 0x69, 0x07,
205         0x28, 0x2d, 0x82, 0x78, 0x78, 0x6e, 0x07, 0x28,
206         0x3c, 0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x4b,
207         0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x5a, 0x82,
208         0x78, 0x64, 0x50, 0x07, 0x23, 0x17, 0x7d, 0x73,
209         0x73, 0x5f, 0x07, 0x23, 0x2d, 0x82, 0x78, 0x78,
210         0x64, 0x07, 0x23, 0x3c, 0x82, 0x78, 0x78, 0x64,
211         0x07, 0x23, 0x4b, 0x82, 0x78, 0x64, 0x50, 0x07,
212         0x23, 0x5a, 0x82, 0x78, 0x5a, 0x46, 0x08, 0x3b,
213         0x17, 0x7d, 0x73, 0x73, 0x73, 0x08, 0x3b, 0x2d,
214         0x82, 0x78, 0x78, 0x78, 0x08, 0x3b, 0x3c, 0x82,
215         0x78, 0x78, 0x78, 0x08, 0x3b, 0x4b, 0x82, 0x78,
216         0x78, 0x78, 0x08, 0x3b, 0x5a, 0x82, 0x78, 0x78,
217         0x78, 0x08, 0x32, 0x17, 0x7d, 0x73, 0x73, 0x73,
218         0x08, 0x32, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x08,
219         0x32, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32,
220         0x4b, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32, 0x5a,
221         0x82, 0x78, 0x6e, 0x64, 0x08, 0x28, 0x17, 0x7d,
222         0x73, 0x73, 0x69, 0x08, 0x28, 0x2d, 0x82, 0x78,
223         0x78, 0x6e, 0x08, 0x28, 0x3c, 0x82, 0x78, 0x78,
224         0x64, 0x08, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x64,
225         0x08, 0x28, 0x5a, 0x82, 0x78, 0x64, 0x50, 0x08,
226         0x23, 0x17, 0x7d, 0x73, 0x73, 0x5f, 0x08, 0x23,
227         0x2d, 0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x3c,
228         0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x4b, 0x82,
229         0x78, 0x64, 0x50, 0x08, 0x23, 0x5a, 0x82, 0x78,
230         0x5a, 0x46,
231 };
232
233
234 static struct system_edp_entry __initdata tegra_system_edp_map[] = {
235
236 /* {SKU, power-limit (in 100mW), {freq limits (in 10Mhz)} } */
237
238         {  1,  49, {130, 120, 120, 120} },
239         {  1,  44, {130, 120, 120, 110} },
240         {  1,  37, {130, 120, 110, 100} },
241         {  1,  35, {130, 120, 110,  90} },
242         {  1,  29, {130, 120, 100,  80} },
243         {  1,  27, {130, 120,  90,  80} },
244         {  1,  25, {130, 110,  80,  60} },
245         {  1,  21, {130, 100,  80,  40} },
246 };
247
248 /*
249  * "Safe entry" to be used when no match for speedo_id /
250  * regulator_cur is found; must be the last one
251  */
252 static struct tegra_edp_limits edp_default_limits[] = {
253         {85, {1000000, 1000000, 1000000, 1000000} },
254 };
255
256
257
258 /*
259  * Specify regulator current in mA, e.g. 5000mA
260  * Use 0 for default
261  */
262 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
263 {
264         int cpu_speedo_id = tegra_cpu_speedo_id;
265         int i, j;
266         struct tegra_edp_limits *e;
267         struct tegra_edp_entry *t = (struct tegra_edp_entry *)tegra_edp_map;
268         int tsize = sizeof(tegra_edp_map)/sizeof(struct tegra_edp_entry);
269
270         if (!regulator_mA) {
271                 edp_limits = edp_default_limits;
272                 edp_limits_size = ARRAY_SIZE(edp_default_limits);
273                 return;
274         }
275         regulator_cur = regulator_mA;
276
277         for (i = 0; i < tsize; i++) {
278                 if (t[i].speedo_id == cpu_speedo_id &&
279                     t[i].regulator_100mA <= regulator_mA / 100)
280                         break;
281         }
282
283         /* No entry found in tegra_edp_map */
284         if (i >= tsize) {
285                 edp_limits = edp_default_limits;
286                 edp_limits_size = ARRAY_SIZE(edp_default_limits);
287                 return;
288         }
289
290         /* Find all rows for this entry */
291         for (j = i + 1; j < tsize; j++) {
292                 if (t[i].speedo_id != t[j].speedo_id ||
293                     t[i].regulator_100mA != t[j].regulator_100mA)
294                         break;
295         }
296
297         edp_limits_size = j - i;
298         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
299                     GFP_KERNEL);
300         BUG_ON(!e);
301
302         for (j = 0; j < edp_limits_size; j++) {
303                 e[j].temperature = (int)t[i+j].temperature;
304                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0] * 10000;
305                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1] * 10000;
306                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2] * 10000;
307                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3] * 10000;
308         }
309
310         if (edp_limits != edp_default_limits)
311                 kfree(edp_limits);
312
313         edp_limits = e;
314 }
315
316
317 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
318 {
319         int cpu_speedo_id = tegra_cpu_speedo_id;
320         int i;
321         unsigned int *e;
322         struct system_edp_entry *t =
323                 (struct system_edp_entry *)tegra_system_edp_map;
324         int tsize = sizeof(tegra_system_edp_map) /
325                 sizeof(struct system_edp_entry);
326
327         if (!power_limit_mW) {
328                 e = NULL;
329                 goto out;
330         }
331
332         for (i = 0; i < tsize; i++)
333                 if (t[i].speedo_id == cpu_speedo_id)
334                         break;
335
336         if (i >= tsize) {
337                 e = NULL;
338                 goto out;
339         }
340
341         do {
342                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
343                         break;
344                 i++;
345         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
346
347         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
348                 i--; /* No low enough entry in the table, use best possible */
349
350         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
351         BUG_ON(!e);
352
353         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
354         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
355         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
356         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
357
358 out:
359         kfree(system_edp_limits);
360
361         system_edp_limits = e;
362 }
363
364
365 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
366 {
367         *limits = edp_limits;
368         *size = edp_limits_size;
369 }
370
371 void tegra_get_system_edp_limits(const unsigned int **limits)
372 {
373         *limits = system_edp_limits;
374 }
375
376 #ifdef CONFIG_DEBUG_FS
377
378 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
379 {
380         seq_printf(s, "%u\n", tegra_get_edp_limit());
381         return 0;
382 }
383
384 static int edp_debugfs_show(struct seq_file *s, void *data)
385 {
386         int i;
387
388         seq_printf(s, "-- CPU %sEDP table (%umA) --\n",
389                    edp_limits == edp_default_limits ? "default " : "",
390                    regulator_cur);
391         for (i = 0; i < edp_limits_size; i++) {
392                 seq_printf(s, "%4dC: %10u %10u %10u %10u\n",
393                            edp_limits[i].temperature,
394                            edp_limits[i].freq_limits[0],
395                            edp_limits[i].freq_limits[1],
396                            edp_limits[i].freq_limits[2],
397                            edp_limits[i].freq_limits[3]);
398         }
399
400         if (system_edp_limits) {
401                 seq_printf(s, "\n-- System EDP table --\n");
402                 seq_printf(s, "%10u %10u %10u %10u\n",
403                            system_edp_limits[0],
404                            system_edp_limits[1],
405                            system_edp_limits[2],
406                            system_edp_limits[3]);
407         }
408
409         return 0;
410 }
411
412
413 static int edp_debugfs_open(struct inode *inode, struct file *file)
414 {
415         return single_open(file, edp_debugfs_show, inode->i_private);
416 }
417
418 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
419 {
420         return single_open(file, edp_limit_debugfs_show, inode->i_private);
421 }
422
423
424 static const struct file_operations edp_debugfs_fops = {
425         .open           = edp_debugfs_open,
426         .read           = seq_read,
427         .llseek         = seq_lseek,
428         .release        = single_release,
429 };
430
431 static const struct file_operations edp_limit_debugfs_fops = {
432         .open           = edp_limit_debugfs_open,
433         .read           = seq_read,
434         .llseek         = seq_lseek,
435         .release        = single_release,
436 };
437
438 static int __init tegra_edp_debugfs_init(void)
439 {
440         struct dentry *d;
441
442         d = debugfs_create_file("edp", S_IRUGO, NULL, NULL,
443                                 &edp_debugfs_fops);
444         if (!d)
445                 return -ENOMEM;
446
447         d = debugfs_create_file("edp_limit", S_IRUGO, NULL, NULL,
448                                 &edp_limit_debugfs_fops);
449
450         return 0;
451 }
452
453 late_initcall(tegra_edp_debugfs_init);
454 #endif /* CONFIG_DEBUG_FS */