summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c')
-rw-r--r--drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c b/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c
new file mode 100644
index 00000000..f88718b6
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c
@@ -0,0 +1,150 @@
1/*
2 * GP10B RPFB
3 *
4 * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 */
15
16#include <linux/pm_runtime.h>
17#include <linux/dma-mapping.h>
18#include "gk20a/gk20a.h"
19#include "rpfb_gp10b.h"
20#include "hw_fifo_gp10b.h"
21#include "hw_fb_gp10b.h"
22#include "hw_bus_gp10b.h"
23#include "hw_gmmu_gp10b.h"
24
25int gp10b_replayable_pagefault_buffer_init(struct gk20a *g)
26{
27 u32 addr_lo;
28 u32 addr_hi;
29 struct vm_gk20a *vm = &g->mm.bar2.vm;
30 int err;
31 size_t rbfb_size = NV_UVM_FAULT_BUF_SIZE *
32 fifo_replay_fault_buffer_size_hw_entries_v();
33
34 gk20a_dbg_fn("");
35
36 if (!g->mm.bar2_desc.gpu_va) {
37 err = gk20a_gmmu_alloc_map_sys(vm, rbfb_size,
38 &g->mm.bar2_desc);
39 if (err) {
40 dev_err(dev_from_gk20a(g),
41 "%s Error in replayable fault buffer\n", __func__);
42 return err;
43 }
44 }
45 addr_lo = u64_lo32(g->mm.bar2_desc.gpu_va >> 12);
46 addr_hi = u64_hi32(g->mm.bar2_desc.gpu_va);
47 gk20a_writel(g, fifo_replay_fault_buffer_hi_r(),
48 fifo_replay_fault_buffer_hi_base_f(addr_hi));
49
50 gk20a_writel(g, fifo_replay_fault_buffer_lo_r(),
51 fifo_replay_fault_buffer_lo_base_f(addr_lo) |
52 fifo_replay_fault_buffer_lo_enable_true_v());
53 gk20a_dbg_fn("done");
54 return 0;
55}
56
57void gp10b_replayable_pagefault_buffer_deinit(struct gk20a *g)
58{
59 struct vm_gk20a *vm = &g->mm.bar2.vm;
60
61 gk20a_gmmu_unmap_free(vm, &g->mm.bar2_desc);
62}
63
64u32 gp10b_replayable_pagefault_buffer_get_index(struct gk20a *g)
65{
66 u32 get_idx = 0;
67
68 gk20a_dbg_fn("");
69
70 get_idx = gk20a_readl(g, fifo_replay_fault_buffer_get_r());
71
72 if (get_idx >= fifo_replay_fault_buffer_size_hw_entries_v())
73 dev_err(dev_from_gk20a(g), "%s Error in replayable fault buffer\n",
74 __func__);
75 gk20a_dbg_fn("done");
76 return get_idx;
77}
78
79u32 gp10b_replayable_pagefault_buffer_put_index(struct gk20a *g)
80{
81 u32 put_idx = 0;
82
83 gk20a_dbg_fn("");
84 put_idx = gk20a_readl(g, fifo_replay_fault_buffer_put_r());
85
86 if (put_idx >= fifo_replay_fault_buffer_size_hw_entries_v())
87 dev_err(dev_from_gk20a(g), "%s Error in UVM\n",
88 __func__);
89 gk20a_dbg_fn("done");
90 return put_idx;
91}
92
93bool gp10b_replayable_pagefault_buffer_is_empty(struct gk20a *g)
94{
95 u32 get_idx = gk20a_readl(g, fifo_replay_fault_buffer_get_r());
96 u32 put_idx = gk20a_readl(g, fifo_replay_fault_buffer_put_r());
97
98 return (get_idx == put_idx ? true : false);
99}
100
101bool gp10b_replayable_pagefault_buffer_is_full(struct gk20a *g)
102{
103 u32 get_idx = gk20a_readl(g, fifo_replay_fault_buffer_get_r());
104 u32 put_idx = gk20a_readl(g, fifo_replay_fault_buffer_put_r());
105 u32 hw_entries = gk20a_readl(g, fifo_replay_fault_buffer_size_r());
106
107 return (get_idx == ((put_idx + 1) % hw_entries) ? true : false);
108}
109
110bool gp10b_replayable_pagefault_buffer_is_overflow(struct gk20a *g)
111{
112 u32 info = gk20a_readl(g, fifo_replay_fault_buffer_info_r());
113
114 return fifo_replay_fault_buffer_info_overflow_f(info);
115}
116
117void gp10b_replayable_pagefault_buffer_clear_overflow(struct gk20a *g)
118{
119 u32 info = gk20a_readl(g, fifo_replay_fault_buffer_info_r());
120
121 info |= fifo_replay_fault_buffer_info_overflow_clear_v();
122 gk20a_writel(g, fifo_replay_fault_buffer_info_r(), info);
123
124}
125
126void gp10b_replayable_pagefault_buffer_info(struct gk20a *g)
127{
128
129 gk20a_dbg_fn("");
130 pr_info("rpfb low: 0x%x\n",
131 (gk20a_readl(g, fifo_replay_fault_buffer_lo_r()) >> 12));
132 pr_info("rpfb hi: 0x%x\n",
133 gk20a_readl(g, fifo_replay_fault_buffer_hi_r()));
134 pr_info("rpfb enabled: 0x%x\n",
135 (gk20a_readl(g, fifo_replay_fault_buffer_lo_r()) & 0x1));
136 pr_info("rpfb size: %d\n",
137 gk20a_readl(g, fifo_replay_fault_buffer_size_r()));
138 pr_info("rpfb get index: %d\n",
139 gp10b_replayable_pagefault_buffer_get_index(g));
140 pr_info("rpfb put index: %d\n",
141 gp10b_replayable_pagefault_buffer_put_index(g));
142 pr_info("rpfb empty: %d\n",
143 gp10b_replayable_pagefault_buffer_is_empty(g));
144 pr_info("rpfb full %d\n",
145 gp10b_replayable_pagefault_buffer_is_full(g));
146 pr_info("rpfb overflow %d\n",
147 gp10b_replayable_pagefault_buffer_is_overflow(g));
148
149 gk20a_dbg_fn("done");
150}