summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2017-04-19 17:09:05 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-06-27 06:57:13 -0400
commit8b3d94ffd3e5b6d7a622c6ad54692d79bf39d1ce (patch)
treefb8648cd40e99892e18e28de8e8851915a0ac0b9 /drivers/gpu/nvgpu/common
parent52445fba1feac3ee20bf1c3db149adc42715af9e (diff)
gpu: nvgpu: Move sysfs dependencies from HAL to Linux
Move sysfs dependencies from gk20a/ and gp10b/ to common/linux. At the same time the gk20a and gp10b variants are merged into one. JIRA NVGPU-48 Change-Id: I212be8f1beb8d20a57de04a57513e8fa0e2e83b4 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: https://git-master/r/1466055 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r--drivers/gpu/nvgpu/common/linux/driver_common.c3
-rw-r--r--drivers/gpu/nvgpu/common/linux/module.c4
-rw-r--r--drivers/gpu/nvgpu/common/linux/pci.c4
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c6
-rw-r--r--drivers/gpu/nvgpu/common/linux/sysfs.c1023
-rw-r--r--drivers/gpu/nvgpu/common/linux/sysfs.h24
6 files changed, 1053 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/driver_common.c b/drivers/gpu/nvgpu/common/linux/driver_common.c
index c4d40c35..a7bc230c 100644
--- a/drivers/gpu/nvgpu/common/linux/driver_common.c
+++ b/drivers/gpu/nvgpu/common/linux/driver_common.c
@@ -28,6 +28,7 @@
28#include "gk20a/platform_gk20a.h" 28#include "gk20a/platform_gk20a.h"
29#include "module.h" 29#include "module.h"
30#include "os_linux.h" 30#include "os_linux.h"
31#include "sysfs.h"
31 32
32#define EMC3D_DEFAULT_RATIO 750 33#define EMC3D_DEFAULT_RATIO 750
33 34
@@ -190,7 +191,7 @@ int nvgpu_probe(struct gk20a *g,
190 191
191 nvgpu_init_mm_vars(g); 192 nvgpu_init_mm_vars(g);
192 193
193 gk20a_create_sysfs(g->dev); 194 nvgpu_create_sysfs(g->dev);
194 gk20a_debug_init(g, debugfs_symlink); 195 gk20a_debug_init(g, debugfs_symlink);
195 196
196 g->dbg_regops_tmp_buf = nvgpu_kzalloc(g, SZ_4K); 197 g->dbg_regops_tmp_buf = nvgpu_kzalloc(g, SZ_4K);
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c
index bfd2c790..99bbc25e 100644
--- a/drivers/gpu/nvgpu/common/linux/module.c
+++ b/drivers/gpu/nvgpu/common/linux/module.c
@@ -31,8 +31,8 @@
31#include <nvgpu/enabled.h> 31#include <nvgpu/enabled.h>
32#include <nvgpu/debug.h> 32#include <nvgpu/debug.h>
33 33
34#include "gk20a/gk20a.h"
35#include "gk20a/platform_gk20a.h" 34#include "gk20a/platform_gk20a.h"
35#include "sysfs.h"
36#include "vgpu/vgpu.h" 36#include "vgpu/vgpu.h"
37#include "gk20a/gk20a_scale.h" 37#include "gk20a/gk20a_scale.h"
38#include "gk20a/ctxsw_trace_gk20a.h" 38#include "gk20a/ctxsw_trace_gk20a.h"
@@ -985,7 +985,7 @@ static int __exit gk20a_remove(struct platform_device *pdev)
985 985
986 gk20a_debug_deinit(g); 986 gk20a_debug_deinit(g);
987 987
988 gk20a_remove_sysfs(dev); 988 nvgpu_remove_sysfs(dev);
989 989
990 if (platform->secure_buffer.destroy) 990 if (platform->secure_buffer.destroy)
991 platform->secure_buffer.destroy(g, 991 platform->secure_buffer.destroy(g,
diff --git a/drivers/gpu/nvgpu/common/linux/pci.c b/drivers/gpu/nvgpu/common/linux/pci.c
index cb315973..acb1bb9f 100644
--- a/drivers/gpu/nvgpu/common/linux/pci.c
+++ b/drivers/gpu/nvgpu/common/linux/pci.c
@@ -29,7 +29,7 @@
29#include "module.h" 29#include "module.h"
30#include "intr.h" 30#include "intr.h"
31#include "gp106/pmu_mclk_gp106.h" 31#include "gp106/pmu_mclk_gp106.h"
32 32#include "sysfs.h"
33#include "pci.h" 33#include "pci.h"
34 34
35#include "os_linux.h" 35#include "os_linux.h"
@@ -491,7 +491,7 @@ static void nvgpu_pci_remove(struct pci_dev *pdev)
491 debugfs_remove_recursive(platform->debugfs_alias); 491 debugfs_remove_recursive(platform->debugfs_alias);
492#endif 492#endif
493 493
494 gk20a_remove_sysfs(g->dev); 494 nvgpu_remove_sysfs(g->dev);
495 495
496 if (platform->remove) 496 if (platform->remove)
497 platform->remove(g->dev); 497 platform->remove(g->dev);
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
index 5980c592..ab2aa1c5 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
+++ b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
@@ -38,7 +38,6 @@
38#include "gk20a/gk20a_scale.h" 38#include "gk20a/gk20a_scale.h"
39 39
40#include "platform_gk20a_tegra.h" 40#include "platform_gk20a_tegra.h"
41#include "gp10b/gp10b_sysfs.h"
42#include "gp10b/platform_gp10b.h" 41#include "gp10b/platform_gp10b.h"
43#include "platform_gp10b_tegra.h" 42#include "platform_gp10b_tegra.h"
44 43
@@ -161,9 +160,6 @@ static int gp10b_tegra_late_probe(struct device *dev)
161 /* Cause early VPR resize */ 160 /* Cause early VPR resize */
162 gk20a_tegra_secure_page_alloc(dev); 161 gk20a_tegra_secure_page_alloc(dev);
163 162
164 /*Create GP10B specific sysfs*/
165 gp10b_create_sysfs(dev);
166
167 /* Initialise tegra specific scaling quirks */ 163 /* Initialise tegra specific scaling quirks */
168 gp10b_tegra_scale_init(dev); 164 gp10b_tegra_scale_init(dev);
169 return 0; 165 return 0;
@@ -172,8 +168,6 @@ static int gp10b_tegra_late_probe(struct device *dev)
172int gp10b_tegra_remove(struct device *dev) 168int gp10b_tegra_remove(struct device *dev)
173{ 169{
174 gr_gp10b_remove_sysfs(dev); 170 gr_gp10b_remove_sysfs(dev);
175 /*Remove GP10B specific sysfs*/
176 gp10b_remove_sysfs(dev);
177 171
178 /* deinitialise tegra specific scaling quirks */ 172 /* deinitialise tegra specific scaling quirks */
179 gp10b_tegra_scale_exit(dev); 173 gp10b_tegra_scale_exit(dev);
diff --git a/drivers/gpu/nvgpu/common/linux/sysfs.c b/drivers/gpu/nvgpu/common/linux/sysfs.c
new file mode 100644
index 00000000..e0da4661
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/linux/sysfs.c
@@ -0,0 +1,1023 @@
1/*
2 * Copyright (c) 2011-2017, 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/version.h>
18#include <linux/device.h>
19#include <linux/pm_runtime.h>
20#include <linux/fb.h>
21#include <soc/tegra/tegra-dvfs.h>
22
23#include <nvgpu/kmem.h>
24#include <nvgpu/nvhost.h>
25
26#include "sysfs.h"
27#include "gk20a/platform_gk20a.h"
28#include "gk20a/pmu_gk20a.h"
29#include "gk20a/gr_gk20a.h"
30
31#define PTIMER_FP_FACTOR 1000000
32
33#define ROOTRW (S_IRWXU|S_IRGRP|S_IROTH)
34
35static ssize_t elcg_enable_store(struct device *dev,
36 struct device_attribute *attr, const char *buf, size_t count)
37{
38 struct gk20a *g = get_gk20a(dev);
39 unsigned long val = 0;
40 int err;
41
42 if (kstrtoul(buf, 10, &val) < 0)
43 return -EINVAL;
44
45 err = gk20a_busy(g);
46 if (err)
47 return err;
48
49 if (val) {
50 g->elcg_enabled = true;
51 gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO);
52 } else {
53 g->elcg_enabled = false;
54 gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN);
55 }
56
57 gk20a_idle(g);
58
59 nvgpu_info(g, "ELCG is %s.", g->elcg_enabled ? "enabled" :
60 "disabled");
61
62 return count;
63}
64
65static ssize_t elcg_enable_read(struct device *dev,
66 struct device_attribute *attr, char *buf)
67{
68 struct gk20a *g = get_gk20a(dev);
69
70 return snprintf(buf, PAGE_SIZE, "%d\n", g->elcg_enabled ? 1 : 0);
71}
72
73static DEVICE_ATTR(elcg_enable, ROOTRW, elcg_enable_read, elcg_enable_store);
74
75static ssize_t blcg_enable_store(struct device *dev,
76 struct device_attribute *attr, const char *buf, size_t count)
77{
78 struct gk20a *g = get_gk20a(dev);
79 unsigned long val = 0;
80 int err;
81
82 if (kstrtoul(buf, 10, &val) < 0)
83 return -EINVAL;
84
85 if (val)
86 g->blcg_enabled = true;
87 else
88 g->blcg_enabled = false;
89
90 err = gk20a_busy(g);
91 if (err)
92 return err;
93
94 if (g->ops.clock_gating.blcg_bus_load_gating_prod)
95 g->ops.clock_gating.blcg_bus_load_gating_prod(g,
96 g->blcg_enabled);
97 if (g->ops.clock_gating.blcg_ce_load_gating_prod)
98 g->ops.clock_gating.blcg_ce_load_gating_prod(g,
99 g->blcg_enabled);
100 if (g->ops.clock_gating.blcg_ctxsw_firmware_load_gating_prod)
101 g->ops.clock_gating.blcg_ctxsw_firmware_load_gating_prod(g,
102 g->blcg_enabled);
103 if (g->ops.clock_gating.blcg_fb_load_gating_prod)
104 g->ops.clock_gating.blcg_fb_load_gating_prod(g,
105 g->blcg_enabled);
106 if (g->ops.clock_gating.blcg_fifo_load_gating_prod)
107 g->ops.clock_gating.blcg_fifo_load_gating_prod(g,
108 g->blcg_enabled);
109 if (g->ops.clock_gating.blcg_gr_load_gating_prod)
110 g->ops.clock_gating.blcg_gr_load_gating_prod(g,
111 g->blcg_enabled);
112 if (g->ops.clock_gating.blcg_ltc_load_gating_prod)
113 g->ops.clock_gating.blcg_ltc_load_gating_prod(g,
114 g->blcg_enabled);
115 if (g->ops.clock_gating.blcg_pmu_load_gating_prod)
116 g->ops.clock_gating.blcg_pmu_load_gating_prod(g,
117 g->blcg_enabled);
118 if (g->ops.clock_gating.blcg_xbar_load_gating_prod)
119 g->ops.clock_gating.blcg_xbar_load_gating_prod(g,
120 g->blcg_enabled);
121 gk20a_idle(g);
122
123 nvgpu_info(g, "BLCG is %s.", g->blcg_enabled ? "enabled" :
124 "disabled");
125
126 return count;
127}
128
129static ssize_t blcg_enable_read(struct device *dev,
130 struct device_attribute *attr, char *buf)
131{
132 struct gk20a *g = get_gk20a(dev);
133
134 return snprintf(buf, PAGE_SIZE, "%d\n", g->blcg_enabled ? 1 : 0);
135}
136
137
138static DEVICE_ATTR(blcg_enable, ROOTRW, blcg_enable_read, blcg_enable_store);
139
140static ssize_t slcg_enable_store(struct device *dev,
141 struct device_attribute *attr, const char *buf, size_t count)
142{
143 struct gk20a *g = get_gk20a(dev);
144 unsigned long val = 0;
145 int err;
146
147 if (kstrtoul(buf, 10, &val) < 0)
148 return -EINVAL;
149
150 if (val)
151 g->slcg_enabled = true;
152 else
153 g->slcg_enabled = false;
154
155 /*
156 * TODO: slcg_therm_load_gating is not enabled anywhere during
157 * init. Therefore, it would be incongruous to add it here. Once
158 * it is added to init, we should add it here too.
159 */
160 err = gk20a_busy(g);
161 if (err)
162 return err;
163
164 if (g->ops.clock_gating.slcg_bus_load_gating_prod)
165 g->ops.clock_gating.slcg_bus_load_gating_prod(g,
166 g->slcg_enabled);
167 if (g->ops.clock_gating.slcg_ce2_load_gating_prod)
168 g->ops.clock_gating.slcg_ce2_load_gating_prod(g,
169 g->slcg_enabled);
170 if (g->ops.clock_gating.slcg_chiplet_load_gating_prod)
171 g->ops.clock_gating.slcg_chiplet_load_gating_prod(g,
172 g->slcg_enabled);
173 if (g->ops.clock_gating.slcg_ctxsw_firmware_load_gating_prod)
174 g->ops.clock_gating.slcg_ctxsw_firmware_load_gating_prod(g,
175 g->slcg_enabled);
176 if (g->ops.clock_gating.slcg_fb_load_gating_prod)
177 g->ops.clock_gating.slcg_fb_load_gating_prod(g,
178 g->slcg_enabled);
179 if (g->ops.clock_gating.slcg_fifo_load_gating_prod)
180 g->ops.clock_gating.slcg_fifo_load_gating_prod(g,
181 g->slcg_enabled);
182 if (g->ops.clock_gating.slcg_gr_load_gating_prod)
183 g->ops.clock_gating.slcg_gr_load_gating_prod(g,
184 g->slcg_enabled);
185 if (g->ops.clock_gating.slcg_ltc_load_gating_prod)
186 g->ops.clock_gating.slcg_ltc_load_gating_prod(g,
187 g->slcg_enabled);
188 if (g->ops.clock_gating.slcg_perf_load_gating_prod)
189 g->ops.clock_gating.slcg_perf_load_gating_prod(g,
190 g->slcg_enabled);
191 if (g->ops.clock_gating.slcg_priring_load_gating_prod)
192 g->ops.clock_gating.slcg_priring_load_gating_prod(g,
193 g->slcg_enabled);
194 if (g->ops.clock_gating.slcg_pmu_load_gating_prod)
195 g->ops.clock_gating.slcg_pmu_load_gating_prod(g,
196 g->slcg_enabled);
197 if (g->ops.clock_gating.slcg_xbar_load_gating_prod)
198 g->ops.clock_gating.slcg_xbar_load_gating_prod(g,
199 g->slcg_enabled);
200 gk20a_idle(g);
201
202 nvgpu_info(g, "SLCG is %s.", g->slcg_enabled ? "enabled" :
203 "disabled");
204
205 return count;
206}
207
208static ssize_t slcg_enable_read(struct device *dev,
209 struct device_attribute *attr, char *buf)
210{
211 struct gk20a *g = get_gk20a(dev);
212
213 return snprintf(buf, PAGE_SIZE, "%d\n", g->slcg_enabled ? 1 : 0);
214}
215
216static DEVICE_ATTR(slcg_enable, ROOTRW, slcg_enable_read, slcg_enable_store);
217
218static ssize_t ptimer_scale_factor_show(struct device *dev,
219 struct device_attribute *attr,
220 char *buf)
221{
222 struct gk20a *g = get_gk20a(dev);
223 struct gk20a_platform *platform = dev_get_drvdata(dev);
224 u32 src_freq_hz = platform->ptimer_src_freq;
225 u32 scaling_factor_fp;
226 ssize_t res;
227
228 if (!src_freq_hz) {
229 nvgpu_err(g, "reference clk_m rate is not set correctly");
230 return -EINVAL;
231 }
232
233 scaling_factor_fp = (u32)(PTIMER_REF_FREQ_HZ) /
234 ((u32)(src_freq_hz) /
235 (u32)(PTIMER_FP_FACTOR));
236 res = snprintf(buf,
237 PAGE_SIZE,
238 "%u.%u\n",
239 scaling_factor_fp / PTIMER_FP_FACTOR,
240 scaling_factor_fp % PTIMER_FP_FACTOR);
241
242 return res;
243
244}
245
246static DEVICE_ATTR(ptimer_scale_factor,
247 S_IRUGO,
248 ptimer_scale_factor_show,
249 NULL);
250
251static ssize_t ptimer_ref_freq_show(struct device *dev,
252 struct device_attribute *attr,
253 char *buf)
254{
255 struct gk20a *g = get_gk20a(dev);
256 struct gk20a_platform *platform = dev_get_drvdata(dev);
257 u32 src_freq_hz = platform->ptimer_src_freq;
258 ssize_t res;
259
260 if (!src_freq_hz) {
261 nvgpu_err(g, "reference clk_m rate is not set correctly");
262 return -EINVAL;
263 }
264
265 res = snprintf(buf, PAGE_SIZE, "%u\n", PTIMER_REF_FREQ_HZ);
266
267 return res;
268
269}
270
271static DEVICE_ATTR(ptimer_ref_freq,
272 S_IRUGO,
273 ptimer_ref_freq_show,
274 NULL);
275
276static ssize_t ptimer_src_freq_show(struct device *dev,
277 struct device_attribute *attr,
278 char *buf)
279{
280 struct gk20a *g = get_gk20a(dev);
281 struct gk20a_platform *platform = dev_get_drvdata(dev);
282 u32 src_freq_hz = platform->ptimer_src_freq;
283 ssize_t res;
284
285 if (!src_freq_hz) {
286 nvgpu_err(g, "reference clk_m rate is not set correctly");
287 return -EINVAL;
288 }
289
290 res = snprintf(buf, PAGE_SIZE, "%u\n", src_freq_hz);
291
292 return res;
293
294}
295
296static DEVICE_ATTR(ptimer_src_freq,
297 S_IRUGO,
298 ptimer_src_freq_show,
299 NULL);
300
301
302#if defined(CONFIG_PM)
303static ssize_t railgate_enable_store(struct device *dev,
304 struct device_attribute *attr, const char *buf, size_t count)
305{
306 unsigned long railgate_enable = 0;
307 /* dev is guaranteed to be valid here. Ok to de-reference */
308 struct gk20a *g = get_gk20a(dev);
309 int err = 0;
310
311 if (kstrtoul(buf, 10, &railgate_enable) < 0)
312 return -EINVAL;
313
314 if (railgate_enable && !g->can_railgate) {
315 /* release extra ref count */
316 gk20a_idle(g);
317 g->can_railgate = true;
318 g->user_railgate_disabled = false;
319 } else if (railgate_enable == 0 && g->can_railgate) {
320 /* take extra ref count */
321 err = gk20a_busy(g);
322 if (err)
323 return err;
324 g->can_railgate = false;
325 g->user_railgate_disabled = true;
326 }
327
328 nvgpu_info(g, "railgate is %s.", g->can_railgate ?
329 "enabled" : "disabled");
330
331 return count;
332}
333
334static ssize_t railgate_enable_read(struct device *dev,
335 struct device_attribute *attr, char *buf)
336{
337 struct gk20a *g = get_gk20a(dev);
338
339 return snprintf(buf, PAGE_SIZE, "%d\n", g->can_railgate ? 1 : 0);
340}
341
342static DEVICE_ATTR(railgate_enable, ROOTRW, railgate_enable_read,
343 railgate_enable_store);
344#endif
345
346static ssize_t railgate_delay_store(struct device *dev,
347 struct device_attribute *attr,
348 const char *buf, size_t count)
349{
350 int railgate_delay = 0, ret = 0;
351 struct gk20a *g = get_gk20a(dev);
352 int err;
353
354 if (!g->can_railgate) {
355 nvgpu_info(g, "does not support power-gating");
356 return count;
357 }
358
359 ret = sscanf(buf, "%d", &railgate_delay);
360 if (ret == 1 && railgate_delay >= 0) {
361 g->railgate_delay = railgate_delay;
362 pm_runtime_set_autosuspend_delay(dev, g->railgate_delay);
363 } else
364 nvgpu_err(g, "Invalid powergate delay");
365
366 /* wake-up system to make rail-gating delay effective immediately */
367 err = gk20a_busy(g);
368 if (err)
369 return err;
370 gk20a_idle(g);
371
372 return count;
373}
374static ssize_t railgate_delay_show(struct device *dev,
375 struct device_attribute *attr, char *buf)
376{
377 struct gk20a *g = get_gk20a(dev);
378
379 return snprintf(buf, PAGE_SIZE, "%d\n", g->railgate_delay);
380}
381static DEVICE_ATTR(railgate_delay, ROOTRW, railgate_delay_show,
382 railgate_delay_store);
383
384static ssize_t is_railgated_show(struct device *dev,
385 struct device_attribute *attr, char *buf)
386{
387 struct gk20a_platform *platform = dev_get_drvdata(dev);
388 bool is_railgated = 0;
389
390 if (platform->is_railgated)
391 is_railgated = platform->is_railgated(platform->g->dev);
392
393 return snprintf(buf, PAGE_SIZE, "%s\n", is_railgated ? "yes" : "no");
394}
395static DEVICE_ATTR(is_railgated, S_IRUGO, is_railgated_show, NULL);
396
397static ssize_t counters_show(struct device *dev,
398 struct device_attribute *attr, char *buf)
399{
400 struct gk20a *g = get_gk20a(dev);
401 u32 busy_cycles, total_cycles;
402 ssize_t res;
403
404 nvgpu_pmu_get_load_counters(g, &busy_cycles, &total_cycles);
405
406 res = snprintf(buf, PAGE_SIZE, "%u %u\n", busy_cycles, total_cycles);
407
408 return res;
409}
410static DEVICE_ATTR(counters, S_IRUGO, counters_show, NULL);
411
412static ssize_t counters_show_reset(struct device *dev,
413 struct device_attribute *attr, char *buf)
414{
415 ssize_t res = counters_show(dev, attr, buf);
416 struct gk20a *g = get_gk20a(dev);
417
418 nvgpu_pmu_reset_load_counters(g);
419
420 return res;
421}
422static DEVICE_ATTR(counters_reset, S_IRUGO, counters_show_reset, NULL);
423
424static ssize_t gk20a_load_show(struct device *dev,
425 struct device_attribute *attr,
426 char *buf)
427{
428 struct gk20a *g = get_gk20a(dev);
429 u32 busy_time;
430 ssize_t res;
431 int err;
432
433 if (!g->power_on) {
434 busy_time = 0;
435 } else {
436 err = gk20a_busy(g);
437 if (err)
438 return err;
439
440 nvgpu_pmu_load_update(g);
441 nvgpu_pmu_load_norm(g, &busy_time);
442 gk20a_idle(g);
443 }
444
445 res = snprintf(buf, PAGE_SIZE, "%u\n", busy_time);
446
447 return res;
448}
449static DEVICE_ATTR(load, S_IRUGO, gk20a_load_show, NULL);
450
451static ssize_t elpg_enable_store(struct device *dev,
452 struct device_attribute *attr, const char *buf, size_t count)
453{
454 struct gk20a *g = get_gk20a(dev);
455 unsigned long val = 0;
456 int err;
457
458 if (kstrtoul(buf, 10, &val) < 0)
459 return -EINVAL;
460
461 if (!g->power_on) {
462 g->elpg_enabled = val ? true : false;
463 } else {
464 err = gk20a_busy(g);
465 if (err)
466 return -EAGAIN;
467 /*
468 * Since elpg is refcounted, we should not unnecessarily call
469 * enable/disable if it is already so.
470 */
471 if (val && !g->elpg_enabled) {
472 g->elpg_enabled = true;
473 nvgpu_pmu_pg_global_enable(g, true);
474
475 } else if (!val && g->elpg_enabled) {
476 if (g->ops.pmu.pmu_pg_engines_feature_list &&
477 g->ops.pmu.pmu_pg_engines_feature_list(g,
478 PMU_PG_ELPG_ENGINE_ID_GRAPHICS) !=
479 PMU_PG_FEATURE_GR_POWER_GATING_ENABLED) {
480 nvgpu_pmu_pg_global_enable(g, false);
481 g->elpg_enabled = false;
482 } else {
483 g->elpg_enabled = false;
484 nvgpu_pmu_pg_global_enable(g, false);
485 }
486 }
487 gk20a_idle(g);
488 }
489 nvgpu_info(g, "ELPG is %s.", g->elpg_enabled ? "enabled" :
490 "disabled");
491
492 return count;
493}
494
495static ssize_t elpg_enable_read(struct device *dev,
496 struct device_attribute *attr, char *buf)
497{
498 struct gk20a *g = get_gk20a(dev);
499
500 return snprintf(buf, PAGE_SIZE, "%d\n", g->elpg_enabled ? 1 : 0);
501}
502
503static DEVICE_ATTR(elpg_enable, ROOTRW, elpg_enable_read, elpg_enable_store);
504
505static ssize_t mscg_enable_store(struct device *dev,
506 struct device_attribute *attr, const char *buf, size_t count)
507{
508 struct gk20a *g = get_gk20a(dev);
509 struct nvgpu_pmu *pmu = &g->pmu;
510 unsigned long val = 0;
511 int err;
512
513 if (kstrtoul(buf, 10, &val) < 0)
514 return -EINVAL;
515
516 if (!g->power_on) {
517 g->mscg_enabled = val ? true : false;
518 } else {
519 err = gk20a_busy(g);
520 if (err)
521 return -EAGAIN;
522 /*
523 * Since elpg is refcounted, we should not unnecessarily call
524 * enable/disable if it is already so.
525 */
526 if (val && !g->mscg_enabled) {
527 g->mscg_enabled = true;
528 if (g->ops.pmu.pmu_is_lpwr_feature_supported(g,
529 PMU_PG_LPWR_FEATURE_MSCG)) {
530 if (!ACCESS_ONCE(pmu->mscg_stat)) {
531 WRITE_ONCE(pmu->mscg_stat,
532 PMU_MSCG_ENABLED);
533 /* make status visible */
534 smp_mb();
535 }
536 }
537
538 } else if (!val && g->mscg_enabled) {
539 if (g->ops.pmu.pmu_is_lpwr_feature_supported(g,
540 PMU_PG_LPWR_FEATURE_MSCG)) {
541 nvgpu_pmu_pg_global_enable(g, false);
542 WRITE_ONCE(pmu->mscg_stat, PMU_MSCG_DISABLED);
543 /* make status visible */
544 smp_mb();
545 g->mscg_enabled = false;
546 if (g->elpg_enabled)
547 nvgpu_pmu_pg_global_enable(g, true);
548 }
549 g->mscg_enabled = false;
550 }
551 gk20a_idle(g);
552 }
553 nvgpu_info(g, "MSCG is %s.", g->mscg_enabled ? "enabled" :
554 "disabled");
555
556 return count;
557}
558
559static ssize_t mscg_enable_read(struct device *dev,
560 struct device_attribute *attr, char *buf)
561{
562 struct gk20a *g = get_gk20a(dev);
563
564 return snprintf(buf, PAGE_SIZE, "%d\n", g->mscg_enabled ? 1 : 0);
565}
566
567static DEVICE_ATTR(mscg_enable, ROOTRW, mscg_enable_read, mscg_enable_store);
568
569static ssize_t aelpg_param_store(struct device *dev,
570 struct device_attribute *attr, const char *buf, size_t count)
571{
572 struct gk20a *g = get_gk20a(dev);
573 int status = 0;
574 union pmu_ap_cmd ap_cmd;
575 int *paramlist = (int *)g->pmu.aelpg_param;
576 u32 defaultparam[5] = {
577 APCTRL_SAMPLING_PERIOD_PG_DEFAULT_US,
578 APCTRL_MINIMUM_IDLE_FILTER_DEFAULT_US,
579 APCTRL_MINIMUM_TARGET_SAVING_DEFAULT_US,
580 APCTRL_POWER_BREAKEVEN_DEFAULT_US,
581 APCTRL_CYCLES_PER_SAMPLE_MAX_DEFAULT
582 };
583
584 /* Get each parameter value from input string*/
585 sscanf(buf, "%d %d %d %d %d", &paramlist[0], &paramlist[1],
586 &paramlist[2], &paramlist[3], &paramlist[4]);
587
588 /* If parameter value is 0 then reset to SW default values*/
589 if ((paramlist[0] | paramlist[1] | paramlist[2]
590 | paramlist[3] | paramlist[4]) == 0x00) {
591 memcpy(paramlist, defaultparam, sizeof(defaultparam));
592 }
593
594 /* If aelpg is enabled & pmu is ready then post values to
595 * PMU else store then post later
596 */
597 if (g->aelpg_enabled && g->pmu.pmu_ready) {
598 /* Disable AELPG */
599 ap_cmd.disable_ctrl.cmd_id = PMU_AP_CMD_ID_DISABLE_CTRL;
600 ap_cmd.disable_ctrl.ctrl_id = PMU_AP_CTRL_ID_GRAPHICS;
601 status = nvgpu_pmu_ap_send_command(g, &ap_cmd, false);
602
603 /* Enable AELPG */
604 nvgpu_aelpg_init(g);
605 nvgpu_aelpg_init_and_enable(g, PMU_AP_CTRL_ID_GRAPHICS);
606 }
607
608 return count;
609}
610
611static ssize_t aelpg_param_read(struct device *dev,
612 struct device_attribute *attr, char *buf)
613{
614 struct gk20a *g = get_gk20a(dev);
615
616 return snprintf(buf, PAGE_SIZE,
617 "%d %d %d %d %d\n", g->pmu.aelpg_param[0],
618 g->pmu.aelpg_param[1], g->pmu.aelpg_param[2],
619 g->pmu.aelpg_param[3], g->pmu.aelpg_param[4]);
620}
621
622static DEVICE_ATTR(aelpg_param, ROOTRW,
623 aelpg_param_read, aelpg_param_store);
624
625static ssize_t aelpg_enable_store(struct device *dev,
626 struct device_attribute *attr, const char *buf, size_t count)
627{
628 struct gk20a *g = get_gk20a(dev);
629 unsigned long val = 0;
630 int status = 0;
631 union pmu_ap_cmd ap_cmd;
632 int err;
633
634 if (kstrtoul(buf, 10, &val) < 0)
635 return -EINVAL;
636
637 err = gk20a_busy(g);
638 if (err)
639 return err;
640
641 if (g->pmu.pmu_ready) {
642 if (val && !g->aelpg_enabled) {
643 g->aelpg_enabled = true;
644 /* Enable AELPG */
645 ap_cmd.enable_ctrl.cmd_id = PMU_AP_CMD_ID_ENABLE_CTRL;
646 ap_cmd.enable_ctrl.ctrl_id = PMU_AP_CTRL_ID_GRAPHICS;
647 status = nvgpu_pmu_ap_send_command(g, &ap_cmd, false);
648 } else if (!val && g->aelpg_enabled) {
649 g->aelpg_enabled = false;
650 /* Disable AELPG */
651 ap_cmd.disable_ctrl.cmd_id = PMU_AP_CMD_ID_DISABLE_CTRL;
652 ap_cmd.disable_ctrl.ctrl_id = PMU_AP_CTRL_ID_GRAPHICS;
653 status = nvgpu_pmu_ap_send_command(g, &ap_cmd, false);
654 }
655 } else {
656 nvgpu_info(g, "PMU is not ready, AELPG request failed");
657 }
658 gk20a_idle(g);
659
660 nvgpu_info(g, "AELPG is %s.", g->aelpg_enabled ? "enabled" :
661 "disabled");
662
663 return count;
664}
665
666static ssize_t aelpg_enable_read(struct device *dev,
667 struct device_attribute *attr, char *buf)
668{
669 struct gk20a *g = get_gk20a(dev);
670
671 return snprintf(buf, PAGE_SIZE, "%d\n", g->aelpg_enabled ? 1 : 0);
672}
673
674static DEVICE_ATTR(aelpg_enable, ROOTRW,
675 aelpg_enable_read, aelpg_enable_store);
676
677
678static ssize_t allow_all_enable_read(struct device *dev,
679 struct device_attribute *attr, char *buf)
680{
681 struct gk20a *g = get_gk20a(dev);
682
683 return snprintf(buf, PAGE_SIZE, "%d\n", g->allow_all ? 1 : 0);
684}
685
686static ssize_t allow_all_enable_store(struct device *dev,
687 struct device_attribute *attr, const char *buf, size_t count)
688{
689 struct gk20a *g = get_gk20a(dev);
690 unsigned long val = 0;
691 int err;
692
693 if (kstrtoul(buf, 10, &val) < 0)
694 return -EINVAL;
695
696 err = gk20a_busy(g);
697 g->allow_all = (val ? true : false);
698 gk20a_idle(g);
699
700 return count;
701}
702
703static DEVICE_ATTR(allow_all, ROOTRW,
704 allow_all_enable_read, allow_all_enable_store);
705
706static ssize_t emc3d_ratio_store(struct device *dev,
707 struct device_attribute *attr, const char *buf, size_t count)
708{
709 struct gk20a *g = get_gk20a(dev);
710 unsigned long val = 0;
711
712 if (kstrtoul(buf, 10, &val) < 0)
713 return -EINVAL;
714
715 g->emc3d_ratio = val;
716
717 return count;
718}
719
720static ssize_t emc3d_ratio_read(struct device *dev,
721 struct device_attribute *attr, char *buf)
722{
723 struct gk20a *g = get_gk20a(dev);
724
725 return snprintf(buf, PAGE_SIZE, "%d\n", g->emc3d_ratio);
726}
727
728static DEVICE_ATTR(emc3d_ratio, ROOTRW, emc3d_ratio_read, emc3d_ratio_store);
729
730static ssize_t fmax_at_vmin_safe_read(struct device *dev,
731 struct device_attribute *attr, char *buf)
732{
733 struct gk20a *g = get_gk20a(dev);
734 unsigned long gpu_fmax_at_vmin_hz = 0;
735 struct clk *clk = g->clk.tegra_clk;
736
737 gpu_fmax_at_vmin_hz = tegra_dvfs_get_fmax_at_vmin_safe_t(clk);
738
739 return snprintf(buf, PAGE_SIZE, "%d\n", (int)(gpu_fmax_at_vmin_hz));
740}
741
742static DEVICE_ATTR(fmax_at_vmin_safe, S_IRUGO, fmax_at_vmin_safe_read, NULL);
743
744#ifdef CONFIG_PM
745static ssize_t force_idle_store(struct device *dev,
746 struct device_attribute *attr, const char *buf, size_t count)
747{
748 struct gk20a *g = get_gk20a(dev);
749 unsigned long val = 0;
750 int err = 0;
751
752 if (kstrtoul(buf, 10, &val) < 0)
753 return -EINVAL;
754
755 if (val) {
756 if (g->forced_idle)
757 return count; /* do nothing */
758 else {
759 err = __gk20a_do_idle(g, false);
760 if (!err) {
761 g->forced_idle = 1;
762 nvgpu_info(g, "gpu is idle : %d",
763 g->forced_idle);
764 }
765 }
766 } else {
767 if (!g->forced_idle)
768 return count; /* do nothing */
769 else {
770 err = __gk20a_do_unidle(g);
771 if (!err) {
772 g->forced_idle = 0;
773 nvgpu_info(g, "gpu is idle : %d",
774 g->forced_idle);
775 }
776 }
777 }
778
779 return count;
780}
781
782static ssize_t force_idle_read(struct device *dev,
783 struct device_attribute *attr, char *buf)
784{
785 struct gk20a *g = get_gk20a(dev);
786
787 return snprintf(buf, PAGE_SIZE, "%d\n", g->forced_idle ? 1 : 0);
788}
789
790static DEVICE_ATTR(force_idle, ROOTRW, force_idle_read, force_idle_store);
791#endif
792
793static ssize_t tpc_fs_mask_store(struct device *dev,
794 struct device_attribute *attr, const char *buf, size_t count)
795{
796 struct gk20a *g = get_gk20a(dev);
797 unsigned long val = 0;
798
799 if (kstrtoul(buf, 10, &val) < 0)
800 return -EINVAL;
801
802 if (!g->gr.gpc_tpc_mask)
803 return -ENODEV;
804
805 if (val && val != g->gr.gpc_tpc_mask[0] && g->ops.gr.set_gpc_tpc_mask) {
806 g->gr.gpc_tpc_mask[0] = val;
807 g->tpc_fs_mask_user = val;
808
809 g->ops.gr.set_gpc_tpc_mask(g, 0);
810
811 nvgpu_vfree(g, g->gr.ctx_vars.local_golden_image);
812 g->gr.ctx_vars.local_golden_image = NULL;
813 g->gr.ctx_vars.golden_image_initialized = false;
814 g->gr.ctx_vars.golden_image_size = 0;
815 g->gr.sw_ready = false;
816 }
817
818 return count;
819}
820
821static ssize_t tpc_fs_mask_read(struct device *dev,
822 struct device_attribute *attr, char *buf)
823{
824 struct gk20a *g = get_gk20a(dev);
825 struct gr_gk20a *gr = &g->gr;
826 u32 gpc_index;
827 u32 tpc_fs_mask = 0;
828 int err = 0;
829
830 err = gk20a_busy(g);
831 if (err)
832 return err;
833
834 for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) {
835 if (g->ops.gr.get_gpc_tpc_mask)
836 tpc_fs_mask |=
837 g->ops.gr.get_gpc_tpc_mask(g, gpc_index) <<
838 (gr->max_tpc_per_gpc_count * gpc_index);
839 }
840
841 gk20a_idle(g);
842
843 return snprintf(buf, PAGE_SIZE, "0x%x\n", tpc_fs_mask);
844}
845
846static DEVICE_ATTR(tpc_fs_mask, ROOTRW, tpc_fs_mask_read, tpc_fs_mask_store);
847
848static ssize_t min_timeslice_us_read(struct device *dev,
849 struct device_attribute *attr, char *buf)
850{
851 struct gk20a *g = get_gk20a(dev);
852
853 return snprintf(buf, PAGE_SIZE, "%u\n", g->min_timeslice_us);
854}
855
856static ssize_t min_timeslice_us_store(struct device *dev,
857 struct device_attribute *attr, const char *buf, size_t count)
858{
859 struct gk20a *g = get_gk20a(dev);
860 unsigned long val;
861
862 if (kstrtoul(buf, 10, &val) < 0)
863 return -EINVAL;
864
865 if (val > g->max_timeslice_us)
866 return -EINVAL;
867
868 g->min_timeslice_us = val;
869
870 return count;
871}
872
873static DEVICE_ATTR(min_timeslice_us, ROOTRW, min_timeslice_us_read,
874 min_timeslice_us_store);
875
876static ssize_t max_timeslice_us_read(struct device *dev,
877 struct device_attribute *attr, char *buf)
878{
879 struct gk20a *g = get_gk20a(dev);
880
881 return snprintf(buf, PAGE_SIZE, "%u\n", g->max_timeslice_us);
882}
883
884static ssize_t max_timeslice_us_store(struct device *dev,
885 struct device_attribute *attr, const char *buf, size_t count)
886{
887 struct gk20a *g = get_gk20a(dev);
888 unsigned long val;
889
890 if (kstrtoul(buf, 10, &val) < 0)
891 return -EINVAL;
892
893 if (val < g->min_timeslice_us)
894 return -EINVAL;
895
896 g->max_timeslice_us = val;
897
898 return count;
899}
900
901static DEVICE_ATTR(max_timeslice_us, ROOTRW, max_timeslice_us_read,
902 max_timeslice_us_store);
903
904static ssize_t czf_bypass_store(struct device *dev,
905 struct device_attribute *attr, const char *buf, size_t count)
906{
907 struct gk20a *g = get_gk20a(dev);
908 unsigned long val;
909
910 if (kstrtoul(buf, 10, &val) < 0)
911 return -EINVAL;
912
913 if (val >= 4)
914 return -EINVAL;
915
916 g->gr.czf_bypass = val;
917
918 return count;
919}
920
921static ssize_t czf_bypass_read(struct device *dev,
922 struct device_attribute *attr, char *buf)
923{
924 struct gk20a *g = get_gk20a(dev);
925
926 return sprintf(buf, "%d\n", g->gr.czf_bypass);
927}
928
929static DEVICE_ATTR(czf_bypass, ROOTRW, czf_bypass_read, czf_bypass_store);
930
931
932void nvgpu_remove_sysfs(struct device *dev)
933{
934 device_remove_file(dev, &dev_attr_elcg_enable);
935 device_remove_file(dev, &dev_attr_blcg_enable);
936 device_remove_file(dev, &dev_attr_slcg_enable);
937 device_remove_file(dev, &dev_attr_ptimer_scale_factor);
938 device_remove_file(dev, &dev_attr_ptimer_ref_freq);
939 device_remove_file(dev, &dev_attr_ptimer_src_freq);
940 device_remove_file(dev, &dev_attr_elpg_enable);
941 device_remove_file(dev, &dev_attr_mscg_enable);
942 device_remove_file(dev, &dev_attr_emc3d_ratio);
943 device_remove_file(dev, &dev_attr_fmax_at_vmin_safe);
944 device_remove_file(dev, &dev_attr_counters);
945 device_remove_file(dev, &dev_attr_counters_reset);
946 device_remove_file(dev, &dev_attr_load);
947 device_remove_file(dev, &dev_attr_railgate_delay);
948 device_remove_file(dev, &dev_attr_is_railgated);
949#ifdef CONFIG_PM
950 device_remove_file(dev, &dev_attr_force_idle);
951 device_remove_file(dev, &dev_attr_railgate_enable);
952#endif
953 device_remove_file(dev, &dev_attr_aelpg_param);
954 device_remove_file(dev, &dev_attr_aelpg_enable);
955 device_remove_file(dev, &dev_attr_allow_all);
956 device_remove_file(dev, &dev_attr_tpc_fs_mask);
957 device_remove_file(dev, &dev_attr_min_timeslice_us);
958 device_remove_file(dev, &dev_attr_max_timeslice_us);
959
960#ifdef CONFIG_TEGRA_GK20A_NVHOST
961 nvgpu_nvhost_remove_symlink(get_gk20a(dev));
962#endif
963
964 device_remove_file(dev, &dev_attr_czf_bypass);
965
966 if (strcmp(dev_name(dev), "gpu.0")) {
967 struct kobject *kobj = &dev->kobj;
968 struct device *parent = container_of((kobj->parent),
969 struct device, kobj);
970 sysfs_remove_link(&parent->kobj, "gpu.0");
971 }
972}
973
974int nvgpu_create_sysfs(struct device *dev)
975{
976 struct gk20a *g = get_gk20a(dev);
977 int error = 0;
978
979 error |= device_create_file(dev, &dev_attr_elcg_enable);
980 error |= device_create_file(dev, &dev_attr_blcg_enable);
981 error |= device_create_file(dev, &dev_attr_slcg_enable);
982 error |= device_create_file(dev, &dev_attr_ptimer_scale_factor);
983 error |= device_create_file(dev, &dev_attr_ptimer_ref_freq);
984 error |= device_create_file(dev, &dev_attr_ptimer_src_freq);
985 error |= device_create_file(dev, &dev_attr_elpg_enable);
986 error |= device_create_file(dev, &dev_attr_mscg_enable);
987 error |= device_create_file(dev, &dev_attr_emc3d_ratio);
988 error |= device_create_file(dev, &dev_attr_fmax_at_vmin_safe);
989 error |= device_create_file(dev, &dev_attr_counters);
990 error |= device_create_file(dev, &dev_attr_counters_reset);
991 error |= device_create_file(dev, &dev_attr_load);
992 error |= device_create_file(dev, &dev_attr_railgate_delay);
993 error |= device_create_file(dev, &dev_attr_is_railgated);
994#ifdef CONFIG_PM
995 error |= device_create_file(dev, &dev_attr_force_idle);
996 error |= device_create_file(dev, &dev_attr_railgate_enable);
997#endif
998 error |= device_create_file(dev, &dev_attr_aelpg_param);
999 error |= device_create_file(dev, &dev_attr_aelpg_enable);
1000 error |= device_create_file(dev, &dev_attr_allow_all);
1001 error |= device_create_file(dev, &dev_attr_tpc_fs_mask);
1002 error |= device_create_file(dev, &dev_attr_min_timeslice_us);
1003 error |= device_create_file(dev, &dev_attr_max_timeslice_us);
1004
1005#ifdef CONFIG_TEGRA_GK20A_NVHOST
1006 error |= nvgpu_nvhost_create_symlink(g);
1007#endif
1008
1009 error |= device_create_file(dev, &dev_attr_czf_bypass);
1010
1011 if (strcmp(dev_name(dev), "gpu.0")) {
1012 struct kobject *kobj = &dev->kobj;
1013 struct device *parent = container_of((kobj->parent),
1014 struct device, kobj);
1015 error |= sysfs_create_link(&parent->kobj,
1016 &dev->kobj, "gpu.0");
1017 }
1018
1019 if (error)
1020 nvgpu_err(g, "Failed to create sysfs attributes!\n");
1021
1022 return error;
1023}
diff --git a/drivers/gpu/nvgpu/common/linux/sysfs.h b/drivers/gpu/nvgpu/common/linux/sysfs.h
new file mode 100644
index 00000000..80925844
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/linux/sysfs.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (c) 2017, 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#ifndef NVGPU_SYSFS_H
17#define NVGPU_SYSFS_H
18
19struct device;
20
21int nvgpu_create_sysfs(struct device *dev);
22void nvgpu_remove_sysfs(struct device *dev);
23
24#endif