ARM: tegra: remove duplicate defines for chip_id
[linux-3.10.git] / arch / arm / mach-tegra / edp.c
1 /*
2  * arch/arm/mach-tegra/edp.c
3  *
4  * Copyright (C) 2011-2013, NVIDIA CORPORATION. All Rights Reserved.
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 <linux/edp.h>
28
29 #include <mach/edp.h>
30 #include <mach/hardware.h>
31
32 #include "fuse.h"
33 #include "dvfs.h"
34 #include "clock.h"
35 #include "cpu-tegra.h"
36
37 #define FREQ_STEP 12750000
38 #define OVERRIDE_DEFAULT 6000
39
40 static struct tegra_edp_limits *edp_limits;
41 static int edp_limits_size;
42 static unsigned int regulator_cur;
43 /* Value to subtract from regulator current limit */
44 static unsigned int edp_reg_override_mA = OVERRIDE_DEFAULT;
45
46 static const unsigned int *system_edp_limits;
47
48 static struct tegra_system_edp_entry *power_edp_limits;
49 static int power_edp_limits_size;
50
51 /*
52  * Temperature step size cannot be less than 4C because of hysteresis
53  * delta
54  * Code assumes different temperatures for the same speedo_id /
55  * regulator_cur are adjacent in the table, and higest regulator_cur
56  * comes first
57  */
58 static char __initdata tegra_edp_vdd_cpu_map[] = {
59         0x00, 0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x00,
60         0x2f, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f,
61         0x3c, 0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x4b,
62         0x82, 0x78, 0x78, 0x78, 0x00, 0x2f, 0x55, 0x82,
63         0x78, 0x78, 0x78, 0x00, 0x28, 0x17, 0x7d, 0x73,
64         0x73, 0x73, 0x00, 0x28, 0x2d, 0x82, 0x78, 0x78,
65         0x78, 0x00, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78,
66         0x00, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x00,
67         0x28, 0x55, 0x82, 0x78, 0x78, 0x69, 0x00, 0x23,
68         0x17, 0x7d, 0x73, 0x73, 0x73, 0x00, 0x23, 0x2d,
69         0x82, 0x78, 0x78, 0x78, 0x00, 0x23, 0x3c, 0x82,
70         0x78, 0x78, 0x6e, 0x00, 0x23, 0x4b, 0x82, 0x78,
71         0x78, 0x64, 0x00, 0x23, 0x55, 0x82, 0x78, 0x6e,
72         0x5a, 0x00, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64,
73         0x00, 0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x00,
74         0x1e, 0x3c, 0x82, 0x78, 0x78, 0x64, 0x00, 0x1e,
75         0x4b, 0x82, 0x78, 0x6e, 0x5a, 0x00, 0x1e, 0x55,
76         0x82, 0x78, 0x64, 0x50, 0x00, 0x19, 0x17, 0x7d,
77         0x73, 0x69, 0x55, 0x00, 0x19, 0x2d, 0x82, 0x78,
78         0x6e, 0x5a, 0x00, 0x19, 0x3c, 0x82, 0x78, 0x69,
79         0x55, 0x00, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b,
80         0x00, 0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x01,
81         0x2f, 0x17, 0x7d, 0x73, 0x73, 0x73, 0x01, 0x2f,
82         0x2d, 0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x3c,
83         0x82, 0x78, 0x78, 0x78, 0x01, 0x2f, 0x4b, 0x82,
84         0x78, 0x78, 0x78, 0x01, 0x2f, 0x55, 0x82, 0x78,
85         0x78, 0x78, 0x01, 0x28, 0x17, 0x7d, 0x73, 0x73,
86         0x73, 0x01, 0x28, 0x2d, 0x82, 0x78, 0x78, 0x78,
87         0x01, 0x28, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x01,
88         0x28, 0x4b, 0x82, 0x78, 0x78, 0x73, 0x01, 0x28,
89         0x55, 0x82, 0x78, 0x78, 0x69, 0x01, 0x23, 0x17,
90         0x7d, 0x73, 0x73, 0x73, 0x01, 0x23, 0x2d, 0x82,
91         0x78, 0x78, 0x78, 0x01, 0x23, 0x3c, 0x82, 0x78,
92         0x78, 0x6e, 0x01, 0x23, 0x4b, 0x82, 0x78, 0x78,
93         0x64, 0x01, 0x23, 0x55, 0x82, 0x78, 0x6e, 0x5a,
94         0x01, 0x1e, 0x17, 0x7d, 0x73, 0x73, 0x64, 0x01,
95         0x1e, 0x2d, 0x82, 0x78, 0x78, 0x69, 0x01, 0x1e,
96         0x3c, 0x82, 0x78, 0x78, 0x64, 0x01, 0x1e, 0x4b,
97         0x82, 0x78, 0x6e, 0x5a, 0x01, 0x1e, 0x55, 0x82,
98         0x78, 0x64, 0x50, 0x01, 0x19, 0x17, 0x7d, 0x73,
99         0x69, 0x55, 0x01, 0x19, 0x2d, 0x82, 0x78, 0x6e,
100         0x5a, 0x01, 0x19, 0x3c, 0x82, 0x78, 0x69, 0x55,
101         0x01, 0x19, 0x4b, 0x82, 0x78, 0x5f, 0x4b, 0x01,
102         0x19, 0x55, 0x82, 0x73, 0x55, 0x3c, 0x02, 0x3d,
103         0x17, 0x87, 0x7d, 0x7d, 0x7d, 0x02, 0x3d, 0x2d,
104         0x8c, 0x82, 0x82, 0x82, 0x02, 0x3d, 0x3c, 0x8c,
105         0x82, 0x82, 0x82, 0x02, 0x3d, 0x4b, 0x8c, 0x82,
106         0x82, 0x82, 0x02, 0x3d, 0x55, 0x8c, 0x82, 0x82,
107         0x82, 0x02, 0x32, 0x17, 0x87, 0x7d, 0x7d, 0x7d,
108         0x02, 0x32, 0x2d, 0x8c, 0x82, 0x82, 0x82, 0x02,
109         0x32, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x02, 0x32,
110         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x02, 0x32, 0x55,
111         0x8c, 0x82, 0x82, 0x6e, 0x02, 0x28, 0x17, 0x87,
112         0x7d, 0x7d, 0x73, 0x02, 0x28, 0x2d, 0x8c, 0x82,
113         0x82, 0x78, 0x02, 0x28, 0x3c, 0x8c, 0x82, 0x82,
114         0x73, 0x02, 0x28, 0x4b, 0x8c, 0x82, 0x78, 0x69,
115         0x02, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a, 0x02,
116         0x23, 0x17, 0x87, 0x7d, 0x7d, 0x69, 0x02, 0x23,
117         0x2d, 0x8c, 0x82, 0x82, 0x6e, 0x02, 0x23, 0x3c,
118         0x8c, 0x82, 0x78, 0x69, 0x02, 0x23, 0x4b, 0x8c,
119         0x82, 0x6e, 0x5a, 0x02, 0x23, 0x55, 0x8c, 0x82,
120         0x64, 0x50, 0x03, 0x3d, 0x17, 0x87, 0x7d, 0x7d,
121         0x7d, 0x03, 0x3d, 0x2d, 0x8c, 0x82, 0x82, 0x82,
122         0x03, 0x3d, 0x3c, 0x8c, 0x82, 0x82, 0x82, 0x03,
123         0x3d, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x3d,
124         0x55, 0x8c, 0x82, 0x82, 0x82, 0x03, 0x32, 0x17,
125         0x87, 0x7d, 0x7d, 0x7d, 0x03, 0x32, 0x2d, 0x8c,
126         0x82, 0x82, 0x82, 0x03, 0x32, 0x3c, 0x8c, 0x82,
127         0x82, 0x82, 0x03, 0x32, 0x4b, 0x8c, 0x82, 0x82,
128         0x78, 0x03, 0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e,
129         0x03, 0x28, 0x17, 0x87, 0x7d, 0x7d, 0x73, 0x03,
130         0x28, 0x2d, 0x8c, 0x82, 0x82, 0x78, 0x03, 0x28,
131         0x3c, 0x8c, 0x82, 0x82, 0x73, 0x03, 0x28, 0x4b,
132         0x8c, 0x82, 0x78, 0x69, 0x03, 0x28, 0x55, 0x8c,
133         0x82, 0x6e, 0x5a, 0x03, 0x23, 0x17, 0x87, 0x7d,
134         0x7d, 0x69, 0x03, 0x23, 0x2d, 0x8c, 0x82, 0x82,
135         0x6e, 0x03, 0x23, 0x3c, 0x8c, 0x82, 0x78, 0x69,
136         0x03, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x03,
137         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x04, 0x32,
138         0x17, 0x91, 0x87, 0x87, 0x87, 0x04, 0x32, 0x2d,
139         0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x3c, 0x96,
140         0x8c, 0x8c, 0x8c, 0x04, 0x32, 0x46, 0x96, 0x8c,
141         0x8c, 0x8c, 0x04, 0x32, 0x4b, 0x82, 0x78, 0x78,
142         0x78, 0x04, 0x32, 0x55, 0x82, 0x78, 0x78, 0x78,
143         0x04, 0x2f, 0x17, 0x91, 0x87, 0x87, 0x87, 0x04,
144         0x2f, 0x2d, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f,
145         0x3c, 0x96, 0x8c, 0x8c, 0x8c, 0x04, 0x2f, 0x46,
146         0x96, 0x8c, 0x8c, 0x82, 0x04, 0x2f, 0x4b, 0x82,
147         0x78, 0x78, 0x78, 0x04, 0x2f, 0x55, 0x82, 0x78,
148         0x78, 0x78, 0x04, 0x28, 0x17, 0x91, 0x87, 0x87,
149         0x87, 0x04, 0x28, 0x2d, 0x96, 0x8c, 0x8c, 0x82,
150         0x04, 0x28, 0x3c, 0x96, 0x8c, 0x8c, 0x82, 0x04,
151         0x28, 0x46, 0x96, 0x8c, 0x8c, 0x78, 0x04, 0x28,
152         0x4b, 0x82, 0x78, 0x78, 0x78, 0x04, 0x28, 0x55,
153         0x82, 0x78, 0x78, 0x6e, 0x04, 0x23, 0x17, 0x91,
154         0x87, 0x87, 0x73, 0x04, 0x23, 0x2d, 0x96, 0x8c,
155         0x8c, 0x78, 0x04, 0x23, 0x3c, 0x96, 0x8c, 0x82,
156         0x78, 0x04, 0x23, 0x46, 0x96, 0x8c, 0x82, 0x6e,
157         0x04, 0x23, 0x4b, 0x82, 0x78, 0x78, 0x6e, 0x04,
158         0x23, 0x55, 0x82, 0x78, 0x78, 0x64, 0x04, 0x1e,
159         0x17, 0x91, 0x87, 0x7d, 0x69, 0x04, 0x1e, 0x2d,
160         0x96, 0x8c, 0x82, 0x6e, 0x04, 0x1e, 0x3c, 0x96,
161         0x8c, 0x78, 0x64, 0x04, 0x1e, 0x46, 0x96, 0x8c,
162         0x78, 0x5a, 0x04, 0x1e, 0x4b, 0x82, 0x78, 0x78,
163         0x5a, 0x04, 0x1e, 0x55, 0x82, 0x78, 0x64, 0x50,
164         0x04, 0x19, 0x17, 0x91, 0x87, 0x69, 0x55, 0x04,
165         0x19, 0x2d, 0x96, 0x8c, 0x6e, 0x5a, 0x04, 0x19,
166         0x3c, 0x96, 0x82, 0x6e, 0x55, 0x04, 0x19, 0x46,
167         0x96, 0x82, 0x64, 0x50, 0x04, 0x19, 0x4b, 0x82,
168         0x78, 0x64, 0x50, 0x04, 0x19, 0x55, 0x82, 0x78,
169         0x55, 0x3c, 0x05, 0x64, 0x17, 0xa5, 0x9b, 0x9b,
170         0x9b, 0x05, 0x64, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
171         0x05, 0x64, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x05,
172         0x64, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x05, 0x64,
173         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x64, 0x55,
174         0x8c, 0x82, 0x82, 0x82, 0x05, 0x50, 0x17, 0xa5,
175         0x9b, 0x9b, 0x9b, 0x05, 0x50, 0x2d, 0xaa, 0xa0,
176         0xa0, 0xa0, 0x05, 0x50, 0x3c, 0xaa, 0xa0, 0xa0,
177         0x96, 0x05, 0x50, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
178         0x05, 0x50, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x05,
179         0x50, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x05, 0x3c,
180         0x17, 0xa5, 0x9b, 0x9b, 0x87, 0x05, 0x3c, 0x2d,
181         0xaa, 0xa0, 0xa0, 0x8c, 0x05, 0x3c, 0x3c, 0xaa,
182         0xa0, 0x96, 0x82, 0x05, 0x3c, 0x46, 0xaa, 0xa0,
183         0x96, 0x78, 0x05, 0x3c, 0x4b, 0x8c, 0x82, 0x82,
184         0x78, 0x05, 0x3c, 0x55, 0x8c, 0x82, 0x82, 0x6e,
185         0x05, 0x28, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x05,
186         0x28, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x05, 0x28,
187         0x3c, 0xaa, 0x96, 0x78, 0x64, 0x05, 0x28, 0x46,
188         0xaa, 0x8c, 0x6e, 0x5a, 0x05, 0x28, 0x4b, 0x8c,
189         0x82, 0x6e, 0x5a, 0x05, 0x28, 0x55, 0x8c, 0x82,
190         0x64, 0x50, 0x06, 0x3d, 0x17, 0xa5, 0x9b, 0x7d,
191         0x7d, 0x06, 0x3d, 0x2d, 0xaa, 0xa0, 0x82, 0x82,
192         0x06, 0x3d, 0x3c, 0xaa, 0xa0, 0x82, 0x82, 0x06,
193         0x3d, 0x46, 0xaa, 0xa0, 0x82, 0x82, 0x06, 0x3d,
194         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x06, 0x3d, 0x55,
195         0x8c, 0x82, 0x82, 0x82, 0x06, 0x32, 0x17, 0xa5,
196         0x9b, 0x7d, 0x7d, 0x06, 0x32, 0x2d, 0xaa, 0xa0,
197         0x82, 0x82, 0x06, 0x32, 0x3c, 0xaa, 0xa0, 0x82,
198         0x82, 0x06, 0x32, 0x46, 0xaa, 0xa0, 0x82, 0x78,
199         0x06, 0x32, 0x4b, 0x8c, 0x82, 0x82, 0x78, 0x06,
200         0x32, 0x55, 0x8c, 0x82, 0x82, 0x6e, 0x06, 0x28,
201         0x17, 0xa5, 0x9b, 0x7d, 0x73, 0x06, 0x28, 0x2d,
202         0xaa, 0xa0, 0x82, 0x78, 0x06, 0x28, 0x3c, 0xaa,
203         0x96, 0x82, 0x73, 0x06, 0x28, 0x46, 0xaa, 0x96,
204         0x78, 0x69, 0x06, 0x28, 0x4b, 0x8c, 0x82, 0x78,
205         0x69, 0x06, 0x28, 0x55, 0x8c, 0x82, 0x6e, 0x5a,
206         0x06, 0x23, 0x17, 0xa5, 0x91, 0x7d, 0x69, 0x06,
207         0x23, 0x2d, 0xaa, 0x96, 0x82, 0x6e, 0x06, 0x23,
208         0x3c, 0xaa, 0x96, 0x78, 0x69, 0x06, 0x23, 0x46,
209         0xaa, 0x8c, 0x6e, 0x5a, 0x06, 0x23, 0x4b, 0x8c,
210         0x82, 0x6e, 0x5a, 0x06, 0x23, 0x55, 0x8c, 0x82,
211         0x64, 0x50, 0x07, 0x3b, 0x17, 0x7d, 0x73, 0x73,
212         0x73, 0x07, 0x3b, 0x2d, 0x82, 0x78, 0x78, 0x78,
213         0x07, 0x3b, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x07,
214         0x3b, 0x4b, 0x82, 0x78, 0x78, 0x78, 0x07, 0x3b,
215         0x5a, 0x82, 0x78, 0x78, 0x78, 0x07, 0x32, 0x17,
216         0x7d, 0x73, 0x73, 0x73, 0x07, 0x32, 0x2d, 0x82,
217         0x78, 0x78, 0x78, 0x07, 0x32, 0x3c, 0x82, 0x78,
218         0x78, 0x78, 0x07, 0x32, 0x4b, 0x82, 0x78, 0x78,
219         0x78, 0x07, 0x32, 0x5a, 0x82, 0x78, 0x6e, 0x64,
220         0x07, 0x28, 0x17, 0x7d, 0x73, 0x73, 0x69, 0x07,
221         0x28, 0x2d, 0x82, 0x78, 0x78, 0x6e, 0x07, 0x28,
222         0x3c, 0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x4b,
223         0x82, 0x78, 0x78, 0x64, 0x07, 0x28, 0x5a, 0x82,
224         0x78, 0x64, 0x50, 0x07, 0x23, 0x17, 0x7d, 0x73,
225         0x73, 0x5f, 0x07, 0x23, 0x2d, 0x82, 0x78, 0x78,
226         0x64, 0x07, 0x23, 0x3c, 0x82, 0x78, 0x78, 0x64,
227         0x07, 0x23, 0x4b, 0x82, 0x78, 0x64, 0x50, 0x07,
228         0x23, 0x5a, 0x82, 0x78, 0x5a, 0x46, 0x08, 0x3b,
229         0x17, 0x7d, 0x73, 0x73, 0x73, 0x08, 0x3b, 0x2d,
230         0x82, 0x78, 0x78, 0x78, 0x08, 0x3b, 0x3c, 0x82,
231         0x78, 0x78, 0x78, 0x08, 0x3b, 0x4b, 0x82, 0x78,
232         0x78, 0x78, 0x08, 0x3b, 0x5a, 0x82, 0x78, 0x78,
233         0x78, 0x08, 0x32, 0x17, 0x7d, 0x73, 0x73, 0x73,
234         0x08, 0x32, 0x2d, 0x82, 0x78, 0x78, 0x78, 0x08,
235         0x32, 0x3c, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32,
236         0x4b, 0x82, 0x78, 0x78, 0x78, 0x08, 0x32, 0x5a,
237         0x82, 0x78, 0x6e, 0x64, 0x08, 0x28, 0x17, 0x7d,
238         0x73, 0x73, 0x69, 0x08, 0x28, 0x2d, 0x82, 0x78,
239         0x78, 0x6e, 0x08, 0x28, 0x3c, 0x82, 0x78, 0x78,
240         0x64, 0x08, 0x28, 0x4b, 0x82, 0x78, 0x78, 0x64,
241         0x08, 0x28, 0x5a, 0x82, 0x78, 0x64, 0x50, 0x08,
242         0x23, 0x17, 0x7d, 0x73, 0x73, 0x5f, 0x08, 0x23,
243         0x2d, 0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x3c,
244         0x82, 0x78, 0x78, 0x64, 0x08, 0x23, 0x4b, 0x82,
245         0x78, 0x64, 0x50, 0x08, 0x23, 0x5a, 0x82, 0x78,
246         0x5a, 0x46, 0x0c, 0x52, 0x17, 0xa5, 0x9b, 0x9b,
247         0x9b, 0x0c, 0x52, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0,
248         0x0c, 0x52, 0x3c, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c,
249         0x52, 0x46, 0xaa, 0xa0, 0xa0, 0xa0, 0x0c, 0x52,
250         0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x52, 0x55,
251         0x8c, 0x82, 0x82, 0x82, 0x0c, 0x42, 0x17, 0xa5,
252         0x9b, 0x9b, 0x91, 0x0c, 0x42, 0x2d, 0xaa, 0xa0,
253         0xa0, 0x96, 0x0c, 0x42, 0x3c, 0xaa, 0xa0, 0xa0,
254         0x96, 0x0c, 0x42, 0x46, 0xaa, 0xa0, 0xa0, 0x96,
255         0x0c, 0x42, 0x4b, 0x8c, 0x82, 0x82, 0x82, 0x0c,
256         0x42, 0x55, 0x8c, 0x82, 0x82, 0x82, 0x0c, 0x3d,
257         0x17, 0xa5, 0x9b, 0x9b, 0x91, 0x0c, 0x3d, 0x2d,
258         0xaa, 0xa0, 0xa0, 0x96, 0x0c, 0x3d, 0x3c, 0xaa,
259         0xa0, 0xa0, 0x8c, 0x0c, 0x3d, 0x46, 0xaa, 0xa0,
260         0x96, 0x8c, 0x0c, 0x3d, 0x4b, 0x8c, 0x82, 0x82,
261         0x82, 0x0c, 0x3d, 0x55, 0x8c, 0x82, 0x82, 0x82,
262         0x0c, 0x32, 0x17, 0xa5, 0x9b, 0x91, 0x87, 0x0c,
263         0x32, 0x2d, 0xaa, 0xa0, 0x96, 0x8c, 0x0c, 0x32,
264         0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0c, 0x32, 0x46,
265         0xaa, 0xa0, 0x8c, 0x78, 0x0c, 0x32, 0x4b, 0x8c,
266         0x82, 0x82, 0x78, 0x0c, 0x32, 0x55, 0x8c, 0x82,
267         0x82, 0x6e, 0x0c, 0x28, 0x17, 0xa5, 0x9b, 0x87,
268         0x73, 0x0c, 0x28, 0x2d, 0xaa, 0xa0, 0x8c, 0x78,
269         0x0c, 0x28, 0x3c, 0xaa, 0x96, 0x82, 0x73, 0x0c,
270         0x28, 0x46, 0xaa, 0x96, 0x78, 0x69, 0x0c, 0x28,
271         0x4b, 0x8c, 0x82, 0x78, 0x69, 0x0c, 0x28, 0x55,
272         0x8c, 0x82, 0x6e, 0x5a, 0x0c, 0x23, 0x17, 0xa5,
273         0x91, 0x7d, 0x69, 0x0c, 0x23, 0x2d, 0xaa, 0x96,
274         0x82, 0x6e, 0x0c, 0x23, 0x3c, 0xaa, 0x96, 0x78,
275         0x69, 0x0c, 0x23, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
276         0x0c, 0x23, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0c,
277         0x23, 0x55, 0x8c, 0x82, 0x64, 0x50, 0x0d, 0x64,
278         0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d, 0x64, 0x2d,
279         0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x3c, 0xaa,
280         0xa0, 0xa0, 0xa0, 0x0d, 0x64, 0x46, 0xaa, 0xa0,
281         0xa0, 0xa0, 0x0d, 0x64, 0x4b, 0x8c, 0x82, 0x82,
282         0x82, 0x0d, 0x64, 0x55, 0x8c, 0x82, 0x82, 0x82,
283         0x0d, 0x50, 0x17, 0xa5, 0x9b, 0x9b, 0x9b, 0x0d,
284         0x50, 0x2d, 0xaa, 0xa0, 0xa0, 0xa0, 0x0d, 0x50,
285         0x3c, 0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x46,
286         0xaa, 0xa0, 0xa0, 0x96, 0x0d, 0x50, 0x4b, 0x8c,
287         0x82, 0x82, 0x82, 0x0d, 0x50, 0x55, 0x8c, 0x82,
288         0x82, 0x82, 0x0d, 0x3c, 0x17, 0xa5, 0x9b, 0x9b,
289         0x87, 0x0d, 0x3c, 0x2d, 0xaa, 0xa0, 0xa0, 0x8c,
290         0x0d, 0x3c, 0x3c, 0xaa, 0xa0, 0x96, 0x82, 0x0d,
291         0x3c, 0x46, 0xaa, 0xa0, 0x96, 0x78, 0x0d, 0x3c,
292         0x4b, 0x8c, 0x82, 0x82, 0x78, 0x0d, 0x3c, 0x55,
293         0x8c, 0x82, 0x82, 0x6e, 0x0d, 0x28, 0x17, 0xa5,
294         0x91, 0x7d, 0x69, 0x0d, 0x28, 0x2d, 0xaa, 0x96,
295         0x82, 0x6e, 0x0d, 0x28, 0x3c, 0xaa, 0x96, 0x78,
296         0x64, 0x0d, 0x28, 0x46, 0xaa, 0x8c, 0x6e, 0x5a,
297         0x0d, 0x28, 0x4b, 0x8c, 0x82, 0x6e, 0x5a, 0x0d,
298         0x28, 0x55, 0x8c, 0x82, 0x64, 0x50,
299 };
300
301
302 static struct tegra_system_edp_entry __initdata tegra_system_edp_map[] = {
303
304 /* {SKU, power-limit (in 100mW), {freq limits (in 10Mhz)} } */
305
306         {  1,  49, {130, 120, 120, 120} },
307         {  1,  44, {130, 120, 120, 110} },
308         {  1,  37, {130, 120, 110, 100} },
309         {  1,  35, {130, 120, 110,  90} },
310         {  1,  29, {130, 120, 100,  80} },
311         {  1,  27, {130, 120,  90,  80} },
312         {  1,  25, {130, 110,  80,  60} },
313         {  1,  21, {130, 100,  80,  40} },
314
315         {  4,  49, {130, 120, 120, 120} },
316         {  4,  44, {130, 120, 120, 110} },
317         {  4,  37, {130, 120, 110, 100} },
318         {  4,  35, {130, 120, 110,  90} },
319         {  4,  29, {130, 120, 100,  80} },
320         {  4,  27, {130, 120,  90,  80} },
321         {  4,  25, {130, 110,  80,  60} },
322         {  4,  21, {130, 100,  80,  40} },
323 };
324
325 /*
326  * "Safe entry" to be used when no match for speedo_id /
327  * regulator_cur is found; must be the last one
328  */
329 static struct tegra_edp_limits edp_default_limits[] = {
330         {85, {1000000, 1000000, 1000000, 1000000} },
331 };
332
333 static struct tegra_system_edp_entry power_edp_default_limits[] = {
334         {0, 20, {1000000, 1000000, 1000000, 1000000} },
335 };
336
337 /* Constants for EDP calculations */
338 static const int temperatures[] = { /* degree celcius (C) */
339         23, 40, 50, 60, 70, 74, 78, 82, 86, 90, 94, 98, 102,
340 };
341 static const int power_cap_levels[] = { /* milliwatts (mW) */
342         500, 1000, 1500, 2000, 2500, 3000, 3500,
343         4000, 4500, 5000, 5500, 6000, 6500, 7000, 7500,
344         8000, 8500, 9000, 9500, 10000, 10500, 11000, 11500,
345         12000, 12500, 13000, 13500, 14000, 14500, 15000, 15500,
346         16000, 16500, 17000,
347 };
348
349 #ifdef CONFIG_ARCH_TEGRA_14x_SOC
350 static struct tegra_edp_cpu_leakage_params leakage_params[] = {
351         {
352                 .cpu_speedo_id      = 0, /* A01 CPU */
353                 .dyn_consts_n       = {  643724,  908655, 1173586, 1438517 },
354                 .leakage_consts_n   = {  524409,  699606,  874803, 1050000 },
355                 .leakage_consts_ijk = {
356                         /* i = 0 */
357                         { {   0,   -5346808,   97234,   -464, },
358                           {   0,   16803984, -307162,   1481, },
359                           {   0,  -17730060,  322460,  -1546, },
360                           {   0,    6489900, -118190,    564, },
361                         },
362                         /* i = 1 */
363                         { {   0,   -7166070,   16144,  -2495, },
364                           {   0,   22733881,  -62339,   7849, },
365                           {   0,  -22851718,   17626,  -7211, },
366                           {   0,    8845764,   -3232,   2668, },
367                         },
368                         /* i = 2 */
369                         { {   0,  -13755297,   88228,    194, },
370                           {   0,   43058825, -281494,   -604, },
371                           {   0,  -45854189,  328873,    337, },
372                           {   0,   17332703, -123100,   -128, },
373                         },
374                         /* i = 3 */
375                         { {   0,    1950888,   -8210,    -62, },
376                           {   0,   -6086732,   26052,    197, },
377                           {   0,    6462190,  -32222,   -161, },
378                           {   0,   -2416618,   11593,     62, },
379                         },
380                  },
381         },
382 };
383 #else
384 static struct tegra_edp_cpu_leakage_params leakage_params[] = {
385         {
386                 .cpu_speedo_id      = 0, /* A01 CPU */
387                 .dyn_consts_n       = { 1091747, 2035205, 2978661, 3922119 },
388                 .leakage_consts_n   = {  538991,  752463,  959441, 1150000 },
389                 .leakage_consts_ijk = {
390                          /* i = 0 */
391                          { {  -42746668,   -5458429,   164998,  -1711, },
392                            {  178262421,   13375684,  -411791,   4590, },
393                            { -228866784,  -10482993,   331248,  -4062, },
394                            {   94301550,    2618719,   -85983,   1193, },
395                          },
396                          /* i = 1 */
397                          { { -256611791,   49677413, -1655785,  14917, },
398                            {  584675433, -132620939,  4541560, -41812, },
399                            { -398106336,  115987156, -4102328,  38737, },
400                            {   68897184,  -33030745,  1217839, -11801, },
401                          },
402                          /* i = 2 */
403                          { {  186324676,  -36019083,  1177969, -10669, },
404                            { -439237936,   98429131, -3276444,  30301, },
405                            {  315060898,  -88635036,  3004777, -28474, },
406                            {  -60854399,   26267188,  -907121,   8844, },
407                          },
408                          /* i = 3 */
409                          { {  -35432997,    6154621,  -202200,   1830, },
410                            {   87402153,  -16908683,   565152,  -5220, },
411                            {  -67775314,   15326770,  -521221,   4927, },
412                            {   15618709,   -4576116,   158401,  -1538, },
413                          },
414                  },
415         },
416         {
417                 .cpu_speedo_id      = 1, /* A01P+ CPU */
418                 .dyn_consts_n       = { 1091747, 2035205, 2978661, 3922119 },
419                 .leakage_consts_n   = {  538991,  752463,  959441, 1150000 },
420                 .leakage_consts_ijk = {
421                          /* i = 0 */
422                          { {  -42746668,   -5458429,   164998,  -1711, },
423                            {  178262421,   13375684,  -411791,   4590, },
424                            { -228866784,  -10482993,   331248,  -4062, },
425                            {   94301550,    2618719,   -85983,   1193, },
426                          },
427                          /* i = 1 */
428                          { { -256611791,   49677413, -1655785,  14917, },
429                            {  584675433, -132620939,  4541560, -41812, },
430                            { -398106336,  115987156, -4102328,  38737, },
431                            {   68897184,  -33030745,  1217839, -11801, },
432                          },
433                          /* i = 2 */
434                          { {  186324676,  -36019083,  1177969, -10669, },
435                            { -439237936,   98429131, -3276444,  30301, },
436                            {  315060898,  -88635036,  3004777, -28474, },
437                            {  -60854399,   26267188,  -907121,   8844, },
438                          },
439                          /* i = 3 */
440                          { {  -35432997,    6154621,  -202200,   1830, },
441                            {   87402153,  -16908683,   565152,  -5220, },
442                            {  -67775314,   15326770,  -521221,   4927, },
443                            {   15618709,   -4576116,   158401,  -1538, },
444                          },
445                  },
446                 .safety_cap = { 1810500, 1810500, 1606500, 1606500 },
447         },
448         {
449                 .cpu_speedo_id      = 2, /* A01P+ fast CPU */
450                 .dyn_consts_n       = { 1091747, 2035205, 2978661, 3922119 },
451                 .leakage_consts_n   = {  538991,  752463,  959441, 1150000 },
452                 .leakage_consts_ijk = {
453                          /* i = 0 */
454                          { {  -42746668,   -5458429,   164998,  -1711, },
455                            {  178262421,   13375684,  -411791,   4590, },
456                            { -228866784,  -10482993,   331248,  -4062, },
457                            {   94301550,    2618719,   -85983,   1193, },
458                          },
459                          /* i = 1 */
460                          { { -256611791,   49677413, -1655785,  14917, },
461                            {  584675433, -132620939,  4541560, -41812, },
462                            { -398106336,  115987156, -4102328,  38737, },
463                            {   68897184,  -33030745,  1217839, -11801, },
464                          },
465                          /* i = 2 */
466                          { {  186324676,  -36019083,  1177969, -10669, },
467                            { -439237936,   98429131, -3276444,  30301, },
468                            {  315060898,  -88635036,  3004777, -28474, },
469                            {  -60854399,   26267188,  -907121,   8844, },
470                          },
471                          /* i = 3 */
472                          { {  -35432997,    6154621,  -202200,   1830, },
473                            {   87402153,  -16908683,   565152,  -5220, },
474                            {  -67775314,   15326770,  -521221,   4927, },
475                            {   15618709,   -4576116,   158401,  -1538, },
476                          },
477                  },
478                 .safety_cap = { 1912500, 1912500, 1912500, 1912500 },
479         },
480 };
481 #endif
482
483 static struct tegra_edp_freq_voltage_table *freq_voltage_lut_saved;
484 static unsigned int freq_voltage_lut_size_saved;
485 static struct tegra_edp_freq_voltage_table *freq_voltage_lut;
486 static unsigned int freq_voltage_lut_size;
487
488 static inline s64 edp_pow(s64 val, int pwr)
489 {
490         s64 retval = 1;
491
492         while (pwr) {
493                 if (pwr & 1)
494                         retval *= val;
495                 pwr >>= 1;
496                 if (pwr)
497                         val *= val;
498         }
499
500         return retval;
501 }
502
503 /*
504  * Find the maximum frequency that results in dynamic and leakage current that
505  * is less than the regulator current limit.
506  * temp_C - always valid
507  * power_mW - valid or -1 (infinite)
508  */
509 unsigned int edp_calculate_maxf(struct tegra_edp_cpu_leakage_params *params,
510                                 int temp_C, int power_mW,
511                                 int iddq_mA,
512                                 int n_cores_idx)
513 {
514         unsigned int voltage_mV, freq_KHz;
515         unsigned int cur_effective = regulator_cur - edp_reg_override_mA;
516         int f, i, j, k;
517         s64 leakage_mA, dyn_mA, leakage_calc_step;
518         s64 leakage_mW, dyn_mW;
519
520         for (f = freq_voltage_lut_size - 1; f >= 0; f--) {
521                 freq_KHz = freq_voltage_lut[f].freq / 1000;
522                 voltage_mV = freq_voltage_lut[f].voltage_mV;
523
524                 /* Calculate leakage current */
525                 leakage_mA = 0;
526                 for (i = 0; i <= 3; i++) {
527                         for (j = 0; j <= 3; j++) {
528                                 for (k = 0; k <= 3; k++) {
529                                         leakage_calc_step =
530                                                 params->leakage_consts_ijk
531                                                 [i][j][k] * edp_pow(iddq_mA, i);
532                                         /* Convert (mA)^i to (A)^i */
533                                         leakage_calc_step =
534                                                 div64_s64(leakage_calc_step,
535                                                           edp_pow(1000, i));
536                                         leakage_calc_step *=
537                                                 edp_pow(voltage_mV, j);
538                                         /* Convert (mV)^i to (V)^i */
539                                         leakage_calc_step =
540                                                 div64_s64(leakage_calc_step,
541                                                           edp_pow(1000, j));
542                                         leakage_calc_step *=
543                                                 edp_pow(temp_C, k);
544                                         /* leakage_consts_ijk was X 100,000 */
545                                         leakage_calc_step =
546                                                 div64_s64(leakage_calc_step,
547                                                           100000);
548                                         leakage_mA += leakage_calc_step;
549                                 }
550                         }
551                 }
552                 leakage_mA *= params->leakage_consts_n[n_cores_idx];
553                 /* leakage_const_n was pre-multiplied by 1,000,000 */
554                 leakage_mA = div64_s64(leakage_mA, 1000000);
555
556                 /* Calculate dynamic current */
557                 dyn_mA = voltage_mV * freq_KHz / 1000;
558                 /* Convert mV to V */
559                 dyn_mA = div64_s64(dyn_mA, 1000);
560                 dyn_mA *= params->dyn_consts_n[n_cores_idx];
561                 /* dyn_const_n was pre-multiplied by 1,000,000 */
562                 dyn_mA = div64_s64(dyn_mA, 1000000);
563
564                 if (power_mW != -1) {
565                         leakage_mW = leakage_mA * voltage_mV;
566                         dyn_mW = dyn_mA * voltage_mV;
567                         if (div64_s64(leakage_mW + dyn_mW, 1000) <= power_mW)
568                                 return freq_KHz;
569                 } else if ((leakage_mA + dyn_mA) <= cur_effective) {
570                         return freq_KHz;
571                 }
572         }
573         return 0;
574 }
575
576 static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
577                         unsigned int cpu_speedo_idx,
578                         unsigned int freq_volt_lut_size,
579                         struct tegra_edp_freq_voltage_table *freq_volt_lut)
580 {
581         unsigned int i, j, freq;
582         int voltage_mV;
583
584         for (i = 0, j = 0, freq = 0;
585                  i < freq_volt_lut_size;
586                  i++, freq += FREQ_STEP) {
587
588                 /* Predict voltages */
589                 voltage_mV = tegra_dvfs_predict_millivolts(clk_cpu_g, freq);
590                 if (voltage_mV < 0) {
591                         pr_err("%s: couldn't predict voltage: freq %u; err %d",
592                                __func__, freq, voltage_mV);
593                         return -EINVAL;
594                 }
595
596                 /* Cache frequency / voltage / voltage constant relationship */
597                 freq_volt_lut[i].freq = freq;
598                 freq_volt_lut[i].voltage_mV = voltage_mV;
599         }
600         return 0;
601 }
602
603 unsigned int tegra_edp_find_maxf(int volt)
604 {
605         unsigned int i;
606
607         for (i = 0; i < freq_voltage_lut_size_saved; i++) {
608                 if (freq_voltage_lut_saved[i].voltage_mV > volt)
609                         break;
610         }
611         return freq_voltage_lut[i - 1].freq;
612 }
613
614
615 int edp_find_speedo_idx(int cpu_speedo_id, unsigned int *cpu_speedo_idx)
616 {
617         int i;
618
619         for (i = 0; i < ARRAY_SIZE(leakage_params); i++)
620                 if (cpu_speedo_id == leakage_params[i].cpu_speedo_id) {
621                         *cpu_speedo_idx = i;
622                         return 0;
623                 }
624
625         pr_err("%s: couldn't find cpu speedo id %d in freq/voltage LUT\n",
626                __func__, cpu_speedo_id);
627         return -EINVAL;
628 }
629
630 static int init_cpu_edp_limits_calculated(void)
631 {
632         unsigned int temp_idx, n_cores_idx, pwr_idx;
633         unsigned int cpu_g_minf, cpu_g_maxf;
634         unsigned int iddq_mA;
635         unsigned int cpu_speedo_idx;
636         unsigned int cap, limit;
637         struct tegra_edp_limits *edp_calculated_limits;
638         struct tegra_system_edp_entry *power_edp_calc_limits;
639         struct tegra_edp_cpu_leakage_params *params;
640         int ret;
641         struct clk *clk_cpu_g = tegra_get_clock_by_name("cpu_g");
642         int cpu_speedo_id = tegra_cpu_speedo_id();
643
644         /* Determine all inputs to EDP formula */
645         iddq_mA = tegra_get_cpu_iddq_value();
646         ret = edp_find_speedo_idx(cpu_speedo_id, &cpu_speedo_idx);
647         if (ret)
648                 return ret;
649
650         params = &leakage_params[cpu_speedo_idx];
651
652         edp_calculated_limits = kmalloc(sizeof(struct tegra_edp_limits)
653                                         * ARRAY_SIZE(temperatures), GFP_KERNEL);
654         BUG_ON(!edp_calculated_limits);
655
656         power_edp_calc_limits = kmalloc(sizeof(struct tegra_system_edp_entry)
657                                 * ARRAY_SIZE(power_cap_levels), GFP_KERNEL);
658         BUG_ON(!power_edp_calc_limits);
659
660         cpu_g_minf = 0;
661         cpu_g_maxf = clk_get_max_rate(clk_cpu_g);
662         freq_voltage_lut_size = (cpu_g_maxf - cpu_g_minf) / FREQ_STEP + 1;
663         freq_voltage_lut = kmalloc(sizeof(struct tegra_edp_freq_voltage_table)
664                                    * freq_voltage_lut_size, GFP_KERNEL);
665         if (!freq_voltage_lut) {
666                 pr_err("%s: failed alloc mem for freq/voltage LUT\n", __func__);
667                 kfree(power_edp_calc_limits);
668                 kfree(edp_calculated_limits);
669                 return -ENOMEM;
670         }
671
672         ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx,
673                                 freq_voltage_lut_size, freq_voltage_lut);
674         if (ret) {
675                 kfree(power_edp_calc_limits);
676                 kfree(edp_calculated_limits);
677                 kfree(freq_voltage_lut);
678                 return ret;
679         }
680
681         if (freq_voltage_lut_size != freq_voltage_lut_size_saved) {
682                 /* release previous table if present */
683                 kfree(freq_voltage_lut_saved);
684                 /* create table to save */
685                 freq_voltage_lut_saved =
686                         kmalloc(sizeof(struct tegra_edp_freq_voltage_table) *
687                         freq_voltage_lut_size, GFP_KERNEL);
688                 if (!freq_voltage_lut_saved) {
689                         pr_err("%s: failed alloc mem for freq/voltage LUT\n",
690                                 __func__);
691                         kfree(freq_voltage_lut);
692                         return -ENOMEM;
693                 }
694                 freq_voltage_lut_size_saved = freq_voltage_lut_size;
695         }
696         memcpy(freq_voltage_lut_saved,
697                 freq_voltage_lut,
698                 sizeof(struct tegra_edp_freq_voltage_table) *
699                         freq_voltage_lut_size);
700
701         /* Calculate EDP table */
702         for (n_cores_idx = 0; n_cores_idx < NR_CPUS; n_cores_idx++) {
703                 for (temp_idx = 0;
704                      temp_idx < ARRAY_SIZE(temperatures); temp_idx++) {
705                         edp_calculated_limits[temp_idx].temperature =
706                                 temperatures[temp_idx];
707                         limit = edp_calculate_maxf(params,
708                                                    temperatures[temp_idx],
709                                                    -1,
710                                                    iddq_mA,
711                                                    n_cores_idx);
712                         /* apply safety cap if it is specified */
713                         if (n_cores_idx < 4) {
714                                 cap = params->safety_cap[n_cores_idx];
715                                 if (cap && cap < limit)
716                                         limit = cap;
717                         }
718                         edp_calculated_limits[temp_idx].
719                                 freq_limits[n_cores_idx] = limit;
720                 }
721
722                 for (pwr_idx = 0;
723                      pwr_idx < ARRAY_SIZE(power_cap_levels); pwr_idx++) {
724                         power_edp_calc_limits[pwr_idx].power_limit_100mW =
725                                 power_cap_levels[pwr_idx] / 100;
726                         limit = edp_calculate_maxf(params,
727                                                    90,
728                                                    power_cap_levels[pwr_idx],
729                                                    iddq_mA,
730                                                    n_cores_idx);
731                         power_edp_calc_limits[pwr_idx].
732                                 freq_limits[n_cores_idx] = limit;
733                 }
734         }
735
736         /*
737          * If this is an EDP table update, need to overwrite old table.
738          * The old table's address must remain valid.
739          */
740         if (edp_limits != edp_default_limits) {
741                 memcpy(edp_limits, edp_calculated_limits,
742                        sizeof(struct tegra_edp_limits)
743                        * ARRAY_SIZE(temperatures));
744                 kfree(edp_calculated_limits);
745         }
746         else {
747                 edp_limits = edp_calculated_limits;
748                 edp_limits_size = ARRAY_SIZE(temperatures);
749         }
750
751         if (power_edp_limits != power_edp_default_limits) {
752                 memcpy(power_edp_limits, power_edp_calc_limits,
753                        sizeof(struct tegra_system_edp_entry)
754                        * ARRAY_SIZE(power_cap_levels));
755                 kfree(power_edp_calc_limits);
756         } else {
757                 power_edp_limits = power_edp_calc_limits;
758                 power_edp_limits_size = ARRAY_SIZE(power_cap_levels);
759         }
760
761         kfree(freq_voltage_lut);
762         return 0;
763 }
764
765 static int __init init_cpu_edp_limits_lookup(void)
766 {
767         int i, j;
768         struct tegra_edp_limits *e;
769         struct tegra_edp_vdd_cpu_entry *t;
770         int tsize;
771         int cpu_speedo_id = tegra_cpu_speedo_id();
772
773         t = (struct tegra_edp_vdd_cpu_entry *)tegra_edp_vdd_cpu_map;
774         tsize = sizeof(tegra_edp_vdd_cpu_map)
775                 / sizeof(struct tegra_edp_vdd_cpu_entry);
776
777         for (i = 0; i < tsize; i++) {
778                 if (t[i].speedo_id == cpu_speedo_id &&
779                     t[i].regulator_100mA <= regulator_cur / 100)
780                         break;
781         }
782
783         /* No entry found in tegra_edp_vdd_cpu_map */
784         if (i >= tsize)
785                 return -EINVAL;
786
787         /* Find all rows for this entry */
788         for (j = i + 1; j < tsize; j++) {
789                 if (t[i].speedo_id != t[j].speedo_id ||
790                     t[i].regulator_100mA != t[j].regulator_100mA)
791                         break;
792         }
793
794         edp_limits_size = j - i;
795         e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
796                     GFP_KERNEL);
797         BUG_ON(!e);
798
799         for (j = 0; j < edp_limits_size; j++) {
800                 e[j].temperature = (int)t[i+j].temperature;
801                 e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0]*10000;
802                 e[j].freq_limits[1] = (unsigned int)t[i+j].freq_limits[1]*10000;
803                 e[j].freq_limits[2] = (unsigned int)t[i+j].freq_limits[2]*10000;
804                 e[j].freq_limits[3] = (unsigned int)t[i+j].freq_limits[3]*10000;
805         }
806
807         if (edp_limits != edp_default_limits)
808                 kfree(edp_limits);
809
810         edp_limits = e;
811         return 0;
812 }
813
814 void tegra_recalculate_cpu_edp_limits(void)
815 {
816         if (tegra_chip_id == TEGRA_CHIPID_TEGRA11)
817                 init_cpu_edp_limits_calculated();
818 }
819
820 /*
821  * Specify regulator current in mA, e.g. 5000mA
822  * Use 0 for default
823  */
824 void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
825 {
826         if (!regulator_mA)
827                 goto end;
828         regulator_cur = regulator_mA + OVERRIDE_DEFAULT;
829
830         switch (tegra_chip_id) {
831         case TEGRA_CHIPID_TEGRA3:
832                 if (init_cpu_edp_limits_lookup() == 0)
833                         return;
834                 break;
835         case TEGRA_CHIPID_TEGRA11:
836         case TEGRA_CHIPID_TEGRA14:
837                 if (init_cpu_edp_limits_calculated() == 0)
838                         return;
839                 break;
840         case TEGRA_CHIPID_TEGRA2:
841         default:
842                 BUG();
843                 break;
844         }
845
846  end:
847         edp_limits = edp_default_limits;
848         edp_limits_size = ARRAY_SIZE(edp_default_limits);
849
850         power_edp_limits = power_edp_default_limits;
851         power_edp_limits_size = ARRAY_SIZE(power_edp_default_limits);
852 }
853
854 void __init tegra_init_system_edp_limits(unsigned int power_limit_mW)
855 {
856         int cpu_speedo_id = tegra_cpu_speedo_id();
857         int i;
858         unsigned int *e;
859         struct tegra_system_edp_entry *t = tegra_system_edp_map;
860         int tsize = ARRAY_SIZE(tegra_system_edp_map);
861
862         if (!power_limit_mW) {
863                 e = NULL;
864                 goto out;
865         }
866
867         for (i = 0; i < tsize; i++)
868                 if (t[i].speedo_id == cpu_speedo_id)
869                         break;
870
871         if (i >= tsize) {
872                 e = NULL;
873                 goto out;
874         }
875
876         do {
877                 if (t[i].power_limit_100mW <= power_limit_mW / 100)
878                         break;
879                 i++;
880         } while (i < tsize && t[i].speedo_id == cpu_speedo_id);
881
882         if (i >= tsize || t[i].speedo_id != cpu_speedo_id)
883                 i--; /* No low enough entry in the table, use best possible */
884
885         e = kmalloc(sizeof(unsigned int) * 4, GFP_KERNEL);
886         BUG_ON(!e);
887
888         e[0] = (unsigned int)t[i].freq_limits[0] * 10000;
889         e[1] = (unsigned int)t[i].freq_limits[1] * 10000;
890         e[2] = (unsigned int)t[i].freq_limits[2] * 10000;
891         e[3] = (unsigned int)t[i].freq_limits[3] * 10000;
892
893 out:
894         kfree(system_edp_limits);
895
896         system_edp_limits = e;
897 }
898
899
900 void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size)
901 {
902         *limits = edp_limits;
903         *size = edp_limits_size;
904 }
905
906 void tegra_get_system_edp_limits(const unsigned int **limits)
907 {
908         *limits = system_edp_limits;
909 }
910
911 void tegra_platform_edp_init(struct thermal_trip_info *trips,
912                                 int *num_trips, int margin)
913 {
914         const struct tegra_edp_limits *cpu_edp_limits;
915         struct thermal_trip_info *trip_state;
916         int i, cpu_edp_limits_size;
917
918         if (!trips || !num_trips)
919                 return;
920
921         /* edp capping */
922         tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size);
923
924         if (cpu_edp_limits_size > MAX_THROT_TABLE_SIZE)
925                 BUG();
926
927         for (i = 0; i < cpu_edp_limits_size-1; i++) {
928                 trip_state = &trips[*num_trips];
929
930                 trip_state->cdev_type = "cpu_edp";
931                 trip_state->trip_temp =
932                         (cpu_edp_limits[i].temperature * 1000) - margin;
933                 trip_state->trip_type = THERMAL_TRIP_ACTIVE;
934                 trip_state->upper = trip_state->lower = i + 1;
935                 trip_state->hysteresis = 1000;
936
937                 (*num_trips)++;
938
939                 if (*num_trips >= THERMAL_MAX_TRIPS)
940                         BUG();
941         }
942 }
943
944 struct tegra_system_edp_entry *tegra_get_system_edp_entries(int *size)
945 {
946         *size = power_edp_limits_size;
947         return power_edp_limits;
948 }
949
950 #ifdef CONFIG_DEBUG_FS
951
952 static int edp_limit_debugfs_show(struct seq_file *s, void *data)
953 {
954 #ifdef CONFIG_CPU_FREQ
955         seq_printf(s, "%u\n", tegra_get_edp_limit(NULL));
956 #endif
957         return 0;
958 }
959
960 static int edp_debugfs_show(struct seq_file *s, void *data)
961 {
962         int i, th_idx;
963
964 #ifdef CONFIG_CPU_FREQ
965         tegra_get_edp_limit(&th_idx);
966 #else
967         th_idx = 0;
968 #endif
969         seq_printf(s, "-- VDD_CPU %sEDP table (%umA = %umA - %umA) --\n",
970                    edp_limits == edp_default_limits ? "default " : "",
971                    regulator_cur - edp_reg_override_mA,
972                    regulator_cur, edp_reg_override_mA);
973         seq_printf(s, "%6s %10s %10s %10s %10s\n",
974                    " Temp.", "1-core", "2-cores", "3-cores", "4-cores");
975         for (i = 0; i < edp_limits_size; i++) {
976                 seq_printf(s, "%c%3dC: %10u %10u %10u %10u\n",
977                            i == th_idx ? '>' : ' ',
978                            edp_limits[i].temperature,
979                            edp_limits[i].freq_limits[0],
980                            edp_limits[i].freq_limits[1],
981                            edp_limits[i].freq_limits[2],
982                            edp_limits[i].freq_limits[3]);
983         }
984
985         seq_printf(s, "-- VDD_CPU Power EDP table --\n");
986         seq_printf(s, "%6s %10s %10s %10s %10s\n",
987                    " Power", "1-core", "2-cores", "3-cores", "4-cores");
988         for (i = 0; i < power_edp_limits_size; i++) {
989                 seq_printf(s, "%5dmW: %10u %10u %10u %10u\n",
990                            power_edp_limits[i].power_limit_100mW * 100,
991                            power_edp_limits[i].freq_limits[0],
992                            power_edp_limits[i].freq_limits[1],
993                            power_edp_limits[i].freq_limits[2],
994                            power_edp_limits[i].freq_limits[3]);
995         }
996
997         if (system_edp_limits) {
998                 seq_printf(s, "\n-- System EDP table --\n");
999                 seq_printf(s, "%10u %10u %10u %10u\n",
1000                            system_edp_limits[0],
1001                            system_edp_limits[1],
1002                            system_edp_limits[2],
1003                            system_edp_limits[3]);
1004         }
1005
1006         return 0;
1007 }
1008
1009 static int edp_reg_override_show(struct seq_file *s, void *data)
1010 {
1011         seq_printf(s, "Limit override: %u mA. Effective limit: %u mA\n",
1012                    edp_reg_override_mA, regulator_cur - edp_reg_override_mA);
1013         return 0;
1014 }
1015
1016 static int edp_reg_override_write(struct file *file,
1017         const char __user *userbuf, size_t count, loff_t *ppos)
1018 {
1019         char buf[32], *end;
1020         unsigned int edp_reg_override_mA_temp;
1021         unsigned int edp_reg_override_mA_prev = edp_reg_override_mA;
1022
1023         if (sizeof(buf) <= count)
1024                 goto override_err;
1025
1026         if (copy_from_user(buf, userbuf, count))
1027                 goto override_err;
1028
1029         /* terminate buffer and trim - white spaces may be appended
1030          *  at the end when invoked from shell command line */
1031         buf[count]='\0';
1032         strim(buf);
1033
1034         edp_reg_override_mA_temp = simple_strtoul(buf, &end, 10);
1035         if (*end != '\0')
1036                 goto override_err;
1037
1038         if (edp_reg_override_mA_temp >= regulator_cur)
1039                 goto override_err;
1040
1041         if (edp_reg_override_mA == edp_reg_override_mA_temp)
1042                 return count;
1043
1044         edp_reg_override_mA = edp_reg_override_mA_temp;
1045         if (init_cpu_edp_limits_calculated()) {
1046                 /* Revert to previous override value if new value fails */
1047                 edp_reg_override_mA = edp_reg_override_mA_prev;
1048                 goto override_err;
1049         }
1050
1051 #ifdef CONFIG_CPU_FREQ
1052         if (tegra_cpu_set_speed_cap(NULL)) {
1053                 pr_err("FAILED: Set CPU freq cap with new VDD_CPU EDP table\n");
1054                 goto override_out;
1055         }
1056
1057         pr_info("Reinitialized VDD_CPU EDP table with regulator current limit"
1058                         " %u mA\n", regulator_cur - edp_reg_override_mA);
1059 #else
1060         pr_err("FAILED: tegra_cpu_set_speed_cap() does not exist, failed to reinitialize VDD_CPU EDP table");
1061 #endif
1062
1063         return count;
1064
1065 override_err:
1066         pr_err("FAILED: Reinitialize VDD_CPU EDP table with override \"%s\"",
1067                buf);
1068 #ifdef CONFIG_CPU_FREQ
1069 override_out:
1070 #endif
1071         return -EINVAL;
1072 }
1073
1074 static int edp_debugfs_open(struct inode *inode, struct file *file)
1075 {
1076         return single_open(file, edp_debugfs_show, inode->i_private);
1077 }
1078
1079 static int edp_limit_debugfs_open(struct inode *inode, struct file *file)
1080 {
1081         return single_open(file, edp_limit_debugfs_show, inode->i_private);
1082 }
1083
1084 static int edp_reg_override_open(struct inode *inode, struct file *file)
1085 {
1086         return single_open(file, edp_reg_override_show, inode->i_private);
1087 }
1088
1089 static const struct file_operations edp_debugfs_fops = {
1090         .open           = edp_debugfs_open,
1091         .read           = seq_read,
1092         .llseek         = seq_lseek,
1093         .release        = single_release,
1094 };
1095
1096 static const struct file_operations edp_limit_debugfs_fops = {
1097         .open           = edp_limit_debugfs_open,
1098         .read           = seq_read,
1099         .llseek         = seq_lseek,
1100         .release        = single_release,
1101 };
1102
1103 static const struct file_operations edp_reg_override_debugfs_fops = {
1104         .open           = edp_reg_override_open,
1105         .read           = seq_read,
1106         .write          = edp_reg_override_write,
1107         .llseek         = seq_lseek,
1108         .release        = single_release,
1109 };
1110
1111 #ifdef CONFIG_EDP_FRAMEWORK
1112 static __init struct dentry *tegra_edp_debugfs_dir(void)
1113 {
1114         return edp_debugfs_dir;
1115 }
1116 #else
1117 static __init struct dentry *tegra_edp_debugfs_dir(void)
1118 {
1119         return debugfs_create_dir("edp", NULL);
1120 }
1121 #endif
1122
1123 static int __init tegra_edp_debugfs_init(void)
1124 {
1125         struct dentry *d_edp;
1126         struct dentry *d_edp_limit;
1127         struct dentry *d_edp_reg_override;
1128         struct dentry *edp_dir;
1129         struct dentry *vdd_cpu_dir;
1130
1131         edp_dir = tegra_edp_debugfs_dir();
1132
1133         if (!edp_dir)
1134                 goto edp_dir_err;
1135
1136         vdd_cpu_dir = debugfs_create_dir("vdd_cpu", edp_dir);
1137
1138         if (!vdd_cpu_dir)
1139                 goto vdd_cpu_dir_err;
1140
1141         d_edp = debugfs_create_file("edp", S_IRUGO, vdd_cpu_dir, NULL,
1142                                 &edp_debugfs_fops);
1143
1144         if (!d_edp)
1145                 goto edp_err;
1146
1147         d_edp_limit = debugfs_create_file("edp_limit", S_IRUGO, vdd_cpu_dir,
1148                                 NULL, &edp_limit_debugfs_fops);
1149
1150         if (!d_edp_limit)
1151                 goto edp_limit_err;
1152
1153         d_edp_reg_override = debugfs_create_file("edp_reg_override",
1154                                 S_IRUGO | S_IWUSR, vdd_cpu_dir, NULL,
1155                                 &edp_reg_override_debugfs_fops);
1156
1157         if (!d_edp_reg_override)
1158                 goto edp_reg_override_err;
1159
1160         if (tegra_core_edp_debugfs_init(edp_dir))
1161                 goto edp_reg_override_err;
1162
1163         return 0;
1164
1165 edp_reg_override_err:
1166         debugfs_remove(d_edp_limit);
1167 edp_limit_err:
1168         debugfs_remove(d_edp);
1169 edp_err:
1170         debugfs_remove(vdd_cpu_dir);
1171 vdd_cpu_dir_err:
1172         debugfs_remove(edp_dir);
1173 edp_dir_err:
1174         return -ENOMEM;
1175 }
1176
1177 late_initcall(tegra_edp_debugfs_init);
1178 #endif /* CONFIG_DEBUG_FS */