arm: tegra: la: Add latency allowance support for T11x.
[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-2012, 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/seq_file.h>
22 #include <linux/err.h>
23 #include <linux/spinlock_types.h>
24 #include <linux/spinlock.h>
25 #include <linux/stringify.h>
26 #include <asm/bug.h>
27 #include <asm/io.h>
28 #include <asm/string.h>
29 #include <mach/iomap.h>
30 #include <mach/io.h>
31 #include <mach/latency_allowance.h>
32 #include "la_priv_common.h"
33 #include "tegra3_la_priv.h"
34 #include "tegra11x_la_priv.h"
35
36 #define ENABLE_LA_DEBUG         0
37 #define TEST_LA_CODE            0
38
39 #define la_debug(fmt, ...) \
40         if (ENABLE_LA_DEBUG) { \
41                 printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__); \
42         }
43
44 /* Bug 995270 */
45 #define HACK_LA_FIFO 1
46
47 static struct dentry *latency_debug_dir;
48 static DEFINE_SPINLOCK(safety_lock);
49 static unsigned short id_to_index[ID(MAX_ID) + 1];
50 static struct la_scaling_info scaling_info[TEGRA_LA_MAX_ID];
51 static int la_scaling_enable_count;
52
53 #define VALIDATE_ID(id) \
54         do { \
55                 if (id >= TEGRA_LA_MAX_ID || id_to_index[id] == 0xFFFF) { \
56                         pr_err("%s: invalid Id=%d", __func__, id); \
57                         return -EINVAL; \
58                 } \
59                 BUG_ON(la_info_array[id_to_index[id]].id != id); \
60         } while (0)
61
62 #define VALIDATE_BW(bw_in_mbps) \
63         do { \
64                 if (bw_in_mbps >= 4096) \
65                         return -EINVAL; \
66         } while (0)
67
68 #define VALIDATE_THRESHOLDS(tl, tm, th) \
69         do { \
70                 if (tl > 100 || tm > 100 || th > 100) \
71                         return -EINVAL; \
72         } while (0)
73
74 /* Sets latency allowance based on clients memory bandwitdh requirement.
75  * Bandwidth passed is in mega bytes per second.
76  */
77 int tegra_set_latency_allowance(enum tegra_la_id id,
78                                 unsigned int bandwidth_in_mbps)
79 {
80         int ideal_la;
81         int la_to_set;
82         unsigned long reg_read;
83         unsigned long reg_write;
84         unsigned int fifo_size_in_atoms;
85         int bytes_per_atom = normal_atom_size;
86         const int fifo_scale = 4;               /* 25% of the FIFO */
87         struct la_client_info *ci;
88         int idx = id_to_index[id];
89
90         VALIDATE_ID(id);
91         VALIDATE_BW(bandwidth_in_mbps);
92
93         ci = &la_info_array[idx];
94         fifo_size_in_atoms = ci->fifo_size_in_atoms;
95
96 #if HACK_LA_FIFO
97         /* pretend that our FIFO is only as deep as the lowest fullness
98          * we expect to see */
99         if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_HCB))
100                 fifo_size_in_atoms /= fifo_scale;
101 #endif
102
103         if (bandwidth_in_mbps == 0) {
104                 la_to_set = MC_LA_MAX_VALUE;
105         } else {
106                 ideal_la = (fifo_size_in_atoms * bytes_per_atom * 1000) /
107                            (bandwidth_in_mbps * ns_per_tick);
108                 la_to_set = ideal_la - (ci->expiration_in_ns/ns_per_tick) - 1;
109         }
110
111         la_debug("\n%s:id=%d,idx=%d, bw=%dmbps, la_to_set=%d",
112                 __func__, id, idx, bandwidth_in_mbps, la_to_set);
113         la_to_set = (la_to_set < 0) ? 0 : la_to_set;
114         la_to_set = (la_to_set > MC_LA_MAX_VALUE) ? MC_LA_MAX_VALUE : la_to_set;
115         scaling_info[idx].actual_la_to_set = la_to_set;
116
117         spin_lock(&safety_lock);
118         reg_read = readl(ci->reg_addr);
119         reg_write = (reg_read & ~ci->mask) |
120                         (la_to_set << ci->shift);
121         writel(reg_write, ci->reg_addr);
122         scaling_info[idx].la_set = la_to_set;
123         la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
124                 (u32)ci->reg_addr, (u32)reg_read, (u32)reg_write);
125         spin_unlock(&safety_lock);
126         return 0;
127 }
128
129 #if defined(CONFIG_TEGRA_LATENCY_ALLOWANCE_SCALING)
130 static void set_thresholds(struct la_scaling_reg_info *info,
131                             enum tegra_la_id id)
132 {
133         unsigned long reg_read;
134         unsigned long reg_write;
135         unsigned int thresh_low;
136         unsigned int thresh_mid;
137         unsigned int thresh_high;
138         int la_set;
139         int idx = id_to_index[id];
140
141         reg_read = readl(la_info_array[idx].reg_addr);
142         la_set = (reg_read & la_info_array[idx].mask) >>
143                  la_info_array[idx].shift;
144         /* la should be set before enabling scaling. */
145         BUG_ON(la_set != scaling_info[idx].la_set);
146
147         thresh_low = (scaling_info[idx].threshold_low * la_set) / 100;
148         thresh_mid = (scaling_info[idx].threshold_mid * la_set) / 100;
149         thresh_high = (scaling_info[idx].threshold_high * la_set) / 100;
150         la_debug("%s: la_set=%d, thresh_low=%d(%d%%), thresh_mid=%d(%d%%),"
151                 " thresh_high=%d(%d%%) ", __func__, la_set,
152                 thresh_low, scaling_info[idx].threshold_low,
153                 thresh_mid, scaling_info[idx].threshold_mid,
154                 thresh_high, scaling_info[idx].threshold_high);
155
156         reg_read = readl(info->tl_reg_addr);
157         reg_write = (reg_read & ~info->tl_mask) |
158                 (thresh_low << info->tl_shift);
159         writel(reg_write, info->tl_reg_addr);
160         la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
161                 (u32)info->tl_reg_addr, (u32)reg_read, (u32)reg_write);
162
163         reg_read = readl(info->tm_reg_addr);
164         reg_write = (reg_read & ~info->tm_mask) |
165                 (thresh_mid << info->tm_shift);
166         writel(reg_write, info->tm_reg_addr);
167         la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
168                 (u32)info->tm_reg_addr, (u32)reg_read, (u32)reg_write);
169
170         reg_read = readl(info->th_reg_addr);
171         reg_write = (reg_read & ~info->th_mask) |
172                 (thresh_high << info->th_shift);
173         writel(reg_write, info->th_reg_addr);
174         la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
175                 (u32)info->th_reg_addr, (u32)reg_read, (u32)reg_write);
176 }
177
178 static void set_disp_latency_thresholds(enum tegra_la_id id)
179 {
180         set_thresholds(&disp_info[id - ID(DISPLAY_0A)], id);
181 }
182
183 static void set_vi_latency_thresholds(enum tegra_la_id id)
184 {
185         set_thresholds(&vi_info[id - ID(VI_WSB)], id);
186 }
187
188 /* Thresholds for scaling are specified in % of fifo freeness.
189  * If threshold_low is specified as 20%, it means when the fifo free
190  * between 0 to 20%, use la as programmed_la.
191  * If threshold_mid is specified as 50%, it means when the fifo free
192  * between 20 to 50%, use la as programmed_la/2 .
193  * If threshold_high is specified as 80%, it means when the fifo free
194  * between 50 to 80%, use la as programmed_la/4.
195  * When the fifo is free between 80 to 100%, use la as 0(highest priority).
196  */
197 int tegra_enable_latency_scaling(enum tegra_la_id id,
198                                     unsigned int threshold_low,
199                                     unsigned int threshold_mid,
200                                     unsigned int threshold_high)
201 {
202         unsigned long reg;
203         void __iomem *scaling_enable_reg = (void __iomem *)(MC_RA(ARB_OVERRIDE));
204         int idx = id_to_index[id];
205
206         VALIDATE_ID(id);
207         VALIDATE_THRESHOLDS(threshold_low, threshold_mid, threshold_high);
208
209         if (la_info_array[idx].scaling_supported == false)
210                 goto exit;
211
212         spin_lock(&safety_lock);
213
214         la_debug("\n%s: id=%d, tl=%d, tm=%d, th=%d", __func__,
215                 id, threshold_low, threshold_mid, threshold_high);
216         scaling_info[idx].threshold_low = threshold_low;
217         scaling_info[idx].threshold_mid = threshold_mid;
218         scaling_info[idx].threshold_high = threshold_high;
219         scaling_info[idx].scaling_ref_count++;
220
221         if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_1BB))
222                 set_disp_latency_thresholds(id);
223         else if (id >= ID(VI_WSB) && id <= ID(VI_WY))
224                 set_vi_latency_thresholds(id);
225         if (!la_scaling_enable_count++) {
226                 reg = readl(scaling_enable_reg);
227                 reg |= (1 << GLOBAL_LATENCY_SCALING_ENABLE_BIT);
228                 writel(reg,  scaling_enable_reg);
229                 la_debug("enabled scaling.");
230         }
231         spin_unlock(&safety_lock);
232 exit:
233         return 0;
234 }
235
236 void tegra_disable_latency_scaling(enum tegra_la_id id)
237 {
238         unsigned long reg;
239         void __iomem *scaling_enable_reg = (void __iomem *)(MC_RA(ARB_OVERRIDE));
240         int idx;
241
242         BUG_ON(id >= TEGRA_LA_MAX_ID);
243         idx = id_to_index[id];
244         BUG_ON(la_info_array[idx].id != id);
245
246         if (la_info_array[idx].scaling_supported == false)
247                 return;
248         spin_lock(&safety_lock);
249         la_debug("\n%s: id=%d", __func__, id);
250         scaling_info[idx].scaling_ref_count--;
251         BUG_ON(scaling_info[idx].scaling_ref_count < 0);
252
253         if (!--la_scaling_enable_count) {
254                 reg = readl(scaling_enable_reg);
255                 reg = reg & ~(1 << GLOBAL_LATENCY_SCALING_ENABLE_BIT);
256                 writel(reg, scaling_enable_reg);
257                 la_debug("disabled scaling.");
258         }
259         spin_unlock(&safety_lock);
260 }
261 #endif
262
263 void tegra_latency_allowance_update_tick_length(unsigned int new_ns_per_tick)
264 {
265         int i = 0;
266         int la;
267         unsigned long reg_read;
268         unsigned long reg_write;
269         unsigned long scale_factor = new_ns_per_tick / ns_per_tick;
270
271         if (scale_factor > 1) {
272                 spin_lock(&safety_lock);
273                 ns_per_tick = new_ns_per_tick;
274                 for (i = 0; i < ARRAY_SIZE(la_info_array) - 1; i++) {
275                         reg_read = readl(la_info_array[i].reg_addr);
276                         la = ((reg_read & la_info_array[i].mask) >>
277                                 la_info_array[i].shift) / scale_factor;
278
279                         reg_write = (reg_read & ~la_info_array[i].mask) |
280                                         (la << la_info_array[i].shift);
281                         writel(reg_write, la_info_array[i].reg_addr);
282                         scaling_info[i].la_set = la;
283                 }
284                 spin_unlock(&safety_lock);
285
286                 /* Re-scale G2PR, G2SR, G2DR, G2DW with updated ns_per_tick */
287                 tegra_set_latency_allowance(TEGRA_LA_G2PR, 20);
288                 tegra_set_latency_allowance(TEGRA_LA_G2SR, 20);
289                 tegra_set_latency_allowance(TEGRA_LA_G2DR, 20);
290                 tegra_set_latency_allowance(TEGRA_LA_G2DW, 20);
291         }
292 }
293
294 static int la_regs_show(struct seq_file *s, void *unused)
295 {
296         unsigned i;
297         unsigned long la;
298
299         /* iterate the list, but don't print MAX_ID */
300         for (i = 0; i < ARRAY_SIZE(la_info_array) - 1; i++) {
301                 la = (readl(la_info_array[i].reg_addr) & la_info_array[i].mask)
302                         >> la_info_array[i].shift;
303                 seq_printf(s, "%-16s: %4lu\n", la_info_array[i].name, la);
304         }
305
306         return 0;
307 }
308
309 static int dbg_la_regs_open(struct inode *inode, struct file *file)
310 {
311         return single_open(file, la_regs_show, inode->i_private);
312 }
313
314 static const struct file_operations regs_fops = {
315         .open           = dbg_la_regs_open,
316         .read           = seq_read,
317         .llseek         = seq_lseek,
318         .release        = single_release,
319 };
320
321 static int __init tegra_latency_allowance_debugfs_init(void)
322 {
323         if (latency_debug_dir)
324                 return 0;
325
326         latency_debug_dir = debugfs_create_dir("tegra_latency", NULL);
327
328         debugfs_create_file("la_info", S_IRUGO, latency_debug_dir, NULL,
329                 &regs_fops);
330
331         return 0;
332 }
333
334 late_initcall(tegra_latency_allowance_debugfs_init);
335
336 static int __init tegra_latency_allowance_init(void)
337 {
338         unsigned int i;
339
340         la_scaling_enable_count = 0;
341         memset(&id_to_index[0], 0xFF, sizeof(id_to_index));
342
343         for (i = 0; i < ARRAY_SIZE(la_info_array); i++)
344                 id_to_index[la_info_array[i].id] = i;
345
346         tegra_set_latency_allowance(TEGRA_LA_G2PR, 20);
347         tegra_set_latency_allowance(TEGRA_LA_G2SR, 20);
348         tegra_set_latency_allowance(TEGRA_LA_G2DR, 20);
349         tegra_set_latency_allowance(TEGRA_LA_G2DW, 20);
350         return 0;
351 }
352
353 core_initcall(tegra_latency_allowance_init);
354
355 #if TEST_LA_CODE
356 #define PRINT_ID_IDX_MAPPING 0
357 static int __init test_la(void)
358 {
359         int i;
360         int err;
361         enum tegra_la_id id = 0;
362         int repeat_count = 5;
363
364 #if PRINT_ID_IDX_MAPPING
365         for (i = 0; i < ID(MAX_ID); i++)
366                 pr_info("ID=0x%x, Idx=0x%x", i, id_to_index[i]);
367 #endif
368
369         do {
370                 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
371                         err = tegra_set_latency_allowance(id, 200);
372                         if (err)
373                                 la_debug("\n***tegra_set_latency_allowance,"
374                                         " err=%d", err);
375                 }
376
377                 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
378                         if (id >= ID(DISPLAY_0AB) && id <= ID(DISPLAY_HCB))
379                                 continue;
380                         if (id >= ID(VI_WSB) && id <= ID(VI_WY))
381                                 continue;
382                         err = tegra_enable_latency_scaling(id, 20, 50, 80);
383                         if (err)
384                                 la_debug("\n***tegra_enable_latency_scaling,"
385                                         " err=%d", err);
386                 }
387
388                 la_debug("la_scaling_enable_count =%d",
389                         la_scaling_enable_count);
390                 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
391                         if (id >= ID(DISPLAY_0AB) && id <= ID(DISPLAY_HCB))
392                                 continue;
393                         if (id >= ID(VI_WSB) && id <= ID(VI_WY))
394                                 continue;
395                         tegra_disable_latency_scaling(id);
396                 }
397                 la_debug("la_scaling_enable_count=%d",
398                         la_scaling_enable_count);
399         } while (--repeat_count);
400         return 0;
401 }
402
403 late_initcall(test_la);
404 #endif