summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c
diff options
context:
space:
mode:
authorSeshendra Gadagottu <sgadagottu@nvidia.com>2015-02-06 15:39:05 -0500
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:52:04 -0500
commit8fe7abebbbbfdc8b1acedd41aa8ac1926a24dc93 (patch)
tree34d1179b51df7b1a94698eed1e8f6d98c8055add /drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c
parent750014be79cce9562653db96e735f78fdc2e058f (diff)
gpu: nvgpu: gp10b: Add replayable pagefault buffer
Add support for replayable fault buffer and enable it. Bug 1587836 Change-Id: Iee4ba42ab175c0d72d2c041fdb3ac9d845358847 Signed-off-by: Seshendra Gadagottu <sgadagottu@nvidia.com> Reviewed-on: http://git-master/r/661668 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c')
-rw-r--r--drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c146
1 files changed, 146 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..ba91403c
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c
@@ -0,0 +1,146 @@
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 err = gk20a_gmmu_alloc_map(vm, rbfb_size, &g->mm.bar2_desc);
37 if (err) {
38 dev_err(dev_from_gk20a(g), "%s Error in replayable fault buffer\n",
39 __func__);
40 return err;
41 }
42 addr_lo = u64_lo32(g->mm.bar2_desc.gpu_va >> 12);
43 addr_hi = u64_hi32(g->mm.bar2_desc.gpu_va);
44 gk20a_writel(g, fifo_replay_fault_buffer_hi_r(),
45 fifo_replay_fault_buffer_hi_base_f(addr_hi));
46
47 gk20a_writel(g, fifo_replay_fault_buffer_lo_r(),
48 fifo_replay_fault_buffer_lo_base_f(addr_lo) |
49 fifo_replay_fault_buffer_lo_enable_true_v());
50
51 gk20a_dbg_fn("done");
52 return 0;
53}
54
55void gp10b_replayable_pagefault_buffer_deinit(struct gk20a *g)
56{
57 struct vm_gk20a *vm = &g->mm.bar2.vm;
58 gk20a_gmmu_unmap_free(vm, &g->mm.bar2_desc);
59}
60
61u32 gp10b_replayable_pagefault_buffer_get_index(struct gk20a *g)
62{
63 u32 get_idx = 0;
64 gk20a_dbg_fn("");
65
66 get_idx = gk20a_readl(g, fifo_replay_fault_buffer_get_r());
67
68 if (get_idx >= fifo_replay_fault_buffer_size_hw_entries_v())
69 dev_err(dev_from_gk20a(g), "%s Error in replayable fault buffer\n",
70 __func__);
71 gk20a_dbg_fn("done");
72 return get_idx;
73}
74
75u32 gp10b_replayable_pagefault_buffer_put_index(struct gk20a *g)
76{
77 u32 put_idx = 0;
78
79 gk20a_dbg_fn("");
80 put_idx = gk20a_readl(g, fifo_replay_fault_buffer_put_r());
81
82 if (put_idx >= fifo_replay_fault_buffer_size_hw_entries_v())
83 dev_err(dev_from_gk20a(g), "%s Error in UVM\n",
84 __func__);
85 gk20a_dbg_fn("done");
86 return put_idx;
87}
88
89bool gp10b_replayable_pagefault_buffer_is_empty(struct gk20a *g)
90{
91 u32 get_idx = gk20a_readl(g, fifo_replay_fault_buffer_get_r());
92 u32 put_idx = gk20a_readl(g, fifo_replay_fault_buffer_put_r());
93
94 return (get_idx == put_idx ? true : false);
95}
96
97bool gp10b_replayable_pagefault_buffer_is_full(struct gk20a *g)
98{
99 u32 get_idx = gk20a_readl(g, fifo_replay_fault_buffer_get_r());
100 u32 put_idx = gk20a_readl(g, fifo_replay_fault_buffer_put_r());
101 u32 hw_entries = gk20a_readl(g, fifo_replay_fault_buffer_size_r());
102
103 return (get_idx == ((put_idx + 1) % hw_entries) ? true : false);
104}
105
106bool gp10b_replayable_pagefault_buffer_is_overflow(struct gk20a *g)
107{
108 u32 info = gk20a_readl(g, fifo_replay_fault_buffer_info_r());
109
110 return fifo_replay_fault_buffer_info_overflow_f(info);
111}
112
113void gp10b_replayable_pagefault_buffer_clear_overflow(struct gk20a *g)
114{
115 u32 info = gk20a_readl(g, fifo_replay_fault_buffer_info_r());
116
117 info |= fifo_replay_fault_buffer_info_overflow_clear_v();
118 gk20a_writel(g, fifo_replay_fault_buffer_info_r(), info);
119
120}
121
122void gp10b_replayable_pagefault_buffer_info(struct gk20a *g)
123{
124
125 gk20a_dbg_fn("");
126 pr_info("rpfb low: 0x%x\n",
127 (gk20a_readl(g, fifo_replay_fault_buffer_lo_r()) >> 12));
128 pr_info("rpfb hi: 0x%x\n",
129 gk20a_readl(g, fifo_replay_fault_buffer_hi_r()));
130 pr_info("rpfb enabled: 0x%x\n",
131 (gk20a_readl(g, fifo_replay_fault_buffer_lo_r()) & 0x1));
132 pr_info("rpfb size: %d\n",
133 gk20a_readl(g, fifo_replay_fault_buffer_size_r()));
134 pr_info("rpfb get index: %d\n",
135 gp10b_replayable_pagefault_buffer_get_index(g));
136 pr_info("rpfb put index: %d\n",
137 gp10b_replayable_pagefault_buffer_put_index(g));
138 pr_info("rpfb empty: %d\n",
139 gp10b_replayable_pagefault_buffer_is_empty(g));
140 pr_info("rpfb full %d\n",
141 gp10b_replayable_pagefault_buffer_is_full(g));
142 pr_info("rpfb overflow %d\n",
143 gp10b_replayable_pagefault_buffer_is_overflow(g));
144
145 gk20a_dbg_fn("done");
146}