summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2017-12-07 19:48:09 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-01-25 20:39:53 -0500
commitfbdcc8a2d4c2b7f145b034ee7bde7105e66e0a4e (patch)
tree0bb7c6d0a1bbd723bf891f5c3287cb8abc315cd4
parent37b8298a48ec65ca78048e68c8c3e1a060b8fb63 (diff)
gpu: nvgpu: Initial Nvlink driver skeleton
Adds the skeleton and integration of the GV100 endpoint driver to NVGPU (1) Adds a OS abstraction layer for the internal nvlink structure. (2) Adds linux specific integration with Nvlink core driver. (3) Adds function pointers for nvlink api, initialization and isr process. (4) Adds initial support for minion. (5) Adds new GPU enable properties to handle NVLINK presence (6) Adds new GPU enable properties for SG_PHY bypass (required for NVLINK over PCI) (7) Adds parsing of nvlink vbios structures. (8) Adds logging defines for NVGPU JIRA: EVLR-2328 Change-Id: I0720a165a15c7187892c8c1a0662ec598354ac06 Signed-off-by: David Nieto <dmartineznie@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1644708 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-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