diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mc_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mc_gk20a.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c index e51c4a29..3d6919c5 100644 --- a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c | |||
@@ -14,6 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/delay.h> | ||
17 | #include <trace/events/gk20a.h> | 18 | #include <trace/events/gk20a.h> |
18 | 19 | ||
19 | #include "gk20a.h" | 20 | #include "gk20a.h" |
@@ -248,6 +249,63 @@ void mc_gk20a_intr_unit_config(struct gk20a *g, bool enable, | |||
248 | } | 249 | } |
249 | } | 250 | } |
250 | 251 | ||
252 | void gk20a_mc_disable(struct gk20a *g, u32 units) | ||
253 | { | ||
254 | u32 pmc; | ||
255 | |||
256 | gk20a_dbg(gpu_dbg_info, "pmc disable: %08x\n", units); | ||
257 | |||
258 | nvgpu_spinlock_acquire(&g->mc_enable_lock); | ||
259 | pmc = gk20a_readl(g, mc_enable_r()); | ||
260 | pmc &= ~units; | ||
261 | gk20a_writel(g, mc_enable_r(), pmc); | ||
262 | nvgpu_spinlock_release(&g->mc_enable_lock); | ||
263 | } | ||
264 | |||
265 | void gk20a_mc_enable(struct gk20a *g, u32 units) | ||
266 | { | ||
267 | u32 pmc; | ||
268 | |||
269 | gk20a_dbg(gpu_dbg_info, "pmc enable: %08x\n", units); | ||
270 | |||
271 | nvgpu_spinlock_acquire(&g->mc_enable_lock); | ||
272 | pmc = gk20a_readl(g, mc_enable_r()); | ||
273 | pmc |= units; | ||
274 | gk20a_writel(g, mc_enable_r(), pmc); | ||
275 | gk20a_readl(g, mc_enable_r()); | ||
276 | nvgpu_spinlock_release(&g->mc_enable_lock); | ||
277 | |||
278 | udelay(20); | ||
279 | } | ||
280 | |||
281 | void gk20a_mc_reset(struct gk20a *g, u32 units) | ||
282 | { | ||
283 | g->ops.mc.disable(g, units); | ||
284 | if (units & gk20a_fifo_get_all_ce_engine_reset_mask(g)) | ||
285 | udelay(500); | ||
286 | else | ||
287 | udelay(20); | ||
288 | g->ops.mc.enable(g, units); | ||
289 | } | ||
290 | |||
291 | u32 gk20a_mc_boot_0(struct gk20a *g, u32 *arch, u32 *impl, u32 *rev) | ||
292 | { | ||
293 | u32 val = gk20a_readl(g, mc_boot_0_r()); | ||
294 | |||
295 | if (arch) | ||
296 | *arch = mc_boot_0_architecture_v(val) << | ||
297 | NVGPU_GPU_ARCHITECTURE_SHIFT; | ||
298 | |||
299 | if (impl) | ||
300 | *impl = mc_boot_0_implementation_v(val); | ||
301 | |||
302 | if (rev) | ||
303 | *rev = (mc_boot_0_major_revision_v(val) << 4) | | ||
304 | mc_boot_0_minor_revision_v(val); | ||
305 | |||
306 | return val; | ||
307 | } | ||
308 | |||
251 | void gk20a_init_mc(struct gpu_ops *gops) | 309 | void gk20a_init_mc(struct gpu_ops *gops) |
252 | { | 310 | { |
253 | gops->mc.intr_enable = mc_gk20a_intr_enable; | 311 | gops->mc.intr_enable = mc_gk20a_intr_enable; |
@@ -257,4 +315,8 @@ void gk20a_init_mc(struct gpu_ops *gops) | |||
257 | gops->mc.isr_thread_stall = mc_gk20a_intr_thread_stall; | 315 | gops->mc.isr_thread_stall = mc_gk20a_intr_thread_stall; |
258 | gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall; | 316 | gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall; |
259 | gops->mc.isr_nonstall_cb = mc_gk20a_nonstall_cb; | 317 | gops->mc.isr_nonstall_cb = mc_gk20a_nonstall_cb; |
318 | gops->mc.enable = gk20a_mc_enable; | ||
319 | gops->mc.disable = gk20a_mc_disable; | ||
320 | gops->mc.reset = gk20a_mc_reset; | ||
321 | gops->mc.boot_0 = gk20a_mc_boot_0; | ||
260 | } | 322 | } |