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