diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/intr.c | 84 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/intr.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/module.c | 9 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/pci.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mc_gk20a.c | 128 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mc_gk20a.h | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/mc_gm20b.c | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/mc_gp10b.c | 54 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/mc_gp10b.h | 2 |
11 files changed, 150 insertions, 158 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/intr.c b/drivers/gpu/nvgpu/common/linux/intr.c index 77e44dd9..7d699dee 100644 --- a/drivers/gpu/nvgpu/common/linux/intr.c +++ b/drivers/gpu/nvgpu/common/linux/intr.c | |||
@@ -12,10 +12,12 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <trace/events/gk20a.h> | 14 | #include <trace/events/gk20a.h> |
15 | #include <linux/irqreturn.h> | ||
15 | 16 | ||
16 | #include "gk20a/gk20a.h" | 17 | #include "gk20a/gk20a.h" |
17 | 18 | ||
18 | #include <nvgpu/atomic.h> | 19 | #include <nvgpu/atomic.h> |
20 | #include <nvgpu/unit.h> | ||
19 | 21 | ||
20 | irqreturn_t nvgpu_intr_stall(struct gk20a *g) | 22 | irqreturn_t nvgpu_intr_stall(struct gk20a *g) |
21 | { | 23 | { |
@@ -56,3 +58,85 @@ irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g) | |||
56 | return IRQ_HANDLED; | 58 | return IRQ_HANDLED; |
57 | } | 59 | } |
58 | 60 | ||
61 | irqreturn_t nvgpu_intr_nonstall(struct gk20a *g) | ||
62 | { | ||
63 | u32 mc_intr_1; | ||
64 | u32 hw_irq_count; | ||
65 | u32 engine_id_idx; | ||
66 | u32 active_engine_id = 0; | ||
67 | u32 engine_enum = ENGINE_INVAL_GK20A; | ||
68 | int ops_old, ops_new, ops = 0; | ||
69 | if (!g->power_on) | ||
70 | return IRQ_NONE; | ||
71 | |||
72 | /* not from gpu when sharing irq with others */ | ||
73 | mc_intr_1 = g->ops.mc.intr_nonstall(g); | ||
74 | if (unlikely(!mc_intr_1)) | ||
75 | return IRQ_NONE; | ||
76 | |||
77 | g->ops.mc.intr_nonstall_pause(g); | ||
78 | |||
79 | if (g->ops.mc.is_intr1_pending(g, NVGPU_UNIT_FIFO, mc_intr_1)) | ||
80 | ops |= gk20a_fifo_nonstall_isr(g); | ||
81 | |||
82 | for (engine_id_idx = 0; engine_id_idx < g->fifo.num_engines; | ||
83 | engine_id_idx++) { | ||
84 | struct fifo_engine_info_gk20a *engine_info; | ||
85 | |||
86 | active_engine_id = g->fifo.active_engines_list[engine_id_idx]; | ||
87 | engine_info = &g->fifo.engine_info[active_engine_id]; | ||
88 | |||
89 | if (mc_intr_1 & engine_info->intr_mask) { | ||
90 | engine_enum = engine_info->engine_enum; | ||
91 | /* GR Engine */ | ||
92 | if (engine_enum == ENGINE_GR_GK20A) | ||
93 | ops |= gk20a_gr_nonstall_isr(g); | ||
94 | |||
95 | /* CE Engine */ | ||
96 | if (((engine_enum == ENGINE_GRCE_GK20A) || | ||
97 | (engine_enum == ENGINE_ASYNC_CE_GK20A)) && | ||
98 | g->ops.ce2.isr_nonstall) | ||
99 | ops |= g->ops.ce2.isr_nonstall(g, | ||
100 | engine_info->inst_id, | ||
101 | engine_info->pri_base); | ||
102 | } | ||
103 | } | ||
104 | if (ops) { | ||
105 | do { | ||
106 | ops_old = atomic_read(&g->nonstall_ops); | ||
107 | ops_new = ops_old | ops; | ||
108 | } while (ops_old != atomic_cmpxchg(&g->nonstall_ops, | ||
109 | ops_old, ops_new)); | ||
110 | |||
111 | queue_work(g->nonstall_work_queue, &g->nonstall_fn_work); | ||
112 | } | ||
113 | |||
114 | hw_irq_count = atomic_inc_return(&g->hw_irq_nonstall_count); | ||
115 | |||
116 | /* sync handled irq counter before re-enabling interrupts */ | ||
117 | atomic_set(&g->sw_irq_nonstall_last_handled, hw_irq_count); | ||
118 | |||
119 | g->ops.mc.intr_nonstall_resume(g); | ||
120 | |||
121 | wake_up_all(&g->sw_irq_nonstall_last_handled_wq); | ||
122 | |||
123 | return IRQ_HANDLED; | ||
124 | } | ||
125 | |||
126 | void nvgpu_intr_nonstall_cb(struct work_struct *work) | ||
127 | { | ||
128 | struct gk20a *g = container_of(work, struct gk20a, nonstall_fn_work); | ||
129 | u32 ops; | ||
130 | bool semaphore_wakeup, post_events; | ||
131 | |||
132 | do { | ||
133 | ops = atomic_xchg(&g->nonstall_ops, 0); | ||
134 | |||
135 | semaphore_wakeup = ops & gk20a_nonstall_ops_wakeup_semaphore; | ||
136 | post_events = ops & gk20a_nonstall_ops_post_events; | ||
137 | |||
138 | if (semaphore_wakeup) | ||
139 | gk20a_channel_semaphore_wakeup(g, post_events); | ||
140 | |||
141 | } while (atomic_read(&g->nonstall_ops) != 0); | ||
142 | } | ||
diff --git a/drivers/gpu/nvgpu/common/linux/intr.h b/drivers/gpu/nvgpu/common/linux/intr.h index 243d8f51..d43cdccb 100644 --- a/drivers/gpu/nvgpu/common/linux/intr.h +++ b/drivers/gpu/nvgpu/common/linux/intr.h | |||
@@ -17,4 +17,6 @@ struct gk20a; | |||
17 | 17 | ||
18 | irqreturn_t nvgpu_intr_stall(struct gk20a *g); | 18 | irqreturn_t nvgpu_intr_stall(struct gk20a *g); |
19 | irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g); | 19 | irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g); |
20 | irqreturn_t nvgpu_intr_nonstall(struct gk20a *g); | ||
21 | void nvgpu_intr_nonstall_cb(struct work_struct *work); | ||
20 | #endif | 22 | #endif |
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c index 4f7fc3fa..34a0ded6 100644 --- a/drivers/gpu/nvgpu/common/linux/module.c +++ b/drivers/gpu/nvgpu/common/linux/module.c | |||
@@ -162,6 +162,13 @@ int gk20a_pm_finalize_poweron(struct device *dev) | |||
162 | nice_value = task_nice(current); | 162 | nice_value = task_nice(current); |
163 | set_user_nice(current, -20); | 163 | set_user_nice(current, -20); |
164 | 164 | ||
165 | /* Enable interrupt workqueue */ | ||
166 | if (!g->nonstall_work_queue) { | ||
167 | g->nonstall_work_queue = alloc_workqueue("%s", | ||
168 | WQ_HIGHPRI, 1, "mc_nonstall"); | ||
169 | INIT_WORK(&g->nonstall_fn_work, nvgpu_intr_nonstall_cb); | ||
170 | } | ||
171 | |||
165 | err = gk20a_finalize_poweron(g); | 172 | err = gk20a_finalize_poweron(g); |
166 | set_user_nice(current, nice_value); | 173 | set_user_nice(current, nice_value); |
167 | if (err) | 174 | if (err) |
@@ -492,7 +499,7 @@ static irqreturn_t gk20a_intr_isr_nonstall(int irq, void *dev_id) | |||
492 | { | 499 | { |
493 | struct gk20a *g = dev_id; | 500 | struct gk20a *g = dev_id; |
494 | 501 | ||
495 | return g->ops.mc.isr_nonstall(g); | 502 | return nvgpu_intr_nonstall(g); |
496 | } | 503 | } |
497 | 504 | ||
498 | static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id) | 505 | static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id) |
diff --git a/drivers/gpu/nvgpu/common/linux/pci.c b/drivers/gpu/nvgpu/common/linux/pci.c index b66a6658..4351ba5b 100644 --- a/drivers/gpu/nvgpu/common/linux/pci.c +++ b/drivers/gpu/nvgpu/common/linux/pci.c | |||
@@ -235,7 +235,7 @@ static irqreturn_t nvgpu_pci_isr(int irq, void *dev_id) | |||
235 | irqreturn_t ret_nonstall; | 235 | irqreturn_t ret_nonstall; |
236 | 236 | ||
237 | ret_stall = nvgpu_intr_stall(g); | 237 | ret_stall = nvgpu_intr_stall(g); |
238 | ret_nonstall = g->ops.mc.isr_nonstall(g); | 238 | ret_nonstall = nvgpu_intr_nonstall(g); |
239 | 239 | ||
240 | #if defined(CONFIG_PCI_MSI) | 240 | #if defined(CONFIG_PCI_MSI) |
241 | /* Send MSI EOI */ | 241 | /* Send MSI EOI */ |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index e4d454fe..b038cd81 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c | |||
@@ -187,13 +187,6 @@ int gk20a_finalize_poweron(struct gk20a *g) | |||
187 | if (g->ops.clk.disable_slowboot) | 187 | if (g->ops.clk.disable_slowboot) |
188 | g->ops.clk.disable_slowboot(g); | 188 | g->ops.clk.disable_slowboot(g); |
189 | 189 | ||
190 | /* Enable interrupt workqueue */ | ||
191 | if (!g->nonstall_work_queue) { | ||
192 | g->nonstall_work_queue = alloc_workqueue("%s", | ||
193 | WQ_HIGHPRI, 1, "mc_nonstall"); | ||
194 | INIT_WORK(&g->nonstall_fn_work, g->ops.mc.isr_nonstall_cb); | ||
195 | } | ||
196 | |||
197 | gk20a_enable_priv_ring(g); | 190 | gk20a_enable_priv_ring(g); |
198 | 191 | ||
199 | /* TBD: move this after graphics init in which blcg/slcg is enabled. | 192 | /* TBD: move this after graphics init in which blcg/slcg is enabled. |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index bd93cc33..60494050 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -36,7 +36,6 @@ struct nvgpu_clk_pll_debug_data; | |||
36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
37 | #include <nvgpu/lock.h> | 37 | #include <nvgpu/lock.h> |
38 | #include <nvgpu/thread.h> | 38 | #include <nvgpu/thread.h> |
39 | #include <linux/irqreturn.h> | ||
40 | #include <linux/version.h> | 39 | #include <linux/version.h> |
41 | #include <linux/cdev.h> | 40 | #include <linux/cdev.h> |
42 | #ifdef CONFIG_DEBUG_FS | 41 | #ifdef CONFIG_DEBUG_FS |
@@ -841,14 +840,14 @@ struct gpu_ops { | |||
841 | void (*intr_unit_config)(struct gk20a *g, | 840 | void (*intr_unit_config)(struct gk20a *g, |
842 | bool enable, bool is_stalling, u32 unit); | 841 | bool enable, bool is_stalling, u32 unit); |
843 | void (*isr_stall)(struct gk20a *g); | 842 | void (*isr_stall)(struct gk20a *g); |
844 | irqreturn_t (*isr_nonstall)(struct gk20a *g); | ||
845 | void (*isr_thread_nonstall)(struct gk20a *g, u32 intr); | ||
846 | void (*isr_nonstall_cb)(struct work_struct *work); | ||
847 | bool (*is_intr_hub_pending)(struct gk20a *g, u32 mc_intr); | 843 | bool (*is_intr_hub_pending)(struct gk20a *g, u32 mc_intr); |
848 | u32 intr_mask_restore[4]; | 844 | u32 intr_mask_restore[4]; |
849 | u32 (*intr_stall)(struct gk20a *g); | 845 | u32 (*intr_stall)(struct gk20a *g); |
850 | void (*intr_stall_pause)(struct gk20a *g); | 846 | void (*intr_stall_pause)(struct gk20a *g); |
851 | void (*intr_stall_resume)(struct gk20a *g); | 847 | void (*intr_stall_resume)(struct gk20a *g); |
848 | u32 (*intr_nonstall)(struct gk20a *g); | ||
849 | void (*intr_nonstall_pause)(struct gk20a *g); | ||
850 | void (*intr_nonstall_resume)(struct gk20a *g); | ||
852 | void (*enable)(struct gk20a *g, u32 units); | 851 | void (*enable)(struct gk20a *g, u32 units); |
853 | void (*disable)(struct gk20a *g, u32 units); | 852 | void (*disable)(struct gk20a *g, u32 units); |
854 | void (*reset)(struct gk20a *g, u32 units); | 853 | 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 2cdcaaeb..111872a2 100644 --- a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c | |||
@@ -24,62 +24,6 @@ | |||
24 | 24 | ||
25 | #include <nvgpu/hw/gk20a/hw_mc_gk20a.h> | 25 | #include <nvgpu/hw/gk20a/hw_mc_gk20a.h> |
26 | 26 | ||
27 | void mc_gk20a_nonstall_cb(struct work_struct *work) | ||
28 | { | ||
29 | struct gk20a *g = container_of(work, struct gk20a, nonstall_fn_work); | ||
30 | u32 ops; | ||
31 | bool semaphore_wakeup, post_events; | ||
32 | |||
33 | do { | ||
34 | ops = atomic_xchg(&g->nonstall_ops, 0); | ||
35 | |||
36 | semaphore_wakeup = ops & gk20a_nonstall_ops_wakeup_semaphore; | ||
37 | post_events = ops & gk20a_nonstall_ops_post_events; | ||
38 | |||
39 | if (semaphore_wakeup) | ||
40 | gk20a_channel_semaphore_wakeup(g, post_events); | ||
41 | |||
42 | } while (atomic_read(&g->nonstall_ops) != 0); | ||
43 | } | ||
44 | |||
45 | irqreturn_t mc_gk20a_isr_nonstall(struct gk20a *g) | ||
46 | { | ||
47 | u32 mc_intr_1; | ||
48 | u32 hw_irq_count; | ||
49 | |||
50 | if (!g->power_on) | ||
51 | return IRQ_NONE; | ||
52 | |||
53 | /* not from gpu when sharing irq with others */ | ||
54 | mc_intr_1 = gk20a_readl(g, mc_intr_1_r()); | ||
55 | if (unlikely(!mc_intr_1)) | ||
56 | return IRQ_NONE; | ||
57 | |||
58 | gk20a_writel(g, mc_intr_en_1_r(), | ||
59 | mc_intr_en_1_inta_disabled_f()); | ||
60 | |||
61 | /* flush previous write */ | ||
62 | gk20a_readl(g, mc_intr_en_1_r()); | ||
63 | |||
64 | if (g->ops.mc.isr_thread_nonstall) | ||
65 | g->ops.mc.isr_thread_nonstall(g, mc_intr_1); | ||
66 | |||
67 | hw_irq_count = atomic_inc_return(&g->hw_irq_nonstall_count); | ||
68 | |||
69 | /* sync handled irq counter before re-enabling interrupts */ | ||
70 | atomic_set(&g->sw_irq_nonstall_last_handled, hw_irq_count); | ||
71 | |||
72 | gk20a_writel(g, mc_intr_en_1_r(), | ||
73 | mc_intr_en_1_inta_hardware_f()); | ||
74 | |||
75 | /* flush previous write */ | ||
76 | gk20a_readl(g, mc_intr_en_1_r()); | ||
77 | |||
78 | wake_up_all(&g->sw_irq_nonstall_last_handled_wq); | ||
79 | |||
80 | return IRQ_HANDLED; | ||
81 | } | ||
82 | |||
83 | void mc_gk20a_isr_stall(struct gk20a *g) | 27 | void mc_gk20a_isr_stall(struct gk20a *g) |
84 | { | 28 | { |
85 | u32 mc_intr_0; | 29 | u32 mc_intr_0; |
@@ -128,49 +72,6 @@ void mc_gk20a_isr_stall(struct gk20a *g) | |||
128 | atomic_set(&g->sw_irq_stall_last_handled, hw_irq_count); | 72 | atomic_set(&g->sw_irq_stall_last_handled, hw_irq_count); |
129 | } | 73 | } |
130 | 74 | ||
131 | void mc_gk20a_intr_thread_nonstall(struct gk20a *g, u32 mc_intr_1) | ||
132 | { | ||
133 | u32 engine_id_idx; | ||
134 | u32 active_engine_id = 0; | ||
135 | u32 engine_enum = ENGINE_INVAL_GK20A; | ||
136 | int ops_old, ops_new, ops = 0; | ||
137 | |||
138 | if (g->ops.mc.is_intr1_pending(g, NVGPU_UNIT_FIFO, mc_intr_1)) | ||
139 | ops |= gk20a_fifo_nonstall_isr(g); | ||
140 | |||
141 | for (engine_id_idx = 0; engine_id_idx < g->fifo.num_engines; | ||
142 | engine_id_idx++) { | ||
143 | active_engine_id = g->fifo.active_engines_list[engine_id_idx]; | ||
144 | |||
145 | if (mc_intr_1 & | ||
146 | g->fifo.engine_info[active_engine_id].intr_mask) { | ||
147 | engine_enum = g->fifo.engine_info[active_engine_id].engine_enum; | ||
148 | /* GR Engine */ | ||
149 | if (engine_enum == ENGINE_GR_GK20A) | ||
150 | ops |= gk20a_gr_nonstall_isr(g); | ||
151 | |||
152 | /* CE Engine */ | ||
153 | if (((engine_enum == ENGINE_GRCE_GK20A) || | ||
154 | (engine_enum == ENGINE_ASYNC_CE_GK20A)) && | ||
155 | g->ops.ce2.isr_nonstall) | ||
156 | ops |= g->ops.ce2.isr_nonstall(g, | ||
157 | g->fifo.engine_info[active_engine_id]. | ||
158 | inst_id, | ||
159 | g->fifo.engine_info[active_engine_id]. | ||
160 | pri_base); | ||
161 | } | ||
162 | } | ||
163 | if (ops) { | ||
164 | do { | ||
165 | ops_old = atomic_read(&g->nonstall_ops); | ||
166 | ops_new = ops_old | ops; | ||
167 | } while (ops_old != atomic_cmpxchg(&g->nonstall_ops, | ||
168 | ops_old, ops_new)); | ||
169 | |||
170 | queue_work(g->nonstall_work_queue, &g->nonstall_fn_work); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | void mc_gk20a_intr_enable(struct gk20a *g) | 75 | void mc_gk20a_intr_enable(struct gk20a *g) |
175 | { | 76 | { |
176 | u32 eng_intr_mask = gk20a_fifo_engine_interrupt_mask(g); | 77 | u32 eng_intr_mask = gk20a_fifo_engine_interrupt_mask(g); |
@@ -226,11 +127,34 @@ void mc_gk20a_intr_stall_resume(struct gk20a *g) | |||
226 | gk20a_readl(g, mc_intr_en_0_r()); | 127 | gk20a_readl(g, mc_intr_en_0_r()); |
227 | } | 128 | } |
228 | 129 | ||
130 | void mc_gk20a_intr_nonstall_pause(struct gk20a *g) | ||
131 | { | ||
132 | gk20a_writel(g, mc_intr_en_1_r(), | ||
133 | mc_intr_en_0_inta_disabled_f()); | ||
134 | |||
135 | /* flush previous write */ | ||
136 | gk20a_readl(g, mc_intr_en_1_r()); | ||
137 | } | ||
138 | |||
139 | void mc_gk20a_intr_nonstall_resume(struct gk20a *g) | ||
140 | { | ||
141 | gk20a_writel(g, mc_intr_en_1_r(), | ||
142 | mc_intr_en_0_inta_hardware_f()); | ||
143 | |||
144 | /* flush previous write */ | ||
145 | gk20a_readl(g, mc_intr_en_1_r()); | ||
146 | } | ||
147 | |||
229 | u32 mc_gk20a_intr_stall(struct gk20a *g) | 148 | u32 mc_gk20a_intr_stall(struct gk20a *g) |
230 | { | 149 | { |
231 | return gk20a_readl(g, mc_intr_0_r()); | 150 | return gk20a_readl(g, mc_intr_0_r()); |
232 | } | 151 | } |
233 | 152 | ||
153 | u32 mc_gk20a_intr_nonstall(struct gk20a *g) | ||
154 | { | ||
155 | return gk20a_readl(g, mc_intr_1_r()); | ||
156 | } | ||
157 | |||
234 | void gk20a_mc_disable(struct gk20a *g, u32 units) | 158 | void gk20a_mc_disable(struct gk20a *g, u32 units) |
235 | { | 159 | { |
236 | u32 pmc; | 160 | u32 pmc; |
@@ -320,9 +244,9 @@ void gk20a_init_mc(struct gpu_ops *gops) | |||
320 | gops->mc.intr_stall = mc_gk20a_intr_stall; | 244 | gops->mc.intr_stall = mc_gk20a_intr_stall; |
321 | gops->mc.intr_stall_pause = mc_gk20a_intr_stall_pause; | 245 | gops->mc.intr_stall_pause = mc_gk20a_intr_stall_pause; |
322 | gops->mc.intr_stall_resume = mc_gk20a_intr_stall_resume; | 246 | gops->mc.intr_stall_resume = mc_gk20a_intr_stall_resume; |
323 | gops->mc.isr_nonstall = mc_gk20a_isr_nonstall; | 247 | gops->mc.intr_nonstall = mc_gk20a_intr_nonstall; |
324 | gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall; | 248 | gops->mc.intr_nonstall_pause = mc_gk20a_intr_nonstall_pause; |
325 | gops->mc.isr_nonstall_cb = mc_gk20a_nonstall_cb; | 249 | gops->mc.intr_nonstall_resume = mc_gk20a_intr_nonstall_resume; |
326 | gops->mc.enable = gk20a_mc_enable; | 250 | gops->mc.enable = gk20a_mc_enable; |
327 | gops->mc.disable = gk20a_mc_disable; | 251 | gops->mc.disable = gk20a_mc_disable; |
328 | gops->mc.reset = gk20a_mc_reset; | 252 | gops->mc.reset = gk20a_mc_reset; |
diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.h b/drivers/gpu/nvgpu/gk20a/mc_gk20a.h index 6c0d159a..7ecd27bf 100644 --- a/drivers/gpu/nvgpu/gk20a/mc_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.h | |||
@@ -23,10 +23,9 @@ void mc_gk20a_isr_stall(struct gk20a *g); | |||
23 | u32 mc_gk20a_intr_stall(struct gk20a *g); | 23 | u32 mc_gk20a_intr_stall(struct gk20a *g); |
24 | void mc_gk20a_intr_stall_pause(struct gk20a *g); | 24 | void mc_gk20a_intr_stall_pause(struct gk20a *g); |
25 | void mc_gk20a_intr_stall_resume(struct gk20a *g); | 25 | void mc_gk20a_intr_stall_resume(struct gk20a *g); |
26 | irqreturn_t mc_gk20a_isr_nonstall(struct gk20a *g); | 26 | u32 mc_gk20a_intr_nonstall(struct gk20a *g); |
27 | irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g); | 27 | void mc_gk20a_intr_nonstall_pause(struct gk20a *g); |
28 | void mc_gk20a_intr_thread_nonstall(struct gk20a *g, u32 intr); | 28 | void mc_gk20a_intr_nonstall_resume(struct gk20a *g); |
29 | void mc_gk20a_nonstall_cb(struct work_struct *work); | ||
30 | void gk20a_mc_enable(struct gk20a *g, u32 units); | 29 | void gk20a_mc_enable(struct gk20a *g, u32 units); |
31 | void gk20a_mc_disable(struct gk20a *g, u32 units); | 30 | void gk20a_mc_disable(struct gk20a *g, u32 units); |
32 | void gk20a_mc_reset(struct gk20a *g, u32 units); | 31 | void gk20a_mc_reset(struct gk20a *g, u32 units); |
diff --git a/drivers/gpu/nvgpu/gm20b/mc_gm20b.c b/drivers/gpu/nvgpu/gm20b/mc_gm20b.c index 7330a027..005ec729 100644 --- a/drivers/gpu/nvgpu/gm20b/mc_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/mc_gm20b.c | |||
@@ -25,9 +25,9 @@ void gm20b_init_mc(struct gpu_ops *gops) | |||
25 | gops->mc.intr_stall = mc_gk20a_intr_stall; | 25 | gops->mc.intr_stall = mc_gk20a_intr_stall; |
26 | gops->mc.intr_stall_pause = mc_gk20a_intr_stall_pause; | 26 | gops->mc.intr_stall_pause = mc_gk20a_intr_stall_pause; |
27 | gops->mc.intr_stall_resume = mc_gk20a_intr_stall_resume; | 27 | gops->mc.intr_stall_resume = mc_gk20a_intr_stall_resume; |
28 | gops->mc.isr_nonstall = mc_gk20a_isr_nonstall; | 28 | gops->mc.intr_nonstall = mc_gk20a_intr_nonstall; |
29 | gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall; | 29 | gops->mc.intr_nonstall_pause = mc_gk20a_intr_nonstall_pause; |
30 | gops->mc.isr_nonstall_cb = mc_gk20a_nonstall_cb; | 30 | gops->mc.intr_nonstall_resume = mc_gk20a_intr_nonstall_resume; |
31 | gops->mc.enable = gk20a_mc_enable; | 31 | gops->mc.enable = gk20a_mc_enable; |
32 | gops->mc.disable = gk20a_mc_disable; | 32 | gops->mc.disable = gk20a_mc_disable; |
33 | gops->mc.reset = gk20a_mc_reset; | 33 | gops->mc.reset = gk20a_mc_reset; |
diff --git a/drivers/gpu/nvgpu/gp10b/mc_gp10b.c b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c index 7ccea370..39ad8f9b 100644 --- a/drivers/gpu/nvgpu/gp10b/mc_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c | |||
@@ -68,37 +68,6 @@ void mc_gp10b_intr_unit_config(struct gk20a *g, bool enable, | |||
68 | gk20a_writel(g, reg, mask); | 68 | gk20a_writel(g, reg, mask); |
69 | } | 69 | } |
70 | 70 | ||
71 | irqreturn_t mc_gp10b_isr_nonstall(struct gk20a *g) | ||
72 | { | ||
73 | u32 mc_intr_1; | ||
74 | u32 hw_irq_count; | ||
75 | |||
76 | if (!g->power_on) | ||
77 | return IRQ_NONE; | ||
78 | |||
79 | /* not from gpu when sharing irq with others */ | ||
80 | mc_intr_1 = gk20a_readl(g, mc_intr_r(1)); | ||
81 | if (unlikely(!mc_intr_1)) | ||
82 | return IRQ_NONE; | ||
83 | |||
84 | gk20a_writel(g, mc_intr_en_clear_r(1), 0xffffffff); | ||
85 | |||
86 | if (g->ops.mc.isr_thread_nonstall) | ||
87 | g->ops.mc.isr_thread_nonstall(g, mc_intr_1); | ||
88 | |||
89 | hw_irq_count = atomic_inc_return(&g->hw_irq_nonstall_count); | ||
90 | |||
91 | gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_NONSTALLING), | ||
92 | g->ops.mc.intr_mask_restore[NVGPU_MC_INTR_NONSTALLING]); | ||
93 | |||
94 | /* sync handled irq counter before re-enabling interrupts */ | ||
95 | atomic_set(&g->sw_irq_nonstall_last_handled, hw_irq_count); | ||
96 | |||
97 | wake_up_all(&g->sw_irq_nonstall_last_handled_wq); | ||
98 | |||
99 | return IRQ_HANDLED; | ||
100 | } | ||
101 | |||
102 | void mc_gp10b_isr_stall(struct gk20a *g) | 71 | void mc_gp10b_isr_stall(struct gk20a *g) |
103 | { | 72 | { |
104 | u32 mc_intr_0; | 73 | u32 mc_intr_0; |
@@ -170,6 +139,23 @@ void mc_gp10b_intr_stall_resume(struct gk20a *g) | |||
170 | g->ops.mc.intr_mask_restore[NVGPU_MC_INTR_STALLING]); | 139 | g->ops.mc.intr_mask_restore[NVGPU_MC_INTR_STALLING]); |
171 | } | 140 | } |
172 | 141 | ||
142 | u32 mc_gp10b_intr_nonstall(struct gk20a *g) | ||
143 | { | ||
144 | return gk20a_readl(g, mc_intr_r(NVGPU_MC_INTR_NONSTALLING)); | ||
145 | } | ||
146 | |||
147 | void mc_gp10b_intr_nonstall_pause(struct gk20a *g) | ||
148 | { | ||
149 | gk20a_writel(g, mc_intr_en_clear_r(NVGPU_MC_INTR_NONSTALLING), | ||
150 | 0xffffffff); | ||
151 | } | ||
152 | |||
153 | void mc_gp10b_intr_nonstall_resume(struct gk20a *g) | ||
154 | { | ||
155 | gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_NONSTALLING), | ||
156 | g->ops.mc.intr_mask_restore[NVGPU_MC_INTR_NONSTALLING]); | ||
157 | } | ||
158 | |||
173 | static bool mc_gp10b_is_intr1_pending(struct gk20a *g, | 159 | static bool mc_gp10b_is_intr1_pending(struct gk20a *g, |
174 | enum nvgpu_unit unit, u32 mc_intr_1) | 160 | enum nvgpu_unit unit, u32 mc_intr_1) |
175 | { | 161 | { |
@@ -202,9 +188,9 @@ void gp10b_init_mc(struct gpu_ops *gops) | |||
202 | gops->mc.intr_stall = mc_gp10b_intr_stall; | 188 | gops->mc.intr_stall = mc_gp10b_intr_stall; |
203 | gops->mc.intr_stall_pause = mc_gp10b_intr_stall_pause; | 189 | gops->mc.intr_stall_pause = mc_gp10b_intr_stall_pause; |
204 | gops->mc.intr_stall_resume = mc_gp10b_intr_stall_resume; | 190 | gops->mc.intr_stall_resume = mc_gp10b_intr_stall_resume; |
205 | gops->mc.isr_nonstall = mc_gp10b_isr_nonstall; | 191 | gops->mc.intr_nonstall = mc_gp10b_intr_nonstall; |
206 | gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall; | 192 | gops->mc.intr_nonstall_pause = mc_gp10b_intr_nonstall_pause; |
207 | gops->mc.isr_nonstall_cb = mc_gk20a_nonstall_cb; | 193 | gops->mc.intr_nonstall_resume = mc_gp10b_intr_nonstall_resume; |
208 | gops->mc.enable = gk20a_mc_enable; | 194 | gops->mc.enable = gk20a_mc_enable; |
209 | gops->mc.disable = gk20a_mc_disable; | 195 | gops->mc.disable = gk20a_mc_disable; |
210 | gops->mc.reset = gk20a_mc_reset; | 196 | gops->mc.reset = gk20a_mc_reset; |
diff --git a/drivers/gpu/nvgpu/gp10b/mc_gp10b.h b/drivers/gpu/nvgpu/gp10b/mc_gp10b.h index 31867a88..ceba0b39 100644 --- a/drivers/gpu/nvgpu/gp10b/mc_gp10b.h +++ b/drivers/gpu/nvgpu/gp10b/mc_gp10b.h | |||
@@ -25,6 +25,4 @@ 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 | void 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); | ||
29 | irqreturn_t mc_gp10b_intr_thread_nonstall(struct gk20a *g); | ||
30 | #endif | 28 | #endif |