summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/Makefile3
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gp106/clk_gp106.c188
-rw-r--r--drivers/gpu/nvgpu/gp106/clk_gp106.h18
-rw-r--r--drivers/gpu/nvgpu/gp106/hal_gp106.c2
-rw-r--r--drivers/gpu/nvgpu/gv100/hal_gv100.c2
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/clk.h42
-rw-r--r--drivers/gpu/nvgpu/os/linux/debug_clk_gp106.c193
-rw-r--r--drivers/gpu/nvgpu/os/linux/debug_clk_gp106.h29
-rw-r--r--drivers/gpu/nvgpu/os/linux/module.c16
-rw-r--r--drivers/gpu/nvgpu/os/linux/os_linux.h4
-rw-r--r--drivers/gpu/nvgpu/os/linux/os_ops.c8
-rw-r--r--drivers/gpu/nvgpu/os/linux/os_ops_gp106.c30
-rw-r--r--drivers/gpu/nvgpu/os/linux/os_ops_gp106.h22
-rw-r--r--drivers/gpu/nvgpu/os/linux/os_ops_gv100.c30
-rw-r--r--drivers/gpu/nvgpu/os/linux/os_ops_gv100.h22
16 files changed, 404 insertions, 206 deletions
diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile
index e74fa2bb..24322f82 100644
--- a/drivers/gpu/nvgpu/Makefile
+++ b/drivers/gpu/nvgpu/Makefile
@@ -51,6 +51,8 @@ nvgpu-y += \
51 os/linux/os_ops.o \ 51 os/linux/os_ops.o \
52 os/linux/os_ops_gm20b.o \ 52 os/linux/os_ops_gm20b.o \
53 os/linux/os_ops_gp10b.o \ 53 os/linux/os_ops_gp10b.o \
54 os/linux/os_ops_gp106.o \
55 os/linux/os_ops_gv100.o \
54 os/linux/kmem.o \ 56 os/linux/kmem.o \
55 os/linux/timers.o \ 57 os/linux/timers.o \
56 os/linux/ioctl.o \ 58 os/linux/ioctl.o \
@@ -98,6 +100,7 @@ nvgpu-$(CONFIG_DEBUG_FS) += \
98 os/linux/debug_allocator.o \ 100 os/linux/debug_allocator.o \
99 os/linux/debug_hal.o \ 101 os/linux/debug_hal.o \
100 os/linux/debug_clk_gm20b.o \ 102 os/linux/debug_clk_gm20b.o \
103 os/linux/debug_clk_gp106.o \
101 os/linux/debug_bios.o \ 104 os/linux/debug_bios.o \
102 os/linux/debug_ltc.o \ 105 os/linux/debug_ltc.o \
103 os/linux/debug_xve.o 106 os/linux/debug_xve.o
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index f0b0bebe..be00f708 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -1089,6 +1089,7 @@ struct gpu_ops {
1089 u32 clkapidomain, u32 *pfpointscount, 1089 u32 clkapidomain, u32 *pfpointscount,
1090 u16 *pfreqpointsinmhz); 1090 u16 *pfreqpointsinmhz);
1091 unsigned long (*measure_freq)(struct gk20a *g, u32 api_domain); 1091 unsigned long (*measure_freq)(struct gk20a *g, u32 api_domain);
1092 u32 (*get_rate_cntr)(struct gk20a *g, struct namemap_cfg *c);
1092 unsigned long (*get_rate)(struct gk20a *g, u32 api_domain); 1093 unsigned long (*get_rate)(struct gk20a *g, u32 api_domain);
1093 int (*set_rate)(struct gk20a *g, u32 api_domain, unsigned long rate); 1094 int (*set_rate)(struct gk20a *g, u32 api_domain, unsigned long rate);
1094 unsigned long (*get_fmax_at_vmin_safe)(struct gk20a *g); 1095 unsigned long (*get_fmax_at_vmin_safe)(struct gk20a *g);
diff --git a/drivers/gpu/nvgpu/gp106/clk_gp106.c b/drivers/gpu/nvgpu/gp106/clk_gp106.c
index dd7a2dd6..13a401f0 100644
--- a/drivers/gpu/nvgpu/gp106/clk_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/clk_gp106.c
@@ -22,11 +22,6 @@
22 * DEALINGS IN THE SOFTWARE. 22 * DEALINGS IN THE SOFTWARE.
23 */ 23 */
24 24
25#ifdef CONFIG_DEBUG_FS
26#include <linux/debugfs.h>
27#include "os/linux/os_linux.h"
28#endif
29
30#include <nvgpu/kmem.h> 25#include <nvgpu/kmem.h>
31#include <nvgpu/io.h> 26#include <nvgpu/io.h>
32#include <nvgpu/list.h> 27#include <nvgpu/list.h>
@@ -42,15 +37,9 @@
42 37
43#include <nvgpu/hw/gp106/hw_trim_gp106.h> 38#include <nvgpu/hw/gp106/hw_trim_gp106.h>
44 39
45#ifdef CONFIG_DEBUG_FS
46static int clk_gp106_debugfs_init(struct gk20a *g);
47#endif
48
49#define NUM_NAMEMAPS 4 40#define NUM_NAMEMAPS 4
50#define XTAL4X_KHZ 108000 41#define XTAL4X_KHZ 108000
51 42
52
53static u32 gp106_get_rate_cntr(struct gk20a *g, struct namemap_cfg *);
54u32 gp106_crystal_clk_hz(struct gk20a *g) 43u32 gp106_crystal_clk_hz(struct gk20a *g)
55{ 44{
56 return (XTAL4X_KHZ * 1000); 45 return (XTAL4X_KHZ * 1000);
@@ -173,16 +162,11 @@ int gp106_init_clk_support(struct gk20a *g)
173 162
174 clk->g = g; 163 clk->g = g;
175 164
176#ifdef CONFIG_DEBUG_FS
177 if (!clk->debugfs_set) {
178 if (!clk_gp106_debugfs_init(g))
179 clk->debugfs_set = true;
180 }
181#endif
182 return err; 165 return err;
183} 166}
184 167
185static u32 gp106_get_rate_cntr(struct gk20a *g, struct namemap_cfg *c) { 168u32 gp106_get_rate_cntr(struct gk20a *g, struct namemap_cfg *c)
169{
186 u32 save_reg; 170 u32 save_reg;
187 u32 retries; 171 u32 retries;
188 u32 cntr = 0; 172 u32 cntr = 0;
@@ -275,174 +259,6 @@ int gp106_clk_domain_get_f_points(
275 return status; 259 return status;
276} 260}
277 261
278
279#ifdef CONFIG_DEBUG_FS
280static int gp106_get_rate_show(void *data , u64 *val) {
281 struct namemap_cfg *c = (struct namemap_cfg *) data;
282 struct gk20a *g = c->g;
283
284 *val = c->is_counter ? (u64)c->scale * gp106_get_rate_cntr(g, c) :
285 0 /* TODO PLL read */;
286 return 0;
287}
288DEFINE_SIMPLE_ATTRIBUTE(get_rate_fops, gp106_get_rate_show, NULL, "%llu\n");
289
290static int sys_cfc_read(void *data , u64 *val)
291{
292 struct gk20a *g = (struct gk20a *)data;
293 bool bload = boardobjgrpmask_bitget(
294 &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super,
295 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_SYS);
296
297 /* val = 1 implies CLFC is loaded or enabled */
298 *val = bload ? 1 : 0;
299 return 0;
300}
301static int sys_cfc_write(void *data , u64 val)
302{
303 struct gk20a *g = (struct gk20a *)data;
304 int status;
305 /* val = 1 implies load or enable the CLFC */
306 bool bload = val ? true : false;
307
308 nvgpu_clk_arb_pstate_change_lock(g, true);
309 status = clk_pmu_freq_controller_load(g, bload,
310 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_SYS);
311 nvgpu_clk_arb_pstate_change_lock(g, false);
312
313 return status;
314}
315DEFINE_SIMPLE_ATTRIBUTE(sys_cfc_fops, sys_cfc_read, sys_cfc_write, "%llu\n");
316
317static int ltc_cfc_read(void *data , u64 *val)
318{
319 struct gk20a *g = (struct gk20a *)data;
320 bool bload = boardobjgrpmask_bitget(
321 &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super,
322 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_LTC);
323
324 /* val = 1 implies CLFC is loaded or enabled */
325 *val = bload ? 1 : 0;
326 return 0;
327}
328static int ltc_cfc_write(void *data , u64 val)
329{
330 struct gk20a *g = (struct gk20a *)data;
331 int status;
332 /* val = 1 implies load or enable the CLFC */
333 bool bload = val ? true : false;
334
335 nvgpu_clk_arb_pstate_change_lock(g, true);
336 status = clk_pmu_freq_controller_load(g, bload,
337 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_LTC);
338 nvgpu_clk_arb_pstate_change_lock(g, false);
339
340 return status;
341}
342DEFINE_SIMPLE_ATTRIBUTE(ltc_cfc_fops, ltc_cfc_read, ltc_cfc_write, "%llu\n");
343
344static int xbar_cfc_read(void *data , u64 *val)
345{
346 struct gk20a *g = (struct gk20a *)data;
347 bool bload = boardobjgrpmask_bitget(
348 &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super,
349 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_XBAR);
350
351 /* val = 1 implies CLFC is loaded or enabled */
352 *val = bload ? 1 : 0;
353 return 0;
354}
355static int xbar_cfc_write(void *data , u64 val)
356{
357 struct gk20a *g = (struct gk20a *)data;
358 int status;
359 /* val = 1 implies load or enable the CLFC */
360 bool bload = val ? true : false;
361
362 nvgpu_clk_arb_pstate_change_lock(g, true);
363 status = clk_pmu_freq_controller_load(g, bload,
364 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_XBAR);
365 nvgpu_clk_arb_pstate_change_lock(g, false);
366
367 return status;
368}
369DEFINE_SIMPLE_ATTRIBUTE(xbar_cfc_fops, xbar_cfc_read,
370 xbar_cfc_write, "%llu\n");
371
372static int gpc_cfc_read(void *data , u64 *val)
373{
374 struct gk20a *g = (struct gk20a *)data;
375 bool bload = boardobjgrpmask_bitget(
376 &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super,
377 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC0);
378
379 /* val = 1 implies CLFC is loaded or enabled */
380 *val = bload ? 1 : 0;
381 return 0;
382}
383static int gpc_cfc_write(void *data , u64 val)
384{
385 struct gk20a *g = (struct gk20a *)data;
386 int status;
387 /* val = 1 implies load or enable the CLFC */
388 bool bload = val ? true : false;
389
390 nvgpu_clk_arb_pstate_change_lock(g, true);
391 status = clk_pmu_freq_controller_load(g, bload,
392 CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC0);
393 nvgpu_clk_arb_pstate_change_lock(g, false);
394
395 return status;
396}
397DEFINE_SIMPLE_ATTRIBUTE(gpc_cfc_fops, gpc_cfc_read, gpc_cfc_write, "%llu\n");
398
399static int clk_gp106_debugfs_init(struct gk20a *g)
400{
401 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
402 struct dentry *gpu_root = l->debugfs;
403 struct dentry *clocks_root, *clk_freq_ctlr_root;
404 struct dentry *d;
405 unsigned int i;
406
407 if (NULL == (clocks_root = debugfs_create_dir("clocks", gpu_root)))
408 return -ENOMEM;
409
410 clk_freq_ctlr_root = debugfs_create_dir("clk_freq_ctlr", gpu_root);
411 if (clk_freq_ctlr_root == NULL)
412 return -ENOMEM;
413
414 d = debugfs_create_file("sys", S_IRUGO | S_IWUSR, clk_freq_ctlr_root,
415 g, &sys_cfc_fops);
416 d = debugfs_create_file("ltc", S_IRUGO | S_IWUSR, clk_freq_ctlr_root,
417 g, &ltc_cfc_fops);
418 d = debugfs_create_file("xbar", S_IRUGO | S_IWUSR, clk_freq_ctlr_root,
419 g, &xbar_cfc_fops);
420 d = debugfs_create_file("gpc", S_IRUGO | S_IWUSR, clk_freq_ctlr_root,
421 g, &gpc_cfc_fops);
422
423 nvgpu_log(g, gpu_dbg_info, "g=%p", g);
424
425 for (i = 0; i < g->clk.namemap_num; i++) {
426 if (g->clk.clk_namemap[i].is_enable) {
427 d = debugfs_create_file(
428 g->clk.clk_namemap[i].name,
429 S_IRUGO,
430 clocks_root,
431 &g->clk.clk_namemap[i],
432 &get_rate_fops);
433 if (!d)
434 goto err_out;
435 }
436 }
437 return 0;
438
439err_out:
440 pr_err("%s: Failed to make debugfs node\n", __func__);
441 debugfs_remove_recursive(clocks_root);
442 return -ENOMEM;
443}
444#endif /* CONFIG_DEBUG_FS */
445
446int gp106_suspend_clk_support(struct gk20a *g) 262int gp106_suspend_clk_support(struct gk20a *g)
447{ 263{
448 nvgpu_mutex_destroy(&g->clk.clk_mutex); 264 nvgpu_mutex_destroy(&g->clk.clk_mutex);
diff --git a/drivers/gpu/nvgpu/gp106/clk_gp106.h b/drivers/gpu/nvgpu/gp106/clk_gp106.h
index b7ab3164..079b94f0 100644
--- a/drivers/gpu/nvgpu/gp106/clk_gp106.h
+++ b/drivers/gpu/nvgpu/gp106/clk_gp106.h
@@ -23,6 +23,7 @@
23#define CLK_GP106_H 23#define CLK_GP106_H
24 24
25#include <nvgpu/lock.h> 25#include <nvgpu/lock.h>
26#include <nvgpu/clk.h>
26 27
27#define CLK_NAMEMAP_INDEX_GPC2CLK 0x00 28#define CLK_NAMEMAP_INDEX_GPC2CLK 0x00
28#define CLK_NAMEMAP_INDEX_XBAR2CLK 0x02 29#define CLK_NAMEMAP_INDEX_XBAR2CLK 0x02
@@ -36,22 +37,7 @@
36#define XTAL_CNTR_DELAY 1000 /* we need acuracy up to the ms */ 37#define XTAL_CNTR_DELAY 1000 /* we need acuracy up to the ms */
37#define XTAL_SCALE_TO_KHZ 1 38#define XTAL_SCALE_TO_KHZ 1
38 39
39 40u32 gp106_get_rate_cntr(struct gk20a *g, struct namemap_cfg *c);
40
41struct namemap_cfg {
42 u32 namemap;
43 u32 is_enable; /* Namemap enabled */
44 u32 is_counter; /* Using cntr */
45 struct gk20a *g;
46 struct {
47 u32 reg_ctrl_addr;
48 u32 reg_ctrl_idx;
49 u32 reg_cntr_addr;
50 } cntr;
51 u32 scale;
52 char name[24];
53};
54
55int gp106_init_clk_support(struct gk20a *g); 41int gp106_init_clk_support(struct gk20a *g);
56u32 gp106_crystal_clk_hz(struct gk20a *g); 42u32 gp106_crystal_clk_hz(struct gk20a *g);
57unsigned long gp106_clk_measure_freq(struct gk20a *g, u32 api_domain); 43unsigned long gp106_clk_measure_freq(struct gk20a *g, u32 api_domain);
diff --git a/drivers/gpu/nvgpu/gp106/hal_gp106.c b/drivers/gpu/nvgpu/gp106/hal_gp106.c
index f1a701a0..af2d4c00 100644
--- a/drivers/gpu/nvgpu/gp106/hal_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/hal_gp106.c
@@ -673,6 +673,7 @@ static const struct gpu_ops gp106_ops = {
673 .clk = { 673 .clk = {
674 .init_clk_support = gp106_init_clk_support, 674 .init_clk_support = gp106_init_clk_support,
675 .get_crystal_clk_hz = gp106_crystal_clk_hz, 675 .get_crystal_clk_hz = gp106_crystal_clk_hz,
676 .get_rate_cntr = gp106_get_rate_cntr,
676 .measure_freq = gp106_clk_measure_freq, 677 .measure_freq = gp106_clk_measure_freq,
677 .suspend_clk_support = gp106_suspend_clk_support, 678 .suspend_clk_support = gp106_suspend_clk_support,
678 .clk_domain_get_f_points = gp106_clk_domain_get_f_points, 679 .clk_domain_get_f_points = gp106_clk_domain_get_f_points,
@@ -848,6 +849,7 @@ int gp106_init_hal(struct gk20a *g)
848 */ 849 */
849 gops->clk.init_clk_support = gp106_ops.clk.init_clk_support; 850 gops->clk.init_clk_support = gp106_ops.clk.init_clk_support;
850 gops->clk.get_crystal_clk_hz = gp106_ops.clk.get_crystal_clk_hz; 851 gops->clk.get_crystal_clk_hz = gp106_ops.clk.get_crystal_clk_hz;
852 gops->clk.get_rate_cntr = gp106_ops.clk.get_rate_cntr;
851 gops->clk.measure_freq = gp106_ops.clk.measure_freq; 853 gops->clk.measure_freq = gp106_ops.clk.measure_freq;
852 gops->clk.suspend_clk_support = gp106_ops.clk.suspend_clk_support; 854 gops->clk.suspend_clk_support = gp106_ops.clk.suspend_clk_support;
853 gops->clk.mclk_init = gp106_ops.clk.mclk_init; 855 gops->clk.mclk_init = gp106_ops.clk.mclk_init;
diff --git a/drivers/gpu/nvgpu/gv100/hal_gv100.c b/drivers/gpu/nvgpu/gv100/hal_gv100.c
index 295e896d..78798196 100644
--- a/drivers/gpu/nvgpu/gv100/hal_gv100.c
+++ b/drivers/gpu/nvgpu/gv100/hal_gv100.c
@@ -769,6 +769,7 @@ static const struct gpu_ops gv100_ops = {
769 .clk = { 769 .clk = {
770 .init_clk_support = gp106_init_clk_support, 770 .init_clk_support = gp106_init_clk_support,
771 .get_crystal_clk_hz = gp106_crystal_clk_hz, 771 .get_crystal_clk_hz = gp106_crystal_clk_hz,
772 .get_rate_cntr = gp106_get_rate_cntr,
772 .measure_freq = gp106_clk_measure_freq, 773 .measure_freq = gp106_clk_measure_freq,
773 .suspend_clk_support = gp106_suspend_clk_support, 774 .suspend_clk_support = gp106_suspend_clk_support,
774 }, 775 },
@@ -976,6 +977,7 @@ int gv100_init_hal(struct gk20a *g)
976 977
977 /* clocks */ 978 /* clocks */
978 gops->clk.init_clk_support = gv100_ops.clk.init_clk_support; 979 gops->clk.init_clk_support = gv100_ops.clk.init_clk_support;
980 gops->clk.get_rate_cntr = gv100_ops.clk.get_rate_cntr;
979 gops->clk.get_crystal_clk_hz = gv100_ops.clk.get_crystal_clk_hz; 981 gops->clk.get_crystal_clk_hz = gv100_ops.clk.get_crystal_clk_hz;
980 gops->clk.measure_freq = gv100_ops.clk.measure_freq; 982 gops->clk.measure_freq = gv100_ops.clk.measure_freq;
981 gops->clk.suspend_clk_support = gv100_ops.clk.suspend_clk_support; 983 gops->clk.suspend_clk_support = gv100_ops.clk.suspend_clk_support;
diff --git a/drivers/gpu/nvgpu/include/nvgpu/clk.h b/drivers/gpu/nvgpu/include/nvgpu/clk.h
new file mode 100644
index 00000000..62bb0f94
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/clk.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef __NVGPU_CLK_H__
24#define __NVGPU_CLK_H__
25
26#define CLK_NAME_MAX 24
27
28struct namemap_cfg {
29 u32 namemap;
30 u32 is_enable; /* Namemap enabled */
31 u32 is_counter; /* Using cntr */
32 struct gk20a *g;
33 struct {
34 u32 reg_ctrl_addr;
35 u32 reg_ctrl_idx;
36 u32 reg_cntr_addr;
37 } cntr;
38 u32 scale;
39 char name[CLK_NAME_MAX];
40};
41
42#endif
diff --git a/drivers/gpu/nvgpu/os/linux/debug_clk_gp106.c b/drivers/gpu/nvgpu/os/linux/debug_clk_gp106.c
new file mode 100644
index 00000000..4900c005
--- /dev/null
+++ b/drivers/gpu/nvgpu/os/linux/debug_clk_gp106.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 <nvgpu/clk.h>
20
21#include "os_linux.h"
22
23void nvgpu_clk_arb_pstate_change_lock(struct gk20a *g, bool lock);
24
25static int gp106_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, gp106_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 gp106_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}
diff --git a/drivers/gpu/nvgpu/os/linux/debug_clk_gp106.h b/drivers/gpu/nvgpu/os/linux/debug_clk_gp106.h
new file mode 100644
index 00000000..b1d031d9
--- /dev/null
+++ b/drivers/gpu/nvgpu/os/linux/debug_clk_gp106.h
@@ -0,0 +1,29 @@
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#ifndef __DEBUG_CLK_GP106_H
18#define __DEBUG_CLK_GP106_H
19
20#ifdef CONFIG_DEBUG_FS
21int gp106_clk_init_debugfs(struct gk20a *g);
22#else
23inline int gp106_clk_init_debugfs(struct gk20a *g)
24{
25 return 0;
26}
27#endif
28
29#endif
diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c
index d226ceeb..02b0ea5c 100644
--- a/drivers/gpu/nvgpu/os/linux/module.c
+++ b/drivers/gpu/nvgpu/os/linux/module.c
@@ -198,6 +198,14 @@ int nvgpu_finalize_poweron_linux(struct nvgpu_os_linux *l)
198 return err; 198 return err;
199 } 199 }
200 200
201 if (l->ops.clk.init_debugfs) {
202 err = l->ops.clk.init_debugfs(g);
203 if (err) {
204 nvgpu_err(g, "failed to init linux clk debugfs");
205 return err;
206 }
207 }
208
201 l->init_done = true; 209 l->init_done = true;
202 210
203 return 0; 211 return 0;
@@ -250,6 +258,10 @@ int gk20a_pm_finalize_poweron(struct device *dev)
250 if (err) 258 if (err)
251 goto done; 259 goto done;
252 260
261 err = nvgpu_init_os_linux_ops(l);
262 if (err)
263 goto done;
264
253 err = nvgpu_finalize_poweron_linux(l); 265 err = nvgpu_finalize_poweron_linux(l);
254 if (err) 266 if (err)
255 goto done; 267 goto done;
@@ -268,10 +280,6 @@ int gk20a_pm_finalize_poweron(struct device *dev)
268 280
269 trace_gk20a_finalize_poweron_done(dev_name(dev)); 281 trace_gk20a_finalize_poweron_done(dev_name(dev));
270 282
271 err = nvgpu_init_os_linux_ops(l);
272 if (err)
273 goto done;
274
275 enable_irq(g->irq_stall); 283 enable_irq(g->irq_stall);
276 if (g->irq_stall != g->irq_nonstall) 284 if (g->irq_stall != g->irq_nonstall)
277 enable_irq(g->irq_nonstall); 285 enable_irq(g->irq_nonstall);
diff --git a/drivers/gpu/nvgpu/os/linux/os_linux.h b/drivers/gpu/nvgpu/os/linux/os_linux.h
index 5f35db09..96eff12e 100644
--- a/drivers/gpu/nvgpu/os/linux/os_linux.h
+++ b/drivers/gpu/nvgpu/os/linux/os_linux.h
@@ -38,6 +38,10 @@ struct nvgpu_os_linux_ops {
38 void *scatter_buffer_ptr, 38 void *scatter_buffer_ptr,
39 size_t scatter_buffer_size); 39 size_t scatter_buffer_size);
40 } cde; 40 } cde;
41
42 struct {
43 int (*init_debugfs)(struct gk20a *g);
44 } clk;
41}; 45};
42 46
43struct nvgpu_os_linux { 47struct nvgpu_os_linux {
diff --git a/drivers/gpu/nvgpu/os/linux/os_ops.c b/drivers/gpu/nvgpu/os/linux/os_ops.c
index 14f92787..5fc5beb4 100644
--- a/drivers/gpu/nvgpu/os/linux/os_ops.c
+++ b/drivers/gpu/nvgpu/os/linux/os_ops.c
@@ -18,6 +18,8 @@
18 18
19#include "os_ops_gm20b.h" 19#include "os_ops_gm20b.h"
20#include "os_ops_gp10b.h" 20#include "os_ops_gp10b.h"
21#include "os_ops_gp106.h"
22#include "os_ops_gv100.h"
21 23
22int nvgpu_init_os_linux_ops(struct nvgpu_os_linux *l) 24int nvgpu_init_os_linux_ops(struct nvgpu_os_linux *l)
23{ 25{
@@ -32,6 +34,12 @@ int nvgpu_init_os_linux_ops(struct nvgpu_os_linux *l)
32 case NVGPU_GPUID_GP10B: 34 case NVGPU_GPUID_GP10B:
33 nvgpu_gp10b_init_os_ops(l); 35 nvgpu_gp10b_init_os_ops(l);
34 break; 36 break;
37 case NVGPU_GPUID_GP106:
38 nvgpu_gp106_init_os_ops(l);
39 break;
40 case NVGPU_GPUID_GV100:
41 nvgpu_gv100_init_os_ops(l);
42 break;
35 default: 43 default:
36 break; 44 break;
37 } 45 }
diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gp106.c b/drivers/gpu/nvgpu/os/linux/os_ops_gp106.c
new file mode 100644
index 00000000..13ce73e6
--- /dev/null
+++ b/drivers/gpu/nvgpu/os/linux/os_ops_gp106.c
@@ -0,0 +1,30 @@
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 "os_linux.h"
18
19#include "debug_clk_gp106.h"
20
21static struct nvgpu_os_linux_ops gp106_os_linux_ops = {
22 .clk = {
23 .init_debugfs = gp106_clk_init_debugfs,
24 },
25};
26
27void nvgpu_gp106_init_os_ops(struct nvgpu_os_linux *l)
28{
29 l->ops.clk = gp106_os_linux_ops.clk;
30}
diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gp106.h b/drivers/gpu/nvgpu/os/linux/os_ops_gp106.h
new file mode 100644
index 00000000..7d423d5d
--- /dev/null
+++ b/drivers/gpu/nvgpu/os/linux/os_ops_gp106.h
@@ -0,0 +1,22 @@
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#ifndef __LINUX_OS_OPS_GP106_H
18#define __LINUX_OS_OPS_GP106_H
19
20void nvgpu_gp106_init_os_ops(struct nvgpu_os_linux *l);
21
22#endif
diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gv100.c b/drivers/gpu/nvgpu/os/linux/os_ops_gv100.c
new file mode 100644
index 00000000..9236286b
--- /dev/null
+++ b/drivers/gpu/nvgpu/os/linux/os_ops_gv100.c
@@ -0,0 +1,30 @@
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 "os_linux.h"
18
19#include "debug_clk_gp106.h"
20
21static struct nvgpu_os_linux_ops gv100_os_linux_ops = {
22 .clk = {
23 .init_debugfs = gp106_clk_init_debugfs,
24 },
25};
26
27void nvgpu_gv100_init_os_ops(struct nvgpu_os_linux *l)
28{
29 l->ops.clk = gv100_os_linux_ops.clk;
30}
diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gv100.h b/drivers/gpu/nvgpu/os/linux/os_ops_gv100.h
new file mode 100644
index 00000000..43923b27
--- /dev/null
+++ b/drivers/gpu/nvgpu/os/linux/os_ops_gv100.h
@@ -0,0 +1,22 @@
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#ifndef __LINUX_OS_OPS_GV100_H
18#define __LINUX_OS_OPS_GV100_H
19
20void nvgpu_gv100_init_os_ops(struct nvgpu_os_linux *l);
21
22#endif