]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - drivers/platform/tegra/mc/emc_bwmgr.c
nvpmodel: add nvpmodel_emc_cap driver and sysfs
[hercules2020/nv-tegra/linux-4.4.git] / drivers / platform / tegra / mc / emc_bwmgr.c
1 /**
2  * Copyright (c) 2015 - 2016, NVIDIA CORPORATION. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  */
13
14 #include <linux/types.h>
15 #include <linux/mutex.h>
16 #include <linux/err.h>
17 #include <linux/module.h>
18 #include <linux/platform/tegra/emc_bwmgr.h>
19 #include <linux/platform/tegra/isomgr.h>
20 #include <linux/debugfs.h>
21
22 u8 bwmgr_dram_efficiency;
23 u32 *bwmgr_dram_iso_eff_table;
24 int bwmgr_iso_bw_percentage;
25 enum bwmgr_dram_types bwmgr_dram_type;
26 int emc_to_dram_freq_factor;
27
28 #define IS_HANDLE_VALID(x) ((x >= bwmgr.bwmgr_client) && \
29                 (x < bwmgr.bwmgr_client + TEGRA_BWMGR_CLIENT_COUNT))
30
31 struct tegra_bwmgr_client {
32         unsigned long bw;
33         unsigned long iso_bw;
34         unsigned long cap;
35         unsigned long iso_cap;
36         unsigned long floor;
37         int refcount;
38 };
39
40 /* TODO: Manage client state in a dynamic list */
41 static struct {
42         struct tegra_bwmgr_client bwmgr_client[TEGRA_BWMGR_CLIENT_COUNT];
43         struct mutex lock;
44         unsigned long emc_min_rate;
45         unsigned long emc_max_rate;
46         struct clk *emc_clk;
47         struct task_struct *task;
48         bool status;
49 } bwmgr;
50
51 static bool clk_update_disabled;
52
53 static struct {
54         unsigned long bw;
55         unsigned long iso_bw;
56         unsigned long non_iso_cap;
57         unsigned long iso_cap;
58         unsigned long floor;
59         unsigned long total_bw_aftr_eff;
60         unsigned long iso_bw_aftr_eff;
61         unsigned long calc_freq;
62         unsigned long req_freq;
63 } debug_info;
64
65 static void bwmgr_debugfs_init(void);
66
67 static inline void bwmgr_lock(void)
68 {
69         BUG_ON(bwmgr.task == current); /* disallow rentrance, avoid deadlock */
70         mutex_lock(&bwmgr.lock);
71         bwmgr.task = current;
72 }
73
74 static inline void bwmgr_unlock(void)
75 {
76         BUG_ON(bwmgr.task != current); /* detect mismatched calls */
77         bwmgr.task = NULL;
78         mutex_unlock(&bwmgr.lock);
79 }
80
81 /* call with bwmgr lock held except during init*/
82 static void purge_client(struct tegra_bwmgr_client *handle)
83 {
84         handle->bw = 0;
85         handle->iso_bw = 0;
86         handle->cap = bwmgr.emc_max_rate;
87         handle->iso_cap = bwmgr.emc_max_rate;
88         handle->floor = 0;
89         handle->refcount = 0;
90 }
91
92 static unsigned long bwmgr_apply_efficiency(
93                 unsigned long total_bw, unsigned long iso_bw,
94                 unsigned long max_rate, u64 usage_flags,
95                 unsigned long *iso_bw_min);
96
97 /* call with bwmgr lock held */
98 static int bwmgr_update_clk(void)
99 {
100         int i;
101         unsigned long bw = 0;
102         unsigned long iso_bw = 0;
103         unsigned long non_iso_cap = bwmgr.emc_max_rate;
104         unsigned long iso_cap = bwmgr.emc_max_rate;
105         unsigned long floor = 0;
106         unsigned long iso_bw_min;
107         u64 iso_client_flags = 0;
108         int ret = 0;
109
110         /* sizeof(iso_client_flags) */
111         BUILD_BUG_ON(TEGRA_BWMGR_CLIENT_COUNT > 64);
112         BUG_ON(bwmgr.task != current); /* check that lock is held */
113
114         for (i = 0; i < TEGRA_BWMGR_CLIENT_COUNT; i++) {
115                 bw += bwmgr.bwmgr_client[i].bw;
116                 bw = min(bw, bwmgr.emc_max_rate);
117
118                 if (bwmgr.bwmgr_client[i].iso_bw > 0) {
119                         iso_client_flags |= BIT(i);
120                         iso_bw += bwmgr.bwmgr_client[i].iso_bw;
121                         iso_bw = min(iso_bw, bwmgr.emc_max_rate);
122                 }
123
124                 non_iso_cap = min(non_iso_cap, bwmgr.bwmgr_client[i].cap);
125                 iso_cap = min(iso_cap, bwmgr.bwmgr_client[i].iso_cap);
126                 floor = max(floor, bwmgr.bwmgr_client[i].floor);
127         }
128         debug_info.bw = bw;
129         debug_info.iso_bw = iso_bw;
130         debug_info.floor = floor;
131         debug_info.iso_cap = iso_cap;
132         debug_info.non_iso_cap = non_iso_cap;
133         bw += iso_bw;
134         bw = bwmgr_apply_efficiency(
135                         bw, iso_bw, bwmgr.emc_max_rate,
136                         iso_client_flags, &iso_bw_min);
137         debug_info.total_bw_aftr_eff = bw;
138         debug_info.iso_bw_aftr_eff = iso_bw_min;
139         iso_bw_min = clk_round_rate(bwmgr.emc_clk, iso_bw_min);
140         floor = min(floor, bwmgr.emc_max_rate);
141         bw = max(bw, floor);
142         bw = min(bw, min(iso_cap, max(non_iso_cap, iso_bw_min)));
143         debug_info.calc_freq = bw;
144         bw = clk_round_rate(bwmgr.emc_clk, bw);
145         debug_info.req_freq = bw;
146         if (bw == tegra_bwmgr_get_emc_rate())
147                 return ret;
148
149         ret = clk_set_rate(bwmgr.emc_clk, bw);
150         if (ret)
151                 pr_err
152                 ("bwmgr: clk_set_rate failed for freq %lu Hz with errno %d\n",
153                                 bw, ret);
154
155         return ret;
156 }
157
158 struct tegra_bwmgr_client *tegra_bwmgr_register(
159                 enum tegra_bwmgr_client_id client)
160 {
161         if ((client >= TEGRA_BWMGR_CLIENT_COUNT) || (client < 0)) {
162                 pr_err("bwmgr: invalid client id %d tried to register",
163                                 client);
164                 WARN_ON(true);
165                 return ERR_PTR(-EINVAL);
166         }
167
168         bwmgr_lock();
169         (bwmgr.bwmgr_client + client)->refcount++;
170         bwmgr_unlock();
171         return (bwmgr.bwmgr_client + client);
172 }
173 EXPORT_SYMBOL_GPL(tegra_bwmgr_register);
174
175 void tegra_bwmgr_unregister(struct tegra_bwmgr_client *handle)
176 {
177         if (!IS_HANDLE_VALID(handle)) {
178                 WARN_ON(true);
179                 return;
180         }
181
182         bwmgr_lock();
183         handle->refcount--;
184
185         if (handle->refcount <= 0) {
186                 if (handle->refcount < 0) {
187                         pr_err("bwmgr: Mismatched unregister call, client %ld\n",
188                                 handle - bwmgr.bwmgr_client);
189                         WARN_ON(true);
190                 }
191                 purge_client(handle);
192         }
193
194         bwmgr_unlock();
195 }
196 EXPORT_SYMBOL_GPL(tegra_bwmgr_unregister);
197
198 unsigned long tegra_bwmgr_get_max_emc_rate(void)
199 {
200         return bwmgr.emc_max_rate;
201 }
202 EXPORT_SYMBOL_GPL(tegra_bwmgr_get_max_emc_rate);
203
204 /* Returns the ratio between dram and emc freq based on the type of dram */
205 int bwmgr_get_emc_to_dram_freq_factor(void)
206 {
207         return emc_to_dram_freq_factor;
208 }
209 EXPORT_SYMBOL_GPL(bwmgr_get_emc_to_dram_freq_factor);
210
211 /* Returns the actual emc frequency calculated using the dram
212  * frequency and emc_to_dram conversion factor
213  */
214 unsigned long tegra_bwmgr_get_core_emc_rate(void)
215 {
216         return (unsigned long)(tegra_bwmgr_get_emc_rate() /
217                 bwmgr_get_emc_to_dram_freq_factor());
218 }
219 EXPORT_SYMBOL_GPL(tegra_bwmgr_get_core_emc_rate);
220
221 unsigned long tegra_bwmgr_round_rate(unsigned long bw)
222 {
223         if (bwmgr.emc_clk)
224                 return clk_round_rate(bwmgr.emc_clk, bw);
225
226         return 0;
227 }
228 EXPORT_SYMBOL_GPL(tegra_bwmgr_round_rate);
229
230 int tegra_bwmgr_set_emc(struct tegra_bwmgr_client *handle, unsigned long val,
231                 enum tegra_bwmgr_request_type req)
232 {
233         int ret = 0;
234         bool update_clk = false;
235
236         if (!bwmgr.emc_clk)
237                 return 0;
238
239         if (!bwmgr.status)
240                 return 0;
241
242         if (!IS_HANDLE_VALID(handle)) {
243                 pr_err("bwmgr: client sent bad handle %p\n",
244                                 handle);
245                 WARN_ON(true);
246                 return -EINVAL;
247         }
248
249         if (req >= TEGRA_BWMGR_SET_EMC_REQ_COUNT) {
250                 pr_err("bwmgr: client %ld sent bad request type %d\n",
251                                 handle - bwmgr.bwmgr_client, req);
252                 WARN_ON(true);
253                 return -EINVAL;
254         }
255
256         bwmgr_lock();
257
258         switch (req) {
259         case TEGRA_BWMGR_SET_EMC_FLOOR:
260                 if (handle->floor != val) {
261                         handle->floor = val;
262                         update_clk = true;
263                 }
264                 break;
265
266         case TEGRA_BWMGR_SET_EMC_CAP:
267                 if (val == 0)
268                         val = bwmgr.emc_max_rate;
269
270                 if (handle->cap != val) {
271                         handle->cap = val;
272                         update_clk = true;
273                 }
274                 break;
275
276         case TEGRA_BWMGR_SET_EMC_ISO_CAP:
277                 if (val == 0)
278                         val = bwmgr.emc_max_rate;
279
280                 if (handle->iso_cap != val) {
281                         handle->iso_cap = val;
282                         update_clk = true;
283                 }
284                 break;
285
286         case TEGRA_BWMGR_SET_EMC_SHARED_BW:
287                 if (handle->bw != val) {
288                         handle->bw = val;
289                         update_clk = true;
290                 }
291                 break;
292
293         case TEGRA_BWMGR_SET_EMC_SHARED_BW_ISO:
294                 if (handle->iso_bw != val) {
295                         handle->iso_bw = val;
296                         update_clk = true;
297                 }
298                 break;
299
300         default:
301                 WARN_ON(true);
302                 break;
303         }
304
305         if (update_clk && !clk_update_disabled)
306                 ret = bwmgr_update_clk();
307
308         bwmgr_unlock();
309
310         return ret;
311 }
312 EXPORT_SYMBOL_GPL(tegra_bwmgr_set_emc);
313
314 int tegra_bwmgr_notifier_register(struct notifier_block *nb)
315 {
316         if (!nb)
317                 return -EINVAL;
318
319         if (bwmgr.emc_clk)
320                 return clk_notifier_register(bwmgr.emc_clk, nb);
321         else
322                 return -ENODEV;
323 }
324 EXPORT_SYMBOL_GPL(tegra_bwmgr_notifier_register);
325
326 int tegra_bwmgr_notifier_unregister(struct notifier_block *nb)
327 {
328         if (!nb)
329                 return -EINVAL;
330
331         if (bwmgr.emc_clk)
332                 return clk_notifier_unregister(bwmgr.emc_clk, nb);
333         else
334                 return -ENODEV;
335 }
336 EXPORT_SYMBOL_GPL(tegra_bwmgr_notifier_unregister);
337
338 /* Should be overrided always */
339 void __weak bwmgr_eff_init(void)
340 {
341         BUG();
342 }
343
344 int get_iso_bw_table_idx(unsigned long iso_bw);
345
346 unsigned long tegra_bwmgr_get_emc_rate(void)
347 {
348         if (bwmgr.emc_clk)
349                 return clk_get_rate(bwmgr.emc_clk);
350
351         return 0;
352 }
353 EXPORT_SYMBOL_GPL(tegra_bwmgr_get_emc_rate);
354
355 static unsigned long bwmgr_apply_efficiency(
356                 unsigned long total_bw, unsigned long iso_bw,
357                 unsigned long max_rate, u64 usage_flags,
358                 unsigned long *iso_bw_min)
359 {
360         u8 efficiency = bwmgr_dram_efficiency;
361         if (total_bw && efficiency && (efficiency < 100)) {
362                 total_bw = total_bw / efficiency;
363                 total_bw = (total_bw < max_rate / 100) ?
364                                 (total_bw * 100) : max_rate;
365         }
366
367         efficiency = bwmgr_dram_iso_eff_table[get_iso_bw_table_idx(iso_bw)];
368         WARN_ON(efficiency == 1);
369         if (iso_bw && efficiency && (efficiency < 100)) {
370                 iso_bw /= efficiency;
371                 iso_bw = (iso_bw < max_rate / 100) ?
372                         (iso_bw * 100) : max_rate;
373         }
374
375         if (iso_bw_min)
376                 *iso_bw_min = iso_bw;
377
378         return max(total_bw, iso_bw);
379 }
380
381 int bwmgr_iso_bw_percentage_max(void)
382 {
383         return bwmgr_iso_bw_percentage;
384 }
385 EXPORT_SYMBOL_GPL(bwmgr_iso_bw_percentage_max);
386
387 int __init bwmgr_init(void)
388 {
389         int i;
390         struct device_node *dn;
391         long round_rate;
392
393         mutex_init(&bwmgr.lock);
394         bwmgr_debugfs_init();
395         bwmgr_eff_init();
396         pmqos_bwmgr_init();
397
398         dn = of_find_compatible_node(NULL, NULL, "nvidia,bwmgr");
399         if (dn == NULL) {
400                 pr_err("bwmgr: dt node not found.\n");
401                 return -ENODEV;
402         }
403
404         bwmgr.emc_clk = of_clk_get(dn, 0);
405         if (IS_ERR_OR_NULL(bwmgr.emc_clk)) {
406                 pr_err("bwmgr: couldn't find emc clock.\n");
407                 bwmgr.emc_clk = NULL;
408                 WARN_ON(true);
409                 return -ENODEV;
410         }
411
412         round_rate = clk_round_rate(bwmgr.emc_clk, 0);
413         if (round_rate < 0) {
414                 bwmgr.emc_min_rate = 0;
415                 pr_err("bwmgr: couldn't get emc clock min rate.\n");
416         } else
417                 bwmgr.emc_min_rate = (unsigned long)round_rate;
418
419         /* Use LONG_MAX as downstream functions treats rate arg as signed */
420         round_rate = clk_round_rate(bwmgr.emc_clk, LONG_MAX);
421         if (round_rate < 0) {
422                 bwmgr.emc_max_rate = 0;
423                 pr_err("bwmgr: couldn't get emc clock max rate.\n");
424         } else
425                 bwmgr.emc_max_rate = (unsigned long)round_rate;
426
427         for (i = 0; i < TEGRA_BWMGR_CLIENT_COUNT; i++)
428                 purge_client(bwmgr.bwmgr_client + i);
429
430         /* Check status property is okay or not. */
431         if (of_device_is_available(dn))
432                 bwmgr.status = true;
433         else
434                 bwmgr.status = false;
435         return 0;
436 }
437 subsys_initcall(bwmgr_init);
438
439 void __exit bwmgr_exit(void)
440 {
441         int i;
442
443         for (i = 0; i < TEGRA_BWMGR_CLIENT_COUNT; i++)
444                 purge_client(bwmgr.bwmgr_client + i);
445
446         bwmgr.emc_clk = NULL;
447         mutex_destroy(&bwmgr.lock);
448 }
449 module_exit(bwmgr_exit);
450
451 #ifdef CONFIG_DEBUG_FS
452 static struct tegra_bwmgr_client *bwmgr_debugfs_client_handle;
453 static struct dentry *debugfs_dir;
454 static struct dentry *debugfs_node_floor;
455 static struct dentry *debugfs_node_cap;
456 static struct dentry *debugfs_node_iso_cap;
457 static struct dentry *debugfs_node_bw;
458 static struct dentry *debugfs_node_iso_bw;
459 static struct dentry *debugfs_node_emc_rate;
460 static struct dentry *debugfs_node_emc_min;
461 static struct dentry *debugfs_node_emc_max;
462 static struct dentry *debugfs_node_core_emc_rate;
463 static struct dentry *debugfs_node_clients_info;
464
465 /* keep in sync with tegra_bwmgr_client_id */
466 static const char * const tegra_bwmgr_client_names[] = {
467         "cpu_0",
468         "cpu_1",
469         "disp_0",
470         "disp_1",
471         "disp_2",
472         "usbd",
473         "xhci",
474         "sdmmc1",
475         "sdmmc2",
476         "sdmmc3",
477         "sdmmc4",
478         "mon",
479         "gpu",
480         "msenc",
481         "nvjpg",
482         "nvdec",
483         "tsec",
484         "tsecb",
485         "vi",
486         "ispa",
487         "ispb",
488         "camera",
489         "isomgr",
490         "thermal",
491         "vic",
492         "adsp",
493         "adma",
494         "pcie",
495         "bbc_0",
496         "eqos",
497         "se0",
498         "se1",
499         "se2",
500         "se3",
501         "se4",
502         "pmqos",
503         "nvpmodel",
504         "debug",
505         "null",
506 };
507
508 static int bwmgr_debugfs_emc_rate_set(void *data, u64 val)
509 {
510         return 0;
511 }
512
513 static int bwmgr_debugfs_emc_rate_get(void *data, u64 *val)
514 {
515         *val = tegra_bwmgr_get_emc_rate();
516         return 0;
517 }
518
519 DEFINE_SIMPLE_ATTRIBUTE(fops_debugfs_emc_rate, bwmgr_debugfs_emc_rate_get,
520                 bwmgr_debugfs_emc_rate_set, "%llu\n");
521
522 static int bwmgr_debugfs_core_emc_rate_get(void *data, u64 *val)
523 {
524         *val = tegra_bwmgr_get_core_emc_rate();
525         return 0;
526 }
527
528 DEFINE_SIMPLE_ATTRIBUTE(fops_debugfs_core_emc_rate,
529         bwmgr_debugfs_core_emc_rate_get, NULL, "%llu\n");
530
531 static int bwmgr_debugfs_floor_set(void *data, u64 val)
532 {
533         tegra_bwmgr_set_emc(bwmgr_debugfs_client_handle, val,
534                         TEGRA_BWMGR_SET_EMC_FLOOR);
535         return 0;
536 }
537
538 static int bwmgr_debugfs_floor_get(void *data, u64 *val)
539 {
540         *val = bwmgr_debugfs_client_handle->floor;
541         return 0;
542 }
543
544 DEFINE_SIMPLE_ATTRIBUTE(fops_debugfs_floor, bwmgr_debugfs_floor_get,
545                 bwmgr_debugfs_floor_set, "%llu\n");
546
547 static int bwmgr_debugfs_cap_set(void *data, u64 val)
548 {
549         tegra_bwmgr_set_emc(bwmgr_debugfs_client_handle, val,
550                         TEGRA_BWMGR_SET_EMC_CAP);
551         return 0;
552 }
553
554 static int bwmgr_debugfs_cap_get(void *data, u64 *val)
555 {
556         *val = bwmgr_debugfs_client_handle->cap;
557         return 0;
558 }
559
560 DEFINE_SIMPLE_ATTRIBUTE(fops_debugfs_cap, bwmgr_debugfs_cap_get,
561                 bwmgr_debugfs_cap_set, "%llu\n");
562
563 static int bwmgr_debugfs_iso_cap_set(void *data, u64 val)
564 {
565         tegra_bwmgr_set_emc(bwmgr_debugfs_client_handle, val,
566                         TEGRA_BWMGR_SET_EMC_ISO_CAP);
567         return 0;
568 }
569
570 static int bwmgr_debugfs_iso_cap_get(void *data, u64 *val)
571 {
572         *val = bwmgr_debugfs_client_handle->iso_cap;
573         return 0;
574 }
575
576 DEFINE_SIMPLE_ATTRIBUTE(fops_debugfs_iso_cap, bwmgr_debugfs_iso_cap_get,
577                 bwmgr_debugfs_iso_cap_set, "%llu\n");
578
579 static int bwmgr_debugfs_bw_set(void *data, u64 val)
580 {
581         tegra_bwmgr_set_emc(bwmgr_debugfs_client_handle, val,
582                         TEGRA_BWMGR_SET_EMC_SHARED_BW);
583         return 0;
584 }
585
586 static int bwmgr_debugfs_bw_get(void *data, u64 *val)
587 {
588         *val = bwmgr_debugfs_client_handle->bw;
589         return 0;
590 }
591
592 DEFINE_SIMPLE_ATTRIBUTE(fops_debugfs_bw, bwmgr_debugfs_bw_get,
593                 bwmgr_debugfs_bw_set, "%llu\n");
594
595 static int bwmgr_debugfs_iso_bw_set(void *data, u64 val)
596 {
597         tegra_bwmgr_set_emc(bwmgr_debugfs_client_handle, val,
598                         TEGRA_BWMGR_SET_EMC_SHARED_BW_ISO);
599         return 0;
600 }
601
602 static int bwmgr_debugfs_iso_bw_get(void *data, u64 *val)
603 {
604         *val = bwmgr_debugfs_client_handle->iso_bw;
605         return 0;
606 }
607
608 static int bwmgr_clients_info_show(struct seq_file *s, void *data)
609 {
610         int i;
611
612         bwmgr_lock();
613         seq_printf(s, "%15s%15s%15s%15s%15s%15s (Khz)\n", "Client",
614                         "Floor", "SharedBw", "SharedIsoBw", "Cap",
615                         "IsoCap");
616         for (i = 0; i < TEGRA_BWMGR_CLIENT_COUNT; i++) {
617                 seq_printf(s, "%15s%15lu%15lu%15lu%15lu%15lu\n",
618                                 tegra_bwmgr_client_names[i],
619                                 bwmgr.bwmgr_client[i].floor / 1000,
620                                 bwmgr.bwmgr_client[i].bw / 1000,
621                                 bwmgr.bwmgr_client[i].iso_bw / 1000,
622                                 bwmgr.bwmgr_client[i].cap / 1000,
623                                 bwmgr.bwmgr_client[i].iso_cap / 1000);
624         }
625         seq_printf(s, "Total BW requested                              : %lu (Khz)\n",
626                                  debug_info.bw / 1000);
627         seq_printf(s, "Total ISO_BW requested                          : %lu (Khz)\n",
628                                  debug_info.iso_bw / 1000);
629         seq_printf(s, "Effective floor request                         : %lu (Khz)\n",
630                                  debug_info.floor / 1000);
631         seq_printf(s, "Effective NON_ISO_CAP                           : %lu (Khz)\n",
632                                  debug_info.non_iso_cap / 1000);
633         seq_printf(s, "Effective ISO_CAP                               : %lu (Khz)\n",
634                                  debug_info.iso_cap / 1000);
635         seq_printf(s, "Total BW + ISO_BW                               : %lu (Khz)\n",
636                                  (debug_info.bw + debug_info.iso_bw) / 1000);
637         seq_printf(s, "Total BW+ISO_BW after applying efficieny numbers: %lu (Khz)\n",
638                                  debug_info.total_bw_aftr_eff / 1000);
639         seq_printf(s, "Total ISO_BW after applying efficiency          : %lu (Khz)\n",
640                                  debug_info.iso_bw_aftr_eff / 1000);
641         seq_printf(s, "EMC calculated rate                             : %lu (Khz)\n",
642                                  debug_info.calc_freq / 1000);
643         seq_printf(s, "EMC requested(rounded) rate                     : %lu (Khz)\n",
644                                  debug_info.req_freq / 1000);
645         seq_printf(s, "EMC current rate                                : %lu (Khz)\n",
646                                  tegra_bwmgr_get_emc_rate() / 1000);
647         bwmgr_unlock();
648         return 0;
649 }
650 DEFINE_SIMPLE_ATTRIBUTE(fops_debugfs_iso_bw, bwmgr_debugfs_iso_bw_get,
651                 bwmgr_debugfs_iso_bw_set, "%llu\n");
652
653 static int bwmgr_clients_info_open(struct inode *inode, struct file *file)
654 {
655         return single_open(file, bwmgr_clients_info_show, inode->i_private);
656 }
657
658 static const struct file_operations fops_bwmgr_clients_info = {
659         .open = bwmgr_clients_info_open,
660         .read = seq_read,
661         .llseek = seq_lseek,
662         .release = single_release,
663 };
664
665 static void bwmgr_debugfs_init(void)
666 {
667         bwmgr_debugfs_client_handle =
668                 tegra_bwmgr_register(TEGRA_BWMGR_CLIENT_DEBUG);
669
670         if (IS_ERR_OR_NULL(bwmgr_debugfs_client_handle)) {
671                 bwmgr_debugfs_client_handle = NULL;
672                 pr_err("bwmgr: could not register bwmgr debugfs client\n");
673                 return;
674         }
675
676         debugfs_dir = debugfs_create_dir("tegra_bwmgr", NULL);
677         if (debugfs_dir) {
678                 debugfs_create_bool(
679                         "clk_update_disabled", S_IRWXU, debugfs_dir,
680                         &clk_update_disabled);
681                 debugfs_node_emc_min = debugfs_create_u64(
682                         "emc_min_rate", S_IRUSR, debugfs_dir,
683                         (u64 *) &bwmgr.emc_min_rate);
684                 debugfs_node_emc_max = debugfs_create_u64(
685                         "emc_max_rate", S_IRUSR, debugfs_dir,
686                         (u64 *) &bwmgr.emc_max_rate);
687                 debugfs_node_core_emc_rate = debugfs_create_file(
688                         "core_emc_rate", S_IRUSR, debugfs_dir, NULL,
689                          &fops_debugfs_core_emc_rate);
690                 debugfs_node_emc_rate = debugfs_create_file
691                         ("emc_rate", S_IRUSR, debugfs_dir, NULL,
692                          &fops_debugfs_emc_rate);
693                 debugfs_node_floor = debugfs_create_file
694                         ("debug_client_floor", S_IRWXU, debugfs_dir, NULL,
695                          &fops_debugfs_floor);
696                 debugfs_node_cap = debugfs_create_file
697                         ("debug_client_cap", S_IRWXU, debugfs_dir, NULL,
698                          &fops_debugfs_cap);
699                 debugfs_node_iso_cap = debugfs_create_file
700                         ("debug_client_iso_cap", S_IRWXU, debugfs_dir, NULL,
701                          &fops_debugfs_iso_cap);
702                 debugfs_node_bw = debugfs_create_file
703                         ("debug_client_bw", S_IRWXU, debugfs_dir, NULL,
704                          &fops_debugfs_bw);
705                 debugfs_node_iso_bw = debugfs_create_file
706                         ("debug_client_iso_bw", S_IRWXU, debugfs_dir, NULL,
707                          &fops_debugfs_iso_bw);
708                 debugfs_node_clients_info = debugfs_create_file
709                         ("bwmgr_clients_info", S_IRUGO, debugfs_dir, NULL,
710                          &fops_bwmgr_clients_info);
711         } else
712                 pr_err("bwmgr: error creating bwmgr debugfs dir.\n");
713
714         bwmgr_lock();
715         debug_info.non_iso_cap = bwmgr.emc_max_rate;
716         debug_info.iso_cap = bwmgr.emc_max_rate;
717         bwmgr_unlock();
718 }
719
720 #else
721 static void bwmgr_debugfs_init(void) {};
722 #endif /* CONFIG_DEBUG_FS */
723