diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/pramin.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/pramin.c | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/common/pramin.c b/drivers/gpu/nvgpu/common/pramin.c index 4c6a4a0d..99d588aa 100644 --- a/drivers/gpu/nvgpu/common/pramin.c +++ b/drivers/gpu/nvgpu/common/pramin.c | |||
@@ -28,11 +28,18 @@ | |||
28 | #include "gk20a/gk20a.h" | 28 | #include "gk20a/gk20a.h" |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * This typedef is for functions that get called during the access_batched() | ||
32 | * operation. | ||
33 | */ | ||
34 | typedef void (*pramin_access_batch_fn)(struct gk20a *g, u32 start, u32 words, | ||
35 | u32 **arg); | ||
36 | |||
37 | /* | ||
31 | * The PRAMIN range is 1 MB, must change base addr if a buffer crosses that. | 38 | * The PRAMIN range is 1 MB, must change base addr if a buffer crosses that. |
32 | * This same loop is used for read/write/memset. Offset and size in bytes. | 39 | * This same loop is used for read/write/memset. Offset and size in bytes. |
33 | * One call to "loop" is done per range, with "arg" supplied. | 40 | * One call to "loop" is done per range, with "arg" supplied. |
34 | */ | 41 | */ |
35 | void nvgpu_pramin_access_batched(struct gk20a *g, struct nvgpu_mem *mem, | 42 | static void nvgpu_pramin_access_batched(struct gk20a *g, struct nvgpu_mem *mem, |
36 | u32 offset, u32 size, pramin_access_batch_fn loop, u32 **arg) | 43 | u32 offset, u32 size, pramin_access_batch_fn loop, u32 **arg) |
37 | { | 44 | { |
38 | struct nvgpu_page_alloc *alloc = NULL; | 45 | struct nvgpu_page_alloc *alloc = NULL; |
@@ -87,6 +94,69 @@ void nvgpu_pramin_access_batched(struct gk20a *g, struct nvgpu_mem *mem, | |||
87 | } | 94 | } |
88 | } | 95 | } |
89 | 96 | ||
97 | static void nvgpu_pramin_access_batch_rd_n(struct gk20a *g, | ||
98 | u32 start, u32 words, u32 **arg) | ||
99 | { | ||
100 | u32 r = start, *dest_u32 = *arg; | ||
101 | |||
102 | while (words--) { | ||
103 | *dest_u32++ = nvgpu_readl(g, r); | ||
104 | r += sizeof(u32); | ||
105 | } | ||
106 | |||
107 | *arg = dest_u32; | ||
108 | } | ||
109 | |||
110 | void nvgpu_pramin_rd_n(struct gk20a *g, struct nvgpu_mem *mem, | ||
111 | u32 start, u32 size, void *dest) | ||
112 | { | ||
113 | u32 *dest_u32 = dest; | ||
114 | |||
115 | return nvgpu_pramin_access_batched(g, mem, start, size, | ||
116 | nvgpu_pramin_access_batch_rd_n, &dest_u32); | ||
117 | } | ||
118 | |||
119 | static void nvgpu_pramin_access_batch_wr_n(struct gk20a *g, | ||
120 | u32 start, u32 words, u32 **arg) | ||
121 | { | ||
122 | u32 r = start, *src_u32 = *arg; | ||
123 | |||
124 | while (words--) { | ||
125 | nvgpu_writel_relaxed(g, r, *src_u32++); | ||
126 | r += sizeof(u32); | ||
127 | } | ||
128 | |||
129 | *arg = src_u32; | ||
130 | } | ||
131 | |||
132 | void nvgpu_pramin_wr_n(struct gk20a *g, struct nvgpu_mem *mem, | ||
133 | u32 start, u32 size, void *src) | ||
134 | { | ||
135 | u32 *src_u32 = src; | ||
136 | |||
137 | return nvgpu_pramin_access_batched(g, mem, start, size, | ||
138 | nvgpu_pramin_access_batch_wr_n, &src_u32); | ||
139 | } | ||
140 | |||
141 | static void nvgpu_pramin_access_batch_set(struct gk20a *g, | ||
142 | u32 start, u32 words, u32 **arg) | ||
143 | { | ||
144 | u32 r = start, repeat = **arg; | ||
145 | |||
146 | while (words--) { | ||
147 | nvgpu_writel_relaxed(g, r, repeat); | ||
148 | r += sizeof(u32); | ||
149 | } | ||
150 | } | ||
151 | |||
152 | void nvgpu_pramin_memset(struct gk20a *g, struct nvgpu_mem *mem, | ||
153 | u32 start, u32 size, u32 w) | ||
154 | { | ||
155 | u32 *p = &w; | ||
156 | |||
157 | return nvgpu_pramin_access_batched(g, mem, start, size, | ||
158 | nvgpu_pramin_access_batch_set, &p); | ||
159 | } | ||
90 | void nvgpu_init_pramin(struct mm_gk20a *mm) | 160 | void nvgpu_init_pramin(struct mm_gk20a *mm) |
91 | { | 161 | { |
92 | mm->pramin_window = 0; | 162 | mm->pramin_window = 0; |