52fb6785c9fd8b978787b3568b0beeac5876e2d2
[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, 0x0c, 0x52, 0x17, 0xa5, 0x9b, 0x9b,
231         0x9b, 0x0c, 0x52, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
232         0x0c, 0x52, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c,
233         0x52, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c, 0x52,
234         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x52, 0x55,
235         0x8c, 0x82, 0x82, 0x82, 0x0c, 0x42, 0x17, 0xa5,
236         0x9b, 0x9b, 0x91, 0x0c, 0x42, 0x2d, 0xaa, 0xa0,
237         0xa0, 0x96, 0x0c, 0x42, 0x3c, 0xaa, 0xa0, 0xa0,
238         0x96, 0x0c, 0x42, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
239         0x0c, 0x42, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c,
240         0x42, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x3d,
241         0x17, 0xa5, 0x9b, 0x9b, 0x91, 0x0c, 0x3d, 0x2d,
242         0xaa, 0xa0, 0xa0, 0x96, 0x0c, 0x3d, 0x3c, 0xaa,
243         0xa0, 0xa0, 0x8c, 0x0c, 0x3d, 0x46, 0xaa, 0xa0,
244         0x96, 0x8c, 0x0c, 0x3d, 0x4b, 0x8c, 0x82, 0x82,
245         0x82, 0x0c, 0x3d, 0x55, 0x8c, 0x82, 0x82, 0x82,
246         0x0c, 0x32, 0x17, 0xa5, 0x9b, 0x91, 0x87, 0x0c,
247         0x32, 0x2d, 0xaa, 0xa0, 0x96, 0x8c, 0x0c, 0x32,
248         0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0c, 0x32, 0x46,
249         0xaa, 0xa0, 0x8c, 0x78, 0x0c, 0x32, 0x4b, 0x8c,
250         0x82, 0x82, 0x78, 0x0c, 0x32, 0x55, 0x8c, 0x82,
251         0x82, 0x6e, 0x0c, 0x28, 0x17, 0xa5, 0x9b, 0x87,
252         0x73, 0x0c, 0x28, 0x2d, 0xaa, 0xa0, 0x8c, 0x78,
253         0x0c, 0x28, 0x3c, 0xaa, 0x96, 0x82, 0x73, 0x0c,
254         0x28, 0x46, 0xaa, 0x96, 0x78, 0x69, 0x0c, 0x28,
255         0x4b, 0x8c, 0x82, 0x78, 0x69, 0x0c, 0x28, 0x55,
256         0x8c, 0x82, 0x6e, 0x5a, 0x0c, 0x23, 0x17, 0xa5,
257         0x91, 0x7d, 0x69, 0x0c, 0x23, 0x2d, 0xaa, 0x96,
258         0x82, 0x6e, 0x0c, 0x23, 0x3c, 0xaa, 0x96, 0x78,
259         0x69, 0x0c, 0x23, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
260         0x0c, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0c,
261         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x0d, 0x64,
262         0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d, 0x64, 0x2d,
263         0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x3c, 0xaa,
264         0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x46, 0xaa, 0xa0,
265         0xa0, 0xa0, 0x0d, 0x64, 0x4b, 0x8c, 0x82, 0x82,
266         0x82, 0x0d, 0x64, 0x55, 0x8c, 0x82, 0x82, 0x82,
267         0x0d, 0x50, 0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d,
268         0x50, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x50,
269         0x3c, 0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x46,
270         0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x4b, 0x8c,
271         0x82, 0x82, 0x82, 0x0d, 0x50, 0x55, 0x8c, 0x82,
272         0x82, 0x82, 0x0d, 0x3c, 0x17, 0xa5, 0x9b, 0x9b,
273         0x87, 0x0d, 0x3c, 0x2d, 0xaa, 0xa0, 0xa0, 0x8c,
274         0x0d, 0x3c, 0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0d,
275         0x3c, 0x46, 0xaa, 0xa0, 0x96, 0x78, 0x0d, 0x3c,
276         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x0d, 0x3c, 0x55,
277         0x8c, 0x82, 0x82, 0x6e, 0x0d, 0x28, 0x17, 0xa5,
278         0x91, 0x7d, 0x69, 0x0d, 0x28, 0x2d, 0xaa, 0x96,
279         0x82, 0x6e, 0x0d, 0x28, 0x3c, 0xaa, 0x96, 0x78,
280         0x64, 0x0d, 0x28, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
281         0x0d, 0x28, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0d,
282         0x28, 0x55, 0x8c, 0x82, 0x64, 0x50,
283 };
284
285
286 static struct system_edp_entry __initdata tegra_system_edp_map[] = {
287
288 /* {SKU, power-limit (in 100mW), {freq limits (in 10Mhz)} } */
289
290         {  1,  49, {130, 120, 120, 120} },
291         {  1,  44, {130, 120, 120, 110} },
292         {  1,  37, {130, 120, 110, 100} },
293         {  1,  35, {130, 120, 110,  90} },
294         {  1,  29, {130, 120, 100,  80} },
295         {  1,  27, {130, 120,  90,  80} },
296         {  1,  25, {130, 110,  80,  60} },
297         {  1,  21, {130, 100,  80,  40} },
298
299         {  4,  49, {130, 120, 120, 120} },
300         {  4,  44, {130, 120, 120, 110} },
301         {  4,  37, {130, 120, 110, 100} },
302         {  4,  35, {130, 120, 110,  90} },
303         {  4,  29, {130, 120, 100,  80} },
304         {  4,  27, {130, 120,  90,  80} },
305         {  4,  25, {130, 110,  80,  60} },
306         {  4,  21, {130, 100,  80,  40} },
307 };
308
309 /*
310  * "Safe entry" to be used when no match for speedo_id /
311  * regulator_cur is found; must be the last one
312  */
313 static struct tegra_edp_limits edp_default_limits[] = {
314         {85, {1000000, 1000000, 1000000, 1000000} },
315 };
316
317
318
319 /*
320  * Specify regulator current in mA, e.g. 5000mA
321  * Use 0 for default
322  */
323 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
324 {
325         int cpu_speedo_id = tegra_cpu_speedo_id;
326         int i, j;
327         struct tegra_edp_limits *e;
328         struct tegra_edp_entry *t = (struct tegra_edp_entry *)tegra_edp_map;
329         int tsize = sizeof(tegra_edp_map)/sizeof(struct tegra_edp_entry);
330
331         if (!regulator_mA) {
332                 edp_limits = edp_default_limits;
333                 edp_limits_size = ARRAY_SIZE(edp_default_limits);
334                 return;
335         }
336         regulator_cur = regulator_mA;
337
338         for (i = 0; i < tsize; i++) {
339                 if (t[i].speedo_id == cpu_speedo_id &&
340                     t[i].regulator_100mA <= regulator_mA / 100)
341                         break;
342         }
343
344         /* No entry found in tegra_edp_map */
345         if (i >= tsize) {
346                 edp_limits = edp_default_limits;
347                 edp_limits_size = ARRAY_SIZE(edp_default_limits);
348                 return;
349         }
350
351         /* Find all rows for this entry */
352         for (j = i + 1; j < tsize; j++) {
353                 if (t[i].speedo_id != t[j].speedo_id ||
354                     t[i].regulator_100mA != t[j].regulator_100mA)
355                         break;
356         }
357
358         edp_limits_size = j - i;
359         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
360                     GFP_KERNEL);
361         BUG_ON(!e);
362
363         for (j = 0; j < edp_limits_size; j++) {
364                 e[j].temperature = (int)t[i+j].temperature;
365                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0] * 10000;
366                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1] * 10000;
367                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2] * 10000;
368                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3] * 10000;
369         }
370
371         if (edp_limits != edp_default_limits)
372                 kfree(edp_limits);
373
374         edp_limits = e;
375 }
376
377
378 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
379 {
380         int cpu_speedo_id = tegra_cpu_speedo_id;
381         int i;
382         unsigned int *e;
383         struct system_edp_entry *t =
384                 (struct system_edp_entry *)tegra_system_edp_map;
385         int tsize = sizeof(tegra_system_edp_map) /
386                 sizeof(struct system_edp_entry);
387
388         if (!power_limit_mW) {
389                 e = NULL;
390                 goto out;
391         }
392
393         for (i = 0; i < tsize; i++)
394                 if (t[i].speedo_id == cpu_speedo_id)
395                         break;
396
397         if (i >= tsize) {
398                 e = NULL;
399                 goto out;
400         }
401
402         do {
403                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
404                         break;
405                 i++;
406         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
407
408         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
409                 i--; /* No low enough entry in the table, use best possible */
410
411         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
412         BUG_ON(!e);
413
414         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
415         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
416         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
417         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
418
419 out:
420         kfree(system_edp_limits);
421
422         system_edp_limits = e;
423 }
424
425
426 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
427 {
428         *limits = edp_limits;
429         *size = edp_limits_size;
430 }
431
432 void tegra_get_system_edp_limits(const unsigned int **limits)
433 {
434         *limits = system_edp_limits;
435 }
436
437 #ifdef CONFIG_DEBUG_FS
438
439 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
440 {
441         seq_printf(s, "%u\n", tegra_get_edp_limit());
442         return 0;
443 }
444
445 static int edp_debugfs_show(struct seq_file *s, void *data)
446 {
447         int i;
448
449         seq_printf(s, "-- CPU %sEDP table (%umA) --\n",
450                    edp_limits == edp_default_limits ? "default " : "",
451                    regulator_cur);
452         for (i = 0; i < edp_limits_size; i++) {
453                 seq_printf(s, "%4dC: %10u %10u %10u %10u\n",
454                            edp_limits[i].temperature,
455                            edp_limits[i].freq_limits[0],
456                            edp_limits[i].freq_limits[1],
457                            edp_limits[i].freq_limits[2],
458                            edp_limits[i].freq_limits[3]);
459         }
460
461         if (system_edp_limits) {
462                 seq_printf(s, "\n-- System EDP table --\n");
463                 seq_printf(s, "%10u %10u %10u %10u\n",
464                            system_edp_limits[0],
465                            system_edp_limits[1],
466                            system_edp_limits[2],
467                            system_edp_limits[3]);
468         }
469
470         return 0;
471 }
472
473
474 static int edp_debugfs_open(struct inode *inode, struct file *file)
475 {
476         return single_open(file, edp_debugfs_show, inode->i_private);
477 }
478
479 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
480 {
481         return single_open(file, edp_limit_debugfs_show, inode->i_private);
482 }
483
484
485 static const struct file_operations edp_debugfs_fops = {
486         .open           = edp_debugfs_open,
487         .read           = seq_read,
488         .llseek         = seq_lseek,
489         .release        = single_release,
490 };
491
492 static const struct file_operations edp_limit_debugfs_fops = {
493         .open           = edp_limit_debugfs_open,
494         .read           = seq_read,
495         .llseek         = seq_lseek,
496         .release        = single_release,
497 };
498
499 static int __init tegra_edp_debugfs_init(void)
500 {
501         struct dentry *d;
502
503         d = debugfs_create_file("edp", S_IRUGO, NULL, NULL,
504                                 &edp_debugfs_fops);
505         if (!d)
506                 return -ENOMEM;
507
508         d = debugfs_create_file("edp_limit", S_IRUGO, NULL, NULL,
509                                 &edp_limit_debugfs_fops);
510
511         return 0;
512 }
513
514 late_initcall(tegra_edp_debugfs_init);
515 #endif /* CONFIG_DEBUG_FS */