ARM: tegra11: power: Update T40X core edp tables
[linux-3.10.git] / arch / arm / mach-tegra / tegra11_edp.c
1 /*
2  * arch/arm/mach-tegra/tegra11_edp.c
3  *
4  * Copyright (c) 2012-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 "fuse.h"
31
32 #define CORE_MODULES_STATES 1
33 #define TEMPERATURE_RANGES 4
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         int process_id;
41         unsigned int cap_mA;
42         int mult;
43         unsigned long cap_scpu_on[CORE_EDP_PROFILES_NUM][
44                 CORE_MODULES_STATES][TEMPERATURE_RANGES][CAP_CLKS_NUM];
45         unsigned long cap_scpu_off[CORE_EDP_PROFILES_NUM][
46                 CORE_MODULES_STATES][TEMPERATURE_RANGES][CAP_CLKS_NUM];
47 };
48
49 static int temperatures[] = { 50, 70, 90, 105 };
50
51 #ifdef CONFIG_TEGRA_DUAL_CBUS
52 static char *cap_clks_names[] = { "edp.emc", "edp.c2bus" };
53 #else
54 static char *cap_clks_names[] = { "edp.emc", "edp.cbus" };
55 #endif
56 static struct clk *cap_clks[CAP_CLKS_NUM];
57
58 static struct core_edp_entry core_edp_table[] = {
59         /* SKU 3 */
60         {
61                 .sku            = 0x3,          /* SKU = 3 */
62                 .process_id     = -1,           /* any process id */
63                 .cap_mA         = 6000,         /* 6A cap */
64                 .mult           = 1000000,      /* MHZ */
65                 .cap_scpu_on    = {
66                         /* favor emc */
67                         {       /* core modules power state 0 (all ON) */
68                                 {{ 924, 636 },
69                                  { 924, 612 },
70                                  { 924, 564 },
71                                  { 924, 384 },
72                                 },
73                         },
74                         /* balanced profile */
75                         {       /* core modules power state 0 (all ON) */
76                                 {{ 792, 636 },
77                                  { 792, 636 },
78                                  { 792, 636 },
79                                  { 792, 384 },
80                                 },
81                         },
82                         /* favor gpu */
83                         {       /* core modules power state 0 (all ON) */
84                                 {{ 624, 672 },
85                                  { 624, 672 },
86                                  { 528, 672 },
87                                  { 528, 384 },
88                                 }
89                         },
90                 },
91                 .cap_scpu_off   = {
92                         /* favor emc */
93                         {       /* core modules power state 0 (all ON) */
94                                 {{ 924, 672 },
95                                  { 924, 648 },
96                                  { 924, 636 },
97                                  { 924, 516 },
98                                 },
99                         },
100                         /* balanced profile */
101                         {       /* core modules power state 0 (all ON) */
102                                 {{ 924, 672 },
103                                  { 792, 672 },
104                                  { 792, 672 },
105                                  { 792, 516 },
106                                 },
107                         },
108                         /* favor gpu */
109                         {       /* core modules power state 0 (all ON) */
110                                 {{ 924, 672 },
111                                  { 792, 672 },
112                                  { 792, 672 },
113                                  { 792, 516 },
114                                 }
115                         },
116                 },
117         },
118         {
119                 .sku            = 0x3,          /* SKU = 3 */
120                 .process_id     = -1,           /* any process id */
121                 .cap_mA         = 8000,         /* 8A cap */
122                 .mult           = 1000000,      /* MHZ */
123                 .cap_scpu_on    = {
124                         /* favor emc */
125                         {       /* core modules power state 0 (all ON) */
126                                 {{ 924, 672 },
127                                  { 924, 672 },
128                                  { 924, 672 },
129                                  { 924, 588 },
130                                 },
131                         },
132                         /* balanced profile */
133                         {       /* core modules power state 0 (all ON) */
134                                 {{ 924, 672 },
135                                  { 924, 672 },
136                                  { 924, 672 },
137                                  { 924, 588 },
138                                 },
139                         },
140                         /* favor gpu */
141                         {       /* core modules power state 0 (all ON) */
142                                 {{ 924, 672 },
143                                  { 924, 672 },
144                                  { 924, 672 },
145                                  { 924, 588 },
146                                 }
147                         },
148                 },
149                 .cap_scpu_off   = {
150                         /* favor emc */
151                         {       /* core modules power state 0 (all ON) */
152                                 {{ 924, 672 },
153                                  { 924, 672 },
154                                  { 924, 672 },
155                                  { 924, 588 },
156                                 },
157                         },
158                         /* balanced profile */
159                         {       /* core modules power state 0 (all ON) */
160                                 {{ 924, 672 },
161                                  { 924, 672 },
162                                  { 924, 672 },
163                                  { 924, 588 },
164                                 },
165                         },
166                         /* favor gpu */
167                         {       /* core modules power state 0 (all ON) */
168                                 {{ 924, 672 },
169                                  { 924, 672 },
170                                  { 924, 672 },
171                                  { 924, 588 },
172                                 }
173                         },
174                 },
175         },
176 };
177
178 #ifdef CONFIG_TEGRA_EDP_LIMITS
179 #define LEAKAGE_CONSTS_IJK_COMMON                                       \
180         {                                                               \
181                 /* i = 0 */                                             \
182                 { {   13919916,  -28721837,   7560552,  -570495, },     \
183                   {  -39991855,   87294629, -22972570,  1734058, },     \
184                   {   36869935,  -86826110,  22833611, -1723750, },     \
185                   {  -10611796,   28192235,  -7407903,   559012, },     \
186                 },                                                      \
187                 /* i = 1 */                                             \
188                 { {  -37335213,   53397584, -16025243,  1341064, },     \
189                   {  111121782, -160756323,  48421377, -4049609, },     \
190                   { -107149149,  157911131, -47786861,  3994796, },     \
191                   {   32802647,  -49872380,  15236453, -1268662, },     \
192                 },                                                      \
193                 /* i = 2 */                                             \
194                 { {    3315214,  -21010655,   7718286,  -789185, },     \
195                   {   -4336249,   59786076, -22312653,  2313754, },     \
196                   {   -3346058,  -54529998,  20777469, -2198700, },     \
197                   {    4810027,   15417133,  -6086955,   665766, },     \
198                 },                                                      \
199                 /* i = 3 */                                             \
200                 { {    4681958,   -1470999,   -232691,    73384, },     \
201                   {  -15445149,    5487248,    422447,  -201475, },     \
202                   {   16983482,   -6716242,    -65917,   174128, },     \
203                   {   -6293336,    2756799,   -140100,   -44673, },     \
204                 },                                                      \
205         }
206
207 #define LEAKAGE_PARAMS_COMMON_PART                                      \
208         .temp_scaled        = 10,                                       \
209         .dyn_scaled         = 1000000,                                  \
210         .dyn_consts_n       = { 1410000, 2440000, 3450000, 4440000 },   \
211         .consts_scaled      = 1000000,                                  \
212         .leakage_consts_n   = {  400000,  650000,  850000, 1050000 },   \
213         .ijk_scaled         = 10000,                                    \
214         .leakage_min        = 30,                                       \
215         .volt_temp_cap      = { 70, 1300 },                             \
216         .leakage_consts_ijk = LEAKAGE_CONSTS_IJK_COMMON
217
218 static struct tegra_edp_cpu_leakage_params t11x_leakage_params[] = {
219         {
220                 .cpu_speedo_id      = 0, /* A01 CPU */
221                 .max_current_cap = { /* values are from tegra4 datasheet */
222                         { .max_cur = 9000, .max_temp = 60,
223                                 { 1900000, 1900000, 1600000, 1600000 }
224                         },
225                         { .max_cur = 9000, .max_temp = 75,
226                                 { 1900000, 1900000, 1530000, 1530000 }
227                         },
228                         { .max_cur = 9000, .max_temp = 90,
229                                 { 1900000, 1900000, 1500000, 1500000 }
230                         },
231                         { .max_cur = 12000, .max_temp = 90,
232                                 { 1900000, 1900000, 1700000, 1700000 }
233                         },
234                         { .max_cur = 15000, .max_temp = 90,
235                                 { 1900000, 1900000, 1900000, 1900000 }
236                         },
237                 },
238                 LEAKAGE_PARAMS_COMMON_PART,
239         },
240         {
241                 .cpu_speedo_id      = 1, /* A01P+ CPU */
242                 .safety_cap         = { 1810500, 1810500, 1606500, 1606500 },
243                 .max_current_cap = { /* values are from tegra4 datasheet */
244                         { .max_cur = 7500, .max_temp = 90,
245                                 { 1800000, 1700000, 1320000, 1320000 }
246                         },
247                         { .max_cur = 7500, .max_temp = 75,
248                                 { 1800000, 1700000, 1420000, 1420000 }
249                         },
250                         { .max_cur = 7500, .max_temp = 60,
251                                 { 1800000, 1800000, 1420000, 1420000 }
252                         },
253                         { .max_cur = 7500, .max_temp = 45,
254                                 { 1800000, 1800000, 1530000, 1530000 }
255                         },
256                         { .max_cur = 9000, .max_temp = 90,
257                                 { 1800000, 1800000, 1500000, 1500000 }
258                         },
259                         { .max_cur = 9000, .max_temp = 75,
260                                 { 1800000, 1800000, 1530000, 1530000 }
261                         },
262                         { .max_cur = 9000, .max_temp = 60,
263                                 { 1800000, 1800000, 1600000, 1600000 }
264                         },
265                         { .max_cur = 12000, .max_temp = 45,
266                                 { 1800000, 1800000, 1600000, 1600000 }
267                         },
268                 },
269                 LEAKAGE_PARAMS_COMMON_PART,
270         },
271         {
272                 .cpu_speedo_id      = 2, /* A01P+ fast CPU */
273                 .safety_cap         = { 1912500, 1912500, 1912500, 1912500 },
274                 .max_current_cap = { /* values are from tegra4 datasheet */
275                         { .max_cur = 9000, .max_temp = 90,
276                                 { 1900000, 1900000, 1500000, 1500000 }
277                         },
278                         { .max_cur = 9000, .max_temp = 75,
279                                 { 1900000, 1900000, 1530000, 1530000 }
280                         },
281                         { .max_cur = 9000, .max_temp = 60,
282                                 { 1900000, 1900000, 1600000, 1600000 }
283                         },
284                         { .max_cur = 12000, .max_temp = 90,
285                                 { 1900000, 1900000, 1700000, 1700000 }
286                         },
287                         { .max_cur = 15000, .max_temp = 90,
288                                 { 1900000, 1900000, 1900000, 1900000 }
289                         },
290                 },
291                 LEAKAGE_PARAMS_COMMON_PART,
292         },
293 };
294
295 struct tegra_edp_cpu_leakage_params *tegra11x_get_leakage_params(int index,
296                                                         unsigned int *sz)
297 {
298         BUG_ON(index >= ARRAY_SIZE(t11x_leakage_params));
299         if (sz)
300                 *sz = ARRAY_SIZE(t11x_leakage_params);
301         return &t11x_leakage_params[index];
302 }
303 #endif
304
305 static struct core_edp_entry *find_edp_entry(int sku, unsigned int regulator_mA)
306 {
307         int i;
308         int pid = tegra_core_process_id();
309
310         for (i = 0; i < ARRAY_SIZE(core_edp_table); i++) {
311                 struct core_edp_entry *entry = &core_edp_table[i];
312                 if ((entry->sku == sku) && (entry->cap_mA == regulator_mA) &&
313                     ((entry->process_id == -1) || (entry->process_id == pid)))
314                         return entry;
315         }
316         return NULL;
317 }
318
319 static unsigned long clip_cap_rate(struct clk *cap_clk, unsigned long rate)
320 {
321         unsigned long floor, ceiling;
322         struct clk *p = clk_get_parent(cap_clk);
323
324         if (!p || !p->ops || !p->ops->shared_bus_update) {
325                 WARN(1, "%s: edp cap clk %s is not a shared bus user\n",
326                         __func__, cap_clk->name);
327                 return rate;
328         }
329
330         /*
331          * Clip cap rate to shared bus possible rates (going up via shared
332          * bus * ladder since bus clocks always rounds up with resolution of
333          * at least 2kHz)
334          */
335         ceiling = clk_round_rate(p, clk_get_min_rate(p));
336         do {
337                 floor = ceiling;
338                 ceiling = clk_round_rate(p, floor + 2000);
339                 if (IS_ERR_VALUE(ceiling)) {
340                         pr_err("%s: failed to clip %lu to %s possible rates\n",
341                                __func__, rate, p->name);
342                         return rate;
343                 }
344         } while ((floor < ceiling) && (ceiling <= rate));
345
346         if (floor > rate)
347                 WARN(1, "%s: %s cap rate %lu is below %s floor %lu\n",
348                         __func__, cap_clk->name, rate, p->name, floor);
349         return floor;
350 }
351
352 int __init tegra11x_select_core_edp_table(unsigned int regulator_mA,
353                                           struct tegra_core_edp_limits *limits)
354 {
355         int i;
356         int sku = tegra_sku_id;
357         unsigned long *cap_rates;
358         struct core_edp_entry *edp_entry;
359
360         BUG_ON(ARRAY_SIZE(temperatures) != TEMPERATURE_RANGES);
361         BUG_ON(ARRAY_SIZE(cap_clks_names) != CAP_CLKS_NUM);
362         for (i = 0; i < CAP_CLKS_NUM; i++) {
363                 struct clk *c = tegra_get_clock_by_name(cap_clks_names[i]);
364                 if (!c) {
365                         pr_err("%s: failed to find edp cap clock %s\n",
366                                __func__, cap_clks_names[i]);
367                         return -ENODEV;
368                 }
369                 cap_clks[i] = c;
370         }
371
372         edp_entry = find_edp_entry(sku, regulator_mA);
373         if (!edp_entry) {
374                 pr_info("%s: no core edp table for sku %d, %d mA\n",
375                        __func__, sku, regulator_mA);
376                 return -ENODATA;
377         }
378
379         limits->sku = sku;
380         limits->cap_clocks = cap_clks;
381         limits->cap_clocks_num = CAP_CLKS_NUM;
382         limits->temperatures = temperatures;
383         limits->temperature_ranges = TEMPERATURE_RANGES;
384         limits->core_modules_states = CORE_MODULES_STATES;
385
386         cap_rates = &edp_entry->cap_scpu_on[0][0][0][0];
387         limits->cap_rates_scpu_on = cap_rates;
388         for (i = 0; i < TOTAL_CAPS; i++, cap_rates++) {
389                 unsigned long rate = *cap_rates * edp_entry->mult;
390                 *cap_rates = clip_cap_rate(cap_clks[i % CAP_CLKS_NUM], rate);
391         }
392
393         cap_rates = &edp_entry->cap_scpu_off[0][0][0][0];
394         limits->cap_rates_scpu_off = cap_rates;
395         for (i = 0; i < TOTAL_CAPS; i++, cap_rates++) {
396                 unsigned long rate = *cap_rates * edp_entry->mult;
397                 *cap_rates = clip_cap_rate(cap_clks[i % CAP_CLKS_NUM], rate);
398         }
399
400         return 0;
401 }