ARM: tegra: powermon: Fix copyrights from GPLv3 to GPLv2
[linux-3.10.git] / arch / arm / mach-tegra / latency_allowance.c
1 /*
2  * arch/arm/mach-tegra/latency_allowance.c
3  *
4  * Copyright (C) 2011-2013, NVIDIA CORPORATION. All rights reserved.
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
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  */
16
17 #include <linux/types.h>
18 #include <linux/init.h>
19 #include <linux/kernel.h>
20 #include <linux/debugfs.h>
21 #include <linux/moduleparam.h>
22 #include <linux/seq_file.h>
23 #include <linux/err.h>
24 #include <linux/spinlock_types.h>
25 #include <linux/spinlock.h>
26 #include <linux/stringify.h>
27 #include <linux/clk.h>
28 #include <linux/syscore_ops.h>
29 #include <asm/bug.h>
30 #include <asm/io.h>
31 #include <asm/string.h>
32 #include <mach/hardware.h>
33 #include <mach/clk.h>
34 #include <mach/latency_allowance.h>
35 #include "la_priv.h"
36
37 #define TEST_LA_CODE            0
38
39 /* Bug 995270 */
40 #define HACK_LA_FIFO 1
41 static int default_set_la(enum tegra_la_id id, unsigned int bw_mbps);
42
43 static struct la_chip_specific cs;
44 module_param_named(disable_la, cs.disable_la, bool, 0644);
45 module_param_named(disable_ptsa, cs.disable_ptsa, bool, 0644);
46
47 static void init_chip_specific(void)
48 {
49         enum tegra_chipid cid;
50
51         if (!tegra_platform_is_silicon())
52                 return;
53
54         cs.set_la = default_set_la;
55         memset(&cs.id_to_index[0], 0xFF, sizeof(cs.id_to_index));
56         spin_lock_init(&cs.lock);
57
58         cid = tegra_get_chipid();
59
60         switch (cid) {
61         case TEGRA_CHIPID_TEGRA3:
62                 tegra_la_get_t3_specific(&cs);
63                 break;
64         case TEGRA_CHIPID_TEGRA11:
65                 tegra_la_get_t11x_specific(&cs);
66                 break;
67         case TEGRA_CHIPID_TEGRA14:
68                 tegra_la_get_t14x_specific(&cs);
69                 break;
70         default:
71                 cs.set_la = NULL;
72         }
73 }
74
75 static void set_la(struct la_client_info *ci, int la)
76 {
77         unsigned long reg_read;
78         unsigned long reg_write;
79         int idx = cs.id_to_index[ci->id];
80
81         spin_lock(&cs.lock);
82         reg_read = readl(ci->reg_addr);
83         reg_write = (reg_read & ~ci->mask) |
84                         (la << ci->shift);
85         writel(reg_write, ci->reg_addr);
86         cs.scaling_info[idx].la_set = la;
87         ci->la_set = la;
88         la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
89                 (u32)ci->reg_addr, (u32)reg_read, (u32)reg_write);
90         spin_unlock(&cs.lock);
91 }
92
93 static int default_set_la(enum tegra_la_id id, unsigned int bw_mbps)
94 {
95         int ideal_la;
96         int la_to_set;
97         unsigned int fifo_size_in_atoms;
98         int bytes_per_atom = cs.atom_size;
99         const int fifo_scale = 4;               /* 25% of the FIFO */
100         struct la_client_info *ci;
101         int idx = cs.id_to_index[id];
102
103         if (!tegra_platform_is_silicon())
104                 return 0;
105
106         VALIDATE_ID(id, &cs);
107         VALIDATE_BW(bw_mbps);
108
109         ci = &cs.la_info_array[idx];
110         fifo_size_in_atoms = ci->fifo_size_in_atoms;
111
112 #ifdef CONFIG_TEGRA_MC_PTSA
113         if (id >= TEGRA_LA_DISPLAY_0A && id <= TEGRA_LA_DISPLAY_HCB) {
114                 cs.disp_bw_array[id - TEGRA_LA_DISPLAY_0A] = bw_mbps;
115                 if (cs.update_display_ptsa_rate)
116                         cs.update_display_ptsa_rate(cs.disp_bw_array);
117         }
118 #endif
119 #if HACK_LA_FIFO
120         /* pretend that our FIFO is only as deep as the lowest fullness
121          * we expect to see */
122         if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_HCB))
123                 fifo_size_in_atoms /= fifo_scale;
124 #endif
125
126         if (bw_mbps == 0) {
127                 la_to_set = cs.la_max_value;
128         } else {
129                 ideal_la = (fifo_size_in_atoms * bytes_per_atom * 1000) /
130                            (bw_mbps * cs.ns_per_tick);
131                 la_to_set = ideal_la -
132                             (ci->expiration_in_ns / cs.ns_per_tick) - 1;
133         }
134
135         la_debug("\n%s:id=%d,idx=%d, bw=%dmbps, la_to_set=%d",
136                 __func__, id, idx, bw_mbps, la_to_set);
137         la_to_set = (la_to_set < 0) ? 0 : la_to_set;
138         cs.scaling_info[idx].actual_la_to_set = la_to_set;
139         la_to_set = (la_to_set > cs.la_max_value) ? cs.la_max_value : la_to_set;
140
141         set_la(ci, la_to_set);
142         return 0;
143 }
144
145 /* Sets latency allowance based on clients memory bandwitdh requirement.
146  * Bandwidth passed is in mega bytes per second.
147  */
148 int tegra_set_latency_allowance(enum tegra_la_id id, unsigned int bw_mbps)
149 {
150         if (cs.set_la)
151                 return cs.set_la(id, bw_mbps);
152         return 0;
153 }
154
155 /* Thresholds for scaling are specified in % of fifo freeness.
156  * If threshold_low is specified as 20%, it means when the fifo free
157  * between 0 to 20%, use la as programmed_la.
158  * If threshold_mid is specified as 50%, it means when the fifo free
159  * between 20 to 50%, use la as programmed_la/2 .
160  * If threshold_high is specified as 80%, it means when the fifo free
161  * between 50 to 80%, use la as programmed_la/4.
162  * When the fifo is free between 80 to 100%, use la as 0(highest priority).
163  */
164 int tegra_enable_latency_scaling(enum tegra_la_id id,
165                                     unsigned int threshold_low,
166                                     unsigned int threshold_mid,
167                                     unsigned int threshold_high)
168 {
169         if (cs.enable_la_scaling)
170                 return cs.enable_la_scaling(id, threshold_low,
171                         threshold_mid, threshold_high);
172         return 0;
173 }
174
175 void tegra_disable_latency_scaling(enum tegra_la_id id)
176 {
177         if (cs.disable_la_scaling) {
178                 cs.disable_la_scaling(id);
179         }
180 }
181
182 void tegra_latency_allowance_update_tick_length(unsigned int new_ns_per_tick)
183 {
184         int i = 0;
185         int la;
186         unsigned long reg_read;
187         unsigned long reg_write;
188         unsigned long scale_factor = new_ns_per_tick / cs.ns_per_tick;
189
190         if (scale_factor > 1) {
191                 spin_lock(&cs.lock);
192                 cs.ns_per_tick = new_ns_per_tick;
193                 for (i = 0; i < cs.la_info_array_size - 1; i++) {
194                         reg_read = readl(cs.la_info_array[i].reg_addr);
195                         la = ((reg_read & cs.la_info_array[i].mask) >>
196                                 cs.la_info_array[i].shift) / scale_factor;
197
198                         reg_write = (reg_read & ~cs.la_info_array[i].mask) |
199                                         (la << cs.la_info_array[i].shift);
200                         writel(reg_write, cs.la_info_array[i].reg_addr);
201                         cs.scaling_info[i].la_set = la;
202                 }
203                 spin_unlock(&cs.lock);
204
205 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
206                 /* Re-scale G2PR, G2SR, G2DR, G2DW with updated ns_per_tick */
207                 tegra_set_latency_allowance(TEGRA_LA_G2PR, 20);
208                 tegra_set_latency_allowance(TEGRA_LA_G2SR, 20);
209                 tegra_set_latency_allowance(TEGRA_LA_G2DR, 20);
210                 tegra_set_latency_allowance(TEGRA_LA_G2DW, 20);
211 #endif
212         }
213 }
214
215 static int la_regs_show(struct seq_file *s, void *unused)
216 {
217         int i;
218         unsigned long la;
219
220         /* iterate the list, but don't print MAX_ID */
221         for (i = 0; i < cs.la_info_array_size - 1; i++) {
222                 la = (readl(cs.la_info_array[i].reg_addr) &
223                         cs.la_info_array[i].mask) >> cs.la_info_array[i].shift;
224                 seq_printf(s, "%-16s: %4lu\n", cs.la_info_array[i].name, la);
225         }
226
227         return 0;
228 }
229
230 static int dbg_la_regs_open(struct inode *inode, struct file *file)
231 {
232         return single_open(file, la_regs_show, inode->i_private);
233 }
234
235 static const struct file_operations regs_fops = {
236         .open           = dbg_la_regs_open,
237         .read           = seq_read,
238         .llseek         = seq_lseek,
239         .release        = single_release,
240 };
241
242 static int __init tegra_latency_allowance_debugfs_init(void)
243 {
244         if (cs.latency_debug_dir)
245                 return 0;
246
247         cs.latency_debug_dir = debugfs_create_dir("tegra_latency", NULL);
248
249         debugfs_create_file("la_info", S_IRUGO, cs.latency_debug_dir, NULL,
250                 &regs_fops);
251
252         return 0;
253 }
254
255 static int tegra_la_suspend(void)
256 {
257         if (cs.suspend)
258                 return cs.suspend();
259         return 0;
260 }
261
262 static void tegra_la_resume(void)
263 {
264         int i;
265
266         if (cs.resume) {
267                 cs.resume();
268                 return;
269         }
270         for (i = 0; i < cs.la_info_array_size; i++) {
271                 if (cs.la_info_array[i].la_set)
272                         set_la(&cs.la_info_array[i],
273                                 cs.la_info_array[i].la_set);
274         }
275         if (cs.init_ptsa)
276                 cs.init_ptsa();
277 }
278
279 static struct syscore_ops tegra_la_syscore_ops = {
280         .suspend = tegra_la_suspend,
281         .resume = tegra_la_resume,
282 };
283
284 static __init int tegra_la_syscore_init(void)
285 {
286         register_syscore_ops(&tegra_la_syscore_ops);
287         return 0;
288 }
289
290 static int __init tegra_latency_allowance_init(void)
291 {
292         unsigned int i;
293
294         init_chip_specific();
295
296         for (i = 0; i < cs.la_info_array_size; i++)
297                 cs.id_to_index[cs.la_info_array[i].id] = i;
298
299         for (i = 0; i < cs.la_info_array_size; i++) {
300                 if (cs.la_info_array[i].init_la)
301                         set_la(&cs.la_info_array[i],
302                                 cs.la_info_array[i].init_la);
303         }
304 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
305         tegra_set_latency_allowance(TEGRA_LA_G2PR, 20);
306         tegra_set_latency_allowance(TEGRA_LA_G2SR, 20);
307         tegra_set_latency_allowance(TEGRA_LA_G2DR, 20);
308         tegra_set_latency_allowance(TEGRA_LA_G2DW, 20);
309 #endif
310
311         if (cs.init_ptsa)
312                 cs.init_ptsa();
313         return 0;
314 }
315
316 late_initcall(tegra_latency_allowance_debugfs_init);
317 subsys_initcall(tegra_la_syscore_init);
318 core_initcall(tegra_latency_allowance_init);
319
320 #if TEST_LA_CODE
321 #define PRINT_ID_IDX_MAPPING 0
322 static int __init test_la(void)
323 {
324         int i;
325         int err;
326         enum tegra_la_id id = 0;
327         int repeat_count = 5;
328
329 #if PRINT_ID_IDX_MAPPING
330         for (i = 0; i < ID(MAX_ID); i++)
331                 pr_info("ID=0x%x, Idx=0x%x", i, cs.id_to_index[i]);
332 #endif
333
334         do {
335                 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
336                         err = tegra_set_latency_allowance(id, 200);
337                         if (err)
338                                 la_debug("\n***tegra_set_latency_allowance,"
339                                         " err=%d", err);
340                 }
341
342                 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
343                         if (id >= ID(DISPLAY_0AB) && id <= ID(DISPLAY_HCB))
344                                 continue;
345                         if (id >= ID(VI_WSB) && id <= ID(VI_WY))
346                                 continue;
347                         err = tegra_enable_latency_scaling(id, 20, 50, 80);
348                         if (err)
349                                 la_debug("\n***tegra_enable_latency_scaling,"
350                                         " err=%d", err);
351                 }
352
353                 la_debug("la_scaling_enable_count =%d",
354                         cs.la_scaling_enable_count);
355                 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
356                         if (id >= ID(DISPLAY_0AB) && id <= ID(DISPLAY_HCB))
357                                 continue;
358                         if (id >= ID(VI_WSB) && id <= ID(VI_WY))
359                                 continue;
360                         tegra_disable_latency_scaling(id);
361                 }
362                 la_debug("la_scaling_enable_count=%d",
363                         cs.la_scaling_enable_count);
364         } while (--repeat_count);
365         return 0;
366 }
367
368 late_initcall(test_la);
369 #endif