ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / tegra14_edp.c
1 /*
2  * arch/arm/mach-tegra/tegra14_edp.c
3  *
4  * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/string.h>
22 #include <linux/module.h>
23 #include <linux/clk.h>
24 #include <linux/kobject.h>
25 #include <linux/err.h>
26
27 #include <mach/edp.h>
28
29 #include "clock.h"
30 #include "common.h"
31
32 #define CORE_MODULES_STATES 1
33 #define TEMPERATURE_RANGES 5
34 #define CAP_CLKS_NUM 2
35 #define TOTAL_CAPS (CORE_EDP_PROFILES_NUM * CORE_MODULES_STATES *\
36                         TEMPERATURE_RANGES * CAP_CLKS_NUM)
37
38 struct core_edp_entry {
39         int sku;
40         unsigned int cap_mA;
41         int mult;
42         unsigned long cap_cpu[CORE_EDP_PROFILES_NUM][
43                 CORE_MODULES_STATES][TEMPERATURE_RANGES][CAP_CLKS_NUM];
44 };
45
46 static int temperatures[] = { 50, 70, 80, 90, 100 };
47
48 #ifdef CONFIG_TEGRA_DUAL_CBUS
49 static char *cap_clks_names[] = { "edp.emc", "edp.c2bus" };
50 #else
51 static char *cap_clks_names[] = { "edp.emc", "edp.cbus" };
52 #endif
53 static struct clk *cap_clks[CAP_CLKS_NUM];
54
55 /* FIXME: Populate with correct values as per final EDP tables.
56  * Currently contains *safe* values
57  */
58 static struct core_edp_entry core_edp_table[] = {
59         {
60                 .sku            = 0x7,
61                 .cap_mA         = 3000,         /* 3A cap */
62                 .mult           = 1000000,      /* MHZ */
63                 .cap_cpu        = {
64                         /* favor emc */
65                         {       /* core modules power state 0 (all ON) */
66                                 {{ 921, 655 },
67                                  { 921, 596 },
68                                  { 921, 596 },
69                                  { 921, 596 },
70                                  { 921, 557 },
71                                 },
72                         },
73                         /* balanced profile */
74                         {       /* core modules power state 0 (all ON) */
75                                 {{ 921, 655 },
76                                  { 921, 596 },
77                                  { 921, 596 },
78                                  { 921, 596 },
79                                  { 788, 596 },
80                                 },
81                         },
82                         /* favor gpu */
83                         {       /* core modules power state 0 (all ON) */
84                                 {{ 921, 655 },
85                                  { 788, 655 },
86                                  { 921, 596 },
87                                  { 921, 596 },
88                                  { 788, 596 },
89                                 }
90                         },
91                 },
92         },
93         {
94                 .sku            = 0x3,
95                 .cap_mA         = 3000,         /* 3A cap */
96                 .mult           = 1000000,      /* MHZ */
97                 .cap_cpu        = {
98                         /* favor emc */
99                         {       /* core modules power state 0 (all ON) */
100                                 {{ 921, 672 },
101                                  { 921, 596 },
102                                  { 921, 596 },
103                                  { 921, 596 },
104                                  { 921, 557 },
105                                 },
106                         },
107                         /* balanced profile */
108                         {       /* core modules power state 0 (all ON) */
109                                 {{ 921, 672 },
110                                  { 788, 672 },
111                                  { 921, 596 },
112                                  { 921, 596 },
113                                  { 788, 596 },
114                                 },
115                         },
116                         /* favor gpu */
117                         {       /* core modules power state 0 (all ON) */
118                                 {{ 921, 672 },
119                                  { 788, 672 },
120                                  { 921, 596 },
121                                  { 921, 596 },
122                                  { 788, 596 },
123                                 }
124                         },
125                 },
126         },
127         {
128                 .sku            = 0x3,          /* SL460 */
129                 .cap_mA         = 3500,         /* 3.5A cap */
130                 .mult           = 1000000,      /* MHZ */
131                 .cap_cpu        = {
132                         /* favor emc */
133                         {       /* core modules power state 0 (all ON) */
134                                 {{ 921, 711 },
135                                  { 921, 711 },
136                                  { 921, 711 },
137                                  { 921, 672 },
138                                  { 921, 672 },
139                                 },
140                         },
141                         /* balanced profile */
142                         {       /* core modules power state 0 (all ON) */
143                                 {{ 788, 749 },
144                                  { 921, 711 },
145                                  { 921, 711 },
146                                  { 921, 672 },
147                                  { 921, 672 },
148                                 },
149                         },
150                         /* favor gpu */
151                         {       /* core modules power state 0 (all ON) */
152                                 {{ 788, 749 },
153                                  { 921, 711 },
154                                  { 921, 711 },
155                                  { 921, 672 },
156                                  { 921, 672 },
157                                 }
158                         },
159                 },
160         },
161         {
162                 .sku            = 0x3,          /* SL460 */
163                 .cap_mA         = 4000,         /* 4A cap */
164                 .mult           = 1000000,      /* MHZ */
165                 .cap_cpu        = {
166                         /* favor emc */
167                         {       /* core modules power state 0 (all ON) */
168                                 {{ 921, 749 },
169                                  { 921, 749 },
170                                  { 921, 711 },
171                                  { 921, 672 },
172                                  { 921, 672 },
173                                 },
174                         },
175                         /* balanced profile */
176                         {       /* core modules power state 0 (all ON) */
177                                 {{ 921, 749 },
178                                  { 921, 749 },
179                                  { 921, 711 },
180                                  { 921, 672 },
181                                  { 921, 672 },
182                                 },
183                         },
184                         /* favor gpu */
185                         {       /* core modules power state 0 (all ON) */
186                                 {{ 921, 749 },
187                                  { 921, 749 },
188                                  { 921, 711 },
189                                  { 921, 672 },
190                                  { 921, 672 },
191                                 }
192                         },
193                 },
194         }
195 };
196
197 #ifdef CONFIG_TEGRA_EDP_LIMITS
198 #define LEAKAGE_CONSTS_IJK_COMMON                                       \
199         {                                                               \
200                 /* i = 0 */                                             \
201                 { {    564982,  -1353469,    309283,    -20862, },      \
202                   {  -1866916,   4500931,  -1026666,     68669, },      \
203                   {   1965934,  -4869757,   1107682,    -73554, },      \
204                   {   -637854,   1715497,   -388916,     25621, },      \
205                 },                                                      \
206                 /* i = 1 */                                             \
207                 { {  -7341396,   7706464,  -1729662,    114105, },      \
208                   {  24249928, -25178676,   5651247,   -370322, },      \
209                   { -26109261,  26794485,  -6018513,    392722, },      \
210                   {   9127986,  -9288224,   2091707,   -135487, },      \
211                 },                                                      \
212                 /* i = 2 */                                             \
213                 { {   9830061,  -9444047,   2035950,   -132842, },      \
214                   { -31837469,  30412491,  -6571344,    428173, },      \
215                   {  33645736, -31974811,   6933186,   -452148, },      \
216                   { -11561204,  11000249,  -2395570,    156270, },      \
217                 },                                                      \
218                 /* i = 3 */                                             \
219                 { {  -2848862,   2437747,   -500201,     31386, },      \
220                   {   9160903,  -7785587,   1605160,   -100724, },      \
221                   {  -9619266,   8124245,  -1686232,    106069, },      \
222                   {   3291191,  -2777151,    581139,    -36610, },      \
223                 },                                                      \
224         }
225
226 #define LEAKAGE_PARAMS_COMMON_PART                                      \
227         .temp_scaled        = 10,                                       \
228         .dyn_scaled         = 1000000,                                  \
229         .dyn_consts_n       = {  376000,  638000,  916000, 1203000 },   \
230         .consts_scaled      = 1000000,                                  \
231         .leakage_consts_n   = {  489500,  730600,  867600, 1000000 },   \
232         .ijk_scaled         = 1000,                                     \
233         .leakage_min        = 30,                                       \
234         .volt_temp_cap      = { 80, 1200 },                             \
235         .leakage_consts_ijk = LEAKAGE_CONSTS_IJK_COMMON
236
237 static struct tegra_edp_cpu_leakage_params t14x_leakage_params[] = {
238         {
239                 .cpu_speedo_id      = 0, /* A01 CPU */
240                 LEAKAGE_PARAMS_COMMON_PART,
241         },
242         {
243                 .cpu_speedo_id      = 1, /* SKU 0x3 CPU */
244                 LEAKAGE_PARAMS_COMMON_PART,
245         },
246 };
247
248 struct tegra_edp_cpu_leakage_params *tegra14x_get_leakage_params(int index,
249                                                         unsigned int *sz)
250 {
251         BUG_ON(index >= ARRAY_SIZE(t14x_leakage_params));
252         if (sz)
253                 *sz = ARRAY_SIZE(t14x_leakage_params);
254         return &t14x_leakage_params[index];
255 }
256 #endif
257
258 static struct core_edp_entry *find_edp_entry(int sku, unsigned int regulator_mA)
259 {
260         int i;
261
262         for (i = 0; i < ARRAY_SIZE(core_edp_table); i++) {
263                 struct core_edp_entry *entry = &core_edp_table[i];
264                 if ((entry->sku == sku) && (entry->cap_mA == regulator_mA))
265                         return entry;
266         }
267         return NULL;
268 }
269
270 static unsigned long clip_cap_rate(struct clk *cap_clk, unsigned long rate)
271 {
272         unsigned long floor, ceiling;
273         struct clk *p = clk_get_parent(cap_clk);
274
275         if (!p || !p->ops || !p->ops->shared_bus_update) {
276                 WARN(1, "%s: edp cap clk %s is not a shared bus user\n",
277                         __func__, cap_clk->name);
278                 return rate;
279         }
280
281         /*
282          * Clip cap rate to shared bus possible rates (going up via shared
283          * bus * ladder since bus clocks always rounds up with resolution of
284          * at least 2kHz)
285          */
286         ceiling = clk_round_rate(p, clk_get_min_rate(p));
287         do {
288                 floor = ceiling;
289                 ceiling = clk_round_rate(p, floor + 2000);
290                 if (IS_ERR_VALUE(ceiling)) {
291                         pr_err("%s: failed to clip %lu to %s possible rates\n",
292                                __func__, rate, p->name);
293                         return rate;
294                 }
295         } while ((floor < ceiling) && (ceiling <= rate));
296
297         if (floor > rate)
298                 WARN(1, "%s: %s cap rate %lu is below %s floor %lu\n",
299                         __func__, cap_clk->name, rate, p->name, floor);
300         return floor;
301 }
302
303 int __init tegra14x_select_core_edp_table(unsigned int regulator_mA,
304                                           struct tegra_core_edp_limits *limits)
305 {
306         int i;
307         int sku;
308         unsigned long *cap_rates;
309         struct core_edp_entry *edp_entry;
310
311         BUG_ON(ARRAY_SIZE(temperatures) != TEMPERATURE_RANGES);
312         BUG_ON(ARRAY_SIZE(cap_clks_names) != CAP_CLKS_NUM);
313
314         for (i = 0; i < CAP_CLKS_NUM; i++) {
315                 struct clk *c = tegra_get_clock_by_name(cap_clks_names[i]);
316                 if (!c) {
317                         pr_err("%s: failed to find edp cap clock %s\n",
318                                __func__, cap_clks_names[i]);
319                         return -ENODEV;
320                 }
321                 cap_clks[i] = c;
322         }
323
324         sku = tegra_get_sku_id();
325         if (sku == 0x0)
326                 sku = 0x7;
327
328         if ((sku == 0x7) && (regulator_mA >= 3500)) {
329                 pr_info("%s: no core edp capping for sku %d, %d mA\n",
330                        __func__, sku, regulator_mA);
331                 return -ENODATA;
332         }
333
334         edp_entry = find_edp_entry(sku, regulator_mA);
335         if (!edp_entry) {
336                 pr_info("%s: no core edp table for sku %d, %d mA\n",
337                        __func__, sku, regulator_mA);
338                 return -ENODATA;
339         }
340
341         limits->sku = sku;
342         limits->cap_clocks = cap_clks;
343         limits->cap_clocks_num = CAP_CLKS_NUM;
344         limits->temperatures = temperatures;
345         limits->temperature_ranges = TEMPERATURE_RANGES;
346         limits->core_modules_states = CORE_MODULES_STATES;
347
348         cap_rates = &edp_entry->cap_cpu[0][0][0][0];
349         limits->cap_rates_scpu_on = cap_rates;
350         limits->cap_rates_scpu_off = cap_rates;
351         for (i = 0; i < TOTAL_CAPS; i++, cap_rates++) {
352                 unsigned long rate = *cap_rates * edp_entry->mult;
353                 *cap_rates = clip_cap_rate(cap_clks[i % CAP_CLKS_NUM], rate);
354         }
355
356         return 0;
357 }