diff options
-rw-r--r-- | drivers/gpu/nvgpu/Makefile.nvgpu | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/intr.c | 58 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/intr.h | 20 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/module.c | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/pci.c | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mc_gk20a.c | 76 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mc_gk20a.h | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/mc_gm20b.c | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/mc_gp10b.c | 49 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/mc_gp10b.h | 5 |
11 files changed, 147 insertions, 89 deletions
diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu index c2d98559..109d1e4d 100644 --- a/drivers/gpu/nvgpu/Makefile.nvgpu +++ b/drivers/gpu/nvgpu/Makefile.nvgpu | |||
@@ -41,6 +41,7 @@ nvgpu-y := \ | |||
41 | common/linux/firmware.o \ | 41 | common/linux/firmware.o \ |
42 | common/linux/thread.o \ | 42 | common/linux/thread.o \ |
43 | common/linux/vm.o \ | 43 | common/linux/vm.o \ |
44 | common/linux/intr.o \ | ||
44 | common/mm/nvgpu_allocator.o \ | 45 | common/mm/nvgpu_allocator.o \ |
45 | common/mm/bitmap_allocator.o \ | 46 | common/mm/bitmap_allocator.o \ |
46 | common/mm/buddy_allocator.o \ | 47 | common/mm/buddy_allocator.o \ |
diff --git a/drivers/gpu/nvgpu/common/linux/intr.c b/drivers/gpu/nvgpu/common/linux/intr.c new file mode 100644 index 00000000..77e44dd9 --- /dev/null +++ b/drivers/gpu/nvgpu/common/linux/intr.c | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include <trace/events/gk20a.h> | ||
15 | |||
16 | #include "gk20a/gk20a.h" | ||
17 | |||
18 | #include <nvgpu/atomic.h> | ||
19 | |||
20 | irqreturn_t nvgpu_intr_stall(struct gk20a *g) | ||
21 | { | ||
22 | u32 mc_intr_0; | ||
23 | |||
24 | trace_mc_gk20a_intr_stall(g->name); | ||
25 | |||
26 | if (!g->power_on) | ||
27 | return IRQ_NONE; | ||
28 | |||
29 | /* not from gpu when sharing irq with others */ | ||
30 | mc_intr_0 = g->ops.mc.intr_stall(g); | ||
31 | if (unlikely(!mc_intr_0)) | ||
32 | return IRQ_NONE; | ||
33 | |||
34 | g->ops.mc.intr_stall_pause(g); | ||
35 | |||
36 | atomic_inc(&g->hw_irq_stall_count); | ||
37 | |||
38 | trace_mc_gk20a_intr_stall_done(g->name); | ||
39 | |||
40 | return IRQ_WAKE_THREAD; | ||
41 | } | ||
42 | |||
43 | irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g) | ||
44 | { | ||
45 | gk20a_dbg(gpu_dbg_intr, "interrupt thread launched"); | ||
46 | |||
47 | trace_mc_gk20a_intr_thread_stall(g->name); | ||
48 | |||
49 | g->ops.mc.isr_stall(g); | ||
50 | g->ops.mc.intr_stall_resume(g); | ||
51 | |||
52 | wake_up_all(&g->sw_irq_stall_last_handled_wq); | ||
53 | |||
54 | trace_mc_gk20a_intr_thread_stall_done(g->name); | ||
55 | |||
56 | return IRQ_HANDLED; | ||
57 | } | ||
58 | |||
diff --git a/drivers/gpu/nvgpu/common/linux/intr.h b/drivers/gpu/nvgpu/common/linux/intr.h new file mode 100644 index 00000000..243d8f51 --- /dev/null +++ b/drivers/gpu/nvgpu/common/linux/intr.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef __NVGPU_LINUX_INTR_H__ | ||
15 | #define __NVGPU_LINUX_INTR_H__ | ||
16 | struct gk20a; | ||
17 | |||
18 | irqreturn_t nvgpu_intr_stall(struct gk20a *g); | ||
19 | irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g); | ||
20 | #endif | ||
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c index ab99bef0..5e8af065 100644 --- a/drivers/gpu/nvgpu/common/linux/module.c +++ b/drivers/gpu/nvgpu/common/linux/module.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "gk20a/ctxsw_trace_gk20a.h" | 36 | #include "gk20a/ctxsw_trace_gk20a.h" |
37 | #include "pci.h" | 37 | #include "pci.h" |
38 | #include "module.h" | 38 | #include "module.h" |
39 | #include "intr.h" | ||
39 | #ifdef CONFIG_TEGRA_19x_GPU | 40 | #ifdef CONFIG_TEGRA_19x_GPU |
40 | #include "nvgpu_gpuid_t19x.h" | 41 | #include "nvgpu_gpuid_t19x.h" |
41 | #endif | 42 | #endif |
@@ -482,7 +483,7 @@ static irqreturn_t gk20a_intr_isr_stall(int irq, void *dev_id) | |||
482 | { | 483 | { |
483 | struct gk20a *g = dev_id; | 484 | struct gk20a *g = dev_id; |
484 | 485 | ||
485 | return g->ops.mc.isr_stall(g); | 486 | return nvgpu_intr_stall(g); |
486 | } | 487 | } |
487 | 488 | ||
488 | static irqreturn_t gk20a_intr_isr_nonstall(int irq, void *dev_id) | 489 | static irqreturn_t gk20a_intr_isr_nonstall(int irq, void *dev_id) |
@@ -496,7 +497,7 @@ static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id) | |||
496 | { | 497 | { |
497 | struct gk20a *g = dev_id; | 498 | struct gk20a *g = dev_id; |
498 | 499 | ||
499 | return g->ops.mc.isr_thread_stall(g); | 500 | return nvgpu_intr_thread_stall(g); |
500 | } | 501 | } |
501 | 502 | ||
502 | void gk20a_remove_support(struct gk20a *g) | 503 | void gk20a_remove_support(struct gk20a *g) |
diff --git a/drivers/gpu/nvgpu/common/linux/pci.c b/drivers/gpu/nvgpu/common/linux/pci.c index d729d273..767e9d47 100644 --- a/drivers/gpu/nvgpu/common/linux/pci.c +++ b/drivers/gpu/nvgpu/common/linux/pci.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "gk20a/platform_gk20a.h" | 25 | #include "gk20a/platform_gk20a.h" |
26 | #include "clk/clk.h" | 26 | #include "clk/clk.h" |
27 | #include "module.h" | 27 | #include "module.h" |
28 | #include "intr.h" | ||
28 | 29 | ||
29 | #include "pci.h" | 30 | #include "pci.h" |
30 | 31 | ||
@@ -232,7 +233,7 @@ static irqreturn_t nvgpu_pci_isr(int irq, void *dev_id) | |||
232 | irqreturn_t ret_stall; | 233 | irqreturn_t ret_stall; |
233 | irqreturn_t ret_nonstall; | 234 | irqreturn_t ret_nonstall; |
234 | 235 | ||
235 | ret_stall = g->ops.mc.isr_stall(g); | 236 | ret_stall = nvgpu_intr_stall(g); |
236 | ret_nonstall = g->ops.mc.isr_nonstall(g); | 237 | ret_nonstall = g->ops.mc.isr_nonstall(g); |
237 | 238 | ||
238 | #if defined(CONFIG_PCI_MSI) | 239 | #if defined(CONFIG_PCI_MSI) |
@@ -248,9 +249,7 @@ static irqreturn_t nvgpu_pci_intr_thread(int irq, void *dev_id) | |||
248 | { | 249 | { |
249 | struct gk20a *g = dev_id; | 250 | struct gk20a *g = dev_id; |
250 | 251 | ||
251 | g->ops.mc.isr_thread_stall(g); | 252 | return nvgpu_intr_thread_stall(g); |
252 | |||
253 | return IRQ_HANDLED; | ||
254 | } | 253 | } |
255 | 254 | ||
256 | static int nvgpu_pci_init_support(struct pci_dev *pdev) | 255 | static int nvgpu_pci_init_support(struct pci_dev *pdev) |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index ceadbae2..29ac4763 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -812,13 +812,15 @@ struct gpu_ops { | |||
812 | void (*intr_enable)(struct gk20a *g); | 812 | void (*intr_enable)(struct gk20a *g); |
813 | void (*intr_unit_config)(struct gk20a *g, | 813 | void (*intr_unit_config)(struct gk20a *g, |
814 | bool enable, bool is_stalling, u32 unit); | 814 | bool enable, bool is_stalling, u32 unit); |
815 | irqreturn_t (*isr_stall)(struct gk20a *g); | 815 | void (*isr_stall)(struct gk20a *g); |
816 | irqreturn_t (*isr_nonstall)(struct gk20a *g); | 816 | irqreturn_t (*isr_nonstall)(struct gk20a *g); |
817 | irqreturn_t (*isr_thread_stall)(struct gk20a *g); | ||
818 | void (*isr_thread_nonstall)(struct gk20a *g, u32 intr); | 817 | void (*isr_thread_nonstall)(struct gk20a *g, u32 intr); |
819 | void (*isr_nonstall_cb)(struct work_struct *work); | 818 | void (*isr_nonstall_cb)(struct work_struct *work); |
820 | bool (*is_intr_hub_pending)(struct gk20a *g, u32 mc_intr); | 819 | bool (*is_intr_hub_pending)(struct gk20a *g, u32 mc_intr); |
821 | u32 intr_mask_restore[4]; | 820 | u32 intr_mask_restore[4]; |
821 | u32 (*intr_stall)(struct gk20a *g); | ||
822 | void (*intr_stall_pause)(struct gk20a *g); | ||
823 | void (*intr_stall_resume)(struct gk20a *g); | ||
822 | void (*enable)(struct gk20a *g, u32 units); | 824 | void (*enable)(struct gk20a *g, u32 units); |
823 | void (*disable)(struct gk20a *g, u32 units); | 825 | void (*disable)(struct gk20a *g, u32 units); |
824 | void (*reset)(struct gk20a *g, u32 units); | 826 | void (*reset)(struct gk20a *g, u32 units); |
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 | ||
44 | irqreturn_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 | |||
71 | irqreturn_t mc_gk20a_isr_nonstall(struct gk20a *g) | 44 | irqreturn_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 | ||
109 | irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g) | 82 | void 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 | ||
173 | void mc_gk20a_intr_thread_nonstall(struct gk20a *g, u32 mc_intr_1) | 130 | void 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 | ||
210 | void 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 | |||
219 | void 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 | |||
228 | u32 mc_gk20a_intr_stall(struct gk20a *g) | ||
229 | { | ||
230 | return gk20a_readl(g, mc_intr_0_r()); | ||
231 | } | ||
232 | |||
253 | void gk20a_mc_disable(struct gk20a *g, u32 units) | 233 | void 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; |
diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.h b/drivers/gpu/nvgpu/gk20a/mc_gk20a.h index 9c70eba1..2b4a183e 100644 --- a/drivers/gpu/nvgpu/gk20a/mc_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.h | |||
@@ -19,7 +19,10 @@ void gk20a_init_mc(struct gpu_ops *gops); | |||
19 | void mc_gk20a_intr_enable(struct gk20a *g); | 19 | void mc_gk20a_intr_enable(struct gk20a *g); |
20 | void mc_gk20a_intr_unit_config(struct gk20a *g, bool enable, | 20 | void mc_gk20a_intr_unit_config(struct gk20a *g, bool enable, |
21 | bool is_stalling, u32 mask); | 21 | bool is_stalling, u32 mask); |
22 | irqreturn_t mc_gk20a_isr_stall(struct gk20a *g); | 22 | void mc_gk20a_isr_stall(struct gk20a *g); |
23 | u32 mc_gk20a_intr_stall(struct gk20a *g); | ||
24 | void mc_gk20a_intr_stall_pause(struct gk20a *g); | ||
25 | void mc_gk20a_intr_stall_resume(struct gk20a *g); | ||
23 | irqreturn_t mc_gk20a_isr_nonstall(struct gk20a *g); | 26 | irqreturn_t mc_gk20a_isr_nonstall(struct gk20a *g); |
24 | irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g); | 27 | irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g); |
25 | void mc_gk20a_intr_thread_nonstall(struct gk20a *g, u32 intr); | 28 | void mc_gk20a_intr_thread_nonstall(struct gk20a *g, u32 intr); |
diff --git a/drivers/gpu/nvgpu/gm20b/mc_gm20b.c b/drivers/gpu/nvgpu/gm20b/mc_gm20b.c index 05504e82..ebb9780d 100644 --- a/drivers/gpu/nvgpu/gm20b/mc_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/mc_gm20b.c | |||
@@ -22,8 +22,10 @@ void gm20b_init_mc(struct gpu_ops *gops) | |||
22 | gops->mc.intr_enable = mc_gk20a_intr_enable; | 22 | gops->mc.intr_enable = mc_gk20a_intr_enable; |
23 | gops->mc.intr_unit_config = mc_gk20a_intr_unit_config; | 23 | gops->mc.intr_unit_config = mc_gk20a_intr_unit_config; |
24 | gops->mc.isr_stall = mc_gk20a_isr_stall; | 24 | gops->mc.isr_stall = mc_gk20a_isr_stall; |
25 | gops->mc.intr_stall = mc_gk20a_intr_stall; | ||
26 | gops->mc.intr_stall_pause = mc_gk20a_intr_stall_pause; | ||
27 | gops->mc.intr_stall_resume = mc_gk20a_intr_stall_resume; | ||
25 | gops->mc.isr_nonstall = mc_gk20a_isr_nonstall; | 28 | gops->mc.isr_nonstall = mc_gk20a_isr_nonstall; |
26 | gops->mc.isr_thread_stall = mc_gk20a_intr_thread_stall; | ||
27 | gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall; | 29 | gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall; |
28 | gops->mc.isr_nonstall_cb = mc_gk20a_nonstall_cb; | 30 | gops->mc.isr_nonstall_cb = mc_gk20a_nonstall_cb; |
29 | gops->mc.enable = gk20a_mc_enable; | 31 | gops->mc.enable = gk20a_mc_enable; |
diff --git a/drivers/gpu/nvgpu/gp10b/mc_gp10b.c b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c index 4a48d7fa..bfc7a3d4 100644 --- a/drivers/gpu/nvgpu/gp10b/mc_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * GP20B master | 2 | * GP10B master |
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, |
@@ -67,25 +67,6 @@ void mc_gp10b_intr_unit_config(struct gk20a *g, bool enable, | |||
67 | gk20a_writel(g, reg, mask); | 67 | gk20a_writel(g, reg, mask); |
68 | } | 68 | } |
69 | 69 | ||
70 | irqreturn_t mc_gp10b_isr_stall(struct gk20a *g) | ||
71 | { | ||
72 | u32 mc_intr_0; | ||
73 | |||
74 | if (!g->power_on) | ||
75 | return IRQ_NONE; | ||
76 | |||
77 | /* not from gpu when sharing irq with others */ | ||
78 | mc_intr_0 = gk20a_readl(g, mc_intr_r(0)); | ||
79 | if (unlikely(!mc_intr_0)) | ||
80 | return IRQ_NONE; | ||
81 | |||
82 | gk20a_writel(g, mc_intr_en_clear_r(0), 0xffffffff); | ||
83 | |||
84 | atomic_inc(&g->hw_irq_stall_count); | ||
85 | |||
86 | return IRQ_WAKE_THREAD; | ||
87 | } | ||
88 | |||
89 | irqreturn_t mc_gp10b_isr_nonstall(struct gk20a *g) | 70 | irqreturn_t mc_gp10b_isr_nonstall(struct gk20a *g) |
90 | { | 71 | { |
91 | u32 mc_intr_1; | 72 | u32 mc_intr_1; |
@@ -117,7 +98,7 @@ irqreturn_t mc_gp10b_isr_nonstall(struct gk20a *g) | |||
117 | return IRQ_HANDLED; | 98 | return IRQ_HANDLED; |
118 | } | 99 | } |
119 | 100 | ||
120 | irqreturn_t mc_gp10b_intr_thread_stall(struct gk20a *g) | 101 | void mc_gp10b_isr_stall(struct gk20a *g) |
121 | { | 102 | { |
122 | u32 mc_intr_0; | 103 | u32 mc_intr_0; |
123 | int hw_irq_count; | 104 | int hw_irq_count; |
@@ -126,8 +107,6 @@ irqreturn_t mc_gp10b_intr_thread_stall(struct gk20a *g) | |||
126 | u32 active_engine_id = 0; | 107 | u32 active_engine_id = 0; |
127 | u32 engine_enum = ENGINE_INVAL_GK20A; | 108 | u32 engine_enum = ENGINE_INVAL_GK20A; |
128 | 109 | ||
129 | gk20a_dbg(gpu_dbg_intr, "interrupt thread launched"); | ||
130 | |||
131 | mc_intr_0 = gk20a_readl(g, mc_intr_r(0)); | 110 | mc_intr_0 = gk20a_readl(g, mc_intr_r(0)); |
132 | hw_irq_count = atomic_read(&g->hw_irq_stall_count); | 111 | hw_irq_count = atomic_read(&g->hw_irq_stall_count); |
133 | 112 | ||
@@ -172,12 +151,22 @@ irqreturn_t mc_gp10b_intr_thread_stall(struct gk20a *g) | |||
172 | 151 | ||
173 | gk20a_dbg(gpu_dbg_intr, "stall intr done 0x%08x\n", mc_intr_0); | 152 | gk20a_dbg(gpu_dbg_intr, "stall intr done 0x%08x\n", mc_intr_0); |
174 | 153 | ||
175 | gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_STALLING), | 154 | } |
176 | g->ops.mc.intr_mask_restore[NVGPU_MC_INTR_STALLING]); | ||
177 | 155 | ||
178 | wake_up_all(&g->sw_irq_stall_last_handled_wq); | 156 | u32 mc_gp10b_intr_stall(struct gk20a *g) |
157 | { | ||
158 | return gk20a_readl(g, mc_intr_r(NVGPU_MC_INTR_STALLING)); | ||
159 | } | ||
179 | 160 | ||
180 | return IRQ_HANDLED; | 161 | void mc_gp10b_intr_stall_pause(struct gk20a *g) |
162 | { | ||
163 | gk20a_writel(g, mc_intr_en_clear_r(NVGPU_MC_INTR_STALLING), 0xffffffff); | ||
164 | } | ||
165 | |||
166 | void mc_gp10b_intr_stall_resume(struct gk20a *g) | ||
167 | { | ||
168 | gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_STALLING), | ||
169 | g->ops.mc.intr_mask_restore[NVGPU_MC_INTR_STALLING]); | ||
181 | } | 170 | } |
182 | 171 | ||
183 | void gp10b_init_mc(struct gpu_ops *gops) | 172 | void gp10b_init_mc(struct gpu_ops *gops) |
@@ -185,8 +174,10 @@ void gp10b_init_mc(struct gpu_ops *gops) | |||
185 | gops->mc.intr_enable = mc_gp10b_intr_enable; | 174 | gops->mc.intr_enable = mc_gp10b_intr_enable; |
186 | gops->mc.intr_unit_config = mc_gp10b_intr_unit_config; | 175 | gops->mc.intr_unit_config = mc_gp10b_intr_unit_config; |
187 | gops->mc.isr_stall = mc_gp10b_isr_stall; | 176 | gops->mc.isr_stall = mc_gp10b_isr_stall; |
177 | gops->mc.intr_stall = mc_gp10b_intr_stall; | ||
178 | gops->mc.intr_stall_pause = mc_gp10b_intr_stall_pause; | ||
179 | gops->mc.intr_stall_resume = mc_gp10b_intr_stall_resume; | ||
188 | gops->mc.isr_nonstall = mc_gp10b_isr_nonstall; | 180 | gops->mc.isr_nonstall = mc_gp10b_isr_nonstall; |
189 | gops->mc.isr_thread_stall = mc_gp10b_intr_thread_stall; | ||
190 | gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall; | 181 | gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall; |
191 | gops->mc.isr_nonstall_cb = mc_gk20a_nonstall_cb; | 182 | gops->mc.isr_nonstall_cb = mc_gk20a_nonstall_cb; |
192 | gops->mc.enable = gk20a_mc_enable; | 183 | gops->mc.enable = gk20a_mc_enable; |
diff --git a/drivers/gpu/nvgpu/gp10b/mc_gp10b.h b/drivers/gpu/nvgpu/gp10b/mc_gp10b.h index b2ec4be4..31867a88 100644 --- a/drivers/gpu/nvgpu/gp10b/mc_gp10b.h +++ b/drivers/gpu/nvgpu/gp10b/mc_gp10b.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. | 2 | * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms and conditions of the GNU General Public License, | 5 | * under the terms and conditions of the GNU General Public License, |
@@ -24,8 +24,7 @@ void gp10b_init_mc(struct gpu_ops *gops); | |||
24 | void mc_gp10b_intr_enable(struct gk20a *g); | 24 | void mc_gp10b_intr_enable(struct gk20a *g); |
25 | void mc_gp10b_intr_unit_config(struct gk20a *g, bool enable, | 25 | void mc_gp10b_intr_unit_config(struct gk20a *g, bool enable, |
26 | bool is_stalling, u32 mask); | 26 | bool is_stalling, u32 mask); |
27 | irqreturn_t mc_gp10b_isr_stall(struct gk20a *g); | 27 | void mc_gp10b_isr_stall(struct gk20a *g); |
28 | irqreturn_t mc_gp10b_isr_nonstall(struct gk20a *g); | 28 | irqreturn_t mc_gp10b_isr_nonstall(struct gk20a *g); |
29 | irqreturn_t mc_gp10b_intr_thread_stall(struct gk20a *g); | ||
30 | irqreturn_t mc_gp10b_intr_thread_nonstall(struct gk20a *g); | 29 | irqreturn_t mc_gp10b_intr_thread_nonstall(struct gk20a *g); |
31 | #endif | 30 | #endif |