summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r--drivers/gpu/nvgpu/common/bus/bus_gk20a.c72
-rw-r--r--drivers/gpu/nvgpu/common/bus/bus_gk20a.h2
-rw-r--r--drivers/gpu/nvgpu/common/bus/bus_gm20b.c3
-rw-r--r--drivers/gpu/nvgpu/common/bus/bus_gm20b.h4
-rw-r--r--drivers/gpu/nvgpu/common/linux/ctxsw_trace.c4
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c6
-rw-r--r--drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c1
-rw-r--r--drivers/gpu/nvgpu/common/ptimer/ptimer.c (renamed from drivers/gpu/nvgpu/common/bus/bus.c)4
-rw-r--r--drivers/gpu/nvgpu/common/ptimer/ptimer_gk20a.c100
-rw-r--r--drivers/gpu/nvgpu/common/ptimer/ptimer_gk20a.h32
10 files changed, 143 insertions, 85 deletions
diff --git a/drivers/gpu/nvgpu/common/bus/bus_gk20a.c b/drivers/gpu/nvgpu/common/bus/bus_gk20a.c
index 9f0446c6..532fc9c6 100644
--- a/drivers/gpu/nvgpu/common/bus/bus_gk20a.c
+++ b/drivers/gpu/nvgpu/common/bus/bus_gk20a.c
@@ -28,7 +28,6 @@
28#include "bus_gk20a.h" 28#include "bus_gk20a.h"
29 29
30#include <nvgpu/hw/gk20a/hw_bus_gk20a.h> 30#include <nvgpu/hw/gk20a/hw_bus_gk20a.h>
31#include <nvgpu/hw/gk20a/hw_timer_gk20a.h>
32 31
33void gk20a_bus_init_hw(struct gk20a *g) 32void gk20a_bus_init_hw(struct gk20a *g)
34{ 33{
@@ -45,7 +44,7 @@ void gk20a_bus_init_hw(struct gk20a *g)
45 44
46void gk20a_bus_isr(struct gk20a *g) 45void gk20a_bus_isr(struct gk20a *g)
47{ 46{
48 u32 val, save0, save1, fecs_errcode = 0; 47 u32 val;
49 48
50 val = gk20a_readl(g, bus_intr_0_r()); 49 val = gk20a_readl(g, bus_intr_0_r());
51 50
@@ -53,80 +52,13 @@ void gk20a_bus_isr(struct gk20a *g)
53 bus_intr_0_pri_fecserr_m() | 52 bus_intr_0_pri_fecserr_m() |
54 bus_intr_0_pri_timeout_m())) { 53 bus_intr_0_pri_timeout_m())) {
55 54
56 save0 = gk20a_readl(g, timer_pri_timeout_save_0_r()); 55 g->ops.ptimer.isr(g);
57 if (timer_pri_timeout_save_0_fecs_tgt_v(save0)) {
58 /*
59 * write & addr fields in timeout_save0
60 * might not be reliable
61 */
62 fecs_errcode = gk20a_readl(g,
63 timer_pri_timeout_fecs_errcode_r());
64 }
65
66 save1 = gk20a_readl(g, timer_pri_timeout_save_1_r());
67 nvgpu_err(g, "NV_PBUS_INTR_0: 0x%08x ADR 0x%08x "
68 "%s DATA 0x%08x ",
69 val,
70 timer_pri_timeout_save_0_addr_v(save0) << 2,
71 timer_pri_timeout_save_0_write_v(save0) ?
72 "WRITE" : "READ", save1);
73
74 gk20a_writel(g, timer_pri_timeout_save_0_r(), 0);
75 gk20a_writel(g, timer_pri_timeout_save_1_r(), 0);
76
77 if (fecs_errcode) {
78 nvgpu_err(g, "FECS_ERRCODE 0x%08x", fecs_errcode);
79 if (g->ops.priv_ring.decode_error_code)
80 g->ops.priv_ring.decode_error_code(g,
81 fecs_errcode);
82 }
83
84 } else { 56 } else {
85 nvgpu_err(g, "Unhandled NV_PBUS_INTR_0: 0x%08x", val); 57 nvgpu_err(g, "Unhandled NV_PBUS_INTR_0: 0x%08x", val);
86 } 58 }
87 gk20a_writel(g, bus_intr_0_r(), val); 59 gk20a_writel(g, bus_intr_0_r(), val);
88} 60}
89 61
90int gk20a_read_ptimer(struct gk20a *g, u64 *value)
91{
92 const unsigned int max_iterations = 3;
93 unsigned int i = 0;
94 u32 gpu_timestamp_hi_prev = 0;
95
96 if (!value)
97 return -EINVAL;
98
99 /* Note. The GPU nanosecond timer consists of two 32-bit
100 * registers (high & low). To detect a possible low register
101 * wrap-around between the reads, we need to read the high
102 * register before and after low. The wraparound happens
103 * approximately once per 4 secs. */
104
105 /* get initial gpu_timestamp_hi value */
106 gpu_timestamp_hi_prev = gk20a_readl(g, timer_time_1_r());
107
108 for (i = 0; i < max_iterations; ++i) {
109 u32 gpu_timestamp_hi = 0;
110 u32 gpu_timestamp_lo = 0;
111
112 gpu_timestamp_lo = gk20a_readl(g, timer_time_0_r());
113 gpu_timestamp_hi = gk20a_readl(g, timer_time_1_r());
114
115 if (gpu_timestamp_hi == gpu_timestamp_hi_prev) {
116 *value = (((u64)gpu_timestamp_hi) << 32) |
117 gpu_timestamp_lo;
118 return 0;
119 }
120
121 /* wrap-around detected, retry */
122 gpu_timestamp_hi_prev = gpu_timestamp_hi;
123 }
124
125 /* too many iterations, bail out */
126 nvgpu_err(g, "failed to read ptimer");
127 return -EBUSY;
128}
129
130int gk20a_bus_bar1_bind(struct gk20a *g, struct nvgpu_mem *bar1_inst) 62int gk20a_bus_bar1_bind(struct gk20a *g, struct nvgpu_mem *bar1_inst)
131{ 63{
132 u64 iova = nvgpu_inst_block_addr(g, bar1_inst); 64 u64 iova = nvgpu_inst_block_addr(g, bar1_inst);
diff --git a/drivers/gpu/nvgpu/common/bus/bus_gk20a.h b/drivers/gpu/nvgpu/common/bus/bus_gk20a.h
index fe1cad58..541472cd 100644
--- a/drivers/gpu/nvgpu/common/bus/bus_gk20a.h
+++ b/drivers/gpu/nvgpu/common/bus/bus_gk20a.h
@@ -25,13 +25,11 @@
25#include <nvgpu/types.h> 25#include <nvgpu/types.h>
26 26
27struct gk20a; 27struct gk20a;
28struct gpu_ops;
29struct nvgpu_mem; 28struct nvgpu_mem;
30struct nvgpu_sgt; 29struct nvgpu_sgt;
31struct nvgpu_sgl; 30struct nvgpu_sgl;
32 31
33void gk20a_bus_isr(struct gk20a *g); 32void gk20a_bus_isr(struct gk20a *g);
34int gk20a_read_ptimer(struct gk20a *g, u64 *value);
35void gk20a_bus_init_hw(struct gk20a *g); 33void gk20a_bus_init_hw(struct gk20a *g);
36int gk20a_bus_bar1_bind(struct gk20a *g, struct nvgpu_mem *bar1_inst); 34int gk20a_bus_bar1_bind(struct gk20a *g, struct nvgpu_mem *bar1_inst);
37u32 gk20a_bus_set_bar0_window(struct gk20a *g, struct nvgpu_mem *mem, 35u32 gk20a_bus_set_bar0_window(struct gk20a *g, struct nvgpu_mem *mem,
diff --git a/drivers/gpu/nvgpu/common/bus/bus_gm20b.c b/drivers/gpu/nvgpu/common/bus/bus_gm20b.c
index 3e27053a..669cb0ae 100644
--- a/drivers/gpu/nvgpu/common/bus/bus_gm20b.c
+++ b/drivers/gpu/nvgpu/common/bus/bus_gm20b.c
@@ -23,13 +23,10 @@
23 */ 23 */
24 24
25#include <nvgpu/timers.h> 25#include <nvgpu/timers.h>
26#include <nvgpu/bus.h>
27#include <nvgpu/mm.h> 26#include <nvgpu/mm.h>
28#include <nvgpu/enabled.h> 27#include <nvgpu/enabled.h>
29 28
30#include "gk20a/gk20a.h" 29#include "gk20a/gk20a.h"
31
32#include "bus_gk20a.h"
33#include "bus_gm20b.h" 30#include "bus_gm20b.h"
34 31
35#include <nvgpu/hw/gm20b/hw_bus_gm20b.h> 32#include <nvgpu/hw/gm20b/hw_bus_gm20b.h>
diff --git a/drivers/gpu/nvgpu/common/bus/bus_gm20b.h b/drivers/gpu/nvgpu/common/bus/bus_gm20b.h
index 961b906a..1700a7e7 100644
--- a/drivers/gpu/nvgpu/common/bus/bus_gm20b.h
+++ b/drivers/gpu/nvgpu/common/bus/bus_gm20b.h
@@ -22,8 +22,8 @@
22 * DEALINGS IN THE SOFTWARE. 22 * DEALINGS IN THE SOFTWARE.
23 */ 23 */
24 24
25#ifndef _NVGPU_GM20B_BUS 25#ifndef NVGPU_GM20B_BUS
26#define _NVGPU_GM20B_BUS 26#define NVGPU_GM20B_BUS
27 27
28struct gk20a; 28struct gk20a;
29struct nvgpu_mem; 29struct nvgpu_mem;
diff --git a/drivers/gpu/nvgpu/common/linux/ctxsw_trace.c b/drivers/gpu/nvgpu/common/linux/ctxsw_trace.c
index 2f0c3e89..a335988a 100644
--- a/drivers/gpu/nvgpu/common/linux/ctxsw_trace.c
+++ b/drivers/gpu/nvgpu/common/linux/ctxsw_trace.c
@@ -702,7 +702,7 @@ void gk20a_ctxsw_trace_channel_reset(struct gk20a *g, struct channel_gk20a *ch)
702 if (!g->ctxsw_trace) 702 if (!g->ctxsw_trace)
703 return; 703 return;
704 704
705 g->ops.bus.read_ptimer(g, &entry.timestamp); 705 g->ops.ptimer.read_ptimer(g, &entry.timestamp);
706 gk20a_ctxsw_trace_write(g, &entry); 706 gk20a_ctxsw_trace_write(g, &entry);
707 gk20a_ctxsw_trace_wake_up(g, 0); 707 gk20a_ctxsw_trace_wake_up(g, 0);
708#endif 708#endif
@@ -722,7 +722,7 @@ void gk20a_ctxsw_trace_tsg_reset(struct gk20a *g, struct tsg_gk20a *tsg)
722 if (!g->ctxsw_trace) 722 if (!g->ctxsw_trace)
723 return; 723 return;
724 724
725 g->ops.bus.read_ptimer(g, &entry.timestamp); 725 g->ops.ptimer.read_ptimer(g, &entry.timestamp);
726 gk20a_ctxsw_trace_write(g, &entry); 726 gk20a_ctxsw_trace_write(g, &entry);
727 gk20a_ctxsw_trace_wake_up(g, 0); 727 gk20a_ctxsw_trace_wake_up(g, 0);
728#endif 728#endif
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
index ee0739c9..cda2ce46 100644
--- a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
+++ b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
@@ -24,7 +24,7 @@
24#include <nvgpu/bitops.h> 24#include <nvgpu/bitops.h>
25#include <nvgpu/kmem.h> 25#include <nvgpu/kmem.h>
26#include <nvgpu/bug.h> 26#include <nvgpu/bug.h>
27#include <nvgpu/bus.h> 27#include <nvgpu/ptimer.h>
28#include <nvgpu/vidmem.h> 28#include <nvgpu/vidmem.h>
29#include <nvgpu/log.h> 29#include <nvgpu/log.h>
30#include <nvgpu/enabled.h> 30#include <nvgpu/enabled.h>
@@ -811,7 +811,7 @@ static int nvgpu_gpu_get_cpu_time_correlation_info(
811 return -ENOMEM; 811 return -ENOMEM;
812 } 812 }
813 813
814 err = g->ops.bus.get_timestamps_zipper(g, 814 err = g->ops.ptimer.get_timestamps_zipper(g,
815 args->source_id, args->count, samples); 815 args->source_id, args->count, samples);
816 if (!err) { 816 if (!err) {
817 for (i = 0; i < args->count; i++) { 817 for (i = 0; i < args->count; i++) {
@@ -836,7 +836,7 @@ static int nvgpu_gpu_get_gpu_time(
836 if (err) 836 if (err)
837 return err; 837 return err;
838 838
839 err = g->ops.bus.read_ptimer(g, &time); 839 err = g->ops.ptimer.read_ptimer(g, &time);
840 if (!err) 840 if (!err)
841 args->gpu_timestamp = time; 841 args->gpu_timestamp = time;
842 842
diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c
index 90fbc079..0d224eb9 100644
--- a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c
+++ b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c
@@ -27,7 +27,6 @@
27#include <nvgpu/bug.h> 27#include <nvgpu/bug.h>
28#include <nvgpu/enabled.h> 28#include <nvgpu/enabled.h>
29#include <nvgpu/debug.h> 29#include <nvgpu/debug.h>
30#include <nvgpu/bus.h>
31#include <nvgpu/soc.h> 30#include <nvgpu/soc.h>
32#include <nvgpu/ctxsw_trace.h> 31#include <nvgpu/ctxsw_trace.h>
33#include <nvgpu/defaults.h> 32#include <nvgpu/defaults.h>
diff --git a/drivers/gpu/nvgpu/common/bus/bus.c b/drivers/gpu/nvgpu/common/ptimer/ptimer.c
index 3889512a..d5f9470d 100644
--- a/drivers/gpu/nvgpu/common/bus/bus.c
+++ b/drivers/gpu/nvgpu/common/ptimer/ptimer.c
@@ -20,7 +20,7 @@
20 * DEALINGS IN THE SOFTWARE. 20 * DEALINGS IN THE SOFTWARE.
21 */ 21 */
22 22
23#include <nvgpu/bus.h> 23#include <nvgpu/ptimer.h>
24 24
25#include "gk20a/gk20a.h" 25#include "gk20a/gk20a.h"
26 26
@@ -38,7 +38,7 @@ int nvgpu_get_timestamps_zipper(struct gk20a *g,
38 } 38 }
39 39
40 for (i = 0; i < count; i++) { 40 for (i = 0; i < count; i++) {
41 err = g->ops.bus.read_ptimer(g, &samples[i].gpu_timestamp); 41 err = g->ops.ptimer.read_ptimer(g, &samples[i].gpu_timestamp);
42 if (err) 42 if (err)
43 return err; 43 return err;
44 44
diff --git a/drivers/gpu/nvgpu/common/ptimer/ptimer_gk20a.c b/drivers/gpu/nvgpu/common/ptimer/ptimer_gk20a.c
new file mode 100644
index 00000000..52e47601
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/ptimer/ptimer_gk20a.c
@@ -0,0 +1,100 @@
1/*
2 * Copyright (c) 2017-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#include <nvgpu/log.h>
24
25#include "gk20a/gk20a.h"
26#include "ptimer_gk20a.h"
27
28#include <nvgpu/hw/gk20a/hw_timer_gk20a.h>
29
30void gk20a_ptimer_isr(struct gk20a *g)
31{
32 u32 save0, save1, fecs_errcode = 0;
33
34 save0 = gk20a_readl(g, timer_pri_timeout_save_0_r());
35 if (timer_pri_timeout_save_0_fecs_tgt_v(save0)) {
36 /*
37 * write & addr fields in timeout_save0
38 * might not be reliable
39 */
40 fecs_errcode = gk20a_readl(g,
41 timer_pri_timeout_fecs_errcode_r());
42 }
43
44 save1 = gk20a_readl(g, timer_pri_timeout_save_1_r());
45 nvgpu_err(g, "PRI timeout: ADR 0x%08x "
46 "%s DATA 0x%08x",
47 timer_pri_timeout_save_0_addr_v(save0) << 2,
48 timer_pri_timeout_save_0_write_v(save0) ?
49 "WRITE" : "READ", save1);
50
51 gk20a_writel(g, timer_pri_timeout_save_0_r(), 0);
52 gk20a_writel(g, timer_pri_timeout_save_1_r(), 0);
53
54 if (fecs_errcode) {
55 nvgpu_err(g, "FECS_ERRCODE 0x%08x", fecs_errcode);
56 if (g->ops.priv_ring.decode_error_code)
57 g->ops.priv_ring.decode_error_code(g,
58 fecs_errcode);
59 }
60}
61
62int gk20a_read_ptimer(struct gk20a *g, u64 *value)
63{
64 const unsigned int max_iterations = 3;
65 unsigned int i = 0;
66 u32 gpu_timestamp_hi_prev = 0;
67
68 if (!value)
69 return -EINVAL;
70
71 /* Note. The GPU nanosecond timer consists of two 32-bit
72 * registers (high & low). To detect a possible low register
73 * wrap-around between the reads, we need to read the high
74 * register before and after low. The wraparound happens
75 * approximately once per 4 secs. */
76
77 /* get initial gpu_timestamp_hi value */
78 gpu_timestamp_hi_prev = gk20a_readl(g, timer_time_1_r());
79
80 for (i = 0; i < max_iterations; ++i) {
81 u32 gpu_timestamp_hi = 0;
82 u32 gpu_timestamp_lo = 0;
83
84 gpu_timestamp_lo = gk20a_readl(g, timer_time_0_r());
85 gpu_timestamp_hi = gk20a_readl(g, timer_time_1_r());
86
87 if (gpu_timestamp_hi == gpu_timestamp_hi_prev) {
88 *value = (((u64)gpu_timestamp_hi) << 32) |
89 gpu_timestamp_lo;
90 return 0;
91 }
92
93 /* wrap-around detected, retry */
94 gpu_timestamp_hi_prev = gpu_timestamp_hi;
95 }
96
97 /* too many iterations, bail out */
98 nvgpu_err(g, "failed to read ptimer");
99 return -EBUSY;
100}
diff --git a/drivers/gpu/nvgpu/common/ptimer/ptimer_gk20a.h b/drivers/gpu/nvgpu/common/ptimer/ptimer_gk20a.h
new file mode 100644
index 00000000..b95dc1ca
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/ptimer/ptimer_gk20a.h
@@ -0,0 +1,32 @@
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#ifndef PTIMER_GK20A_H
23#define PTIMER_GK20A_H
24
25#include <nvgpu/types.h>
26
27struct gk20a;
28
29void gk20a_ptimer_isr(struct gk20a *g);
30int gk20a_read_ptimer(struct gk20a *g, u64 *value);
31
32#endif /* PTIMER_GK20A_H */