diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/nvlink.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/nvlink.c | 46 |
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 | |||
52 | static int nvgpu_nvlink_early_init(struct nvlink_device *ndev) | 53 | static 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 | ||
389 | u32 nvgpu_nvlink_enumerate(struct gk20a *g) | 392 | int 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 | ||
403 | u32 nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off) | 406 | int 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 | ||
426 | u32 nvgpu_nvlink_probe(struct gk20a *g) | 429 | int 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); |
515 | free_nvlink: | 518 | return 0; |
519 | |||
520 | unregister_ndev: | ||
521 | nvlink_unregister_device(ndev); | ||
522 | |||
523 | free_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 |