mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
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>
This commit is contained in:
committed by
mobile promotions
parent
223ea4d8a1
commit
0601fd25a5
@@ -246,6 +246,9 @@ nvgpu-y += \
|
||||
gv100/fifo_gv100.o \
|
||||
gv100/gr_gv100.o \
|
||||
gv100/regops_gv100.o \
|
||||
gv100/flcn_gv100.o \
|
||||
gv100/mc_gv100.o \
|
||||
gv100/nvlink_gv100.o \
|
||||
gv100/hal_gv100.o \
|
||||
gv100/pmu_gv100.o \
|
||||
pstate/pstate.o \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -536,6 +536,8 @@ static u64 nvgpu_mem_linux_sgl_gpu_addr(struct gk20a *g, void *sgl,
|
||||
static bool nvgpu_mem_linux_sgt_iommuable(struct gk20a *g,
|
||||
struct nvgpu_sgt *sgt)
|
||||
{
|
||||
if (nvgpu_is_enabled(g, NVGPU_MM_USE_PHYSICAL_SG))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ static u32 __nvgpu_nvlink_get_link(struct nvlink_device *ndev)
|
||||
|
||||
/* Lets find the detected link */
|
||||
if (g->nvlink.initialized_links)
|
||||
link_id = fls(g->nvlink.initialized_links);
|
||||
link_id = ffs(g->nvlink.initialized_links) - 1;
|
||||
else
|
||||
return NVLINK_MAX_LINKS_SW;
|
||||
|
||||
@@ -49,6 +49,7 @@ static u32 __nvgpu_nvlink_get_link(struct nvlink_device *ndev)
|
||||
|
||||
return NVLINK_MAX_LINKS_SW;
|
||||
}
|
||||
|
||||
static int nvgpu_nvlink_early_init(struct nvlink_device *ndev)
|
||||
{
|
||||
struct gk20a *g = (struct gk20a *) ndev->priv;
|
||||
@@ -75,9 +76,10 @@ static int nvgpu_nvlink_link_early_init(struct nvlink_device *ndev)
|
||||
* First check the topology and setup connectivity
|
||||
* HACK: we are only enabling one link for now!!!
|
||||
*/
|
||||
link_id = fls(g->nvlink.discovered_links);
|
||||
link_id = ffs(g->nvlink.discovered_links) - 1;
|
||||
g->nvlink.links[link_id].remote_info.is_connected = true;
|
||||
|
||||
g->nvlink.links[link_id].remote_info.device_type =
|
||||
nvgpu_nvlink_endp_tegra;
|
||||
err = g->ops.nvlink.link_early_init(g, BIT(link_id));
|
||||
|
||||
if (err == 0) {
|
||||
@@ -262,6 +264,7 @@ static u32 nvgpu_nvlink_get_sublink_mode(struct nvlink_device *ndev,
|
||||
return -EINVAL;
|
||||
|
||||
mode = g->ops.nvlink.get_sublink_mode(g, link_id, is_rx_sublink);
|
||||
|
||||
switch (mode) {
|
||||
case nvgpu_nvlink_sublink_tx_hs:
|
||||
return NVLINK_TX_HS;
|
||||
@@ -386,9 +389,9 @@ static int nvgpu_nvlink_set_sublink_mode(struct nvlink_device *ndev,
|
||||
}
|
||||
#endif
|
||||
|
||||
u32 nvgpu_nvlink_enumerate(struct gk20a *g)
|
||||
int nvgpu_nvlink_enumerate(struct gk20a *g)
|
||||
{
|
||||
u32 err = -ENODEV;
|
||||
int err = -ENODEV;
|
||||
#ifdef CONFIG_TEGRA_NVLINK
|
||||
struct nvlink_device *ndev;
|
||||
|
||||
@@ -400,9 +403,9 @@ u32 nvgpu_nvlink_enumerate(struct gk20a *g)
|
||||
return err;
|
||||
}
|
||||
|
||||
u32 nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off)
|
||||
int nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off)
|
||||
{
|
||||
u32 err = -ENODEV;
|
||||
int err = -ENODEV;
|
||||
#ifdef CONFIG_TEGRA_NVLINK
|
||||
struct nvlink_device *ndev;
|
||||
|
||||
@@ -423,10 +426,10 @@ u32 nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off)
|
||||
return err;
|
||||
}
|
||||
|
||||
u32 nvgpu_nvlink_probe(struct gk20a *g)
|
||||
int nvgpu_nvlink_probe(struct gk20a *g)
|
||||
{
|
||||
#ifdef CONFIG_TEGRA_NVLINK
|
||||
u32 err = 0;
|
||||
int err = 0;
|
||||
struct device_node *np = nvgpu_get_node(g);
|
||||
struct device_node *nvlink_np = NULL, *endp_np = NULL;
|
||||
struct nvlink_device *ndev;
|
||||
@@ -435,13 +438,13 @@ u32 nvgpu_nvlink_probe(struct gk20a *g)
|
||||
/* Parse DT */
|
||||
if (np) {
|
||||
nvlink_np = of_get_child_by_name(np, "nvidia,nvlink");
|
||||
if (nvlink_np)
|
||||
endp_np = of_get_child_by_name(np, "endpoint");
|
||||
if (nvlink_np) {
|
||||
endp_np = of_get_child_by_name(nvlink_np, "endpoint");
|
||||
}
|
||||
}
|
||||
|
||||
if (!endp_np) {
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_nvlink,
|
||||
"No Nvlink DT detected");
|
||||
nvgpu_info(g, "no nvlink DT detected");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -466,13 +469,13 @@ u32 nvgpu_nvlink_probe(struct gk20a *g)
|
||||
of_property_read_u32(endp_np, "physical_link",
|
||||
&phys_link_id);
|
||||
|
||||
g->nvlink.topology_connected_links = BIT(phys_link_id);
|
||||
g->nvlink.connected_links = BIT(phys_link_id);
|
||||
|
||||
/* Check that we are in dGPU mode */
|
||||
if (ndev->device_id != NVLINK_ENDPT_GV100) {
|
||||
nvgpu_err(g, "Local nvlink device is not dGPU");
|
||||
err = -EINVAL;
|
||||
goto free_nvlink;
|
||||
goto free_ndev;
|
||||
}
|
||||
|
||||
/* Fill in device struct */
|
||||
@@ -500,22 +503,27 @@ u32 nvgpu_nvlink_probe(struct gk20a *g)
|
||||
err = nvlink_register_device(ndev);
|
||||
if (err) {
|
||||
nvgpu_err(g, "failed on nvlink device registration");
|
||||
goto free_nvlink;
|
||||
goto free_ndev;
|
||||
}
|
||||
|
||||
/* Register link with core driver */
|
||||
err = nvlink_register_link(&ndev->link);
|
||||
if (err) {
|
||||
nvgpu_err(g, "failed on nvlink link registration");
|
||||
goto free_nvlink;
|
||||
goto unregister_ndev;
|
||||
}
|
||||
|
||||
/* Enable NVLINK support */
|
||||
__nvgpu_set_enabled(g, NVGPU_SUPPORT_NVLINK, true);
|
||||
free_nvlink:
|
||||
nvgpu_kfree(g, ndev);
|
||||
return err;
|
||||
return 0;
|
||||
|
||||
unregister_ndev:
|
||||
nvlink_unregister_device(ndev);
|
||||
|
||||
free_ndev:
|
||||
nvgpu_kfree(g, ndev);
|
||||
g->nvlink.priv = NULL;
|
||||
return err;
|
||||
#else
|
||||
return -ENODEV;
|
||||
#endif
|
||||
|
||||
@@ -967,6 +967,8 @@ struct gpu_ops {
|
||||
void (*isr_stall)(struct gk20a *g);
|
||||
bool (*is_intr_hub_pending)(struct gk20a *g, u32 mc_intr);
|
||||
bool (*is_intr_nvlink_pending)(struct gk20a *g, u32 mc_intr);
|
||||
bool (*is_stall_and_eng_intr_pending)(struct gk20a *g,
|
||||
u32 act_eng_id);
|
||||
u32 (*intr_stall)(struct gk20a *g);
|
||||
void (*intr_stall_pause)(struct gk20a *g);
|
||||
void (*intr_stall_resume)(struct gk20a *g);
|
||||
@@ -1064,10 +1066,10 @@ struct gpu_ops {
|
||||
int (*check_priv_security)(struct gk20a *g);
|
||||
} fuse;
|
||||
struct {
|
||||
u32 (*init)(struct gk20a *g);
|
||||
u32 (*discover_ioctrl)(struct gk20a *g);
|
||||
u32 (*discover_link)(struct gk20a *g);
|
||||
u32 (*isr)(struct gk20a *g);
|
||||
int (*init)(struct gk20a *g);
|
||||
int (*discover_ioctrl)(struct gk20a *g);
|
||||
int (*discover_link)(struct gk20a *g);
|
||||
int (*isr)(struct gk20a *g);
|
||||
/* API */
|
||||
int (*link_early_init)(struct gk20a *g, unsigned long mask);
|
||||
u32 (*link_get_mode)(struct gk20a *g, u32 link_id);
|
||||
|
||||
55
drivers/gpu/nvgpu/gv100/flcn_gv100.c
Normal file
55
drivers/gpu/nvgpu/gv100/flcn_gv100.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <nvgpu/falcon.h>
|
||||
#include <nvgpu/pmu.h>
|
||||
|
||||
#include "gk20a/gk20a.h"
|
||||
#include "gk20a/flcn_gk20a.h"
|
||||
#include "gp106/flcn_gp106.h"
|
||||
#include "gv100/flcn_gv100.h"
|
||||
|
||||
#include <nvgpu/hw/gv100/hw_falcon_gv100.h>
|
||||
|
||||
void gv100_falcon_hal_sw_init(struct nvgpu_falcon *flcn)
|
||||
{
|
||||
struct gk20a *g = flcn->g;
|
||||
|
||||
switch (flcn->flcn_id) {
|
||||
case FALCON_ID_MINION:
|
||||
flcn->flcn_base = g->nvlink.minion_base;
|
||||
flcn->is_falcon_supported = true;
|
||||
flcn->is_interrupt_enabled = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (flcn->is_falcon_supported) {
|
||||
nvgpu_mutex_init(&flcn->copy_lock);
|
||||
gk20a_falcon_ops(flcn);
|
||||
} else {
|
||||
/*
|
||||
* Fall back
|
||||
*/
|
||||
gp106_falcon_hal_sw_init(flcn);
|
||||
}
|
||||
}
|
||||
27
drivers/gpu/nvgpu/gv100/flcn_gv100.h
Normal file
27
drivers/gpu/nvgpu/gv100/flcn_gv100.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __FLCN_GV100_H__
|
||||
#define __FLCN_GV100_H__
|
||||
|
||||
void gv100_falcon_hal_sw_init(struct nvgpu_falcon *flcn);
|
||||
|
||||
#endif /* __FLCN_GV100_H__ */
|
||||
@@ -51,20 +51,19 @@
|
||||
#include "gm20b/pmu_gm20b.h"
|
||||
#include "gm20b/acr_gm20b.h"
|
||||
|
||||
#include "gp10b/fb_gp10b.h"
|
||||
#include "gp10b/gr_gp10b.h"
|
||||
|
||||
#include "gp106/clk_gp106.h"
|
||||
#include "gp106/clk_arb_gp106.h"
|
||||
#include "gp106/pmu_gp106.h"
|
||||
#include "gp106/acr_gp106.h"
|
||||
#include "gp106/sec2_gp106.h"
|
||||
#include "gp106/bios_gp106.h"
|
||||
#include "gv100/bios_gv100.h"
|
||||
#include "gp106/therm_gp106.h"
|
||||
#include "gp106/xve_gp106.h"
|
||||
#include "gp106/clk_gp106.h"
|
||||
#include "gp106/flcn_gp106.h"
|
||||
|
||||
#include "gp10b/fb_gp10b.h"
|
||||
#include "gp10b/gr_gp10b.h"
|
||||
#include "gp10b/ltc_gp10b.h"
|
||||
#include "gp10b/therm_gp10b.h"
|
||||
#include "gp10b/mc_gp10b.h"
|
||||
@@ -78,32 +77,33 @@
|
||||
#include "gv11b/css_gr_gv11b.h"
|
||||
#include "gv11b/dbg_gpu_gv11b.h"
|
||||
#include "gv11b/hal_gv11b.h"
|
||||
#include "gv100/gr_gv100.h"
|
||||
#include "gv11b/gr_gv11b.h"
|
||||
#include "gv11b/mc_gv11b.h"
|
||||
#include "gv11b/ltc_gv11b.h"
|
||||
#include "gv11b/gv11b.h"
|
||||
#include "gv11b/ce_gv11b.h"
|
||||
#include "gv100/gr_ctx_gv100.h"
|
||||
#include "gv11b/mm_gv11b.h"
|
||||
#include "gv11b/pmu_gv11b.h"
|
||||
#include "gv11b/fb_gv11b.h"
|
||||
#include "gv100/mm_gv100.h"
|
||||
#include "gv11b/pmu_gv11b.h"
|
||||
#include "gv100/fb_gv100.h"
|
||||
#include "gv100/fifo_gv100.h"
|
||||
#include "gv11b/fifo_gv11b.h"
|
||||
#include "gv11b/regops_gv11b.h"
|
||||
|
||||
#include "gv11b/gv11b_gating_reglist.h"
|
||||
#include "gv100/regops_gv100.h"
|
||||
#include "gv11b/subctx_gv11b.h"
|
||||
|
||||
#include "gv100.h"
|
||||
#include "hal_gv100.h"
|
||||
#include "gv100/bios_gv100.h"
|
||||
#include "gv100/fb_gv100.h"
|
||||
#include "gv100/fifo_gv100.h"
|
||||
#include "gv100/flcn_gv100.h"
|
||||
#include "gv100/gr_ctx_gv100.h"
|
||||
#include "gv100/gr_gv100.h"
|
||||
#include "gv100/mc_gv100.h"
|
||||
#include "gv100/mm_gv100.h"
|
||||
#include "gv100/pmu_gv100.h"
|
||||
#include "gv100/nvlink_gv100.h"
|
||||
#include "gv100/regops_gv100.h"
|
||||
|
||||
#include <nvgpu/bus.h>
|
||||
#include <nvgpu/debug.h>
|
||||
@@ -651,7 +651,7 @@ static const struct gpu_ops gv100_ops = {
|
||||
.apply_smpc_war = gv100_apply_smpc_war,
|
||||
},
|
||||
.mc = {
|
||||
.intr_enable = mc_gv11b_intr_enable,
|
||||
.intr_enable = mc_gv100_intr_enable,
|
||||
.intr_unit_config = mc_gp10b_intr_unit_config,
|
||||
.isr_stall = mc_gp10b_isr_stall,
|
||||
.intr_stall = mc_gp10b_intr_stall,
|
||||
@@ -666,6 +666,9 @@ static const struct gpu_ops gv100_ops = {
|
||||
.boot_0 = gk20a_mc_boot_0,
|
||||
.is_intr1_pending = mc_gp10b_is_intr1_pending,
|
||||
.is_intr_hub_pending = gv11b_mc_is_intr_hub_pending,
|
||||
.is_intr_nvlink_pending = gv100_mc_is_intr_nvlink_pending,
|
||||
.is_stall_and_eng_intr_pending =
|
||||
gv100_mc_is_stall_and_eng_intr_pending,
|
||||
},
|
||||
.debug = {
|
||||
.show_dump = gk20a_debug_show_dump,
|
||||
@@ -712,11 +715,30 @@ static const struct gpu_ops gv100_ops = {
|
||||
.disable_shadow_rom = xve_disable_shadow_rom_gp106,
|
||||
},
|
||||
.falcon = {
|
||||
.falcon_hal_sw_init = gp106_falcon_hal_sw_init,
|
||||
.falcon_hal_sw_init = gv100_falcon_hal_sw_init,
|
||||
},
|
||||
.priv_ring = {
|
||||
.isr = gp10b_priv_ring_isr,
|
||||
},
|
||||
.nvlink = {
|
||||
.discover_ioctrl = gv100_nvlink_discover_ioctrl,
|
||||
.discover_link = gv100_nvlink_discover_link,
|
||||
.init = gv100_nvlink_init,
|
||||
.isr = gv100_nvlink_isr,
|
||||
/* API */
|
||||
.link_early_init = gv100_nvlink_link_early_init,
|
||||
.link_get_state = gv100_nvlink_link_get_state,
|
||||
.link_set_mode = gv100_nvlink_link_set_mode,
|
||||
.link_get_mode = gv100_nvlink_link_get_mode,
|
||||
.get_sublink_mode = gv100_nvlink_link_get_sublink_mode,
|
||||
.get_tx_sublink_state = gv100_nvlink_link_get_tx_sublink_state,
|
||||
.get_rx_sublink_state = gv100_nvlink_link_get_rx_sublink_state,
|
||||
.set_sublink_mode = gv100_nvlink_link_set_sublink_mode,
|
||||
.interface_init = gv100_nvlink_interface_init,
|
||||
.reg_init = gv100_nvlink_reg_init,
|
||||
.shutdown = gv100_nvlink_shutdown,
|
||||
.early_init = gv100_nvlink_early_init,
|
||||
},
|
||||
.chip_init_gpu_characteristics = gv100_init_gpu_characteristics,
|
||||
.get_litter_value = gv100_get_litter_value,
|
||||
};
|
||||
@@ -751,6 +773,7 @@ int gv100_init_hal(struct gk20a *g)
|
||||
gops->xve = gv100_ops.xve;
|
||||
gops->falcon = gv100_ops.falcon;
|
||||
gops->priv_ring = gv100_ops.priv_ring;
|
||||
gops->nvlink = gv100_ops.nvlink;
|
||||
|
||||
/* clocks */
|
||||
gops->clk.init_clk_support = gv100_ops.clk.init_clk_support;
|
||||
|
||||
94
drivers/gpu/nvgpu/gv100/mc_gv100.c
Normal file
94
drivers/gpu/nvgpu/gv100/mc_gv100.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* GV100 master
|
||||
*
|
||||
* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "gk20a/gk20a.h"
|
||||
|
||||
#include "gp10b/mc_gp10b.h"
|
||||
|
||||
#include "mc_gv100.h"
|
||||
#include "gv11b/fb_gv11b.h"
|
||||
|
||||
#include <nvgpu/hw/gv100/hw_mc_gv100.h>
|
||||
|
||||
void mc_gv100_intr_enable(struct gk20a *g)
|
||||
{
|
||||
u32 eng_intr_mask = gk20a_fifo_engine_interrupt_mask(g);
|
||||
|
||||
gk20a_writel(g, mc_intr_en_clear_r(NVGPU_MC_INTR_STALLING),
|
||||
0xffffffff);
|
||||
gk20a_writel(g, mc_intr_en_clear_r(NVGPU_MC_INTR_NONSTALLING),
|
||||
0xffffffff);
|
||||
gv11b_fb_disable_hub_intr(g, STALL_REG_INDEX, HUB_INTR_TYPE_ALL);
|
||||
|
||||
g->mc_intr_mask_restore[NVGPU_MC_INTR_STALLING] =
|
||||
mc_intr_pfifo_pending_f() |
|
||||
mc_intr_hub_pending_f() |
|
||||
mc_intr_priv_ring_pending_f() |
|
||||
mc_intr_pbus_pending_f() |
|
||||
mc_intr_ltc_pending_f() |
|
||||
mc_intr_nvlink_pending_f() |
|
||||
eng_intr_mask;
|
||||
|
||||
g->mc_intr_mask_restore[NVGPU_MC_INTR_NONSTALLING] =
|
||||
mc_intr_pfifo_pending_f()
|
||||
| eng_intr_mask;
|
||||
|
||||
/* TODO: Enable PRI faults for HUB ECC err intr */
|
||||
gv11b_fb_enable_hub_intr(g, STALL_REG_INDEX, g->mm.hub_intr_types);
|
||||
|
||||
gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_STALLING),
|
||||
g->mc_intr_mask_restore[NVGPU_MC_INTR_STALLING]);
|
||||
|
||||
gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_NONSTALLING),
|
||||
g->mc_intr_mask_restore[NVGPU_MC_INTR_NONSTALLING]);
|
||||
|
||||
}
|
||||
|
||||
bool gv100_mc_is_intr_nvlink_pending(struct gk20a *g, u32 mc_intr_0)
|
||||
{
|
||||
return ((mc_intr_0 & mc_intr_nvlink_pending_f()) ? true : false);
|
||||
}
|
||||
|
||||
bool gv100_mc_is_stall_and_eng_intr_pending(struct gk20a *g, u32 act_eng_id)
|
||||
{
|
||||
u32 mc_intr_0 = gk20a_readl(g, mc_intr_r(0));
|
||||
u32 stall_intr, eng_intr_mask;
|
||||
|
||||
eng_intr_mask = gk20a_fifo_act_eng_interrupt_mask(g, act_eng_id);
|
||||
if (mc_intr_0 & eng_intr_mask)
|
||||
return true;
|
||||
|
||||
stall_intr = mc_intr_pfifo_pending_f() |
|
||||
mc_intr_hub_pending_f() |
|
||||
mc_intr_priv_ring_pending_f() |
|
||||
mc_intr_pbus_pending_f() |
|
||||
mc_intr_ltc_pending_f() |
|
||||
mc_intr_nvlink_pending_f();
|
||||
if (mc_intr_0 & stall_intr)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
30
drivers/gpu/nvgpu/gv100/mc_gv100.h
Normal file
30
drivers/gpu/nvgpu/gv100/mc_gv100.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MC_GV100_H
|
||||
#define MC_GV100_H
|
||||
struct gk20a;
|
||||
|
||||
void mc_gv100_intr_enable(struct gk20a *g);
|
||||
bool gv100_mc_is_intr_nvlink_pending(struct gk20a *g, u32 mc_intr_0);
|
||||
bool gv100_mc_is_stall_and_eng_intr_pending(struct gk20a *g, u32 act_eng_id);
|
||||
#endif
|
||||
2654
drivers/gpu/nvgpu/gv100/nvlink_gv100.c
Normal file
2654
drivers/gpu/nvgpu/gv100/nvlink_gv100.c
Normal file
File diff suppressed because it is too large
Load Diff
60
drivers/gpu/nvgpu/gv100/nvlink_gv100.h
Normal file
60
drivers/gpu/nvgpu/gv100/nvlink_gv100.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef NVGPU_NVLINK_GV100_H
|
||||
#define NVGPU_NVLINK_GV100_H
|
||||
|
||||
struct gk20a;
|
||||
|
||||
#define MINION_REG_RD32(g, off) gk20a_readl(g, g->nvlink.minion_base + (off))
|
||||
#define MINION_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.minion_base + (off), (v))
|
||||
#define IOCTRL_REG_RD32(g, off) gk20a_readl(g, g->nvlink.ioctrl_base + (off))
|
||||
#define IOCTRL_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.ioctrl_base + (off), (v));
|
||||
#define MIF_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].mif_base + (off))
|
||||
#define MIF_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].mif_base + (off), (v))
|
||||
#define IPT_REG_RD32(g, off) gk20a_readl(g, g->nvlink.ipt_base + (off))
|
||||
#define IPT_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.ipt_base + (off), (v))
|
||||
#define TLC_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].tl_base + (off))
|
||||
#define TLC_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].tl_base + (off), (v))
|
||||
#define DLPL_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].dlpl_base + (off))
|
||||
#define DLPL_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].dlpl_base + (off), (v))
|
||||
|
||||
int gv100_nvlink_discover_ioctrl(struct gk20a *g);
|
||||
int gv100_nvlink_discover_link(struct gk20a *g);
|
||||
int gv100_nvlink_init(struct gk20a *g);
|
||||
int gv100_nvlink_isr(struct gk20a *g);
|
||||
/* API */
|
||||
int gv100_nvlink_link_early_init(struct gk20a *g, unsigned long mask);
|
||||
u32 gv100_nvlink_link_get_mode(struct gk20a *g, u32 link_id);
|
||||
u32 gv100_nvlink_link_get_state(struct gk20a *g, u32 link_id);
|
||||
int gv100_nvlink_link_set_mode(struct gk20a *g, u32 link_id, u32 mode);
|
||||
u32 gv100_nvlink_link_get_sublink_mode(struct gk20a *g, u32 link_id,
|
||||
bool is_rx_sublink);
|
||||
u32 gv100_nvlink_link_get_tx_sublink_state(struct gk20a *g, u32 link_id);
|
||||
u32 gv100_nvlink_link_get_rx_sublink_state(struct gk20a *g, u32 link_id);
|
||||
int gv100_nvlink_link_set_sublink_mode(struct gk20a *g, u32 link_id,
|
||||
bool is_rx_sublink, u32 mode);
|
||||
int gv100_nvlink_interface_init(struct gk20a *g);
|
||||
int gv100_nvlink_reg_init(struct gk20a *g);
|
||||
int gv100_nvlink_shutdown(struct gk20a *g);
|
||||
int gv100_nvlink_early_init(struct gk20a *g);
|
||||
#endif
|
||||
@@ -482,7 +482,7 @@ static int gv11b_fifo_poll_eng_ctx_status(struct gk20a *g, u32 id,
|
||||
eng_stat = gk20a_readl(g, fifo_engine_status_r(act_eng_id));
|
||||
ctx_stat = fifo_engine_status_ctx_status_v(eng_stat);
|
||||
|
||||
if (gv11b_mc_is_stall_and_eng_intr_pending(g, act_eng_id)) {
|
||||
if (g->ops.mc.is_stall_and_eng_intr_pending(g, act_eng_id)) {
|
||||
stall_intr = true;
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_intr,
|
||||
"stall intr set, "
|
||||
|
||||
@@ -658,6 +658,8 @@ static const struct gpu_ops gv11b_ops = {
|
||||
.boot_0 = gk20a_mc_boot_0,
|
||||
.is_intr1_pending = mc_gp10b_is_intr1_pending,
|
||||
.is_intr_hub_pending = gv11b_mc_is_intr_hub_pending,
|
||||
.is_stall_and_eng_intr_pending =
|
||||
gv11b_mc_is_stall_and_eng_intr_pending,
|
||||
},
|
||||
.debug = {
|
||||
.show_dump = gk20a_debug_show_dump,
|
||||
|
||||
@@ -892,6 +892,14 @@ static inline u32 minion_nvlink_link_intr_code_dlreq_f(void)
|
||||
{
|
||||
return 0x2U;
|
||||
}
|
||||
static inline u32 minion_nvlink_link_intr_code_pmdisabled_v(void)
|
||||
{
|
||||
return 0x00000003U;
|
||||
}
|
||||
static inline u32 minion_nvlink_link_intr_code_pmdisabled_f(void)
|
||||
{
|
||||
return 0x3U;
|
||||
}
|
||||
static inline u32 minion_nvlink_link_intr_subcode_f(u32 v)
|
||||
{
|
||||
return (v & 0xffU) << 8U;
|
||||
|
||||
@@ -182,11 +182,10 @@ struct nvgpu_nvlink_dev {
|
||||
u8 train_at_boot;
|
||||
u32 ac_coupling_mask;
|
||||
|
||||
u32 init_disabled_links;
|
||||
u32 connected_links;
|
||||
u32 initialized_links;
|
||||
u32 enabled_links;
|
||||
u32 topology_connected_links;
|
||||
u32 init_pll_done;
|
||||
|
||||
enum nvgpu_nvlink_speed speed;
|
||||
|
||||
@@ -195,12 +194,18 @@ struct nvgpu_nvlink_dev {
|
||||
u32 hshub_config1;
|
||||
u32 hshub_config2;
|
||||
u32 hshub_config6;
|
||||
|
||||
/* tlc cached errors */
|
||||
u32 tlc_rx_err_status_0[NVLINK_MAX_LINKS_SW];
|
||||
u32 tlc_rx_err_status_1[NVLINK_MAX_LINKS_SW];
|
||||
u32 tlc_tx_err_status_0[NVLINK_MAX_LINKS_SW];
|
||||
|
||||
/* priv struct */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
|
||||
u32 nvgpu_nvlink_enumerate(struct gk20a *g);
|
||||
u32 nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off);
|
||||
u32 nvgpu_nvlink_probe(struct gk20a *g);
|
||||
int nvgpu_nvlink_enumerate(struct gk20a *g);
|
||||
int nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off);
|
||||
int nvgpu_nvlink_probe(struct gk20a *g);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user