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