summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r--drivers/gpu/nvgpu/Makefile2
-rw-r--r--drivers/gpu/nvgpu/common/falcon/falcon.c6
-rw-r--r--drivers/gpu/nvgpu/common/linux/nvlink.c531
-rw-r--r--drivers/gpu/nvgpu/common/linux/pci.c13
-rw-r--r--drivers/gpu/nvgpu/common/vbios/bios.c53
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c12
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h28
-rw-r--r--drivers/gpu/nvgpu/gp10b/mc_gp10b.c5
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/bios.h4
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/enabled.h8
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/falcon.h3
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/log.h3
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/nvlink.h206
13 files changed, 864 insertions, 10 deletions
diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile
index d70c44e8..626fea24 100644
--- a/drivers/gpu/nvgpu/Makefile
+++ b/drivers/gpu/nvgpu/Makefile
@@ -55,6 +55,7 @@ nvgpu-y := \
55 common/linux/ce2.o \ 55 common/linux/ce2.o \
56 common/linux/sim.o \ 56 common/linux/sim.o \
57 common/linux/os_sched.o \ 57 common/linux/os_sched.o \
58 common/linux/nvlink.o \
58 common/mm/nvgpu_allocator.o \ 59 common/mm/nvgpu_allocator.o \
59 common/mm/bitmap_allocator.o \ 60 common/mm/bitmap_allocator.o \
60 common/mm/buddy_allocator.o \ 61 common/mm/buddy_allocator.o \
@@ -291,7 +292,6 @@ nvgpu-$(CONFIG_TEGRA_GR_VIRTUALIZATION) += \
291 common/linux/vgpu/gp10b/vgpu_fuse_gp10b.o \ 292 common/linux/vgpu/gp10b/vgpu_fuse_gp10b.o \
292 common/linux/vgpu/gp10b/vgpu_mm_gp10b.o 293 common/linux/vgpu/gp10b/vgpu_mm_gp10b.o
293 294
294
295nvgpu-$(CONFIG_TEGRA_GR_VIRTUALIZATION) += \ 295nvgpu-$(CONFIG_TEGRA_GR_VIRTUALIZATION) += \
296 common/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.o \ 296 common/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.o \
297 common/linux/vgpu/gv11b/vgpu_gv11b.o \ 297 common/linux/vgpu/gv11b/vgpu_gv11b.o \
diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c
index 42b33c27..41e394f9 100644
--- a/drivers/gpu/nvgpu/common/falcon/falcon.c
+++ b/drivers/gpu/nvgpu/common/falcon/falcon.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -385,6 +385,10 @@ void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id)
385 flcn = &g->nvdec_flcn; 385 flcn = &g->nvdec_flcn;
386 flcn->flcn_id = flcn_id; 386 flcn->flcn_id = flcn_id;
387 break; 387 break;
388 case FALCON_ID_MINION:
389 flcn = &g->minion_flcn;
390 flcn->flcn_id = flcn_id;
391 break;
388 default: 392 default:
389 nvgpu_err(g, "Invalid/Unsupported falcon ID %x", flcn_id); 393 nvgpu_err(g, "Invalid/Unsupported falcon ID %x", flcn_id);
390 break; 394 break;
diff --git a/drivers/gpu/nvgpu/common/linux/nvlink.c b/drivers/gpu/nvgpu/common/linux/nvlink.c
new file mode 100644
index 00000000..eea6eda7
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/linux/nvlink.c
@@ -0,0 +1,531 @@
1/*
2 * Copyright (c) 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 <gk20a/gk20a.h>
18#include <nvgpu/nvlink.h>
19#include <nvgpu/enabled.h>
20#include "module.h"
21
22#ifdef CONFIG_TEGRA_NVLINK
23#include <linux/platform/tegra/tegra-nvlink.h>
24#endif
25
26#ifdef CONFIG_TEGRA_NVLINK
27
28/*
29 * WAR: use this function to find detault link, as only one is supported
30 * on the library for now
31 * Returns NVLINK_MAX_LINKS_SW on failure
32 */
33static u32 __nvgpu_nvlink_get_link(struct nvlink_device *ndev)
34{
35 u32 link_id;
36 struct gk20a *g = (struct gk20a *) ndev->priv;
37
38 if (!g)
39 return NVLINK_MAX_LINKS_SW;
40
41 /* Lets find the detected link */
42 if (g->nvlink.initialized_links)
43 link_id = fls(g->nvlink.initialized_links);
44 else
45 return NVLINK_MAX_LINKS_SW;
46
47 if (g->nvlink.links[link_id].remote_info.is_connected)
48 return link_id;
49
50 return NVLINK_MAX_LINKS_SW;
51}
52static int nvgpu_nvlink_early_init(struct nvlink_device *ndev)
53{
54 struct gk20a *g = (struct gk20a *) ndev->priv;
55 int err;
56
57 /* For now master topology is the only one supported */
58 if (!ndev->is_master) {
59 nvgpu_log(g, gpu_dbg_info | gpu_dbg_nvlink,
60 "dGPU is not master of Nvlink link");
61 return -EINVAL;
62 }
63
64 err = g->ops.nvlink.early_init(g);
65 return err;
66}
67
68static int nvgpu_nvlink_link_early_init(struct nvlink_device *ndev)
69{
70 struct gk20a *g = (struct gk20a *) ndev->priv;
71 int err;
72 u32 link_id;
73
74 /*
75 * First check the topology and setup connectivity
76 * HACK: we are only enabling one link for now!!!
77 */
78 link_id = fls(g->nvlink.discovered_links);
79 g->nvlink.links[link_id].remote_info.is_connected = true;
80
81 err = g->ops.nvlink.link_early_init(g, BIT(link_id));
82
83 if (err == 0) {
84 g->nvlink.links[link_id].priv = (void *) &(ndev->link);
85 ndev->link.priv = (void *) g;
86 }
87 return err;
88}
89
90static int nvgpu_nvlink_interface_init(struct nvlink_device *ndev)
91{
92 int err;
93 struct gk20a *g = (struct gk20a *) ndev->priv;
94
95 err = g->ops.nvlink.interface_init(g);
96 return err;
97}
98
99static int nvgpu_nvlink_shutdown(struct nvlink_device *ndev)
100{
101 int err;
102 struct gk20a *g = (struct gk20a *) ndev->priv;
103
104 err = g->ops.nvlink.shutdown(g);
105 return 0;
106}
107
108static int nvgpu_nvlink_reg_init(struct nvlink_device *ndev)
109{
110 struct gk20a *g = (struct gk20a *) ndev->priv;
111 int err;
112
113 err = g->ops.nvlink.reg_init(g);
114
115 return err;
116}
117
118static u32 nvgpu_nvlink_get_link_mode(struct nvlink_device *ndev)
119{
120 struct gk20a *g = (struct gk20a *) ndev->priv;
121 u32 link_id;
122 u32 mode;
123
124 link_id = __nvgpu_nvlink_get_link(ndev);
125 if (link_id == NVLINK_MAX_LINKS_SW)
126 return -EINVAL;
127
128 mode = g->ops.nvlink.link_get_mode(g, link_id);
129
130 switch (mode) {
131 case nvgpu_nvlink_link_off:
132 return NVLINK_LINK_OFF;
133 case nvgpu_nvlink_link_hs:
134 return NVLINK_LINK_HS;
135 case nvgpu_nvlink_link_safe:
136 return NVLINK_LINK_SAFE;
137 case nvgpu_nvlink_link_fault:
138 return NVLINK_LINK_FAULT;
139 case nvgpu_nvlink_link_recovery:
140 return NVLINK_LINK_RECOVERY;
141 case nvgpu_nvlink_link_detect:
142 return NVLINK_LINK_DETECT;
143 case nvgpu_nvlink_link_reset:
144 return NVLINK_LINK_RESET;
145 case nvgpu_nvlink_link_enable_pm:
146 return NVLINK_LINK_ENABLE_PM;
147 case nvgpu_nvlink_link_disable_pm:
148 return NVLINK_LINK_DISABLE_PM;
149 case nvgpu_nvlink_link_disable_err_detect:
150 return NVLINK_LINK_DISABLE_ERR_DETECT;
151 case nvgpu_nvlink_link_lane_disable:
152 return NVLINK_LINK_LANE_DISABLE;
153 case nvgpu_nvlink_link_lane_shutdown:
154 return NVLINK_LINK_LANE_SHUTDOWN;
155 default:
156 nvgpu_log(g, gpu_dbg_info | gpu_dbg_nvlink,
157 "unsupported mode %u", mode);
158 }
159
160 return NVLINK_LINK_OFF;
161}
162
163static u32 nvgpu_nvlink_get_link_state(struct nvlink_device *ndev)
164{
165 struct gk20a *g = (struct gk20a *) ndev->priv;
166 u32 link_id;
167
168 link_id = __nvgpu_nvlink_get_link(ndev);
169 if (link_id == NVLINK_MAX_LINKS_SW)
170 return -EINVAL;
171
172 return g->ops.nvlink.link_get_state(g, link_id);
173}
174
175static int nvgpu_nvlink_set_link_mode(struct nvlink_device *ndev, u32 mode)
176{
177
178 struct gk20a *g = (struct gk20a *) ndev->priv;
179 u32 link_id;
180 u32 mode_sw;
181
182 link_id = __nvgpu_nvlink_get_link(ndev);
183 if (link_id == NVLINK_MAX_LINKS_SW)
184 return -EINVAL;
185
186 switch (mode) {
187 case NVLINK_LINK_OFF:
188 mode_sw = nvgpu_nvlink_link_off;
189 break;
190 case NVLINK_LINK_HS:
191 mode_sw = nvgpu_nvlink_link_hs;
192 break;
193 case NVLINK_LINK_SAFE:
194 mode_sw = nvgpu_nvlink_link_safe;
195 break;
196 case NVLINK_LINK_FAULT:
197 mode_sw = nvgpu_nvlink_link_fault;
198 break;
199 case NVLINK_LINK_RECOVERY:
200 mode_sw = nvgpu_nvlink_link_recovery;
201 break;
202 case NVLINK_LINK_DETECT:
203 mode_sw = nvgpu_nvlink_link_detect;
204 break;
205 case NVLINK_LINK_RESET:
206 mode_sw = nvgpu_nvlink_link_reset;
207 break;
208 case NVLINK_LINK_ENABLE_PM:
209 mode_sw = nvgpu_nvlink_link_enable_pm;
210 break;
211 case NVLINK_LINK_DISABLE_PM:
212 mode_sw = nvgpu_nvlink_link_disable_pm;
213 break;
214 case NVLINK_LINK_LANE_DISABLE:
215 mode_sw = nvgpu_nvlink_link_lane_disable;
216 break;
217 case NVLINK_LINK_LANE_SHUTDOWN:
218 mode_sw = nvgpu_nvlink_link_lane_shutdown;
219 break;
220 default:
221 mode_sw = nvgpu_nvlink_link_off;
222 }
223
224 return g->ops.nvlink.link_set_mode(g, link_id, mode_sw);
225}
226
227static void nvgpu_nvlink_get_tx_sublink_state(struct nvlink_device *ndev,
228 u32 *state)
229{
230 struct gk20a *g = (struct gk20a *) ndev->priv;
231 u32 link_id;
232
233 link_id = __nvgpu_nvlink_get_link(ndev);
234 if (link_id == NVLINK_MAX_LINKS_SW)
235 return;
236 if (state)
237 *state = g->ops.nvlink.get_tx_sublink_state(g, link_id);
238}
239
240static void nvgpu_nvlink_get_rx_sublink_state(struct nvlink_device *ndev,
241 u32 *state)
242{
243 struct gk20a *g = (struct gk20a *) ndev->priv;
244 u32 link_id;
245
246 link_id = __nvgpu_nvlink_get_link(ndev);
247 if (link_id == NVLINK_MAX_LINKS_SW)
248 return;
249 if (state)
250 *state = g->ops.nvlink.get_rx_sublink_state(g, link_id);
251}
252
253static u32 nvgpu_nvlink_get_sublink_mode(struct nvlink_device *ndev,
254 bool is_rx_sublink)
255{
256 struct gk20a *g = (struct gk20a *) ndev->priv;
257 u32 link_id;
258 u32 mode;
259
260 link_id = __nvgpu_nvlink_get_link(ndev);
261 if (link_id == NVLINK_MAX_LINKS_SW)
262 return -EINVAL;
263
264 mode = g->ops.nvlink.get_sublink_mode(g, link_id, is_rx_sublink);
265 switch (mode) {
266 case nvgpu_nvlink_sublink_tx_hs:
267 return NVLINK_TX_HS;
268 case nvgpu_nvlink_sublink_tx_off:
269 return NVLINK_TX_OFF;
270 case nvgpu_nvlink_sublink_tx_single_lane:
271 return NVLINK_TX_SINGLE_LANE;
272 case nvgpu_nvlink_sublink_tx_safe:
273 return NVLINK_TX_SAFE;
274 case nvgpu_nvlink_sublink_tx_enable_pm:
275 return NVLINK_TX_ENABLE_PM;
276 case nvgpu_nvlink_sublink_tx_disable_pm:
277 return NVLINK_TX_DISABLE_PM;
278 case nvgpu_nvlink_sublink_tx_common:
279 return NVLINK_TX_COMMON;
280 case nvgpu_nvlink_sublink_tx_common_disable:
281 return NVLINK_TX_COMMON_DISABLE;
282 case nvgpu_nvlink_sublink_tx_data_ready:
283 return NVLINK_TX_DATA_READY;
284 case nvgpu_nvlink_sublink_tx_prbs_en:
285 return NVLINK_TX_PRBS_EN;
286 case nvgpu_nvlink_sublink_rx_hs:
287 return NVLINK_RX_HS;
288 case nvgpu_nvlink_sublink_rx_enable_pm:
289 return NVLINK_RX_ENABLE_PM;
290 case nvgpu_nvlink_sublink_rx_disable_pm:
291 return NVLINK_RX_DISABLE_PM;
292 case nvgpu_nvlink_sublink_rx_single_lane:
293 return NVLINK_RX_SINGLE_LANE;
294 case nvgpu_nvlink_sublink_rx_safe:
295 return NVLINK_RX_SAFE;
296 case nvgpu_nvlink_sublink_rx_off:
297 return NVLINK_RX_OFF;
298 case nvgpu_nvlink_sublink_rx_rxcal:
299 return NVLINK_RX_RXCAL;
300 default:
301 nvgpu_log(g, gpu_dbg_nvlink, "Unsupported mode: %u", mode);
302 break;
303 }
304
305 if (is_rx_sublink)
306 return NVLINK_RX_OFF;
307 return NVLINK_TX_OFF;
308}
309
310static int nvgpu_nvlink_set_sublink_mode(struct nvlink_device *ndev,
311 bool is_rx_sublink, u32 mode)
312{
313 struct gk20a *g = (struct gk20a *) ndev->priv;
314 u32 link_id;
315 u32 mode_sw;
316
317 link_id = __nvgpu_nvlink_get_link(ndev);
318 if (link_id == NVLINK_MAX_LINKS_SW)
319 return -EINVAL;
320
321 if (!is_rx_sublink) {
322 switch (mode) {
323 case NVLINK_TX_HS:
324 mode_sw = nvgpu_nvlink_sublink_tx_hs;
325 break;
326 case NVLINK_TX_ENABLE_PM:
327 mode_sw = nvgpu_nvlink_sublink_tx_enable_pm;
328 break;
329 case NVLINK_TX_DISABLE_PM:
330 mode_sw = nvgpu_nvlink_sublink_tx_disable_pm;
331 break;
332 case NVLINK_TX_SINGLE_LANE:
333 mode_sw = nvgpu_nvlink_sublink_tx_single_lane;
334 break;
335 case NVLINK_TX_SAFE:
336 mode_sw = nvgpu_nvlink_sublink_tx_safe;
337 break;
338 case NVLINK_TX_OFF:
339 mode_sw = nvgpu_nvlink_sublink_tx_off;
340 break;
341 case NVLINK_TX_COMMON:
342 mode_sw = nvgpu_nvlink_sublink_tx_common;
343 break;
344 case NVLINK_TX_COMMON_DISABLE:
345 mode_sw = nvgpu_nvlink_sublink_tx_common_disable;
346 break;
347 case NVLINK_TX_DATA_READY:
348 mode_sw = nvgpu_nvlink_sublink_tx_data_ready;
349 break;
350 case NVLINK_TX_PRBS_EN:
351 mode_sw = nvgpu_nvlink_sublink_tx_prbs_en;
352 break;
353 default:
354 return -EINVAL;
355 }
356 } else {
357 switch (mode) {
358 case NVLINK_RX_HS:
359 mode_sw = nvgpu_nvlink_sublink_rx_hs;
360 break;
361 case NVLINK_RX_ENABLE_PM:
362 mode_sw = nvgpu_nvlink_sublink_rx_enable_pm;
363 break;
364 case NVLINK_RX_DISABLE_PM:
365 mode_sw = nvgpu_nvlink_sublink_rx_disable_pm;
366 break;
367 case NVLINK_RX_SINGLE_LANE:
368 mode_sw = nvgpu_nvlink_sublink_rx_single_lane;
369 break;
370 case NVLINK_RX_SAFE:
371 mode_sw = nvgpu_nvlink_sublink_rx_safe;
372 break;
373 case NVLINK_RX_OFF:
374 mode_sw = nvgpu_nvlink_sublink_rx_off;
375 break;
376 case NVLINK_RX_RXCAL:
377 mode_sw = nvgpu_nvlink_sublink_rx_rxcal;
378 break;
379 default:
380 return -EINVAL;
381 }
382 }
383
384 return g->ops.nvlink.set_sublink_mode(g, link_id, is_rx_sublink,
385 mode_sw);
386}
387#endif
388
389u32 nvgpu_nvlink_enumerate(struct gk20a *g)
390{
391 u32 err = -ENODEV;
392#ifdef CONFIG_TEGRA_NVLINK
393 struct nvlink_device *ndev;
394
395 ndev = (struct nvlink_device *) g->nvlink.priv;
396
397 if (ndev)
398 err = nvlink_enumerate(ndev);
399#endif
400 return err;
401}
402
403u32 nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off)
404{
405 u32 err = -ENODEV;
406#ifdef CONFIG_TEGRA_NVLINK
407 struct nvlink_device *ndev;
408
409 ndev = (struct nvlink_device *) g->nvlink.priv;
410
411 if (!ndev)
412 return -ENODEV;
413
414 /* Check if the link is connected */
415 if (!g->nvlink.links[link_id].remote_info.is_connected)
416 return -ENODEV;
417
418 if (from_off)
419 return nvlink_transition_intranode_conn_off_to_safe(ndev);
420 return nvlink_train_intranode_conn_safe_to_hs(ndev);
421
422#endif
423 return err;
424}
425
426u32 nvgpu_nvlink_probe(struct gk20a *g)
427{
428#ifdef CONFIG_TEGRA_NVLINK
429 u32 err = 0;
430 struct device_node *np = nvgpu_get_node(g);
431 struct device_node *nvlink_np = NULL, *endp_np = NULL;
432 struct nvlink_device *ndev;
433 u32 phys_link_id;
434
435 /* Parse DT */
436 if (np) {
437 nvlink_np = of_get_child_by_name(np, "nvidia,nvlink");
438 if (nvlink_np)
439 endp_np = of_get_child_by_name(np, "endpoint");
440 }
441
442 if (!endp_np) {
443 nvgpu_log(g, gpu_dbg_info | gpu_dbg_nvlink,
444 "No Nvlink DT detected");
445 return -ENODEV;
446 }
447
448 /* Allocating structures */
449 ndev = nvgpu_kzalloc(g, sizeof(struct nvlink_device));
450 if (!ndev) {
451 nvgpu_err(g, "OOM while allocating nvlink device struct");
452 return -ENOMEM;
453 }
454
455 ndev->priv = (void *) g;
456 g->nvlink.priv = (void *) ndev;
457
458 /* Parse DT structure to detect endpoint topology */
459 of_property_read_u32(endp_np, "local_dev_id", &ndev->device_id);
460 of_property_read_u32(endp_np, "local_link_id", &ndev->link.link_id);
461 ndev->is_master = of_property_read_bool(endp_np, "is_master");
462 of_property_read_u32(endp_np, "remote_dev_id",
463 &ndev->link.remote_dev_info.device_id);
464 of_property_read_u32(endp_np, "remote_link_id",
465 &ndev->link.remote_dev_info.link_id);
466 of_property_read_u32(endp_np, "physical_link",
467 &phys_link_id);
468
469 g->nvlink.topology_connected_links = BIT(phys_link_id);
470
471 mutex_init(&ndev->init_state_mutex);
472
473 /* Check that we are in dGPU mode */
474 if (ndev->device_id != NVLINK_ENDPT_GV100) {
475 nvgpu_err(g, "Local nvlink device is not dGPU");
476 err = -EINVAL;
477 goto free_nvlink;
478 }
479
480 err = nvlink_set_init_state(ndev, NVLINK_DEV_OFF);
481 if (err) {
482 nvgpu_err(g, "Error initalizing device state to OFF");
483 goto free_nvlink;
484 }
485
486 /* Fill in device struct */
487 ndev->dev_ops.dev_early_init = nvgpu_nvlink_early_init;
488 ndev->dev_ops.dev_interface_init = nvgpu_nvlink_interface_init;
489 ndev->dev_ops.dev_reg_init = nvgpu_nvlink_reg_init;
490 ndev->dev_ops.dev_shutdown = nvgpu_nvlink_shutdown;
491
492 /* Fill in the link struct */
493 ndev->link.device_id = ndev->device_id;
494 ndev->link.mode = NVLINK_LINK_OFF;
495 ndev->link.link_ops.get_link_mode = nvgpu_nvlink_get_link_mode;
496 ndev->link.link_ops.set_link_mode = nvgpu_nvlink_set_link_mode;
497 ndev->link.link_ops.get_sublink_mode = nvgpu_nvlink_get_sublink_mode;
498 ndev->link.link_ops.set_sublink_mode = nvgpu_nvlink_set_sublink_mode;
499 ndev->link.link_ops.get_link_state = nvgpu_nvlink_get_link_state;
500 ndev->link.link_ops.get_tx_sublink_state =
501 nvgpu_nvlink_get_tx_sublink_state;
502 ndev->link.link_ops.get_rx_sublink_state =
503 nvgpu_nvlink_get_rx_sublink_state;
504 ndev->link.link_ops.link_early_init =
505 nvgpu_nvlink_link_early_init;
506
507 /* Register device with core driver*/
508 err = nvlink_register_device(ndev);
509 if (err) {
510 nvgpu_err(g, "failed on nvlink device registration");
511 goto free_nvlink;
512 }
513
514 /* Register link with core driver */
515 err = nvlink_register_link(&ndev->link);
516 if (err) {
517 nvgpu_err(g, "failed on nvlink link registration");
518 goto free_nvlink;
519 }
520
521 /* Enable NVLINK support */
522 __nvgpu_set_enabled(g, NVGPU_SUPPORT_NVLINK, true);
523free_nvlink:
524 nvgpu_kfree(g, ndev);
525 return err;
526
527#else
528 return -ENODEV;
529#endif
530}
531
diff --git a/drivers/gpu/nvgpu/common/linux/pci.c b/drivers/gpu/nvgpu/common/linux/pci.c
index 9c18fbc9..905a3d39 100644
--- a/drivers/gpu/nvgpu/common/linux/pci.c
+++ b/drivers/gpu/nvgpu/common/linux/pci.c
@@ -21,6 +21,7 @@
21#include <nvgpu/nvgpu_common.h> 21#include <nvgpu/nvgpu_common.h>
22#include <nvgpu/kmem.h> 22#include <nvgpu/kmem.h>
23#include <nvgpu/enabled.h> 23#include <nvgpu/enabled.h>
24#include <nvgpu/nvlink.h>
24#include <linux/of_platform.h> 25#include <linux/of_platform.h>
25#include <linux/of_address.h> 26#include <linux/of_address.h>
26 27
@@ -629,6 +630,18 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
629 return err; 630 return err;
630 } 631 }
631 632
633 err = nvgpu_nvlink_probe(g);
634 /*
635 * ENODEV is a legal error which means there is no NVLINK
636 * any other error is fatal
637 */
638 if (err) {
639 if (err != -ENODEV) {
640 nvgpu_err(g, "fatal error probing nvlink, bailing out");
641 return err;
642 }
643 }
644
632 g->mm.has_physical_mode = false; 645 g->mm.has_physical_mode = false;
633 646
634 np = nvgpu_get_node(g); 647 np = nvgpu_get_node(g);
diff --git a/drivers/gpu/nvgpu/common/vbios/bios.c b/drivers/gpu/nvgpu/common/vbios/bios.c
index fa700a66..52c0a798 100644
--- a/drivers/gpu/nvgpu/common/vbios/bios.c
+++ b/drivers/gpu/nvgpu/common/vbios/bios.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2015-2018, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -74,6 +74,22 @@ struct bit {
74#define TOKEN_ID_VIRT_PTRS 0x56 74#define TOKEN_ID_VIRT_PTRS 0x56
75#define TOKEN_ID_MEMORY_PTRS 0x4D 75#define TOKEN_ID_MEMORY_PTRS 0x4D
76 76
77#define NVLINK_CONFIG_DATA_HDR_VER_10 0x1
78#define NVLINK_CONFIG_DATA_HDR_10_SIZE 16
79#define NVLINK_CONFIG_DATA_HDR_11_SIZE 17
80#define NVLINK_CONFIG_DATA_HDR_12_SIZE 21
81
82struct nvlink_config_data_hdr_v1 {
83 u8 version;
84 u8 hdr_size;
85 u16 rsvd0;
86 u32 link_disable_mask;
87 u32 link_mode_mask;
88 u32 link_refclk_mask;
89 u8 train_at_boot;
90 u32 ac_coupling_mask;
91} __packed;
92
77#define MEMORY_PTRS_V1 1 93#define MEMORY_PTRS_V1 1
78#define MEMORY_PTRS_V2 2 94#define MEMORY_PTRS_V2 2
79 95
@@ -369,6 +385,41 @@ static void nvgpu_bios_parse_nvinit_ptrs(struct gk20a *g, int offset)
369 g->bios.bootscripts = &g->bios.data[nvinit_ptrs.bootscripts_ptr]; 385 g->bios.bootscripts = &g->bios.data[nvinit_ptrs.bootscripts_ptr];
370 g->bios.bootscripts_size = nvinit_ptrs.bootscripts_size; 386 g->bios.bootscripts_size = nvinit_ptrs.bootscripts_size;
371 g->bios.condition_table_ptr = nvinit_ptrs.condition_table_ptr; 387 g->bios.condition_table_ptr = nvinit_ptrs.condition_table_ptr;
388 g->bios.nvlink_config_data_offset = nvinit_ptrs.nvlink_config_data_ptr;
389}
390
391u32 nvgpu_bios_get_nvlink_config_data(struct gk20a *g)
392{
393 struct nvlink_config_data_hdr_v1 config;
394
395 if (g->bios.nvlink_config_data_offset == 0)
396 return -EINVAL;
397
398 memcpy(&config, &g->bios.data[g->bios.nvlink_config_data_offset],
399 sizeof(config));
400
401 if (config.version != NVLINK_CONFIG_DATA_HDR_VER_10) {
402 nvgpu_err(g, "unsupported nvlink bios version: 0x%x",
403 config.version);
404 return -EINVAL;
405 }
406
407 switch (config.hdr_size) {
408 case NVLINK_CONFIG_DATA_HDR_12_SIZE:
409 g->nvlink.ac_coupling_mask = config.ac_coupling_mask;
410 case NVLINK_CONFIG_DATA_HDR_11_SIZE:
411 g->nvlink.train_at_boot = config.train_at_boot;
412 case NVLINK_CONFIG_DATA_HDR_10_SIZE:
413 g->nvlink.link_disable_mask = config.link_disable_mask;
414 g->nvlink.link_mode_mask = config.link_mode_mask;
415 g->nvlink.link_refclk_mask = config.link_refclk_mask;
416 break;
417 default:
418 nvgpu_err(g, "invalid nvlink bios config size");
419 return -EINVAL;
420 }
421
422 return 0;
372} 423}
373 424
374static void nvgpu_bios_parse_memory_ptrs(struct gk20a *g, int offset, u8 version) 425static void nvgpu_bios_parse_memory_ptrs(struct gk20a *g, int offset, u8 version)
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index b4886e31..868792c0 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -186,6 +186,18 @@ int gk20a_finalize_poweron(struct gk20a *g)
186 } 186 }
187 } 187 }
188 188
189 if (nvgpu_is_enabled(g, NVGPU_SUPPORT_NVLINK)) {
190 if (g->ops.nvlink.init) {
191 err = g->ops.nvlink.init(g);
192 if (err) {
193 nvgpu_err(g, "failed to init nvlink");
194 __nvgpu_set_enabled(g, NVGPU_SUPPORT_NVLINK,
195 false);
196 }
197 } else
198 __nvgpu_set_enabled(g, NVGPU_SUPPORT_NVLINK, false);
199 }
200
189 if (g->ops.fb.mem_unlock) { 201 if (g->ops.fb.mem_unlock) {
190 err = g->ops.fb.mem_unlock(g); 202 err = g->ops.fb.mem_unlock(g);
191 if (err) { 203 if (err) {
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index cc62865c..f187f730 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -62,6 +62,7 @@ struct nvgpu_ctxsw_trace_filter;
62#include <nvgpu/barrier.h> 62#include <nvgpu/barrier.h>
63#include <nvgpu/rwsem.h> 63#include <nvgpu/rwsem.h>
64#include <nvgpu/clk_arb.h> 64#include <nvgpu/clk_arb.h>
65#include <nvgpu/nvlink.h>
65 66
66#include "clk_gk20a.h" 67#include "clk_gk20a.h"
67#include "ce2_gk20a.h" 68#include "ce2_gk20a.h"
@@ -961,6 +962,7 @@ struct gpu_ops {
961 bool enable, bool is_stalling, u32 unit); 962 bool enable, bool is_stalling, u32 unit);
962 void (*isr_stall)(struct gk20a *g); 963 void (*isr_stall)(struct gk20a *g);
963 bool (*is_intr_hub_pending)(struct gk20a *g, u32 mc_intr); 964 bool (*is_intr_hub_pending)(struct gk20a *g, u32 mc_intr);
965 bool (*is_intr_nvlink_pending)(struct gk20a *g, u32 mc_intr);
964 u32 (*intr_stall)(struct gk20a *g); 966 u32 (*intr_stall)(struct gk20a *g);
965 void (*intr_stall_pause)(struct gk20a *g); 967 void (*intr_stall_pause)(struct gk20a *g);
966 void (*intr_stall_resume)(struct gk20a *g); 968 void (*intr_stall_resume)(struct gk20a *g);
@@ -1057,7 +1059,27 @@ struct gpu_ops {
1057 struct { 1059 struct {
1058 int (*check_priv_security)(struct gk20a *g); 1060 int (*check_priv_security)(struct gk20a *g);
1059 } fuse; 1061 } fuse;
1060 1062 struct {
1063 u32 (*init)(struct gk20a *g);
1064 u32 (*discover_ioctrl)(struct gk20a *g);
1065 u32 (*discover_link)(struct gk20a *g);
1066 u32 (*isr)(struct gk20a *g);
1067 /* API */
1068 int (*link_early_init)(struct gk20a *g, unsigned long mask);
1069 u32 (*link_get_mode)(struct gk20a *g, u32 link_id);
1070 u32 (*link_get_state)(struct gk20a *g, u32 link_id);
1071 int (*link_set_mode)(struct gk20a *g, u32 link_id, u32 mode);
1072 u32 (*get_sublink_mode)(struct gk20a *g, u32 link_id,
1073 bool is_rx_sublink);
1074 u32 (*get_rx_sublink_state)(struct gk20a *g, u32 link_id);
1075 u32 (*get_tx_sublink_state)(struct gk20a *g, u32 link_id);
1076 int (*set_sublink_mode)(struct gk20a *g, u32 link_id,
1077 bool is_rx_sublink, u32 mode);
1078 int (*interface_init)(struct gk20a *g);
1079 int (*reg_init)(struct gk20a *g);
1080 int (*shutdown)(struct gk20a *g);
1081 int (*early_init)(struct gk20a *g);
1082 } nvlink;
1061}; 1083};
1062 1084
1063struct nvgpu_bios_ucode { 1085struct nvgpu_bios_ucode {
@@ -1100,6 +1122,8 @@ struct nvgpu_bios {
1100 struct bit_token *clock_token; 1122 struct bit_token *clock_token;
1101 struct bit_token *virt_token; 1123 struct bit_token *virt_token;
1102 u32 expansion_rom_offset; 1124 u32 expansion_rom_offset;
1125
1126 u32 nvlink_config_data_offset;
1103}; 1127};
1104 1128
1105struct nvgpu_gpu_params { 1129struct nvgpu_gpu_params {
@@ -1153,8 +1177,10 @@ struct gk20a {
1153 struct nvgpu_falcon fecs_flcn; 1177 struct nvgpu_falcon fecs_flcn;
1154 struct nvgpu_falcon gpccs_flcn; 1178 struct nvgpu_falcon gpccs_flcn;
1155 struct nvgpu_falcon nvdec_flcn; 1179 struct nvgpu_falcon nvdec_flcn;
1180 struct nvgpu_falcon minion_flcn;
1156 struct clk_gk20a clk; 1181 struct clk_gk20a clk;
1157 struct fifo_gk20a fifo; 1182 struct fifo_gk20a fifo;
1183 struct nvgpu_nvlink_dev nvlink;
1158 struct gr_gk20a gr; 1184 struct gr_gk20a gr;
1159 struct sim_gk20a *sim; 1185 struct sim_gk20a *sim;
1160 struct mm_gk20a mm; 1186 struct mm_gk20a mm;
diff --git a/drivers/gpu/nvgpu/gp10b/mc_gp10b.c b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c
index 9aea76f9..dde12854 100644
--- a/drivers/gpu/nvgpu/gp10b/mc_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * GP10B master 2 * GP10B master
3 * 3 *
4 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a 6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"), 7 * copy of this software and associated documentation files (the "Software"),
@@ -122,6 +122,9 @@ void mc_gp10b_isr_stall(struct gk20a *g)
122 g->ops.ltc.isr(g); 122 g->ops.ltc.isr(g);
123 if (mc_intr_0 & mc_intr_pbus_pending_f()) 123 if (mc_intr_0 & mc_intr_pbus_pending_f())
124 g->ops.bus.isr(g); 124 g->ops.bus.isr(g);
125 if (g->ops.mc.is_intr_nvlink_pending &&
126 g->ops.mc.is_intr_nvlink_pending(g, mc_intr_0))
127 g->ops.nvlink.isr(g);
125 128
126 gk20a_dbg(gpu_dbg_intr, "stall intr done 0x%08x\n", mc_intr_0); 129 gk20a_dbg(gpu_dbg_intr, "stall intr done 0x%08x\n", mc_intr_0);
127 130
diff --git a/drivers/gpu/nvgpu/include/nvgpu/bios.h b/drivers/gpu/nvgpu/include/nvgpu/bios.h
index a4823caa..fb0a313f 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/bios.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/bios.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -1051,5 +1051,5 @@ u32 nvgpu_bios_read_u32(struct gk20a *g, u32 offset);
1051void *nvgpu_bios_get_perf_table_ptrs(struct gk20a *g, 1051void *nvgpu_bios_get_perf_table_ptrs(struct gk20a *g,
1052 struct bit_token *ptoken, u8 table_id); 1052 struct bit_token *ptoken, u8 table_id);
1053int nvgpu_bios_execute_script(struct gk20a *g, u32 offset); 1053int nvgpu_bios_execute_script(struct gk20a *g, u32 offset);
1054 1054u32 nvgpu_bios_get_nvlink_config_data(struct gk20a *g);
1055#endif 1055#endif
diff --git a/drivers/gpu/nvgpu/include/nvgpu/enabled.h b/drivers/gpu/nvgpu/include/nvgpu/enabled.h
index c614ce4d..4d8dbb08 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/enabled.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/enabled.h
@@ -77,7 +77,8 @@ struct gk20a;
77#define NVGPU_SUPPORT_MAP_BUFFER_BATCH 25 77#define NVGPU_SUPPORT_MAP_BUFFER_BATCH 25
78/* Support DMA coherence */ 78/* Support DMA coherence */
79#define NVGPU_DMA_COHERENT 26 79#define NVGPU_DMA_COHERENT 26
80 80/* Use physical scatter tables instead of IOMMU */
81#define NVGPU_MM_USE_PHYSICAL_SG 27
81 82
82/* 83/*
83 * Host flags 84 * Host flags
@@ -114,6 +115,11 @@ struct gk20a;
114#define NVGPU_SEC_PRIVSECURITY 42 115#define NVGPU_SEC_PRIVSECURITY 42
115 116
116/* 117/*
118 * Nvlink flags
119 */
120
121#define NVGPU_SUPPORT_NVLINK 45
122/*
117 * PMU flags. 123 * PMU flags.
118 */ 124 */
119/* perfmon enabled or disabled for PMU */ 125/* perfmon enabled or disabled for PMU */
diff --git a/drivers/gpu/nvgpu/include/nvgpu/falcon.h b/drivers/gpu/nvgpu/include/nvgpu/falcon.h
index 1f104fa1..31587ee7 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/falcon.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/falcon.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -34,6 +34,7 @@
34#define FALCON_ID_GPCCS (3) 34#define FALCON_ID_GPCCS (3)
35#define FALCON_ID_NVDEC (4) 35#define FALCON_ID_NVDEC (4)
36#define FALCON_ID_SEC2 (7) 36#define FALCON_ID_SEC2 (7)
37#define FALCON_ID_MINION (10)
37 38
38/* 39/*
39 * Falcon Base address Defines 40 * Falcon Base address Defines
diff --git a/drivers/gpu/nvgpu/include/nvgpu/log.h b/drivers/gpu/nvgpu/include/nvgpu/log.h
index 65f86198..7d7a41e3 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/log.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/log.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -79,6 +79,7 @@ enum nvgpu_log_categories {
79 gpu_dbg_dma = BIT(22), /* DMA allocation prints. */ 79 gpu_dbg_dma = BIT(22), /* DMA allocation prints. */
80 gpu_dbg_sgl = BIT(23), /* SGL related traces. */ 80 gpu_dbg_sgl = BIT(23), /* SGL related traces. */
81 gpu_dbg_vidmem = BIT(24), /* VIDMEM tracing. */ 81 gpu_dbg_vidmem = BIT(24), /* VIDMEM tracing. */
82 gpu_dbg_nvlink = BIT(25), /* nvlink Operation tracing. */
82 gpu_dbg_mem = BIT(31), /* memory accesses; very verbose. */ 83 gpu_dbg_mem = BIT(31), /* memory accesses; very verbose. */
83}; 84};
84 85
diff --git a/drivers/gpu/nvgpu/include/nvgpu/nvlink.h b/drivers/gpu/nvgpu/include/nvgpu/nvlink.h
new file mode 100644
index 00000000..48851ff1
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/nvlink.h
@@ -0,0 +1,206 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef __NVGPU_NVLINK_H__
24#define __NVGPU_NVLINK_H__
25
26#include <nvgpu/types.h>
27
28struct gk20a;
29
30struct nvgpu_nvlink_ioctrl_list {
31 bool valid;
32 u32 pri_base_addr;
33 u8 intr_enum;
34 u8 reset_enum;
35};
36
37struct nvgpu_nvlink_device_list {
38 bool valid;
39 u8 device_type;
40 u8 device_id;
41 u8 device_version;
42 u32 pri_base_addr;
43 u8 intr_enum;
44 u8 reset_enum;
45 u8 num_tx;
46 u8 num_rx;
47 u8 pll_master;
48 u8 pll_master_id;
49};
50
51enum nvgpu_nvlink_endp {
52 nvgpu_nvlink_endp_gpu,
53 nvgpu_nvlink_endp_tegra,
54 nvgpu_nvlink_endp__last,
55};
56
57enum nvgpu_nvlink_link_mode {
58 nvgpu_nvlink_link_off,
59 nvgpu_nvlink_link_hs,
60 nvgpu_nvlink_link_safe,
61 nvgpu_nvlink_link_fault,
62 nvgpu_nvlink_link_recovery,
63 nvgpu_nvlink_link_detect,
64 nvgpu_nvlink_link_reset,
65 nvgpu_nvlink_link_enable_pm,
66 nvgpu_nvlink_link_disable_pm,
67 nvgpu_nvlink_link_disable_err_detect,
68 nvgpu_nvlink_link_lane_disable,
69 nvgpu_nvlink_link_lane_shutdown,
70 nvgpu_nvlink_link__last,
71};
72
73enum nvgpu_nvlink_sublink_mode {
74 nvgpu_nvlink_sublink_tx_hs,
75 nvgpu_nvlink_sublink_tx_enable_pm,
76 nvgpu_nvlink_sublink_tx_disable_pm,
77 nvgpu_nvlink_sublink_tx_single_lane,
78 nvgpu_nvlink_sublink_tx_safe,
79 nvgpu_nvlink_sublink_tx_off,
80 nvgpu_nvlink_sublink_tx_common,
81 nvgpu_nvlink_sublink_tx_common_disable,
82 nvgpu_nvlink_sublink_tx_data_ready,
83 nvgpu_nvlink_sublink_tx_prbs_en,
84 nvgpu_nvlink_sublink_tx__last,
85 /* RX */
86 nvgpu_nvlink_sublink_rx_hs,
87 nvgpu_nvlink_sublink_rx_enable_pm,
88 nvgpu_nvlink_sublink_rx_disable_pm,
89 nvgpu_nvlink_sublink_rx_single_lane,
90 nvgpu_nvlink_sublink_rx_safe,
91 nvgpu_nvlink_sublink_rx_off,
92 nvgpu_nvlink_sublink_rx_rxcal,
93 nvgpu_nvlink_sublink_rx__last,
94};
95
96struct nvgpu_nvlink_conn_info {
97 enum nvgpu_nvlink_endp device_type;
98 u32 link_number;
99 bool is_connected;
100};
101
102struct nvgpu_nvlink_link {
103 bool valid;
104 struct gk20a *g;
105 u8 link_id;
106
107 u32 dlpl_base;
108 u8 dlpl_version;
109
110 u32 tl_base;
111 u8 tl_version;
112
113 u32 mif_base;
114 u8 mif_version;
115
116 u8 intr_enum;
117 u8 reset_enum;
118
119 bool dl_init_done;
120
121 u8 pll_master_link_id;
122 u8 pll_slave_link_id;
123
124 struct nvgpu_nvlink_conn_info remote_info;
125 void *priv;
126};
127
128#define NVLINK_MAX_LINKS_SW 6
129
130enum nvgpu_nvlink_speed {
131 nvgpu_nvlink_speed_default,
132 nvgpu_nvlink_speed__last,
133};
134
135struct nvgpu_nvlink_dev {
136 struct nvgpu_nvlink_ioctrl_list *ioctrl_table;
137 u32 io_num_entries;
138
139 struct nvgpu_nvlink_device_list *device_table;
140 u32 num_devices;
141
142 struct nvgpu_nvlink_link links[NVLINK_MAX_LINKS_SW];
143
144 u8 dlpl_type;
145 u32 dlpl_base[NVLINK_MAX_LINKS_SW];
146
147 u8 tl_type;
148 u32 tl_base[NVLINK_MAX_LINKS_SW];
149
150 u8 mif_type;
151 u32 mif_base[NVLINK_MAX_LINKS_SW];
152
153 u8 ipt_type;
154 u32 ipt_base;
155 u8 ipt_version;
156
157 u8 dlpl_multicast_type;
158 u8 dlpl_multicast_version;
159 u32 dlpl_multicast_base;
160
161 u8 tl_multicast_type;
162 u8 tl_multicast_version;
163 u32 tl_multicast_base;
164
165 u8 mif_multicast_type;
166 u8 mif_multicast_version;
167 u32 mif_multicast_base;
168
169 u8 ioctrl_type;
170 u32 ioctrl_base;
171
172 u8 minion_type;
173 u32 minion_base;
174 u8 minion_version;
175
176 u32 discovered_links;
177
178 /* VBIOS settings */
179 u32 link_disable_mask;
180 u32 link_mode_mask;
181 u32 link_refclk_mask;
182 u8 train_at_boot;
183 u32 ac_coupling_mask;
184
185 u32 init_disabled_links;
186 u32 connected_links;
187 u32 initialized_links;
188 u32 enabled_links;
189 u32 topology_connected_links;
190
191 enum nvgpu_nvlink_speed speed;
192
193 /* hshub settings */
194 u32 hshub_config0;
195 u32 hshub_config1;
196 u32 hshub_config2;
197 u32 hshub_config6;
198 /* priv struct */
199 void *priv;
200};
201
202
203u32 nvgpu_nvlink_enumerate(struct gk20a *g);
204u32 nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off);
205u32 nvgpu_nvlink_probe(struct gk20a *g);
206#endif