diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/pci.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/pci.c | 861 |
1 files changed, 0 insertions, 861 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/pci.c b/drivers/gpu/nvgpu/common/linux/pci.c deleted file mode 100644 index 1011b441..00000000 --- a/drivers/gpu/nvgpu/common/linux/pci.c +++ /dev/null | |||
@@ -1,861 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016-2018, 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 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/pci.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/pm_runtime.h> | ||
20 | #include <linux/of_platform.h> | ||
21 | #include <linux/of_address.h> | ||
22 | |||
23 | #include <nvgpu/nvhost.h> | ||
24 | #include <nvgpu/nvgpu_common.h> | ||
25 | #include <nvgpu/kmem.h> | ||
26 | #include <nvgpu/enabled.h> | ||
27 | #include <nvgpu/nvlink.h> | ||
28 | #include <nvgpu/soc.h> | ||
29 | |||
30 | #include "gk20a/gk20a.h" | ||
31 | #include "clk/clk.h" | ||
32 | #include "clk/clk_mclk.h" | ||
33 | #include "module.h" | ||
34 | #include "intr.h" | ||
35 | #include "sysfs.h" | ||
36 | #include "os_linux.h" | ||
37 | #include "platform_gk20a.h" | ||
38 | #include <nvgpu/sim.h> | ||
39 | |||
40 | #include "pci.h" | ||
41 | #include "pci_usermode.h" | ||
42 | |||
43 | #include "os_linux.h" | ||
44 | #include "driver_common.h" | ||
45 | |||
46 | #define PCI_INTERFACE_NAME "card-%s%%s" | ||
47 | |||
48 | static int nvgpu_pci_tegra_probe(struct device *dev) | ||
49 | { | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static int nvgpu_pci_tegra_remove(struct device *dev) | ||
54 | { | ||
55 | struct gk20a *g = get_gk20a(dev); | ||
56 | |||
57 | if (g->ops.gr.remove_gr_sysfs) | ||
58 | g->ops.gr.remove_gr_sysfs(g); | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static bool nvgpu_pci_tegra_is_railgated(struct device *pdev) | ||
64 | { | ||
65 | return false; | ||
66 | } | ||
67 | |||
68 | static long nvgpu_pci_clk_round_rate(struct device *dev, unsigned long rate) | ||
69 | { | ||
70 | long ret = (long)rate; | ||
71 | |||
72 | if (rate == UINT_MAX) | ||
73 | ret = BOOT_GPC2CLK_MHZ * 1000000UL; | ||
74 | |||
75 | return ret; | ||
76 | } | ||
77 | |||
78 | static struct gk20a_platform nvgpu_pci_device[] = { | ||
79 | { /* DEVICE=0x1c35 */ | ||
80 | /* ptimer src frequency in hz */ | ||
81 | .ptimer_src_freq = 31250000, | ||
82 | |||
83 | .probe = nvgpu_pci_tegra_probe, | ||
84 | .remove = nvgpu_pci_tegra_remove, | ||
85 | |||
86 | /* power management configuration */ | ||
87 | .railgate_delay_init = 500, | ||
88 | .can_railgate_init = false, | ||
89 | .can_elpg_init = true, | ||
90 | .enable_elpg = true, | ||
91 | .enable_elcg = false, | ||
92 | .enable_slcg = true, | ||
93 | .enable_blcg = true, | ||
94 | .enable_mscg = true, | ||
95 | .can_slcg = true, | ||
96 | .can_blcg = true, | ||
97 | .can_elcg = true, | ||
98 | |||
99 | .disable_aspm = true, | ||
100 | |||
101 | /* power management callbacks */ | ||
102 | .is_railgated = nvgpu_pci_tegra_is_railgated, | ||
103 | .clk_round_rate = nvgpu_pci_clk_round_rate, | ||
104 | |||
105 | .ch_wdt_timeout_ms = 7000, | ||
106 | |||
107 | .honors_aperture = true, | ||
108 | .dma_mask = DMA_BIT_MASK(40), | ||
109 | .vbios_min_version = 0x86063000, | ||
110 | .hardcode_sw_threshold = true, | ||
111 | .ina3221_dcb_index = 0, | ||
112 | .ina3221_i2c_address = 0x84, | ||
113 | .ina3221_i2c_port = 0x2, | ||
114 | }, | ||
115 | { /* DEVICE=0x1c36 */ | ||
116 | /* ptimer src frequency in hz */ | ||
117 | .ptimer_src_freq = 31250000, | ||
118 | |||
119 | .probe = nvgpu_pci_tegra_probe, | ||
120 | .remove = nvgpu_pci_tegra_remove, | ||
121 | |||
122 | /* power management configuration */ | ||
123 | .railgate_delay_init = 500, | ||
124 | .can_railgate_init = false, | ||
125 | .can_elpg_init = true, | ||
126 | .enable_elpg = true, | ||
127 | .enable_elcg = false, | ||
128 | .enable_slcg = true, | ||
129 | .enable_blcg = true, | ||
130 | .enable_mscg = true, | ||
131 | .can_slcg = true, | ||
132 | .can_blcg = true, | ||
133 | .can_elcg = true, | ||
134 | |||
135 | .disable_aspm = true, | ||
136 | |||
137 | /* power management callbacks */ | ||
138 | .is_railgated = nvgpu_pci_tegra_is_railgated, | ||
139 | .clk_round_rate = nvgpu_pci_clk_round_rate, | ||
140 | |||
141 | .ch_wdt_timeout_ms = 7000, | ||
142 | |||
143 | .honors_aperture = true, | ||
144 | .dma_mask = DMA_BIT_MASK(40), | ||
145 | .vbios_min_version = 0x86062d00, | ||
146 | .hardcode_sw_threshold = true, | ||
147 | .ina3221_dcb_index = 0, | ||
148 | .ina3221_i2c_address = 0x84, | ||
149 | .ina3221_i2c_port = 0x2, | ||
150 | }, | ||
151 | { /* DEVICE=0x1c37 */ | ||
152 | /* ptimer src frequency in hz */ | ||
153 | .ptimer_src_freq = 31250000, | ||
154 | |||
155 | .probe = nvgpu_pci_tegra_probe, | ||
156 | .remove = nvgpu_pci_tegra_remove, | ||
157 | |||
158 | /* power management configuration */ | ||
159 | .railgate_delay_init = 500, | ||
160 | .can_railgate_init = false, | ||
161 | .can_elpg_init = true, | ||
162 | .enable_elpg = true, | ||
163 | .enable_elcg = false, | ||
164 | .enable_slcg = true, | ||
165 | .enable_blcg = true, | ||
166 | .enable_mscg = true, | ||
167 | .can_slcg = true, | ||
168 | .can_blcg = true, | ||
169 | .can_elcg = true, | ||
170 | |||
171 | .disable_aspm = true, | ||
172 | |||
173 | /* power management callbacks */ | ||
174 | .is_railgated = nvgpu_pci_tegra_is_railgated, | ||
175 | .clk_round_rate = nvgpu_pci_clk_round_rate, | ||
176 | |||
177 | .ch_wdt_timeout_ms = 7000, | ||
178 | |||
179 | .honors_aperture = true, | ||
180 | .dma_mask = DMA_BIT_MASK(40), | ||
181 | .vbios_min_version = 0x86063000, | ||
182 | .hardcode_sw_threshold = true, | ||
183 | .ina3221_dcb_index = 0, | ||
184 | .ina3221_i2c_address = 0x84, | ||
185 | .ina3221_i2c_port = 0x2, | ||
186 | }, | ||
187 | { /* DEVICE=0x1c75 */ | ||
188 | /* ptimer src frequency in hz */ | ||
189 | .ptimer_src_freq = 31250000, | ||
190 | |||
191 | .probe = nvgpu_pci_tegra_probe, | ||
192 | .remove = nvgpu_pci_tegra_remove, | ||
193 | |||
194 | /* power management configuration */ | ||
195 | .railgate_delay_init = 500, | ||
196 | .can_railgate_init = false, | ||
197 | .can_elpg_init = true, | ||
198 | .enable_elpg = true, | ||
199 | .enable_elcg = false, | ||
200 | .enable_slcg = true, | ||
201 | .enable_blcg = true, | ||
202 | .enable_mscg = true, | ||
203 | .can_slcg = true, | ||
204 | .can_blcg = true, | ||
205 | .can_elcg = true, | ||
206 | |||
207 | .disable_aspm = true, | ||
208 | |||
209 | /* power management callbacks */ | ||
210 | .is_railgated = nvgpu_pci_tegra_is_railgated, | ||
211 | .clk_round_rate = nvgpu_pci_clk_round_rate, | ||
212 | |||
213 | .ch_wdt_timeout_ms = 7000, | ||
214 | |||
215 | .honors_aperture = true, | ||
216 | .dma_mask = DMA_BIT_MASK(40), | ||
217 | .vbios_min_version = 0x86065300, | ||
218 | .hardcode_sw_threshold = false, | ||
219 | .ina3221_dcb_index = 1, | ||
220 | .ina3221_i2c_address = 0x80, | ||
221 | .ina3221_i2c_port = 0x1, | ||
222 | }, | ||
223 | { /* DEVICE=PG503 SKU 201 */ | ||
224 | /* ptimer src frequency in hz */ | ||
225 | .ptimer_src_freq = 31250000, | ||
226 | |||
227 | .probe = nvgpu_pci_tegra_probe, | ||
228 | .remove = nvgpu_pci_tegra_remove, | ||
229 | |||
230 | /* power management configuration */ | ||
231 | .railgate_delay_init = 500, | ||
232 | .can_railgate_init = false, | ||
233 | .can_elpg_init = false, | ||
234 | .enable_elpg = false, | ||
235 | .enable_elcg = false, | ||
236 | .enable_slcg = false, | ||
237 | .enable_blcg = false, | ||
238 | .enable_mscg = false, | ||
239 | .can_slcg = false, | ||
240 | .can_blcg = false, | ||
241 | .can_elcg = false, | ||
242 | |||
243 | .disable_aspm = true, | ||
244 | |||
245 | /* power management callbacks */ | ||
246 | .is_railgated = nvgpu_pci_tegra_is_railgated, | ||
247 | .clk_round_rate = nvgpu_pci_clk_round_rate, | ||
248 | |||
249 | .ch_wdt_timeout_ms = 7000, | ||
250 | |||
251 | .honors_aperture = true, | ||
252 | .dma_mask = DMA_BIT_MASK(40), | ||
253 | .vbios_min_version = 0x88001e00, | ||
254 | .hardcode_sw_threshold = false, | ||
255 | .run_preos = true, | ||
256 | }, | ||
257 | { /* DEVICE=PG503 SKU 200 ES */ | ||
258 | /* ptimer src frequency in hz */ | ||
259 | .ptimer_src_freq = 31250000, | ||
260 | |||
261 | .probe = nvgpu_pci_tegra_probe, | ||
262 | .remove = nvgpu_pci_tegra_remove, | ||
263 | |||
264 | /* power management configuration */ | ||
265 | .railgate_delay_init = 500, | ||
266 | .can_railgate_init = false, | ||
267 | .can_elpg_init = false, | ||
268 | .enable_elpg = false, | ||
269 | .enable_elcg = false, | ||
270 | .enable_slcg = false, | ||
271 | .enable_blcg = false, | ||
272 | .enable_mscg = false, | ||
273 | .can_slcg = false, | ||
274 | .can_blcg = false, | ||
275 | .can_elcg = false, | ||
276 | |||
277 | .disable_aspm = true, | ||
278 | |||
279 | /* power management callbacks */ | ||
280 | .is_railgated = nvgpu_pci_tegra_is_railgated, | ||
281 | .clk_round_rate = nvgpu_pci_clk_round_rate, | ||
282 | |||
283 | .ch_wdt_timeout_ms = 7000, | ||
284 | |||
285 | .honors_aperture = true, | ||
286 | .dma_mask = DMA_BIT_MASK(40), | ||
287 | .vbios_min_version = 0x88001e00, | ||
288 | .hardcode_sw_threshold = false, | ||
289 | .run_preos = true, | ||
290 | }, | ||
291 | { | ||
292 | /* ptimer src frequency in hz */ | ||
293 | .ptimer_src_freq = 31250000, | ||
294 | |||
295 | .probe = nvgpu_pci_tegra_probe, | ||
296 | .remove = nvgpu_pci_tegra_remove, | ||
297 | |||
298 | /* power management configuration */ | ||
299 | .railgate_delay_init = 500, | ||
300 | .can_railgate_init = false, | ||
301 | .can_elpg_init = false, | ||
302 | .enable_elpg = false, | ||
303 | .enable_elcg = false, | ||
304 | .enable_slcg = false, | ||
305 | .enable_blcg = false, | ||
306 | .enable_mscg = false, | ||
307 | .can_slcg = false, | ||
308 | .can_blcg = false, | ||
309 | .can_elcg = false, | ||
310 | |||
311 | .disable_aspm = true, | ||
312 | |||
313 | /* power management callbacks */ | ||
314 | .is_railgated = nvgpu_pci_tegra_is_railgated, | ||
315 | .clk_round_rate = nvgpu_pci_clk_round_rate, | ||
316 | |||
317 | .ch_wdt_timeout_ms = 7000, | ||
318 | |||
319 | .honors_aperture = true, | ||
320 | .dma_mask = DMA_BIT_MASK(40), | ||
321 | .vbios_min_version = 0x88000126, | ||
322 | .hardcode_sw_threshold = false, | ||
323 | .run_preos = true, | ||
324 | .has_syncpoints = true, | ||
325 | }, | ||
326 | { /* SKU250 */ | ||
327 | /* ptimer src frequency in hz */ | ||
328 | .ptimer_src_freq = 31250000, | ||
329 | |||
330 | .probe = nvgpu_pci_tegra_probe, | ||
331 | .remove = nvgpu_pci_tegra_remove, | ||
332 | |||
333 | /* power management configuration */ | ||
334 | .railgate_delay_init = 500, | ||
335 | .can_railgate_init = false, | ||
336 | .can_elpg_init = false, | ||
337 | .enable_elpg = false, | ||
338 | .enable_elcg = true, | ||
339 | .enable_slcg = true, | ||
340 | .enable_blcg = true, | ||
341 | .enable_mscg = false, | ||
342 | .can_slcg = true, | ||
343 | .can_blcg = true, | ||
344 | .can_elcg = true, | ||
345 | |||
346 | .disable_aspm = true, | ||
347 | |||
348 | /* power management callbacks */ | ||
349 | .is_railgated = nvgpu_pci_tegra_is_railgated, | ||
350 | .clk_round_rate = nvgpu_pci_clk_round_rate, | ||
351 | |||
352 | .ch_wdt_timeout_ms = 7000, | ||
353 | |||
354 | .honors_aperture = true, | ||
355 | .dma_mask = DMA_BIT_MASK(40), | ||
356 | .vbios_min_version = 0x1, | ||
357 | .hardcode_sw_threshold = false, | ||
358 | .run_preos = true, | ||
359 | .has_syncpoints = true, | ||
360 | }, | ||
361 | { /* SKU 0x1e3f */ | ||
362 | /* ptimer src frequency in hz */ | ||
363 | .ptimer_src_freq = 31250000, | ||
364 | |||
365 | .probe = nvgpu_pci_tegra_probe, | ||
366 | .remove = nvgpu_pci_tegra_remove, | ||
367 | |||
368 | /* power management configuration */ | ||
369 | .railgate_delay_init = 500, | ||
370 | .can_railgate_init = false, | ||
371 | .can_elpg_init = false, | ||
372 | .enable_elpg = false, | ||
373 | .enable_elcg = false, | ||
374 | .enable_slcg = false, | ||
375 | .enable_blcg = false, | ||
376 | .enable_mscg = false, | ||
377 | .can_slcg = false, | ||
378 | .can_blcg = false, | ||
379 | .can_elcg = false, | ||
380 | |||
381 | .disable_aspm = true, | ||
382 | |||
383 | /* power management callbacks */ | ||
384 | .is_railgated = nvgpu_pci_tegra_is_railgated, | ||
385 | .clk_round_rate = nvgpu_pci_clk_round_rate, | ||
386 | |||
387 | /* | ||
388 | * WAR: PCIE X1 is very slow, set to very high value till nvlink is up | ||
389 | */ | ||
390 | .ch_wdt_timeout_ms = 30000, | ||
391 | |||
392 | .honors_aperture = true, | ||
393 | .dma_mask = DMA_BIT_MASK(40), | ||
394 | .vbios_min_version = 0x1, | ||
395 | .hardcode_sw_threshold = false, | ||
396 | .unified_memory = false, | ||
397 | }, | ||
398 | { /* 0x1eba */ | ||
399 | /* ptimer src frequency in hz */ | ||
400 | .ptimer_src_freq = 31250000, | ||
401 | |||
402 | .probe = nvgpu_pci_tegra_probe, | ||
403 | .remove = nvgpu_pci_tegra_remove, | ||
404 | |||
405 | /* power management configuration */ | ||
406 | .railgate_delay_init = 500, | ||
407 | .can_railgate_init = false, | ||
408 | .can_elpg_init = false, | ||
409 | .enable_elpg = false, | ||
410 | .enable_elcg = false, | ||
411 | .enable_slcg = false, | ||
412 | .enable_blcg = false, | ||
413 | .enable_mscg = false, | ||
414 | .can_slcg = false, | ||
415 | .can_blcg = false, | ||
416 | .can_elcg = false, | ||
417 | |||
418 | .disable_aspm = true, | ||
419 | |||
420 | /* power management callbacks */ | ||
421 | .is_railgated = nvgpu_pci_tegra_is_railgated, | ||
422 | .clk_round_rate = nvgpu_pci_clk_round_rate, | ||
423 | |||
424 | .ch_wdt_timeout_ms = 7000, | ||
425 | |||
426 | .honors_aperture = true, | ||
427 | .dma_mask = DMA_BIT_MASK(40), | ||
428 | .vbios_min_version = 0x90040109, | ||
429 | .hardcode_sw_threshold = false, | ||
430 | .has_syncpoints = true, | ||
431 | }, | ||
432 | }; | ||
433 | |||
434 | static struct pci_device_id nvgpu_pci_table[] = { | ||
435 | { | ||
436 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1c35), | ||
437 | .class = PCI_BASE_CLASS_DISPLAY << 16, | ||
438 | .class_mask = 0xff << 16, | ||
439 | .driver_data = 0, | ||
440 | }, | ||
441 | { | ||
442 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1c36), | ||
443 | .class = PCI_BASE_CLASS_DISPLAY << 16, | ||
444 | .class_mask = 0xff << 16, | ||
445 | .driver_data = 1, | ||
446 | }, | ||
447 | { | ||
448 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1c37), | ||
449 | .class = PCI_BASE_CLASS_DISPLAY << 16, | ||
450 | .class_mask = 0xff << 16, | ||
451 | .driver_data = 2, | ||
452 | }, | ||
453 | { | ||
454 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1c75), | ||
455 | .class = PCI_BASE_CLASS_DISPLAY << 16, | ||
456 | .class_mask = 0xff << 16, | ||
457 | .driver_data = 3, | ||
458 | }, | ||
459 | { | ||
460 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1db1), | ||
461 | .class = PCI_BASE_CLASS_DISPLAY << 16, | ||
462 | .class_mask = 0xff << 16, | ||
463 | .driver_data = 4, | ||
464 | }, | ||
465 | { | ||
466 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1db0), | ||
467 | .class = PCI_BASE_CLASS_DISPLAY << 16, | ||
468 | .class_mask = 0xff << 16, | ||
469 | .driver_data = 5, | ||
470 | }, | ||
471 | { | ||
472 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1dbe), | ||
473 | .class = PCI_BASE_CLASS_DISPLAY << 16, | ||
474 | .class_mask = 0xff << 16, | ||
475 | .driver_data = 6, | ||
476 | }, | ||
477 | { | ||
478 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1df1), | ||
479 | .class = PCI_BASE_CLASS_DISPLAY << 16, | ||
480 | .class_mask = 0xff << 16, | ||
481 | .driver_data = 7, | ||
482 | }, | ||
483 | { | ||
484 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1e3f), | ||
485 | .class = PCI_BASE_CLASS_DISPLAY << 16, | ||
486 | .class_mask = 0xff << 16, | ||
487 | .driver_data = 8, | ||
488 | }, | ||
489 | { | ||
490 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1eba), | ||
491 | .class = PCI_BASE_CLASS_DISPLAY << 16, | ||
492 | .class_mask = 0xff << 16, | ||
493 | .driver_data = 9, | ||
494 | }, | ||
495 | {} | ||
496 | }; | ||
497 | |||
498 | static irqreturn_t nvgpu_pci_isr(int irq, void *dev_id) | ||
499 | { | ||
500 | struct gk20a *g = dev_id; | ||
501 | irqreturn_t ret_stall; | ||
502 | irqreturn_t ret_nonstall; | ||
503 | |||
504 | ret_stall = nvgpu_intr_stall(g); | ||
505 | ret_nonstall = nvgpu_intr_nonstall(g); | ||
506 | |||
507 | #if defined(CONFIG_PCI_MSI) | ||
508 | /* Send MSI EOI */ | ||
509 | if (g->ops.xve.rearm_msi && g->msi_enabled) | ||
510 | g->ops.xve.rearm_msi(g); | ||
511 | #endif | ||
512 | |||
513 | return (ret_stall == IRQ_NONE) ? ret_nonstall : IRQ_WAKE_THREAD; | ||
514 | } | ||
515 | |||
516 | static irqreturn_t nvgpu_pci_intr_thread(int irq, void *dev_id) | ||
517 | { | ||
518 | struct gk20a *g = dev_id; | ||
519 | |||
520 | return nvgpu_intr_thread_stall(g); | ||
521 | } | ||
522 | |||
523 | static int nvgpu_pci_init_support(struct pci_dev *pdev) | ||
524 | { | ||
525 | int err = 0; | ||
526 | struct gk20a *g = get_gk20a(&pdev->dev); | ||
527 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | ||
528 | |||
529 | l->regs = ioremap(pci_resource_start(pdev, 0), | ||
530 | pci_resource_len(pdev, 0)); | ||
531 | if (IS_ERR(l->regs)) { | ||
532 | nvgpu_err(g, "failed to remap gk20a registers"); | ||
533 | err = PTR_ERR(l->regs); | ||
534 | goto fail; | ||
535 | } | ||
536 | |||
537 | l->bar1 = ioremap(pci_resource_start(pdev, 1), | ||
538 | pci_resource_len(pdev, 1)); | ||
539 | if (IS_ERR(l->bar1)) { | ||
540 | nvgpu_err(g, "failed to remap gk20a bar1"); | ||
541 | err = PTR_ERR(l->bar1); | ||
542 | goto fail; | ||
543 | } | ||
544 | |||
545 | err = nvgpu_init_sim_support_linux_pci(g); | ||
546 | if (err) | ||
547 | goto fail; | ||
548 | err = nvgpu_init_sim_support_pci(g); | ||
549 | if (err) | ||
550 | goto fail_sim; | ||
551 | |||
552 | nvgpu_pci_init_usermode_support(l); | ||
553 | |||
554 | return 0; | ||
555 | |||
556 | fail_sim: | ||
557 | nvgpu_remove_sim_support_linux_pci(g); | ||
558 | fail: | ||
559 | if (l->regs) { | ||
560 | iounmap(l->regs); | ||
561 | l->regs = NULL; | ||
562 | } | ||
563 | if (l->bar1) { | ||
564 | iounmap(l->bar1); | ||
565 | l->bar1 = NULL; | ||
566 | } | ||
567 | |||
568 | return err; | ||
569 | } | ||
570 | |||
571 | static char *nvgpu_pci_devnode(struct device *dev, umode_t *mode) | ||
572 | { | ||
573 | if (mode) | ||
574 | *mode = S_IRUGO | S_IWUGO; | ||
575 | return kasprintf(GFP_KERNEL, "nvgpu-pci/%s", dev_name(dev)); | ||
576 | } | ||
577 | |||
578 | static struct class nvgpu_pci_class = { | ||
579 | .owner = THIS_MODULE, | ||
580 | .name = "nvidia-pci-gpu", | ||
581 | .devnode = nvgpu_pci_devnode, | ||
582 | }; | ||
583 | |||
584 | #ifdef CONFIG_PM | ||
585 | static int nvgpu_pci_pm_runtime_resume(struct device *dev) | ||
586 | { | ||
587 | return gk20a_pm_finalize_poweron(dev); | ||
588 | } | ||
589 | |||
590 | static int nvgpu_pci_pm_runtime_suspend(struct device *dev) | ||
591 | { | ||
592 | return 0; | ||
593 | } | ||
594 | |||
595 | static const struct dev_pm_ops nvgpu_pci_pm_ops = { | ||
596 | .runtime_resume = nvgpu_pci_pm_runtime_resume, | ||
597 | .runtime_suspend = nvgpu_pci_pm_runtime_suspend, | ||
598 | .resume = nvgpu_pci_pm_runtime_resume, | ||
599 | .suspend = nvgpu_pci_pm_runtime_suspend, | ||
600 | }; | ||
601 | #endif | ||
602 | |||
603 | static int nvgpu_pci_pm_init(struct device *dev) | ||
604 | { | ||
605 | #ifdef CONFIG_PM | ||
606 | struct gk20a *g = get_gk20a(dev); | ||
607 | |||
608 | if (!g->can_railgate) { | ||
609 | pm_runtime_disable(dev); | ||
610 | } else { | ||
611 | if (g->railgate_delay) | ||
612 | pm_runtime_set_autosuspend_delay(dev, | ||
613 | g->railgate_delay); | ||
614 | |||
615 | /* | ||
616 | * Runtime PM for PCI devices is disabled by default, | ||
617 | * so we need to enable it first | ||
618 | */ | ||
619 | pm_runtime_use_autosuspend(dev); | ||
620 | pm_runtime_put_noidle(dev); | ||
621 | pm_runtime_allow(dev); | ||
622 | } | ||
623 | #endif | ||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | static int nvgpu_pci_probe(struct pci_dev *pdev, | ||
628 | const struct pci_device_id *pent) | ||
629 | { | ||
630 | struct gk20a_platform *platform = NULL; | ||
631 | struct nvgpu_os_linux *l; | ||
632 | struct gk20a *g; | ||
633 | int err; | ||
634 | char nodefmt[64]; | ||
635 | struct device_node *np; | ||
636 | |||
637 | /* make sure driver_data is a sane index */ | ||
638 | if (pent->driver_data >= sizeof(nvgpu_pci_device) / | ||
639 | sizeof(nvgpu_pci_device[0])) { | ||
640 | return -EINVAL; | ||
641 | } | ||
642 | |||
643 | l = kzalloc(sizeof(*l), GFP_KERNEL); | ||
644 | if (!l) { | ||
645 | dev_err(&pdev->dev, "couldn't allocate gk20a support"); | ||
646 | return -ENOMEM; | ||
647 | } | ||
648 | |||
649 | hash_init(l->ecc_sysfs_stats_htable); | ||
650 | |||
651 | g = &l->g; | ||
652 | nvgpu_init_gk20a(g); | ||
653 | |||
654 | nvgpu_kmem_init(g); | ||
655 | |||
656 | /* Allocate memory to hold platform data*/ | ||
657 | platform = (struct gk20a_platform *)nvgpu_kzalloc( g, | ||
658 | sizeof(struct gk20a_platform)); | ||
659 | if (!platform) { | ||
660 | dev_err(&pdev->dev, "couldn't allocate platform data"); | ||
661 | err = -ENOMEM; | ||
662 | goto err_free_l; | ||
663 | } | ||
664 | |||
665 | /* copy detected device data to allocated platform space*/ | ||
666 | memcpy((void *)platform, (void *)&nvgpu_pci_device[pent->driver_data], | ||
667 | sizeof(struct gk20a_platform)); | ||
668 | |||
669 | pci_set_drvdata(pdev, platform); | ||
670 | |||
671 | err = nvgpu_init_enabled_flags(g); | ||
672 | if (err) | ||
673 | goto err_free_platform; | ||
674 | |||
675 | platform->g = g; | ||
676 | l->dev = &pdev->dev; | ||
677 | |||
678 | np = nvgpu_get_node(g); | ||
679 | if (of_dma_is_coherent(np)) { | ||
680 | __nvgpu_set_enabled(g, NVGPU_USE_COHERENT_SYSMEM, true); | ||
681 | __nvgpu_set_enabled(g, NVGPU_SUPPORT_IO_COHERENCE, true); | ||
682 | } | ||
683 | |||
684 | err = pci_enable_device(pdev); | ||
685 | if (err) | ||
686 | goto err_free_platform; | ||
687 | pci_set_master(pdev); | ||
688 | |||
689 | g->pci_vendor_id = pdev->vendor; | ||
690 | g->pci_device_id = pdev->device; | ||
691 | g->pci_subsystem_vendor_id = pdev->subsystem_vendor; | ||
692 | g->pci_subsystem_device_id = pdev->subsystem_device; | ||
693 | g->pci_class = (pdev->class >> 8) & 0xFFFFU; // we only want base/sub | ||
694 | g->pci_revision = pdev->revision; | ||
695 | |||
696 | g->ina3221_dcb_index = platform->ina3221_dcb_index; | ||
697 | g->ina3221_i2c_address = platform->ina3221_i2c_address; | ||
698 | g->ina3221_i2c_port = platform->ina3221_i2c_port; | ||
699 | g->hardcode_sw_threshold = platform->hardcode_sw_threshold; | ||
700 | |||
701 | #if defined(CONFIG_PCI_MSI) | ||
702 | err = pci_enable_msi(pdev); | ||
703 | if (err) { | ||
704 | nvgpu_err(g, | ||
705 | "MSI could not be enabled, falling back to legacy"); | ||
706 | g->msi_enabled = false; | ||
707 | } else | ||
708 | g->msi_enabled = true; | ||
709 | #endif | ||
710 | |||
711 | g->irq_stall = pdev->irq; | ||
712 | g->irq_nonstall = pdev->irq; | ||
713 | if (g->irq_stall < 0) { | ||
714 | err = -ENXIO; | ||
715 | goto err_disable_msi; | ||
716 | } | ||
717 | |||
718 | err = devm_request_threaded_irq(&pdev->dev, | ||
719 | g->irq_stall, | ||
720 | nvgpu_pci_isr, | ||
721 | nvgpu_pci_intr_thread, | ||
722 | #if defined(CONFIG_PCI_MSI) | ||
723 | g->msi_enabled ? 0 : | ||
724 | #endif | ||
725 | IRQF_SHARED, "nvgpu", g); | ||
726 | if (err) { | ||
727 | nvgpu_err(g, | ||
728 | "failed to request irq @ %d", g->irq_stall); | ||
729 | goto err_disable_msi; | ||
730 | } | ||
731 | disable_irq(g->irq_stall); | ||
732 | |||
733 | err = nvgpu_pci_init_support(pdev); | ||
734 | if (err) | ||
735 | goto err_free_irq; | ||
736 | |||
737 | if (strchr(dev_name(&pdev->dev), '%')) { | ||
738 | nvgpu_err(g, "illegal character in device name"); | ||
739 | err = -EINVAL; | ||
740 | goto err_free_irq; | ||
741 | } | ||
742 | |||
743 | snprintf(nodefmt, sizeof(nodefmt), | ||
744 | PCI_INTERFACE_NAME, dev_name(&pdev->dev)); | ||
745 | |||
746 | err = nvgpu_probe(g, "gpu_pci", nodefmt, &nvgpu_pci_class); | ||
747 | if (err) | ||
748 | goto err_free_irq; | ||
749 | |||
750 | err = nvgpu_pci_pm_init(&pdev->dev); | ||
751 | if (err) { | ||
752 | nvgpu_err(g, "pm init failed"); | ||
753 | goto err_free_irq; | ||
754 | } | ||
755 | |||
756 | err = nvgpu_nvlink_probe(g); | ||
757 | /* | ||
758 | * ENODEV is a legal error which means there is no NVLINK | ||
759 | * any other error is fatal | ||
760 | */ | ||
761 | if (err) { | ||
762 | if (err != -ENODEV) { | ||
763 | nvgpu_err(g, "fatal error probing nvlink, bailing out"); | ||
764 | goto err_free_irq; | ||
765 | } | ||
766 | /* Enable Semaphore SHIM on nvlink only for now. */ | ||
767 | __nvgpu_set_enabled(g, NVGPU_SUPPORT_NVLINK, false); | ||
768 | g->has_syncpoints = false; | ||
769 | } else { | ||
770 | err = nvgpu_nvhost_syncpt_init(g); | ||
771 | if (err) { | ||
772 | if (err != -ENOSYS) { | ||
773 | nvgpu_err(g, "syncpt init failed"); | ||
774 | goto err_free_irq; | ||
775 | } | ||
776 | } | ||
777 | } | ||
778 | |||
779 | g->mm.has_physical_mode = false; | ||
780 | |||
781 | return 0; | ||
782 | |||
783 | err_free_irq: | ||
784 | nvgpu_free_irq(g); | ||
785 | err_disable_msi: | ||
786 | #if defined(CONFIG_PCI_MSI) | ||
787 | if (g->msi_enabled) | ||
788 | pci_disable_msi(pdev); | ||
789 | #endif | ||
790 | err_free_platform: | ||
791 | nvgpu_kfree(g, platform); | ||
792 | err_free_l: | ||
793 | kfree(l); | ||
794 | return err; | ||
795 | } | ||
796 | |||
797 | static void nvgpu_pci_remove(struct pci_dev *pdev) | ||
798 | { | ||
799 | struct gk20a *g = get_gk20a(&pdev->dev); | ||
800 | struct device *dev = dev_from_gk20a(g); | ||
801 | int err; | ||
802 | |||
803 | /* no support yet for unbind if DGPU is in VGPU mode */ | ||
804 | if (gk20a_gpu_is_virtual(dev)) | ||
805 | return; | ||
806 | |||
807 | nvgpu_nvlink_remove(g); | ||
808 | |||
809 | gk20a_driver_start_unload(g); | ||
810 | err = nvgpu_quiesce(g); | ||
811 | /* TODO: handle failure to idle */ | ||
812 | WARN(err, "gpu failed to idle during driver removal"); | ||
813 | |||
814 | nvgpu_free_irq(g); | ||
815 | |||
816 | nvgpu_remove(dev, &nvgpu_pci_class); | ||
817 | |||
818 | #if defined(CONFIG_PCI_MSI) | ||
819 | if (g->msi_enabled) | ||
820 | pci_disable_msi(pdev); | ||
821 | else { | ||
822 | /* IRQ does not need to be enabled in MSI as the line is not | ||
823 | * shared | ||
824 | */ | ||
825 | enable_irq(g->irq_stall); | ||
826 | } | ||
827 | #endif | ||
828 | |||
829 | /* free allocated platform data space */ | ||
830 | nvgpu_kfree(g, gk20a_get_platform(&pdev->dev)); | ||
831 | |||
832 | gk20a_get_platform(&pdev->dev)->g = NULL; | ||
833 | gk20a_put(g); | ||
834 | } | ||
835 | |||
836 | static struct pci_driver nvgpu_pci_driver = { | ||
837 | .name = "nvgpu", | ||
838 | .id_table = nvgpu_pci_table, | ||
839 | .probe = nvgpu_pci_probe, | ||
840 | .remove = nvgpu_pci_remove, | ||
841 | #ifdef CONFIG_PM | ||
842 | .driver.pm = &nvgpu_pci_pm_ops, | ||
843 | #endif | ||
844 | }; | ||
845 | |||
846 | int __init nvgpu_pci_init(void) | ||
847 | { | ||
848 | int ret; | ||
849 | |||
850 | ret = class_register(&nvgpu_pci_class); | ||
851 | if (ret) | ||
852 | return ret; | ||
853 | |||
854 | return pci_register_driver(&nvgpu_pci_driver); | ||
855 | } | ||
856 | |||
857 | void __exit nvgpu_pci_exit(void) | ||
858 | { | ||
859 | pci_unregister_driver(&nvgpu_pci_driver); | ||
860 | class_unregister(&nvgpu_pci_class); | ||
861 | } | ||