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