91eeed3c03659da938261146381197c0e5087248
[linux-2.6.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
33 #define MC_ARB_OVERRIDE         0xe8
34 #define GLOBAL_LATENCY_SCALING_ENABLE_BIT 7
35
36 #define MC_LA_AFI_0             0x2e0
37 #define MC_LA_AVPC_ARM7_0       0x2e4
38 #define MC_LA_DC_0              0x2e8
39 #define MC_LA_DC_1              0x2ec
40 #define MC_LA_DC_2              0x2f0
41 #define MC_LA_DCB_0             0x2f4
42 #define MC_LA_DCB_1             0x2f8
43 #define MC_LA_DCB_2             0x2fc
44 #define MC_LA_EPP_0             0x300
45 #define MC_LA_EPP_1             0x304
46 #define MC_LA_G2_0              0x308
47 #define MC_LA_G2_1              0x30c
48 #define MC_LA_HC_0              0x310
49 #define MC_LA_HC_1              0x314
50 #define MC_LA_HDA_0             0x318
51 #define MC_LA_ISP_0             0x31C
52 #define MC_LA_MPCORE_0          0x320
53 #define MC_LA_MPCORELP_0        0x324
54 #define MC_LA_MPE_0             0x328
55 #define MC_LA_MPE_1             0x32c
56 #define MC_LA_MPE_2             0x330
57 #define MC_LA_NV_0              0x334
58 #define MC_LA_NV_1              0x338
59 #define MC_LA_NV2_0             0x33c
60 #define MC_LA_NV2_1             0x340
61 #define MC_LA_PPCS_0            0x344
62 #define MC_LA_PPCS_1            0x348
63 #define MC_LA_PTC_0             0x34c
64 #define MC_LA_SATA_0            0x350
65 #define MC_LA_VDE_0             0x354
66 #define MC_LA_VDE_1             0x358
67 #define MC_LA_VDE_2             0x35c
68 #define MC_LA_VDE_3             0x360
69 #define MC_LA_VI_0              0x364
70 #define MC_LA_VI_1              0x368
71 #define MC_LA_VI_2              0x36c
72
73 #define DS_DISP_MCCIF_DISPLAY0A_HYST (0x481 * 4)
74 #define DS_DISP_MCCIF_DISPLAY0B_HYST (0x482 * 4)
75 #define DS_DISP_MCCIF_DISPLAY0C_HYST (0x483 * 4)
76 #define DS_DISP_MCCIF_DISPLAY1B_HYST (0x484 * 4)
77
78 #define DS_DISP_MCCIF_DISPLAY0AB_HYST (0x481 * 4)
79 #define DS_DISP_MCCIF_DISPLAY0BB_HYST (0x482 * 4)
80 #define DS_DISP_MCCIF_DISPLAY0CB_HYST (0x483 * 4)
81 #define DS_DISP_MCCIF_DISPLAY1BB_HYST (0x484 * 4)
82
83 #define VI_MCCIF_VIWSB_HYST     (0x9a * 4)
84 #define VI_MCCIF_VIWU_HYST      (0x9b * 4)
85 #define VI_MCCIF_VIWV_HYST      (0x9c * 4)
86 #define VI_MCCIF_VIWY_HYST      (0x9d * 4)
87
88 #define VI_TIMEOUT_WOCAL_VI     (0x70 * 4)
89 #define VI_RESERVE_3            (0x97 * 4)
90 #define VI_RESERVE_4            (0x98 * 4)
91
92 /* maximum valid value for latency allowance */
93 #define MC_LA_MAX_VALUE         255
94
95 #define ENABLE_LA_DEBUG         0
96 #define TEST_LA_CODE            0
97
98 #define la_debug(fmt, ...) \
99         if (ENABLE_LA_DEBUG) { \
100                 printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__); \
101         }
102
103 /* Bug 995270 */
104 #define HACK_LA_FIFO 1
105
106 static struct dentry *latency_debug_dir;
107
108 struct la_client_info {
109         unsigned int fifo_size_in_atoms;
110         unsigned int expiration_in_ns;  /* worst case expiration value */
111         void __iomem *reg_addr;
112         unsigned long mask;
113         unsigned long shift;
114         enum tegra_la_id id;
115         char *name;
116         bool scaling_supported;
117 };
118 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
119 static DEFINE_SPINLOCK(safety_lock);
120 #endif
121
122 static const int ns_per_tick = 30;
123 /* fifo atom size in bytes for non-fdc clients*/
124 static const int normal_atom_size = 16;
125 /* fifo atom size in bytes for fdc clients*/
126 static const int fdc_atom_size = 32;
127
128 #define MC_RA(r) \
129         (IO_ADDRESS(TEGRA_MC_BASE) + (MC_##r))
130 #define RA(r) \
131         (IO_ADDRESS(TEGRA_MC_BASE) + (MC_LA_##r))
132
133 #define MASK(x) \
134         ((0xFFFFFFFFUL >> (31 - (1 ? x) + (0 ? x))) << (0 ? x))
135 #define SHIFT(x) \
136         (0 ? x)
137 #define ID(id) \
138         TEGRA_LA_##id
139
140 #define LA_INFO(f, e, a, r, id, ss) \
141 {f, e, RA(a), MASK(r), SHIFT(r), ID(id), __stringify(id), ss}
142
143 /*
144  * The rule for getting the fifo_size_in_atoms is:
145  * 1.If REORDER_DEPTH exists, use it(default is overridden).
146  * 2.Else if (write_client) use RFIFO_DEPTH.
147  * 3.Else (read client) use RDFIFO_DEPTH.
148  * Refer to project.h file.
149  */
150 struct la_client_info la_info[] = {
151         LA_INFO(32,     150,    AFI_0,  7 : 0,          AFIR,           false),
152         LA_INFO(32,     150,    AFI_0,  23 : 16,        AFIW,           false),
153         LA_INFO(2,      150,    AVPC_ARM7_0, 7 : 0,     AVPC_ARM7R,     false),
154         LA_INFO(2,      150,    AVPC_ARM7_0, 23 : 16,   AVPC_ARM7W,     false),
155         LA_INFO(128,    1050,   DC_0,   7 : 0,          DISPLAY_0A,     true),
156         LA_INFO(64,     1050,   DC_0,   23 : 16,        DISPLAY_0B,     true),
157         LA_INFO(128,    1050,   DC_1,   7 : 0,          DISPLAY_0C,     true),
158         LA_INFO(64,     1050,   DC_1,   23 : 16,        DISPLAY_1B,     true),
159         LA_INFO(2,      1050,   DC_2,   7 : 0,          DISPLAY_HC,     false),
160         LA_INFO(128,    1050,   DCB_0,  7 : 0,          DISPLAY_0AB,    true),
161         LA_INFO(64,     1050,   DCB_0,  23 : 16,        DISPLAY_0BB,    true),
162         LA_INFO(128,    1050,   DCB_1,  7 : 0,          DISPLAY_0CB,    true),
163         LA_INFO(64,     1050,   DCB_1,  23 : 16,        DISPLAY_1BB,    true),
164         LA_INFO(2,      1050,   DCB_2,  7 : 0,          DISPLAY_HCB,    false),
165         LA_INFO(8,      150,    EPP_0,  7 : 0,          EPPUP,          false),
166         LA_INFO(64,     150,    EPP_0,  23 : 16,        EPPU,           false),
167         LA_INFO(64,     150,    EPP_1,  7 : 0,          EPPV,           false),
168         LA_INFO(64,     150,    EPP_1,  23 : 16,        EPPY,           false),
169         LA_INFO(64,     150,    G2_0,   7 : 0,          G2PR,           false),
170         LA_INFO(64,     150,    G2_0,   23 : 16,        G2SR,           false),
171         LA_INFO(48,     150,    G2_1,   7 : 0,          G2DR,           false),
172         LA_INFO(128,    150,    G2_1,   23 : 16,        G2DW,           false),
173         LA_INFO(16,     150,    HC_0,   7 : 0,          HOST1X_DMAR,    false),
174         LA_INFO(8,      150,    HC_0,   23 : 16,        HOST1XR,        false),
175         LA_INFO(32,     150,    HC_1,   7 : 0,          HOST1XW,        false),
176         LA_INFO(16,     150,    HDA_0,  7 : 0,          HDAR,           false),
177         LA_INFO(16,     150,    HDA_0,  23 : 16,        HDAW,           false),
178         LA_INFO(64,     150,    ISP_0,  7 : 0,          ISPW,           false),
179         LA_INFO(14,     150,    MPCORE_0, 7 : 0,        MPCORER,        false),
180         LA_INFO(24,     150,    MPCORE_0, 23 : 16,      MPCOREW,        false),
181         LA_INFO(14,     150,    MPCORELP_0, 7 : 0,      MPCORE_LPR,     false),
182         LA_INFO(24,     150,    MPCORELP_0, 23 : 16,    MPCORE_LPW,     false),
183         LA_INFO(8,      150,    MPE_0,  7 : 0,          MPE_UNIFBR,     false),
184         LA_INFO(2,      150,    MPE_0,  23 : 16,        MPE_IPRED,      false),
185         LA_INFO(64,     150,    MPE_1,  7 : 0,          MPE_AMEMRD,     false),
186         LA_INFO(8,      150,    MPE_1,  23 : 16,        MPE_CSRD,       false),
187         LA_INFO(8,      150,    MPE_2,  7 : 0,          MPE_UNIFBW,     false),
188         LA_INFO(8,      150,    MPE_2,  23 : 16,        MPE_CSWR,       false),
189         LA_INFO(48,     150,    NV_0,   7 : 0,          FDCDRD,         false),
190         LA_INFO(64,     150,    NV_0,   23 : 16,        IDXSRD,         false),
191         LA_INFO(64,     150,    NV_1,   7 : 0,          TEXSRD,         false),
192         LA_INFO(48,     150,    NV_1,   23 : 16,        FDCDWR,         false),
193         LA_INFO(48,     150,    NV2_0,  7 : 0,          FDCDRD2,        false),
194         LA_INFO(64,     150,    NV2_0,  23 : 16,        IDXSRD2,        false),
195         LA_INFO(64,     150,    NV2_1,  7 : 0,          TEXSRD2,        false),
196         LA_INFO(48,     150,    NV2_1,  23 : 16,        FDCDWR2,        false),
197         LA_INFO(2,      150,    PPCS_0, 7 : 0,          PPCS_AHBDMAR,   false),
198         LA_INFO(8,      150,    PPCS_0, 23 : 16,        PPCS_AHBSLVR,   false),
199         LA_INFO(2,      150,    PPCS_1, 7 : 0,          PPCS_AHBDMAW,   false),
200         LA_INFO(4,      150,    PPCS_1, 23 : 16,        PPCS_AHBSLVW,   false),
201         LA_INFO(2,      150,    PTC_0,  7 : 0,          PTCR,           false),
202         LA_INFO(32,     150,    SATA_0, 7 : 0,          SATAR,          false),
203         LA_INFO(32,     150,    SATA_0, 23 : 16,        SATAW,          false),
204         LA_INFO(8,      150,    VDE_0,  7 : 0,          VDE_BSEVR,      false),
205         LA_INFO(4,      150,    VDE_0,  23 : 16,        VDE_MBER,       false),
206         LA_INFO(16,     150,    VDE_1,  7 : 0,          VDE_MCER,       false),
207         LA_INFO(16,     150,    VDE_1,  23 : 16,        VDE_TPER,       false),
208         LA_INFO(4,      150,    VDE_2,  7 : 0,          VDE_BSEVW,      false),
209         LA_INFO(16,     150,    VDE_2,  23 : 16,        VDE_DBGW,       false),
210         LA_INFO(2,      150,    VDE_3,  7 : 0,          VDE_MBEW,       false),
211         LA_INFO(16,     150,    VDE_3,  23 : 16,        VDE_TPMW,       false),
212         LA_INFO(8,      1050,   VI_0,   7 : 0,          VI_RUV,         false),
213         LA_INFO(64,     1050,   VI_0,   23 : 16,        VI_WSB,         true),
214         LA_INFO(64,     1050,   VI_1,   7 : 0,          VI_WU,          true),
215         LA_INFO(64,     1050,   VI_1,   23 : 16,        VI_WV,          true),
216         LA_INFO(64,     1050,   VI_2,   7 : 0,          VI_WY,          true),
217
218 /* end of list. */
219         LA_INFO(0,      0,      AFI_0,  0 : 0,          MAX_ID,         false)
220 };
221
222 struct la_scaling_info {
223         unsigned int threshold_low;
224         unsigned int threshold_mid;
225         unsigned int threshold_high;
226         int scaling_ref_count;
227         int actual_la_to_set;
228         int la_set;
229 };
230
231 struct la_scaling_reg_info {
232         enum tegra_la_id id;
233         void __iomem *tl_reg_addr;
234         unsigned int tl_mask;
235         unsigned int tl_shift;
236         void __iomem *tm_reg_addr;
237         unsigned int tm_mask;
238         unsigned int tm_shift;
239         void __iomem *th_reg_addr;
240         unsigned int th_mask;
241         unsigned int th_shift;
242 };
243
244 #define DISP1_RA(r) \
245         (IO_ADDRESS(TEGRA_DISPLAY_BASE) + DS_DISP_MCCIF_##r##_HYST)
246 #define DISP2_RA(r) \
247         (IO_ADDRESS(TEGRA_DISPLAY2_BASE) + DS_DISP_MCCIF_##r##_HYST)
248
249 #define DISP_SCALING_REG_INFO(id, r, ra) \
250         { \
251                 ID(id), \
252                 ra(r), MASK(15 : 8), SHIFT(15 : 8), \
253                 ra(r), MASK(23 : 16), SHIFT(15 : 8), \
254                 ra(r), MASK(7 : 0), SHIFT(15 : 8) \
255         }
256
257 struct la_scaling_reg_info disp_info[] = {
258         DISP_SCALING_REG_INFO(DISPLAY_0A, DISPLAY0A, DISP1_RA),
259         DISP_SCALING_REG_INFO(DISPLAY_0B, DISPLAY0B, DISP1_RA),
260         DISP_SCALING_REG_INFO(DISPLAY_0C, DISPLAY0C, DISP1_RA),
261         DISP_SCALING_REG_INFO(DISPLAY_1B, DISPLAY1B, DISP1_RA),
262         DISP_SCALING_REG_INFO(MAX_ID,     DISPLAY1B, DISP1_RA), /*dummy entry*/
263         DISP_SCALING_REG_INFO(DISPLAY_0AB, DISPLAY0AB, DISP2_RA),
264         DISP_SCALING_REG_INFO(DISPLAY_0BB, DISPLAY0BB, DISP2_RA),
265         DISP_SCALING_REG_INFO(DISPLAY_0CB, DISPLAY0CB, DISP2_RA),
266         DISP_SCALING_REG_INFO(DISPLAY_1BB, DISPLAY1BB, DISP2_RA),
267 };
268
269 #define VI_TH_RA(r) \
270         (IO_ADDRESS(TEGRA_VI_BASE) + VI_MCCIF_##r##_HYST)
271 #define VI_TM_RA(r) \
272         (IO_ADDRESS(TEGRA_VI_BASE) + VI_TIMEOUT_WOCAL_VI)
273 #define VI_TL_RA(r) \
274         (IO_ADDRESS(TEGRA_VI_BASE) + VI_RESERVE_##r)
275
276 struct la_scaling_reg_info vi_info[] = {
277         {
278                 ID(VI_WSB),
279                 VI_TL_RA(4), MASK(7 : 0), SHIFT(7 : 0),
280                 VI_TM_RA(0), MASK(7 : 0), SHIFT(7 : 0),
281                 VI_TH_RA(VIWSB), MASK(7 : 0), SHIFT(7 : 0)
282         },
283         {
284                 ID(VI_WU),
285                 VI_TL_RA(3), MASK(15 : 8), SHIFT(15 : 8),
286                 VI_TM_RA(0), MASK(15 : 8), SHIFT(15 : 8),
287                 VI_TH_RA(VIWU), MASK(7 : 0), SHIFT(7 : 0)
288         },
289         {
290                 ID(VI_WV),
291                 VI_TL_RA(3), MASK(7 : 0), SHIFT(7 : 0),
292                 VI_TM_RA(0), MASK(23 : 16), SHIFT(23 : 16),
293                 VI_TH_RA(VIWV), MASK(7 : 0), SHIFT(7 : 0)
294         },
295         {
296                 ID(VI_WY),
297                 VI_TL_RA(4), MASK(15 : 8), SHIFT(15 : 8),
298                 VI_TM_RA(0), MASK(31 : 24), SHIFT(31 : 24),
299                 VI_TH_RA(VIWY), MASK(7 : 0), SHIFT(7 : 0)
300         }
301 };
302
303 static int la_scaling_enable_count;
304
305 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
306 static struct la_scaling_info scaling_info[TEGRA_LA_MAX_ID];
307
308 #define VALIDATE_ID(id) \
309         do { \
310                 if (id >= TEGRA_LA_MAX_ID) \
311                         return -EINVAL; \
312                 BUG_ON(la_info[id].id != id); \
313         } while (0)
314
315 #define VALIDATE_BW(bw_in_mbps) \
316         do { \
317                 if (bw_in_mbps >= 4096) \
318                         return -EINVAL; \
319         } while (0)
320
321 #define VALIDATE_THRESHOLDS(tl, tm, th) \
322         do { \
323                 if (tl > 100 || tm > 100 || th > 100) \
324                         return -EINVAL; \
325         } while (0)
326
327 static void set_thresholds(struct la_scaling_reg_info *info,
328                             enum tegra_la_id id)
329 {
330         unsigned long reg_read;
331         unsigned long reg_write;
332         unsigned int thresh_low;
333         unsigned int thresh_mid;
334         unsigned int thresh_high;
335         int la_set;
336
337         reg_read = readl(la_info[id].reg_addr);
338         la_set = (reg_read & la_info[id].mask) >> la_info[id].shift;
339         /* la should be set before enabling scaling. */
340         BUG_ON(la_set != scaling_info[id].la_set);
341
342         thresh_low = (scaling_info[id].threshold_low * la_set) / 100;
343         thresh_mid = (scaling_info[id].threshold_mid * la_set) / 100;
344         thresh_high = (scaling_info[id].threshold_high * la_set) / 100;
345         la_debug("%s: la_set=%d, thresh_low=%d(%d%%), thresh_mid=%d(%d%%),"
346                 " thresh_high=%d(%d%%) ", __func__, la_set,
347                 thresh_low, scaling_info[id].threshold_low,
348                 thresh_mid, scaling_info[id].threshold_mid,
349                 thresh_high, scaling_info[id].threshold_high);
350
351         reg_read = readl(info->tl_reg_addr);
352         reg_write = (reg_read & ~info->tl_mask) |
353                 (thresh_low << info->tl_shift);
354         writel(reg_write, info->tl_reg_addr);
355         la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
356                 (u32)info->tl_reg_addr, (u32)reg_read, (u32)reg_write);
357
358         reg_read = readl(info->tm_reg_addr);
359         reg_write = (reg_read & ~info->tm_mask) |
360                 (thresh_mid << info->tm_shift);
361         writel(reg_write, info->tm_reg_addr);
362         la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
363                 (u32)info->tm_reg_addr, (u32)reg_read, (u32)reg_write);
364
365         reg_read = readl(info->th_reg_addr);
366         reg_write = (reg_read & ~info->th_mask) |
367                 (thresh_high << info->th_shift);
368         writel(reg_write, info->th_reg_addr);
369         la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
370                 (u32)info->th_reg_addr, (u32)reg_read, (u32)reg_write);
371 }
372
373 static void set_disp_latency_thresholds(enum tegra_la_id id)
374 {
375         set_thresholds(&disp_info[id - ID(DISPLAY_0A)], id);
376 }
377
378 static void set_vi_latency_thresholds(enum tegra_la_id id)
379 {
380         set_thresholds(&vi_info[id - ID(VI_WSB)], id);
381 }
382
383 /* Sets latency allowance based on clients memory bandwitdh requirement.
384  * Bandwidth passed is in mega bytes per second.
385  */
386 int tegra_set_latency_allowance(enum tegra_la_id id,
387                                 unsigned int bandwidth_in_mbps)
388 {
389         int ideal_la;
390         int la_to_set;
391         unsigned long reg_read;
392         unsigned long reg_write;
393         unsigned int fifo_size_in_atoms;
394         int bytes_per_atom = normal_atom_size;
395         const int fifo_scale = 4;               /* 25% of the FIFO */
396         struct la_client_info *ci;
397
398         VALIDATE_ID(id);
399         VALIDATE_BW(bandwidth_in_mbps);
400         if (id == ID(FDCDRD) || id == ID(FDCDWR) ||
401                 id == ID(FDCDRD2) || id == ID(FDCDWR2))
402                 bytes_per_atom = fdc_atom_size;
403
404         ci = &la_info[id];
405         fifo_size_in_atoms = ci->fifo_size_in_atoms;
406
407 #if HACK_LA_FIFO
408         /* pretend that our FIFO is only as deep as the lowest fullness
409          * we expect to see */
410         if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_HCB))
411                 fifo_size_in_atoms /= fifo_scale;
412 #endif
413
414         if (bandwidth_in_mbps == 0) {
415                 la_to_set = MC_LA_MAX_VALUE;
416         } else {
417                 ideal_la = (fifo_size_in_atoms * bytes_per_atom * 1000) /
418                            (bandwidth_in_mbps * ns_per_tick);
419                 la_to_set = ideal_la - (ci->expiration_in_ns/ns_per_tick) - 1;
420         }
421
422         la_debug("\n%s:id=%d,bw=%dmbps, la_to_set=%d",
423                 __func__, id, bandwidth_in_mbps, la_to_set);
424         la_to_set = (la_to_set < 0) ? 0 : la_to_set;
425         la_to_set = (la_to_set > MC_LA_MAX_VALUE) ? MC_LA_MAX_VALUE : la_to_set;
426         scaling_info[id].actual_la_to_set = la_to_set;
427
428         spin_lock(&safety_lock);
429         reg_read = readl(ci->reg_addr);
430         reg_write = (reg_read & ~ci->mask) |
431                         (la_to_set << ci->shift);
432         writel(reg_write, ci->reg_addr);
433         scaling_info[id].la_set = la_to_set;
434         la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
435                 (u32)ci->reg_addr, (u32)reg_read, (u32)reg_write);
436         spin_unlock(&safety_lock);
437         return 0;
438 }
439
440 /* Thresholds for scaling are specified in % of fifo freeness.
441  * If threshold_low is specified as 20%, it means when the fifo free
442  * between 0 to 20%, use la as programmed_la.
443  * If threshold_mid is specified as 50%, it means when the fifo free
444  * between 20 to 50%, use la as programmed_la/2 .
445  * If threshold_high is specified as 80%, it means when the fifo free
446  * between 50 to 80%, use la as programmed_la/4.
447  * When the fifo is free between 80 to 100%, use la as 0(highest priority).
448  */
449 int tegra_enable_latency_scaling(enum tegra_la_id id,
450                                     unsigned int threshold_low,
451                                     unsigned int threshold_mid,
452                                     unsigned int threshold_high)
453 {
454         unsigned long reg;
455         void __iomem *scaling_enable_reg = MC_RA(ARB_OVERRIDE);
456
457         VALIDATE_ID(id);
458         VALIDATE_THRESHOLDS(threshold_low, threshold_mid, threshold_high);
459
460         if (la_info[id].scaling_supported == false)
461                 goto exit;
462
463         spin_lock(&safety_lock);
464
465         la_debug("\n%s: id=%d, tl=%d, tm=%d, th=%d", __func__,
466                 id, threshold_low, threshold_mid, threshold_high);
467         scaling_info[id].threshold_low = threshold_low;
468         scaling_info[id].threshold_mid = threshold_mid;
469         scaling_info[id].threshold_high = threshold_high;
470         scaling_info[id].scaling_ref_count++;
471
472         if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_1BB))
473                 set_disp_latency_thresholds(id);
474         else if (id >= ID(VI_WSB) && id <= ID(VI_WY))
475                 set_vi_latency_thresholds(id);
476         if (!la_scaling_enable_count++) {
477                 reg = readl(scaling_enable_reg);
478                 reg |= (1 << GLOBAL_LATENCY_SCALING_ENABLE_BIT);
479                 writel(reg,  scaling_enable_reg);
480                 la_debug("enabled scaling.");
481         }
482         spin_unlock(&safety_lock);
483 exit:
484         return 0;
485 }
486
487 void tegra_disable_latency_scaling(enum tegra_la_id id)
488 {
489         unsigned long reg;
490         void __iomem *scaling_enable_reg = MC_RA(ARB_OVERRIDE);
491
492         if (id >= TEGRA_LA_MAX_ID)
493                 return;
494         BUG_ON(la_info[id].id != id);
495
496         if (la_info[id].scaling_supported == false)
497                 return;
498         spin_lock(&safety_lock);
499         la_debug("\n%s: id=%d", __func__, id);
500         scaling_info[id].scaling_ref_count--;
501         BUG_ON(scaling_info[id].scaling_ref_count < 0);
502
503         if (!--la_scaling_enable_count) {
504                 reg = readl(scaling_enable_reg);
505                 reg = reg & ~(1 << GLOBAL_LATENCY_SCALING_ENABLE_BIT);
506                 writel(reg, scaling_enable_reg);
507                 la_debug("disabled scaling.");
508         }
509         spin_unlock(&safety_lock);
510 }
511 #endif
512
513 static int la_regs_show(struct seq_file *s, void *unused)
514 {
515         unsigned i;
516         unsigned long la;
517
518         /* iterate the list, but don't print MAX_ID */
519         for (i = 0; i < ARRAY_SIZE(la_info) - 1; i++) {
520                 la = (readl(la_info[i].reg_addr) & la_info[i].mask)
521                         >> la_info[i].shift;
522                 seq_printf(s, "%-16s: %4lu\n", la_info[i].name, la);
523         }
524
525         return 0;
526 }
527
528 static int dbg_la_regs_open(struct inode *inode, struct file *file)
529 {
530         return single_open(file, la_regs_show, inode->i_private);
531 }
532
533 static const struct file_operations regs_fops = {
534         .open           = dbg_la_regs_open,
535         .read           = seq_read,
536         .llseek         = seq_lseek,
537         .release        = single_release,
538 };
539
540 static int __init tegra_latency_allowance_debugfs_init(void)
541 {
542         if (latency_debug_dir)
543                 return 0;
544
545         latency_debug_dir = debugfs_create_dir("tegra_latency", NULL);
546
547         debugfs_create_file("la_info", S_IRUGO, latency_debug_dir, NULL,
548                 &regs_fops);
549
550         return 0;
551 }
552
553 late_initcall(tegra_latency_allowance_debugfs_init);
554
555 static int __init tegra_latency_allowance_init(void)
556 {
557         la_scaling_enable_count = 0;
558
559         tegra_set_latency_allowance(TEGRA_LA_G2PR, 20);
560         tegra_set_latency_allowance(TEGRA_LA_G2SR, 20);
561         tegra_set_latency_allowance(TEGRA_LA_G2DR, 20);
562         tegra_set_latency_allowance(TEGRA_LA_G2DW, 20);
563         return 0;
564 }
565
566 core_initcall(tegra_latency_allowance_init);
567
568 #if TEST_LA_CODE
569 static int __init test_la(void)
570 {
571         int err;
572         enum tegra_la_id id = 0;
573         int repeat_count = 5;
574
575         do {
576                 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
577                         err = tegra_set_latency_allowance(id, 200);
578                         if (err)
579                                 la_debug("\n***tegra_set_latency_allowance,"
580                                         " err=%d", err);
581                 }
582
583                 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
584                         if (id >= ID(DISPLAY_0AB) && id <= ID(DISPLAY_HCB))
585                                 continue;
586                         if (id >= ID(VI_WSB) && id <= ID(VI_WY))
587                                 continue;
588                         err = tegra_enable_latency_scaling(id, 20, 50, 80);
589                         if (err)
590                                 la_debug("\n***tegra_enable_latency_scaling,"
591                                         " err=%d", err);
592                 }
593
594                 la_debug("la_scaling_enable_count =%d",
595                         la_scaling_enable_count);
596                 for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
597                         if (id >= ID(DISPLAY_0AB) && id <= ID(DISPLAY_HCB))
598                                 continue;
599                         if (id >= ID(VI_WSB) && id <= ID(VI_WY))
600                                 continue;
601                         tegra_disable_latency_scaling(id);
602                 }
603                 la_debug("la_scaling_enable_count=%d",
604                         la_scaling_enable_count);
605         } while (--repeat_count);
606         return 0;
607 }
608
609 late_initcall(test_la);
610 #endif