summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/nvlink.c
diff options
context:
space:
mode:
authorThomas Fleury <tfleury@nvidia.com>2018-01-23 17:20:43 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-02-26 00:48:24 -0500
commit0601fd25a5e01d0da638efef13c58b64f198bafb (patch)
treedbe843912a525497103bbe9beefc6e78ff67c8c9 /drivers/gpu/nvgpu/common/linux/nvlink.c
parent223ea4d8a179835dd5899bbc12fe78b4998b0bd7 (diff)
gpu: nvgpu: gv100: nvlink endpoint driver
The following changes implements the initial (as per bringup) nvlink driver. (1) SW initialization of nvlink core driver structures (2) Nvlink interrupt handling (3) Device initialization (IOCTRL, pll and clocks, device level intr) (4) Falcon support for minion (5) Minion load and bootstrapping (6) Link initialization and DL PROD settings (7) Device Interface init (and switching HSHUB to nvlink) (8) HS set/get mode for both link and sublink (9) Topology discovery and VBIOS settings. (10) Ensures we get physical contiguous memory when Nvlink is enabled This driver includes a hack for the current single dev/single link limitation. JIRA: EVLR-2331 JIRA: EVLR-2330 JIRA: EVLR-2329 JIRA: EVLR-2328 Change-Id: Idca9a819179376cc655784482b24b575a52fa9e5 Signed-off-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1656790 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/nvlink.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/nvlink.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/nvlink.c b/drivers/gpu/nvgpu/common/linux/nvlink.c
index 6cf74048..61dc8bc7 100644
--- a/drivers/gpu/nvgpu/common/linux/nvlink.c
+++ b/drivers/gpu/nvgpu/common/linux/nvlink.c
@@ -40,7 +40,7 @@ static u32 __nvgpu_nvlink_get_link(struct nvlink_device *ndev)
40 40
41 /* Lets find the detected link */ 41 /* Lets find the detected link */
42 if (g->nvlink.initialized_links) 42 if (g->nvlink.initialized_links)
43 link_id = fls(g->nvlink.initialized_links); 43 link_id = ffs(g->nvlink.initialized_links) - 1;
44 else 44 else
45 return NVLINK_MAX_LINKS_SW; 45 return NVLINK_MAX_LINKS_SW;
46 46
@@ -49,6 +49,7 @@ static u32 __nvgpu_nvlink_get_link(struct nvlink_device *ndev)
49 49
50 return NVLINK_MAX_LINKS_SW; 50 return NVLINK_MAX_LINKS_SW;
51} 51}
52
52static int nvgpu_nvlink_early_init(struct nvlink_device *ndev) 53static int nvgpu_nvlink_early_init(struct nvlink_device *ndev)
53{ 54{
54 struct gk20a *g = (struct gk20a *) ndev->priv; 55 struct gk20a *g = (struct gk20a *) ndev->priv;
@@ -75,9 +76,10 @@ static int nvgpu_nvlink_link_early_init(struct nvlink_device *ndev)
75 * First check the topology and setup connectivity 76 * First check the topology and setup connectivity
76 * HACK: we are only enabling one link for now!!! 77 * HACK: we are only enabling one link for now!!!
77 */ 78 */
78 link_id = fls(g->nvlink.discovered_links); 79 link_id = ffs(g->nvlink.discovered_links) - 1;
79 g->nvlink.links[link_id].remote_info.is_connected = true; 80 g->nvlink.links[link_id].remote_info.is_connected = true;
80 81 g->nvlink.links[link_id].remote_info.device_type =
82 nvgpu_nvlink_endp_tegra;
81 err = g->ops.nvlink.link_early_init(g, BIT(link_id)); 83 err = g->ops.nvlink.link_early_init(g, BIT(link_id));
82 84
83 if (err == 0) { 85 if (err == 0) {
@@ -262,6 +264,7 @@ static u32 nvgpu_nvlink_get_sublink_mode(struct nvlink_device *ndev,
262 return -EINVAL; 264 return -EINVAL;
263 265
264 mode = g->ops.nvlink.get_sublink_mode(g, link_id, is_rx_sublink); 266 mode = g->ops.nvlink.get_sublink_mode(g, link_id, is_rx_sublink);
267
265 switch (mode) { 268 switch (mode) {
266 case nvgpu_nvlink_sublink_tx_hs: 269 case nvgpu_nvlink_sublink_tx_hs:
267 return NVLINK_TX_HS; 270 return NVLINK_TX_HS;
@@ -386,9 +389,9 @@ static int nvgpu_nvlink_set_sublink_mode(struct nvlink_device *ndev,
386} 389}
387#endif 390#endif
388 391
389u32 nvgpu_nvlink_enumerate(struct gk20a *g) 392int nvgpu_nvlink_enumerate(struct gk20a *g)
390{ 393{
391 u32 err = -ENODEV; 394 int err = -ENODEV;
392#ifdef CONFIG_TEGRA_NVLINK 395#ifdef CONFIG_TEGRA_NVLINK
393 struct nvlink_device *ndev; 396 struct nvlink_device *ndev;
394 397
@@ -400,9 +403,9 @@ u32 nvgpu_nvlink_enumerate(struct gk20a *g)
400 return err; 403 return err;
401} 404}
402 405
403u32 nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off) 406int nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off)
404{ 407{
405 u32 err = -ENODEV; 408 int err = -ENODEV;
406#ifdef CONFIG_TEGRA_NVLINK 409#ifdef CONFIG_TEGRA_NVLINK
407 struct nvlink_device *ndev; 410 struct nvlink_device *ndev;
408 411
@@ -423,10 +426,10 @@ u32 nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off)
423 return err; 426 return err;
424} 427}
425 428
426u32 nvgpu_nvlink_probe(struct gk20a *g) 429int nvgpu_nvlink_probe(struct gk20a *g)
427{ 430{
428#ifdef CONFIG_TEGRA_NVLINK 431#ifdef CONFIG_TEGRA_NVLINK
429 u32 err = 0; 432 int err = 0;
430 struct device_node *np = nvgpu_get_node(g); 433 struct device_node *np = nvgpu_get_node(g);
431 struct device_node *nvlink_np = NULL, *endp_np = NULL; 434 struct device_node *nvlink_np = NULL, *endp_np = NULL;
432 struct nvlink_device *ndev; 435 struct nvlink_device *ndev;
@@ -435,13 +438,13 @@ u32 nvgpu_nvlink_probe(struct gk20a *g)
435 /* Parse DT */ 438 /* Parse DT */
436 if (np) { 439 if (np) {
437 nvlink_np = of_get_child_by_name(np, "nvidia,nvlink"); 440 nvlink_np = of_get_child_by_name(np, "nvidia,nvlink");
438 if (nvlink_np) 441 if (nvlink_np) {
439 endp_np = of_get_child_by_name(np, "endpoint"); 442 endp_np = of_get_child_by_name(nvlink_np, "endpoint");
443 }
440 } 444 }
441 445
442 if (!endp_np) { 446 if (!endp_np) {
443 nvgpu_log(g, gpu_dbg_info | gpu_dbg_nvlink, 447 nvgpu_info(g, "no nvlink DT detected");
444 "No Nvlink DT detected");
445 return -ENODEV; 448 return -ENODEV;
446 } 449 }
447 450
@@ -466,13 +469,13 @@ u32 nvgpu_nvlink_probe(struct gk20a *g)
466 of_property_read_u32(endp_np, "physical_link", 469 of_property_read_u32(endp_np, "physical_link",
467 &phys_link_id); 470 &phys_link_id);
468 471
469 g->nvlink.topology_connected_links = BIT(phys_link_id); 472 g->nvlink.connected_links = BIT(phys_link_id);
470 473
471 /* Check that we are in dGPU mode */ 474 /* Check that we are in dGPU mode */
472 if (ndev->device_id != NVLINK_ENDPT_GV100) { 475 if (ndev->device_id != NVLINK_ENDPT_GV100) {
473 nvgpu_err(g, "Local nvlink device is not dGPU"); 476 nvgpu_err(g, "Local nvlink device is not dGPU");
474 err = -EINVAL; 477 err = -EINVAL;
475 goto free_nvlink; 478 goto free_ndev;
476 } 479 }
477 480
478 /* Fill in device struct */ 481 /* Fill in device struct */
@@ -500,22 +503,27 @@ u32 nvgpu_nvlink_probe(struct gk20a *g)
500 err = nvlink_register_device(ndev); 503 err = nvlink_register_device(ndev);
501 if (err) { 504 if (err) {
502 nvgpu_err(g, "failed on nvlink device registration"); 505 nvgpu_err(g, "failed on nvlink device registration");
503 goto free_nvlink; 506 goto free_ndev;
504 } 507 }
505 508
506 /* Register link with core driver */ 509 /* Register link with core driver */
507 err = nvlink_register_link(&ndev->link); 510 err = nvlink_register_link(&ndev->link);
508 if (err) { 511 if (err) {
509 nvgpu_err(g, "failed on nvlink link registration"); 512 nvgpu_err(g, "failed on nvlink link registration");
510 goto free_nvlink; 513 goto unregister_ndev;
511 } 514 }
512 515
513 /* Enable NVLINK support */ 516 /* Enable NVLINK support */
514 __nvgpu_set_enabled(g, NVGPU_SUPPORT_NVLINK, true); 517 __nvgpu_set_enabled(g, NVGPU_SUPPORT_NVLINK, true);
515free_nvlink: 518 return 0;
519
520unregister_ndev:
521 nvlink_unregister_device(ndev);
522
523free_ndev:
516 nvgpu_kfree(g, ndev); 524 nvgpu_kfree(g, ndev);
525 g->nvlink.priv = NULL;
517 return err; 526 return err;
518
519#else 527#else
520 return -ENODEV; 528 return -ENODEV;
521#endif 529#endif