summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/os/linux/debug_clk_gv100.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/os/linux/debug_clk_gv100.c')
-rw-r--r--drivers/gpu/nvgpu/os/linux/debug_clk_gv100.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/debug_clk_gv100.c b/drivers/gpu/nvgpu/os/linux/debug_clk_gv100.c
new file mode 100644
index 00000000..623f2b6b
--- /dev/null
+++ b/drivers/gpu/nvgpu/os/linux/debug_clk_gv100.c
@@ -0,0 +1,193 @@
1/*
2 * Copyright (c) 2018, NVIDIA Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope 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 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/debugfs.h>
18
19#include "gv100/clk_gv100.h"
20
21#include "os_linux.h"
22
23void nvgpu_clk_arb_pstate_change_lock(struct gk20a *g, bool lock);
24
25static int gv100_get_rate_show(void *data , u64 *val)
26{
27 struct namemap_cfg *c = (struct namemap_cfg *)data;
28 struct gk20a *g = c->g;
29
30 if (!g->ops.clk.get_rate_cntr)
31 return -EINVAL;
32
33 *val = c->is_counter ? (u64)c->scale * g->ops.clk.get_rate_cntr(g, c) :
34 0 /* TODO PLL read */;
35
36 return 0;
37}
38DEFINE_SIMPLE_ATTRIBUTE(get_rate_fops, gv100_get_rate_show, NULL, "%llu\n");
39
40static int sys_cfc_read(void *data , u64 *val)
41{
42 struct gk20a *g = (struct gk20a *)data;
43 bool bload = boardobjgrpmask_bitget(
44 &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super,
45 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_SYS);
46
47 /* val = 1 implies CLFC is loaded or enabled */
48 *val = bload ? 1 : 0;
49 return 0;
50}
51static int sys_cfc_write(void *data , u64 val)
52{
53 struct gk20a *g = (struct gk20a *)data;
54 int status;
55 /* val = 1 implies load or enable the CLFC */
56 bool bload = val ? true : false;
57
58 nvgpu_clk_arb_pstate_change_lock(g, true);
59 status = clk_pmu_freq_controller_load(g, bload,
60 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_SYS);
61 nvgpu_clk_arb_pstate_change_lock(g, false);
62
63 return status;
64}
65DEFINE_SIMPLE_ATTRIBUTE(sys_cfc_fops, sys_cfc_read, sys_cfc_write, "%llu\n");
66
67static int ltc_cfc_read(void *data , u64 *val)
68{
69 struct gk20a *g = (struct gk20a *)data;
70 bool bload = boardobjgrpmask_bitget(
71 &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super,
72 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_LTC);
73
74 /* val = 1 implies CLFC is loaded or enabled */
75 *val = bload ? 1 : 0;
76 return 0;
77}
78static int ltc_cfc_write(void *data , u64 val)
79{
80 struct gk20a *g = (struct gk20a *)data;
81 int status;
82 /* val = 1 implies load or enable the CLFC */
83 bool bload = val ? true : false;
84
85 nvgpu_clk_arb_pstate_change_lock(g, true);
86 status = clk_pmu_freq_controller_load(g, bload,
87 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_LTC);
88 nvgpu_clk_arb_pstate_change_lock(g, false);
89
90 return status;
91}
92DEFINE_SIMPLE_ATTRIBUTE(ltc_cfc_fops, ltc_cfc_read, ltc_cfc_write, "%llu\n");
93
94static int xbar_cfc_read(void *data , u64 *val)
95{
96 struct gk20a *g = (struct gk20a *)data;
97 bool bload = boardobjgrpmask_bitget(
98 &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super,
99 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_XBAR);
100
101 /* val = 1 implies CLFC is loaded or enabled */
102 *val = bload ? 1 : 0;
103 return 0;
104}
105static int xbar_cfc_write(void *data , u64 val)
106{
107 struct gk20a *g = (struct gk20a *)data;
108 int status;
109 /* val = 1 implies load or enable the CLFC */
110 bool bload = val ? true : false;
111
112 nvgpu_clk_arb_pstate_change_lock(g, true);
113 status = clk_pmu_freq_controller_load(g, bload,
114 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_XBAR);
115 nvgpu_clk_arb_pstate_change_lock(g, false);
116
117 return status;
118}
119DEFINE_SIMPLE_ATTRIBUTE(xbar_cfc_fops, xbar_cfc_read,
120 xbar_cfc_write, "%llu\n");
121
122static int gpc_cfc_read(void *data , u64 *val)
123{
124 struct gk20a *g = (struct gk20a *)data;
125 bool bload = boardobjgrpmask_bitget(
126 &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super,
127 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC0);
128
129 /* val = 1 implies CLFC is loaded or enabled */
130 *val = bload ? 1 : 0;
131 return 0;
132}
133static int gpc_cfc_write(void *data , u64 val)
134{
135 struct gk20a *g = (struct gk20a *)data;
136 int status;
137 /* val = 1 implies load or enable the CLFC */
138 bool bload = val ? true : false;
139
140 nvgpu_clk_arb_pstate_change_lock(g, true);
141 status = clk_pmu_freq_controller_load(g, bload,
142 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC0);
143 nvgpu_clk_arb_pstate_change_lock(g, false);
144
145 return status;
146}
147DEFINE_SIMPLE_ATTRIBUTE(gpc_cfc_fops, gpc_cfc_read, gpc_cfc_write, "%llu\n");
148
149int gv100_clk_init_debugfs(struct gk20a *g)
150{
151 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
152 struct dentry *gpu_root = l->debugfs;
153 struct dentry *clocks_root, *clk_freq_ctlr_root;
154 struct dentry *d;
155 unsigned int i;
156
157 if (NULL == (clocks_root = debugfs_create_dir("clocks", gpu_root)))
158 return -ENOMEM;
159
160 clk_freq_ctlr_root = debugfs_create_dir("clk_freq_ctlr", gpu_root);
161 if (clk_freq_ctlr_root == NULL)
162 return -ENOMEM;
163
164 d = debugfs_create_file("sys", S_IRUGO | S_IWUSR, clk_freq_ctlr_root,
165 g, &sys_cfc_fops);
166 d = debugfs_create_file("ltc", S_IRUGO | S_IWUSR, clk_freq_ctlr_root,
167 g, &ltc_cfc_fops);
168 d = debugfs_create_file("xbar", S_IRUGO | S_IWUSR, clk_freq_ctlr_root,
169 g, &xbar_cfc_fops);
170 d = debugfs_create_file("gpc", S_IRUGO | S_IWUSR, clk_freq_ctlr_root,
171 g, &gpc_cfc_fops);
172
173 nvgpu_log(g, gpu_dbg_info, "g=%p", g);
174
175 for (i = 0; i < g->clk.namemap_num; i++) {
176 if (g->clk.clk_namemap[i].is_enable) {
177 d = debugfs_create_file(
178 g->clk.clk_namemap[i].name,
179 S_IRUGO,
180 clocks_root,
181 &g->clk.clk_namemap[i],
182 &get_rate_fops);
183 if (!d)
184 goto err_out;
185 }
186 }
187 return 0;
188
189err_out:
190 pr_err("%s: Failed to make debugfs node\n", __func__);
191 debugfs_remove_recursive(clocks_root);
192 return -ENOMEM;
193}