diff --git a/drivers/gpu/nvgpu/hal/init/hal_ga10b.c b/drivers/gpu/nvgpu/hal/init/hal_ga10b.c index 011dd032a..3884875fb 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_ga10b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_ga10b.c @@ -1678,6 +1678,7 @@ static const struct gops_grmgr ga10b_ops_grmgr = { #ifdef CONFIG_NVGPU_HAL_NON_FUSA static const struct gops_mssnvlink ga10b_ops_mssnvlink = { + .get_links = ga10b_mssnvlink_get_links, .init_soc_credits = ga10b_mssnvlink_init_soc_credits }; #endif diff --git a/drivers/gpu/nvgpu/hal/mssnvlink/mssnvlink_ga10b.c b/drivers/gpu/nvgpu/hal/mssnvlink/mssnvlink_ga10b.c index 5b7f79d80..c606aa7ae 100644 --- a/drivers/gpu/nvgpu/hal/mssnvlink/mssnvlink_ga10b.c +++ b/drivers/gpu/nvgpu/hal/mssnvlink/mssnvlink_ga10b.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "mssnvlink_ga10b.h" @@ -44,17 +46,30 @@ #define MSS_NVLINK_INIT_CREDITS 0x00000001U #define MSS_NVLINK_FORCE_COH_SNP 0x3U -void ga10b_mssnvlink_init_soc_credits(struct gk20a *g) +u32 ga10b_mssnvlink_get_links(struct gk20a *g, u32 **links) { - u32 i = 0U; - u32 val = MSS_NVLINK_INIT_CREDITS; - u32 nvlink_base[MSS_NVLINK_INTERNAL_NUM] = { MSS_NVLINK_1_BASE, MSS_NVLINK_2_BASE, MSS_NVLINK_3_BASE, MSS_NVLINK_4_BASE, MSS_NVLINK_5_BASE, MSS_NVLINK_6_BASE, MSS_NVLINK_7_BASE, MSS_NVLINK_8_BASE }; + *links = nvgpu_kzalloc(g, sizeof(nvlink_base)); + if (*links == NULL) { + return 0; + } + nvgpu_memcpy((u8 *)*links, (u8 *)nvlink_base, sizeof(nvlink_base)); + + return MSS_NVLINK_INTERNAL_NUM; +} + +void ga10b_mssnvlink_init_soc_credits(struct gk20a *g) +{ + u32 i = 0U; + u32 val = MSS_NVLINK_INIT_CREDITS; + u32 *nvlink_base; + u32 num_links; + uintptr_t mssnvlink_control[MSS_NVLINK_INTERNAL_NUM]; if (nvgpu_platform_is_simulation(g)) { @@ -68,15 +83,22 @@ void ga10b_mssnvlink_init_soc_credits(struct gk20a *g) "nvlink soc credits init done by bpmp on silicon"); return; } - /* init nvlink soc credits and force snoop */ - for (i = 0U; i < MSS_NVLINK_INTERNAL_NUM; i++) { + + num_links = g->ops.mssnvlink.get_links(g, &nvlink_base); + if (num_links == 0) { + nvgpu_err(g, "num_links = %d, skipping", num_links); + return; + } + + for (i = 0U; i < num_links; i++) { mssnvlink_control[i] = nvgpu_io_map(g, nvlink_base[i], MSS_NVLINK_SIZE); } + /* init nvlink soc credits */ nvgpu_log(g, gpu_dbg_info, "init nvlink soc credits"); - for (i = 0U; i < MSS_NVLINK_INTERNAL_NUM; i++) { + for (i = 0U; i < num_links; i++) { nvgpu_os_writel(val, (*(mssnvlink_control + i) + MSS_NVLINK_GLOBAL_CREDIT_CONTROL_0)); } @@ -87,7 +109,7 @@ void ga10b_mssnvlink_init_soc_credits(struct gk20a *g) */ nvgpu_log(g, gpu_dbg_info, "set force snoop"); - for (i = 0U; i < MSS_NVLINK_INTERNAL_NUM; i++) { + for (i = 0U; i < num_links; i++) { val = nvgpu_os_readl((*(mssnvlink_control + i) + MSS_NVLINK_MCF_MEMORY_TYPE_CONTROL_0)); val &= ~(MSS_NVLINK_FORCE_COH_SNP); @@ -95,4 +117,9 @@ void ga10b_mssnvlink_init_soc_credits(struct gk20a *g) nvgpu_os_writel(val, *(mssnvlink_control + i) + MSS_NVLINK_MCF_MEMORY_TYPE_CONTROL_0); } + + for (i = 0U; i < num_links; i++) { + nvgpu_io_unmap(g, mssnvlink_control[i], MSS_NVLINK_SIZE); + } + nvgpu_kfree(g, nvlink_base); } diff --git a/drivers/gpu/nvgpu/hal/mssnvlink/mssnvlink_ga10b.h b/drivers/gpu/nvgpu/hal/mssnvlink/mssnvlink_ga10b.h index 078e5655c..9617cb686 100644 --- a/drivers/gpu/nvgpu/hal/mssnvlink/mssnvlink_ga10b.h +++ b/drivers/gpu/nvgpu/hal/mssnvlink/mssnvlink_ga10b.h @@ -25,6 +25,7 @@ struct gk20a; +u32 ga10b_mssnvlink_get_links(struct gk20a *g, u32 **links); void ga10b_mssnvlink_init_soc_credits(struct gk20a *g); #endif /* NVGPU_MSSNVLINK_GA10B_H */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops/mssnvlink.h b/drivers/gpu/nvgpu/include/nvgpu/gops/mssnvlink.h index 997682259..5befdd35d 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops/mssnvlink.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops/mssnvlink.h @@ -38,6 +38,7 @@ struct gk20a; * @see gpu_ops */ struct gops_mssnvlink { + u32 (*get_links)(struct gk20a *g, u32 **links); void (*init_soc_credits)(struct gk20a *g); };