summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/mc_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mc_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mc_gk20a.c76
1 files changed, 29 insertions, 47 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c
index ca7189cc..bc11b14d 100644
--- a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * GK20A Master Control 2 * GK20A Master Control
3 * 3 *
4 * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 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, 7 * under the terms and conditions of the GNU General Public License,
@@ -41,33 +41,6 @@ void mc_gk20a_nonstall_cb(struct work_struct *work)
41 } while (atomic_read(&g->nonstall_ops) != 0); 41 } while (atomic_read(&g->nonstall_ops) != 0);
42} 42}
43 43
44irqreturn_t mc_gk20a_isr_stall(struct gk20a *g)
45{
46 u32 mc_intr_0;
47
48 trace_mc_gk20a_intr_stall(g->name);
49
50 if (!g->power_on)
51 return IRQ_NONE;
52
53 /* not from gpu when sharing irq with others */
54 mc_intr_0 = gk20a_readl(g, mc_intr_0_r());
55 if (unlikely(!mc_intr_0))
56 return IRQ_NONE;
57
58 gk20a_writel(g, mc_intr_en_0_r(),
59 mc_intr_en_0_inta_disabled_f());
60
61 /* flush previous write */
62 gk20a_readl(g, mc_intr_en_0_r());
63
64 atomic_inc(&g->hw_irq_stall_count);
65
66 trace_mc_gk20a_intr_stall_done(g->name);
67
68 return IRQ_WAKE_THREAD;
69}
70
71irqreturn_t mc_gk20a_isr_nonstall(struct gk20a *g) 44irqreturn_t mc_gk20a_isr_nonstall(struct gk20a *g)
72{ 45{
73 u32 mc_intr_1; 46 u32 mc_intr_1;
@@ -106,7 +79,7 @@ irqreturn_t mc_gk20a_isr_nonstall(struct gk20a *g)
106 return IRQ_HANDLED; 79 return IRQ_HANDLED;
107} 80}
108 81
109irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g) 82void mc_gk20a_isr_stall(struct gk20a *g)
110{ 83{
111 u32 mc_intr_0; 84 u32 mc_intr_0;
112 int hw_irq_count; 85 int hw_irq_count;
@@ -114,11 +87,7 @@ irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g)
114 u32 active_engine_id = 0; 87 u32 active_engine_id = 0;
115 u32 engine_enum = ENGINE_INVAL_GK20A; 88 u32 engine_enum = ENGINE_INVAL_GK20A;
116 89
117 gk20a_dbg(gpu_dbg_intr, "interrupt thread launched"); 90 mc_intr_0 = g->ops.mc.intr_stall(g);
118
119 trace_mc_gk20a_intr_thread_stall(g->name);
120
121 mc_intr_0 = gk20a_readl(g, mc_intr_0_r());
122 hw_irq_count = atomic_read(&g->hw_irq_stall_count); 91 hw_irq_count = atomic_read(&g->hw_irq_stall_count);
123 92
124 gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0); 93 gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0);
@@ -156,18 +125,6 @@ irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g)
156 125
157 /* sync handled irq counter before re-enabling interrupts */ 126 /* sync handled irq counter before re-enabling interrupts */
158 atomic_set(&g->sw_irq_stall_last_handled, hw_irq_count); 127 atomic_set(&g->sw_irq_stall_last_handled, hw_irq_count);
159
160 gk20a_writel(g, mc_intr_en_0_r(),
161 mc_intr_en_0_inta_hardware_f());
162
163 /* flush previous write */
164 gk20a_readl(g, mc_intr_en_0_r());
165
166 wake_up_all(&g->sw_irq_stall_last_handled_wq);
167
168 trace_mc_gk20a_intr_thread_stall_done(g->name);
169
170 return IRQ_HANDLED;
171} 128}
172 129
173void mc_gk20a_intr_thread_nonstall(struct gk20a *g, u32 mc_intr_1) 130void mc_gk20a_intr_thread_nonstall(struct gk20a *g, u32 mc_intr_1)
@@ -250,6 +207,29 @@ void mc_gk20a_intr_unit_config(struct gk20a *g, bool enable,
250 } 207 }
251} 208}
252 209
210void mc_gk20a_intr_stall_pause(struct gk20a *g)
211{
212 gk20a_writel(g, mc_intr_en_0_r(),
213 mc_intr_en_0_inta_disabled_f());
214
215 /* flush previous write */
216 gk20a_readl(g, mc_intr_en_0_r());
217}
218
219void mc_gk20a_intr_stall_resume(struct gk20a *g)
220{
221 gk20a_writel(g, mc_intr_en_0_r(),
222 mc_intr_en_0_inta_hardware_f());
223
224 /* flush previous write */
225 gk20a_readl(g, mc_intr_en_0_r());
226}
227
228u32 mc_gk20a_intr_stall(struct gk20a *g)
229{
230 return gk20a_readl(g, mc_intr_0_r());
231}
232
253void gk20a_mc_disable(struct gk20a *g, u32 units) 233void gk20a_mc_disable(struct gk20a *g, u32 units)
254{ 234{
255 u32 pmc; 235 u32 pmc;
@@ -312,8 +292,10 @@ void gk20a_init_mc(struct gpu_ops *gops)
312 gops->mc.intr_enable = mc_gk20a_intr_enable; 292 gops->mc.intr_enable = mc_gk20a_intr_enable;
313 gops->mc.intr_unit_config = mc_gk20a_intr_unit_config; 293 gops->mc.intr_unit_config = mc_gk20a_intr_unit_config;
314 gops->mc.isr_stall = mc_gk20a_isr_stall; 294 gops->mc.isr_stall = mc_gk20a_isr_stall;
295 gops->mc.intr_stall = mc_gk20a_intr_stall;
296 gops->mc.intr_stall_pause = mc_gk20a_intr_stall_pause;
297 gops->mc.intr_stall_resume = mc_gk20a_intr_stall_resume;
315 gops->mc.isr_nonstall = mc_gk20a_isr_nonstall; 298 gops->mc.isr_nonstall = mc_gk20a_isr_nonstall;
316 gops->mc.isr_thread_stall = mc_gk20a_intr_thread_stall;
317 gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall; 299 gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall;
318 gops->mc.isr_nonstall_cb = mc_gk20a_nonstall_cb; 300 gops->mc.isr_nonstall_cb = mc_gk20a_nonstall_cb;
319 gops->mc.enable = gk20a_mc_enable; 301 gops->mc.enable = gk20a_mc_enable;