summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/bus/bus_gk20a.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2018-05-24 18:25:41 -0400
committerTejal Kudav <tkudav@nvidia.com>2018-06-14 09:44:07 -0400
commitd71d38087ded679f60714dae3a859523a19df04f (patch)
tree61439d294705ef91ce08ae4c02d4921eec943283 /drivers/gpu/nvgpu/common/bus/bus_gk20a.c
parent5215d65c25b5e76c19d9d12b03c52f69e2d40227 (diff)
gpu: nvgpu: Separate timer from bus
Code touching timer registers was combined with bus code. They're two logically separate register spaces, so separate the code accordingly. JIRA NVGPU-588 Change-Id: I40e2925ff156669f41ddc1f2e7714f92a2da367b Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1730893 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/bus/bus_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/common/bus/bus_gk20a.c72
1 files changed, 2 insertions, 70 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);