arm: tegra: power: Add debugfs entry for CPU regulator limit
[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 <linux/module.h>
26 #include <linux/uaccess.h>
27 #include <mach/edp.h>
28
29 #include "fuse.h"
30 #include "dvfs.h"
31 #include "clock.h"
32 #include "cpu-tegra.h"
33
34 #define FREQ_STEP 10000000
35 #define A_TEMP_LUT_MAX 7
36 #define A_VOLTAGE_LUT_MAX 49
37
38 static struct tegra_edp_limits *edp_limits;
39 static int edp_limits_size;
40 static unsigned int regulator_cur;
41 /* Value to subtract from regulator current limit */
42 static unsigned int edp_reg_override_mA = 0;
43
44 static const unsigned int *system_edp_limits;
45
46 /*
47  * Temperature step size cannot be less than 4C because of hysteresis
48  * delta
49  * Code assumes different temperatures for the same speedo_id /
50  * regulator_cur are adjacent in the table, and higest regulator_cur
51  * comes first
52  */
53 static char __initdata tegra_edp_map[] = {
54         0x00, 0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x00,
55         0x2f, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f,
56         0x3c, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x4b,
57         0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x55, 0x82,
58         0x78, 0x78, 0x78, 0x00, 0x28, 0x17, 0x7d, 0x73,
59         0x73, 0x73, 0x00, 0x28, 0x2d, 0x82, 0x78, 0x78,
60         0x78, 0x00, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78,
61         0x00, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x00,
62         0x28, 0x55, 0x82, 0x78, 0x78, 0x69, 0x00, 0x23,
63         0x17, 0x7d, 0x73, 0x73, 0x73, 0x00, 0x23, 0x2d,
64         0x82, 0x78, 0x78, 0x78, 0x00, 0x23, 0x3c, 0x82,
65         0x78, 0x78, 0x6e, 0x00, 0x23, 0x4b, 0x82, 0x78,
66         0x78, 0x64, 0x00, 0x23, 0x55, 0x82, 0x78, 0x6e,
67         0x5a, 0x00, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64,
68         0x00, 0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x00,
69         0x1e, 0x3c, 0x82, 0x78, 0x78, 0x64, 0x00, 0x1e,
70         0x4b, 0x82, 0x78, 0x6e, 0x5a, 0x00, 0x1e, 0x55,
71         0x82, 0x78, 0x64, 0x50, 0x00, 0x19, 0x17, 0x7d,
72         0x73, 0x69, 0x55, 0x00, 0x19, 0x2d, 0x82, 0x78,
73         0x6e, 0x5a, 0x00, 0x19, 0x3c, 0x82, 0x78, 0x69,
74         0x55, 0x00, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b,
75         0x00, 0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x01,
76         0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x01, 0x2f,
77         0x2d, 0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x3c,
78         0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x4b, 0x82,
79         0x78, 0x78, 0x78, 0x01, 0x2f, 0x55, 0x82, 0x78,
80         0x78, 0x78, 0x01, 0x28, 0x17, 0x7d, 0x73, 0x73,
81         0x73, 0x01, 0x28, 0x2d, 0x82, 0x78, 0x78, 0x78,
82         0x01, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x01,
83         0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x01, 0x28,
84         0x55, 0x82, 0x78, 0x78, 0x69, 0x01, 0x23, 0x17,
85         0x7d, 0x73, 0x73, 0x73, 0x01, 0x23, 0x2d, 0x82,
86         0x78, 0x78, 0x78, 0x01, 0x23, 0x3c, 0x82, 0x78,
87         0x78, 0x6e, 0x01, 0x23, 0x4b, 0x82, 0x78, 0x78,
88         0x64, 0x01, 0x23, 0x55, 0x82, 0x78, 0x6e, 0x5a,
89         0x01, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64, 0x01,
90         0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x01, 0x1e,
91         0x3c, 0x82, 0x78, 0x78, 0x64, 0x01, 0x1e, 0x4b,
92         0x82, 0x78, 0x6e, 0x5a, 0x01, 0x1e, 0x55, 0x82,
93         0x78, 0x64, 0x50, 0x01, 0x19, 0x17, 0x7d, 0x73,
94         0x69, 0x55, 0x01, 0x19, 0x2d, 0x82, 0x78, 0x6e,
95         0x5a, 0x01, 0x19, 0x3c, 0x82, 0x78, 0x69, 0x55,
96         0x01, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b, 0x01,
97         0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x02, 0x3d,
98         0x17, 0x87, 0x7d, 0x7d, 0x7d, 0x02, 0x3d, 0x2d,
99         0x8c, 0x82, 0x82, 0x82, 0x02, 0x3d, 0x3c, 0x8c,
100         0x82, 0x82, 0x82, 0x02, 0x3d, 0x4b, 0x8c, 0x82,
101         0x82, 0x82, 0x02, 0x3d, 0x55, 0x8c, 0x82, 0x82,
102         0x82, 0x02, 0x32, 0x17, 0x87, 0x7d, 0x7d, 0x7d,
103         0x02, 0x32, 0x2d, 0x8c, 0x82, 0x82, 0x82, 0x02,
104         0x32, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x02, 0x32,
105         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x02, 0x32, 0x55,
106         0x8c, 0x82, 0x82, 0x6e, 0x02, 0x28, 0x17, 0x87,
107         0x7d, 0x7d, 0x73, 0x02, 0x28, 0x2d, 0x8c, 0x82,
108         0x82, 0x78, 0x02, 0x28, 0x3c, 0x8c, 0x82, 0x82,
109         0x73, 0x02, 0x28, 0x4b, 0x8c, 0x82, 0x78, 0x69,
110         0x02, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a, 0x02,
111         0x23, 0x17, 0x87, 0x7d, 0x7d, 0x69, 0x02, 0x23,
112         0x2d, 0x8c, 0x82, 0x82, 0x6e, 0x02, 0x23, 0x3c,
113         0x8c, 0x82, 0x78, 0x69, 0x02, 0x23, 0x4b, 0x8c,
114         0x82, 0x6e, 0x5a, 0x02, 0x23, 0x55, 0x8c, 0x82,
115         0x64, 0x50, 0x03, 0x3d, 0x17, 0x87, 0x7d, 0x7d,
116         0x7d, 0x03, 0x3d, 0x2d, 0x8c, 0x82, 0x82, 0x82,
117         0x03, 0x3d, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x03,
118         0x3d, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x3d,
119         0x55, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x32, 0x17,
120         0x87, 0x7d, 0x7d, 0x7d, 0x03, 0x32, 0x2d, 0x8c,
121         0x82, 0x82, 0x82, 0x03, 0x32, 0x3c, 0x8c, 0x82,
122         0x82, 0x82, 0x03, 0x32, 0x4b, 0x8c, 0x82, 0x82,
123         0x78, 0x03, 0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e,
124         0x03, 0x28, 0x17, 0x87, 0x7d, 0x7d, 0x73, 0x03,
125         0x28, 0x2d, 0x8c, 0x82, 0x82, 0x78, 0x03, 0x28,
126         0x3c, 0x8c, 0x82, 0x82, 0x73, 0x03, 0x28, 0x4b,
127         0x8c, 0x82, 0x78, 0x69, 0x03, 0x28, 0x55, 0x8c,
128         0x82, 0x6e, 0x5a, 0x03, 0x23, 0x17, 0x87, 0x7d,
129         0x7d, 0x69, 0x03, 0x23, 0x2d, 0x8c, 0x82, 0x82,
130         0x6e, 0x03, 0x23, 0x3c, 0x8c, 0x82, 0x78, 0x69,
131         0x03, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x03,
132         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x04, 0x32,
133         0x17, 0x91, 0x87, 0x87, 0x87, 0x04, 0x32, 0x2d,
134         0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x3c, 0x96,
135         0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x46, 0x96, 0x8c,
136         0x8c, 0x8c, 0x04, 0x32, 0x4b, 0x82, 0x78, 0x78,
137         0x78, 0x04, 0x32, 0x55, 0x82, 0x78, 0x78, 0x78,
138         0x04, 0x2f, 0x17, 0x91, 0x87, 0x87, 0x87, 0x04,
139         0x2f, 0x2d, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f,
140         0x3c, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f, 0x46,
141         0x96, 0x8c, 0x8c, 0x82, 0x04, 0x2f, 0x4b, 0x82,
142         0x78, 0x78, 0x78, 0x04, 0x2f, 0x55, 0x82, 0x78,
143         0x78, 0x78, 0x04, 0x28, 0x17, 0x91, 0x87, 0x87,
144         0x87, 0x04, 0x28, 0x2d, 0x96, 0x8c, 0x8c, 0x82,
145         0x04, 0x28, 0x3c, 0x96, 0x8c, 0x8c, 0x82, 0x04,
146         0x28, 0x46, 0x96, 0x8c, 0x8c, 0x78, 0x04, 0x28,
147         0x4b, 0x82, 0x78, 0x78, 0x78, 0x04, 0x28, 0x55,
148         0x82, 0x78, 0x78, 0x6e, 0x04, 0x23, 0x17, 0x91,
149         0x87, 0x87, 0x73, 0x04, 0x23, 0x2d, 0x96, 0x8c,
150         0x8c, 0x78, 0x04, 0x23, 0x3c, 0x96, 0x8c, 0x82,
151         0x78, 0x04, 0x23, 0x46, 0x96, 0x8c, 0x82, 0x6e,
152         0x04, 0x23, 0x4b, 0x82, 0x78, 0x78, 0x6e, 0x04,
153         0x23, 0x55, 0x82, 0x78, 0x78, 0x64, 0x04, 0x1e,
154         0x17, 0x91, 0x87, 0x7d, 0x69, 0x04, 0x1e, 0x2d,
155         0x96, 0x8c, 0x82, 0x6e, 0x04, 0x1e, 0x3c, 0x96,
156         0x8c, 0x78, 0x64, 0x04, 0x1e, 0x46, 0x96, 0x8c,
157         0x78, 0x5a, 0x04, 0x1e, 0x4b, 0x82, 0x78, 0x78,
158         0x5a, 0x04, 0x1e, 0x55, 0x82, 0x78, 0x64, 0x50,
159         0x04, 0x19, 0x17, 0x91, 0x87, 0x69, 0x55, 0x04,
160         0x19, 0x2d, 0x96, 0x8c, 0x6e, 0x5a, 0x04, 0x19,
161         0x3c, 0x96, 0x82, 0x6e, 0x55, 0x04, 0x19, 0x46,
162         0x96, 0x82, 0x64, 0x50, 0x04, 0x19, 0x4b, 0x82,
163         0x78, 0x64, 0x50, 0x04, 0x19, 0x55, 0x82, 0x78,
164         0x55, 0x3c, 0x05, 0x64, 0x17, 0xa5, 0x9b, 0x9b,
165         0x9b, 0x05, 0x64, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
166         0x05, 0x64, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x05,
167         0x64, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x05, 0x64,
168         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x64, 0x55,
169         0x8c, 0x82, 0x82, 0x82, 0x05, 0x50, 0x17, 0xa5,
170         0x9b, 0x9b, 0x9b, 0x05, 0x50, 0x2d, 0xaa, 0xa0,
171         0xa0, 0xa0, 0x05, 0x50, 0x3c, 0xaa, 0xa0, 0xa0,
172         0x96, 0x05, 0x50, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
173         0x05, 0x50, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05,
174         0x50, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x3c,
175         0x17, 0xa5, 0x9b, 0x9b, 0x87, 0x05, 0x3c, 0x2d,
176         0xaa, 0xa0, 0xa0, 0x8c, 0x05, 0x3c, 0x3c, 0xaa,
177         0xa0, 0x96, 0x82, 0x05, 0x3c, 0x46, 0xaa, 0xa0,
178         0x96, 0x78, 0x05, 0x3c, 0x4b, 0x8c, 0x82, 0x82,
179         0x78, 0x05, 0x3c, 0x55, 0x8c, 0x82, 0x82, 0x6e,
180         0x05, 0x28, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x05,
181         0x28, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x05, 0x28,
182         0x3c, 0xaa, 0x96, 0x78, 0x64, 0x05, 0x28, 0x46,
183         0xaa, 0x8c, 0x6e, 0x5a, 0x05, 0x28, 0x4b, 0x8c,
184         0x82, 0x6e, 0x5a, 0x05, 0x28, 0x55, 0x8c, 0x82,
185         0x64, 0x50, 0x06, 0x3d, 0x17, 0xa5, 0x9b, 0x7d,
186         0x7d, 0x06, 0x3d, 0x2d, 0xaa, 0xa0, 0x82, 0x82,
187         0x06, 0x3d, 0x3c, 0xaa, 0xa0, 0x82, 0x82, 0x06,
188         0x3d, 0x46, 0xaa, 0xa0, 0x82, 0x82, 0x06, 0x3d,
189         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x06, 0x3d, 0x55,
190         0x8c, 0x82, 0x82, 0x82, 0x06, 0x32, 0x17, 0xa5,
191         0x9b, 0x7d, 0x7d, 0x06, 0x32, 0x2d, 0xaa, 0xa0,
192         0x82, 0x82, 0x06, 0x32, 0x3c, 0xaa, 0xa0, 0x82,
193         0x82, 0x06, 0x32, 0x46, 0xaa, 0xa0, 0x82, 0x78,
194         0x06, 0x32, 0x4b, 0x8c, 0x82, 0x82, 0x78, 0x06,
195         0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e, 0x06, 0x28,
196         0x17, 0xa5, 0x9b, 0x7d, 0x73, 0x06, 0x28, 0x2d,
197         0xaa, 0xa0, 0x82, 0x78, 0x06, 0x28, 0x3c, 0xaa,
198         0x96, 0x82, 0x73, 0x06, 0x28, 0x46, 0xaa, 0x96,
199         0x78, 0x69, 0x06, 0x28, 0x4b, 0x8c, 0x82, 0x78,
200         0x69, 0x06, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a,
201         0x06, 0x23, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x06,
202         0x23, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x06, 0x23,
203         0x3c, 0xaa, 0x96, 0x78, 0x69, 0x06, 0x23, 0x46,
204         0xaa, 0x8c, 0x6e, 0x5a, 0x06, 0x23, 0x4b, 0x8c,
205         0x82, 0x6e, 0x5a, 0x06, 0x23, 0x55, 0x8c, 0x82,
206         0x64, 0x50, 0x07, 0x3b, 0x17, 0x7d, 0x73, 0x73,
207         0x73, 0x07, 0x3b, 0x2d, 0x82, 0x78, 0x78, 0x78,
208         0x07, 0x3b, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x07,
209         0x3b, 0x4b, 0x82, 0x78, 0x78, 0x78, 0x07, 0x3b,
210         0x5a, 0x82, 0x78, 0x78, 0x78, 0x07, 0x32, 0x17,
211         0x7d, 0x73, 0x73, 0x73, 0x07, 0x32, 0x2d, 0x82,
212         0x78, 0x78, 0x78, 0x07, 0x32, 0x3c, 0x82, 0x78,
213         0x78, 0x78, 0x07, 0x32, 0x4b, 0x82, 0x78, 0x78,
214         0x78, 0x07, 0x32, 0x5a, 0x82, 0x78, 0x6e, 0x64,
215         0x07, 0x28, 0x17, 0x7d, 0x73, 0x73, 0x69, 0x07,
216         0x28, 0x2d, 0x82, 0x78, 0x78, 0x6e, 0x07, 0x28,
217         0x3c, 0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x4b,
218         0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x5a, 0x82,
219         0x78, 0x64, 0x50, 0x07, 0x23, 0x17, 0x7d, 0x73,
220         0x73, 0x5f, 0x07, 0x23, 0x2d, 0x82, 0x78, 0x78,
221         0x64, 0x07, 0x23, 0x3c, 0x82, 0x78, 0x78, 0x64,
222         0x07, 0x23, 0x4b, 0x82, 0x78, 0x64, 0x50, 0x07,
223         0x23, 0x5a, 0x82, 0x78, 0x5a, 0x46, 0x08, 0x3b,
224         0x17, 0x7d, 0x73, 0x73, 0x73, 0x08, 0x3b, 0x2d,
225         0x82, 0x78, 0x78, 0x78, 0x08, 0x3b, 0x3c, 0x82,
226         0x78, 0x78, 0x78, 0x08, 0x3b, 0x4b, 0x82, 0x78,
227         0x78, 0x78, 0x08, 0x3b, 0x5a, 0x82, 0x78, 0x78,
228         0x78, 0x08, 0x32, 0x17, 0x7d, 0x73, 0x73, 0x73,
229         0x08, 0x32, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x08,
230         0x32, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32,
231         0x4b, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32, 0x5a,
232         0x82, 0x78, 0x6e, 0x64, 0x08, 0x28, 0x17, 0x7d,
233         0x73, 0x73, 0x69, 0x08, 0x28, 0x2d, 0x82, 0x78,
234         0x78, 0x6e, 0x08, 0x28, 0x3c, 0x82, 0x78, 0x78,
235         0x64, 0x08, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x64,
236         0x08, 0x28, 0x5a, 0x82, 0x78, 0x64, 0x50, 0x08,
237         0x23, 0x17, 0x7d, 0x73, 0x73, 0x5f, 0x08, 0x23,
238         0x2d, 0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x3c,
239         0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x4b, 0x82,
240         0x78, 0x64, 0x50, 0x08, 0x23, 0x5a, 0x82, 0x78,
241         0x5a, 0x46, 0x0c, 0x52, 0x17, 0xa5, 0x9b, 0x9b,
242         0x9b, 0x0c, 0x52, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
243         0x0c, 0x52, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c,
244         0x52, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c, 0x52,
245         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x52, 0x55,
246         0x8c, 0x82, 0x82, 0x82, 0x0c, 0x42, 0x17, 0xa5,
247         0x9b, 0x9b, 0x91, 0x0c, 0x42, 0x2d, 0xaa, 0xa0,
248         0xa0, 0x96, 0x0c, 0x42, 0x3c, 0xaa, 0xa0, 0xa0,
249         0x96, 0x0c, 0x42, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
250         0x0c, 0x42, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c,
251         0x42, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x3d,
252         0x17, 0xa5, 0x9b, 0x9b, 0x91, 0x0c, 0x3d, 0x2d,
253         0xaa, 0xa0, 0xa0, 0x96, 0x0c, 0x3d, 0x3c, 0xaa,
254         0xa0, 0xa0, 0x8c, 0x0c, 0x3d, 0x46, 0xaa, 0xa0,
255         0x96, 0x8c, 0x0c, 0x3d, 0x4b, 0x8c, 0x82, 0x82,
256         0x82, 0x0c, 0x3d, 0x55, 0x8c, 0x82, 0x82, 0x82,
257         0x0c, 0x32, 0x17, 0xa5, 0x9b, 0x91, 0x87, 0x0c,
258         0x32, 0x2d, 0xaa, 0xa0, 0x96, 0x8c, 0x0c, 0x32,
259         0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0c, 0x32, 0x46,
260         0xaa, 0xa0, 0x8c, 0x78, 0x0c, 0x32, 0x4b, 0x8c,
261         0x82, 0x82, 0x78, 0x0c, 0x32, 0x55, 0x8c, 0x82,
262         0x82, 0x6e, 0x0c, 0x28, 0x17, 0xa5, 0x9b, 0x87,
263         0x73, 0x0c, 0x28, 0x2d, 0xaa, 0xa0, 0x8c, 0x78,
264         0x0c, 0x28, 0x3c, 0xaa, 0x96, 0x82, 0x73, 0x0c,
265         0x28, 0x46, 0xaa, 0x96, 0x78, 0x69, 0x0c, 0x28,
266         0x4b, 0x8c, 0x82, 0x78, 0x69, 0x0c, 0x28, 0x55,
267         0x8c, 0x82, 0x6e, 0x5a, 0x0c, 0x23, 0x17, 0xa5,
268         0x91, 0x7d, 0x69, 0x0c, 0x23, 0x2d, 0xaa, 0x96,
269         0x82, 0x6e, 0x0c, 0x23, 0x3c, 0xaa, 0x96, 0x78,
270         0x69, 0x0c, 0x23, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
271         0x0c, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0c,
272         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x0d, 0x64,
273         0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d, 0x64, 0x2d,
274         0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x3c, 0xaa,
275         0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x46, 0xaa, 0xa0,
276         0xa0, 0xa0, 0x0d, 0x64, 0x4b, 0x8c, 0x82, 0x82,
277         0x82, 0x0d, 0x64, 0x55, 0x8c, 0x82, 0x82, 0x82,
278         0x0d, 0x50, 0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d,
279         0x50, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x50,
280         0x3c, 0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x46,
281         0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x4b, 0x8c,
282         0x82, 0x82, 0x82, 0x0d, 0x50, 0x55, 0x8c, 0x82,
283         0x82, 0x82, 0x0d, 0x3c, 0x17, 0xa5, 0x9b, 0x9b,
284         0x87, 0x0d, 0x3c, 0x2d, 0xaa, 0xa0, 0xa0, 0x8c,
285         0x0d, 0x3c, 0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0d,
286         0x3c, 0x46, 0xaa, 0xa0, 0x96, 0x78, 0x0d, 0x3c,
287         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x0d, 0x3c, 0x55,
288         0x8c, 0x82, 0x82, 0x6e, 0x0d, 0x28, 0x17, 0xa5,
289         0x91, 0x7d, 0x69, 0x0d, 0x28, 0x2d, 0xaa, 0x96,
290         0x82, 0x6e, 0x0d, 0x28, 0x3c, 0xaa, 0x96, 0x78,
291         0x64, 0x0d, 0x28, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
292         0x0d, 0x28, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0d,
293         0x28, 0x55, 0x8c, 0x82, 0x64, 0x50,
294 };
295
296
297 static struct system_edp_entry __initdata tegra_system_edp_map[] = {
298
299 /* {SKU, power-limit (in 100mW), {freq limits (in 10Mhz)} } */
300
301         {  1,  49, {130, 120, 120, 120} },
302         {  1,  44, {130, 120, 120, 110} },
303         {  1,  37, {130, 120, 110, 100} },
304         {  1,  35, {130, 120, 110,  90} },
305         {  1,  29, {130, 120, 100,  80} },
306         {  1,  27, {130, 120,  90,  80} },
307         {  1,  25, {130, 110,  80,  60} },
308         {  1,  21, {130, 100,  80,  40} },
309
310         {  4,  49, {130, 120, 120, 120} },
311         {  4,  44, {130, 120, 120, 110} },
312         {  4,  37, {130, 120, 110, 100} },
313         {  4,  35, {130, 120, 110,  90} },
314         {  4,  29, {130, 120, 100,  80} },
315         {  4,  27, {130, 120,  90,  80} },
316         {  4,  25, {130, 110,  80,  60} },
317         {  4,  21, {130, 100,  80,  40} },
318 };
319
320 /*
321  * "Safe entry" to be used when no match for speedo_id /
322  * regulator_cur is found; must be the last one
323  */
324 static struct tegra_edp_limits edp_default_limits[] = {
325         {85, {1000000, 1000000, 1000000, 1000000} },
326 };
327
328 /*
329  * Constants for EDP calculations
330  */
331
332 struct a_voltage_lut_t {
333         unsigned int voltage;
334         unsigned int a_voltage;
335 };
336
337 struct a_temp_lut_t {
338         unsigned int temp;
339         unsigned int a_temp;
340 };
341
342 /* TODO: This struct will get large for 13 speedo IDs... relocate. */
343 struct edp_constants_lut_t {
344         int cpu_speedo_id;
345
346         struct a_temp_lut_t a_temp_lut [A_TEMP_LUT_MAX];
347         unsigned int a_temp_lut_size;
348
349         struct a_voltage_lut_t a_voltage_lut [A_VOLTAGE_LUT_MAX];
350         unsigned int a_voltage_lut_size;
351
352         unsigned int a_cores_lut[NR_CPUS];
353 } edp_constants_lut[] = {
354         {
355                 .cpu_speedo_id = -1,
356                 .a_temp_lut = {
357                         {23, 23270},
358                         {45, 37559},
359                         {60, 52056},
360                         {70, 64712},
361                         {75, 72150},
362                         {85, 89690},
363                         {90, 100000}
364                 },
365                 .a_temp_lut_size = 7,
366                 .a_voltage_lut = {
367                         {700, 321},
368                         {713, 336},
369                         {725, 352},
370                         {738, 369},
371                         {750, 386},
372                         {763, 405},
373                         {775, 423},
374                         {788, 444},
375                         {800, 464},
376                         {813, 487},
377                         {825, 509},
378                         {838, 534},
379                         {850, 558},
380                         {863, 585},
381                         {875, 612},
382                         {888, 642},
383                         {900, 671},
384                         {913, 704},
385                         {925, 736},
386                         {938, 772},
387                         {950, 807},
388                         {963, 847},
389                         {975, 885},
390                         {988, 929},
391                         {1000, 971},
392                         {1013, 1019},
393                         {1025, 1066},
394                         {1038, 1119},
395                         {1050, 1170},
396                         {1063, 1228},
397                         {1075, 1284},
398                         {1088, 1348},
399                         {1100, 1410},
400                         {1113, 1480},
401                         {1125, 1548},
402                         {1138, 1625},
403                         {1150, 1699},
404                         {1163, 1784},
405                         {1175, 1865},
406                         {1188, 1958},
407                         {1200, 2048},
408                         {1213, 2150},
409                         {1225, 2248},
410                         {1238, 2360},
411                         {1250, 2468},
412                         {1263, 2591},
413                         {1275, 2709},
414                         {1288, 2844},
415                         {1300, 2974}
416                 },
417                 .a_voltage_lut_size = 49,
418                 .a_cores_lut = {
419                         3565,
420                         5710,
421                         7855,
422                         10000
423                 },
424         }
425 };
426
427 struct freq_voltage_lut_t {
428         unsigned int freq;
429         struct a_voltage_lut_t *a_voltage_lut;
430 } *freq_voltage_lut = 0;
431 unsigned int freq_voltage_lut_size;
432
433 /*
434  * Find the maximum frequency that results in dynamic and leakage current that
435  * is less than the regulator current limit.
436  */
437 unsigned int edp_calculate_maxf(unsigned int a_temp,
438                                 unsigned int a_cores,
439                                 unsigned int n_cores,
440                                 unsigned int iddq_mA)
441 {
442         unsigned int voltage_mV, a_voltage, leakage_mA, op_mA, freq_MHz;
443         unsigned int regulator_cur_effective = regulator_cur - edp_reg_override_mA;
444         int i;
445
446         for (i = freq_voltage_lut_size - 1; i  >= 0; i--) {
447                 freq_MHz = freq_voltage_lut[i].freq / 1000000;
448                 voltage_mV = freq_voltage_lut[i].a_voltage_lut->voltage;
449                 a_voltage = freq_voltage_lut[i].a_voltage_lut->a_voltage;
450
451                 leakage_mA = a_temp * a_voltage;
452                 /* a_voltage was pre-multiplied by 1000 */
453                 leakage_mA /= 1000;
454                 leakage_mA *= a_cores;
455                 /* a_temp was pre-multiplied by 100,000 */
456                 leakage_mA /= 100000;
457                 leakage_mA *= iddq_mA;
458                 /* a_cores was pre-multiplied by 10,000 */
459                 leakage_mA /= 10000;
460
461                 op_mA = 55 * voltage_mV * freq_MHz * n_cores;
462                 /* 55 was pre-multiplied by 100000 */
463                 op_mA /= 100000;
464
465                 /* TODO: Apply additional margin to total current calculated? */
466                 if ((leakage_mA + op_mA) <= regulator_cur_effective)
467                         return freq_MHz * 1000;
468         }
469         return 0;
470 }
471
472 static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
473                                 unsigned int cpu_speedo_idx)
474 {
475         unsigned int i, j, freq, voltage_mV, a_voltage_lut_size;
476         struct a_voltage_lut_t *a_voltage_lut;
477
478         a_voltage_lut = edp_constants_lut[cpu_speedo_idx].a_voltage_lut;
479         a_voltage_lut_size = edp_constants_lut[cpu_speedo_idx].a_voltage_lut_size;
480
481         for (i = 0, j = 0, freq = clk_get_min_rate(clk_cpu_g);
482                  i < freq_voltage_lut_size;
483                  i++, freq += FREQ_STEP) {
484
485                 /* Predict voltages */
486                 voltage_mV = tegra_dvfs_predict_millivolts(clk_cpu_g, freq);
487                 if (voltage_mV < 0) {
488                         pr_err("%s: could not predict voltage for freqency %u, err %d\n",
489                                 __func__, freq, voltage_mV);
490                         return -EINVAL;
491                 }
492
493                 /* Look up voltage constant */
494                 for (;j < a_voltage_lut_size; j++) {
495                         if (voltage_mV <= a_voltage_lut[j].voltage) {
496                                 break;
497                         }
498                 }
499                 if (j == a_voltage_lut_size) {
500                         pr_err("%s: couldn't find voltage const for predicted voltage %d\n",
501                                 __func__, voltage_mV);
502                         return -EINVAL;
503                 }
504
505                 /* Cache frequency / voltage / voltage constant relationship */
506                 freq_voltage_lut[i].freq = freq;
507                 freq_voltage_lut[i].a_voltage_lut = &a_voltage_lut[j];
508         }
509
510         return 0;
511 }
512
513 int edp_find_speedo_idx(int cpu_speedo_id, unsigned int *cpu_speedo_idx)
514 {
515         int i;
516
517         for (i = 0; i < ARRAY_SIZE(edp_constants_lut); i++)
518                 if (cpu_speedo_id == edp_constants_lut[i].cpu_speedo_id) {
519                         *cpu_speedo_idx = i;
520                         return 0;
521                 }
522
523         pr_err("%s: couldn't find cpu speedo id in freq/voltage LUT\n", __func__);
524         return -EINVAL;
525 }
526
527 int init_cpu_edp_limits_calculated(int cpu_speedo_id)
528 {
529         unsigned int temp_idx, n_cores_idx, cpu_speedo_idx;
530         unsigned int cpu_g_minf, cpu_g_maxf;
531         unsigned int *a_cores_lut, a_temp_lut_size, iddq_mA;
532         struct a_temp_lut_t *a_temp_lut;
533         struct tegra_edp_limits *edp_calculated_limits;
534         int ret, edp_calculated_limits_size;
535         struct clk *clk_cpu_g = tegra_get_clock_by_name("cpu_g");
536
537         /* Determine all inputs to EDP formula */
538         tegra_fuse_get_cpu_iddq_mA(&iddq_mA);
539
540         ret = edp_find_speedo_idx(cpu_speedo_id, &cpu_speedo_idx);
541         if (ret)
542                 return ret;
543
544         a_temp_lut = edp_constants_lut[cpu_speedo_idx].a_temp_lut;
545         a_temp_lut_size = edp_constants_lut[cpu_speedo_idx].a_temp_lut_size;
546
547         a_cores_lut = edp_constants_lut[cpu_speedo_idx].a_cores_lut;
548
549         edp_calculated_limits =
550                 kmalloc(sizeof(struct tegra_edp_limits) * a_temp_lut_size, GFP_KERNEL);
551         BUG_ON(!edp_calculated_limits);
552         edp_calculated_limits_size = a_temp_lut_size;
553
554         cpu_g_minf = clk_get_min_rate(clk_cpu_g);
555         cpu_g_maxf = clk_get_max_rate(clk_cpu_g);
556         freq_voltage_lut_size = (cpu_g_maxf - cpu_g_minf) / FREQ_STEP + 1;
557         freq_voltage_lut =
558                 kmalloc(sizeof(struct freq_voltage_lut_t) * freq_voltage_lut_size,
559                 GFP_KERNEL);
560         if (!freq_voltage_lut) {
561                 pr_err("%s: failed to allocate mem for freq/voltage LUT\n", __func__);
562                 return -ENOMEM;
563         }
564
565         ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx);
566         if (ret) {
567                 kfree(freq_voltage_lut);
568                 return ret;
569         }
570
571         /* Calculate EDP table */
572         for (temp_idx = 0; temp_idx < a_temp_lut_size; temp_idx++) {
573                 edp_calculated_limits[temp_idx].temperature = a_temp_lut[temp_idx].temp;
574
575                 for (n_cores_idx = 0; n_cores_idx < NR_CPUS; n_cores_idx++)
576                         edp_calculated_limits[temp_idx].freq_limits[n_cores_idx] =
577                                 edp_calculate_maxf(a_temp_lut[temp_idx].a_temp,
578                                                 a_cores_lut[n_cores_idx],
579                                                 n_cores_idx + 1,
580                                                 iddq_mA);
581         }
582
583         /*
584          * If this is an EDP table update, need to overwrite old table.
585          * The old table's address must remain valid.
586          */
587         if (edp_limits != edp_default_limits) {
588                 memcpy(edp_limits, edp_calculated_limits,
589                         sizeof(struct tegra_edp_limits) * edp_calculated_limits_size);
590                 kfree(edp_calculated_limits);
591         }
592         else {
593                 edp_limits = edp_calculated_limits;
594                 edp_limits_size = edp_calculated_limits_size;
595         }
596
597         kfree(freq_voltage_lut);
598         return 0;
599 }
600
601 int init_cpu_edp_limits_lookup(int cpu_speedo_id)
602 {
603         int i, j;
604         struct tegra_edp_limits *e;
605         struct tegra_edp_entry *t = (struct tegra_edp_entry *)tegra_edp_map;
606         int tsize = sizeof(tegra_edp_map)/sizeof(struct tegra_edp_entry);
607
608         for (i = 0; i < tsize; i++) {
609                 if (t[i].speedo_id == cpu_speedo_id &&
610                     t[i].regulator_100mA <= regulator_cur / 100)
611                         break;
612         }
613
614         /* No entry found in tegra_edp_map */
615         if (i >= tsize)
616                 return -EINVAL;
617
618         /* Find all rows for this entry */
619         for (j = i + 1; j < tsize; j++) {
620                 if (t[i].speedo_id != t[j].speedo_id ||
621                     t[i].regulator_100mA != t[j].regulator_100mA)
622                         break;
623         }
624
625         edp_limits_size = j - i;
626         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
627                     GFP_KERNEL);
628         BUG_ON(!e);
629
630         for (j = 0; j < edp_limits_size; j++) {
631                 e[j].temperature = (int)t[i+j].temperature;
632                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0] * 10000;
633                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1] * 10000;
634                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2] * 10000;
635                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3] * 10000;
636         }
637
638         if (edp_limits != edp_default_limits)
639                 kfree(edp_limits);
640
641         edp_limits = e;
642         return 0;
643 }
644
645 /*
646  * Specify regulator current in mA, e.g. 5000mA
647  * Use 0 for default
648  */
649 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
650 {
651         int cpu_speedo_id = tegra_cpu_speedo_id();
652         if (!regulator_mA) {
653                 edp_limits = edp_default_limits;
654                 edp_limits_size = ARRAY_SIZE(edp_default_limits);
655                 return;
656         }
657         regulator_cur = regulator_mA;
658
659         if (!init_cpu_edp_limits_lookup(cpu_speedo_id))
660                 return;
661
662         if (!init_cpu_edp_limits_calculated(cpu_speedo_id))
663                 return;
664
665         edp_limits = edp_default_limits;
666         edp_limits_size = ARRAY_SIZE(edp_default_limits);
667 }
668
669 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
670 {
671         int cpu_speedo_id = tegra_cpu_speedo_id();
672         int i;
673         unsigned int *e;
674         struct system_edp_entry *t =
675                 (struct system_edp_entry *)tegra_system_edp_map;
676         int tsize = sizeof(tegra_system_edp_map) /
677                 sizeof(struct system_edp_entry);
678
679         if (!power_limit_mW) {
680                 e = NULL;
681                 goto out;
682         }
683
684         for (i = 0; i < tsize; i++)
685                 if (t[i].speedo_id == cpu_speedo_id)
686                         break;
687
688         if (i >= tsize) {
689                 e = NULL;
690                 goto out;
691         }
692
693         do {
694                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
695                         break;
696                 i++;
697         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
698
699         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
700                 i--; /* No low enough entry in the table, use best possible */
701
702         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
703         BUG_ON(!e);
704
705         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
706         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
707         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
708         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
709
710 out:
711         kfree(system_edp_limits);
712
713         system_edp_limits = e;
714 }
715
716
717 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
718 {
719         *limits = edp_limits;
720         *size = edp_limits_size;
721 }
722
723 void tegra_get_system_edp_limits(const unsigned int **limits)
724 {
725         *limits = system_edp_limits;
726 }
727
728 #ifdef CONFIG_DEBUG_FS
729
730 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
731 {
732         seq_printf(s, "%u\n", tegra_get_edp_limit());
733         return 0;
734 }
735
736 static int edp_debugfs_show(struct seq_file *s, void *data)
737 {
738         int i;
739
740         seq_printf(s, "-- CPU %sEDP table (%umA) --\n",
741                    edp_limits == edp_default_limits ? "default " : "",
742                    regulator_cur);
743         for (i = 0; i < edp_limits_size; i++) {
744                 seq_printf(s, "%4dC: %10u %10u %10u %10u\n",
745                            edp_limits[i].temperature,
746                            edp_limits[i].freq_limits[0],
747                            edp_limits[i].freq_limits[1],
748                            edp_limits[i].freq_limits[2],
749                            edp_limits[i].freq_limits[3]);
750         }
751
752         if (system_edp_limits) {
753                 seq_printf(s, "\n-- System EDP table --\n");
754                 seq_printf(s, "%10u %10u %10u %10u\n",
755                            system_edp_limits[0],
756                            system_edp_limits[1],
757                            system_edp_limits[2],
758                            system_edp_limits[3]);
759         }
760
761         return 0;
762 }
763
764 static int edp_reg_override_show(struct seq_file *s, void *data)
765 {
766         seq_printf(s,
767                 "Regulator limit override: %u mA. Effective regulator limit: %u mA\n",
768                 edp_reg_override_mA, regulator_cur - edp_reg_override_mA);
769         return 0;
770 }
771
772 static int edp_reg_override_write(struct file *file,
773         const char __user *userbuf, size_t count, loff_t *ppos)
774 {
775         char buf[32], *end;
776         unsigned int edp_reg_override_mA_temp;
777         int cpu_speedo_id;
778
779         if (sizeof(buf) <= count)
780                 goto override_err;
781
782         if (copy_from_user(buf, userbuf, count))
783                 goto override_err;
784
785         /* terminate buffer and trim - white spaces may be appended
786          *  at the end when invoked from shell command line */
787         buf[count]='\0';
788         strim(buf);
789
790         edp_reg_override_mA_temp = simple_strtoul(buf, &end, 10);
791         if (*end != '\0')
792                 goto override_err;
793
794         if (edp_reg_override_mA_temp >= regulator_cur)
795                 goto override_err;
796
797         edp_reg_override_mA = edp_reg_override_mA_temp;
798         cpu_speedo_id = tegra_cpu_speedo_id();
799         if(init_cpu_edp_limits_calculated(cpu_speedo_id))
800                 goto override_err;
801
802         if (tegra_cpu_set_speed_cap(NULL))
803                 goto override_err;
804
805         pr_info("Reinitialized VDD_CPU EDP table with regulator current limit"
806                         " %u mA\n", regulator_cur - edp_reg_override_mA);
807
808         return count;
809
810 override_err:
811         pr_err("Failed to reinitialized VDD_CPU EDP table with override \"%s\"\n"
812                 ,buf);
813
814         return -EINVAL;
815
816 }
817
818 static int edp_debugfs_open(struct inode *inode, struct file *file)
819 {
820         return single_open(file, edp_debugfs_show, inode->i_private);
821 }
822
823 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
824 {
825         return single_open(file, edp_limit_debugfs_show, inode->i_private);
826 }
827
828 static int edp_reg_override_open(struct inode *inode, struct file *file)
829 {
830         return single_open(file, edp_reg_override_show, inode->i_private);
831 }
832
833 static const struct file_operations edp_debugfs_fops = {
834         .open           = edp_debugfs_open,
835         .read           = seq_read,
836         .llseek         = seq_lseek,
837         .release        = single_release,
838 };
839
840 static const struct file_operations edp_limit_debugfs_fops = {
841         .open           = edp_limit_debugfs_open,
842         .read           = seq_read,
843         .llseek         = seq_lseek,
844         .release        = single_release,
845 };
846
847 static const struct file_operations edp_reg_override_debugfs_fops = {
848         .open           = edp_reg_override_open,
849         .read           = seq_read,
850         .write          = edp_reg_override_write,
851         .llseek         = seq_lseek,
852         .release        = single_release,
853 };
854
855 static int __init tegra_edp_debugfs_init(void)
856 {
857         struct dentry *d;
858
859         d = debugfs_create_file("edp", S_IRUGO, NULL, NULL,
860                                 &edp_debugfs_fops);
861         if (!d)
862                 return -ENOMEM;
863
864         d = debugfs_create_file("edp_limit", S_IRUGO, NULL, NULL,
865                                 &edp_limit_debugfs_fops);
866
867         d = debugfs_create_file("edp_reg_override", S_IRUGO | S_IWUSR, NULL, NULL,
868                                 &edp_reg_override_debugfs_fops);
869         if (!d)
870                 return -ENOMEM;
871
872         return 0;
873 }
874
875 late_initcall(tegra_edp_debugfs_init);
876 #endif /* CONFIG_DEBUG_FS */