gpu: nvgpu: add ga10b & ga100 sources

Mass copy ga10b & ga100 sources from nvgpu-next repo.
TOP COMMIT-ID: 98f530e6924c844a1bf46816933a7fe015f3cce1

Jira NVGPU-4771

Change-Id: Ibf7102e9208133f8ef3bd3a98381138d5396d831
Signed-off-by: Sagar Kadamati <skadamati@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2524817
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com>
Reviewed-by: Debarshi Dutta <ddutta@nvidia.com>
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Reviewed-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Sagar Kadamati
2021-05-04 16:09:51 +05:30
committed by mobile promotions
parent 82734765d8
commit 3e43f92f21
326 changed files with 62836 additions and 0 deletions

180
arch/nvgpu-next-common.yaml Normal file
View File

@@ -0,0 +1,180 @@
#
# Copyright (c) 2020-2021, 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.
#
# Common elements and units in nvgpu.
#
##
## Common elements.
##
nvgpu_next_fifo:
safe: no
owner: Seshendra G
children:
engines:
safe: no
sources: [ include/nvgpu/nvgpu_next_engines.h,
common/fifo/nvgpu_next_engines.c ]
runlist:
safe: no
sources: [ include/nvgpu/nvgpu_next_runlist.h,
common/fifo/nvgpu_next_runlist.c ]
pbdma:
safe: no
sources: [ include/nvgpu/nvgpu_next_pbdma.h ]
fifo:
safe: no
sources: [ include/nvgpu/nvgpu_next_gops_fifo.h ]
nvgpu_next_sim:
safe: no
owner: Vedashree V
sources: [ include/nvgpu/nvgpu_next_sim.h,
common/sim/nvgpu_next_sim_netlist.c,
common/sim/nvgpu_next_sim.c ]
nvgpu_next_netlist:
safe: no
owner: Vedashree V
sources: [ include/nvgpu/nvgpu_next_gops_fifo.h,
include/nvgpu/nvgpu_next_netlist.h,
common/netlist/nvgpu_next_netlist_priv.h,
common/netlist/nvgpu_next_netlist.c ]
nvgpu_next_gr:
safe: no
owner: Vedashree V
sources: [ include/nvgpu/nvgpu_next_gops_gr.h,
include/nvgpu/gr/nvgpu_next_gr.h,
include/nvgpu/gr/nvgpu_next_fs_state.h,
include/nvgpu/gr/nvgpu_next_gr_ecc.h,
include/nvgpu/nvgpu_next_gops_gr_ctxsw_prog.h,
common/gr/nvgpu_next_fs_state.c,
common/gr/nvgpu_next_gr.c ]
nvgpu_next_bios:
safe: no
owner: Thomas F
sources: [ common/vbios/bios_sw_ga100.c,
common/vbios/bios_sw_ga100.h ]
nvgpu_next_device:
safe: yes
owner: Alex W
sources: [ include/nvgpu/nvgpu_next_device.h ]
nvgpu_next_ltc:
safe: no
owner: Antony
sources: [ include/nvgpu/nvgpu_next_gops_ltc.h,
include/nvgpu/nvgpu_next_gops_ltc_intr.h ]
nvgpu_next_ce:
safe: no
owner: Antony
sources: [ include/nvgpu/nvgpu_next_gops_ce.h ]
nvgpu_next_grmgr:
safe: no
owner: Lakshmanan M
sources: [ include/nvgpu/nvgpu_next_gops_grmgr.h ]
nvgpu_next_priv_ring:
safe: no
owner: Lakshmanan M
sources: [ include/nvgpu/nvgpu_next_gops_priv_ring.h ]
nvgpu_next_pmu_perfmon:
safe: no
owner: Ramesh M
sources: [ common/pmu/perfmon/pmu_perfmon_sw_ga10b.c,
common/pmu/perfmon/pmu_perfmon_sw_ga10b.h ]
nvgpu_next_mc:
safe: yes
owner: Antony Clince Alex
sources: [ common/mc/nvgpu_next_mc.c,
include/nvgpu/nvgpu_next_mc.h ]
nvgpu_next_cic:
safe: yes
owner: Tejal Kudav
sources: [ include/nvgpu/nvgpu_next_cic.h,
common/cic/nvgpu_next_cic.c ]
nvgpu_next_pmu_pg:
safe: no
owner: Ramesh M
sources: [ common/pmu/pg/pg_sw_ga10b.c,
common/pmu/pg/pg_sw_ga10b.h ]
nvgpu_next_err:
safe: yes
owner: Antony Clince Alex
sources: [ include/nvgpu/nvgpu_next_err.h ]
nvgpu_next_acr_fusa:
safe: no
owner: Deepak G
sources: [ common/acr/nvgpu_next_acr_bootstrap.c,
common/acr/nvgpu_next_acr_bootstrap.h,
include/nvgpu/riscv.h,
common/riscv/riscv.c ]
nvgpu_next_acr:
safe: no
owner: Deepak G
sources: [ common/acr/acr_sw_ga10b.c,
common/acr/acr_sw_ga10b.h,
common/acr/acr_sw_ga100.c,
common/acr/acr_sw_ga100.h ]
nvgpu_next_falcon:
safe: no
owner: Deepak G
sources: [ common/falcon/falcon_sw_ga10b.c,
common/falcon/falcon_sw_ga10b.h ]
nvgpu_next_litter:
safe: no
owner: Antony
sources: [ include/nvgpu/nvgpu_next_litter.h ]
nvgpu_next_profiler:
safe: no
owner: Antony
sources: [ common/profiler/nvgpu_next_profiler.h,
common/profiler/nvgpu_next_profiler.c ]
nvgpu_next_fb:
safe: no
owner: Vedashree V
sources: [ common/fb/nvgpu_next_fb.c ]
nvgpu_next_utils:
safe: no
owner: Vedashree V
sources: [ include/nvgpu/nvgpu_next_errata.h ]

View File

@@ -0,0 +1,98 @@
#
# Copyright (c) 2020-2021, 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.
#
# Define meta elements and units for describing GPU HW interactions in
# nvgpu.
#
nvgpu_next_headers:
safe: no
owner: Seshendra G
sources: [ include/nvgpu/hw/ga100/hw_bus_ga100.h,
include/nvgpu/hw/ga100/hw_ce_ga100.h,
include/nvgpu/hw/ga100/hw_ctrl_ga100.h,
include/nvgpu/hw/ga100/hw_ctxsw_prog_ga100.h,
include/nvgpu/hw/ga100/hw_falcon_ga100.h,
include/nvgpu/hw/ga100/hw_fb_ga100.h,
include/nvgpu/hw/ga100/hw_flush_ga100.h,
include/nvgpu/hw/ga100/hw_func_ga100.h,
include/nvgpu/hw/ga100/hw_fuse_ga100.h,
include/nvgpu/hw/ga100/hw_gc6_ga100.h,
include/nvgpu/hw/ga100/hw_gmmu_ga100.h,
include/nvgpu/hw/ga100/hw_gr_ga100.h,
include/nvgpu/hw/ga100/hw_ltc_ga100.h,
include/nvgpu/hw/ga100/hw_mc_ga100.h,
include/nvgpu/hw/ga100/hw_pbdma_ga100.h,
include/nvgpu/hw/ga100/hw_perf_ga100.h,
include/nvgpu/hw/ga100/hw_pgsp_ga100.h,
include/nvgpu/hw/ga100/hw_pram_ga100.h,
include/nvgpu/hw/ga100/hw_pri_fbp_ga100.h,
include/nvgpu/hw/ga100/hw_pri_gpc_ga100.h,
include/nvgpu/hw/ga100/hw_pri_ringmaster_ga100.h,
include/nvgpu/hw/ga100/hw_pri_ringstation_sys_ga100.h,
include/nvgpu/hw/ga100/hw_pri_sys_ga100.h,
include/nvgpu/hw/ga100/hw_proj_ga100.h,
include/nvgpu/hw/ga100/hw_psec_ga100.h,
include/nvgpu/hw/ga100/hw_pwr_ga100.h,
include/nvgpu/hw/ga100/hw_ram_ga100.h,
include/nvgpu/hw/ga100/hw_runlist_ga100.h,
include/nvgpu/hw/ga100/hw_smcarb_ga100.h,
include/nvgpu/hw/ga100/hw_timer_ga100.h,
include/nvgpu/hw/ga100/hw_top_ga100.h,
include/nvgpu/hw/ga100/hw_pnvdec_ga100.h,
include/nvgpu/hw/ga100/hw_therm_ga100.h,
include/nvgpu/hw/ga100/hw_trim_ga100.h,
include/nvgpu/hw/ga100/hw_xp_ga100.h,
include/nvgpu/hw/ga100/hw_xve_ga100.h,
include/nvgpu/hw/ga100/hw_fbpa_ga100.h,
include/nvgpu/hw/ga10b/hw_bus_ga10b.h,
include/nvgpu/hw/ga10b/hw_ccsr_ga10b.h,
include/nvgpu/hw/ga10b/hw_ce_ga10b.h,
include/nvgpu/hw/ga10b/hw_ctrl_ga10b.h,
include/nvgpu/hw/ga10b/hw_ctxsw_prog_ga10b.h,
include/nvgpu/hw/ga10b/hw_falcon_ga10b.h,
include/nvgpu/hw/ga10b/hw_fb_ga10b.h,
include/nvgpu/hw/ga10b/hw_flush_ga10b.h,
include/nvgpu/hw/ga10b/hw_func_ga10b.h,
include/nvgpu/hw/ga10b/hw_fuse_ga10b.h,
include/nvgpu/hw/ga10b/hw_gmmu_ga10b.h,
include/nvgpu/hw/ga10b/hw_gr_ga10b.h,
include/nvgpu/hw/ga10b/hw_ltc_ga10b.h,
include/nvgpu/hw/ga10b/hw_mc_ga10b.h,
include/nvgpu/hw/ga10b/hw_pbdma_ga10b.h,
include/nvgpu/hw/ga10b/hw_perf_ga10b.h,
include/nvgpu/hw/ga10b/hw_pgsp_ga10b.h,
include/nvgpu/hw/ga10b/hw_pram_ga10b.h,
include/nvgpu/hw/ga10b/hw_pri_fbp_ga10b.h,
include/nvgpu/hw/ga10b/hw_pri_gpc_ga10b.h,
include/nvgpu/hw/ga10b/hw_pri_ringmaster_ga10b.h,
include/nvgpu/hw/ga10b/hw_pri_ringstation_sys_ga10b.h,
include/nvgpu/hw/ga10b/hw_pri_sys_ga10b.h,
include/nvgpu/hw/ga10b/hw_proj_ga10b.h,
include/nvgpu/hw/ga10b/hw_priscv_ga10b.h,
include/nvgpu/hw/ga10b/hw_pwr_ga10b.h,
include/nvgpu/hw/ga10b/hw_ram_ga10b.h,
include/nvgpu/hw/ga10b/hw_runlist_ga10b.h,
include/nvgpu/hw/ga10b/hw_smcarb_ga10b.h,
include/nvgpu/hw/ga10b/hw_therm_ga10b.h,
include/nvgpu/hw/ga10b/hw_timer_ga10b.h,
include/nvgpu/hw/ga10b/hw_top_ga10b.h ]

View File

@@ -0,0 +1,30 @@
#
# Copyright (c) 2020-2021, 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.
#
# VGPU HAL units.
#
vgpu-next-init:
safe: no
owner: Aparna D
sources: [ hal/vgpu/init/vgpu_hal_ga10b.c,
hal/vgpu/init/vgpu_hal_ga10b.h ]

427
arch/nvgpu-next-hal.yaml Normal file
View File

@@ -0,0 +1,427 @@
#
# Copyright (c) 2020-2021, 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.
#
# HAL units. These are the units that have access to HW.
#
nvgpu_next_init:
safe: no
owner: Seshendra G
sources: [ hal/init/hal_ga100.c,
hal/init/hal_ga100.h,
hal/init/hal_ga10b.c,
hal/init/hal_ga10b.h,
hal/init/hal_ga100_litter.c,
hal/init/hal_ga100_litter.h,
hal/init/hal_ga10b_litter.c,
hal/init/hal_ga10b_litter.h ]
nvgpu_next_class:
safe: no
owner: Seshendra G
sources: [ hal/class/class_ga10b.h,
hal/class/class_ga10b.c,
hal/class/class_ga100.h,
hal/class/class_ga100.c,
include/nvgpu/nvgpu_next_class.h ]
nvgpu_next_top:
safe: no
owner: Seshendra G
sources: [ hal/top/top_ga10b.h,
hal/top/top_ga10b_fusa.c ]
nvgpu_next_fuse:
safe: no
owner: Seshendra G
sources: [ include/nvgpu/nvgpu_next_gops_fuse.h,
include/nvgpu/nvgpu_next_fuse.h,
hal/fuse/fuse_ga10b.h,
hal/fuse/fuse_ga100.h,
hal/fuse/fuse_ga10b.c,
hal/fuse/fuse_ga100.c ]
nvgpu_next_clk:
safe: no
sources: [ hal/clk/clk_ga100.c,
hal/clk/clk_ga100.h ]
nvgpu_next_fifo:
safe: no
owner: Seshendra G
children:
runlist:
safe: no
sources: [ include/nvgpu/nvgpu_next_gops_runlist.h,
hal/fifo/runlist_ga10b.h,
hal/fifo/runlist_ga10b_fusa.c ]
runlist_fusa:
safe: no
sources: [ hal/fifo/runlist_fifo_ga10b.h,
hal/fifo/runlist_fifo_ga10b.c,
hal/fifo/runlist_fifo_ga10b_fusa.c,
hal/fifo/runlist_fifo_ga100.h,
hal/fifo/runlist_fifo_ga100_fusa.c ]
fifo_fusa:
safe: no
sources: [ hal/fifo/fifo_ga10b_fusa.c,
hal/fifo/fifo_intr_ga10b_fusa.c,
hal/fifo/ctxsw_timeout_ga10b_fusa.c,
hal/fifo/ctxsw_timeout_ga10b.h,
hal/fifo/fifo_intr_ga10b.h,
hal/fifo/fifo_ga10b.h ]
channel_fusa:
safe: no
sources: [ hal/fifo/channel_ga10b_fusa.c,
hal/fifo/channel_ga10b.h,
hal/fifo/channel_ga100_fusa.c,
hal/fifo/channel_ga100.h ]
tsg:
safe: no
sources: [ hal/fifo/tsg_ga10b.h,
hal/fifo/tsg_ga10b.c ]
engine_status_fusa:
safe: no
sources: [ include/nvgpu/nvgpu_next_engine_status.h,
hal/fifo/engine_status_ga10b_fusa.c,
hal/fifo/engine_status_ga10b.h ]
ramfc_fusa:
safe: no
sources: [ hal/fifo/ramfc_ga10b_fusa.c,
hal/fifo/ramfc_ga10b.h ]
pbdma_status_fusa:
safe: no
sources: [ hal/fifo/pbdma_status_ga10b_fusa.c,
hal/fifo/pbdma_status_ga10b.h ]
pbdma_fusa:
safe: no
sources: [ hal/fifo/pbdma_ga10b_fusa.c,
hal/fifo/pbdma_ga10b.h,
hal/fifo/pbdma_ga100_fusa.c,
hal/fifo/pbdma_ga100.h,
include/nvgpu/nvgpu_next_gops_pbdma.h ]
preempt_fusa:
safe: no
sources: [ hal/fifo/preempt_ga10b_fusa.c,
hal/fifo/preempt_ga10b.h ]
pbdma:
safe: no
sources: [ hal/fifo/pbdma_ga10b.c ]
ramin_fusa:
safe: no
sources: [ hal/fifo/ramin_ga10b_fusa.c,
hal/fifo/ramin_ga10b.h ]
usermode_fusa:
safe: no
sources: [ hal/fifo/usermode_ga10b_fusa.c,
hal/fifo/usermode_ga10b.h ]
userd:
safe: no
sources: [ hal/fifo/userd_ga10b.c,
hal/fifo/userd_ga10b.h ]
utils_fusa:
safe: no
sources: [ hal/fifo/fifo_utils_ga10b_fusa.c,
hal/fifo/fifo_utils_ga10b.h ]
nvgpu_next_mm:
safe: no
owner: Seema K
children:
mm:
safe: no
sources: [ include/nvgpu/nvgpu_next_mm.h ]
mmu_fault:
safe: no
sources: [ hal/mm/mmu_fault/mmu_fault_ga10b_fusa.c,
hal/mm/mmu_fault/mmu_fault_ga10b.h ]
gmmu_fusa:
safe: no
sources: [ hal/mm/gmmu/gmmu_ga10b_fusa.c,
hal/mm/gmmu/gmmu_ga10b.h ]
nvgpu_next_gr:
safe: no
owner: Seema K
children:
ctxsw_prog_fusa:
safe: no
sources: [ hal/gr/ctxsw_prog/ctxsw_prog_ga10b_fusa.c,
hal/gr/ctxsw_prog/ctxsw_prog_ga10b.h,
hal/gr/ctxsw_prog/ctxsw_prog_ga100_fusa.c,
hal/gr/ctxsw_prog/ctxsw_prog_ga100.h]
ctxsw_prog:
safe: no
sources: [ hal/gr/ctxsw_prog/ctxsw_prog_ga10b.c,
hal/gr/ctxsw_prog/ctxsw_prog_ga10b_dbg.c,
hal/gr/ctxsw_prog/ctxsw_prog_ga100.c,
hal/gr/ctxsw_prog/ctxsw_prog_ga100_dbg.c ]
init_fusa:
safe: no
sources: [ include/nvgpu/nvgpu_next_gops_gr_init.h,
hal/gr/init/gr_init_ga10b_fusa.c,
hal/gr/init/gr_init_ga100_fusa.c,
hal/gr/init/gr_init_ga100.h,
hal/gr/init/gr_init_ga10b.h ]
init:
safe: no
sources: [ hal/gr/init/gr_init_ga10b.c,
hal/gr/init/gr_init_ga10b.h,
hal/gr/init/gr_init_ga100.c,
hal/gr/init/gr_init_ga100.h ]
intr_fusa:
safe: no
sources: [ include/nvgpu/nvgpu_next_gops_gr_intr.h,
hal/gr/intr/gr_intr_ga10b_fusa.c,
hal/gr/intr/gr_intr_ga10b.h,
hal/gr/intr/gr_intr_ga100_fusa.c,
hal/gr/intr/gr_intr_ga100.h ]
gr:
safe: no
sources: [ hal/gr/gr/gr_ga10b.c,
hal/gr/gr/gr_ga10b.h,
hal/gr/gr/gr_ga100.c,
hal/gr/gr/gr_ga100.h,
hal/gr/gr/gr_pri_ga10b.h ]
falcon_fusa:
safe: no
sources: [ hal/gr/falcon/gr_falcon_ga10b_fusa.c,
hal/gr/falcon/gr_falcon_ga10b.h ]
falcon:
safe: no
sources: [ hal/gr/falcon/gr_falcon_ga10b.c,
hal/gr/falcon/gr_falcon_ga100.c,
hal/gr/falcon/gr_falcon_ga100.h ]
zbc:
safe: no
sources: [ hal/gr/zbc/zbc_ga10b.c,
hal/gr/zbc/zbc_ga10b.h ]
ecc_fusa:
safe: no
sources: [ hal/gr/ecc/ecc_ga10b_fusa.c,
hal/gr/ecc/ecc_ga10b.h ]
ecc:
safe: no
sources: [ hal/gr/ecc/ecc_ga10b.c ,
hal/gr/ecc/ecc_ga10b.h ]
nvgpu_next_ltc:
safe: no
owner: Vedashree V
children:
ltc:
safe: no
sources: [ hal/ltc/ltc_ga10b.c ]
ltc_fusa:
safe: no
sources: [ hal/ltc/ltc_ga10b.h,
hal/ltc/ltc_ga10b_fusa.c ]
ltc_intr:
safe: no
sources: [ hal/ltc/intr/ltc_intr_ga10b.h,
hal/ltc/intr/ltc_intr_ga10b_fusa.c ]
nvgpu_next_mc_fusa:
safe: no
owner: Seema K
sources: [ hal/mc/mc_intr_ga10b_fusa.c,
include/nvgpu/nvgpu_next_mc.h,
hal/mc/mc_intr_ga10b.h,
include/nvgpu/nvgpu_next_gops_mc.h,
hal/mc/mc_ga10b_fusa.c,
hal/mc/mc_ga10b.h ]
nvgpu_next_cbc:
safe: no
owner: Vedashree V
sources: [ hal/cbc/cbc_ga10b.c,
hal/cbc/cbc_ga10b.h,
hal/cbc/cbc_ga100.c,
hal/cbc/cbc_ga100.h ]
nvgpu_next_fb:
safe: no
owner: Vedashree V
sources: [ hal/fb/fb_ga10b.c,
hal/fb/fb_ga100.h,
hal/fb/fb_ga100.c,
hal/fb/vab/vab_ga10b.c,
hal/fb/vab/vab_ga10b.h,
include/nvgpu/nvgpu_next_fb.h,
include/nvgpu/nvgpu_next_gops_fb_vab.h ]
nvgpu_next_fb_fusa:
safe: no
owner: Seshendra G
sources: [ include/nvgpu/nvgpu_next_ecc.h,
hal/fb/fb_ga10b.h,
hal/fb/fb_ga10b_fusa.c,
include/nvgpu/nvgpu_next_gops_fb.h,
hal/fb/ecc/fb_ecc_ga10b.h,
hal/fb/ecc/fb_ecc_ga10b_fusa.c,
hal/fb/intr/fb_intr_ga10b.h,
hal/fb/intr/fb_intr_ga10b_fusa.c,
hal/fb/fb_mmu_fault_ga10b.h,
hal/fb/fb_mmu_fault_ga10b_fusa.c,
hal/fb/intr/fb_intr_ecc_ga10b.h,
hal/fb/intr/fb_intr_ecc_ga10b_fusa.c ]
nvgpu_next_netlist:
safe: no
owner: Seshendra G
sources: [ hal/netlist/netlist_ga10b_fusa.c,
hal/netlist/netlist_ga10b.h,
hal/netlist/netlist_ga100.c,
hal/netlist/netlist_ga100.h ]
nvgpu_next_bus:
safe: no
owner: Seshendra G
sources: [ hal/bus/bus_ga10b.c,
hal/bus/bus_ga10b.h,
hal/bus/bus_ga100.c,
hal/bus/bus_ga100.h ]
nvgpu_next_regops:
safe: no
owner: Seshendra G
sources: [ hal/regops/regops_ga10b.c,
hal/regops/regops_ga100.c,
hal/regops/regops_ga10b.h,
hal/regops/regops_ga100.h,
hal/regops/allowlist_ga10b.c,
hal/regops/allowlist_ga10b.h,
hal/regops/allowlist_ga100.c,
hal/regops/allowlist_ga100.h ]
nvgpu_next_falcon_fusa:
safe: no
owner: Divya S
sources: [ hal/falcon/falcon_ga10b_fusa.c,
hal/falcon/falcon_ga10b.h ]
nvgpu_next_pmu:
safe: no
owner: Mahantesh K
sources: [ hal/pmu/pmu_ga10b.h,
hal/pmu/pmu_ga10b.c,
hal/pmu/pmu_ga100.h,
hal/pmu/pmu_ga100.c ]
nvgpu_next_gsp:
safe: no
owner: Deepak G
sources: [ hal/gsp/gsp_ga10b.h,
hal/gsp/gsp_ga10b.c ]
nvgpu_next_priv_ring_fusa:
safe: no
owner: Seema K
sources: [ hal/priv_ring/priv_ring_ga10b_fusa.c,
hal/priv_ring/priv_ring_ga10b.h,
hal/priv_ring/priv_ring_ga100_fusa.c,
hal/priv_ring/priv_ring_ga100.h ]
nvgpu_next_ptimer_fusa:
safe: no
owner: Seema K
sources: [ hal/ptimer/ptimer_ga10b_fusa.c,
hal/ptimer/ptimer_ga10b.h ]
nvgpu_next_perf:
safe: no
owner: Seshendra G
sources: [ hal/perf/perf_ga10b.c,
hal/perf/perf_ga10b.h,
hal/perf/perf_ga100.c,
hal/perf/perf_ga100.h,
include/nvgpu/nvgpu_next_gops_perf.h ]
nvgpu_next_cg:
safe: no
owner: Antony
sources: [ include/nvgpu/nvgpu_next_gops_cg.h,
hal/power_features/cg/ga10b_gating_reglist.c,
hal/power_features/cg/ga10b_gating_reglist.h,
hal/power_features/cg/ga100_gating_reglist.c,
hal/power_features/cg/ga100_gating_reglist.h ]
nvgpu_next_therm_fusa:
safe: no
owner: Antony
sources: [ hal/therm/therm_ga10b_fusa.c,
hal/therm/therm_ga10b.h ]
nvgpu_next_ce_fusa:
safe: no
owner: Antony
sources: [ hal/ce/ce_ga10b_fusa.c,
hal/ce/ce_ga10b.h ]
nvgpu_next_misc:
safe: no
owner: Vedashree V
sources: [ nvgpu_next_gpuid.h ]
nvgpu_next_nvdec:
safe: no
owner: Mahantesh K
sources: [ hal/nvdec/nvdec_ga100.c,
hal/nvdec/nvdec_ga100.h ]
nvgpu_next_grmgr:
safe: no
owner: Lakshmanan M
sources: [ hal/grmgr/grmgr_ga10b.c,
hal/grmgr/grmgr_ga10b.h,
hal/grmgr/grmgr_ga100.c,
hal/grmgr/grmgr_ga100.h,]
nvgpu_next_func:
safe: no
owner: Vedashree V
sources: [ hal/func/func_ga10b.c,
hal/func/func_ga10b.h ]

View File

@@ -0,0 +1,41 @@
#
# Copyright (c) 2020-2021, 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.
#
# Linux elements and units in nvgpu.
#
# The safe: tag is ommited through out since all Linux units are by definition
# not safe.
#
# I also have not put a huge amount of thought into this since none of this
# code is "safe" code. Nor are we planning on spending a lot of effort to
# clean this up. At least not yet.
nvgpu_next_platform:
sources: [ os/linux/platform_ga10b_tegra.c,
os/linux/nvlink/hal/ga10b_mssnvlink.c ]
vgpu-next:
sources: [ os/linux/vgpu/ga10b/platform_ga10b_vgpu_tegra.c ]
nvgpu_next_ioctl:
sources: [ os/linux/nvgpu_next_ioctl_prof.c,
os/linux/nvgpu_next_ioctl_prof.h ]

View File

@@ -786,3 +786,157 @@ ifeq ($(CONFIG_NVGPU_GR_VIRTUALIZATION),y)
nvgpu-$(CONFIG_NVGPU_HAL_NON_FUSA) += \ nvgpu-$(CONFIG_NVGPU_HAL_NON_FUSA) += \
hal/vgpu/init/vgpu_hal_gv11b.o hal/vgpu/init/vgpu_hal_gv11b.o
endif endif
ifeq ($(CONFIG_ARCH_TEGRA_23x_SOC),y)
CONFIG_NVGPU_NEXT := y
ccflags-y += -DCONFIG_NVGPU_NEXT
# Multi Instance GPU support
CONFIG_NVGPU_MIG := y
endif
ifeq ($(CONFIG_NVGPU_NEXT),y)
ifeq ($(CONFIG_NVGPU_HAL_NON_FUSA),y)
nvgpu-y += \
common/fifo/nvgpu_next_engines.o \
common/fifo/nvgpu_next_runlist.o \
common/acr/nvgpu_next_acr_bootstrap.o \
common/falcon/falcon_sw_ga10b.o \
common/fb/nvgpu_next_fb.o \
common/riscv/riscv.o \
common/acr/acr_sw_ga10b.o \
common/acr/acr_sw_ga100.o \
common/sim/nvgpu_next_sim.o \
common/gr/nvgpu_next_gr.o \
common/gr/nvgpu_next_fs_state.o \
common/netlist/nvgpu_next_netlist.o \
common/sim/nvgpu_next_sim_netlist.o \
common/pmu/perfmon/pmu_perfmon_sw_ga10b.o \
common/cic/nvgpu_next_cic.o \
common/pmu/pg/pg_sw_ga10b.o \
common/profiler/nvgpu_next_profiler.o
nvgpu-y += \
hal/init/hal_ga10b.o \
hal/init/hal_ga10b_litter.o \
hal/gr/zbc/zbc_ga10b.o \
hal/class/class_ga10b.o \
hal/class/class_ga100.o \
hal/mc/mc_ga10b_fusa.o \
hal/mc/mc_intr_ga10b_fusa.o \
hal/mm/mmu_fault/mmu_fault_ga10b_fusa.o \
hal/mm/gmmu/gmmu_ga10b_fusa.o \
hal/func/func_ga10b.o \
hal/fuse/fuse_ga10b.o \
hal/falcon/falcon_ga10b_fusa.o \
hal/fifo/usermode_ga10b_fusa.o \
hal/fifo/fifo_intr_ga10b_fusa.o \
hal/fifo/ctxsw_timeout_ga10b_fusa.o \
hal/fifo/fifo_ga10b_fusa.o \
hal/fifo/pbdma_ga10b_fusa.o \
hal/fifo/pbdma_ga10b.o \
hal/fifo/usermode_ga10b_fusa.o \
hal/fifo/fifo_utils_ga10b_fusa.o \
hal/fifo/engine_status_ga10b_fusa.o \
hal/fifo/pbdma_status_ga10b_fusa.o \
hal/fifo/preempt_ga10b_fusa.o \
hal/fifo/runlist_fifo_ga10b_fusa.o \
hal/fifo/runlist_fifo_ga10b.o \
hal/fifo/tsg_ga10b.o \
hal/fifo/userd_ga10b.o \
hal/fifo/ramin_ga10b_fusa.o \
hal/fifo/ramfc_ga10b_fusa.o \
hal/fifo/runlist_ga10b_fusa.o \
hal/gr/ctxsw_prog/ctxsw_prog_ga10b.o \
hal/gr/ctxsw_prog/ctxsw_prog_ga10b_dbg.o \
hal/gr/ctxsw_prog/ctxsw_prog_ga10b_fusa.o \
hal/gr/ctxsw_prog/ctxsw_prog_ga100.o \
hal/gr/ctxsw_prog/ctxsw_prog_ga100_dbg.o \
hal/gr/ctxsw_prog/ctxsw_prog_ga100_fusa.o \
hal/gr/gr/gr_ga10b.o \
hal/gr/init/gr_init_ga10b.o \
hal/gr/init/gr_init_ga10b_fusa.o \
hal/gr/intr/gr_intr_ga10b_fusa.o \
hal/gr/falcon/gr_falcon_ga10b_fusa.o \
hal/gr/falcon/gr_falcon_ga10b.o \
hal/gr/ecc/ecc_ga10b.o \
hal/gr/ecc/ecc_ga10b_fusa.o \
hal/netlist/netlist_ga10b_fusa.o \
hal/fifo/channel_ga10b_fusa.o \
hal/ltc/ltc_ga10b_fusa.o \
hal/ltc/ltc_ga10b.o \
hal/ltc/intr/ltc_intr_ga10b_fusa.o \
hal/top/top_ga10b_fusa.o \
hal/bus/bus_ga10b.o \
hal/pmu/pmu_ga10b.o \
hal/gsp/gsp_ga10b.o \
hal/fb/fb_ga100.o \
hal/fb/fb_ga10b.o \
hal/fb/fb_ga10b_fusa.o \
hal/fb/fb_mmu_fault_ga10b_fusa.o \
hal/fb/ecc/fb_ecc_ga10b_fusa.o \
hal/fb/intr/fb_intr_ga10b_fusa.o \
hal/fb/intr/fb_intr_ecc_ga10b_fusa.o \
hal/fb/vab/vab_ga10b.o \
hal/priv_ring/priv_ring_ga10b_fusa.o \
hal/ptimer/ptimer_ga10b_fusa.o \
hal/perf/perf_ga10b.o \
hal/regops/regops_ga10b.o \
hal/regops/allowlist_ga10b.o \
hal/power_features/cg/ga10b_gating_reglist.o \
hal/therm/therm_ga10b_fusa.o \
hal/ce/ce_ga10b_fusa.o \
hal/grmgr/grmgr_ga10b.o
ifeq ($(CONFIG_NVGPU_COMPRESSION),y)
nvgpu-y += \
hal/cbc/cbc_ga100.o \
hal/cbc/cbc_ga10b.o
endif
nvgpu-$(CONFIG_NVGPU_GR_VIRTUALIZATION) += \
hal/vgpu/init/vgpu_hal_ga10b.o \
os/linux/vgpu/ga10b/platform_ga10b_vgpu_tegra.o
endif
ifeq ($(CONFIG_NVGPU_DGPU),y)
nvgpu-y += \
hal/init/hal_ga100.o \
hal/init/hal_ga100_litter.o \
hal/gr/gr/gr_ga100.o \
hal/bus/bus_ga100.o \
hal/fuse/fuse_ga100.o \
hal/gr/intr/gr_intr_ga100_fusa.o \
hal/gr/init/gr_init_ga100_fusa.o \
hal/gr/init/gr_init_ga100.o \
hal/gr/falcon/gr_falcon_ga100.o \
hal/clk/clk_ga100.o \
hal/nvdec/nvdec_ga100.o \
hal/pmu/pmu_ga100.o \
hal/perf/perf_ga100.o \
hal/fb/fb_ga100.o \
hal/fifo/channel_ga100_fusa.o \
hal/fifo/pbdma_ga100_fusa.o \
hal/fifo/runlist_fifo_ga100_fusa.o \
hal/netlist/netlist_ga100.o \
common/vbios/bios_sw_ga100.o \
hal/power_features/cg/ga100_gating_reglist.o \
hal/priv_ring/priv_ring_ga100_fusa.o \
hal/regops/regops_ga100.o \
hal/regops/allowlist_ga100.o
endif
ifeq ($(CONFIG_NVGPU_MIG),y)
ccflags-y += -DCONFIG_NVGPU_MIG
ifeq ($(CONFIG_NVGPU_DGPU),y)
nvgpu-y += \
hal/grmgr/grmgr_ga100.o
endif
endif
nvgpu-y += \
os/linux/platform_ga10b_tegra.o \
os/linux/nvgpu_next_ioctl_prof.o \
os/linux/nvlink/hal/ga10b_mssnvlink.o
endif

View File

@@ -709,3 +709,142 @@ endif
ifeq ($(CONFIG_NVGPU_TPC_POWERGATE),1) ifeq ($(CONFIG_NVGPU_TPC_POWERGATE),1)
srcs += hal/tpc/tpc_gv11b.c srcs += hal/tpc/tpc_gv11b.c
endif endif
ifeq ($(CONFIG_NVGPU_NEXT),1)
ifeq ($(CONFIG_NVGPU_HAL_NON_FUSA),1)
srcs += \
common/fifo/nvgpu_next_engines.c \
common/acr/nvgpu_next_acr_bootstrap.c \
common/riscv/riscv.c \
common/acr/acr_sw_ga10b.c \
common/acr/acr_sw_ga100.c \
common/fb/nvgpu_next_fb.c \
common/fifo/nvgpu_next_runlist.c \
common/gr/nvgpu_next_gr.c \
common/gr/nvgpu_next_fs_state.c \
common/netlist/nvgpu_next_netlist.c \
common/sim/nvgpu_next_sim.c \
common/sim/nvgpu_next_sim_netlist.c \
common/pmu/perfmon/pmu_perfmon_sw_ga10b.c \
common/cic/nvgpu_next_cic.c \
common/pmu/pg/pg_sw_ga10b.c \
common/falcon/falcon_sw_ga10b.c \
common/profiler/nvgpu_next_profiler.c
srcs += hal/init/hal_ga10b.c \
hal/init/hal_ga10b_litter.c \
hal/gr/zbc/zbc_ga10b.c \
hal/class/class_ga10b.c \
hal/class/class_ga100.c \
hal/mc/mc_ga10b_fusa.c \
hal/mc/mc_intr_ga10b_fusa.c \
hal/mm/mmu_fault/mmu_fault_ga10b_fusa.c \
hal/mm/gmmu/gmmu_ga10b_fusa.c \
hal/func/func_ga10b.c \
hal/fuse/fuse_ga10b.c \
hal/falcon/falcon_ga10b_fusa.c \
hal/fifo/usermode_ga10b_fusa.c \
hal/fifo/fifo_intr_ga10b_fusa.c \
hal/fifo/ctxsw_timeout_ga10b_fusa.c \
hal/fifo/fifo_utils_ga10b_fusa.c \
hal/fifo/fifo_ga10b_fusa.c \
hal/fifo/pbdma_ga10b_fusa.c \
hal/fifo/pbdma_ga10b.c \
hal/fifo/engine_status_ga10b_fusa.c \
hal/fifo/pbdma_status_ga10b_fusa.c \
hal/fifo/preempt_ga10b_fusa.c \
hal/fifo/runlist_fifo_ga10b_fusa.c \
hal/fifo/runlist_fifo_ga10b.c \
hal/fifo/runlist_ga10b_fusa.c \
hal/fifo/tsg_ga10b.c \
hal/fifo/userd_ga10b.c \
hal/fifo/ramin_ga10b_fusa.c \
hal/fifo/ramfc_ga10b_fusa.c \
hal/gr/ctxsw_prog/ctxsw_prog_ga10b.c \
hal/gr/ctxsw_prog/ctxsw_prog_ga10b_dbg.c \
hal/gr/ctxsw_prog/ctxsw_prog_ga10b_fusa.c \
hal/gr/ctxsw_prog/ctxsw_prog_ga100.c \
hal/gr/ctxsw_prog/ctxsw_prog_ga100_dbg.c \
hal/gr/ctxsw_prog/ctxsw_prog_ga100_fusa.c \
hal/gr/gr/gr_ga10b.c \
hal/gr/init/gr_init_ga10b.c \
hal/gr/init/gr_init_ga10b_fusa.c \
hal/gr/intr/gr_intr_ga10b_fusa.c \
hal/gr/falcon/gr_falcon_ga10b_fusa.c \
hal/gr/falcon/gr_falcon_ga10b.c \
hal/gr/ecc/ecc_ga10b.c \
hal/gr/ecc/ecc_ga10b_fusa.c \
hal/netlist/netlist_ga10b_fusa.c \
hal/fifo/channel_ga10b_fusa.c \
hal/ltc/ltc_ga10b_fusa.c \
hal/ltc/ltc_ga10b.c \
hal/ltc/intr/ltc_intr_ga10b_fusa.c \
hal/top/top_ga10b_fusa.c \
hal/bus/bus_ga10b.c \
hal/pmu/pmu_ga10b.c \
hal/gsp/gsp_ga10b.c \
hal/fb/fb_ga10b.c \
hal/fb/fb_mmu_fault_ga10b_fusa.c \
hal/fb/fb_ga10b_fusa.c \
hal/fb/ecc/fb_ecc_ga10b_fusa.c \
hal/fb/intr/fb_intr_ga10b_fusa.c \
hal/fb/intr/fb_intr_ecc_ga10b_fusa.c \
hal/fb/vab/vab_ga10b.c \
hal/priv_ring/priv_ring_ga10b_fusa.c \
hal/ptimer/ptimer_ga10b_fusa.c \
hal/perf/perf_ga10b.c \
hal/regops/regops_ga10b.c \
hal/regops/allowlist_ga10b.c \
hal/power_features/cg/ga10b_gating_reglist.c \
hal/therm/therm_ga10b_fusa.c \
hal/ce/ce_ga10b_fusa.c \
hal/grmgr/grmgr_ga10b.c
ifeq ($(CONFIG_NVGPU_COMPRESSION),1)
srcs += \
hal/cbc/cbc_ga100.c \
hal/cbc/cbc_ga10b.c
endif
endif
ifeq ($(CONFIG_NVGPU_IGPU_VIRT),1)
srcs += \
hal/vgpu/init/vgpu_hal_ga10b.c
endif
ifeq ($(CONFIG_NVGPU_DGPU),1)
srcs += \
hal/init/hal_ga100.c \
hal/init/hal_ga100_litter.c \
hal/gr/gr/gr_ga100.c \
hal/bus/bus_ga100.c \
hal/fuse/fuse_ga100.c \
hal/gr/intr/gr_intr_ga100_fusa.c \
hal/gr/init/gr_init_ga100_fusa.c \
hal/gr/init/gr_init_ga100.c \
hal/gr/falcon/gr_falcon_ga100.c \
hal/clk/clk_ga100.c \
hal/nvdec/nvdec_ga100.c \
hal/pmu/pmu_ga100.c \
hal/perf/perf_ga100.c \
hal/fb/fb_ga100.c \
hal/fifo/channel_ga100_fusa.c \
hal/fifo/pbdma_ga100_fusa.c \
hal/fifo/runlist_fifo_ga100_fusa.c \
hal/netlist/netlist_ga100.c \
common/vbios/bios_sw_ga100.c \
hal/power_features/cg/ga100_gating_reglist.c \
hal/priv_ring/priv_ring_ga100_fusa.c \
hal/regops/regops_ga100.c \
hal/regops/allowlist_ga100.c
endif
ifeq ($(CONFIG_NVGPU_MIG),1)
ifeq ($(CONFIG_NVGPU_DGPU),1)
srcs += \
hal/grmgr/grmgr_ga100.c
endif
endif
endif

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2020, 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/gk20a.h>
#include <nvgpu/falcon.h>
#include "common/acr/acr_priv.h"
#include "common/acr/acr_sw_tu104.h"
#include "acr_sw_ga100.h"
static u32* ga100_get_versioned_sig(struct gk20a *g, struct nvgpu_acr *acr,
u32 *sig, u32 *sig_size)
{
u32 ucode_version = 0U;
u32 sig_size_words = 0U;
u32 sig_idx = 0;
nvgpu_log_fn(g, " ");
g->ops.fuse.read_ucode_version(g, FALCON_ID_SEC2, &ucode_version);
*sig_size = *sig_size/acr->num_of_sig;
sig_idx = (!ucode_version) ? 1U : 0U;
sig_size_words = *sig_size/4U;
sig = sig + nvgpu_safe_mult_u32(sig_idx, sig_size_words);
return sig;
}
void nvgpu_next_dgpu_acr_sw_init(struct gk20a *g, struct nvgpu_acr *acr)
{
nvgpu_log_fn(g, " ");
acr->num_of_sig = 2U;
nvgpu_tu104_acr_sw_init(g, acr);
acr->get_versioned_sig = ga100_get_versioned_sig;
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2020, 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 ACR_SW_GA100_H
#define ACR_SW_GA100_H
struct gk20a;
struct nvgpu_acr;
void nvgpu_next_dgpu_acr_sw_init(struct gk20a *g, struct nvgpu_acr *acr);
#endif /*ACR_SW_GA100_H*/

View File

@@ -0,0 +1,343 @@
/*
* Copyright (c) 2020-2021, 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/types.h>
#include <nvgpu/firmware.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/bug.h>
#include <nvgpu/dma.h>
#include <nvgpu/pmu.h>
#ifdef CONFIG_NVGPU_LS_PMU
#include <nvgpu/pmu/fw.h>
#endif
#include "common/acr/acr_wpr.h"
#include "common/acr/acr_priv.h"
#include "common/acr/acr_blob_alloc.h"
#include "common/acr/acr_blob_construct.h"
#include "common/acr/acr_bootstrap.h"
#include "common/acr/acr_sw_gv11b.h"
#include "acr_sw_ga10b.h"
#define RECOVERY_UCODE_BLOB_SIZE (0U)
#define WPR_OFFSET (0U)
#define GSPDBG_RISCV_ACR_FW_MANIFEST "acr-gsp.manifest.encrypt.bin.out.bin"
#define GSPDBG_RISCV_ACR_FW_CODE "acr-gsp.text.encrypt.bin"
#define GSPDBG_RISCV_ACR_FW_DATA "acr-gsp.data.encrypt.bin"
#define GSPPROD_RISCV_ACR_FW_MANIFEST "acr-gsp.manifest.encrypt.bin.out.bin.prod"
#define GSPPROD_RISCV_ACR_FW_CODE "acr-gsp.text.encrypt.bin.prod"
#define GSPPROD_RISCV_ACR_FW_DATA "acr-gsp.data.encrypt.bin.prod"
static int ga10b_bootstrap_hs_acr(struct gk20a *g, struct nvgpu_acr *acr)
{
int err = 0;
nvgpu_log_fn(g, " ");
err = nvgpu_acr_bootstrap_hs_ucode_riscv(g, g->acr);
if (err != 0) {
nvgpu_err(g, "ACR bootstrap failed");
}
return err;
}
static int ga10b_acr_patch_wpr_info_to_ucode(struct gk20a *g,
struct nvgpu_acr *acr, struct hs_acr *acr_desc, bool is_recovery)
{
int err = 0;
#ifdef CONFIG_NVGPU_LS_PMU
struct nvgpu_mem *ls_pmu_desc = &acr_desc->ls_pmu_desc;
struct nvgpu_firmware *fw_desc;
#endif
struct nvgpu_mem *acr_falcon2_sysmem_desc =
&acr_desc->acr_falcon2_sysmem_desc;
struct flcn2_acr_desc *acr_sysmem_desc = &acr_desc->acr_sysmem_desc;
nvgpu_log_fn(g, " ");
#ifdef CONFIG_NVGPU_NON_FUSA
if (is_recovery) {
/*
* In case of recovery ucode blob size is 0 as it has already
* been authenticated during cold boot.
*/
if (!nvgpu_mem_is_valid(&acr_desc->acr_falcon2_sysmem_desc)) {
nvgpu_err(g, "invalid mem acr_falcon2_sysmem_desc");
return -EINVAL;
}
acr_sysmem_desc->nonwpr_ucode_blob_size =
RECOVERY_UCODE_BLOB_SIZE;
} else
#endif
{
/*
* Alloc space for sys mem space to which interface struct is
* copied.
*/
if (nvgpu_mem_is_valid(acr_falcon2_sysmem_desc)) {
acr_sysmem_desc->nonwpr_ucode_blob_size =
RECOVERY_UCODE_BLOB_SIZE;
goto load;
}
err = nvgpu_dma_alloc_flags_sys(g,
NVGPU_DMA_PHYSICALLY_ADDRESSED,
sizeof(struct flcn2_acr_desc),
acr_falcon2_sysmem_desc);
if (err != 0) {
goto end;
}
#ifdef CONFIG_NVGPU_LS_PMU
if(g->support_ls_pmu &&
nvgpu_is_enabled(g, NVGPU_PMU_NEXT_CORE_ENABLED)) {
err = nvgpu_dma_alloc_flags_sys(g,
NVGPU_DMA_PHYSICALLY_ADDRESSED,
sizeof(struct falcon_next_core_ucode_desc),
ls_pmu_desc);
if (err != 0) {
goto end;
}
fw_desc = nvgpu_pmu_fw_desc_desc(g, g->pmu);
nvgpu_mem_wr_n(g, ls_pmu_desc, 0U, fw_desc->data,
sizeof(struct falcon_next_core_ucode_desc));
acr_sysmem_desc->ls_pmu_desc =
nvgpu_mem_get_addr(g, ls_pmu_desc);
}
#endif
/*
* Start address of non wpr sysmem region holding ucode blob.
*/
acr_sysmem_desc->nonwpr_ucode_blob_start =
nvgpu_mem_get_addr(g, &g->acr->ucode_blob);
/*
* LS ucode blob size.
*/
nvgpu_assert(g->acr->ucode_blob.size <= U32_MAX);
acr_sysmem_desc->nonwpr_ucode_blob_size =
(u32)g->acr->ucode_blob.size;
/*
* Max regions to be used by acr. Cannot be 0U.
*/
acr_sysmem_desc->regions.no_regions = 1U;
/*
* Offset from the WPR region holding the wpr header
*/
acr_sysmem_desc->wpr_offset = WPR_OFFSET;
}
load:
/*
* Push the acr descriptor data to sysmem.
*/
nvgpu_mem_wr_n(g, acr_falcon2_sysmem_desc, 0U,
acr_sysmem_desc,
sizeof(struct flcn2_acr_desc));
end:
return err;
}
/* LSF static config functions */
#ifdef CONFIG_NVGPU_LS_PMU
static u32 ga10b_acr_lsf_pmu(struct gk20a *g,
struct acr_lsf_config *lsf)
{
if (!g->support_ls_pmu) {
/* skip adding LS PMU ucode to ACR blob */
return 0;
}
/* PMU LS falcon info */
lsf->falcon_id = FALCON_ID_PMU;
lsf->falcon_dma_idx = GK20A_PMU_DMAIDX_UCODE;
lsf->is_lazy_bootstrap = false;
lsf->is_priv_load = false;
lsf->get_lsf_ucode_details = nvgpu_acr_lsf_pmu_ucode_details;
lsf->get_cmd_line_args_offset = nvgpu_pmu_fw_get_cmd_line_args_offset;
return BIT32(lsf->falcon_id);
}
static u32 ga10b_acr_lsf_pmu_next_core(struct gk20a *g,
struct acr_lsf_config *lsf)
{
nvgpu_log_fn(g, " ");
if (!g->support_ls_pmu) {
/* skip adding LS PMU ucode to ACR blob */
return 0;
}
/* PMU LS falcon info */
lsf->falcon_id = FALCON_ID_PMU_NEXT_CORE;
lsf->falcon_dma_idx = GK20A_PMU_DMAIDX_UCODE;
lsf->is_lazy_bootstrap = false;
lsf->is_priv_load = false;
lsf->get_lsf_ucode_details = nvgpu_acr_lsf_pmu_ncore_ucode_details;
lsf->get_cmd_line_args_offset = NULL;
return BIT32(lsf->falcon_id);
}
#endif
/* LSF init */
static u32 ga10b_acr_lsf_fecs(struct gk20a *g,
struct acr_lsf_config *lsf)
{
/* FECS LS falcon info */
lsf->falcon_id = FALCON_ID_FECS;
lsf->falcon_dma_idx = GK20A_PMU_DMAIDX_UCODE;
/*
* Lazy bootstrap is a secure iGPU feature where LS falcons(FECS and
* GPCCS) are bootstrapped by LSPMU in both cold boot and recovery boot.
* As there is no ACR running after boot, we need LSPMU to bootstrap LS
* falcons to support recovery.
* In absence of LSPMU, ACR will bootstrap LS falcons but recovery is
* not supported.
*/
lsf->is_lazy_bootstrap = g->support_ls_pmu ? true : false;
lsf->is_priv_load = false;
lsf->get_lsf_ucode_details = nvgpu_acr_lsf_fecs_ucode_details;
lsf->get_cmd_line_args_offset = NULL;
return BIT32(lsf->falcon_id);
}
static u32 ga10b_acr_lsf_gpccs(struct gk20a *g,
struct acr_lsf_config *lsf)
{
/* GPCCS LS falcon info */
lsf->falcon_id = FALCON_ID_GPCCS;
/*
* Lazy bootstrap is a secure iGPU feature where LS falcons(FECS and
* GPCCS) are bootstrapped by LSPMU in both cold boot and recovery boot.
* As there is no ACR running after boot, we need LSPMU to bootstrap LS
* falcons to support recovery.
* In absence of LSPMU, ACR will bootstrap LS falcons but recovery is
* not supported.
*/
lsf->is_lazy_bootstrap = g->support_ls_pmu ? true : false;
lsf->is_priv_load = true;
lsf->get_lsf_ucode_details = nvgpu_acr_lsf_gpccs_ucode_details;
lsf->get_cmd_line_args_offset = NULL;
return BIT32(lsf->falcon_id);
}
static u32 ga10b_acr_lsf_config(struct gk20a *g,
struct nvgpu_acr *acr)
{
u32 lsf_enable_mask = 0U;
#ifdef CONFIG_NVGPU_LS_PMU
if (nvgpu_is_enabled(g, NVGPU_PMU_NEXT_CORE_ENABLED)) {
lsf_enable_mask |= ga10b_acr_lsf_pmu_next_core(g,
&acr->lsf[FALCON_ID_PMU_NEXT_CORE]);
} else {
lsf_enable_mask |= ga10b_acr_lsf_pmu(g, &acr->lsf[FALCON_ID_PMU]);
}
#endif
lsf_enable_mask |= ga10b_acr_lsf_fecs(g, &acr->lsf[FALCON_ID_FECS]);
lsf_enable_mask |= ga10b_acr_lsf_gpccs(g, &acr->lsf[FALCON_ID_GPCCS]);
return lsf_enable_mask;
}
static void ga10b_acr_default_sw_init(struct gk20a *g, struct hs_acr *riscv_hs)
{
nvgpu_log_fn(g, " ");
riscv_hs->acr_type = ACR_DEFAULT;
if (g->ops.pmu.is_debug_mode_enabled(g)) {
riscv_hs->acr_code_name = GSPDBG_RISCV_ACR_FW_CODE;
riscv_hs->acr_data_name = GSPDBG_RISCV_ACR_FW_DATA;
riscv_hs->acr_manifest_name = GSPDBG_RISCV_ACR_FW_MANIFEST;
} else {
riscv_hs->acr_code_name = GSPPROD_RISCV_ACR_FW_CODE;
riscv_hs->acr_data_name = GSPPROD_RISCV_ACR_FW_DATA;
riscv_hs->acr_manifest_name = GSPPROD_RISCV_ACR_FW_MANIFEST;
}
riscv_hs->acr_flcn = &g->gsp_flcn;
riscv_hs->report_acr_engine_bus_err_status =
nvgpu_pmu_report_bar0_pri_err_status;
riscv_hs->acr_engine_bus_err_status =
g->ops.pmu.bar0_error_status;
riscv_hs->acr_validate_mem_integrity = g->ops.pmu.validate_mem_integrity;
}
static void ga10b_acr_sw_init(struct gk20a *g, struct nvgpu_acr *acr)
{
nvgpu_log_fn(g, " ");
acr->g = g;
acr->bootstrap_owner = FALCON_ID_GSPLITE;
acr->lsf_enable_mask = ga10b_acr_lsf_config(g, acr);
ga10b_acr_default_sw_init(g, &acr->acr_asc);
acr->prepare_ucode_blob = nvgpu_acr_prepare_ucode_blob;
acr->get_wpr_info = nvgpu_acr_wpr_info_sys;
acr->alloc_blob_space = nvgpu_acr_alloc_blob_space_sys;
acr->bootstrap_hs_acr = ga10b_bootstrap_hs_acr;
acr->patch_wpr_info_to_ucode = ga10b_acr_patch_wpr_info_to_ucode;
}
extern void nvgpu_next_acr_sw_init(struct gk20a *g, struct nvgpu_acr *acr)
{
nvgpu_log_fn(g, " ");
acr->g = g;
#ifdef CONFIG_NVGPU_NON_FUSA
if (nvgpu_falcon_is_falcon2_enabled(&g->gsp_flcn)) {
nvgpu_set_enabled(g, NVGPU_ACR_NEXT_CORE_ENABLED, true);
}
#else
if (nvgpu_falcon_is_falcon2_enabled(&g->pmu_flcn)) {
/*
* ACR will be booting on PMU engine so need changes
* in ACR unit
*/
nvgpu_set_enabled(g, NVGPU_ACR_NEXT_CORE_ENABLED, true);
}
#endif
/* TODO: Make it generic for PMU/GSP */
if (nvgpu_is_enabled(g, NVGPU_ACR_NEXT_CORE_ENABLED)) {
nvgpu_info(g, "Booting RISCV core in Peregrine");
ga10b_acr_sw_init(g, acr);
} else {
nvgpu_info(g, "Booting Falcon core in Peregrine");
nvgpu_gv11b_acr_sw_init(g, g->acr);
acr->lsf_enable_mask = ga10b_acr_lsf_config(g, acr);
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2020, 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 ACR_SW_GA10B_H
#define ACR_SW_GA10B_H
struct gk20a;
struct nvgpu_acr;
void nvgpu_next_acr_sw_init(struct gk20a *g, struct nvgpu_acr *acr);
#endif /*ACR_SW_GA10B_H*/

View File

@@ -0,0 +1,167 @@
/*
* Copyright (c) 2020, 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/types.h>
#include <nvgpu/dma.h>
#include <nvgpu/timers.h>
#include <nvgpu/nvgpu_mem.h>
#include <nvgpu/firmware.h>
#include <nvgpu/riscv.h>
#include <nvgpu/pmu.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/acr.h>
#include <nvgpu/bug.h>
#include <nvgpu/soc.h>
#include <nvgpu/io.h>
#include "common/acr/acr_bootstrap.h"
#include "common/acr/acr_priv.h"
#define RISCV_BR_COMPLETION_TIMEOUT_NON_SILICON_MS 10000 /*in msec */
#define RISCV_BR_COMPLETION_TIMEOUT_SILICON_MS 100 /*in msec */
static void ga10b_riscv_release_firmware(struct gk20a *g, struct nvgpu_acr *acr)
{
nvgpu_release_firmware(g, acr->acr_asc.manifest_fw);
nvgpu_release_firmware(g, acr->acr_asc.code_fw);
nvgpu_release_firmware(g, acr->acr_asc.data_fw);
}
static int ga10b_load_riscv_acr_ucodes(struct gk20a *g, struct hs_acr *acr)
{
int err = 0;
acr->manifest_fw = nvgpu_request_firmware(g,
acr->acr_manifest_name,
NVGPU_REQUEST_FIRMWARE_NO_WARN);
if (acr->manifest_fw == NULL) {
nvgpu_err(g, "%s ucode get fail for %s",
acr->acr_manifest_name, g->name);
return -ENOENT;
}
acr->code_fw = nvgpu_request_firmware(g,
acr->acr_code_name,
NVGPU_REQUEST_FIRMWARE_NO_WARN);
if (acr->code_fw == NULL) {
nvgpu_err(g, "%s ucode get fail for %s",
acr->acr_code_name, g->name);
nvgpu_release_firmware(g, acr->manifest_fw);
return -ENOENT;
}
acr->data_fw = nvgpu_request_firmware(g,
acr->acr_data_name,
NVGPU_REQUEST_FIRMWARE_NO_WARN);
if (acr->data_fw == NULL) {
nvgpu_err(g, "%s ucode get fail for %s",
acr->acr_data_name, g->name);
nvgpu_release_firmware(g, acr->manifest_fw);
nvgpu_release_firmware(g, acr->code_fw);
return -ENOENT;
}
return err;
}
static bool nvgpu_acr_wait_for_riscv_brom_completion(struct nvgpu_falcon *flcn,
signed int timeoutms)
{
u32 reg = 0;
do {
reg = flcn->g->ops.falcon.get_brom_retcode(flcn);
if (flcn->g->ops.falcon.check_brom_passed(reg)) {
break;
}
if (timeoutms <= 0) {
return false;
}
nvgpu_msleep(10);
timeoutms -= 10;
} while (true);
return true;
}
int nvgpu_acr_bootstrap_hs_ucode_riscv(struct gk20a *g, struct nvgpu_acr *acr)
{
int err = 0;
bool brom_complete = false;
u32 timeout = 0;
u64 acr_sysmem_desc_addr = 0LL;
err = ga10b_load_riscv_acr_ucodes(g, &acr->acr_asc);
if (err !=0) {
nvgpu_err(g, "RISCV ucode loading failed");
return -EINVAL;
}
err = acr->patch_wpr_info_to_ucode(g, acr, &acr->acr_asc, false);
if (err != 0) {
nvgpu_err(g, "RISCV ucode patch wpr info failed");
return err;
}
acr_sysmem_desc_addr = nvgpu_mem_get_addr(g,
&acr->acr_asc.acr_falcon2_sysmem_desc);
nvgpu_riscv_dump_brom_stats(acr->acr_asc.acr_flcn);
nvgpu_riscv_hs_ucode_load_bootstrap(acr->acr_asc.acr_flcn,
acr->acr_asc.manifest_fw,
acr->acr_asc.code_fw,
acr->acr_asc.data_fw,
acr_sysmem_desc_addr);
if (nvgpu_platform_is_silicon(g)) {
timeout = RISCV_BR_COMPLETION_TIMEOUT_SILICON_MS;
} else {
timeout = RISCV_BR_COMPLETION_TIMEOUT_NON_SILICON_MS;
}
brom_complete = nvgpu_acr_wait_for_riscv_brom_completion(
acr->acr_asc.acr_flcn, timeout);
nvgpu_riscv_dump_brom_stats(acr->acr_asc.acr_flcn);
if (brom_complete == false) {
nvgpu_err(g, "RISCV BROM timed out, limit: %d ms", timeout);
err = -ETIMEDOUT;
} else {
nvgpu_info(g, "RISCV BROM passed");
}
/* wait for complete & halt */
if (nvgpu_platform_is_silicon(g)) {
timeout = ACR_COMPLETION_TIMEOUT_SILICON_MS;
} else {
timeout = ACR_COMPLETION_TIMEOUT_NON_SILICON_MS;
}
err = nvgpu_acr_wait_for_completion(g, &acr->acr_asc, timeout);
ga10b_riscv_release_firmware(g, acr);
return err;
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2020, 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_NEXT_ACR_BOOTSTRAP_H
#define NVGPU_NEXT_ACR_BOOTSTRAP_H
struct gk20a;
struct nvgpu_acr;
struct hs_acr;
int nvgpu_acr_bootstrap_hs_ucode_riscv(struct gk20a *g, struct nvgpu_acr *acr);
#endif /* NVGPU_NEXT_ACR_BOOTSTRAP_H */

View File

@@ -0,0 +1,92 @@
/*
*
* Copyright (c) 2021, 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/gk20a.h>
#include <nvgpu/lock.h>
#include <nvgpu/cic.h>
void nvgpu_cic_intr_unit_vectorid_init(struct gk20a *g, u32 unit, u32 *vectorid,
u32 num_entries)
{
unsigned long flags = 0;
u32 i = 0U;
struct nvgpu_intr_unit_info *intr_unit_info;
nvgpu_assert(num_entries <= NVGPU_CIC_INTR_VECTORID_SIZE_MAX);
nvgpu_log(g, gpu_dbg_intr, "UNIT=%d, nvecs=%d", unit, num_entries);
intr_unit_info = g->mc.nvgpu_next.intr_unit_info;
nvgpu_spinlock_irqsave(&g->mc.intr_lock, flags);
if (intr_unit_info[unit].valid == false) {
for (i = 0U; i < num_entries; i++) {
nvgpu_log(g, gpu_dbg_intr, " vec[%d] = %d", i,
*(vectorid + i));
intr_unit_info[unit].vectorid[i] = *(vectorid + i);
}
intr_unit_info[unit].vectorid_size = num_entries;
}
nvgpu_spinunlock_irqrestore(&g->mc.intr_lock, flags);
}
bool nvgpu_cic_intr_is_unit_info_valid(struct gk20a *g, u32 unit)
{
struct nvgpu_intr_unit_info *intr_unit_info;
bool info_valid = false;
if (unit >= NVGPU_CIC_INTR_UNIT_MAX) {
nvgpu_err(g, "invalid unit(%d)", unit);
return false;
}
intr_unit_info = g->mc.nvgpu_next.intr_unit_info;
if (intr_unit_info[unit].valid == true) {
info_valid = true;
}
return info_valid;
}
bool nvgpu_cic_intr_get_unit_info(struct gk20a *g, u32 unit, u32 *subtree,
u64 *subtree_mask)
{
if (unit >= NVGPU_CIC_INTR_UNIT_MAX) {
nvgpu_err(g, "invalid unit(%d)", unit);
return false;
}
if (nvgpu_cic_intr_is_unit_info_valid(g, unit) != true) {
if (g->ops.mc.intr_get_unit_info(g, unit) != true) {
nvgpu_err(g, "failed to fetch info for unit(%d)", unit);
return false;
}
}
*subtree = g->mc.nvgpu_next.intr_unit_info[unit].subtree;
*subtree_mask = g->mc.nvgpu_next.intr_unit_info[unit].subtree_mask;
nvgpu_log(g, gpu_dbg_intr, "subtree(%d) subtree_mask(%llx)",
*subtree, *subtree_mask);
return true;
}

View File

@@ -0,0 +1,158 @@
/*
* Copyright (c) 2020-2021, 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/gk20a.h>
#include <nvgpu/falcon.h>
#include "common/falcon/falcon_sw_gk20a.h"
#include "common/falcon/falcon_sw_ga10b.h"
static void check_and_enable_falcon2(struct nvgpu_falcon *flcn,
unsigned long *fuse_settings)
{
struct gk20a *g = flcn->g;
bool is_falcon_enabled = false;
bool is_falcon2_enabled = false;
int err = 0;
nvgpu_info(g, "Fetch FUSE settings for FALCON - %d *", flcn->flcn_id);
err = g->ops.fuse.fetch_falcon_fuse_settings(g, flcn->flcn_id,
fuse_settings);
if (err != 0) {
nvgpu_err(g, "Failed to fetch fuse settings for Falcon %d",
flcn->flcn_id);
/* setting default to FALCON until bring-up */
nvgpu_err(g, " setting default to Falcon");
flcn->is_falcon2_enabled = false;
return;
}
nvgpu_info(g, "fuse_settings - %lx", *fuse_settings);
is_falcon_enabled =
(!(nvgpu_falcon_is_feature_supported(flcn, FCD)) &&
!nvgpu_falcon_is_feature_supported(flcn, DCS));
is_falcon2_enabled = !is_falcon_enabled &&
nvgpu_falcon_is_feature_supported(flcn, DCS);
/* select the FALCON/RISCV core based on fuse */
if (!is_falcon_enabled && !is_falcon2_enabled) {
nvgpu_err(g, "Invalid fuse combination, both core disabled");
nvgpu_err(g, "Further execution will try on FALCON core");
flcn->is_falcon2_enabled = false;
} else if (is_falcon_enabled && !is_falcon2_enabled) {
nvgpu_info(g, "FALCON is enabled");
/* FALCON is enabled*/
flcn->is_falcon2_enabled = false;
} else {
nvgpu_info(g, "FALCON/RISCV can be enabled, default RISCV is enabled");
flcn->is_falcon2_enabled = true;
}
if (flcn->is_falcon2_enabled) {
if (nvgpu_falcon_is_feature_supported(flcn,
NVRISCV_BRE_EN)) {
nvgpu_info(g, "BRE info enabled");
} else {
nvgpu_info(g, "BRE info not enabled");
}
if (nvgpu_falcon_is_feature_supported(flcn, NVRISCV_DEVD)) {
nvgpu_info(g, "DevD");
} else {
nvgpu_info(g, "DevE");
}
if (nvgpu_falcon_is_feature_supported(flcn,
NVRISCV_PLD)) {
nvgpu_info(g, "PL request disabled");
} else {
nvgpu_info(g, "PL request enabled");
}
if (nvgpu_falcon_is_feature_supported(flcn, NVRISCV_SEN)) {
nvgpu_info(g, "S enabled");
if (nvgpu_falcon_is_feature_supported(flcn,
NVRISCV_SA)) {
nvgpu_info(g, "assert enabled");
} else {
nvgpu_info(g, "assert disabled");
}
if (nvgpu_falcon_is_feature_supported(flcn,
NVRISCV_SH)) {
nvgpu_info(g, "HALT enabled");
} else {
nvgpu_info(g, "HALT disabled");
}
if (nvgpu_falcon_is_feature_supported(flcn,
NVRISCV_SI)) {
nvgpu_info(g, "interrupt enabled");
} else {
nvgpu_info(g, "interrupt disabled");
}
} else {
nvgpu_info(g, "S not enabled");
}
}
}
extern void nvgpu_next_falcon_sw_init(struct nvgpu_falcon *flcn)
{
struct gk20a *g = flcn->g;
switch (flcn->flcn_id) {
case FALCON_ID_PMU:
flcn->flcn_base = g->ops.pmu.falcon_base_addr();
flcn->flcn2_base = g->ops.pmu.falcon2_base_addr();
flcn->is_falcon_supported = true;
flcn->is_interrupt_enabled = true;
check_and_enable_falcon2(flcn, &flcn->fuse_settings);
break;
case FALCON_ID_GSPLITE:
flcn->flcn_base = g->ops.gsp.falcon_base_addr();
flcn->flcn2_base = g->ops.gsp.falcon2_base_addr();
flcn->is_falcon_supported = true;
flcn->is_interrupt_enabled = false;
check_and_enable_falcon2(flcn, &flcn->fuse_settings);
break;
default:
/*
* set false to inherit falcon support
* from previous chips HAL
*/
flcn->is_falcon_supported = false;
break;
}
if (flcn->is_falcon_supported) {
gk20a_falcon_engine_dependency_ops(flcn);
} else {
gk20a_falcon_sw_init(flcn);
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2020, 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_FALCON_SW_GA10B_H
#define NVGPU_FALCON_SW_GA10B_H
void nvgpu_next_falcon_sw_init(struct nvgpu_falcon *flcn);
#endif /* NVGPU_FALCON_SW_GA10B_H */

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2021, 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/gk20a.h>
#include <nvgpu/fb.h>
int nvgpu_fb_vab_init_hal(struct gk20a *g)
{
int err = 0;
if (g->ops.fb.vab.init != NULL) {
err = g->ops.fb.vab.init(g);
}
return err;
}
int nvgpu_fb_vab_teardown_hal(struct gk20a *g)
{
int err = 0;
if (g->ops.fb.vab.teardown != NULL) {
err = g->ops.fb.vab.teardown(g);
}
return err;
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 2020, 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/device.h>
#include <nvgpu/engines.h>
#include <nvgpu/runlist.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/fifo.h>
int nvgpu_next_engine_init_one_dev(struct gk20a *g,
const struct nvgpu_device *dev)
{
struct nvgpu_device *dev_rw = (struct nvgpu_device *)dev;
/*
* Currently due to the nature of the nvgpu_next repo, this will still
* be called even on non-ga10b systems. Eventually this code will fold into
* the nvgpu-linux repo, at which point this logic will be present in
* nvgpu_engine_init_one_dev().
*
* In any event, the purpose of this is to make sure we _don't_ execute
* this code pre-ga10b. We can check for HALs that only exist on ga10x to
* short circuit.
*/
if (g->ops.runlist.get_engine_id_from_rleng_id == NULL) {
return 0;
}
/*
* Init PBDMA info for this device; needs FIFO to be alive to do this.
* SW expects at least pbdma instance0 to be valid.
*
* See JIRA NVGPU-4980 for multiple pbdma support.
*/
g->ops.runlist.get_pbdma_info(g,
dev->next.rl_pri_base,
&dev_rw->next.pbdma_info);
if (dev->next.pbdma_info.pbdma_id[ENGINE_PBDMA_INSTANCE0] ==
NVGPU_INVALID_PBDMA_ID) {
nvgpu_err(g, "busted pbdma info: no pbdma for engine id:%d",
dev->engine_id);
return -EINVAL;
}
dev_rw->pbdma_id = dev->next.pbdma_info.pbdma_id[ENGINE_PBDMA_INSTANCE0];
nvgpu_log(g, gpu_dbg_device, "Parsed engine: ID: %u", dev->engine_id);
nvgpu_log(g, gpu_dbg_device, " inst_id %u, runlist_id: %u, fault id %u",
dev->inst_id, dev->runlist_id, dev->fault_id);
nvgpu_log(g, gpu_dbg_device, " intr_id %u, reset_id %u",
dev->intr_id, dev->reset_id);
nvgpu_log(g, gpu_dbg_device, " engine_type %u",
dev->type);
nvgpu_log(g, gpu_dbg_device, " reset_id 0x%08x, rleng_id 0x%x",
dev->reset_id, dev->next.rleng_id);
nvgpu_log(g, gpu_dbg_device, " runlist_pri_base 0x%x",
dev->next.rl_pri_base);
return 0;
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 2020-2021, 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/engines.h>
#include <nvgpu/device.h>
#include <nvgpu/runlist.h>
#include <nvgpu/pbdma.h>
#include <nvgpu/gk20a.h>
static void nvgpu_runlist_init_engine_info(struct gk20a *g,
struct nvgpu_runlist *runlist,
const struct nvgpu_device *dev)
{
u32 i = 0U;
/*
* runlist_pri_base, chram_bar0_offset and pbdma_info
* will get over-written with same info, if multiple engines
* are present on same runlist. Required optimization will be
* done as part of JIRA NVGPU-4980
*/
runlist->nvgpu_next.runlist_pri_base =
dev->next.rl_pri_base;
runlist->nvgpu_next.chram_bar0_offset =
g->ops.runlist.get_chram_bar0_offset(g, dev->next.rl_pri_base);
nvgpu_log(g, gpu_dbg_info, "runlist[%d]: runlist_pri_base 0x%x",
runlist->id, runlist->nvgpu_next.runlist_pri_base);
nvgpu_log(g, gpu_dbg_info, "runlist[%d]: chram_bar0_offset 0x%x",
runlist->id, runlist->nvgpu_next.chram_bar0_offset);
runlist->nvgpu_next.pbdma_info = &dev->next.pbdma_info;
for (i = 0U; i < PBDMA_PER_RUNLIST_SIZE; i++) {
nvgpu_log(g, gpu_dbg_info,
"runlist[%d]: pbdma_id[%d] %d pbdma_pri_base[%d] 0x%x",
runlist->id, i,
runlist->nvgpu_next.pbdma_info->pbdma_id[i], i,
runlist->nvgpu_next.pbdma_info->pbdma_pri_base[i]);
}
runlist->nvgpu_next.rl_dev_list[dev->next.rleng_id] = dev;
}
static u32 nvgpu_runlist_get_pbdma_mask(struct gk20a *g,
struct nvgpu_runlist *runlist)
{
u32 pbdma_mask = 0U;
u32 i;
u32 pbdma_id;
nvgpu_assert(runlist != NULL);
for ( i = 0U; i < PBDMA_PER_RUNLIST_SIZE; i++) {
pbdma_id = runlist->nvgpu_next.pbdma_info->pbdma_id[i];
if (pbdma_id != NVGPU_INVALID_PBDMA_ID)
pbdma_mask |= BIT32(pbdma_id);
}
return pbdma_mask;
}
void nvgpu_next_runlist_init_enginfo(struct gk20a *g, struct nvgpu_fifo *f)
{
struct nvgpu_runlist *runlist;
const struct nvgpu_device *dev;
u32 i, j;
nvgpu_log_fn(g, " ");
if (g->is_virtual) {
return;
}
for (i = 0U; i < f->num_runlists; i++) {
runlist = &f->active_runlists[i];
nvgpu_log(g, gpu_dbg_info, "Configuring runlist %u (%u)", runlist->id, i);
for (j = 0U; j < f->num_engines; j++) {
dev = f->active_engines[j];
if (dev->runlist_id == runlist->id) {
runlist->eng_bitmask |= BIT32(dev->engine_id);
nvgpu_runlist_init_engine_info(g, runlist, dev);
}
}
runlist->pbdma_bitmask = nvgpu_runlist_get_pbdma_mask(g, runlist);
nvgpu_log(g, gpu_dbg_info, " Active engine bitmask: 0x%x", runlist->eng_bitmask);
nvgpu_log(g, gpu_dbg_info, " PBDMA bitmask: 0x%x", runlist->pbdma_bitmask);
}
nvgpu_log_fn(g, "done");
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2020, 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/gk20a.h>
#include <nvgpu/static_analysis.h>
#include <nvgpu/gr/config.h>
#include <nvgpu/gr/nvgpu_next_fs_state.h>
int nvgpu_gr_init_sm_id_early_config(struct gk20a *g, struct nvgpu_gr_config *config)
{
u32 tpc_index, gpc_index;
u32 sm_id = 0;
u32 num_sm;
int err = 0;
nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gr, " ");
err = g->ops.gr.config.init_sm_id_table(g, config);
if (err != 0) {
return err;
}
num_sm = nvgpu_gr_config_get_no_of_sm(config);
nvgpu_assert(num_sm > 0U);
for (sm_id = 0; sm_id < num_sm; sm_id++) {
struct nvgpu_sm_info *sm_info =
nvgpu_gr_config_get_sm_info(config, sm_id);
tpc_index = nvgpu_gr_config_get_sm_info_tpc_index(sm_info);
gpc_index = nvgpu_gr_config_get_sm_info_gpc_index(sm_info);
g->ops.gr.init.sm_id_numbering(g, gpc_index, tpc_index, sm_id,
config, NULL, false);
}
return err;
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2020, 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/gk20a.h>
#include <nvgpu/netlist.h>
#include <nvgpu/io.h>
#include <nvgpu/gr/nvgpu_next_gr.h>
void nvgpu_next_gr_init_reset_enable_hw_non_ctx_local(struct gk20a *g)
{
u32 i = 0U;
struct netlist_av_list *sw_non_ctx_local_compute_load =
nvgpu_next_netlist_get_sw_non_ctx_local_compute_load_av_list(g);
#ifdef CONFIG_NVGPU_GRAPHICS
struct netlist_av_list *sw_non_ctx_local_gfx_load =
nvgpu_next_netlist_get_sw_non_ctx_local_gfx_load_av_list(g);
#endif
for (i = 0U; i < sw_non_ctx_local_compute_load->count; i++) {
nvgpu_writel(g, sw_non_ctx_local_compute_load->l[i].addr,
sw_non_ctx_local_compute_load->l[i].value);
}
#ifdef CONFIG_NVGPU_GRAPHICS
if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_MIG)) {
for (i = 0U; i < sw_non_ctx_local_gfx_load->count; i++) {
nvgpu_writel(g, sw_non_ctx_local_gfx_load->l[i].addr,
sw_non_ctx_local_gfx_load->l[i].value);
}
}
#endif
return;
}
void nvgpu_next_gr_init_reset_enable_hw_non_ctx_global(struct gk20a *g)
{
u32 i = 0U;
struct netlist_av_list *sw_non_ctx_global_compute_load =
nvgpu_next_netlist_get_sw_non_ctx_global_compute_load_av_list(g);
#ifdef CONFIG_NVGPU_GRAPHICS
struct netlist_av_list *sw_non_ctx_global_gfx_load =
nvgpu_next_netlist_get_sw_non_ctx_global_gfx_load_av_list(g);
#endif
for (i = 0U; i < sw_non_ctx_global_compute_load->count; i++) {
nvgpu_writel(g, sw_non_ctx_global_compute_load->l[i].addr,
sw_non_ctx_global_compute_load->l[i].value);
}
#ifdef CONFIG_NVGPU_GRAPHICS
if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_MIG)) {
for (i = 0U; i < sw_non_ctx_global_gfx_load->count; i++) {
nvgpu_writel(g, sw_non_ctx_global_gfx_load->l[i].addr,
sw_non_ctx_global_gfx_load->l[i].value);
}
}
#endif
return;
}

View File

@@ -0,0 +1,92 @@
/*
*
* Copyright (c) 2020, 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/gk20a.h>
#include <nvgpu/lock.h>
#include <nvgpu/mc.h>
void nvgpu_mc_intr_unit_vectorid_init(struct gk20a *g, u32 unit, u32 *vectorid,
u32 num_entries)
{
unsigned long flags = 0;
u32 i = 0U;
struct nvgpu_intr_unit_info *intr_unit_info;
nvgpu_assert(num_entries <= MC_INTR_VECTORID_SIZE_MAX);
nvgpu_log(g, gpu_dbg_intr, "UNIT=%d, nvecs=%d", unit, num_entries);
intr_unit_info = g->mc.nvgpu_next.intr_unit_info;
nvgpu_spinlock_irqsave(&g->mc.intr_lock, flags);
if (intr_unit_info[unit].valid == false) {
for (i = 0U; i < num_entries; i++) {
nvgpu_log(g, gpu_dbg_intr, " vec[%d] = %d", i,
*(vectorid + i));
intr_unit_info[unit].vectorid[i] = *(vectorid + i);
}
intr_unit_info[unit].vectorid_size = num_entries;
}
nvgpu_spinunlock_irqrestore(&g->mc.intr_lock, flags);
}
bool nvgpu_mc_intr_is_unit_info_valid(struct gk20a *g, u32 unit)
{
struct nvgpu_intr_unit_info *intr_unit_info;
bool info_valid = false;
if (unit >= MC_INTR_UNIT_MAX) {
nvgpu_err(g, "invalid unit(%d)", unit);
return false;
}
intr_unit_info = g->mc.nvgpu_next.intr_unit_info;
if (intr_unit_info[unit].valid == true) {
info_valid = true;
}
return info_valid;
}
bool nvgpu_mc_intr_get_unit_info(struct gk20a *g, u32 unit, u32 *subtree,
u64 *subtree_mask)
{
if (unit >= MC_INTR_UNIT_MAX) {
nvgpu_err(g, "invalid unit(%d)", unit);
return false;
}
if (nvgpu_mc_intr_is_unit_info_valid(g, unit) != true) {
if (g->ops.mc.intr_get_unit_info(g, unit) != true) {
nvgpu_err(g, "failed to fetch info for unit(%d)", unit);
return false;
}
}
*subtree = g->mc.nvgpu_next.intr_unit_info[unit].subtree;
*subtree_mask = g->mc.nvgpu_next.intr_unit_info[unit].subtree_mask;
nvgpu_log(g, gpu_dbg_intr, "subtree(%d) subtree_mask(%llx)",
*subtree, *subtree_mask);
return true;
}

View File

@@ -0,0 +1,383 @@
/*
* Copyright (c) 2020-2021, 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/gk20a.h>
#include <nvgpu/string.h>
#include <nvgpu/netlist.h>
#include "common/netlist/netlist_priv.h"
/* Copied from common/netlist/netlist.c */
static int nvgpu_netlist_alloc_load_av_list(struct gk20a *g, u8 *src, u32 len,
struct netlist_av_list *av_list)
{
av_list->count = len / U32(sizeof(struct netlist_av));
if (nvgpu_netlist_alloc_av_list(g, av_list) == NULL) {
return -ENOMEM;
}
nvgpu_memcpy((u8 *)av_list->l, src, len);
return 0;
}
/* Copied from common/netlist/netlist.c */
static int nvgpu_netlist_alloc_load_aiv_list(struct gk20a *g, u8 *src, u32 len,
struct netlist_aiv_list *aiv_list)
{
aiv_list->count = len / U32(sizeof(struct netlist_aiv));
if (nvgpu_netlist_alloc_aiv_list(g, aiv_list) == NULL) {
return -ENOMEM;
}
nvgpu_memcpy((u8 *)aiv_list->l, src, len);
return 0;
}
#ifdef CONFIG_NVGPU_DEBUGGER
bool nvgpu_next_netlist_handle_debugger_region_id(struct gk20a *g,
u32 region_id, u8 *src, u32 size,
struct nvgpu_netlist_vars *netlist_vars, int *err_code)
{
int err = 0;
bool handled = true;
switch (region_id) {
case NETLIST_REGIONID_CTXREG_SYS_COMPUTE:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_SYS_COMPUTE");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.sys_compute);
break;
case NETLIST_REGIONID_CTXREG_GPC_COMPUTE:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_GPC_COMPUTE");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.gpc_compute);
break;
case NETLIST_REGIONID_CTXREG_TPC_COMPUTE:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_TPC_COMPUTE");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.tpc_compute);
break;
case NETLIST_REGIONID_CTXREG_PPC_COMPUTE:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_PPC_COMPUTE");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.ppc_compute);
break;
case NETLIST_REGIONID_CTXREG_ETPC_COMPUTE:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_ETPC_COMPUTE");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.etpc_compute);
break;
case NETLIST_REGIONID_CTXREG_LTS_BC:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_LTS_BC");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.lts_bc);
break;
case NETLIST_REGIONID_CTXREG_LTS_UC:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_LTS_UC");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.lts_uc);
break;
default:
handled = false;
break;
}
if ((handled == false) && (!nvgpu_is_enabled(g, NVGPU_SUPPORT_MIG))) {
handled = true;
switch (region_id) {
#ifdef CONFIG_NVGPU_GRAPHICS
case NETLIST_REGIONID_CTXREG_SYS_GFX:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_SYS_GFX");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.sys_gfx);
break;
case NETLIST_REGIONID_CTXREG_GPC_GFX:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_GPC_GFX");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.gpc_gfx);
break;
case NETLIST_REGIONID_CTXREG_TPC_GFX:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_TPC_GFX");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.tpc_gfx);
break;
case NETLIST_REGIONID_CTXREG_PPC_GFX:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_PPC_GFX");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.ppc_gfx);
break;
case NETLIST_REGIONID_CTXREG_ETPC_GFX:
nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_ETPC_GFX");
err = nvgpu_netlist_alloc_load_aiv_list(g, src, size,
&netlist_vars->ctxsw_regs.nvgpu_next.etpc_gfx);
break;
#endif
default:
handled = false;
break;
}
}
*err_code = err;
return handled;
}
void nvgpu_next_netlist_deinit_ctxsw_regs(struct gk20a *g)
{
struct nvgpu_netlist_vars *netlist_vars = g->netlist_vars;
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.sys_compute.l);
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.gpc_compute.l);
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.tpc_compute.l);
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.ppc_compute.l);
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.etpc_compute.l);
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.lts_bc.l);
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.lts_uc.l);
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.sys_gfx.l);
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.gpc_gfx.l);
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.tpc_gfx.l);
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.ppc_gfx.l);
nvgpu_kfree(g, netlist_vars->ctxsw_regs.nvgpu_next.etpc_gfx.l);
}
#endif /* CONFIG_NVGPU_DEBUGGER */
bool nvgpu_next_netlist_handle_sw_bundles_region_id(struct gk20a *g,
u32 region_id, u8 *src, u32 size,
struct nvgpu_netlist_vars *netlist_vars, int *err_code)
{
int err = 0;
bool handled = true;
switch(region_id) {
case NETLIST_REGIONID_SW_NON_CTX_LOCAL_COMPUTE_LOAD:
nvgpu_log_info(g, "NETLIST_REGIONID_SW_NON_CTX_LOCAL_COMPUTE_LOAD");
err = nvgpu_netlist_alloc_load_av_list(g, src, size,
&netlist_vars->nvgpu_next.sw_non_ctx_local_compute_load);
break;
case NETLIST_REGIONID_SW_NON_CTX_GLOBAL_COMPUTE_LOAD:
nvgpu_log_info(g, "NETLIST_REGIONID_SW_NON_CTX_GLOBAL_COMPUTE_LOAD");
err = nvgpu_netlist_alloc_load_av_list(g, src, size,
&netlist_vars->nvgpu_next.sw_non_ctx_global_compute_load);
break;
default:
handled = false;
break;
}
if ((handled == false) && (!nvgpu_is_enabled(g, NVGPU_SUPPORT_MIG))) {
handled = true;
switch (region_id) {
#ifdef CONFIG_NVGPU_GRAPHICS
case NETLIST_REGIONID_SW_NON_CTX_LOCAL_GFX_LOAD:
nvgpu_log_info(g, "NETLIST_REGIONID_SW_NON_CTX_LOCAL_GFX_LOAD");
err = nvgpu_netlist_alloc_load_av_list(g, src, size,
&netlist_vars->nvgpu_next.sw_non_ctx_local_gfx_load);
break;
case NETLIST_REGIONID_SW_NON_CTX_GLOBAL_GFX_LOAD:
nvgpu_log_info(g, "NETLIST_REGIONID_SW_NON_CTX_GLOBAL_GFX_LOAD");
err = nvgpu_netlist_alloc_load_av_list(g, src, size,
&netlist_vars->nvgpu_next.sw_non_ctx_global_gfx_load);
break;
#endif
default:
handled = false;
break;
}
}
*err_code = err;
return handled;
}
void nvgpu_next_netlist_deinit_ctx_vars(struct gk20a *g)
{
struct nvgpu_netlist_vars *netlist_vars = g->netlist_vars;
nvgpu_kfree(g, netlist_vars->nvgpu_next.sw_non_ctx_local_compute_load.l);
nvgpu_kfree(g, netlist_vars->nvgpu_next.sw_non_ctx_global_compute_load.l);
#ifdef CONFIG_NVGPU_GRAPHICS
nvgpu_kfree(g, netlist_vars->nvgpu_next.sw_non_ctx_local_gfx_load.l);
nvgpu_kfree(g, netlist_vars->nvgpu_next.sw_non_ctx_global_gfx_load.l);
#endif
}
#ifdef CONFIG_NVGPU_DEBUGGER
struct netlist_aiv_list *nvgpu_next_netlist_get_sys_compute_ctxsw_regs(
struct gk20a *g)
{
return &g->netlist_vars->ctxsw_regs.nvgpu_next.sys_compute;
}
struct netlist_aiv_list *nvgpu_next_netlist_get_gpc_compute_ctxsw_regs(
struct gk20a *g)
{
return &g->netlist_vars->ctxsw_regs.nvgpu_next.gpc_compute;
}
struct netlist_aiv_list *nvgpu_next_netlist_get_tpc_compute_ctxsw_regs(
struct gk20a *g)
{
return &g->netlist_vars->ctxsw_regs.nvgpu_next.tpc_compute;
}
struct netlist_aiv_list *nvgpu_next_netlist_get_ppc_compute_ctxsw_regs(
struct gk20a *g)
{
return &g->netlist_vars->ctxsw_regs.nvgpu_next.ppc_compute;
}
struct netlist_aiv_list *nvgpu_next_netlist_get_etpc_compute_ctxsw_regs(
struct gk20a *g)
{
return &g->netlist_vars->ctxsw_regs.nvgpu_next.etpc_compute;
}
struct netlist_aiv_list *nvgpu_next_netlist_get_lts_ctxsw_regs(
struct gk20a *g)
{
return &g->netlist_vars->ctxsw_regs.nvgpu_next.lts_bc;
}
struct netlist_aiv_list *nvgpu_next_netlist_get_sys_gfx_ctxsw_regs(
struct gk20a *g)
{
return &g->netlist_vars->ctxsw_regs.nvgpu_next.sys_gfx;
}
struct netlist_aiv_list *nvgpu_next_netlist_get_gpc_gfx_ctxsw_regs(
struct gk20a *g)
{
return &g->netlist_vars->ctxsw_regs.nvgpu_next.gpc_gfx;
}
struct netlist_aiv_list *nvgpu_next_netlist_get_tpc_gfx_ctxsw_regs(
struct gk20a *g)
{
return &g->netlist_vars->ctxsw_regs.nvgpu_next.tpc_gfx;
}
struct netlist_aiv_list *nvgpu_next_netlist_get_ppc_gfx_ctxsw_regs(
struct gk20a *g)
{
return &g->netlist_vars->ctxsw_regs.nvgpu_next.ppc_gfx;
}
struct netlist_aiv_list *nvgpu_next_netlist_get_etpc_gfx_ctxsw_regs(
struct gk20a *g)
{
return &g->netlist_vars->ctxsw_regs.nvgpu_next.etpc_gfx;
}
u32 nvgpu_next_netlist_get_sys_ctxsw_regs_count(struct gk20a *g)
{
u32 count = nvgpu_next_netlist_get_sys_compute_ctxsw_regs(g)->count;
count = nvgpu_safe_add_u32(count,
nvgpu_next_netlist_get_sys_gfx_ctxsw_regs(g)->count);
return count;
}
u32 nvgpu_next_netlist_get_ppc_ctxsw_regs_count(struct gk20a *g)
{
u32 count = nvgpu_next_netlist_get_ppc_compute_ctxsw_regs(g)->count;
count = nvgpu_safe_add_u32(count,
nvgpu_next_netlist_get_ppc_gfx_ctxsw_regs(g)->count);
return count;
}
u32 nvgpu_next_netlist_get_gpc_ctxsw_regs_count(struct gk20a *g)
{
u32 count = nvgpu_next_netlist_get_gpc_compute_ctxsw_regs(g)->count;
count = nvgpu_safe_add_u32(count,
nvgpu_next_netlist_get_gpc_gfx_ctxsw_regs(g)->count);
return count;
}
u32 nvgpu_next_netlist_get_tpc_ctxsw_regs_count(struct gk20a *g)
{
u32 count = nvgpu_next_netlist_get_tpc_compute_ctxsw_regs(g)->count;
count = nvgpu_safe_add_u32(count,
nvgpu_next_netlist_get_tpc_gfx_ctxsw_regs(g)->count);
return count;
}
u32 nvgpu_next_netlist_get_etpc_ctxsw_regs_count(struct gk20a *g)
{
u32 count = nvgpu_next_netlist_get_etpc_compute_ctxsw_regs(g)->count;
count = nvgpu_safe_add_u32(count,
nvgpu_next_netlist_get_etpc_gfx_ctxsw_regs(g)->count);
return count;
}
void nvgpu_next_netlist_print_ctxsw_reg_info(struct gk20a *g)
{
nvgpu_log_info(g, "GRCTX_REG_LIST_SYS_(COMPUTE/GRAPICS)_COUNT :%d %d",
nvgpu_next_netlist_get_sys_compute_ctxsw_regs(g)->count,
nvgpu_next_netlist_get_sys_gfx_ctxsw_regs(g)->count);
nvgpu_log_info(g, "GRCTX_REG_LIST_GPC_(COMPUTE/GRAPHICS)_COUNT :%d %d",
nvgpu_next_netlist_get_gpc_compute_ctxsw_regs(g)->count,
nvgpu_next_netlist_get_gpc_gfx_ctxsw_regs(g)->count);
nvgpu_log_info(g, "GRCTX_REG_LIST_TPC_(COMPUTE/GRAPHICS)_COUNT :%d %d",
nvgpu_next_netlist_get_tpc_compute_ctxsw_regs(g)->count,
nvgpu_next_netlist_get_tpc_gfx_ctxsw_regs(g)->count);
nvgpu_log_info(g, "GRCTX_REG_LIST_PPC_(COMPUTE/GRAHPICS)_COUNT :%d %d",
nvgpu_next_netlist_get_ppc_compute_ctxsw_regs(g)->count,
nvgpu_next_netlist_get_ppc_gfx_ctxsw_regs(g)->count);
nvgpu_log_info(g, "GRCTX_REG_LIST_ETPC_(COMPUTE/GRAPHICS)_COUNT :%d %d",
nvgpu_next_netlist_get_etpc_compute_ctxsw_regs(g)->count,
nvgpu_next_netlist_get_etpc_gfx_ctxsw_regs(g)->count);
nvgpu_log_info(g, "GRCTX_REG_LIST_LTS_BC_COUNT :%d",
nvgpu_next_netlist_get_lts_ctxsw_regs(g)->count);
}
#endif /* CONFIG_NVGPU_DEBUGGER */
struct netlist_av_list *nvgpu_next_netlist_get_sw_non_ctx_local_compute_load_av_list(
struct gk20a *g)
{
return &g->netlist_vars->nvgpu_next.sw_non_ctx_local_compute_load;
}
struct netlist_av_list *nvgpu_next_netlist_get_sw_non_ctx_global_compute_load_av_list(
struct gk20a *g)
{
return &g->netlist_vars->nvgpu_next.sw_non_ctx_global_compute_load;
}
#ifdef CONFIG_NVGPU_GRAPHICS
struct netlist_av_list *nvgpu_next_netlist_get_sw_non_ctx_local_gfx_load_av_list(
struct gk20a *g)
{
return &g->netlist_vars->nvgpu_next.sw_non_ctx_local_gfx_load;
}
struct netlist_av_list *nvgpu_next_netlist_get_sw_non_ctx_global_gfx_load_av_list(
struct gk20a *g)
{
return &g->netlist_vars->nvgpu_next.sw_non_ctx_global_gfx_load;
}
#endif /* CONFIG_NVGPU_GRAPHICS */

View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) 2020-2021, 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_NEXT_NETLIST_PRIV_H
#define NVGPU_NEXT_NETLIST_PRIV_H
/**
* @file
*
* Declare netlist_vars specific struct and defines.
*/
#include <nvgpu/types.h>
struct gk20a;
struct netlist_av_list;
struct netlist_aiv_list;
#ifdef CONFIG_NVGPU_DEBUGGER
#define NETLIST_REGIONID_CTXREG_SYS_COMPUTE 36
#define NETLIST_REGIONID_CTXREG_GPC_COMPUTE 38
#define NETLIST_REGIONID_CTXREG_TPC_COMPUTE 40
#define NETLIST_REGIONID_CTXREG_PPC_COMPUTE 42
#define NETLIST_REGIONID_CTXREG_ETPC_COMPUTE 44
#ifdef CONFIG_NVGPU_GRAPHICS
#define NETLIST_REGIONID_CTXREG_SYS_GFX 37
#define NETLIST_REGIONID_CTXREG_GPC_GFX 39
#define NETLIST_REGIONID_CTXREG_TPC_GFX 41
#define NETLIST_REGIONID_CTXREG_PPC_GFX 43
#define NETLIST_REGIONID_CTXREG_ETPC_GFX 45
#endif /* CONFIG_NVGPU_GRAPHICS */
#endif /* CONFIG_NVGPU_DEBUGGER */
#define NETLIST_REGIONID_SW_NON_CTX_LOCAL_COMPUTE_LOAD 48
#define NETLIST_REGIONID_SW_NON_CTX_GLOBAL_COMPUTE_LOAD 50
#ifdef CONFIG_NVGPU_GRAPHICS
#define NETLIST_REGIONID_SW_NON_CTX_LOCAL_GFX_LOAD 49
#define NETLIST_REGIONID_SW_NON_CTX_GLOBAL_GFX_LOAD 51
#endif /* CONFIG_NVGPU_GRAPHICS */
#ifdef CONFIG_NVGPU_DEBUGGER
#define NETLIST_REGIONID_CTXREG_LTS_BC 57
#define NETLIST_REGIONID_CTXREG_LTS_UC 58
#endif /* CONFIG_DEBUGGER */
struct nvgpu_next_netlist_vars {
struct netlist_av_list sw_non_ctx_local_compute_load;
struct netlist_av_list sw_non_ctx_global_compute_load;
#ifdef CONFIG_NVGPU_GRAPHICS
struct netlist_av_list sw_non_ctx_local_gfx_load;
struct netlist_av_list sw_non_ctx_global_gfx_load;
#endif /* CONFIG_NVGPU_GRAPHICS */
};
#ifdef CONFIG_NVGPU_DEBUGGER
struct nvgpu_next_ctxsw_regs {
struct netlist_aiv_list sys_compute;
struct netlist_aiv_list gpc_compute;
struct netlist_aiv_list tpc_compute;
struct netlist_aiv_list ppc_compute;
struct netlist_aiv_list etpc_compute;
struct netlist_aiv_list lts_bc;
struct netlist_aiv_list lts_uc;
#ifdef CONFIG_NVGPU_GRAPHICS
struct netlist_aiv_list sys_gfx;
struct netlist_aiv_list gpc_gfx;
struct netlist_aiv_list tpc_gfx;
struct netlist_aiv_list ppc_gfx;
struct netlist_aiv_list etpc_gfx;
#endif /* CONFIG_NVGPU_GRAPHICS */
};
#endif /* CONFIG_NVGPU_DEBUGGER */
#endif /* NVGPU_NEXT_NETLIST_PRIV_H */

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2020, 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/pmu/pmu_perfmon.h>
#include <nvgpu/log.h>
#include "pmu_perfmon_sw_ga10b.h"
void nvgpu_next_perfmon_sw_init(struct gk20a *g,
struct nvgpu_pmu_perfmon *perfmon)
{
nvgpu_log_fn(g, " ");
perfmon->init_perfmon = nvgpu_pmu_init_perfmon_rpc;
perfmon->start_sampling = nvgpu_pmu_perfmon_start_sampling_rpc;
perfmon->stop_sampling = nvgpu_pmu_perfmon_stop_sampling_rpc;
perfmon->get_samples_rpc = nvgpu_pmu_perfmon_get_samples_rpc;
perfmon->perfmon_event_handler = nvgpu_pmu_handle_perfmon_event_rpc;
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2020, 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_PMU_PERFMON_SW_GA10B_H
#define NVGPU_PMU_PERFMON_SW_GA10B_H
void nvgpu_next_perfmon_sw_init(struct gk20a *g,
struct nvgpu_pmu_perfmon *perfmon);
#endif /* NVGPU_PMU_PERFMON_SW_GA10B_H */

View File

@@ -0,0 +1,379 @@
/*
* Copyright (c) 2020-2021, 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/gk20a.h>
#include <nvgpu/pmu.h>
#include <nvgpu/pmu/pmu_pg.h>
#include <nvgpu/pmu/pmuif/pg.h>
#include <nvgpu/pmu/cmd.h>
#include "common/pmu/pg/pmu_pg.h"
#include "common/pmu/pg/pg_sw_gp106.h"
#include "common/pmu/pg/pg_sw_gm20b.h"
#include "common/pmu/pg/pg_sw_gv11b.h"
#include "pg_sw_ga10b.h"
u32 ga10b_pmu_pg_engines_list(struct gk20a *g)
{
return nvgpu_is_enabled(g, NVGPU_ELPG_MS_ENABLED) ?
(BIT32(PMU_PG_ELPG_ENGINE_ID_GRAPHICS) |
BIT32(PMU_PG_ELPG_ENGINE_ID_MS_LTC)) :
(BIT32(PMU_PG_ELPG_ENGINE_ID_GRAPHICS));
}
static int ga10b_pmu_pg_pre_init(struct gk20a *g, struct nvgpu_pmu *pmu)
{
struct pmu_rpc_struct_lpwr_loading_pre_init rpc;
int status;
u32 idx;
nvgpu_log_fn(g, " ");
(void) memset(&rpc, 0,
sizeof(struct pmu_rpc_struct_lpwr_loading_pre_init));
rpc.arch_sf_support_mask = NV_PMU_ARCH_FEATURE_SUPPORT_MASK;
rpc.base_period_ms = NV_PMU_BASE_SAMPLING_PERIOD_MS;
rpc.b_no_pstate_vbios = true;
/* Initialize LPWR GR and MS grp data for GRAPHICS and MS_LTC engine */
for (idx = 0; idx < NV_PMU_LPWR_GRP_CTRL_ID__COUNT; idx++)
{
if (idx == NV_PMU_LPWR_GRP_CTRL_ID_GR) {
rpc.grp_ctrl_mask[idx] =
BIT(PMU_PG_ELPG_ENGINE_ID_GRAPHICS);
}
if (nvgpu_is_enabled(g, NVGPU_ELPG_MS_ENABLED)) {
if (idx == NV_PMU_LPWR_GRP_CTRL_ID_MS) {
rpc.grp_ctrl_mask[idx] =
BIT(PMU_PG_ELPG_ENGINE_ID_MS_LTC);
}
}
}
PMU_RPC_EXECUTE_CPB(status, pmu, PG_LOADING, PRE_INIT, &rpc, 0);
if (status != 0) {
nvgpu_err(g, "Failed to execute RPC status=0x%x", status);
}
return status;
}
static int ga10b_pmu_pg_init(struct gk20a *g, struct nvgpu_pmu *pmu,
u8 pg_engine_id)
{
struct pmu_rpc_struct_lpwr_loading_pg_ctrl_init rpc;
int status;
nvgpu_log_fn(g, " ");
/* init ELPG */
(void) memset(&rpc, 0,
sizeof(struct pmu_rpc_struct_lpwr_loading_pg_ctrl_init));
rpc.ctrl_id = (u32)pg_engine_id;
rpc.support_mask = NV_PMU_SUB_FEATURE_SUPPORT_MASK;
PMU_RPC_EXECUTE_CPB(status, pmu, PG_LOADING, INIT, &rpc, 0);
if (status != 0) {
nvgpu_err(g, "Failed to execute RPC status=0x%x",
status);
}
/* Update Stats Dmem offset for reading statistics info */
pmu->pg->stat_dmem_offset[pg_engine_id] = rpc.stats_dmem_offset;
return status;
}
static int ga10b_pmu_pg_allow(struct gk20a *g, struct nvgpu_pmu *pmu,
u8 pg_engine_id)
{
struct pmu_rpc_struct_lpwr_pg_ctrl_allow rpc;
int status;
nvgpu_log_fn(g, " ");
(void) memset(&rpc, 0,
sizeof(struct pmu_rpc_struct_lpwr_pg_ctrl_allow));
rpc.ctrl_id = (u32)pg_engine_id;
PMU_RPC_EXECUTE_CPB(status, pmu, PG, ALLOW, &rpc, 0);
if (status != 0) {
nvgpu_err(g, "Failed to execute RPC status=0x%x",
status);
return status;
}
return status;
}
static int ga10b_pmu_pg_disallow(struct gk20a *g, struct nvgpu_pmu *pmu,
u8 pg_engine_id)
{
struct pmu_rpc_struct_lpwr_pg_ctrl_disallow rpc;
int status;
nvgpu_log_fn(g, " ");
(void) memset(&rpc, 0,
sizeof(struct pmu_rpc_struct_lpwr_pg_ctrl_disallow));
rpc.ctrl_id = (u32)pg_engine_id;
PMU_RPC_EXECUTE_CPB(status, pmu, PG, DISALLOW, &rpc, 0);
if (status != 0) {
nvgpu_err(g, "Failed to execute RPC status=0x%x",
status);
}
return status;
}
static int ga10b_pmu_pg_threshold_update(struct gk20a *g,
struct nvgpu_pmu *pmu, u8 pg_engine_id)
{
struct pmu_rpc_struct_lpwr_pg_ctrl_threshold_update rpc;
int status;
nvgpu_log_fn(g, " ");
(void) memset(&rpc, 0,
sizeof(struct pmu_rpc_struct_lpwr_pg_ctrl_threshold_update));
rpc.ctrl_id = (u32)pg_engine_id;
#ifdef CONFIG_NVGPU_SIM
if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
rpc.threshold_cycles.idle = PMU_PG_IDLE_THRESHOLD_SIM;
rpc.threshold_cycles.ppu = PMU_PG_POST_POWERUP_IDLE_THRESHOLD_SIM;
} else
#endif
{
rpc.threshold_cycles.idle = PMU_PG_IDLE_THRESHOLD;
rpc.threshold_cycles.ppu = PMU_PG_POST_POWERUP_IDLE_THRESHOLD;
}
PMU_RPC_EXECUTE_CPB(status, pmu, PG, THRESHOLD_UPDATE, &rpc, 0);
if (status != 0) {
nvgpu_err(g, "Failed to execute RPC status=0x%x",
status);
}
return status;
}
static int ga10b_pmu_pg_sfm_update(struct gk20a *g,
struct nvgpu_pmu *pmu, u8 pg_engine_id)
{
struct pmu_rpc_struct_lpwr_pg_ctrl_sfm_update rpc;
int status;
nvgpu_log_fn(g, " ");
(void) memset(&rpc, 0,
sizeof(struct pmu_rpc_struct_lpwr_pg_ctrl_sfm_update));
rpc.ctrl_id = (u32)pg_engine_id;
rpc.enabled_mask = NV_PMU_SUB_FEATURE_SUPPORT_MASK;
PMU_RPC_EXECUTE_CPB(status, pmu, PG, SFM_UPDATE, &rpc, 0);
if (status != 0) {
nvgpu_err(g, "Failed to execute RPC status=0x%x",
status);
}
return status;
}
static int ga10b_pmu_pg_post_init(struct gk20a *g,struct nvgpu_pmu *pmu)
{
struct pmu_rpc_struct_lpwr_loading_post_init rpc;
int status;
nvgpu_log_fn(g, " ");
(void) memset(&rpc, 0,
sizeof(struct pmu_rpc_struct_lpwr_loading_post_init));
PMU_RPC_EXECUTE_CPB(status, pmu, PG_LOADING, POST_INIT, &rpc, 0);
if (status != 0) {
nvgpu_err(g, "Failed to execute RPC status=0x%x", status);
}
return status;
}
static int ga10b_pmu_pg_init_send(struct gk20a *g,
struct nvgpu_pmu *pmu, u8 pg_engine_id)
{
int status;
nvgpu_log_fn(g, " ");
status = ga10b_pmu_pg_pre_init(g, pmu);
if (status != 0) {
nvgpu_err(g, "Failed to execute PG_PRE_INIT RPC");
return status;
}
status = ga10b_pmu_pg_init(g, pmu, pg_engine_id);
if (status != 0) {
nvgpu_err(g, "Failed to execute PG_INIT RPC");
return status;
}
status = ga10b_pmu_pg_threshold_update(g, pmu, pg_engine_id);
if (status != 0) {
nvgpu_err(g, "Failed to execute PG_THRESHOLD_UPDATE RPC");
return status;
}
status = ga10b_pmu_pg_sfm_update(g, pmu, pg_engine_id);
if (status != 0) {
nvgpu_err(g, "Failed to execute PG_SFM_UPDATE RPC");
return status;
}
status = ga10b_pmu_pg_post_init(g, pmu);
if (status != 0) {
nvgpu_err(g, "Failed to execute PG_POST_INIT RPC");
return status;
}
return status;
}
static int ga10b_pmu_pg_load_buff(struct gk20a *g, struct nvgpu_pmu *pmu)
{
struct pmu_rpc_struct_lpwr_loading_pg_ctrl_buf_load rpc;
u32 gr_engine_id;
int status;
nvgpu_log_fn(g, " ");
gr_engine_id = nvgpu_engine_get_gr_id(g);
(void) memset(&rpc, 0,
sizeof(struct pmu_rpc_struct_lpwr_loading_pg_ctrl_buf_load));
rpc.ctrl_id = nvgpu_safe_cast_u32_to_u8(gr_engine_id);
rpc.buf_idx = PMU_PGENG_GR_BUFFER_IDX_FECS;
rpc.dma_desc.params = (pmu->pg->pg_buf.size & 0xFFFFFFU);
rpc.dma_desc.params |= (U32(PMU_DMAIDX_VIRT) << U32(24));
rpc.dma_desc.address.lo = u64_lo32(pmu->pg->pg_buf.gpu_va);
rpc.dma_desc.address.hi = u64_hi32(pmu->pg->pg_buf.gpu_va);
pmu->pg->buf_loaded = false;
PMU_RPC_EXECUTE_CPB(status, pmu, PG_LOADING, BUF_LOAD, &rpc, 0);
if (status != 0) {
nvgpu_err(g, "Failed to execute RPC status=0x%x",
status);
return status;
}
return status;
}
static void ga10b_pg_rpc_handler(struct gk20a *g, struct nvgpu_pmu *pmu,
struct nv_pmu_rpc_header *rpc)
{
nvgpu_log_fn(g, " ");
switch (rpc->function) {
case NV_PMU_RPC_ID_PG_LOADING_PRE_INIT:
nvgpu_pmu_dbg(g, "Reply to PG_PRE_INIT");
break;
case NV_PMU_RPC_ID_PG_LOADING_POST_INIT:
nvgpu_pmu_dbg(g, "Reply to PG_POST_INIT");
break;
case NV_PMU_RPC_ID_PG_LOADING_INIT:
nvgpu_pmu_dbg(g, "Reply to PG_INIT");
break;
case NV_PMU_RPC_ID_PG_THRESHOLD_UPDATE:
nvgpu_pmu_dbg(g, "Reply to PG_THRESHOLD_UPDATE");
break;
case NV_PMU_RPC_ID_PG_SFM_UPDATE:
nvgpu_pmu_dbg(g, "Reply to PG_SFM_UPDATE");
nvgpu_pmu_fw_state_change(g, pmu, PMU_FW_STATE_ELPG_BOOTED, true);
break;
case NV_PMU_RPC_ID_PG_LOADING_BUF_LOAD:
nvgpu_pmu_dbg(g, "Reply to PG_LOADING_BUF_LOAD");
pmu->pg->buf_loaded = true;
nvgpu_pmu_fw_state_change(g, pmu, PMU_FW_STATE_LOADING_ZBC, true);
break;
case NV_PMU_RPC_ID_PG_ALLOW:
nvgpu_pmu_dbg(g, "Reply to PG_ALLOW");
pmu->pg->elpg_stat = PMU_ELPG_STAT_ON;
break;
case NV_PMU_RPC_ID_PG_DISALLOW:
nvgpu_pmu_dbg(g, "Reply to PG_DISALLOW");
pmu->pg->elpg_stat = PMU_ELPG_STAT_OFF;
break;
default:
nvgpu_err(g,
"unsupported PG rpc function : 0x%x", rpc->function);
break;
}
}
static int ga10b_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
struct pmu_pg_stats_data *pg_stat_data)
{
struct nvgpu_pmu *pmu = g->pmu;
struct pmu_pg_stats_v3 stats;
int err;
err = nvgpu_falcon_copy_from_dmem(pmu->flcn,
pmu->pg->stat_dmem_offset[pg_engine_id],
(u8 *)&stats, (u32)sizeof(struct pmu_pg_stats_v3), 0);
if (err != 0) {
nvgpu_err(g, "PMU falcon DMEM copy failed");
return err;
}
pg_stat_data->ingating_time = stats.total_sleep_time_us;
pg_stat_data->ungating_time = stats.total_non_sleep_time_us;
pg_stat_data->gating_cnt = stats.entry_count;
pg_stat_data->avg_entry_latency_us = stats.entry_latency_avg_us;
pg_stat_data->avg_exit_latency_us = stats.exit_latency_avg_us;
return err;
}
void nvgpu_next_pg_sw_init(struct gk20a *g,
struct nvgpu_pmu_pg *pg)
{
nvgpu_log_fn(g, " ");
pg->elpg_statistics = ga10b_pmu_elpg_statistics;
pg->init_param = NULL;
pg->supported_engines_list = ga10b_pmu_pg_engines_list;
pg->engines_feature_list = NULL;
pg->set_sub_feature_mask = NULL;
pg->save_zbc = gm20b_pmu_save_zbc;
pg->allow = ga10b_pmu_pg_allow;
pg->disallow = ga10b_pmu_pg_disallow;
pg->init = ga10b_pmu_pg_init;
pg->alloc_dmem = NULL;
pg->load_buff = ga10b_pmu_pg_load_buff;
pg->hw_load_zbc = NULL;
pg->rpc_handler = ga10b_pg_rpc_handler;
pg->init_send = ga10b_pmu_pg_init_send;
}

View File

@@ -0,0 +1,298 @@
/*
* Copyright (c) 2020-2021, 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_PMU_PG_SW_GA10B_H
#define NVGPU_PMU_PG_SW_GA10B_H
#include <nvgpu/types.h>
struct gk20a;
#define NV_PMU_SUB_FEATURE_SUPPORT_MASK 0xf84
#define NV_PMU_ARCH_FEATURE_SUPPORT_MASK 0x1B3
#define NV_PMU_BASE_SAMPLING_PERIOD_MS 0xFFFF
/*
* Brief Identifier for each Lpwr Group Ctrl ids
*/
enum
{
NV_PMU_LPWR_GRP_CTRL_ID_GR = 0,
NV_PMU_LPWR_GRP_CTRL_ID_MS,
NV_PMU_LPWR_GRP_CTRL_ID__COUNT,
};
/*
* Defines the structure that holds data used to execute PRE_INIT RPC.
*/
struct pmu_rpc_struct_lpwr_loading_pre_init
{
/*
* [IN/OUT] Must be first field in RPC structure.
*/
struct nv_pmu_rpc_header hdr;
/*
* [IN] Lpwr group data
*/
u32 grp_ctrl_mask[NV_PMU_LPWR_GRP_CTRL_ID__COUNT];
/*
* [IN] Mask of NV_PMU_SUBFEATURE_ID_ARCH_xyz
*/
u32 arch_sf_support_mask;
/*
* [IN] Base sampling period for centralised LPWR callback
*/
u16 base_period_ms;
/*
* [IN] Indicates if it is a no pstate vbios
*/
bool b_no_pstate_vbios;
/*
* [NONE] Must be last field in RPC structure.
*/
u32 scratch[1];
};
/*
* Defines the structure that holds data used to execute POST_INIT RPC.
*/
struct pmu_rpc_struct_lpwr_loading_post_init
{
/* [IN/OUT] Must be first field in RPC structure */
struct nv_pmu_rpc_header hdr;
/* Must be last field in RPC structure.*/
u32 scratch[5];
};
struct pmu_rpc_struct_lpwr_loading_pg_ctrl_init
{
/*[IN/OUT] Must be first field in RPC structure */
struct nv_pmu_rpc_header hdr;
/*
* [OUT] stats dmem offset
*/
u32 stats_dmem_offset;
/*
* [OUT] Engines hold off Mask
*/
u32 eng_hold_off_Mask;
/*
* [OUT] HW FSM index
*/
u8 hw_eng_idx;
/*
* [OUT] Indicates if wakeup reason type is cumulative or normal
*/
bool b_cumulative_wakeup_mask;
/*
* [IN/OUT] Sub-feature support mask
*/
u32 support_mask;
/*
* [IN] Controller ID - NV_PMU_PG_ELPG_ENGINE_ID_xyz
*/
u32 ctrl_id;
/*
* [IN] Dummy array to match with pmu struct
*/
u8 dummy[8];
/*
* [NONE] Must be last field in RPC structure.
*/
u32 scratch[1];
};
/*
* Defines the structure that holds data used to execute PG_CTRL_ALLOW RPC.
*/
struct pmu_rpc_struct_lpwr_pg_ctrl_allow
{
/*
* [IN/OUT] Must be first field in RPC structure.
*/
struct nv_pmu_rpc_header hdr;
/*
* [IN] Controller ID - NV_PMU_PG_ELPG_ENGINE_ID_xyz
*/
u32 ctrl_id;
/*
* [NONE] Must be last field in RPC structure.
*/
u32 scratch[1];
};
/*
* Defines the structure that holds data used to execute PG_CTRL_DISALLOW RPC.
*/
struct pmu_rpc_struct_lpwr_pg_ctrl_disallow
{
/*
* [IN/OUT] Must be first field in RPC structure.
*/
struct nv_pmu_rpc_header hdr;
/*
* [IN] Controller ID - NV_PMU_PG_ELPG_ENGINE_ID_xyz
*/
u32 ctrl_id;
/*
* [NONE] Must be last field in RPC structure.
*/
u32 scratch[1];
};
/*
* Brief Structure defining PG Ctrl thresholds
*/
struct pg_ctrl_threshold
{
/*
*Idle threshold. HW FSM raises entry interrupt after expiration
*of idle threshold.
*/
u32 idle;
/*
* Post power up threshold. This helps to avoid immediate entry
* after exit. PPU threshold is used for HOST based wake-up.
*/
u32 ppu;
/* Minimum value of Idle threshold supported */
u32 min_idle;
/* Maximum value of Idle threshold supported */
u32 max_idle;
};
/*
* Defines the structure that holds data used to execute PG_CTRL_THRESHOLD_UPDATE RPC.
*/
struct pmu_rpc_struct_lpwr_pg_ctrl_threshold_update
{
/*
* [IN/OUT] Must be first field in RPC structure.
*/
struct nv_pmu_rpc_header hdr;
/*
* [IN] Controller ID - NV_PMU_PG_ELPG_ENGINE_ID_xyz
*/
u32 ctrl_id;
/*
* [IN] PgCtrl thresholds
*/
struct pg_ctrl_threshold threshold_cycles;
/*
* [NONE] Must be last field in RPC structure.
*/
u32 scratch[1];
};
/*
* Defines the structure that holds data used to execute PG_CTRL_SFM_UPDATE RPC.
*/
struct pmu_rpc_struct_lpwr_pg_ctrl_sfm_update
{
/*
* [IN/OUT] Must be first field in RPC structure.
*/
struct nv_pmu_rpc_header hdr;
/*
* [IN] Updated enabled mask - NV_PMU_PG_ELPG_ENGINE_ID_xyz
*/
u32 enabled_mask;
/*
* [IN] Controller ID - NV_PMU_PG_ELPG_ENGINE_ID_xyz
*/
u32 ctrl_id;
/*
* [NONE] Must be last field in RPC structure.
*/
u32 scratch[1];
};
/*
* Defines the structure that holds data used to execute PG_CTRL_BUF_LOAD RPC.
*/
struct pmu_rpc_struct_lpwr_loading_pg_ctrl_buf_load
{
/*
* [IN/OUT] Must be first field in RPC structure.
*/
struct nv_pmu_rpc_header hdr;
/*
* [IN] DMA buffer descriptor
*/
struct flcn_mem_desc_v0 dma_desc;
/*
* [IN] PgCtrl ID
*/
u8 ctrl_id;
/*
* [IN] Engine Buffer Index
*/
u8 buf_idx;
/*
* [NONE] Must be last field in RPC structure.
*/
u32 scratch[1];
};
/*
* Brief Statistics structure for PG features
*/
struct pmu_pg_stats_v3
{
/* Number of time PMU successfully engaged sleep state */
u32 entry_count;
/* Number of time PMU exit sleep state */
u32 exit_count;
/* Number of time PMU aborted in entry sequence */
u32 abort_count;
/* Number of time task thrashing/starvation detected by Task MGMT feature */
u32 detection_count;
/*
* Time for which GPU was neither in Sleep state not
* executing sleep sequence.
*/
u32 powered_up_time_us;
/* Entry and exit latency of current sleep cycle */
u32 entry_latency_us;
u32 exit_latency_us;
/* Resident time for current sleep cycle. */
u32 resident_time_us;
/* Rolling average entry and exit latencies */
u32 entry_latency_avg_us;
u32 exit_latency_avg_us;
/* Max entry and exit latencies */
u32 entry_latency_max_us;
u32 exit_latency_max_us;
/* Total time spent in sleep and non-sleep state */
u32 total_sleep_time_us;
u32 total_non_sleep_time_us;
/* Wakeup Type - Saves events that caused a power-up. */
u32 wake_up_events;
/* Abort Reason - Saves reason that caused an abort */
u32 abort_reason;
u32 sw_disallow_reason_mask;
u32 hw_disallow_reason_mask;
};
void nvgpu_next_pg_sw_init(struct gk20a *g, struct nvgpu_pmu_pg *pg);
u32 ga10b_pmu_pg_engines_list(struct gk20a *g);
#endif /* NVGPU_PMU_PG_SW_GA10B_H */

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2021, 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/gk20a.h>
#include "nvgpu_next_profiler.h"
void nvgpu_next_profiler_hs_stream_quiesce(struct gk20a *g)
{
if (g->ops.perf.reset_hs_streaming_credits != NULL) {
/* Reset high speed streaming credits to 0. */
g->ops.perf.reset_hs_streaming_credits(g);
}
if (g->ops.perf.enable_hs_streaming != NULL) {
/* Disable high speed streaming */
g->ops.perf.enable_hs_streaming(g, false);
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2021, 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_NEXT_PROFILER_H
#define NVGPU_NEXT_PROFILER_H
void nvgpu_next_profiler_hs_stream_quiesce(struct gk20a *g);
#endif /* NVGPU_NEXT_PROFILER_H */

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2020, 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/gk20a.h>
#include <nvgpu/io.h>
#include <nvgpu/falcon.h>
#include <nvgpu/riscv.h>
#include <nvgpu/timers.h>
#include <nvgpu/firmware.h>
static bool is_falcon_valid(struct nvgpu_falcon *flcn)
{
if (flcn == NULL) {
return false;
}
if (!flcn->is_falcon_supported) {
nvgpu_err(flcn->g, "Core-id %d not supported", flcn->flcn_id);
return false;
}
return true;
}
u32 nvgpu_riscv_readl(struct nvgpu_falcon *flcn, u32 offset)
{
return nvgpu_readl(flcn->g,
nvgpu_safe_add_u32(flcn->flcn2_base, offset));
}
void nvgpu_riscv_writel(struct nvgpu_falcon *flcn,
u32 offset, u32 val)
{
nvgpu_writel(flcn->g, nvgpu_safe_add_u32(flcn->flcn2_base, offset), val);
}
int nvgpu_riscv_hs_ucode_load_bootstrap(struct nvgpu_falcon *flcn,
struct nvgpu_firmware *manifest_fw,
struct nvgpu_firmware *code_fw,
struct nvgpu_firmware *data_fw,
u64 ucode_sysmem_desc_addr)
{
struct gk20a *g;
u32 dmem_size = 0U;
int err = 0;
if (!is_falcon_valid(flcn)) {
return -EINVAL;
}
g = flcn->g;
/* core reset */
err = nvgpu_falcon_reset(flcn);
if (err != 0) {
nvgpu_err(g, "core reset failed err=%d", err);
return err;
}
/* Copy dmem desc address to mailbox */
nvgpu_falcon_mailbox_write(flcn, FALCON_MAILBOX_0,
u64_lo32(ucode_sysmem_desc_addr));
nvgpu_falcon_mailbox_write(flcn, FALCON_MAILBOX_1,
u64_hi32(ucode_sysmem_desc_addr));
g->ops.falcon.set_bcr(flcn);
err = nvgpu_falcon_get_mem_size(flcn, MEM_DMEM, &dmem_size);
err = nvgpu_falcon_copy_to_imem(flcn, 0x0, code_fw->data,
code_fw->size, 0, true, 0x0);
if (err != 0) {
nvgpu_err(g, "RISCV code copy to IMEM failed");
goto exit;
}
err = nvgpu_falcon_copy_to_dmem(flcn, 0x0, data_fw->data,
data_fw->size, 0x0);
if (err != 0) {
nvgpu_err(g, "RISCV data copy to DMEM failed");
goto exit;
}
err = nvgpu_falcon_copy_to_dmem(flcn, dmem_size - manifest_fw->size,
manifest_fw->data, manifest_fw->size, 0x0);
if (err != 0) {
nvgpu_err(g, "RISCV manifest copy to DMEM failed");
goto exit;
}
g->ops.falcon.bootstrap(flcn, 0x0);
exit:
return err;
}
void nvgpu_riscv_dump_brom_stats(struct nvgpu_falcon *flcn)
{
if (!is_falcon_valid(flcn)) {
return;
}
flcn->g->ops.falcon.dump_brom_stats(flcn);
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2020, 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/utils.h>
#include <nvgpu/hw_sim.h>
#include <nvgpu/sim.h>
#include <nvgpu/string.h>
static void nvgpu_next_sim_esc_readl(struct gk20a *g,
const char *path, u32 index, u32 *data)
{
int err;
u32 data_offset;
sim_write_hdr(g, sim_msg_function_sim_escape_read_v(),
sim_escape_read_hdr_size());
*sim_msg_param(g, 0) = index;
*sim_msg_param(g, 4) = sizeof(u32);
data_offset = round_up(
nvgpu_safe_add_u64(strlen(path), 1ULL), sizeof(u32));
*sim_msg_param(g, 8) = data_offset;
strcpy((char *)sim_msg_param(g, sim_escape_read_hdr_size()), path);
err = issue_rpc_and_wait(g);
if (err == 0) {
nvgpu_memcpy((u8 *)data, (u8 *)sim_msg_param(g,
nvgpu_safe_add_u32(data_offset,
sim_escape_read_hdr_size())),
sizeof(u32));
} else {
*data = 0xffffffff;
WARN(1, "issue_rpc_and_wait failed err=%d", err);
}
}
void nvgpu_next_init_sim_support(struct gk20a *g)
{
if (g->sim) {
g->sim->esc_readl = nvgpu_next_sim_esc_readl;
}
}

View File

@@ -0,0 +1,445 @@
/*
* Copyright (c) 2020, 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/gk20a.h>
#include <nvgpu/sim.h>
#include <nvgpu/netlist.h>
#include "nvgpu/nvgpu_next_sim.h"
int nvgpu_next_init_sim_netlist_ctx_vars(struct gk20a *g)
{
u32 i;
struct netlist_av_list *sw_non_ctx_local_compute_load;
struct netlist_av_list *sw_non_ctx_local_gfx_load;
struct netlist_av_list *sw_non_ctx_global_compute_load;
struct netlist_av_list *sw_non_ctx_global_gfx_load;
sw_non_ctx_local_compute_load =
nvgpu_next_netlist_get_sw_non_ctx_local_compute_load_av_list(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_NONCTXSW_LOCAL_COMPUTE_REG_SIZE", 0,
&sw_non_ctx_local_compute_load->count);
if (nvgpu_netlist_alloc_av_list(g, sw_non_ctx_local_compute_load) ==
NULL) {
nvgpu_info(g, "sw_non_ctx_local_compute_load failed");
}
for (i = 0; i < sw_non_ctx_local_compute_load->count; i++) {
struct netlist_av *l = sw_non_ctx_local_compute_load->l;
g->sim->esc_readl(g, "GRCTX_NONCTXSW_LOCAL_COMPUTE_REG:REG",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_NONCTXSW_LOCAL_COMPUTE_REG:VALUE",
i, &l[i].value);
}
#ifdef CONFIG_NVGPU_GRAPHICS
sw_non_ctx_local_gfx_load =
nvgpu_next_netlist_get_sw_non_ctx_local_gfx_load_av_list(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_NONCTXSW_LOCAL_GRAPHICS_REG_SIZE", 0,
&sw_non_ctx_local_gfx_load->count);
if (nvgpu_netlist_alloc_av_list(g, sw_non_ctx_local_gfx_load) ==
NULL) {
nvgpu_info(g, "sw_non_ctx_local_gfx_load failed");
}
for (i = 0; i < sw_non_ctx_local_gfx_load->count; i++) {
struct netlist_av *l = sw_non_ctx_local_gfx_load->l;
g->sim->esc_readl(g, "GRCTX_NONCTXSW_LOCAL_GRAPHICS_REG:REG",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_NONCTXSW_LOCAL_GRAPHICS_REG:VALUE",
i, &l[i].value);
}
#endif
sw_non_ctx_global_compute_load =
nvgpu_next_netlist_get_sw_non_ctx_global_compute_load_av_list(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_NONCTXSW_GLOBAL_COMPUTE_REG_SIZE", 0,
&sw_non_ctx_global_compute_load->count);
if (nvgpu_netlist_alloc_av_list(g, sw_non_ctx_global_compute_load) ==
NULL) {
nvgpu_info(g, "sw_non_ctx_global_compute_load failed");
}
for (i = 0; i < sw_non_ctx_global_compute_load->count; i++) {
struct netlist_av *l = sw_non_ctx_global_compute_load->l;
g->sim->esc_readl(g, "GRCTX_NONCTXSW_GLOBAL_COMPUTE_REG:REG",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_NONCTXSW_GLOBAL_COMPUTE_REG:VALUE",
i, &l[i].value);
}
#ifdef CONFIG_NVGPU_GRAPHICS
sw_non_ctx_global_gfx_load =
nvgpu_next_netlist_get_sw_non_ctx_global_gfx_load_av_list(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_NONCTXSW_GLOBAL_GRAPHICS_REG_SIZE", 0,
&sw_non_ctx_global_gfx_load->count);
if (nvgpu_netlist_alloc_av_list(g, sw_non_ctx_global_gfx_load) ==
NULL) {
nvgpu_info(g, "sw_non_ctx_global_gfx_load failed");
}
for (i = 0; i < sw_non_ctx_global_gfx_load->count; i++) {
struct netlist_av *l = sw_non_ctx_global_gfx_load->l;
g->sim->esc_readl(g, "GRCTX_NONCTXSW_GLOBAL_GRAPHICS_REG:REG",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_NONCTXSW_GLOBAL_GRAPHICS_REG:VALUE",
i, &l[i].value);
}
#endif
return 0;
}
void nvgpu_next_init_sim_netlist_ctx_vars_free(struct gk20a *g)
{
struct netlist_av_list *sw_non_ctx_local_compute_load;
struct netlist_av_list *sw_non_ctx_local_gfx_load;
struct netlist_av_list *sw_non_ctx_global_compute_load;
struct netlist_av_list *sw_non_ctx_global_gfx_load;
sw_non_ctx_local_compute_load =
nvgpu_next_netlist_get_sw_non_ctx_local_compute_load_av_list(g);
sw_non_ctx_global_compute_load =
nvgpu_next_netlist_get_sw_non_ctx_global_compute_load_av_list(g);
nvgpu_kfree(g, sw_non_ctx_local_compute_load->l);
nvgpu_kfree(g, sw_non_ctx_global_compute_load->l);
#ifdef CONFIG_NVGPU_GRAPHICS
sw_non_ctx_local_gfx_load =
nvgpu_next_netlist_get_sw_non_ctx_local_gfx_load_av_list(g);
sw_non_ctx_global_gfx_load =
nvgpu_next_netlist_get_sw_non_ctx_global_gfx_load_av_list(g);
nvgpu_kfree(g, sw_non_ctx_local_gfx_load->l);
nvgpu_kfree(g, sw_non_ctx_global_gfx_load->l);
#endif
}
#ifdef CONFIG_NVGPU_DEBUGGER
int nvgpu_next_init_sim_netlist_ctxsw_regs(struct gk20a *g)
{
u32 i;
struct netlist_aiv_list *sys_compute_ctxsw_regs;
struct netlist_aiv_list *gpc_compute_ctxsw_regs;
struct netlist_aiv_list *tpc_compute_ctxsw_regs;
struct netlist_aiv_list *ppc_compute_ctxsw_regs;
struct netlist_aiv_list *etpc_compute_ctxsw_regs;
struct netlist_aiv_list *lts_ctxsw_regs;
struct netlist_aiv_list *sys_gfx_ctxsw_regs;
struct netlist_aiv_list *gpc_gfx_ctxsw_regs;
struct netlist_aiv_list *tpc_gfx_ctxsw_regs;
struct netlist_aiv_list *ppc_gfx_ctxsw_regs;
struct netlist_aiv_list *etpc_gfx_ctxsw_regs;
sys_compute_ctxsw_regs =
nvgpu_next_netlist_get_sys_compute_ctxsw_regs(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS_COMPUTE_COUNT", 0,
&sys_compute_ctxsw_regs->count);
if (nvgpu_netlist_alloc_aiv_list(g, sys_compute_ctxsw_regs) == NULL) {
nvgpu_info(g, "sys_compute_ctxsw_regs failed");
}
for (i = 0; i < sys_compute_ctxsw_regs->count; i++) {
struct netlist_aiv *l = sys_compute_ctxsw_regs->l;
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS_COMPUTE:ADDR",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS_COMPUTE:INDEX",
i, &l[i].index);
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS_COMPUTE:VALUE",
i, &l[i].value);
}
gpc_compute_ctxsw_regs =
nvgpu_next_netlist_get_gpc_compute_ctxsw_regs(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC_COMPUTE_COUNT", 0,
&gpc_compute_ctxsw_regs->count);
if (nvgpu_netlist_alloc_aiv_list(g, gpc_compute_ctxsw_regs) == NULL) {
nvgpu_info(g, "gpc_compute_ctxsw_regs failed");
}
for (i = 0; i < gpc_compute_ctxsw_regs->count; i++) {
struct netlist_aiv *l = gpc_compute_ctxsw_regs->l;
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC_COMPUTE:ADDR",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC_COMPUTE:INDEX",
i, &l[i].index);
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC_COMPUTE:VALUE",
i, &l[i].value);
}
tpc_compute_ctxsw_regs =
nvgpu_next_netlist_get_tpc_compute_ctxsw_regs(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC_COMPUTE_COUNT", 0,
&tpc_compute_ctxsw_regs->count);
if (nvgpu_netlist_alloc_aiv_list(g, tpc_compute_ctxsw_regs) == NULL) {
nvgpu_info(g, "tpc_compute_ctxsw_regs failed");
}
for (i = 0; i < tpc_compute_ctxsw_regs->count; i++) {
struct netlist_aiv *l = tpc_compute_ctxsw_regs->l;
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC_COMPUTE:ADDR",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC_COMPUTE:INDEX",
i, &l[i].index);
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC_COMPUTE:VALUE",
i, &l[i].value);
}
ppc_compute_ctxsw_regs =
nvgpu_next_netlist_get_ppc_compute_ctxsw_regs(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC_COMPUTE_COUNT", 0,
&ppc_compute_ctxsw_regs->count);
if (nvgpu_netlist_alloc_aiv_list(g, ppc_compute_ctxsw_regs) == NULL) {
nvgpu_info(g, "ppc_compute_ctxsw_regs failed");
}
for (i = 0; i < ppc_compute_ctxsw_regs->count; i++) {
struct netlist_aiv *l = ppc_compute_ctxsw_regs->l;
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC_COMPUTE:ADDR",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC_COMPUTE:INDEX",
i, &l[i].index);
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC_COMPUTE:VALUE",
i, &l[i].value);
}
etpc_compute_ctxsw_regs =
nvgpu_next_netlist_get_etpc_compute_ctxsw_regs(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC_COMPUTE_COUNT", 0,
&etpc_compute_ctxsw_regs->count);
if (nvgpu_netlist_alloc_aiv_list(g, etpc_compute_ctxsw_regs) == NULL) {
nvgpu_info(g, "etpc_compute_ctxsw_regs failed");
}
for (i = 0; i < etpc_compute_ctxsw_regs->count; i++) {
struct netlist_aiv *l = etpc_compute_ctxsw_regs->l;
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC_COMPUTE:ADDR",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC_COMPUTE:INDEX",
i, &l[i].index);
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC_COMPUTE:VALUE",
i, &l[i].value);
}
/*
* TODO: https://jirasw.nvidia.com/browse/NVGPU-5761
*/
lts_ctxsw_regs = nvgpu_next_netlist_get_lts_ctxsw_regs(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_REG_LIST_LTS_BC_COUNT", 0,
&lts_ctxsw_regs->count);
nvgpu_log_info(g, "total: %d lts registers", lts_ctxsw_regs->count);
if (nvgpu_netlist_alloc_aiv_list(g, lts_ctxsw_regs) == NULL) {
nvgpu_info(g, "lts_ctxsw_regs failed");
}
for (i = 0U; i < lts_ctxsw_regs->count; i++) {
struct netlist_aiv *l = lts_ctxsw_regs->l;
g->sim->esc_readl(g, "GRCTX_REG_LIST_LTS_BC:ADDR",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_REG_LIST_LTS_BC:INDEX",
i, &l[i].index);
g->sim->esc_readl(g, "GRCTX_REG_LIST_LTS_BC:VALUE",
i, &l[i].value);
nvgpu_log_info(g, "entry(%d) a(0x%x) i(%d) v(0x%x)", i, l[i].addr,
l[i].index, l[i].value);
}
sys_gfx_ctxsw_regs = nvgpu_next_netlist_get_sys_gfx_ctxsw_regs(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS_GRAPHICS_COUNT", 0,
&sys_gfx_ctxsw_regs->count);
if (nvgpu_netlist_alloc_aiv_list(g, sys_gfx_ctxsw_regs) == NULL) {
nvgpu_info(g, "sys_gfx_ctxsw_regs failed");
}
for (i = 0; i < sys_gfx_ctxsw_regs->count; i++) {
struct netlist_aiv *l = sys_gfx_ctxsw_regs->l;
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS_GRAPHICS:ADDR",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS_GRAPHICS:INDEX",
i, &l[i].index);
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS_GRAPHICS:VALUE",
i, &l[i].value);
}
gpc_gfx_ctxsw_regs = nvgpu_next_netlist_get_gpc_gfx_ctxsw_regs(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC_GRAPHICS_COUNT", 0,
&gpc_gfx_ctxsw_regs->count);
if (nvgpu_netlist_alloc_aiv_list(g, gpc_gfx_ctxsw_regs) == NULL) {
nvgpu_info(g, "gpc_gfx_ctxsw_regs failed");
}
for (i = 0; i < gpc_gfx_ctxsw_regs->count; i++) {
struct netlist_aiv *l = gpc_gfx_ctxsw_regs->l;
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC_GRAPHICS:ADDR",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC_GRAPHICS:INDEX",
i, &l[i].index);
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC_GRAPHICS:VALUE",
i, &l[i].value);
}
tpc_gfx_ctxsw_regs = nvgpu_next_netlist_get_tpc_gfx_ctxsw_regs(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC_GRAPHICS_COUNT", 0,
&tpc_gfx_ctxsw_regs->count);
if (nvgpu_netlist_alloc_aiv_list(g, tpc_gfx_ctxsw_regs) == NULL) {
nvgpu_info(g, "tpc_gfx_ctxsw_regs failed");
}
for (i = 0; i < tpc_gfx_ctxsw_regs->count; i++) {
struct netlist_aiv *l = tpc_gfx_ctxsw_regs->l;
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC_GRAPHICS:ADDR",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC_GRAPHICS:INDEX",
i, &l[i].index);
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC_GRAPHICS:VALUE",
i, &l[i].value);
}
ppc_gfx_ctxsw_regs = nvgpu_next_netlist_get_ppc_gfx_ctxsw_regs(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC_GRAPHICS_COUNT", 0,
&ppc_gfx_ctxsw_regs->count);
if (nvgpu_netlist_alloc_aiv_list(g, ppc_gfx_ctxsw_regs) == NULL) {
nvgpu_info(g, "ppc_gfx_ctxsw_regs failed");
}
for (i = 0; i < ppc_gfx_ctxsw_regs->count; i++) {
struct netlist_aiv *l = ppc_gfx_ctxsw_regs->l;
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC_GRAPHICS:ADDR",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC_GRAPHICS:INDEX",
i, &l[i].index);
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC_GRAPHICS:VALUE",
i, &l[i].value);
}
etpc_gfx_ctxsw_regs = nvgpu_next_netlist_get_etpc_gfx_ctxsw_regs(g);
/* query sizes and counts */
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC_GRAPHICS_COUNT", 0,
&etpc_gfx_ctxsw_regs->count);
if (nvgpu_netlist_alloc_aiv_list(g, etpc_gfx_ctxsw_regs) == NULL) {
nvgpu_info(g, "etpc_gfx_ctxsw_regs failed");
}
for (i = 0; i < etpc_gfx_ctxsw_regs->count; i++) {
struct netlist_aiv *l = etpc_gfx_ctxsw_regs->l;
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC_GRAPHICS:ADDR",
i, &l[i].addr);
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC_GRAPHICS:INDEX",
i, &l[i].index);
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC_GRAPHICS:VALUE",
i, &l[i].value);
}
return 0;
}
void nvgpu_next_init_sim_netlist_ctxsw_regs_free(struct gk20a *g)
{
struct netlist_aiv_list *sys_compute_ctxsw_regs;
struct netlist_aiv_list *gpc_compute_ctxsw_regs;
struct netlist_aiv_list *tpc_compute_ctxsw_regs;
struct netlist_aiv_list *ppc_compute_ctxsw_regs;
struct netlist_aiv_list *etpc_compute_ctxsw_regs;
struct netlist_aiv_list *lts_ctxsw_regs;
struct netlist_aiv_list *sys_gfx_ctxsw_regs;
struct netlist_aiv_list *gpc_gfx_ctxsw_regs;
struct netlist_aiv_list *tpc_gfx_ctxsw_regs;
struct netlist_aiv_list *ppc_gfx_ctxsw_regs;
struct netlist_aiv_list *etpc_gfx_ctxsw_regs;
sys_compute_ctxsw_regs =
nvgpu_next_netlist_get_sys_compute_ctxsw_regs(g);
gpc_compute_ctxsw_regs =
nvgpu_next_netlist_get_gpc_compute_ctxsw_regs(g);
tpc_compute_ctxsw_regs =
nvgpu_next_netlist_get_tpc_compute_ctxsw_regs(g);
ppc_compute_ctxsw_regs =
nvgpu_next_netlist_get_ppc_compute_ctxsw_regs(g);
etpc_compute_ctxsw_regs =
nvgpu_next_netlist_get_etpc_compute_ctxsw_regs(g);
lts_ctxsw_regs = nvgpu_next_netlist_get_lts_ctxsw_regs(g);
nvgpu_kfree(g, sys_compute_ctxsw_regs->l);
nvgpu_kfree(g, gpc_compute_ctxsw_regs->l);
nvgpu_kfree(g, tpc_compute_ctxsw_regs->l);
nvgpu_kfree(g, ppc_compute_ctxsw_regs->l);
nvgpu_kfree(g, etpc_compute_ctxsw_regs->l);
nvgpu_kfree(g, lts_ctxsw_regs->l);
sys_gfx_ctxsw_regs = nvgpu_next_netlist_get_sys_gfx_ctxsw_regs(g);
gpc_gfx_ctxsw_regs = nvgpu_next_netlist_get_gpc_gfx_ctxsw_regs(g);
tpc_gfx_ctxsw_regs = nvgpu_next_netlist_get_tpc_gfx_ctxsw_regs(g);
ppc_gfx_ctxsw_regs = nvgpu_next_netlist_get_ppc_gfx_ctxsw_regs(g);
etpc_gfx_ctxsw_regs = nvgpu_next_netlist_get_etpc_gfx_ctxsw_regs(g);
nvgpu_kfree(g, sys_gfx_ctxsw_regs->l);
nvgpu_kfree(g, gpc_gfx_ctxsw_regs->l);
nvgpu_kfree(g, tpc_gfx_ctxsw_regs->l);
nvgpu_kfree(g, ppc_gfx_ctxsw_regs->l);
nvgpu_kfree(g, etpc_gfx_ctxsw_regs->l);
}
#endif /* CONFIG_NVGPU_DEBUGGER */

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 2020, 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/types.h>
#include <nvgpu/timers.h>
#include <nvgpu/io.h>
#include <nvgpu/gk20a.h>
#include "common/vbios/bios_sw_tu104.h"
#include "common/vbios/bios_sw_ga100.h"
#define NVGPU_PG209_MIN_VBIOS 0
struct nvgpu_vbios_board {
u16 board_id;
u32 vbios_version;
};
#define NVGPU_GA100_NUM_BOARDS 1
static struct nvgpu_vbios_board vbios_boards[NVGPU_GA100_NUM_BOARDS] = {
/* PG209 SKU 200 */
[0] = {
.board_id = 0x0209,
.vbios_version = 0, /* any VBIOS for now */
},
};
static int ga100_bios_verify_version(struct gk20a *g)
{
struct nvgpu_vbios_board *board = NULL;
u32 i;
nvgpu_info(g, "VBIOS board id %04x", g->bios->vbios_board_id);
nvgpu_info(g, "VBIOS version %08x:%02x\n",
g->bios->vbios_version,
g->bios->vbios_oem_version);
#if NVGPU_PG209_MIN_VBIOS
if (g->bios->vbios_version < NVGPU_PG209_MIN_VBIOS) {
nvgpu_err(g, "unsupported VBIOS version %08x",
g->bios->vbios_version);
return -EINVAL;
}
#endif
for (i = 0; i < NVGPU_GA100_NUM_BOARDS; i++) {
if (g->bios->vbios_board_id == vbios_boards[i].board_id) {
board = &vbios_boards[i];
}
}
if (board == NULL) {
nvgpu_warn(g, "unknown board id %04x",
g->bios->vbios_board_id);
return 0;
}
if ((board->vbios_version != 0U) &&
(g->bios->vbios_version < board->vbios_version)) {
nvgpu_warn(g, "VBIOS version should be at least %08x",
board->vbios_version);
}
return 0;
}
void nvgpu_ga100_bios_sw_init(struct gk20a *g, struct nvgpu_bios *bios)
{
bios->init = tu104_bios_init;
bios->verify_version = ga100_bios_verify_version;
bios->preos_wait_for_halt = NULL;
bios->preos_reload_check = NULL;
bios->preos_bios = NULL;
bios->devinit_bios = NULL;
bios->verify_devinit = tu104_bios_verify_devinit;
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2020, 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_BIOS_SW_GA100_H
#define NVGPU_BIOS_SW_GA100_H
struct gk20a;
void nvgpu_ga100_bios_sw_init(struct gk20a *g, struct nvgpu_bios *bios);
#endif /* NVGPU_BIOS_SW_GA100_H */

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2020, 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/timers.h>
#include <nvgpu/mm.h>
#include <nvgpu/io.h>
#include <nvgpu/gk20a.h>
#include "bus_ga100.h"
#include <nvgpu/hw/ga100/hw_bus_ga100.h>
u32 ga100_bus_read_sw_scratch(struct gk20a *g, u32 index)
{
return gk20a_readl(g, bus_sw_scratch_r(index));
}
void ga100_bus_write_sw_scratch(struct gk20a *g, u32 index, u32 val)
{
gk20a_writel(g, bus_sw_scratch_r(index), val);
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2020, 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_GA100_BUS
#define NVGPU_GA100_BUS
#include <nvgpu/types.h>
struct gk20a;
u32 ga100_bus_read_sw_scratch(struct gk20a *g, u32 index);
void ga100_bus_write_sw_scratch(struct gk20a *g, u32 index, u32 val);
#endif

View File

@@ -0,0 +1,156 @@
/*
* Copyright (c) 2020, 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/log.h>
#include <nvgpu/io.h>
#include <nvgpu/soc.h>
#include <nvgpu/bug.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/nvgpu_err.h>
#include "bus_ga10b.h"
#include <nvgpu/hw/ga10b/hw_bus_ga10b.h>
#define BUS_INTR_0_PRI_MASK \
(\
bus_intr_0_pri_fecserr_m() | \
bus_intr_0_pri_timeout_m() \
)
#define BUS_INTR_0_FB_MASK \
( \
bus_intr_0_fb_req_timeout_m() | \
bus_intr_0_fb_ack_timeout_m() | \
bus_intr_0_fb_ack_extra_m() | \
bus_intr_0_fb_rdata_timeout_m() | \
bus_intr_0_fb_rdata_extra_m() \
)
int ga10b_bus_init_hw(struct gk20a *g)
{
u32 intr_en_mask = 0;
/*
* pbus: pri related interrupts which are generated when fecs could
* communicate error back to host. This is the case of non-posted
* transactions (generally reads)
* pri_fecserr: This bit is set when a pri request returns from fecs
* with error status.
* pri_timeout: This bit is set when a pri request to anywhere is
* discarded due to timeout.
* priv_ring: pri error in pri hub that could not be reported to host
* (error on a posted transaction generally writes).
*/
intr_en_mask = bus_intr_en_0_pri_fecserr_m() |
bus_intr_en_0_pri_timeout_m() |
bus_intr_en_0_fb_req_timeout_m() |
bus_intr_en_0_fb_ack_timeout_m() |
bus_intr_en_0_fb_ack_extra_m() |
bus_intr_en_0_fb_rdata_timeout_m() |
bus_intr_en_0_fb_rdata_extra_m() |
bus_intr_en_0_sw_m() |
bus_intr_en_0_posted_deadlock_timeout_m() |
bus_intr_en_0_mpmu_m() |
bus_intr_en_0_access_timeout_m();
nvgpu_log_info(g, "bus fb_timeout=0x%x",
bus_fb_timeout_period_v(nvgpu_readl(g, bus_fb_timeout_r())));
nvgpu_cic_intr_stall_unit_config(g, NVGPU_CIC_INTR_UNIT_BUS, NVGPU_CIC_INTR_ENABLE);
nvgpu_writel(g, bus_intr_en_0_r(), intr_en_mask);
return 0;
}
void ga10b_bus_isr(struct gk20a *g)
{
u32 bus_intr_0 = 0U;
u32 err_type = GPU_HOST_PBUS_TIMEOUT_ERROR;
u32 bus_intr_0_handled = 0U;
bus_intr_0 = nvgpu_readl(g, bus_intr_0_r());
/*
* These bits signal that a PRI transaction has failed or timed out
* pri_fecserr_m(): fecs initiated PRI transaction failed.
* pri_timeout_m(): PRI transaction timed out.
*/
if ((bus_intr_0 & BUS_INTR_0_PRI_MASK) != 0U) {
if ((bus_intr_0 & bus_intr_0_pri_fecserr_m()) != 0U) {
err_type = GPU_HOST_PBUS_FECS_ERROR;
}
g->ops.ptimer.isr(g);
bus_intr_0_handled |= (bus_intr_0 & BUS_INTR_0_PRI_MASK);
}
/*
* These bits indicate fatal errors in the CPU-to-Frame buffer memory.
*/
if ((bus_intr_0 & BUS_INTR_0_FB_MASK) != 0U) {
nvgpu_err(g, "errors detected on FB access path, status: 0x%08x",
bus_intr_0 & BUS_INTR_0_FB_MASK);
bus_intr_0_handled |= (bus_intr_0 & BUS_INTR_0_FB_MASK);
}
/*
* Indicates a software interrupt, generated by writing 1 to
* NV_PBUS_SW_INTR_0.
*/
if ((bus_intr_0 & bus_intr_0_sw_m()) != 0U) {
nvgpu_err(g, "software interrupt");
bus_intr_0_handled |= bus_intr_0_sw_m();
}
/*
* This bit is set when a deadlock on the posted path is detected.
*/
if ((bus_intr_0 & bus_intr_0_posted_deadlock_timeout_m()) != 0U) {
nvgpu_err(g, "deadlock on posted transaction");
bus_intr_0_handled |= bus_intr_0_posted_deadlock_timeout_m();
}
/*
* Indicates an interrupt from mpmu
*/
if ((bus_intr_0 & bus_intr_0_mpmu_m()) != 0U) {
nvgpu_err(g, "interrupt from MPMU");
bus_intr_0_handled |= bus_intr_0_mpmu_m();
}
/*
* Indicates that a request from a sideband requester has timed out.
*/
if ((bus_intr_0 & bus_intr_0_access_timeout_m()) != 0U) {
nvgpu_err(g, "access timeout detected on sideband requester");
bus_intr_0_handled |= bus_intr_0_access_timeout_m();
}
if (bus_intr_0 != bus_intr_0_handled) {
nvgpu_err(g, "unhandled interrupts, status: 0x%x",
bus_intr_0 & ~bus_intr_0_handled);
}
nvgpu_report_host_err(g, NVGPU_ERR_MODULE_HOST, 0, err_type, bus_intr_0);
nvgpu_writel(g, bus_intr_0_r(), bus_intr_0);
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2020, 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_BUS_GA10B_H
#define NVGPU_BUS_GA10B_H
#include <nvgpu/types.h>
struct gk20a;
int ga10b_bus_init_hw(struct gk20a *g);
void ga10b_bus_isr(struct gk20a *g);
#endif /* NVGPU_BUS_GA10B_H */

View File

@@ -0,0 +1,158 @@
/*
* GA100 CBC
*
* Copyright (c) 2020, 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/gk20a.h>
#include <nvgpu/io.h>
#include <nvgpu/sizes.h>
#include <nvgpu/ltc.h>
#include <nvgpu/cbc.h>
#include <nvgpu/comptags.h>
#include "cbc_ga100.h"
#include <nvgpu/hw/ga100/hw_ltc_ga100.h>
#define SIZE_2K (SZ_1K << 1U)
#define AMAP_DIVIDE_ROUNDING_BASE_VALUE U32(SIZE_2K)
#define AMAP_SWIZZLE_ROUNDING_BASE_VALUE U32(SZ_64K)
int ga100_cbc_alloc_comptags(struct gk20a *g, struct nvgpu_cbc *cbc)
{
/*
* - Compbit backing store is a memory buffer to store compressed data
* corresponding to total compressible memory.
* - In GA10B, 1 ROP tile = 256B data is compressed to 1B compression
* bits. i.e. 1 GOB = 512B data is compressed to 2B compbits.
* - A comptagline is a collection of compbits corresponding to a
* compressible page size. In GA10B, compressible page size is 256KB.
*
* - GA10B has 2 LTCs with 4 slices each. A 256KB page is distributed
* into 8 slices having 32KB (64 GOBs) data each.
* - Thus, each comptagline per slice contains compression status bits
* corresponding to 64 GOBs.
*/
u32 compbit_backing_size;
/* max memory size (MB) to cover */
u32 max_size = g->max_comptag_mem;
u32 max_comptag_lines;
u32 hw_max_comptag_lines =
ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_init_v();
u32 gobs_per_comptagline_per_slice =
ltc_ltcs_ltss_cbc_param2_gobs_per_comptagline_per_slice_v(
nvgpu_readl(g, ltc_ltcs_ltss_cbc_param2_r()));
u32 compstatus_per_gob = 2U;
u32 cbc_param = nvgpu_readl(g, ltc_ltcs_ltss_cbc_param_r());
u32 comptags_size =
ltc_ltcs_ltss_cbc_param_bytes_per_comptagline_per_slice_v(
cbc_param);
u32 amap_divide_rounding = AMAP_DIVIDE_ROUNDING_BASE_VALUE <<
ltc_ltcs_ltss_cbc_param_amap_divide_rounding_v(cbc_param);
u32 amap_swizzle_rounding = AMAP_SWIZZLE_ROUNDING_BASE_VALUE <<
ltc_ltcs_ltss_cbc_param_amap_swizzle_rounding_v(cbc_param);
int err;
nvgpu_log_fn(g, " ");
/* Already initialized */
if (cbc->max_comptag_lines != 0U) {
return 0;
}
if (g->ops.fb.is_comptagline_mode_enabled(g)) {
/*
* one tag line covers 256KB
* So, number of comptag lines = (max_size * SZ_1M) / SZ_256K
*/
max_comptag_lines = max_size << 2U;
if (max_comptag_lines == 0U) {
return 0;
}
if (max_comptag_lines > hw_max_comptag_lines) {
max_comptag_lines = hw_max_comptag_lines;
}
} else {
max_comptag_lines = hw_max_comptag_lines;
}
/* Memory required for comptag lines in all slices of all ltcs */
compbit_backing_size = nvgpu_safe_mult_u32(
nvgpu_safe_mult_u32(max_comptag_lines,
nvgpu_ltc_get_slices_per_ltc(g)),
nvgpu_ltc_get_ltc_count(g));
/* Total memory required for compstatus */
compbit_backing_size = nvgpu_safe_mult_u32(
nvgpu_safe_mult_u32(compbit_backing_size,
gobs_per_comptagline_per_slice), compstatus_per_gob);
compbit_backing_size += nvgpu_ltc_get_ltc_count(g) *
amap_divide_rounding;
compbit_backing_size += amap_swizzle_rounding;
/* aligned to 2KB * ltc_count */
compbit_backing_size +=
nvgpu_ltc_get_ltc_count(g) <<
ltc_ltcs_ltss_cbc_base_alignment_shift_v();
/* must be a multiple of 64KB */
compbit_backing_size = round_up(compbit_backing_size, SZ_64K);
err = nvgpu_cbc_alloc(g, compbit_backing_size, true);
if (err != 0) {
return err;
}
err = gk20a_comptag_allocator_init(g, &cbc->comp_tags,
max_comptag_lines);
if (err != 0) {
return err;
}
cbc->max_comptag_lines = max_comptag_lines;
cbc->comptags_per_cacheline =
nvgpu_ltc_get_cacheline_size(g) / comptags_size;
cbc->gobs_per_comptagline_per_slice = gobs_per_comptagline_per_slice;
cbc->compbit_backing_size = compbit_backing_size;
nvgpu_log(g, gpu_dbg_pte, "compbit backing store size : 0x%x",
compbit_backing_size);
nvgpu_log(g, gpu_dbg_pte, "max comptag lines: %d",
max_comptag_lines);
nvgpu_log(g, gpu_dbg_pte, "gobs_per_comptagline_per_slice: %d",
cbc->gobs_per_comptagline_per_slice);
return 0;
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2020, 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 CBC_GA100_H
#define CBC_GA100_H
#ifdef CONFIG_NVGPU_COMPRESSION
#include <nvgpu/types.h>
struct gk20a;
struct nvgpu_cbc;
int ga100_cbc_alloc_comptags(struct gk20a *g, struct nvgpu_cbc *cbc);
#endif
#endif /* CBC_GA100_H */

View File

@@ -0,0 +1,152 @@
/*
* GA10B CBC
*
* Copyright (c) 2020-2021, 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/gk20a.h>
#include <nvgpu/io.h>
#include <nvgpu/sizes.h>
#include <nvgpu/ltc.h>
#include <nvgpu/cbc.h>
#include <nvgpu/comptags.h>
#include "cbc_ga10b.h"
#include <nvgpu/hw/ga10b/hw_ltc_ga10b.h>
int ga10b_cbc_alloc_comptags(struct gk20a *g, struct nvgpu_cbc *cbc)
{
/*
* - Compbit backing store is a memory buffer to store compressed data
* corresponding to total compressible memory.
* - In GA10B, 1 ROP tile = 256B data is compressed to 1B compression
* bits. i.e. 1 GOB = 512B data is compressed to 2B compbits.
* - A comptagline is a collection of compbits corresponding to a
* compressible page size. In GA10B, compressible page size is 64KB.
*
* - GA10B has 2 LTCs with 4 slices each. A 64KB page is distributed
* into 8 slices having 8KB (16 GOBs) data each.
* - Thus, each comptagline per slice contains compression status bits
* corresponding to 16 GOBs.
*/
u32 compbit_backing_size;
/* max memory size (MB) to cover */
u32 max_size = g->max_comptag_mem;
/*
* one tag line covers 64KB
* So, number of comptag lines = (max_size * SZ_1M) / SZ_64K
*/
u32 max_comptag_lines = max_size << 4U;
u32 hw_max_comptag_lines =
ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_init_v();
u32 gobs_per_comptagline_per_slice =
ltc_ltcs_ltss_cbc_param2_gobs_per_comptagline_per_slice_v(
nvgpu_readl(g, ltc_ltcs_ltss_cbc_param2_r()));
u32 compstatus_per_gob = 2U;
u32 comptags_size =
ltc_ltcs_ltss_cbc_param_bytes_per_comptagline_per_slice_v(
nvgpu_readl(g, ltc_ltcs_ltss_cbc_param_r()));
/*
* For Tegra, the addressing works differently. Unlike DGPU, all
* partitions talk to the same memory.
*/
u32 ltc_count = 1U;
/* check if vidmem is present */
bool alloc_vidmem = g->ops.fb.get_vidmem_size != NULL ? true : false;
int err;
nvgpu_log_fn(g, " ");
if (max_comptag_lines == 0U) {
return 0;
}
/* Already initialized */
if (cbc->max_comptag_lines != 0U) {
return 0;
}
if (max_comptag_lines > hw_max_comptag_lines) {
max_comptag_lines = hw_max_comptag_lines;
}
/* Memory required for comptag lines in all slices of all ltcs */
compbit_backing_size = nvgpu_safe_mult_u32(
nvgpu_safe_mult_u32(max_comptag_lines,
nvgpu_ltc_get_slices_per_ltc(g)), ltc_count);
/* Total memory required for compstatus */
compbit_backing_size = nvgpu_safe_mult_u32(
nvgpu_safe_mult_u32(compbit_backing_size,
gobs_per_comptagline_per_slice), compstatus_per_gob);
/* aligned to 2KB * ltc_count */
compbit_backing_size +=
ltc_count << ltc_ltcs_ltss_cbc_base_alignment_shift_v();
/* must be a multiple of 64KB */
compbit_backing_size = round_up(compbit_backing_size, SZ_64K);
err = nvgpu_cbc_alloc(g, compbit_backing_size, alloc_vidmem);
if (err != 0) {
return err;
}
err = gk20a_comptag_allocator_init(g, &cbc->comp_tags,
max_comptag_lines);
if (err != 0) {
return err;
}
cbc->max_comptag_lines = max_comptag_lines;
cbc->comptags_per_cacheline =
nvgpu_ltc_get_cacheline_size(g) / comptags_size;
cbc->gobs_per_comptagline_per_slice = gobs_per_comptagline_per_slice;
cbc->compbit_backing_size = compbit_backing_size;
nvgpu_log(g, gpu_dbg_pte, "supported LTCs: 0x%x",
nvgpu_ltc_get_ltc_count(g));
nvgpu_log(g, gpu_dbg_pte, "ltc_count used for calculations: 0x%x",
ltc_count);
nvgpu_log(g, gpu_dbg_pte, "compbit backing store size : 0x%x",
compbit_backing_size);
nvgpu_log(g, gpu_dbg_pte, "max comptag lines: %d",
max_comptag_lines);
nvgpu_log(g, gpu_dbg_pte, "gobs_per_comptagline_per_slice: %d",
cbc->gobs_per_comptagline_per_slice);
return 0;
}
void ga10b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc)
{
g->ops.fb.cbc_configure(g, cbc);
g->ops.cbc.ctrl(g, nvgpu_cbc_op_clear, 0U, cbc->max_comptag_lines - 1U);
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2020, 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 CBC_GA10B_H
#define CBC_GA10B_H
#ifdef CONFIG_NVGPU_COMPRESSION
#include <nvgpu/types.h>
struct gk20a;
struct nvgpu_cbc;
int ga10b_cbc_alloc_comptags(struct gk20a *g, struct nvgpu_cbc *cbc);
void ga10b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc);
#endif
#endif /* CBC_GA10B_H */

View File

@@ -0,0 +1,34 @@
/*
* Ampere GPU series copy engine
*
* Copyright (c) 2020, 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_CE_GA10B_H
#define NVGPU_CE_GA10B_H
struct gk20a;
void ga10b_ce_init_hw(struct gk20a *g);
void ga10b_ce_intr_enable(struct gk20a *g, bool enable);
void ga10b_ce_stall_isr(struct gk20a *g, u32 inst_id, u32 pri_base);
void ga10b_ce_intr_retrigger(struct gk20a *g, u32 inst_id);
#endif /* NVGPU_CE_GA10B_H */

View File

@@ -0,0 +1,239 @@
/*
* Ampere GPU series Copy Engine.
*
* Copyright (c) 2020, 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/io.h>
#include <nvgpu/log.h>
#include <nvgpu/device.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/fifo.h>
#include <nvgpu/mc.h>
#include "hal/ce/ce_gv11b.h"
#include "hal/ce/ce_ga10b.h"
#include <nvgpu/hw/ga10b/hw_ce_ga10b.h>
#define CE_LCE_STALL_INTR_MASK \
(\
ce_lce_intr_en_blockpipe_m() |\
ce_lce_intr_en_launcherr_m() |\
ce_lce_intr_en_invalid_config_m() |\
ce_lce_intr_en_mthd_buffer_fault_m() |\
ce_lce_intr_en_fbuf_crc_fail_m() |\
ce_lce_intr_en_fbuf_magic_chk_fail_m() |\
ce_lce_intr_en_poison_error_m() |\
ce_lce_intr_en_stalling_debug_m() \
)
#define CE_LCE_NONSTALL_INTR_MASK \
( \
ce_lce_intr_en_nonblockpipe_m() \
)
static void ga10b_ce_intr_stall_nonstall_enable(struct gk20a *g,
const struct nvgpu_device *dev, bool enable)
{
u32 intr_en_mask = 0U;
u32 intr_ctrl = 0U;
u32 intr_notify_ctrl = 0U;
u32 intr_ctrl_msk = 0U;
u32 intr_notify_ctrl_msk = 0U;
u32 inst_id = dev->inst_id;
intr_ctrl = nvgpu_readl(g, ce_lce_intr_ctrl_r(inst_id));
intr_notify_ctrl =
nvgpu_readl(g, ce_lce_intr_notify_ctrl_r(inst_id));
/*
* The copy engine interrupts are enabled using a single enable
* register: ce_lce_intr_en_r. The interrupts generated by the
* CE engine are grouped into two:
* Stall:
* - Represented by: CE_LCE_STALL_INTR_MASK.
* Non-Stall:
* - Represented by: CE_LCE_NONSTALL_INTR_MASK.
* Stalling interrupts are routed either to the cpu/gsp using
* the POR value of vector_id in register: ce_lce_intr_ctrl_r.
* This vector aligns with the intr_id field in device info.
* Similarly non-stalling interrupts are routed to cpu/gsp using
* the POR value of vector_id in register:
* ce_lce_intr_notify_ctrl_r. However unlike the former, the
* non-stalling interrupt vectors for GRCE0,1 share the vector
* id of GR engine. Hence there is a mis-alignment between the
* POR value of vector_id in ce_lce_intr_notify_ctrl_r register
* of GRCE0,1 with the intr_id field in the device info.
*/
if (enable) {
/*
* Enable all stall, non-stall interrupts. Configure
* intr_(notify_,)_ctrl_r, so that all engine interrupts
* are reported to CPU on the POR values of vector_ids.
* In addition, disable reporting to GSP.
*/
intr_en_mask = CE_LCE_STALL_INTR_MASK |
CE_LCE_NONSTALL_INTR_MASK;
intr_ctrl_msk = ce_lce_intr_ctrl_cpu_enable_f() |
ce_lce_intr_ctrl_gsp_disable_f();
intr_notify_ctrl_msk =
ce_lce_intr_notify_ctrl_cpu_enable_f() |
ce_lce_intr_notify_ctrl_gsp_disable_f();
} else {
/*
* Mask all interrupts from the engine and disable
* reporting to both CPU, GSP.
*/
intr_en_mask = 0U;
intr_ctrl_msk = ce_lce_intr_ctrl_cpu_disable_f() |
ce_lce_intr_ctrl_gsp_disable_f();
intr_notify_ctrl_msk =
ce_lce_intr_notify_ctrl_cpu_disable_f() |
ce_lce_intr_notify_ctrl_gsp_disable_f();
}
intr_ctrl = set_field(intr_ctrl, ce_lce_intr_ctrl_cpu_m() |
ce_lce_intr_ctrl_gsp_m(),
intr_ctrl_msk);
intr_notify_ctrl = set_field(intr_notify_ctrl,
ce_lce_intr_notify_ctrl_cpu_m() |
ce_lce_intr_notify_ctrl_gsp_m(),
intr_notify_ctrl_msk);
nvgpu_log(g, gpu_dbg_intr, "ce(%d) intr_ctrl(0x%x) "\
"intr_notify_ctrl(0x%x) intr_en_mask(0x%x)",
inst_id, intr_ctrl, intr_notify_ctrl,
intr_en_mask);
nvgpu_writel(g, ce_lce_intr_ctrl_r(inst_id), intr_ctrl);
nvgpu_writel(g, ce_lce_intr_notify_ctrl_r(inst_id),
intr_notify_ctrl);
nvgpu_writel(g, ce_lce_intr_en_r(inst_id), intr_en_mask);
}
void ga10b_ce_init_hw(struct gk20a *g)
{
u32 i = 0U;
u32 nonstall_vectorid_tree[NVGPU_CIC_INTR_VECTORID_SIZE_MAX];
u32 num_nonstall_vectors = 0;
for (i = 0U; i < nvgpu_device_count(g, NVGPU_DEVTYPE_LCE); i++) {
const struct nvgpu_device *dev =
nvgpu_device_get(g, NVGPU_DEVTYPE_LCE, i);
nvgpu_assert(dev != NULL);
/*
* The intr_id in dev info is broken for non-stall interrupts
* from grce0,1. Therefore, instead read the vectors from the
* POR values of intr_notify_ctrl_r.
*/
nonstall_vectorid_tree[num_nonstall_vectors] =
ce_lce_intr_notify_ctrl_vector_v(
nvgpu_readl(g, ce_lce_intr_notify_ctrl_r(dev->inst_id)));
nvgpu_log(g, gpu_dbg_intr, "ce(%d) non-stall vector(%d)",
dev->inst_id,
nonstall_vectorid_tree[num_nonstall_vectors]);
num_nonstall_vectors++;
}
/*
* Initalize struct nvgpu_mc with POR values of non-stall vectors ids.
*/
nvgpu_cic_intr_unit_vectorid_init(g, NVGPU_CIC_INTR_UNIT_CE,
nonstall_vectorid_tree, num_nonstall_vectors);
}
void ga10b_ce_intr_enable(struct gk20a *g, bool enable)
{
u32 i = 0U;
for (i = 0U; i < nvgpu_device_count(g, NVGPU_DEVTYPE_LCE); i++) {
const struct nvgpu_device *dev =
nvgpu_device_get(g, NVGPU_DEVTYPE_LCE, i);
nvgpu_assert(dev != NULL);
ga10b_ce_intr_stall_nonstall_enable(g, dev, enable);
}
}
void ga10b_ce_stall_isr(struct gk20a *g, u32 inst_id, u32 pri_base)
{
u32 ce_intr = nvgpu_readl(g, ce_intr_status_r(inst_id));
u32 clear_intr = 0U;
nvgpu_log(g, gpu_dbg_intr, "ce(%u) isr 0x%08x 0x%08x", inst_id,
ce_intr, inst_id);
/*
* Mismatch between the CRC entry in fault buffer and the
* CRC computed from the methods in the buffer.
*/
if ((ce_intr & ce_intr_status_fbuf_crc_fail_pending_f()) != 0U) {
nvgpu_err(g, "ce: inst %d, fault buffer crc mismatch", inst_id);
clear_intr |= ce_intr_status_fbuf_crc_fail_reset_f();
}
/*
* The MAGIC_NUM entry in fault buffer does not match with the expected
* value: NV_CE_MTHD_BUFFER_GLOBAL_HDR_MAGIC_NUM_VAL. This error
* indicates a memory corruption.
*/
if ((ce_intr & ce_intr_status_fbuf_magic_chk_fail_pending_f()) != 0U) {
nvgpu_err(g, "ce: inst %d, fault buffer magic check fail",
inst_id);
clear_intr |= ce_intr_status_fbuf_magic_chk_fail_reset_f();
}
/*
* The poison error indicates that the data returned from the memory
* subsytem is corrupted due to an uncorrectable ecc error.
*/
if ((ce_intr & ce_intr_status_poison_error_pending_f()) != 0U) {
nvgpu_err(g, "ce: inst %d: poison error, uncorrected ecc error",
inst_id);
clear_intr |= ce_intr_status_poison_error_reset_f();
}
/*
* The stalling_debug error interrupt is triggered when SW writes TRUE
* to NV_CE_LCE_OPT_EXT_DEBUG_TRIGGER_STALLING.
*/
if ((ce_intr & ce_intr_status_stalling_debug_pending_f()) != 0U) {
nvgpu_err(g, "ce: inst %d: stalling debug interrupt", inst_id);
clear_intr |= ce_intr_status_stalling_debug_pending_f();
}
nvgpu_writel(g, ce_intr_status_r(inst_id), clear_intr);
/*
* The remaining legacy interrupts are handled by legacy interrupt
* handler.
*/
gv11b_ce_stall_isr(g, inst_id, pri_base);
}
void ga10b_ce_intr_retrigger(struct gk20a *g, u32 inst_id)
{
nvgpu_writel(g, ce_intr_retrigger_r(inst_id),
ce_intr_retrigger_trigger_true_f());
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2020 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/class.h>
#include <nvgpu/nvgpu_next_class.h>
#include <nvgpu/barrier.h>
#include "hal/class/class_ga10b.h"
#include "class_ga100.h"
bool ga100_class_is_valid(u32 class_num)
{
bool valid;
nvgpu_speculation_barrier();
switch (class_num) {
case AMPERE_COMPUTE_A:
case AMPERE_DMA_COPY_A:
#ifdef CONFIG_NVGPU_GRAPHICS
case AMPERE_A:
#endif
valid = true;
break;
default:
valid = ga10b_class_is_valid(class_num);
break;
}
return valid;
};
#ifdef CONFIG_NVGPU_GRAPHICS
bool ga100_class_is_valid_gfx(u32 class_num)
{
bool valid;
nvgpu_speculation_barrier();
switch (class_num) {
case AMPERE_A:
valid = true;
break;
default:
valid = false;
break;
}
return valid;
}
#endif
bool ga100_class_is_valid_compute(u32 class_num)
{
bool valid;
nvgpu_speculation_barrier();
switch (class_num) {
case AMPERE_COMPUTE_A:
valid = true;
break;
default:
valid = ga10b_class_is_valid_compute(class_num);
break;
}
return valid;
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2020, 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_CLASS_GA100
#define NVGPU_CLASS_GA100
#include <nvgpu/types.h>
bool ga100_class_is_valid(u32 class_num);
bool ga100_class_is_valid_compute(u32 class_num);
#ifdef CONFIG_NVGPU_GRAPHICS
bool ga100_class_is_valid_gfx(u32 class_num);
#endif
#endif /* NVGPU_CLASS_GA100 */

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2020 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/class.h>
#include <nvgpu/nvgpu_next_class.h>
#include <nvgpu/barrier.h>
#include "hal/class/class_tu104.h"
#include "class_ga10b.h"
bool ga10b_class_is_valid(u32 class_num)
{
bool valid;
nvgpu_speculation_barrier();
switch (class_num) {
case AMPERE_SMC_PARTITION_REF:
case AMPERE_COMPUTE_B:
case AMPERE_DMA_COPY_B:
case AMPERE_CHANNEL_GPFIFO_B:
#ifdef CONFIG_NVGPU_GRAPHICS
case AMPERE_B:
#endif
valid = true;
break;
default:
valid = tu104_class_is_valid(class_num);
break;
}
return valid;
};
#ifdef CONFIG_NVGPU_GRAPHICS
bool ga10b_class_is_valid_gfx(u32 class_num)
{
bool valid;
nvgpu_speculation_barrier();
switch (class_num) {
case AMPERE_B:
valid = true;
break;
default:
valid = tu104_class_is_valid_gfx(class_num);
break;
}
return valid;
}
#endif
bool ga10b_class_is_valid_compute(u32 class_num)
{
bool valid;
nvgpu_speculation_barrier();
switch (class_num) {
case AMPERE_COMPUTE_B:
valid = true;
break;
default:
valid = tu104_class_is_valid_compute(class_num);
break;
}
return valid;
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2020, 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_CLASS_GA10B
#define NVGPU_CLASS_GA10B
#include <nvgpu/types.h>
bool ga10b_class_is_valid(u32 class_num);
bool ga10b_class_is_valid_compute(u32 class_num);
#ifdef CONFIG_NVGPU_GRAPHICS
bool ga10b_class_is_valid_gfx(u32 class_num);
#endif
#endif /* NVGPU_CLASS_GA10B */

View File

@@ -0,0 +1,38 @@
/*
* GA100 Clocks
*
* Copyright (c) 2016-2020, 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/gk20a.h>
#include <nvgpu/hw/ga100/hw_trim_ga100.h>
#include "clk_ga100.h"
u32 ga100_clk_get_cntr_sysclk_source(struct gk20a *g)
{
return trim_sys_fr_clk_cntr_sysclk_cfg_source_sys_noeg_f();
}
u32 ga100_clk_get_cntr_xbarclk_source(struct gk20a *g)
{
return trim_sys_fll_fr_clk_cntr_xbarclk_cfg_source_xbar_nobg_duplicate_f();
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2020, 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 CLK_GA100_H
#define CLK_GA100_H
u32 ga100_clk_get_cntr_xbarclk_source(struct gk20a *g);
u32 ga100_clk_get_cntr_sysclk_source(struct gk20a *g);
#endif /* CLK_GA100_H */

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2020, 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_FALCON_GA10B_H
#define NVGPU_FALCON_GA10B_H
#include <nvgpu/falcon.h>
#define FALCON_DMEM_BLKSIZE2 8U
u32 ga10b_falcon_dmemc_blk_mask(void);
u32 ga10b_falcon_imemc_blk_field(u32 blk);
u32 ga10b_falcon_get_mem_size(struct nvgpu_falcon *flcn,
enum falcon_mem_type mem_type);
bool ga10b_falcon_is_cpu_halted(struct nvgpu_falcon *flcn);
void ga10b_falcon_set_bcr(struct nvgpu_falcon *flcn);
void ga10b_falcon_bootstrap(struct nvgpu_falcon *flcn, u32 boot_vector);
void ga10b_falcon_dump_brom_stats(struct nvgpu_falcon *flcn);
u32 ga10b_falcon_get_brom_retcode(struct nvgpu_falcon *flcn);
bool ga10b_falcon_is_priv_lockdown(struct nvgpu_falcon *flcn);
bool ga10b_falcon_check_brom_passed(u32 retcode);
void ga10b_falcon_brom_config(struct nvgpu_falcon *flcn, u64 fmc_code_addr,
u64 fmc_data_addr, u64 manifest_addr);
void ga10b_falcon_dump_stats(struct nvgpu_falcon *flcn);
bool ga10b_is_falcon_scrubbing_done(struct nvgpu_falcon *flcn);
bool ga10b_is_falcon_idle(struct nvgpu_falcon *flcn);
#endif /* NVGPU_FALCON_GA10B_H */

View File

@@ -0,0 +1,215 @@
/*
* Copyright (c) 2020-2021, 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/log.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/riscv.h>
#include <nvgpu/hw/ga10b/hw_falcon_ga10b.h>
#include <nvgpu/hw/ga10b/hw_priscv_ga10b.h>
#include "hal/falcon/falcon_gk20a.h"
#include "falcon_ga10b.h"
u32 ga10b_falcon_dmemc_blk_mask(void)
{
return falcon_falcon_dmemc_blk_m();
}
u32 ga10b_falcon_imemc_blk_field(u32 blk)
{
return falcon_falcon_imemc_blk_f(blk);
}
bool ga10b_falcon_is_cpu_halted(struct nvgpu_falcon *flcn)
{
if (flcn->is_falcon2_enabled) {
return (priscv_priscv_cpuctl_halted_v(
nvgpu_riscv_readl(flcn, priscv_priscv_cpuctl_r())) != 0U);
} else {
return ((nvgpu_falcon_readl(flcn, falcon_falcon_cpuctl_r()) &
falcon_falcon_cpuctl_halt_intr_m()) != 0U);
}
}
void ga10b_falcon_set_bcr(struct nvgpu_falcon *flcn)
{
nvgpu_riscv_writel(flcn, priscv_priscv_bcr_ctrl_r(), 0x11);
}
void ga10b_falcon_bootstrap(struct nvgpu_falcon *flcn, u32 boot_vector)
{
/* Need to check this through fuse/SW policy*/
if (flcn->is_falcon2_enabled) {
nvgpu_log_info(flcn->g, "boot riscv core");
nvgpu_riscv_writel(flcn, priscv_priscv_cpuctl_r(),
priscv_priscv_cpuctl_startcpu_true_f());
} else {
nvgpu_log_info(flcn->g, "falcon boot vec 0x%x", boot_vector);
nvgpu_falcon_writel(flcn, falcon_falcon_dmactl_r(),
falcon_falcon_dmactl_require_ctx_f(0));
nvgpu_falcon_writel(flcn, falcon_falcon_bootvec_r(),
falcon_falcon_bootvec_vec_f(boot_vector));
nvgpu_falcon_writel(flcn, falcon_falcon_cpuctl_r(),
falcon_falcon_cpuctl_startcpu_f(1));
}
}
void ga10b_falcon_dump_brom_stats(struct nvgpu_falcon *flcn)
{
u32 reg;
reg = nvgpu_riscv_readl(flcn, priscv_priscv_bcr_ctrl_r());
nvgpu_info(flcn->g, "Bootrom Configuration: 0x%08x", reg);
reg = nvgpu_falcon_readl(flcn, falcon_falcon_hwcfg2_r());
nvgpu_pmu_dbg(flcn->g, "HWCFG2: 0x%08x", reg);
if (falcon_falcon_hwcfg2_riscv_br_priv_lockdown_v(reg) ==
falcon_falcon_hwcfg2_riscv_br_priv_lockdown_lock_v()) {
nvgpu_info(flcn->g, "PRIV LOCKDOWN enabled");
} else {
nvgpu_info(flcn->g, "PRIV LOCKDOWN disabled");
}
reg = nvgpu_riscv_readl(flcn, priscv_priscv_br_retcode_r());
nvgpu_log_info(flcn->g,"RISCV BROM RETCODE: 0x%08x", reg);
}
u32 ga10b_falcon_get_brom_retcode(struct nvgpu_falcon *flcn)
{
return nvgpu_riscv_readl(flcn, priscv_priscv_br_retcode_r());
}
bool ga10b_falcon_is_priv_lockdown(struct nvgpu_falcon *flcn)
{
u32 reg = nvgpu_falcon_readl(flcn, falcon_falcon_hwcfg2_r());
if (falcon_falcon_hwcfg2_riscv_br_priv_lockdown_v(reg) ==
falcon_falcon_hwcfg2_riscv_br_priv_lockdown_lock_v()) {
return true;
}
return false;
}
bool ga10b_falcon_check_brom_passed(u32 retcode)
{
return (priscv_priscv_br_retcode_result_v(retcode) ==
priscv_priscv_br_retcode_result_pass_f()) ||
(priscv_priscv_br_retcode_result_v(retcode) ==
priscv_priscv_br_retcode_result_fail_f());
}
void ga10b_falcon_brom_config(struct nvgpu_falcon *flcn, u64 fmc_code_addr,
u64 fmc_data_addr, u64 manifest_addr)
{
nvgpu_riscv_writel(flcn, priscv_priscv_bcr_dmaaddr_fmccode_lo_r(),
u64_lo32(fmc_code_addr));
nvgpu_riscv_writel(flcn, priscv_priscv_bcr_dmaaddr_fmccode_hi_r(),
u64_hi32(fmc_code_addr));
nvgpu_riscv_writel(flcn, priscv_priscv_bcr_dmaaddr_fmcdata_lo_r(),
u64_lo32(fmc_data_addr));
nvgpu_riscv_writel(flcn, priscv_priscv_bcr_dmaaddr_fmcdata_hi_r(),
u64_hi32(fmc_data_addr));
nvgpu_riscv_writel(flcn, priscv_priscv_bcr_dmaaddr_pkcparam_lo_r(),
u64_lo32(manifest_addr));
nvgpu_riscv_writel(flcn, priscv_priscv_bcr_dmaaddr_pkcparam_hi_r(),
u64_hi32(manifest_addr));
nvgpu_riscv_writel(flcn, priscv_priscv_bcr_dmacfg_r(),
priscv_priscv_bcr_dmacfg_target_noncoherent_system_f() |
priscv_priscv_bcr_dmacfg_lock_locked_f());
nvgpu_riscv_writel(flcn, priscv_priscv_bcr_ctrl_r(), 0x111);
}
#ifdef CONFIG_NVGPU_FALCON_DEBUG
static void ga10b_riscv_dump_stats(struct nvgpu_falcon *flcn)
{
struct gk20a *g = NULL;
g = flcn->g;
nvgpu_err(g, "<<< FALCON id-%d RISCV DEBUG INFORMATION - START >>>",
flcn->flcn_id);
nvgpu_err(g, " RISCV REGISTERS DUMP");
nvgpu_err(g, "riscv_riscv_mailbox0_r : 0x%x",
nvgpu_falcon_readl(flcn, falcon_falcon_mailbox0_r()));
nvgpu_err(g, "riscv_riscv_mailbox1_r : 0x%x",
nvgpu_falcon_readl(flcn, falcon_falcon_mailbox1_r()));
nvgpu_err(g, "priscv_priscv_cpuctl_r : 0x%x",
nvgpu_riscv_readl(flcn, priscv_priscv_cpuctl_r()));
nvgpu_err(g, "priscv_riscv_irqmask_r : 0x%x",
nvgpu_riscv_readl(flcn, priscv_riscv_irqmask_r()));
nvgpu_err(g, "priscv_riscv_irqdest_r : 0x%x",
nvgpu_riscv_readl(flcn, priscv_riscv_irqdest_r()));
}
void ga10b_falcon_dump_stats(struct nvgpu_falcon *flcn)
{
if (flcn->is_falcon2_enabled) {
ga10b_riscv_dump_stats(flcn);
} else {
gk20a_falcon_dump_stats(flcn);
}
}
bool ga10b_is_falcon_scrubbing_done(struct nvgpu_falcon *flcn)
{
u32 hwcfg = 0U;
hwcfg = nvgpu_falcon_readl(flcn, falcon_falcon_hwcfg2_r());
if (falcon_falcon_hwcfg2_mem_scrubbing_v(hwcfg) ==
falcon_falcon_hwcfg2_mem_scrubbing_pending_v()) {
return false;
} else {
return true;
}
}
bool ga10b_is_falcon_idle(struct nvgpu_falcon *flcn)
{
u32 reg = 0U;
if (flcn->is_falcon2_enabled == false) {
return gk20a_is_falcon_idle(flcn);
} else {
reg = nvgpu_falcon_readl(flcn, falcon_falcon_hwcfg2_r());
nvgpu_pmu_dbg(flcn->g, "HWCFG2: 0x%08x", reg);
if (falcon_falcon_hwcfg2_riscv_br_priv_lockdown_v(reg) ==
falcon_falcon_hwcfg2_riscv_br_priv_lockdown_lock_v()) {
nvgpu_pmu_dbg(flcn->g, "PRIV LOCKDOWN enabled");
return true;
}
}
return true;
}
#endif /* CONFIG_NVGPU_FALCON_DEBUG */

View File

@@ -0,0 +1,35 @@
/*
* GA10B FB ECC
*
* Copyright (c) 2020, 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_FB_ECC_GA10B_H
#define NVGPU_FB_ECC_GA10B_H
struct gk20a;
int ga10b_fb_ecc_init(struct gk20a *g);
void ga10b_fb_ecc_free(struct gk20a *g);
void ga10b_fb_ecc_l2tlb_error_mask(u32 *corrected_error_mask,
u32 *uncorrected_error_mask);
#endif /* NVGPU_FB_ECC_GA10B_H */

View File

@@ -0,0 +1,119 @@
/*
* GA10B FB ECC
*
* Copyright (c) 2020, 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/log.h>
#include <nvgpu/io.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/static_analysis.h>
#include "hal/fb/ecc/fb_ecc_gv11b.h"
#include "fb_ecc_ga10b.h"
#include <nvgpu/hw/ga10b/hw_fb_ga10b.h>
#define FB_ECC_L2TLB_CORRECTED_ERROR_MASK \
(\
fb_mmu_l2tlb_ecc_status_corrected_err_l2tlb_sa_data_m() |\
fb_mmu_l2tlb_ecc_status_corrected_err_l2tlb1_sa_data_m() \
)
#define FB_ECC_L2TLB_UNCORRECTED_ERROR_MASK \
(\
fb_mmu_l2tlb_ecc_status_uncorrected_err_l2tlb_sa_data_m() |\
fb_mmu_l2tlb_ecc_status_uncorrected_err_l2tlb1_sa_data_m() \
)
int ga10b_fb_ecc_init(struct gk20a *g)
{
int err = 0;
err = gv11b_fb_ecc_init(g);
if (err != 0) {
goto init_fb_gv11b_counters_fail;
}
err = NVGPU_ECC_COUNTER_INIT_FB(mmu_l2tlb_ecc_uncorrected_unique_err_count);
if (err != 0) {
goto init_l2tlb_ecc_uncorrected_unique_fail;
}
err = NVGPU_ECC_COUNTER_INIT_FB(mmu_l2tlb_ecc_corrected_unique_err_count);
if (err != 0) {
goto init_l2tlb_ecc_corrected_unique_fail;
}
err = NVGPU_ECC_COUNTER_INIT_FB(mmu_hubtlb_ecc_uncorrected_unique_err_count);
if (err != 0) {
goto init_hubtlb_ecc_uncorrected_unique_fail;
}
err = NVGPU_ECC_COUNTER_INIT_FB(mmu_hubtlb_ecc_corrected_unique_err_count);
if (err != 0) {
goto init_hubtlb_ecc_corrected_unique_fail;
}
err = NVGPU_ECC_COUNTER_INIT_FB(mmu_fillunit_ecc_uncorrected_unique_err_count);
if (err != 0) {
goto init_fillunit_ecc_uncorrected_unique_fail;
}
err = NVGPU_ECC_COUNTER_INIT_FB(mmu_fillunit_ecc_corrected_unique_err_count);
if (err != 0) {
goto init_fillunit_ecc_corrected_unique_fail;
}
return 0;
init_fillunit_ecc_corrected_unique_fail:
NVGPU_ECC_COUNTER_FREE_FB(mmu_fillunit_ecc_uncorrected_unique_err_count);
init_fillunit_ecc_uncorrected_unique_fail:
NVGPU_ECC_COUNTER_FREE_FB(mmu_hubtlb_ecc_corrected_unique_err_count);
init_hubtlb_ecc_corrected_unique_fail:
NVGPU_ECC_COUNTER_FREE_FB(mmu_hubtlb_ecc_uncorrected_unique_err_count);
init_hubtlb_ecc_uncorrected_unique_fail:
NVGPU_ECC_COUNTER_FREE_FB(mmu_l2tlb_ecc_corrected_unique_err_count);
init_l2tlb_ecc_corrected_unique_fail:
NVGPU_ECC_COUNTER_FREE_FB(mmu_l2tlb_ecc_uncorrected_unique_err_count);
init_l2tlb_ecc_uncorrected_unique_fail:
gv11b_fb_ecc_free(g);
init_fb_gv11b_counters_fail:
return err;
}
void ga10b_fb_ecc_free(struct gk20a *g)
{
struct nvgpu_ecc *ecc = &g->ecc;
nvgpu_kfree(g, ecc->fb.mmu_l2tlb_ecc_corrected_unique_err_count);
nvgpu_kfree(g, ecc->fb.mmu_l2tlb_ecc_uncorrected_unique_err_count);
nvgpu_kfree(g, ecc->fb.mmu_hubtlb_ecc_corrected_unique_err_count);
nvgpu_kfree(g, ecc->fb.mmu_hubtlb_ecc_uncorrected_unique_err_count);
nvgpu_kfree(g, ecc->fb.mmu_fillunit_ecc_corrected_unique_err_count);
nvgpu_kfree(g, ecc->fb.mmu_fillunit_ecc_uncorrected_unique_err_count);
gv11b_fb_ecc_free(g);
}
void ga10b_fb_ecc_l2tlb_error_mask(u32 *corrected_error_mask,
u32 *uncorrected_error_mask)
{
*corrected_error_mask = FB_ECC_L2TLB_CORRECTED_ERROR_MASK;
*uncorrected_error_mask = FB_ECC_L2TLB_UNCORRECTED_ERROR_MASK;
return;
}

View File

@@ -0,0 +1,80 @@
/*
* GA100 FB
*
* Copyright (c) 2020, 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/io.h>
#include <nvgpu/nvgpu_init.h>
#include <nvgpu/timers.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/sizes.h>
#include "hal/fb/fb_ga100.h"
#include <nvgpu/hw/ga100/hw_fb_ga100.h>
#define SIZE_256K (SZ_1K << 8U)
#define HW_SCRUB_TIMEOUT_DEFAULT 100 /* usec */
#define HW_SCRUB_TIMEOUT_MAX 2000000 /* usec */
void ga100_fb_init_fs_state(struct gk20a *g)
{
u32 retries = HW_SCRUB_TIMEOUT_MAX / HW_SCRUB_TIMEOUT_DEFAULT;
/* wait for memory to be accessible */
do {
u32 w = nvgpu_readl(g, fb_niso_scrub_status_r());
if (fb_niso_scrub_status_flag_v(w) != 0U) {
nvgpu_log_fn(g, "done");
break;
}
nvgpu_udelay(HW_SCRUB_TIMEOUT_DEFAULT);
--retries;
} while (retries != 0);
}
#ifdef CONFIG_NVGPU_COMPRESSION
u64 ga100_fb_compression_page_size(struct gk20a *g)
{
return SIZE_256K;
}
bool ga100_fb_is_comptagline_mode_enabled(struct gk20a *g)
{
u32 reg = 0U;
bool result = true;
gk20a_busy_noresume(g);
if (nvgpu_is_powered_off(g)) {
goto done;
}
reg = nvgpu_readl(g, fb_mmu_hypervisor_ctl_r());
result = (fb_mmu_hypervisor_ctl_force_cbc_raw_mode_v(reg) ==
fb_mmu_hypervisor_ctl_force_cbc_raw_mode_disable_v());
done:
gk20a_idle_nosuspend(g);
return result;
}
#endif

View File

@@ -0,0 +1,37 @@
/*
* GA100 FB
*
* Copyright (c) 2020, 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_FB_GA100_H
#define NVGPU_FB_GA100_H
struct gk20a;
void ga100_fb_init_fs_state(struct gk20a *g);
#ifdef CONFIG_NVGPU_COMPRESSION
u64 ga100_fb_compression_page_size(struct gk20a *g);
bool ga100_fb_is_comptagline_mode_enabled(struct gk20a *g);
#endif
#endif /* NVGPU_FB_GA100_H */

View File

@@ -0,0 +1,378 @@
/*
* Copyright (c) 2020, 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/log.h>
#include <nvgpu/enabled.h>
#include <nvgpu/io.h>
#include <nvgpu/device.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/soc.h>
#include "fb_ga10b.h"
#include <nvgpu/hw/ga10b/hw_fb_ga10b.h>
#ifdef CONFIG_NVGPU_MIG
#include <nvgpu/grmgr.h>
#endif
#ifdef CONFIG_NVGPU_COMPRESSION
void ga10b_fb_cbc_configure(struct gk20a *g, struct nvgpu_cbc *cbc)
{
u64 base_divisor;
u64 compbit_store_base;
u64 compbit_store_pa;
u32 cbc_max;
compbit_store_pa = nvgpu_mem_get_addr(g, &cbc->compbit_store.mem);
base_divisor = g->ops.cbc.get_base_divisor(g);
compbit_store_base = DIV_ROUND_UP(compbit_store_pa, base_divisor);
cbc_max = nvgpu_readl(g, fb_mmu_cbc_max_r());
cbc_max = set_field(cbc_max,
fb_mmu_cbc_max_comptagline_m(),
fb_mmu_cbc_max_comptagline_f(cbc->max_comptag_lines));
nvgpu_writel(g, fb_mmu_cbc_max_r(), cbc_max);
nvgpu_assert(compbit_store_base < U64(U32_MAX));
nvgpu_writel(g, fb_mmu_cbc_base_r(),
fb_mmu_cbc_base_address_f(U32(compbit_store_base)));
nvgpu_log(g, gpu_dbg_info | gpu_dbg_map_v | gpu_dbg_pte,
"compbit base.pa: 0x%x,%08x cbc_base:0x%llx\n",
(u32)(compbit_store_pa >> 32),
(u32)(compbit_store_pa & 0xffffffffU),
compbit_store_base);
cbc->compbit_store.base_hw = compbit_store_base;
}
#endif
#ifdef CONFIG_NVGPU_MIG
int ga10b_fb_config_veid_smc_map(struct gk20a *g, bool enable)
{
u32 reg_val;
u32 gpu_instance_id;
struct nvgpu_gpu_instance *gpu_instance;
struct nvgpu_gr_syspipe *gr_syspipe;
u32 veid_enable_mask = fb_mmu_hypervisor_ctl_use_smc_veid_tables_f(
fb_mmu_hypervisor_ctl_use_smc_veid_tables_disable_v());
u32 default_remote_swizid = 0U;
if (enable) {
for (gpu_instance_id = 0U;
gpu_instance_id < g->mig.num_gpu_instances;
++gpu_instance_id) {
if (!nvgpu_grmgr_is_mig_type_gpu_instance(
&g->mig.gpu_instance[gpu_instance_id])) {
nvgpu_log(g, gpu_dbg_mig, "skip physical instance[%u]",
gpu_instance_id);
continue;
}
gpu_instance =
&g->mig.gpu_instance[gpu_instance_id];
gr_syspipe = &gpu_instance->gr_syspipe;
reg_val = nvgpu_readl(g,
fb_mmu_smc_eng_cfg_0_r(gr_syspipe->gr_syspipe_id));
if (gpu_instance->is_memory_partition_supported) {
default_remote_swizid = gpu_instance->gpu_instance_id;
}
reg_val = set_field(reg_val,
fb_mmu_smc_eng_cfg_0_remote_swizid_m(),
fb_mmu_smc_eng_cfg_0_remote_swizid_f(
default_remote_swizid));
reg_val = set_field(reg_val,
fb_mmu_smc_eng_cfg_0_mmu_eng_veid_offset_m(),
fb_mmu_smc_eng_cfg_0_mmu_eng_veid_offset_f(
gr_syspipe->veid_start_offset));
reg_val = set_field(reg_val,
fb_mmu_smc_eng_cfg_0_veid_max_m(),
fb_mmu_smc_eng_cfg_0_veid_max_f(
nvgpu_safe_sub_u32(
gr_syspipe->max_veid_count_per_tsg, 1U)));
nvgpu_writel(g,
fb_mmu_smc_eng_cfg_0_r(gr_syspipe->gr_syspipe_id),
reg_val);
nvgpu_log(g, gpu_dbg_mig,
"[%d] gpu_instance_id[%u] default_remote_swizid[%u] "
"gr_instance_id[%u] gr_syspipe_id[%u] "
"veid_start_offset[%u] veid_end_offset[%u] "
"reg_val[%x] ",
gpu_instance_id,
g->mig.gpu_instance[gpu_instance_id].gpu_instance_id,
default_remote_swizid,
gr_syspipe->gr_instance_id,
gr_syspipe->gr_syspipe_id,
gr_syspipe->veid_start_offset,
nvgpu_safe_sub_u32(
nvgpu_safe_add_u32(gr_syspipe->veid_start_offset,
gr_syspipe->max_veid_count_per_tsg), 1U),
reg_val);
}
veid_enable_mask = fb_mmu_hypervisor_ctl_use_smc_veid_tables_f(
fb_mmu_hypervisor_ctl_use_smc_veid_tables_enable_v());
}
reg_val = nvgpu_readl(g, fb_mmu_hypervisor_ctl_r());
reg_val &= ~fb_mmu_hypervisor_ctl_use_smc_veid_tables_m();
reg_val |= veid_enable_mask;
nvgpu_writel(g, fb_mmu_hypervisor_ctl_r(), reg_val);
nvgpu_log(g, gpu_dbg_mig,
"state[%d] reg_val[%x] ",
enable, reg_val);
return 0;
}
int ga10b_fb_set_smc_eng_config(struct gk20a *g, bool enable)
{
u32 reg_val;
u32 index;
u32 local_id;
u32 logical_gpc_id_mask;
struct nvgpu_gr_syspipe *gr_syspipe;
for (index = 0U; index < g->mig.num_gpu_instances; index++) {
if (!nvgpu_grmgr_is_mig_type_gpu_instance(
&g->mig.gpu_instance[index])) {
nvgpu_log(g, gpu_dbg_mig, "skip physical instance[%u]",
index);
continue;
}
gr_syspipe = &g->mig.gpu_instance[index].gr_syspipe;
logical_gpc_id_mask = 0U;
if (enable) {
for (local_id = 0U; local_id < gr_syspipe->num_gpc;
local_id++) {
logical_gpc_id_mask |= BIT32(
gr_syspipe->gpcs[local_id].logical_id);
}
}
reg_val = nvgpu_readl(g, fb_mmu_smc_eng_cfg_1_r(
gr_syspipe->gr_syspipe_id));
reg_val = set_field(reg_val,
fb_mmu_smc_eng_cfg_1_gpc_mask_m(),
fb_mmu_smc_eng_cfg_1_gpc_mask_f(
logical_gpc_id_mask));
nvgpu_writel(g, fb_mmu_smc_eng_cfg_1_r(
gr_syspipe->gr_syspipe_id), reg_val);
nvgpu_log(g, gpu_dbg_mig,
"[%d] gpu_instance_id[%u] gr_syspipe_id[%u] "
"gr_instance_id[%u] logical_gpc_id_mask[%x] "
"reg_val[%x] enable[%d] ",
index,
g->mig.gpu_instance[index].gpu_instance_id,
gr_syspipe->gr_syspipe_id,
gr_syspipe->gr_instance_id,
logical_gpc_id_mask,
reg_val,
enable);
}
return 0;
}
int ga10b_fb_set_remote_swizid(struct gk20a *g, bool enable)
{
u32 reg_val;
u32 index;
u32 lce_id;
struct nvgpu_gr_syspipe *gr_syspipe;
u32 default_remote_swizid = 0U;
struct nvgpu_gpu_instance *gpu_instance;
u32 pbdma_id_mask;
struct nvgpu_next_pbdma_info pbdma_info;
u32 pbdma_index;
for (index = 0U; index < g->mig.num_gpu_instances; index++) {
const struct nvgpu_device *gr_dev =
g->mig.gpu_instance[index].gr_syspipe.gr_dev;
gpu_instance = &g->mig.gpu_instance[index];
gr_syspipe = &gpu_instance->gr_syspipe;
pbdma_id_mask = 0U;
if (!nvgpu_grmgr_is_mig_type_gpu_instance(
&g->mig.gpu_instance[index])) {
nvgpu_log(g, gpu_dbg_mig, "skip physical instance[%u]",
index);
continue;
}
/* Set remote swizid for gr */
reg_val = nvgpu_readl(g,
fb_mmu_smc_eng_cfg_0_r(gr_syspipe->gr_syspipe_id));
reg_val &= ~fb_mmu_smc_eng_cfg_0_remote_swizid_m();
if (enable) {
if (gpu_instance->is_memory_partition_supported) {
default_remote_swizid =
g->mig.gpu_instance[index].gpu_instance_id;
}
reg_val |= fb_mmu_smc_eng_cfg_0_remote_swizid_f(
default_remote_swizid);
}
nvgpu_writel(g,
fb_mmu_smc_eng_cfg_0_r(gr_syspipe->gr_syspipe_id),
reg_val);
g->ops.runlist.get_pbdma_info(g,
gr_dev->next.rl_pri_base,
&pbdma_info);
for (pbdma_index = 0U; pbdma_index < PBDMA_PER_RUNLIST_SIZE;
++pbdma_index) {
if (pbdma_info.pbdma_id[pbdma_index] !=
NVGPU_INVALID_PBDMA_ID) {
pbdma_id_mask |=
BIT32(pbdma_info.pbdma_id[pbdma_index]);
nvgpu_log(g, gpu_dbg_mig,
"gr-[%d %d] gpu_instance_id[%u] gr_syspipe_id[%u] "
"pbdma_id[%u] pbdma_id_mask[%x] enable[%d] ",
index,
pbdma_index,
g->mig.gpu_instance[index].gpu_instance_id,
gr_syspipe->gr_syspipe_id,
pbdma_info.pbdma_id[pbdma_index],
pbdma_id_mask,
enable);
}
}
nvgpu_log(g, gpu_dbg_mig,
"gr-[%d] gpu_instance_id[%u] gr_syspipe_id[%u] "
"gr_instance_id[%u] pbdma_id_mask[%x] reg_val[%x] "
"enable[%d] ",
index,
g->mig.gpu_instance[index].gpu_instance_id,
gr_syspipe->gr_syspipe_id,
gr_syspipe->gr_instance_id,
pbdma_id_mask, reg_val, enable);
/* Set remote swizid for lces */
for (lce_id = 0U; lce_id < gpu_instance->num_lce;
lce_id++) {
const struct nvgpu_device *lce =
gpu_instance->lce_devs[lce_id];
reg_val = nvgpu_readl(g,
fb_mmu_mmu_eng_id_cfg_r(lce->fault_id));
reg_val &= ~fb_mmu_mmu_eng_id_cfg_remote_swizid_m();
if (enable) {
reg_val |= fb_mmu_mmu_eng_id_cfg_remote_swizid_f(
default_remote_swizid);
}
g->ops.runlist.get_pbdma_info(g,
lce->next.rl_pri_base,
&pbdma_info);
for (pbdma_index = 0U; pbdma_index < PBDMA_PER_RUNLIST_SIZE;
++pbdma_index) {
if (pbdma_info.pbdma_id[pbdma_index] !=
NVGPU_INVALID_PBDMA_ID) {
pbdma_id_mask |=
BIT32(pbdma_info.pbdma_id[pbdma_index]);
nvgpu_log(g, gpu_dbg_mig,
"lce-[%d %d] gpu_instance_id[%u] gr_syspipe_id[%u] "
"pbdma_id[%u] pbdma_id_mask[%x] enable[%d] ",
index,
pbdma_index,
g->mig.gpu_instance[index].gpu_instance_id,
gr_syspipe->gr_syspipe_id,
pbdma_info.pbdma_id[pbdma_index],
pbdma_id_mask, enable);
}
}
nvgpu_writel(g,
fb_mmu_mmu_eng_id_cfg_r(lce->fault_id),
reg_val);
nvgpu_log(g, gpu_dbg_mig,
"lce-[%d] gpu_instance_id[%u] gr_syspipe_id[%u] "
"gr_instance_id[%u] engine_id[%u] inst_id[%u] "
"fault_id[%u] pbdma_id_mask[%x] reg_val[%x] "
"enable[%d] ",
index,
g->mig.gpu_instance[index].gpu_instance_id,
gr_syspipe->gr_syspipe_id,
gr_syspipe->gr_instance_id,
lce->engine_id, lce->inst_id,
lce->fault_id, pbdma_id_mask,
reg_val, enable);
}
/* Set remote swizid for its pbdma */
while (pbdma_id_mask != 0U) {
u32 fault_id;
u32 pbdma_id = nvgpu_safe_sub_u32(
nvgpu_ffs(pbdma_id_mask), 1UL);
fault_id =
g->ops.pbdma.get_mmu_fault_id(g, pbdma_id);
reg_val = nvgpu_readl(g,
fb_mmu_mmu_eng_id_cfg_r(fault_id));
reg_val &= ~fb_mmu_mmu_eng_id_cfg_remote_swizid_m();
if (enable) {
reg_val |= fb_mmu_mmu_eng_id_cfg_remote_swizid_f(
default_remote_swizid);
}
nvgpu_writel(g,
fb_mmu_mmu_eng_id_cfg_r(fault_id),
reg_val);
nvgpu_log(g, gpu_dbg_mig,
"gpu_instance_id[%u] gr_syspipe_id[%u] "
"pbdma_id[%u] fault_id[%u] pbdma_id_mask[%x] "
"reg_val[%x] enable[%d] ",
g->mig.gpu_instance[index].gpu_instance_id,
gr_syspipe->gr_syspipe_id,
pbdma_id, fault_id, pbdma_id_mask,
reg_val, enable);
pbdma_id_mask ^= BIT32(pbdma_id);
}
}
return 0;
}
#endif

View File

@@ -0,0 +1,63 @@
/*
* GA10B FB
*
* Copyright (c) 2020-2021, 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_FB_GA10B_H
#define NVGPU_FB_GA10B_H
#define VPR_INFO_FETCH_POLL_MS 5U
#define ALIGN_HI32(x) nvgpu_safe_sub_u32(32U, (x))
struct gk20a;
void ga10b_fb_init_fs_state(struct gk20a *g);
void ga10b_fb_init_hw(struct gk20a *g);
u32 ga10b_fb_get_num_active_ltcs(struct gk20a *g);
void ga10b_fb_dump_vpr_info(struct gk20a *g);
void ga10b_fb_dump_wpr_info(struct gk20a *g);
void ga10b_fb_read_wpr_info(struct gk20a *g, u64 *wpr_base, u64 *wpr_size);
int ga10b_fb_vpr_info_fetch(struct gk20a *g);
#if defined(CONFIG_NVGPU_HAL_NON_FUSA)
#if defined(__KERNEL__)
void ga10b_init_nvlink_soc_credits(struct gk20a *g);
#else
static inline void ga10b_init_nvlink_soc_credits(struct gk20a *g)
{
}
#endif
#endif
#ifdef CONFIG_NVGPU_COMPRESSION
void ga10b_fb_cbc_configure(struct gk20a *g, struct nvgpu_cbc *cbc);
#endif
#ifdef CONFIG_NVGPU_MIG
int ga10b_fb_config_veid_smc_map(struct gk20a *g, bool enable);
int ga10b_fb_set_smc_eng_config(struct gk20a *g, bool enable);
int ga10b_fb_set_remote_swizid(struct gk20a *g, bool enable);
#endif
int ga10b_fb_set_atomic_mode(struct gk20a *g);
#endif /* NVGPU_FB_GA10B_H */

View File

@@ -0,0 +1,313 @@
/*
* GA10B FB
*
* Copyright (c) 2020-2021, 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/log.h>
#include <nvgpu/enabled.h>
#include <nvgpu/errata.h>
#include <nvgpu/io.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/static_analysis.h>
#include "hal/fb/fb_gm20b.h"
#include "hal/fb/fb_ga10b.h"
#include "intr/fb_intr_ga10b.h"
#include <nvgpu/hw/ga10b/hw_fb_ga10b.h>
#define HSHUB_ID_0 0U
int ga10b_fb_set_atomic_mode(struct gk20a *g)
{
u32 reg_val;
u32 num_hshubs = 0U;
u32 hshub_ltcs, fbhub_ltcs;
u32 i;
/*
* NV_PFB_PRI_MMU_CTRL_ATOMIC_CAPABILITY_MODE to RMW MODE
* NV_PFB_PRI_MMU_CTRL_ATOMIC_CAPABILITY_SYS_NCOH_MODE to L2
*/
reg_val = nvgpu_readl(g, fb_mmu_ctrl_r());
reg_val = set_field(reg_val, fb_mmu_ctrl_atomic_capability_mode_m(),
fb_mmu_ctrl_atomic_capability_mode_rmw_f());
reg_val = set_field(reg_val,
fb_mmu_ctrl_atomic_capability_sys_ncoh_mode_m(),
fb_mmu_ctrl_atomic_capability_sys_ncoh_mode_l2_f());
nvgpu_writel(g, fb_mmu_ctrl_r(), reg_val);
/* NV_PFB_HSHUB_NUM_ACTIVE_LTCS_HUB_SYS_ATOMIC_MODE to USE_RMW */
reg_val = nvgpu_readl(g, fb_fbhub_num_active_ltcs_r());
reg_val = set_field(reg_val,
fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_m(),
fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_use_rmw_f());
nvgpu_writel(g, fb_fbhub_num_active_ltcs_r(), reg_val);
nvgpu_writel(g, fb_hshub_num_active_ltcs_r(HSHUB_ID_0), reg_val);
/*
* Note: For iGPU, num_hshubs should be 1.
* For num_hshubs = 1, NVLINK_CAPABILITY bits are invalid and
* are ignored.
*/
reg_val = nvgpu_readl(g, fb_hshub_prg_config_r(HSHUB_ID_0));
num_hshubs = fb_hshub_prg_config_num_hshubs_v(reg_val);
nvgpu_assert(num_hshubs == 1U);
/*
* HW expects that SW copies the value of
* FBHUB registers over into HSHUBs since
* they are supposed to have the exact same fields.
*/
fbhub_ltcs = nvgpu_readl(g, fb_fbhub_num_active_ltcs_r());
for (i = 0U; i < num_hshubs; i++) {
hshub_ltcs = nvgpu_readl(g, fb_hshub_num_active_ltcs_r(i));
if (hshub_ltcs != fbhub_ltcs) {
nvgpu_writel(g,
fb_hshub_num_active_ltcs_r(i), fbhub_ltcs);
}
}
return 0;
}
static void ga10b_fb_check_ltcs_count(struct gk20a *g)
{
u32 reg_val;
u32 ltcs_count;
/*
* Number of active ltcs should be same in below registers
* - pri_ringmaster_enum_ltc_r
* - fb_mmu_num_active_ltcs_r
* - fb_fbhub_num_active_ltcs_r
*
* top_num_ltcs_r gives max number of ltcs. If chip is floorswept
* then max ltcs count may not match active ltcs count.
*/
ltcs_count = g->ops.priv_ring.enum_ltc(g);
if (fb_mmu_num_active_ltcs_count_v(
nvgpu_readl(g, fb_mmu_num_active_ltcs_r())) != ltcs_count) {
nvgpu_err(g,
"mmu_num_active_ltcs = %u not equal to enum_ltc() = %u",
fb_mmu_num_active_ltcs_count_v(
nvgpu_readl(g, fb_mmu_num_active_ltcs_r())),
ltcs_count);
} else {
nvgpu_log(g, gpu_dbg_info, "mmu active ltcs %u",
fb_mmu_num_active_ltcs_count_v(
nvgpu_readl(g, fb_mmu_num_active_ltcs_r())));
}
reg_val = nvgpu_readl(g, fb_fbhub_num_active_ltcs_r());
if (fb_fbhub_num_active_ltcs_count_v(reg_val) != ltcs_count) {
nvgpu_err(g,
"fbhub active_ltcs = %u != ringmaster_enum_ltc() = %u",
fb_fbhub_num_active_ltcs_count_v(reg_val),
ltcs_count);
/*
* set num_active_ltcs = ltcs count in pri_ringmaster_enum_ltc_r
*/
if (nvgpu_is_errata_present(g, NVGPU_ERRATA_2969956)) {
reg_val = set_field(reg_val,
fb_fbhub_num_active_ltcs_count_m(),
fb_fbhub_num_active_ltcs_count_f(ltcs_count));
nvgpu_writel(g, fb_fbhub_num_active_ltcs_r(), reg_val);
nvgpu_err(g, "Updated fbhub active ltcs 0x%x",
nvgpu_readl(g, fb_fbhub_num_active_ltcs_r()));
}
} else {
nvgpu_log(g, gpu_dbg_info, "fbhub active ltcs 0x%x",
nvgpu_readl(g, fb_fbhub_num_active_ltcs_r()));
}
}
void ga10b_fb_init_fs_state(struct gk20a *g)
{
nvgpu_log(g, gpu_dbg_fn, "initialize ga10b fb");
#if defined(CONFIG_NVGPU_HAL_NON_FUSA)
ga10b_init_nvlink_soc_credits(g);
#endif
ga10b_fb_check_ltcs_count(g);
if (!nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) {
/* Bypass MMU check for non-secure boot. For
* secure-boot,this register write has no-effect
*/
nvgpu_writel(g, fb_priv_mmu_phy_secure_r(), U32_MAX);
}
}
void ga10b_fb_init_hw(struct gk20a *g)
{
gm20b_fb_init_hw(g);
ga10b_fb_intr_vectorid_init(g);
if (g->ops.fb.intr.enable != NULL) {
g->ops.fb.intr.enable(g);
}
}
u32 ga10b_fb_get_num_active_ltcs(struct gk20a *g)
{
return nvgpu_readl(g, fb_mmu_num_active_ltcs_r());
}
void ga10b_fb_read_wpr_info(struct gk20a *g, u64 *wpr_base, u64 *wpr_size)
{
u32 val = 0U;
u64 wpr_start = 0U;
u64 wpr_end = 0U;
val = fb_mmu_wpr1_addr_lo_val_v(
nvgpu_readl(g, fb_mmu_wpr1_addr_lo_r()));
wpr_start = hi32_lo32_to_u64(
(val >> ALIGN_HI32(fb_mmu_wpr1_addr_lo_val_alignment_v())),
(val << fb_mmu_wpr1_addr_lo_val_alignment_v()));
val = fb_mmu_wpr1_addr_hi_val_v(
nvgpu_readl(g, fb_mmu_wpr1_addr_hi_r()));
wpr_end = hi32_lo32_to_u64(
(val >> ALIGN_HI32(fb_mmu_wpr1_addr_hi_val_alignment_v())),
(val << fb_mmu_wpr1_addr_hi_val_alignment_v()));
*wpr_base = wpr_start;
*wpr_size = nvgpu_safe_sub_u64(wpr_end, wpr_start);
}
void ga10b_fb_dump_wpr_info(struct gk20a *g)
{
u32 val;
u32 allow_read, allow_write;
u64 wpr1_addr_lo, wpr1_addr_hi;
u64 wpr2_addr_lo, wpr2_addr_hi;
allow_read = nvgpu_readl(g, fb_mmu_wpr_allow_read_r());
allow_write = nvgpu_readl(g, fb_mmu_wpr_allow_write_r());
val = fb_mmu_wpr1_addr_lo_val_v(nvgpu_readl(g, fb_mmu_wpr1_addr_lo_r()));
wpr1_addr_lo = hi32_lo32_to_u64(
(val >> ALIGN_HI32(fb_mmu_wpr1_addr_lo_val_alignment_v())),
(val << fb_mmu_wpr1_addr_lo_val_alignment_v()));
val = fb_mmu_wpr1_addr_hi_val_v(nvgpu_readl(g, fb_mmu_wpr1_addr_hi_r()));
wpr1_addr_hi = hi32_lo32_to_u64(
(val >> ALIGN_HI32(fb_mmu_wpr1_addr_hi_val_alignment_v())),
(val << fb_mmu_wpr1_addr_hi_val_alignment_v()));
val = fb_mmu_wpr2_addr_lo_val_v(nvgpu_readl(g, fb_mmu_wpr2_addr_lo_r()));
wpr2_addr_lo = hi32_lo32_to_u64(
(val >> ALIGN_HI32(fb_mmu_wpr2_addr_lo_val_alignment_v())),
(val << fb_mmu_wpr2_addr_lo_val_alignment_v()));
val = fb_mmu_wpr2_addr_hi_val_v(nvgpu_readl(g, fb_mmu_wpr2_addr_hi_r()));
wpr2_addr_hi = hi32_lo32_to_u64(
(val >> ALIGN_HI32(fb_mmu_wpr2_addr_hi_val_alignment_v())),
(val << fb_mmu_wpr2_addr_hi_val_alignment_v()));
nvgpu_err(g, "WPR: allow_read: 0x%08x allow_write: 0x%08x "
"wpr1_addr_lo: 0x%08llx wpr1_addr_hi: 0x%08llx "
"wpr2_addr_lo: 0x%08llx wpr2_addr_hi: 0x%08llx",
allow_read, allow_write,
wpr1_addr_lo, wpr1_addr_hi,
wpr2_addr_lo, wpr2_addr_hi);
}
void ga10b_fb_dump_vpr_info(struct gk20a *g)
{
u32 val;
u32 cya_lo, cya_hi;
u64 addr_lo, addr_hi;
val = fb_mmu_vpr_addr_lo_val_v(
nvgpu_readl(g, fb_mmu_vpr_addr_lo_r()));
addr_lo = hi32_lo32_to_u64(
(val >> ALIGN_HI32(fb_mmu_vpr_addr_lo_val_alignment_v())),
(val << fb_mmu_vpr_addr_lo_val_alignment_v()));
val = fb_mmu_vpr_addr_hi_val_v(
nvgpu_readl(g, fb_mmu_vpr_addr_hi_r()));
addr_hi = hi32_lo32_to_u64(
(val >> ALIGN_HI32(fb_mmu_vpr_addr_hi_val_alignment_v())),
(val << fb_mmu_vpr_addr_hi_val_alignment_v()));
cya_lo = nvgpu_readl(g, fb_mmu_vpr_cya_lo_r());
cya_hi = nvgpu_readl(g, fb_mmu_vpr_cya_hi_r());
nvgpu_err(g, "VPR: addr_lo: 0x%08llx addr_hi: 0x%08llx "
"cya_lo: 0x%08x cya_hi: 0x%08x",
addr_lo, addr_hi, cya_lo, cya_hi);
}
static int ga10b_fb_vpr_mode_fetch_poll(struct gk20a *g, unsigned int poll_ms)
{
struct nvgpu_timeout timeout;
int err = 0;
u32 val = 0U;
u32 delay = POLL_DELAY_MIN_US;
err = nvgpu_timeout_init(g, &timeout, poll_ms, NVGPU_TIMER_CPU_TIMER);
if (err != 0) {
nvgpu_err(g, "nvgpu_timeout_init failed err=%d", err);
return err;
}
do {
val = nvgpu_readl(g, fb_mmu_vpr_mode_r());
if (fb_mmu_vpr_mode_fetch_v(val) ==
fb_mmu_vpr_mode_fetch_false_v()) {
return 0;
}
nvgpu_usleep_range(delay, delay * 2U);
delay = min_t(u32, delay << 1, POLL_DELAY_MAX_US);
} while (nvgpu_timeout_expired(&timeout) == 0);
return -ETIMEDOUT;
}
int ga10b_fb_vpr_info_fetch(struct gk20a *g)
{
int err;
err = ga10b_fb_vpr_mode_fetch_poll(g, VPR_INFO_FETCH_POLL_MS);
if (err != 0) {
return err;
}
nvgpu_writel(g, fb_mmu_vpr_mode_r(),
fb_mmu_vpr_mode_fetch_true_f());
err = ga10b_fb_vpr_mode_fetch_poll(g, VPR_INFO_FETCH_POLL_MS);
if (err != 0) {
nvgpu_err(g, "ga10b_fb_vpr_mode_fetch_poll failed!");
}
return err;
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2020, 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_FB_MMU_FAULT_GA10B_H
#define NVGPU_FB_MMU_FAULT_GA10B_H
#include <nvgpu/types.h>
struct gk20a;
void ga10b_fb_handle_mmu_fault(struct gk20a *g, u32 intr_unit_bitmask);
#endif /* NVGPU_FB_MMU_FAULT_GA10B_H */

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 2021, 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/log.h>
#include <nvgpu/types.h>
#include <nvgpu/nvgpu_mem.h>
#include <nvgpu/io.h>
#include <nvgpu/utils.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/mmu_fault.h>
#include <nvgpu/cic.h>
#include "hal/fb/fb_mmu_fault_gv11b.h"
#include "hal/mm/mmu_fault/mmu_fault_gv11b.h"
#include "fb_mmu_fault_ga10b.h"
#include "nvgpu/hw/ga10b/hw_fb_ga10b.h"
void ga10b_fb_handle_mmu_fault(struct gk20a *g, u32 intr_unit_bitmask)
{
u32 fault_status = g->ops.fb.read_mmu_fault_status(g);
nvgpu_log(g, gpu_dbg_intr, "mmu_fault_status = 0x%08x", fault_status);
if ((intr_unit_bitmask & BIT32(NVGPU_CIC_INTR_UNIT_MMU_INFO_FAULT)) != 0) {
gv11b_fb_handle_dropped_mmu_fault(g, fault_status);
gv11b_mm_mmu_fault_handle_other_fault_notify(g, fault_status);
}
if (gv11b_fb_is_fault_buf_enabled(g,
NVGPU_MMU_FAULT_NONREPLAY_REG_INDX)) {
if ((intr_unit_bitmask &
BIT32(NVGPU_CIC_INTR_UNIT_MMU_NON_REPLAYABLE_FAULT)) != 0) {
gv11b_mm_mmu_fault_handle_nonreplay_replay_fault(g,
fault_status,
NVGPU_MMU_FAULT_NONREPLAY_REG_INDX);
/*
* When all the faults are processed,
* GET and PUT will have same value and mmu fault status
* bit will be reset by HW
*/
}
if ((intr_unit_bitmask &
BIT32(NVGPU_CIC_INTR_UNIT_MMU_NON_REPLAYABLE_FAULT_ERROR)) != 0) {
gv11b_fb_handle_nonreplay_fault_overflow(g,
fault_status);
}
}
#ifdef CONFIG_NVGPU_REPLAYABLE_FAULT
if (gv11b_fb_is_fault_buf_enabled(g,
NVGPU_MMU_FAULT_REPLAY_REG_INDX)) {
if ((intr_unit_bitmask &
BIT32(NVGPU_CIC_INTR_UNIT_MMU_REPLAYABLE_FAULT)) != 0) {
gv11b_mm_mmu_fault_handle_nonreplay_replay_fault(g,
fault_status,
NVGPU_MMU_FAULT_REPLAY_REG_INDX);
}
if ((intr_unit_bitmask &
BIT32(NVGPU_CIC_INTR_UNIT_MMU_REPLAYABLE_FAULT_ERROR)) != 0) {
gv11b_fb_handle_replay_fault_overflow(g,
fault_status);
}
}
#endif
nvgpu_log(g, gpu_dbg_intr, "clear mmu fault status");
g->ops.fb.write_mmu_fault_status(g,
fb_mmu_fault_status_valid_clear_f());
}

View File

@@ -0,0 +1,34 @@
/*
* GA10B FB INTR ECC
*
* Copyright (c) 2020, 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_FB_INTR_ECC_GA10B_H
#define NVGPU_FB_INTR_ECC_GA10B_H
struct gk20a;
void ga10b_fb_intr_handle_ecc_l2tlb(struct gk20a *g, u32 ecc_status);
void ga10b_fb_intr_handle_ecc_hubtlb(struct gk20a *g, u32 ecc_status);
void ga10b_fb_intr_handle_ecc_fillunit(struct gk20a *g, u32 ecc_status);
#endif /* NVGPU_FB_INTR_ECC_GA10B_H */

View File

@@ -0,0 +1,194 @@
/*
* GA10B FB INTR ECC
*
* Copyright (c) 2020, 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/log.h>
#include <nvgpu/io.h>
#include <nvgpu/gk20a.h>
#include "hal/fb/intr/fb_intr_ecc_gv11b.h"
#include "fb_intr_ecc_ga10b.h"
#include <nvgpu/hw/ga10b/hw_fb_ga10b.h>
void ga10b_fb_intr_handle_ecc_l2tlb(struct gk20a *g, u32 ecc_status)
{
u32 corrected_cnt, uncorrected_cnt;
u32 unique_corrected_delta, unique_uncorrected_delta;
u32 unique_corrected_overflow, unique_uncorrected_overflow;
/*
* The unique counters tracks the instances of ecc (un)corrected errors
* where the present, previous error addresses are different.
*/
corrected_cnt = nvgpu_readl(g,
fb_mmu_l2tlb_ecc_corrected_err_count_r());
uncorrected_cnt = nvgpu_readl(g,
fb_mmu_l2tlb_ecc_uncorrected_err_count_r());
unique_corrected_delta =
fb_mmu_l2tlb_ecc_corrected_err_count_unique_v(corrected_cnt);
unique_uncorrected_delta =
fb_mmu_l2tlb_ecc_uncorrected_err_count_unique_v(uncorrected_cnt);
unique_corrected_overflow = ecc_status &
fb_mmu_l2tlb_ecc_status_corrected_err_unique_counter_overflow_m();
unique_uncorrected_overflow = ecc_status &
fb_mmu_l2tlb_ecc_status_uncorrected_err_unique_counter_overflow_m();
/* Handle overflow */
if (unique_corrected_overflow != 0U) {
unique_corrected_delta +=
BIT32(fb_mmu_l2tlb_ecc_corrected_err_count_unique_s());
}
if (unique_uncorrected_overflow != 0U) {
unique_uncorrected_delta +=
BIT32(fb_mmu_l2tlb_ecc_uncorrected_err_count_unique_s());
}
g->ecc.fb.mmu_l2tlb_ecc_corrected_unique_err_count[0].counter =
nvgpu_safe_add_u32(
g->ecc.fb.mmu_l2tlb_ecc_corrected_unique_err_count[0].counter,
unique_corrected_delta);
g->ecc.fb.mmu_l2tlb_ecc_uncorrected_unique_err_count[0].counter =
nvgpu_safe_add_u32(
g->ecc.fb.mmu_l2tlb_ecc_uncorrected_unique_err_count[0].counter,
unique_uncorrected_delta);
if ((unique_corrected_overflow != 0U) || (unique_uncorrected_overflow != 0U)) {
nvgpu_info(g, "mmu l2tlb ecc counter overflow!");
}
/*
* Handle the legacy counters.
*/
gv11b_fb_intr_handle_ecc_l2tlb(g, ecc_status);
}
void ga10b_fb_intr_handle_ecc_hubtlb(struct gk20a *g, u32 ecc_status)
{
u32 corrected_cnt, uncorrected_cnt;
u32 unique_corrected_delta, unique_uncorrected_delta;
u32 unique_corrected_overflow, unique_uncorrected_overflow;
/*
* The unique counters tracks the instances of ecc (un)corrected errors
* where the present, previous error addresses are different.
*/
corrected_cnt = nvgpu_readl(g,
fb_mmu_hubtlb_ecc_corrected_err_count_r());
uncorrected_cnt = nvgpu_readl(g,
fb_mmu_hubtlb_ecc_uncorrected_err_count_r());
unique_corrected_delta =
fb_mmu_hubtlb_ecc_corrected_err_count_unique_v(corrected_cnt);
unique_uncorrected_delta =
fb_mmu_hubtlb_ecc_uncorrected_err_count_unique_v(uncorrected_cnt);
unique_corrected_overflow = ecc_status &
fb_mmu_hubtlb_ecc_status_corrected_err_unique_counter_overflow_m();
unique_uncorrected_overflow = ecc_status &
fb_mmu_hubtlb_ecc_status_uncorrected_err_unique_counter_overflow_m();
/* Handle overflow */
if (unique_corrected_overflow != 0U) {
unique_corrected_delta +=
BIT32(fb_mmu_hubtlb_ecc_corrected_err_count_unique_s());
}
if (unique_uncorrected_overflow != 0U) {
unique_uncorrected_delta +=
BIT32(fb_mmu_hubtlb_ecc_uncorrected_err_count_unique_s());
}
g->ecc.fb.mmu_hubtlb_ecc_corrected_unique_err_count[0].counter =
nvgpu_safe_add_u32(
g->ecc.fb.mmu_hubtlb_ecc_corrected_unique_err_count[0].counter,
unique_corrected_delta);
g->ecc.fb.mmu_hubtlb_ecc_uncorrected_unique_err_count[0].counter =
nvgpu_safe_add_u32(
g->ecc.fb.mmu_hubtlb_ecc_uncorrected_unique_err_count[0].counter,
unique_uncorrected_delta);
if ((unique_corrected_overflow != 0U) || (unique_uncorrected_overflow != 0U)) {
nvgpu_info(g, "mmu hubtlb ecc counter overflow!");
}
/*
* Handle the legacy counters.
*/
gv11b_fb_intr_handle_ecc_hubtlb(g, ecc_status);
}
void ga10b_fb_intr_handle_ecc_fillunit(struct gk20a *g, u32 ecc_status)
{
u32 corrected_cnt, uncorrected_cnt;
u32 unique_corrected_delta, unique_uncorrected_delta;
u32 unique_corrected_overflow, unique_uncorrected_overflow;
/*
* The unique counters tracks the instances of ecc (un)corrected errors
* where the present, previous error addresses are different.
*/
corrected_cnt = nvgpu_readl(g,
fb_mmu_fillunit_ecc_corrected_err_count_r());
uncorrected_cnt = nvgpu_readl(g,
fb_mmu_fillunit_ecc_uncorrected_err_count_r());
unique_corrected_delta =
fb_mmu_fillunit_ecc_corrected_err_count_unique_v(corrected_cnt);
unique_uncorrected_delta =
fb_mmu_fillunit_ecc_uncorrected_err_count_unique_v(uncorrected_cnt);
unique_corrected_overflow = ecc_status &
fb_mmu_fillunit_ecc_status_corrected_err_unique_counter_overflow_m();
unique_uncorrected_overflow = ecc_status &
fb_mmu_fillunit_ecc_status_uncorrected_err_unique_counter_overflow_m();
/* Handle overflow */
if (unique_corrected_overflow != 0U) {
unique_corrected_delta +=
BIT32(fb_mmu_fillunit_ecc_corrected_err_count_unique_s());
}
if (unique_uncorrected_overflow != 0U) {
unique_uncorrected_delta +=
BIT32(fb_mmu_fillunit_ecc_uncorrected_err_count_unique_s());
}
g->ecc.fb.mmu_fillunit_ecc_corrected_unique_err_count[0].counter =
nvgpu_safe_add_u32(
g->ecc.fb.mmu_fillunit_ecc_corrected_unique_err_count[0].counter,
unique_corrected_delta);
g->ecc.fb.mmu_fillunit_ecc_uncorrected_unique_err_count[0].counter =
nvgpu_safe_add_u32(
g->ecc.fb.mmu_fillunit_ecc_uncorrected_unique_err_count[0].counter,
unique_uncorrected_delta);
if ((unique_corrected_overflow != 0U) || (unique_uncorrected_overflow != 0U)) {
nvgpu_info(g, "mmu fillunit ecc counter overflow!");
}
/*
* Handle the legacy counters.
*/
gv11b_fb_intr_handle_ecc_fillunit(g, ecc_status);
}

View File

@@ -0,0 +1,35 @@
/*
* GA10B FB INTR
*
* Copyright (c) 2020, 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_FB_INTR_GA10B_H
#define NVGPU_FB_INTR_GA10B_H
struct gk20a;
void ga10b_fb_intr_vectorid_init(struct gk20a *g);
void ga10b_fb_intr_enable(struct gk20a *g);
void ga10b_fb_intr_disable(struct gk20a *g);
void ga10b_fb_intr_isr(struct gk20a *g, u32 intr_unit_bitmask);
#endif /* NVGPU_FB_INTR_GA10B_H */

View File

@@ -0,0 +1,133 @@
/*
* GA10B FB
*
* Copyright (c) 2021, 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/log.h>
#include <nvgpu/io.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/mc.h>
#include <nvgpu/cic.h>
#include "hal/fb/intr/fb_intr_ecc_gv11b.h"
#include "hal/fb/fb_mmu_fault_ga10b.h"
#include "fb_intr_ga10b.h"
#include <nvgpu/hw/ga10b/hw_fb_ga10b.h>
void ga10b_fb_intr_vectorid_init(struct gk20a *g)
{
u32 ecc_error, info_fault, nonreplay_fault;
#ifdef CONFIG_NVGPU_REPLAYABLE_FAULT
u32 replay_fault;
#endif
u32 vectorid;
ecc_error = nvgpu_readl(g, fb_mmu_int_vector_ecc_error_r());
vectorid = fb_mmu_int_vector_ecc_error_vector_v(ecc_error);
nvgpu_cic_intr_unit_vectorid_init(g, NVGPU_CIC_INTR_UNIT_MMU_FAULT_ECC_ERROR,
&vectorid, NVGPU_CIC_INTR_VECTORID_SIZE_ONE);
info_fault = nvgpu_readl(g, fb_mmu_int_vector_info_fault_r());
vectorid = fb_mmu_int_vector_info_fault_vector_v(info_fault);
nvgpu_cic_intr_unit_vectorid_init(g, NVGPU_CIC_INTR_UNIT_MMU_INFO_FAULT,
&vectorid, NVGPU_CIC_INTR_VECTORID_SIZE_ONE);
nonreplay_fault = nvgpu_readl(g, fb_mmu_int_vector_fault_r(
NVGPU_MMU_FAULT_NONREPLAY_REG_INDX));
vectorid = fb_mmu_int_vector_fault_notify_v(nonreplay_fault);
nvgpu_cic_intr_unit_vectorid_init(g, NVGPU_CIC_INTR_UNIT_MMU_NON_REPLAYABLE_FAULT,
&vectorid, NVGPU_CIC_INTR_VECTORID_SIZE_ONE);
vectorid = fb_mmu_int_vector_fault_error_v(nonreplay_fault);
nvgpu_cic_intr_unit_vectorid_init(g, NVGPU_CIC_INTR_UNIT_MMU_NON_REPLAYABLE_FAULT_ERROR,
&vectorid, NVGPU_CIC_INTR_VECTORID_SIZE_ONE);
#ifdef CONFIG_NVGPU_REPLAYABLE_FAULT
replay_fault = nvgpu_readl(g, fb_mmu_int_vector_fault_r(
NVGPU_MMU_FAULT_REPLAY_REG_INDX));
vectorid = fb_mmu_int_vector_fault_notify_v(replay_fault);
nvgpu_cic_intr_unit_vectorid_init(g, NVGPU_CIC_INTR_UNIT_MMU_REPLAYABLE_FAULT,
&vectorid, NVGPU_CIC_INTR_VECTORID_SIZE_ONE);
vectorid = fb_mmu_int_vector_fault_error_v(replay_fault);
nvgpu_cic_intr_unit_vectorid_init(g, NVGPU_CIC_INTR_UNIT_MMU_REPLAYABLE_FAULT_ERROR,
&vectorid, NVGPU_CIC_INTR_VECTORID_SIZE_ONE);
#endif
/* TBD hub_access_cntr_intr */
}
void ga10b_fb_intr_enable(struct gk20a *g)
{
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_FAULT_ECC_ERROR, NVGPU_CIC_INTR_ENABLE);
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_INFO_FAULT, NVGPU_CIC_INTR_ENABLE);
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_NON_REPLAYABLE_FAULT, NVGPU_CIC_INTR_ENABLE);
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_NON_REPLAYABLE_FAULT_ERROR, NVGPU_CIC_INTR_ENABLE);
#ifdef CONFIG_NVGPU_REPLAYABLE_FAULT
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_REPLAYABLE_FAULT, NVGPU_CIC_INTR_ENABLE);
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_REPLAYABLE_FAULT_ERROR, NVGPU_CIC_INTR_ENABLE);
#endif
/* TBD hub_access_cntr_intr */
}
void ga10b_fb_intr_disable(struct gk20a *g)
{
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_FAULT_ECC_ERROR, NVGPU_CIC_INTR_DISABLE);
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_INFO_FAULT, NVGPU_CIC_INTR_DISABLE);
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_NON_REPLAYABLE_FAULT, NVGPU_CIC_INTR_DISABLE);
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_NON_REPLAYABLE_FAULT_ERROR, NVGPU_CIC_INTR_DISABLE);
#ifdef CONFIG_NVGPU_REPLAYABLE_FAULT
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_REPLAYABLE_FAULT, NVGPU_CIC_INTR_DISABLE);
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_MMU_REPLAYABLE_FAULT_ERROR, NVGPU_CIC_INTR_DISABLE);
#endif
/* TBD hub_access_cntr_intr */
}
void ga10b_fb_intr_isr(struct gk20a *g, u32 intr_unit_bitmask)
{
nvgpu_mutex_acquire(&g->mm.hub_isr_mutex);
nvgpu_log(g, gpu_dbg_intr, "MMU Fault");
if ((intr_unit_bitmask & BIT32(NVGPU_CIC_INTR_UNIT_MMU_FAULT_ECC_ERROR)) !=
0U) {
g->ops.fb.intr.handle_ecc(g);
}
ga10b_fb_handle_mmu_fault(g, intr_unit_bitmask);
nvgpu_mutex_release(&g->mm.hub_isr_mutex);
}

View File

@@ -0,0 +1,372 @@
/*
* Copyright (c) 2021, 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/gk20a.h>
#include <nvgpu/utils.h>
#include <nvgpu/bitops.h>
#include <nvgpu/bug.h>
#include <nvgpu/io.h>
#include <nvgpu/kmem.h>
#include <nvgpu/static_analysis.h>
#include <nvgpu/timers.h>
#include <nvgpu/fuse.h>
#include <nvgpu/fb.h>
#include <nvgpu/nvgpu_mem.h>
#include <nvgpu/dma.h>
#include "hal/fb/vab/vab_ga10b.h"
#include <nvgpu/hw/ga10b/hw_fb_ga10b.h>
#define GA10B_VAB_ENTRY 512U /* = vab_size * 2 */
#define GA10B_VAB_WRITE_PACKETS 8U /* = num_range_checkers */
#define GA10B_VAB_WRITE_PACKET_DWORDS 8U /* 512/8 = 64 bytes = 16 words = 8 double words*/
#define GA10B_VAB_WRITE_PACKET_ACCESS_DWORDS 4U
int ga10b_fb_vab_init(struct gk20a *g)
{
/* - allocate buffer and mapped in bar2
* - single entry is 2K bits i.e. 256 bytes
* - write buffer address to NV_PFB_PRI_MMU_VIDMEM_ACCESS_BIT_BUFFER_LO_ADDR
* and NV_PFB_PRI_MMU_VIDMEM_ACCESS_BIT_BUFFER_HI_ADDR
* - write NV_PFB_PRI_MMU_VIDMEM_ACCESS_BIT_BUFFER_SIZE_VAL
*/
int err = 0;
size_t num_vab_entries = 2U;
struct vm_gk20a *vm = g->mm.bar2.vm;
struct nvgpu_mem *vab_buf = &g->mm.vab.buffer;
u64 buf_addr = 0ULL;
if (!nvgpu_mem_is_valid(&g->mm.vab.buffer)) {
err = nvgpu_dma_alloc_map_sys(vm,
num_vab_entries * GA10B_VAB_ENTRY, vab_buf);
if (err != 0) {
nvgpu_err(g, "Error in vab buffer alloc in bar2 vm ");
return -ENOMEM;
}
}
buf_addr = ((u64)(uintptr_t)vab_buf->gpu_va);
nvgpu_log(g, gpu_dbg_vab, "buf_addr 0x%llx", buf_addr);
nvgpu_writel(g, fb_mmu_vidmem_access_bit_buffer_hi_r(),
fb_mmu_vidmem_access_bit_buffer_hi_addr_f(u64_hi32(buf_addr)));
nvgpu_writel(g, fb_mmu_vidmem_access_bit_buffer_lo_r(),
(fb_mmu_vidmem_access_bit_buffer_lo_addr_m() &
u64_lo32(buf_addr)));
nvgpu_writel(g, fb_mmu_vidmem_access_bit_buffer_size_r(),
fb_mmu_vidmem_access_bit_buffer_size_val_f(num_vab_entries));
return 0;
}
static int ga10b_fb_vab_config_address_range(struct gk20a *g,
u32 num_range_checkers,
struct nvgpu_vab_range_checker *vab_range_checker)
{
/*
* - read num_range_checker, verify user passed range_checker_num
* - for each range_checker,
* - calculate granularity log from actual granularity
* - drop (granularity_shift_bits + bitmask_size_shift_bits) bits from
* start address
* - add granularity and start address lo/hi
*/
/*
* check range address is not in VPR
*/
u32 i = 0U;
u32 max_range_checkers = fb_mmu_vidmem_access_bit_num_range_checker_v();
u32 granularity_shift_bits_base = 16U; /* log(64KB) */
u32 granularity_shift_bits = 0U;
int err = 0U;
nvgpu_err(g, " ");
g->mm.vab.user_num_range_checkers = num_range_checkers;
nvgpu_log(g, gpu_dbg_vab, "num_range_checkers %u", num_range_checkers);
nvgpu_assert(num_range_checkers <= max_range_checkers);
for (i = 0U; i < num_range_checkers; i++) {
if (vab_range_checker[i].granularity_shift <
granularity_shift_bits_base) {
err = -EINVAL;
break;
}
granularity_shift_bits =
vab_range_checker[i].granularity_shift -
granularity_shift_bits_base;
nvgpu_log(g, gpu_dbg_vab, "\t%u: granularity_shift 0x%x",
i, vab_range_checker[i].granularity_shift);
nvgpu_log(g, gpu_dbg_vab, "\t%u: start_phys_addr 0x%llx",
i, vab_range_checker[i].start_phys_addr);
nvgpu_writel(g, fb_mmu_vidmem_access_bit_start_addr_hi_r(i),
U32(vab_range_checker[i].start_phys_addr >> 32U));
nvgpu_writel(g, fb_mmu_vidmem_access_bit_start_addr_lo_r(i),
(vab_range_checker[i].start_phys_addr &
fb_mmu_vidmem_access_bit_start_addr_lo_val_m()) |
fb_mmu_vidmem_access_bit_start_addr_lo_granularity_f(
granularity_shift_bits));
}
return err;
}
int ga10b_fb_vab_reserve(struct gk20a *g, u32 vab_mode, u32 num_range_checkers,
struct nvgpu_vab_range_checker *vab_range_checker)
{
u32 vab_buf_size_reg = 0U;
u32 vab_reg = 0U;
int err = 0U;
nvgpu_log_fn(g, " ");
err = ga10b_fb_vab_config_address_range(g, num_range_checkers,
vab_range_checker);
if (err != 0) {
nvgpu_err(g, "VAB range range checker config failed");
goto fail;
}
/*
* - set NV_PFB_PRI_MMU_VIDMEM_ACCESS_BIT_BUFFER_SIZE_ENABLE
*/
vab_buf_size_reg = nvgpu_readl(g,
fb_mmu_vidmem_access_bit_buffer_size_r());
vab_buf_size_reg = set_field(vab_buf_size_reg,
fb_mmu_vidmem_access_bit_buffer_size_enable_m(),
fb_mmu_vidmem_access_bit_buffer_size_enable_f(
fb_mmu_vidmem_access_bit_buffer_size_enable_true_v()));
nvgpu_writel(g, fb_mmu_vidmem_access_bit_buffer_size_r(),
vab_buf_size_reg);
/*
* - Update NV_PFB_PRI_MMU_VIDMEM_ACCESS_BIT settings
*/
vab_reg = nvgpu_readl(g, fb_mmu_vidmem_access_bit_r());
nvgpu_log(g, gpu_dbg_vab, "vab size %u",
fb_mmu_vidmem_access_bit_size_v(vab_reg));
/* disable_mode_clear: after logging is disabled, MMU clears bitmask */
vab_reg = set_field(vab_reg, fb_mmu_vidmem_access_bit_disable_mode_m(),
fb_mmu_vidmem_access_bit_disable_mode_f(
fb_mmu_vidmem_access_bit_disable_mode_clear_v()));
/* set NV_PFB_PRI_MMU_VIDMEM_ACCESS_BIT_MODE to access or dirty */
if (vab_mode == NVGPU_VAB_MODE_ACCESS) {
vab_reg = set_field(vab_reg, fb_mmu_vidmem_access_bit_mode_m(),
fb_mmu_vidmem_access_bit_mode_f(
fb_mmu_vidmem_access_bit_mode_access_v()));
} else if (vab_mode == NVGPU_VAB_MODE_DIRTY) {
vab_reg = set_field(vab_reg, fb_mmu_vidmem_access_bit_mode_m(),
fb_mmu_vidmem_access_bit_mode_f(
fb_mmu_vidmem_access_bit_mode_dirty_v()));
} else {
nvgpu_err(g, "Unknown vab mode");
err = -EINVAL;
goto fail;
}
/* Enable VAB */
vab_reg = set_field(vab_reg, fb_mmu_vidmem_access_bit_enable_m(),
fb_mmu_vidmem_access_bit_enable_f(
fb_mmu_vidmem_access_bit_enable_true_v()));
nvgpu_writel(g, fb_mmu_vidmem_access_bit_r(), vab_reg);
/*
* Enable VAB in GPC
*/
g->ops.gr.vab_init(g, vab_reg);
fail:
return err;
}
int ga10b_fb_vab_dump_and_clear(struct gk20a *g, u64 *user_buf,
u64 user_buf_size)
{
/*
* set NV_PFB_PRI_MMU_VIDMEM_ACCESS_BIT_DUMP_TRIGGER
* poll NV_PFB_PRI_MMU_VIDMEM_ACCESS_BIT_DUMP_TRIGGER to be cleared
* clear what? buffer or access bits or buffer_put_ptr
*/
int err;
struct nvgpu_mem *vab_buf = &g->mm.vab.buffer;
u64 buffer_offset = 0ULL;
u64 req_buf_size = 0U;
u32 i = 0U, j = 0U;
u32 user_dword_offset = 0U;
u32 user_buf_dwords = 0U;
u32 vab_size = 0U;
u32 vab_dump_reg = 0U;
u32 vab_put_ptr = 0U;
u32 delay = POLL_DELAY_MIN_US;
struct nvgpu_timeout timeout;
u32 max_range_checkers = fb_mmu_vidmem_access_bit_num_range_checker_v();
u32 trigger_set = fb_mmu_vidmem_access_bit_dump_trigger_f(
fb_mmu_vidmem_access_bit_dump_trigger_true_v());
u32 trigger_reset = fb_mmu_vidmem_access_bit_dump_trigger_f(
fb_mmu_vidmem_access_bit_dump_trigger_false_v());
u64 *wr_pkt = nvgpu_kzalloc(g, nvgpu_safe_mult_u32(sizeof(u64),
GA10B_VAB_WRITE_PACKET_DWORDS)); /* 64B write packet */
u32 valid_wr = 0U;
u32 valid_mask = 0x80000000U;
u64 valid_offset = 0ULL;
u64 vab_offset = 0ULL;
/* Get buffer address */
vab_put_ptr = nvgpu_readl(g, fb_mmu_vidmem_access_bit_buffer_put_r());
nvgpu_log(g, gpu_dbg_vab, "vab_put_ptr 0x%x", vab_put_ptr);
buffer_offset = U64(nvgpu_safe_mult_u32(
fb_mmu_vidmem_access_bit_buffer_put_ptr_v(vab_put_ptr),
GA10B_VAB_ENTRY));
nvgpu_log(g, gpu_dbg_vab, "buffer_offset 0x%llx", buffer_offset);
vab_size = fb_mmu_vidmem_access_bit_size_v(nvgpu_readl(g,
fb_mmu_vidmem_access_bit_r()));
/* 1024/8 bytes * 2^vab_size */
req_buf_size = nvgpu_safe_mult_u64(128ULL, (1ULL << vab_size));
/* buffer size will correspond to user range checker count */
req_buf_size = (req_buf_size/max_range_checkers) *
g->mm.vab.user_num_range_checkers;
nvgpu_assert(user_buf_size >= req_buf_size);
/* bytes to dwords */
user_buf_dwords = user_buf_size/8;
/* Set trigger to start vab dump */
nvgpu_writel(g, fb_mmu_vidmem_access_bit_dump_r(), trigger_set);
vab_dump_reg = nvgpu_readl(g, fb_mmu_vidmem_access_bit_dump_r());
nvgpu_log(g, gpu_dbg_vab, "vab_dump_reg 0x%x", vab_dump_reg);
err = nvgpu_timeout_init(g, &timeout, 1000U, NVGPU_TIMER_CPU_TIMER);
if (err != 0) {
nvgpu_err(g, "Timeout init failed");
return err;
}
/* Check if trigger is cleared vab bits collection complete */
do {
nvgpu_usleep_range(delay, delay * 2U);
delay = min_t(u32, delay << 1, POLL_DELAY_MAX_US);
vab_dump_reg = nvgpu_readl(g, fb_mmu_vidmem_access_bit_dump_r());
nvgpu_log(g, gpu_dbg_vab, "vab_dump_reg 0x%x", vab_dump_reg);
} while((fb_mmu_vidmem_access_bit_dump_trigger_v(vab_dump_reg) !=
trigger_reset) &&
(nvgpu_timeout_expired(&timeout) == 0));
user_dword_offset = 0U;
for (i = 0U; i < GA10B_VAB_WRITE_PACKETS; i++) {
/* Poll valid bit for write packet i */
valid_offset = (buffer_offset / 4ULL) +
((i+1) * (GA10B_VAB_WRITE_PACKET_DWORDS * 2)) - 1;
nvgpu_log(g, gpu_dbg_vab, "Read valid bit at 0x%llx offset",
valid_offset);
do {
valid_wr = nvgpu_mem_rd32(g, vab_buf, valid_offset);
} while (valid_wr != valid_mask);
/* Read VAB bits */
vab_offset = buffer_offset +
(i * GA10B_VAB_WRITE_PACKET_DWORDS * 8U);
nvgpu_mem_rd_n(g, vab_buf, vab_offset , (void *)wr_pkt,
GA10B_VAB_WRITE_PACKET_DWORDS * 8U);
/* Copy and print access bits to user buffer */
for (j = 0U; j < GA10B_VAB_WRITE_PACKET_DWORDS; j++) {
if ((user_dword_offset < user_buf_dwords) &&
(j < GA10B_VAB_WRITE_PACKET_ACCESS_DWORDS)) {
user_buf[user_dword_offset++] = wr_pkt[j];
}
nvgpu_log(g, gpu_dbg_vab, "wr_pkt %d: 0x%016llx",
j, wr_pkt[j]);
}
/* Clear MSB valid bit to indicate packet read complete */
nvgpu_mem_wr32(g, vab_buf, valid_offset,
(valid_wr & ~valid_mask));
}
nvgpu_kfree(g, wr_pkt);
return 0;
}
int ga10b_fb_vab_release(struct gk20a *g)
{
/*
* - reset NV_PFB_PRI_MMU_VIDMEM_ACCESS_BIT_BUFFER_SIZE_ENABLE
* - reset NV_PFB_PRI_MMU_VIDMEM_ACCESS_BIT_ENABLE
*/
u32 vab_buf_size_reg = 0U;
u32 vab_reg = 0U;
nvgpu_err(g, " ");
vab_buf_size_reg = nvgpu_readl(g,
fb_mmu_vidmem_access_bit_buffer_size_r());
vab_buf_size_reg = set_field(vab_buf_size_reg,
fb_mmu_vidmem_access_bit_buffer_size_enable_m(),
fb_mmu_vidmem_access_bit_buffer_size_enable_f(
fb_mmu_vidmem_access_bit_buffer_size_enable_false_v()));
nvgpu_writel(g, fb_mmu_vidmem_access_bit_buffer_size_r(), vab_buf_size_reg);
vab_reg = nvgpu_readl(g, fb_mmu_vidmem_access_bit_r());
vab_reg = set_field(vab_reg, fb_mmu_vidmem_access_bit_enable_m(),
fb_mmu_vidmem_access_bit_enable_f(
fb_mmu_vidmem_access_bit_enable_false_v()));
nvgpu_writel(g, fb_mmu_vidmem_access_bit_r(), vab_reg);
/*
* - Disable VAB in GPC
*/
g->ops.gr.vab_release(g, vab_reg);
return 0;
}
int ga10b_fb_vab_teardown(struct gk20a *g)
{
/*
* free vab buffer
*/
struct vm_gk20a *vm = g->mm.bar2.vm;
struct nvgpu_mem *vab_buf = &g->mm.vab.buffer;
if (nvgpu_mem_is_valid(vab_buf)) {
nvgpu_dma_unmap_free(vm, vab_buf);
}
return 0;
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2021, 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 HAL_FB_VAB_GA10B_H
#define HAL_FB_VAB_GA10B_H
struct gk20a;
struct nvgpu_vab_range_checker;
int ga10b_fb_vab_init(struct gk20a *g);
int ga10b_fb_vab_reserve(struct gk20a *g, u32 vab_mode, u32 num_range_checkers,
struct nvgpu_vab_range_checker *vab_range_checker);
int ga10b_fb_vab_dump_and_clear(struct gk20a *g, u64 *user_buf,
u64 user_buf_size);
int ga10b_fb_vab_release(struct gk20a *g);
int ga10b_fb_vab_teardown(struct gk20a *g);
#endif /* HAL_FB_VAB_GA10B_H */

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2020, 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 FIFO_CHANNEL_GA100_H
#define FIFO_CHANNEL_GA100_H
#include <nvgpu/types.h>
struct gk20a;
u32 ga100_channel_count(struct gk20a *g);
#endif /* FIFO_CHANNEL_GA100_H */

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2020, 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/log.h>
#include <nvgpu/gk20a.h>
#include "channel_ga100.h"
#include <nvgpu/hw/ga100/hw_runlist_ga100.h>
u32 ga100_channel_count(struct gk20a *g)
{
u32 num_channels = 0;
num_channels = ((0x1U) << runlist_channel_config_num_channels_log2_2k_v());
nvgpu_log(g, gpu_dbg_info, "Number of channels supported by hw = %u",
num_channels);
return num_channels;
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2020, 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 FIFO_CHANNEL_GA10B_H
#define FIFO_CHANNEL_GA10B_H
#include <nvgpu/types.h>
struct gk20a;
struct nvgpu_channel;
struct nvgpu_channel_hw_state;
u32 ga10b_channel_count(struct gk20a *g);
void ga10b_channel_enable(struct nvgpu_channel *ch);
void ga10b_channel_disable(struct nvgpu_channel *ch);
void ga10b_channel_bind(struct nvgpu_channel *ch);
void ga10b_channel_unbind(struct nvgpu_channel *ch);
void ga10b_channel_read_state(struct gk20a *g, struct nvgpu_channel *ch,
struct nvgpu_channel_hw_state *state);
void ga10b_channel_reset_faulted(struct gk20a *g, struct nvgpu_channel *ch,
bool eng, bool pbdma);
void ga10b_channel_force_ctx_reload(struct nvgpu_channel *ch);
#endif /* FIFO_CHANNEL_GA10B_H */

View File

@@ -0,0 +1,255 @@
/*
* Copyright (c) 2020-2021, 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/channel.h>
#include <nvgpu/runlist.h>
#include <nvgpu/log.h>
#include <nvgpu/atomic.h>
#include <nvgpu/io.h>
#include <nvgpu/gk20a.h>
#include <hal/fifo/fifo_utils_ga10b.h>
#include "channel_ga10b.h"
#include <nvgpu/hw/ga10b/hw_runlist_ga10b.h>
#define NUM_CHANNELS 512U
#define CHANNEL_BOUND 1
#define CHANNEL_UNBOUND 0
u32 ga10b_channel_count(struct gk20a *g)
{
/* Limit number of channels, avoids unnecessary memory allocation */
nvgpu_log(g, gpu_dbg_info, "Number of channels supported by hw = %u",
((0x1U) << runlist_channel_config_num_channels_log2_2k_v()));
nvgpu_log(g, gpu_dbg_info, "Number of channels supported by sw = %u",
NUM_CHANNELS);
return NUM_CHANNELS;
}
void ga10b_channel_enable(struct nvgpu_channel *ch)
{
struct gk20a *g = ch->g;
struct nvgpu_runlist *runlist = NULL;
runlist = ch->runlist;
nvgpu_chram_bar0_writel(g, runlist, runlist_chram_channel_r(ch->chid),
runlist_chram_channel_update_f(
runlist_chram_channel_update_enable_channel_v()));
}
void ga10b_channel_disable(struct nvgpu_channel *ch)
{
struct gk20a *g = ch->g;
struct nvgpu_runlist *runlist = NULL;
runlist = ch->runlist;
nvgpu_chram_bar0_writel(g, runlist, runlist_chram_channel_r(ch->chid),
runlist_chram_channel_update_f(
runlist_chram_channel_update_disable_channel_v()));
}
void ga10b_channel_bind(struct nvgpu_channel *ch)
{
struct gk20a *g = ch->g;
struct nvgpu_runlist *runlist = NULL;
runlist = ch->runlist;
/* Enable channel */
nvgpu_chram_bar0_writel(g, runlist, runlist_chram_channel_r(ch->chid),
runlist_chram_channel_update_f(
runlist_chram_channel_update_enable_channel_v()));
nvgpu_atomic_set(&ch->bound, CHANNEL_BOUND);
}
/*
* The instance associated with a channel is specified in the channel's
* runlist entry. Ampere has no notion of binding/unbinding channels
* to instances. When tearing down a channel or migrating its chid,
* after ensuring it is unloaded and unrunnable, SW must clear the
* channel's entry in the channel RAM by writing
* NV_CHRAM_CHANNEL_UPDATE_CLEAR_CHANNEL to NV_CHRAM_CHANNEL(chid).
*
* Note: From GA10x onwards, channel RAM clear is one of the
* important steps in RC recovery and channel removal.
* Channel Removal Sequence:
* SW may also need to remove some channels from a TSG in order to
* support shutdown of a specific subcontext in that TSG. In this case
* it's important for SW to take care to properly clear the channel RAM
* state of the removed channels and to transfer CTX_RELOAD to some
* other channel that will not be removed. The procedure is as follows:
* 1. Disable all the channels in the TSG (or disable scheduling on the
* runlist)
* 2. Preempt the TSG (or runlist)
* 3. Poll for completion of the preempt (possibly making use of the
* appropriate PREEMPT interrupt to avoid the spin loop).
* While polling, SW must check for interrupts and hangs.
* If a teardown is required, stop following this sequence and
* continue with the teardown sequence from step 4.
* 4. Read the channel RAM for the removed channels to see if CTX_RELOAD
* is set on any of them. If so, force CTX_RELOAD on some other
* channel that isn't being removed by writing
* NV_CHRAM_CHANNEL_UPDATE_FORCE_CTX_RELOAD to chosen channel's chram
* 5. Write NV_CHRAM_CHANNEL_UPDATE_CLEAR_CHANNEL to removed channels.
* This ensures the channels are ready for reuse without confusing
* esched's tracking.
* 6. Submit a new runlist without the removed channels and reenable
* scheduling if disabled in step 1.
* 7. Re-enable all the non-removed channels in the TSG.
*/
void ga10b_channel_unbind(struct nvgpu_channel *ch)
{
struct gk20a *g = ch->g;
struct nvgpu_runlist *runlist = NULL;
runlist = ch->runlist;
if (nvgpu_atomic_cmpxchg(&ch->bound, CHANNEL_BOUND, CHANNEL_UNBOUND) !=
0) {
nvgpu_chram_bar0_writel(g, runlist,
runlist_chram_channel_r(ch->chid),
runlist_chram_channel_update_f(
runlist_chram_channel_update_clear_channel_v()));
}
}
static const char * const chram_status_str[] = {
[runlist_chram_channel_status_idle_v()] = "idle",
[runlist_chram_channel_status_pending_v()] = "pending",
[runlist_chram_channel_status_pending_ctx_reload_v()] =
"pending_ctx_reload",
[runlist_chram_channel_status_pending_acquire_fail_v()] =
"pending_acquire_fail",
[runlist_chram_channel_status_pending_acquire_fail_ctx_reload_v()] =
"pending_acq_fail_ctx_reload",
[runlist_chram_channel_status_pbdma_busy_v()] = "pbdma_busy",
[runlist_chram_channel_status_pbdma_busy_and_eng_busy_v()] =
"pbdma_and_eng_busy",
[runlist_chram_channel_status_eng_busy_v()] = "eng_busy",
[runlist_chram_channel_status_eng_busy_pending_acquire_fail_v()] =
"eng_busy_pending_acquire_fail",
[runlist_chram_channel_status_eng_busy_pending_v()] = "eng_busy_pending",
[runlist_chram_channel_status_pbdma_busy_ctx_reload_v()] =
"pbdma_busy_ctx_reload",
[runlist_chram_channel_status_pbdma_busy_eng_busy_ctx_reload_v()] =
"pbdma_and_eng_busy_ctx_reload",
[runlist_chram_channel_status_busy_ctx_reload_v()] = "busy_ctx_reload",
[runlist_chram_channel_status_eng_busy_pending_ctx_reload_v()] =
"eng_busy_pending_ctx_reload",
[runlist_chram_channel_status_eng_busy_pending_acquire_fail_ctx_reload_v()] =
"eng_busy_pending_acq_fail_ctx_reload",
};
void ga10b_channel_read_state(struct gk20a *g, struct nvgpu_channel *ch,
struct nvgpu_channel_hw_state *state)
{
struct nvgpu_runlist *runlist = NULL;
u32 reg = 0U;
u32 status = 0U;
runlist = ch->runlist;
reg = nvgpu_chram_bar0_readl(g, runlist,
runlist_chram_channel_r(ch->chid));
status = runlist_chram_channel_status_v(reg);
state->next = runlist_chram_channel_next_v(reg) ==
runlist_chram_channel_next_true_v();
state->enabled = runlist_chram_channel_enable_v(reg) ==
runlist_chram_channel_enable_in_use_v();
state->ctx_reload = runlist_chram_channel_ctx_reload_v(reg) ==
runlist_chram_channel_ctx_reload_true_v();
state->busy = runlist_chram_channel_busy_v(reg) ==
runlist_chram_channel_busy_true_v();
state->pending_acquire =
(status ==
runlist_chram_channel_status_pending_acquire_fail_v()) ||
(status ==
runlist_chram_channel_status_eng_busy_pending_acquire_fail_ctx_reload_v()) ||
(status ==
runlist_chram_channel_status_pending_acquire_fail_ctx_reload_v());
state->eng_faulted = runlist_chram_channel_eng_faulted_v(reg) ==
runlist_chram_channel_eng_faulted_true_v();
state->status_string = chram_status_str[status] == NULL ? "N/A" :
chram_status_str[status];
nvgpu_log_info(g, "Channel id:%d state next:%s enabled:%s ctx_reload:%s"
" busy:%s pending_acquire:%s eng_faulted:%s status_string:%s",
ch->chid,
state->next ? "true" : "false",
state->enabled ? "true" : "false",
state->ctx_reload ? "true" : "false",
state->busy ? "true" : "false",
state->pending_acquire ? "true" : "false",
state->eng_faulted ? "true" : "false", state->status_string);
}
void ga10b_channel_reset_faulted(struct gk20a *g, struct nvgpu_channel *ch,
bool eng, bool pbdma)
{
struct nvgpu_runlist *runlist = NULL;
runlist = ch->runlist;
if (eng) {
nvgpu_chram_bar0_writel(g, runlist,
runlist_chram_channel_r(ch->chid),
runlist_chram_channel_update_f(
runlist_chram_channel_update_reset_eng_faulted_v()));
}
if (pbdma) {
nvgpu_chram_bar0_writel(g, runlist,
runlist_chram_channel_r(ch->chid),
runlist_chram_channel_update_f(
runlist_chram_channel_update_reset_pbdma_faulted_v()));
}
/*
* At this point the fault is handled and *_FAULTED bit is cleared.
* However, if the runlist has gone idle, then the esched unit
* will remain idle and will not schedule the runlist unless its
* doorbell is written or a new runlist is submitted. Hence, ring the
* runlist doorbell once the fault is cleared.
*/
g->ops.usermode.ring_doorbell(ch);
}
void ga10b_channel_force_ctx_reload(struct nvgpu_channel *ch)
{
struct gk20a *g = ch->g;
struct nvgpu_runlist *runlist = NULL;
runlist = ch->runlist;
nvgpu_chram_bar0_writel(g, runlist, runlist_chram_channel_r(ch->chid),
runlist_chram_channel_update_f(
runlist_chram_channel_update_force_ctx_reload_v()));
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2020-2021, 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_CTXSW_TIMEOUT_GA10B_H
#define NVGPU_CTXSW_TIMEOUT_GA10B_H
#include <nvgpu/types.h>
#define MS_TO_US 1000U
struct gk20a;
void ga10b_fifo_ctxsw_timeout_enable(struct gk20a *g, bool enable);
void ga10b_fifo_ctxsw_timeout_isr(struct gk20a *g,
struct nvgpu_runlist *runlist);
#endif /* NVGPU_CTXSW_TIMEOUT_GA10B_H */

View File

@@ -0,0 +1,300 @@
/*
* Copyright (c) 2020-2021, 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/gk20a.h>
#include <nvgpu/log.h>
#include <nvgpu/io.h>
#include <nvgpu/soc.h>
#include <nvgpu/ptimer.h>
#include <nvgpu/tsg.h>
#include <nvgpu/rc.h>
#include <nvgpu/nvgpu_err.h>
#include <nvgpu/engines.h>
#include <nvgpu/device.h>
#include <nvgpu/runlist.h>
#include <nvgpu/static_analysis.h>
#include "fifo_utils_ga10b.h"
#include "ctxsw_timeout_ga10b.h"
#include <nvgpu/hw/ga10b/hw_runlist_ga10b.h>
static void ga10b_fifo_ctxsw_timeout_clear_and_enable(struct gk20a *g,
u32 timeout)
{
u32 i, rleng;
struct nvgpu_runlist *runlist;
const struct nvgpu_device *dev;
for (i = 0U; i < g->fifo.num_runlists; i++) {
runlist = &g->fifo.active_runlists[i];
for (rleng = 0U;
rleng < runlist_engine_ctxsw_timeout_config__size_1_v();
rleng++) {
/* clear ctxsw timeout interrupt */
nvgpu_runlist_writel(g, runlist,
runlist_intr_0_r(),
runlist_intr_0_ctxsw_timeout_eng_reset_f(rleng));
dev = runlist->nvgpu_next.rl_dev_list[rleng];
if (dev == NULL) {
continue;
}
/* enable ctxsw timeout interrupt */
nvgpu_runlist_writel(g, runlist,
runlist_engine_ctxsw_timeout_config_r(
dev->next.rleng_id),
timeout);
nvgpu_log_info(g, "ctxsw timeout enable "
"rleng: %u timeout_config_val: 0x%08x",
dev->next.rleng_id, timeout);
}
}
}
static void ga10b_fifo_ctxsw_timeout_disable_and_clear(struct gk20a *g,
u32 timeout)
{
u32 i, rleng;
struct nvgpu_runlist *runlist;
for (i = 0U; i < g->fifo.num_runlists; i++) {
runlist = &g->fifo.active_runlists[i];
for (rleng = 0U;
rleng < runlist_engine_ctxsw_timeout_config__size_1_v();
rleng++) {
/* disable ctxsw timeout interrupt */
nvgpu_runlist_writel(g, runlist,
runlist_engine_ctxsw_timeout_config_r(rleng),
timeout);
/* clear ctxsw timeout interrupt */
nvgpu_runlist_writel(g, runlist,
runlist_intr_0_r(),
runlist_intr_0_ctxsw_timeout_eng_reset_f(rleng));
}
}
}
void ga10b_fifo_ctxsw_timeout_enable(struct gk20a *g, bool enable)
{
u32 timeout;
nvgpu_log_fn(g, " ");
if (enable) {
if (nvgpu_platform_is_silicon(g)) {
timeout = nvgpu_safe_mult_u32(
g->ctxsw_timeout_period_ms, MS_TO_US);
timeout = scale_ptimer(timeout,
ptimer_scalingfactor10x(g->ptimer_src_freq));
timeout =
runlist_engine_ctxsw_timeout_config_period_f(timeout) |
runlist_engine_ctxsw_timeout_config_detection_enabled_f();
} else {
timeout =
runlist_engine_ctxsw_timeout_config_period_max_f() |
runlist_engine_ctxsw_timeout_config_detection_enabled_f();
}
ga10b_fifo_ctxsw_timeout_clear_and_enable(g, timeout);
} else {
timeout =
runlist_engine_ctxsw_timeout_config_detection_disabled_f();
timeout |=
runlist_engine_ctxsw_timeout_config_period_max_f();
ga10b_fifo_ctxsw_timeout_disable_and_clear(g, timeout);
}
}
static u32 ga10b_fifo_ctxsw_timeout_info(struct gk20a *g,
struct nvgpu_runlist *runlist,
u32 rleng_id, u32 *info_status)
{
u32 tsgid = NVGPU_INVALID_TSG_ID;
u32 info;
u32 ctx_status;
info = nvgpu_runlist_readl(g, runlist,
runlist_engine_ctxsw_timeout_info_r(rleng_id));
/*
* ctxsw_state and tsgid are snapped at the point of the timeout and
* will not change while the corresponding INTR_CTXSW_TIMEOUT_ENGINE bit
* is PENDING.
*/
ctx_status = runlist_engine_ctxsw_timeout_info_ctxsw_state_v(info);
if (ctx_status ==
runlist_engine_ctxsw_timeout_info_ctxsw_state_load_v()) {
tsgid = runlist_engine_ctxsw_timeout_info_next_tsgid_v(info);
} else if ((ctx_status ==
runlist_engine_ctxsw_timeout_info_ctxsw_state_switch_v()) ||
(ctx_status ==
runlist_engine_ctxsw_timeout_info_ctxsw_state_save_v())) {
tsgid = runlist_engine_ctxsw_timeout_info_prev_tsgid_v(info);
} else {
nvgpu_log_info(g, "ctxsw_timeout_info_ctxsw_state: 0x%08x",
ctx_status);
}
nvgpu_log_info(g, "ctxsw timeout info: tsgid = %d", tsgid);
/*
* STATUS indicates whether the context request ack was eventually
* received and whether a subsequent request timed out. This field is
* updated live while the corresponding INTR_CTXSW_TIMEOUT_ENGINE bit
* is PENDING. STATUS starts in AWAITING_ACK, and progresses to
* ACK_RECEIVED and finally ends with DROPPED_TIMEOUT.
*
* AWAITING_ACK - context request ack still not returned from engine.
* ENG_WAS_RESET - The engine was reset via a PRI write to NV_PMC_ENABLE
* or NV_PMC_ELPG_ENABLE prior to receiving the ack. Host will not
* expect ctx ack to return, but if it is already in flight, STATUS will
* transition shortly to ACK_RECEIVED unless the interrupt is cleared
* first. Once the engine is reset, additional context switches can
* occur; if one times out, STATUS will transition to DROPPED_TIMEOUT
* if the interrupt isn't cleared first.
* ACK_RECEIVED - The ack for the timed-out context request was
* received between the point of the timeout and this register being
* read. Note this STATUS can be reported during the load stage of the
* same context switch that timed out if the timeout occurred during the
* save half of a context switch. Additional context requests may have
* completed or may be outstanding, but no further context timeout has
* occurred. This simplifies checking for spurious context switch
* timeouts.
* DROPPED_TIMEOUT - The originally timed-out context request acked,
* but a subsequent context request then timed out.
* Information about the subsequent timeout is not stored; in fact, that
* context request may also have already been acked by the time SW
* SW reads this register. If not, there is a chance SW can get the
* dropped information by clearing the corresponding
* INTR_CTXSW_TIMEOUT_ENGINE bit and waiting for the timeout to occur
* again. Note, however, that if the engine does time out again,
* it may not be from the original request that caused the
* DROPPED_TIMEOUT state, as that request may
* be acked in the interim.
*/
*info_status = runlist_engine_ctxsw_timeout_info_status_v(info);
if (*info_status ==
runlist_engine_ctxsw_timeout_info_status_ack_received_v()) {
nvgpu_log_info(g, "ctxsw timeout info: ack received");
/* no need to recover */
tsgid = NVGPU_INVALID_TSG_ID;
} else if (*info_status ==
runlist_engine_ctxsw_timeout_info_status_dropped_timeout_v()) {
nvgpu_log_info(g, "ctxsw timeout info: dropped timeout");
/* no need to recover */
tsgid = NVGPU_INVALID_TSG_ID;
} else {
nvgpu_log_info(g, "ctxsw timeout info status: 0x%08x",
*info_status);
}
return tsgid;
}
void ga10b_fifo_ctxsw_timeout_isr(struct gk20a *g,
struct nvgpu_runlist *runlist)
{
u32 rleng, reg_val, timeout;
u32 active_eng_id;
u32 ms = 0U;
bool recover = false;
u32 info_status;
u32 tsgid = NVGPU_INVALID_TSG_ID;
const struct nvgpu_device *dev;
struct nvgpu_tsg *tsg = NULL;
#ifdef CONFIG_NVGPU_KERNEL_MODE_SUBMIT
bool debug_dump = false;
const char *const ctxsw_timeout_status_desc[] = {
"awaiting ack",
"eng was reset",
"ack received",
"dropped timeout"
};
#endif
for (rleng = 0U;
rleng < runlist_engine_ctxsw_timeout_info__size_1_v();
rleng++) {
reg_val = nvgpu_runlist_readl(g, runlist, runlist_intr_0_r());
if ((reg_val &
runlist_intr_0_ctxsw_timeout_eng_pending_f(rleng))
== 0U) {
/* ctxsw timeout not pending for this rleng */
continue;
}
dev = runlist->nvgpu_next.rl_dev_list[rleng];
if (dev == NULL) {
nvgpu_err(g, "ctxsw timeout for rleng: %u but "
"dev is invalid", rleng);
/* interupt will still be cleared */
continue;
}
/* dump ctxsw timeout for rleng. useful for debugging */
reg_val = nvgpu_runlist_readl(g, runlist,
runlist_engine_ctxsw_timeout_config_r(
dev->next.rleng_id));
timeout = runlist_engine_ctxsw_timeout_config_period_v(reg_val);
nvgpu_log_info(g, "rleng: %u ctxsw timeout period = 0x%x",
dev->next.rleng_id, timeout);
/* handle ctxsw timeout */
tsgid = ga10b_fifo_ctxsw_timeout_info(g, runlist, rleng,
&info_status);
tsg = nvgpu_tsg_check_and_get_from_id(g, tsgid);
if (tsg == NULL) {
continue;
}
nvgpu_report_host_err(g, NVGPU_ERR_MODULE_HOST,
0, GPU_HOST_PFIFO_CTXSW_TIMEOUT_ERROR, tsgid);
#ifdef CONFIG_NVGPU_KERNEL_MODE_SUBMIT
recover = g->ops.tsg.check_ctxsw_timeout(tsg, &debug_dump, &ms);
if (recover) {
const char *info_status_str = "invalid";
if (info_status <
ARRAY_SIZE(ctxsw_timeout_status_desc)) {
info_status_str =
ctxsw_timeout_status_desc[info_status];
}
active_eng_id = dev->engine_id;
nvgpu_err(g, "ctxsw timeout error: "
"active engine id =%u, %s=%d, info: %s ms=%u",
active_eng_id, "tsg", tsgid, info_status_str,
ms);
if (active_eng_id != NVGPU_INVALID_ENG_ID) {
nvgpu_rc_ctxsw_timeout(g, BIT32(active_eng_id),
tsg, debug_dump);
}
continue;
}
#endif
nvgpu_log_info(g, "fifo is waiting for ctxsw switch: "
"for %d ms, %s=%d", ms, "tsg", tsgid);
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2020, 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_ENGINE_STATUS_GA10B_H
#define NVGPU_ENGINE_STATUS_GA10B_H
#include <nvgpu/types.h>
struct gk20a;
struct nvgpu_engine_status_info;
void ga10b_read_engine_status_info(struct gk20a *g, u32 engine_id,
struct nvgpu_engine_status_info *status);
#endif /* NVGPU_ENGINE_STATUS_GA10B_H */

View File

@@ -0,0 +1,153 @@
/*
* Copyright (c) 2020, 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/io.h>
#include <nvgpu/debug.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/engine_status.h>
#include <nvgpu/engines.h>
#include <nvgpu/device.h>
#include <nvgpu/fifo.h>
#include "engine_status_ga10b.h"
#include <nvgpu/hw/ga10b/hw_runlist_ga10b.h>
static void populate_invalid_ctxsw_status_info(
struct nvgpu_engine_status_info *status_info)
{
status_info->ctx_id = ENGINE_STATUS_CTX_ID_INVALID;
status_info->ctx_id_type = ENGINE_STATUS_CTX_NEXT_ID_TYPE_INVALID;
status_info->ctx_next_id =
ENGINE_STATUS_CTX_NEXT_ID_INVALID;
status_info->ctx_next_id_type = ENGINE_STATUS_CTX_NEXT_ID_TYPE_INVALID;
status_info->ctxsw_status = NVGPU_CTX_STATUS_INVALID;
}
static void populate_valid_ctxsw_status_info(
struct nvgpu_engine_status_info *status_info)
{
status_info->ctx_id =
runlist_engine_status0_tsgid_v(status_info->reg_data);
status_info->ctx_id_type = ENGINE_STATUS_CTX_ID_TYPE_TSGID;
status_info->ctx_next_id =
ENGINE_STATUS_CTX_NEXT_ID_INVALID;
status_info->ctx_next_id_type = ENGINE_STATUS_CTX_NEXT_ID_TYPE_INVALID;
status_info->ctxsw_status = NVGPU_CTX_STATUS_VALID;
}
static void populate_load_ctxsw_status_info(
struct nvgpu_engine_status_info *status_info)
{
status_info->ctx_id = ENGINE_STATUS_CTX_ID_INVALID;
status_info->ctx_id_type = ENGINE_STATUS_CTX_ID_TYPE_INVALID;
status_info->ctx_next_id =
runlist_engine_status0_next_tsgid_v(status_info->reg_data);
status_info->ctx_next_id_type = ENGINE_STATUS_CTX_NEXT_ID_TYPE_TSGID;
status_info->ctxsw_status = NVGPU_CTX_STATUS_CTXSW_LOAD;
}
static void populate_save_ctxsw_status_info(
struct nvgpu_engine_status_info *status_info)
{
status_info->ctx_id =
runlist_engine_status0_tsgid_v(status_info->reg_data);
status_info->ctx_id_type = ENGINE_STATUS_CTX_ID_TYPE_TSGID;
status_info->ctx_next_id =
ENGINE_STATUS_CTX_NEXT_ID_INVALID;
status_info->ctx_next_id_type = ENGINE_STATUS_CTX_NEXT_ID_TYPE_INVALID;
status_info->ctxsw_status = NVGPU_CTX_STATUS_CTXSW_SAVE;
}
static void populate_switch_ctxsw_status_info(
struct nvgpu_engine_status_info *status_info)
{
status_info->ctx_id =
runlist_engine_status0_tsgid_v(status_info->reg_data);
status_info->ctx_id_type = ENGINE_STATUS_CTX_ID_TYPE_TSGID;
status_info->ctx_next_id =
runlist_engine_status0_next_tsgid_v(status_info->reg_data);
status_info->ctx_next_id_type = ENGINE_STATUS_CTX_NEXT_ID_TYPE_TSGID;
status_info->ctxsw_status = NVGPU_CTX_STATUS_CTXSW_SWITCH;
}
void ga10b_read_engine_status_info(struct gk20a *g, u32 engine_id,
struct nvgpu_engine_status_info *status)
{
u32 engine_reg0_data;
u32 engine_reg1_data;
u32 ctxsw_state;
const struct nvgpu_device *dev;
(void) memset(status, 0U, sizeof(*status));
if (!nvgpu_engine_check_valid_id(g, engine_id)) {
/* just return NULL info */
return;
}
dev = g->fifo.host_engines[engine_id];
engine_reg0_data = nvgpu_readl(g, nvgpu_safe_add_u32(
dev->next.rl_pri_base,
runlist_engine_status0_r(dev->next.rleng_id)));
engine_reg1_data = nvgpu_readl(g, nvgpu_safe_add_u32(
dev->next.rl_pri_base,
runlist_engine_status1_r(dev->next.rleng_id)));
status->reg_data = engine_reg0_data;
status->nvgpu_next.reg1_data = engine_reg1_data;
/* populate the engine_state enum */
status->is_busy = runlist_engine_status0_engine_v(engine_reg0_data) ==
runlist_engine_status0_engine_busy_v();
/* populate the engine_faulted_state enum */
status->is_faulted =
runlist_engine_status0_faulted_v(engine_reg0_data) ==
runlist_engine_status0_faulted_true_v();
/* populate the ctxsw_in_progress_state */
status->ctxsw_in_progress = ((engine_reg0_data &
runlist_engine_status0_ctxsw_in_progress_f()) != 0U);
/* populate the ctxsw related info */
ctxsw_state = runlist_engine_status0_ctx_status_v(engine_reg0_data);
status->ctxsw_state = ctxsw_state;
/* check for ctx_status switch/load/save before valid */
if (ctxsw_state ==
runlist_engine_status0_ctx_status_switch_v()) {
populate_switch_ctxsw_status_info(status);
} else if (ctxsw_state ==
runlist_engine_status0_ctx_status_load_v()) {
populate_load_ctxsw_status_info(status);
} else if (ctxsw_state ==
runlist_engine_status0_ctx_status_save_v()) {
populate_save_ctxsw_status_info(status);
} else if (ctxsw_state == runlist_engine_status0_ctx_status_valid_v()) {
populate_valid_ctxsw_status_info(status);
} else {
populate_invalid_ctxsw_status_info(status);
}
}

View File

@@ -0,0 +1,36 @@
/*
* GA10B Fifo
*
* Copyright (c) 2020, 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_FIFO_GA10B_H
#define NVGPU_FIFO_GA10B_H
#include <nvgpu/types.h>
struct gk20a;
int ga10b_init_fifo_reset_enable_hw(struct gk20a *g);
int ga10b_init_fifo_setup_hw(struct gk20a *g);
u32 ga10b_fifo_mmu_fault_id_to_pbdma_id(struct gk20a *g, u32 mmu_fault_id);
#endif /* NVGPU_FIFO_GA10B_H */

View File

@@ -0,0 +1,154 @@
/*
* GA10B Fifo
*
* Copyright (c) 2020-2021, 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/log.h>
#include <nvgpu/io.h>
#include <nvgpu/utils.h>
#include <nvgpu/fifo.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/power_features/cg.h>
#include <nvgpu/hw/ga10b/hw_runlist_ga10b.h>
#include <nvgpu/hw/ga10b/hw_ctrl_ga10b.h>
#include "fifo_utils_ga10b.h"
#include "fifo_ga10b.h"
#include "fifo_intr_ga10b.h"
static void enable_fifo_interrupts(struct gk20a *g)
{
g->ops.fifo.intr_top_enable(g, NVGPU_CIC_INTR_ENABLE);
g->ops.fifo.intr_0_enable(g, true);
g->ops.fifo.intr_1_enable(g, true);
}
int ga10b_init_fifo_reset_enable_hw(struct gk20a *g)
{
int err;
nvgpu_log_fn(g, " ");
/* enable pmc pfifo */
err = nvgpu_mc_reset_units(g, NVGPU_UNIT_FIFO);
if (err != 0) {
nvgpu_err(g, "Failed to reset FIFO unit");
}
#ifdef CONFIG_NVGPU_HAL_NON_FUSA
if (g->ops.mc.elpg_enable != NULL) {
g->ops.mc.elpg_enable(g);
}
#endif
nvgpu_cg_slcg_ce2_load_enable(g);
nvgpu_cg_slcg_fifo_load_enable(g);
nvgpu_cg_blcg_fifo_load_enable(g);
if (g->ops.pbdma.setup_hw != NULL) {
g->ops.pbdma.setup_hw(g);
}
if (g->ops.pbdma.pbdma_force_ce_split != NULL) {
g->ops.pbdma.pbdma_force_ce_split(g);
}
nvgpu_log_fn(g, "done");
return 0;
}
static void ga10b_fifo_config_userd_writeback_timer(struct gk20a *g)
{
struct nvgpu_runlist *runlist = NULL;
u32 reg_val = 0U;
u32 i = 0U;
u32 max_runlists = g->fifo.max_runlists;
for (i = 0U; i < max_runlists; i++) {
runlist = g->fifo.runlists[i];
if (runlist == NULL) {
continue;
}
reg_val = runlist_userd_writeback_timescale_0_f() |
runlist_userd_writeback_timer_100us_f();
nvgpu_runlist_writel(g, runlist, runlist_userd_writeback_r(),
reg_val);
}
}
int ga10b_init_fifo_setup_hw(struct gk20a *g)
{
struct nvgpu_fifo *f = &g->fifo;
nvgpu_log_fn(g, " ");
/*
* Current Flow:
* Nvgpu Init sequence:
* g->ops.fifo.reset_enable_hw
* ....
* g->ops.fifo.fifo_init_support
*
* Fifo Init Sequence called from g->ops.fifo.fifo_init_support:
* fifo.reset_enable_hw -> enables interrupts
* fifo.fifo_init_support -> fifo.setup_sw (Sets up runlist info)
* fifo.fifo_init_support -> fifo.init_fifo_setup_hw
*
* Runlist info is required for getting vector id and enabling
* interrupts at top level.
* Get vector ids before enabling interrupts at top level to make sure
* vectorids are initialized in nvgpu_mc struct before intr_top_enable
* is called.
*/
ga10b_fifo_runlist_intr_vectorid_init(g);
f->max_subctx_count = g->ops.gr.init.get_max_subctx_count();
g->ops.usermode.setup_hw(g);
enable_fifo_interrupts(g);
ga10b_fifo_config_userd_writeback_timer(g);
return 0;
}
u32 ga10b_fifo_mmu_fault_id_to_pbdma_id(struct gk20a *g, u32 mmu_fault_id)
{
u32 pbdma_id;
for (pbdma_id = 0U; pbdma_id < g->ops.pbdma.get_num_of_pbdmas();
pbdma_id = nvgpu_safe_add_u32(pbdma_id, 1U)) {
if (g->ops.pbdma.get_mmu_fault_id(g, pbdma_id) ==
mmu_fault_id) {
return pbdma_id;
}
}
return INVAL_ID;
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2020-2021, 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_FIFO_INTR_GA10B_H
#define NVGPU_FIFO_INTR_GA10B_H
#include <nvgpu/types.h>
struct gk20a;
void ga10b_fifo_runlist_intr_vectorid_init(struct gk20a *g);
void ga10b_fifo_intr_top_enable(struct gk20a *g, bool enable);
void ga10b_fifo_intr_0_enable(struct gk20a *g, bool enable);
void ga10b_fifo_intr_1_enable(struct gk20a *g, bool enable);
void ga10b_fifo_intr_0_isr(struct gk20a *g);
void ga10b_fifo_intr_set_recover_mask(struct gk20a *g);
void ga10b_fifo_intr_unset_recover_mask(struct gk20a *g);
void ga10b_fifo_pbdma_isr(struct gk20a *g, struct nvgpu_runlist *runlist, u32 pbdma_idx);
void ga10b_fifo_runlist_intr_retrigger(struct gk20a *g, u32 intr_tree);
#endif /* NVGPU_FIFO_INTR_GA10B_H */

View File

@@ -0,0 +1,485 @@
/*
* Copyright (c) 2020-2021, 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/gk20a.h>
#include <nvgpu/log.h>
#include <nvgpu/io.h>
#include <nvgpu/runlist.h>
#include <nvgpu/mc.h>
#include <nvgpu/nvgpu_err.h>
#include <nvgpu/cic.h>
#include <nvgpu/rc.h>
#include "fifo_utils_ga10b.h"
#include "fifo_intr_ga10b.h"
#include "ctxsw_timeout_ga10b.h"
#include "pbdma_ga10b.h"
#include <nvgpu/hw/ga10b/hw_runlist_ga10b.h>
/**
* [runlist's tree 0 bit] <---------. .---------> [runlist's tree 1 bit]
* Y
* |
* |
* [runlist intr tree 0] ^ [runlist intr tree 1]
* ______________/ \______________
* / |
* NV_RUNLIST_INTR_VECTORID(0) msg NV_RUNLIST_INTR_VECTORID(1) msg
* | |
* ______^______ ______^______
* / \ / \
* '_______________' '_______________'
* ||||||| | | |||||||
* other tree0 | | other tree1
* ANDed intr bits ^ ^ ANDed intr bits
* AND AND
* | | | |
* _______. .______ _______. .________
* / \ / \
*RUNLIST_INTR_0_EN_SET_TREE(0)_intr_bit Y RUNLIST_INTR_0_EN_SET_TREE(1)_intr_bit
* |
* NV_RUNLIST_INTR_0_intr_bit
*/
#define RUNLIST_INTR_0_MASK \
(runlist_intr_0_en_set_tree_ctxsw_timeout_eng0_enabled_f() | \
runlist_intr_0_en_set_tree_ctxsw_timeout_eng1_enabled_f() | \
runlist_intr_0_en_set_tree_ctxsw_timeout_eng2_enabled_f() | \
runlist_intr_0_en_set_tree_pbdma0_intr_tree_0_enabled_f() | \
runlist_intr_0_en_set_tree_pbdma1_intr_tree_0_enabled_f() | \
runlist_intr_0_en_set_tree_bad_tsg_enabled_f())
#define RUNLIST_INTR_0_RECOVER_MASK \
(runlist_intr_0_en_clear_tree_ctxsw_timeout_eng0_enabled_f() | \
runlist_intr_0_en_clear_tree_ctxsw_timeout_eng1_enabled_f() | \
runlist_intr_0_en_clear_tree_ctxsw_timeout_eng2_enabled_f())
#define RUNLIST_INTR_0_RECOVER_UNMASK \
(runlist_intr_0_en_set_tree_ctxsw_timeout_eng0_enabled_f() | \
runlist_intr_0_en_set_tree_ctxsw_timeout_eng1_enabled_f() | \
runlist_intr_0_en_set_tree_ctxsw_timeout_eng2_enabled_f())
#define RUNLIST_INTR_0_CTXSW_TIMEOUT_MASK \
( \
runlist_intr_0_en_clear_tree_ctxsw_timeout_eng0_enabled_f() | \
runlist_intr_0_en_clear_tree_ctxsw_timeout_eng1_enabled_f() | \
runlist_intr_0_en_clear_tree_ctxsw_timeout_eng2_enabled_f() \
)
#define RUNLIST_INTR_0_PBDMA_MASK \
( \
runlist_intr_0_en_set_tree_pbdma0_intr_tree_0_enabled_f() | \
runlist_intr_0_en_set_tree_pbdma1_intr_tree_0_enabled_f() \
)
static const char *const ga10b_bad_tsg_error_str[] = {
"no_error",
"zero_length_tsg",
"max_length_exceeded",
"runlist_overflow",
"expected_a_chid_entry",
"expected_a_tsg_header",
"invalid_runqueue",
};
void ga10b_fifo_runlist_intr_vectorid_init(struct gk20a *g)
{
u32 i, intr_tree, reg_val, intr_unit;
u32 vectorid_tree[NVGPU_CIC_INTR_VECTORID_SIZE_MAX];
u32 num_vectorid;
struct nvgpu_runlist *runlist;
for (intr_tree = 0U; intr_tree < runlist_intr_vectorid__size_1_v();
intr_tree++) {
intr_unit = NVGPU_CIC_INTR_UNIT_RUNLIST_TREE_0 + intr_tree;
if (nvgpu_cic_intr_is_unit_info_valid(g, intr_unit) == true) {
/* intr_unit_info is already set by s/w */
continue;
}
num_vectorid = 0U;
for (i = 0U; i < g->fifo.num_runlists; i++) {
runlist = &g->fifo.active_runlists[i];
reg_val = nvgpu_runlist_readl(g, runlist,
runlist_intr_vectorid_r(intr_tree));
vectorid_tree[i] =
runlist_intr_vectorid_vector_v(reg_val);
num_vectorid ++;
nvgpu_log_info(g,
"init runlist: %u intr_tree_%d vectorid",
i, intr_tree);
}
nvgpu_cic_intr_unit_vectorid_init(g, intr_unit,
vectorid_tree, num_vectorid);
}
}
void ga10b_fifo_intr_top_enable(struct gk20a *g, bool enable)
{
if (enable) {
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_RUNLIST_TREE_0, NVGPU_CIC_INTR_ENABLE);
/**
* RUNLIST_TREE_1 interrupts are not enabled as all runlist
* interrupts are routed to runlist_tree_0
*/
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_RUNLIST_TREE_1, NVGPU_CIC_INTR_DISABLE);
} else {
nvgpu_cic_intr_stall_unit_config(g,
NVGPU_CIC_INTR_UNIT_RUNLIST_TREE_0, NVGPU_CIC_INTR_DISABLE);
}
}
static void ga10b_fifo_runlist_intr_disable(struct gk20a *g)
{
u32 i, intr_tree, reg_val;
struct nvgpu_runlist *runlist;
/** Disable raising interrupt for both runlist trees to CPU and GSP */
for (i = 0U; i < g->fifo.num_runlists; i++) {
runlist = &g->fifo.active_runlists[i];
for (intr_tree = 0U;
intr_tree < runlist_intr_vectorid__size_1_v();
intr_tree++) {
reg_val = nvgpu_runlist_readl(g, runlist,
runlist_intr_vectorid_r(intr_tree));
reg_val &= ~(runlist_intr_vectorid_cpu_enable_f() |
runlist_intr_vectorid_gsp_enable_f());
nvgpu_runlist_writel(g, runlist,
runlist_intr_vectorid_r(intr_tree), reg_val);
nvgpu_log_info(g, "intr_vectorid_r[tree_%u]: 0x%08x",
i + intr_tree, reg_val);
}
/** Clear interrupts */
reg_val = nvgpu_runlist_readl(g, runlist, runlist_intr_0_r());
nvgpu_runlist_writel(g, runlist, runlist_intr_0_r(), reg_val);
}
}
static void ga10b_fifo_runlist_intr_enable(struct gk20a *g)
{
u32 i, intr_tree_0, intr_tree_1, reg_val;
u32 intr0_en_mask;
struct nvgpu_runlist *runlist;
intr_tree_0 = 0U;
intr_tree_1 = 1U;
intr0_en_mask = RUNLIST_INTR_0_MASK;
for (i = 0U; i < g->fifo.num_runlists; i++) {
runlist = &g->fifo.active_runlists[i];
/**
* runlist_intr_0 interrupts can be routed to either
* tree0 or tree1 vector using runlist_intr_0_en_set_tree(0) or
* runlist_intr_0_en_set_tree(1) register. For now route all
* interrupts to tree0.
*/
/** Clear interrupts */
reg_val = nvgpu_runlist_readl(g, runlist, runlist_intr_0_r());
nvgpu_runlist_writel(g, runlist, runlist_intr_0_r(), reg_val);
/** Enable interrupts in tree(0) */
nvgpu_runlist_writel(g, runlist,
runlist_intr_0_en_set_tree_r(intr_tree_0),
intr0_en_mask);
/** Disable all interrupts in tree(1) */
nvgpu_runlist_writel(g, runlist,
runlist_intr_0_en_clear_tree_r(intr_tree_1),
U32_MAX);
reg_val = nvgpu_runlist_readl(g, runlist,
runlist_intr_vectorid_r(intr_tree_0));
/** disable raising interrupt to gsp */
reg_val &= ~(runlist_intr_vectorid_gsp_enable_f());
/** enable raising interrupt to cpu */
reg_val |= runlist_intr_vectorid_cpu_enable_f();
/** enable runlist tree 0 interrupts at runlist level */
nvgpu_runlist_writel(g, runlist,
runlist_intr_vectorid_r(intr_tree_0), reg_val);
reg_val = nvgpu_runlist_readl(g, runlist,
runlist_intr_vectorid_r(intr_tree_1));
/** disable raising interrupt to gsp */
reg_val &= ~(runlist_intr_vectorid_gsp_enable_f());
/** disable raising interrupt to cpu */
reg_val &= ~(runlist_intr_vectorid_cpu_enable_f());
/** Disable runlist tree 1 interrupts at runlist level */
nvgpu_runlist_writel(g, runlist,
runlist_intr_vectorid_r(intr_tree_1), reg_val);
}
}
void ga10b_fifo_intr_0_enable(struct gk20a *g, bool enable)
{
ga10b_fifo_runlist_intr_disable(g);
if (!enable) {
g->ops.fifo.ctxsw_timeout_enable(g, false);
g->ops.pbdma.intr_enable(g, false);
return;
}
/* Enable interrupts */
g->ops.fifo.ctxsw_timeout_enable(g, true);
g->ops.pbdma.intr_enable(g, true);
ga10b_fifo_runlist_intr_enable(g);
}
void ga10b_fifo_intr_1_enable(struct gk20a *g, bool enable)
{
return;
}
static void ga10b_fifo_handle_bad_tsg(struct gk20a *g,
struct nvgpu_runlist *runlist)
{
u32 bad_tsg;
u32 bad_tsg_code;
bad_tsg = nvgpu_runlist_readl(g, runlist, runlist_intr_bad_tsg_r());
bad_tsg_code = runlist_intr_bad_tsg_code_v(bad_tsg);
if (bad_tsg_code < ARRAY_SIZE(ga10b_bad_tsg_error_str)) {
nvgpu_err(g, "runlist bad tsg error: %s",
ga10b_bad_tsg_error_str[bad_tsg_code]);
} else {
nvgpu_err(g, "runlist bad tsg error code not supported");
}
nvgpu_report_host_err(g, NVGPU_ERR_MODULE_HOST,
0, GPU_HOST_PFIFO_SCHED_ERROR, bad_tsg_code);
/* id is unknown, preempt all runlists and do recovery */
/* TBD: nvgpu_rc_sched_error_bad_tsg(g); */
}
static void ga10b_fifo_runlist_intr_clear(struct gk20a *g)
{
u32 i, intr_0;
struct nvgpu_runlist *runlist;
for (i = 0U; i < g->fifo.num_runlists; i++) {
runlist = &g->fifo.active_runlists[i];
intr_0 = nvgpu_runlist_readl(g, runlist, runlist_intr_0_r());
nvgpu_err(g, "unhandled runlist(%d) intr_0: 0x%08x", i, intr_0);
nvgpu_runlist_writel(g, runlist, runlist_intr_0_r(), intr_0);
}
}
void ga10b_fifo_intr_0_isr(struct gk20a *g)
{
u32 i, intr_0, handled_intr_0 = 0U;
u32 intr_0_en_mask = 0U;
u32 pbdma_idx = 0U;
u32 intr_tree_0 = 0U, intr_tree_1 = 1U;
struct nvgpu_runlist *runlist;
/* TODO: sw_ready is needed only for recovery part */
if (!g->fifo.sw_ready) {
ga10b_fifo_runlist_intr_clear(g);
return;
}
/* note we're not actually in an "isr", but rather
* in a threaded interrupt context... */
nvgpu_mutex_acquire(&g->fifo.intr.isr.mutex);
for (i = 0U; i < g->fifo.num_runlists; i++) {
runlist = &g->fifo.active_runlists[i];
intr_0 = nvgpu_runlist_readl(g, runlist, runlist_intr_0_r());
if (intr_0 & runlist_intr_0_bad_tsg_pending_f()) {
ga10b_fifo_handle_bad_tsg(g, runlist);
handled_intr_0 |= runlist_intr_0_bad_tsg_pending_f();
}
for (pbdma_idx = 0U;
pbdma_idx < runlist_intr_0_pbdmai_intr_tree_j__size_1_v();
pbdma_idx++) {
if (intr_0 &
runlist_intr_0_pbdmai_intr_tree_j_pending_f(pbdma_idx, intr_tree_0)) {
ga10b_fifo_pbdma_isr(g, runlist, pbdma_idx);
handled_intr_0 |= runlist_intr_0_pbdmai_intr_tree_j_pending_f(pbdma_idx, intr_tree_0);
}
}
if (intr_0 & RUNLIST_INTR_0_CTXSW_TIMEOUT_MASK) {
ga10b_fifo_ctxsw_timeout_isr(g, runlist);
handled_intr_0 |=
(RUNLIST_INTR_0_CTXSW_TIMEOUT_MASK & intr_0);
}
/*
* The runlist_intr_0_r register can have bits set for which
* interrupts are not enabled by the SW. Hence, create a mask
* of all the runlist interrupts enabled on both runlist
* tree0,1 and consider only these bits when detecting
* unhandled interrupts.
*/
intr_0_en_mask = nvgpu_runlist_readl(g, runlist,
runlist_intr_0_en_set_tree_r(intr_tree_0));
intr_0_en_mask |= nvgpu_runlist_readl(g, runlist,
runlist_intr_0_en_set_tree_r(intr_tree_1));
if (handled_intr_0 != (intr_0 & intr_0_en_mask)) {
nvgpu_err(g,
"unhandled runlist(%d) intr_0: 0x%08x "
"handled: 0x%08x",
i, intr_0 & intr_0_en_mask, handled_intr_0);
}
handled_intr_0 = 0U;
/** Clear interrupts */
nvgpu_runlist_writel(g, runlist, runlist_intr_0_r(), intr_0);
}
nvgpu_mutex_release(&g->fifo.intr.isr.mutex);
}
void ga10b_fifo_intr_set_recover_mask(struct gk20a *g)
{
u32 i, intr_tree_0;
struct nvgpu_runlist *runlist;
/*
* ctxsw timeout error prevents recovery, and ctxsw error will retrigger
* every 100ms. Disable ctxsw timeout error to allow recovery.
*/
intr_tree_0 = 0U;
for (i = 0U; i < g->fifo.num_runlists; i++) {
runlist = &g->fifo.active_runlists[i];
/**
* runlist_intr_0 interrupts can be routed to either
* tree0 or tree1 vector using runlist_intr_0_en_set_tree(0) or
* runlist_intr_0_en_set_tree(1) register. For now route all
* interrupts are routed to tree0.
*/
/*
* Disable ctxsw interrupts in tree(0) using en_clear_tree_r(0).
* Writes of 1 disables reporting of corresponding interrupt,
* whereas writes with 0 are ignored. Read returns enabled
* interrupts instead of the previous write value.
*/
nvgpu_runlist_writel(g, runlist,
runlist_intr_0_en_clear_tree_r(intr_tree_0),
RUNLIST_INTR_0_RECOVER_MASK);
}
}
void ga10b_fifo_intr_unset_recover_mask(struct gk20a *g)
{
u32 i, intr_tree_0;
struct nvgpu_runlist *runlist;
/*
* ctxsw timeout error prevents recovery, and ctxsw error will retrigger
* every 100ms. To allow recovery, ctxsw timeout is disabled. Enable
* the same after recovery is done.
*/
intr_tree_0 = 0U;
for (i = 0U; i < g->fifo.num_runlists; i++) {
runlist = &g->fifo.active_runlists[i];
/**
* runlist_intr_0 interrupts can be routed to either
* tree0 or tree1 vector using runlist_intr_0_en_set_tree(0) or
* runlist_intr_0_en_set_tree(1) register. For now route all
* interrupts are routed to tree0.
*/
/*
* Enable ctxsw interrupts in tree(0) using en_set_tree_r(0).
* Writes of 1 enables reporting of corresponding interrupt,
* whereas writes with 0 are ignored. Read returns enabled
* interrupts instead of the previous write value.
*/
nvgpu_runlist_writel(g, runlist,
runlist_intr_0_en_set_tree_r(intr_tree_0),
RUNLIST_INTR_0_RECOVER_UNMASK);
}
}
void ga10b_fifo_pbdma_isr(struct gk20a *g, struct nvgpu_runlist *runlist, u32 pbdma_idx)
{
u32 pbdma_id;
const struct nvgpu_next_pbdma_info *pbdma_info;
if (pbdma_idx >= PBDMA_PER_RUNLIST_SIZE) {
nvgpu_err(g, "pbdma_idx(%d) >= max_pbdmas_per_runlist(%d)",
pbdma_idx, PBDMA_PER_RUNLIST_SIZE);
return;
}
pbdma_info = runlist->nvgpu_next.pbdma_info;
pbdma_id = pbdma_info->pbdma_id[pbdma_idx];
if (pbdma_id == PBDMA_ID_INVALID) {
nvgpu_err(g, "runlist_id(%d), pbdma_idx(%d): invalid PBDMA",
runlist->id, pbdma_idx);
return;
}
g->ops.pbdma.handle_intr(g, pbdma_id, true);
}
void ga10b_fifo_runlist_intr_retrigger(struct gk20a *g, u32 intr_tree)
{
u32 i = 0U;
struct nvgpu_runlist *runlist;
for (i = 0U; i < g->fifo.num_runlists; i++) {
runlist = &g->fifo.active_runlists[i];
nvgpu_runlist_writel(g, runlist,
runlist_intr_retrigger_r(intr_tree),
runlist_intr_retrigger_trigger_true_f());
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2020-2021, 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 FIFO_UTILS_GA10B_H
#define FIFO_UTILS_GA10B_H
struct gk20a;
struct nvgpu_runlist;
u32 nvgpu_runlist_readl(struct gk20a *g, struct nvgpu_runlist *runlist,
u32 r);
void nvgpu_runlist_writel(struct gk20a *g, struct nvgpu_runlist *runlist,
u32 r, u32 v);
u32 nvgpu_chram_bar0_readl(struct gk20a *g, struct nvgpu_runlist *runlist,
u32 r);
void nvgpu_chram_bar0_writel(struct gk20a *g,
struct nvgpu_runlist *runlist, u32 r, u32 v);
#endif /* FIFO_UTILS_GA10B_H */

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2020-2021, 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/bug.h>
#include <nvgpu/io.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/runlist.h>
#include "fifo_utils_ga10b.h"
u32 nvgpu_runlist_readl(struct gk20a *g, struct nvgpu_runlist *runlist,
u32 r)
{
u32 runlist_pri_base = 0U;
nvgpu_assert(runlist != NULL);
runlist_pri_base = runlist->nvgpu_next.runlist_pri_base;
nvgpu_assert(runlist_pri_base != 0U);
return nvgpu_readl(g, nvgpu_safe_add_u32(runlist_pri_base, r));
}
void nvgpu_runlist_writel(struct gk20a *g, struct nvgpu_runlist *runlist,
u32 r, u32 v)
{
u32 runlist_pri_base = 0U;
nvgpu_assert(runlist != NULL);
runlist_pri_base = runlist->nvgpu_next.runlist_pri_base;
nvgpu_assert(runlist_pri_base != 0U);
nvgpu_writel(g, nvgpu_safe_add_u32(runlist_pri_base, r), v);
}
u32 nvgpu_chram_bar0_readl(struct gk20a *g, struct nvgpu_runlist *runlist,
u32 r)
{
u32 chram_bar0_offset = 0U;
nvgpu_assert(runlist != NULL);
chram_bar0_offset = runlist->nvgpu_next.chram_bar0_offset;
nvgpu_assert(chram_bar0_offset != 0U);
return nvgpu_readl(g, nvgpu_safe_add_u32(chram_bar0_offset, r));
}
void nvgpu_chram_bar0_writel(struct gk20a *g,
struct nvgpu_runlist *runlist, u32 r, u32 v)
{
u32 chram_bar0_offset = 0U;
nvgpu_assert(runlist != NULL);
chram_bar0_offset = runlist->nvgpu_next.chram_bar0_offset;
nvgpu_assert(chram_bar0_offset != 0U);
nvgpu_writel(g, nvgpu_safe_add_u32(chram_bar0_offset, r), v);
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2020-21, 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_PBDMA_GA100_H
#define NVGPU_PBDMA_GA100_H
#include <nvgpu/types.h>
struct gk20a;
struct nvgpu_device;
u32 ga100_pbdma_set_clear_intr_offsets(struct gk20a *g,
u32 set_clear_size);
u32 ga100_pbdma_get_fc_target(const struct nvgpu_device *dev);
void ga100_pbdma_force_ce_split(struct gk20a *g);
u32 ga100_pbdma_read_data(struct gk20a *g, u32 pbdma_id);
u32 ga100_pbdma_get_num_of_pbdmas(void);
#endif /* NVGPU_PBDMA_GA100_H */

View File

@@ -0,0 +1,106 @@
/*
* Copyright (c) 2020-2021, 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/bitops.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/pbdma_status.h>
#include <nvgpu/nvgpu_err.h>
#include <nvgpu/device.h>
#include <nvgpu/runlist.h>
#include <nvgpu/io.h>
#include "pbdma_ga10b.h"
#include "pbdma_ga100.h"
#include <nvgpu/hw/ga100/hw_pbdma_ga100.h>
u32 ga100_pbdma_set_clear_intr_offsets(struct gk20a *g,
u32 set_clear_size)
{
u32 ret = 0U;
switch(set_clear_size) {
case INTR_SIZE:
ret = pbdma_intr_0__size_1_v();
break;
case INTR_SET_SIZE:
ret = pbdma_intr_0_en_set_tree__size_1_v();
break;
case INTR_CLEAR_SIZE:
ret = pbdma_intr_0_en_clear_tree__size_1_v();
break;
default:
nvgpu_err(g, "Invalid input for set_clear_intr_offset");
break;
}
return ret;
}
u32 ga100_pbdma_get_fc_target(const struct nvgpu_device *dev)
{
return (pbdma_target_engine_f(dev->next.rleng_id) |
pbdma_target_eng_ctx_valid_true_f() |
pbdma_target_ce_ctx_valid_true_f());
}
static void ga100_pbdma_force_ce_split_set(struct gk20a *g,
struct nvgpu_runlist *runlist)
{
u32 reg;
u32 i;
u32 pbdma_id;
const struct nvgpu_next_pbdma_info *pbdma_info = NULL;
pbdma_info = runlist->nvgpu_next.pbdma_info;
for (i = 0U; i < PBDMA_PER_RUNLIST_SIZE; i++) {
pbdma_id = pbdma_info->pbdma_id[i];
if (pbdma_id == U32_MAX) {
continue;
}
reg = nvgpu_readl(g, pbdma_secure_config_r(pbdma_id));
reg = set_field(reg, pbdma_secure_config_force_ce_split_m(),
pbdma_secure_config_force_ce_split_true_f());
nvgpu_writel(g, pbdma_secure_config_r(pbdma_id), reg);
}
}
void ga100_pbdma_force_ce_split(struct gk20a *g)
{
struct nvgpu_runlist *runlist = NULL;
u32 i;
for (i = 0U; i < g->fifo.num_runlists; i++) {
runlist = g->fifo.runlists[i];
ga100_pbdma_force_ce_split_set(g, runlist);
}
}
u32 ga100_pbdma_read_data(struct gk20a *g, u32 pbdma_id)
{
return nvgpu_readl(g, pbdma_hdr_shadow_r(pbdma_id));
}
u32 ga100_pbdma_get_num_of_pbdmas(void)
{
return pbdma_cfg0__size_1_v();
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2020, 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/log.h>
#include <nvgpu/log2.h>
#include <nvgpu/utils.h>
#include <nvgpu/io.h>
#include <nvgpu/bitops.h>
#include <nvgpu/bug.h>
#include <nvgpu/debug.h>
#include <nvgpu/fifo.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/pbdma_status.h>
#include <nvgpu/hw/ga10b/hw_pbdma_ga10b.h>
#include "pbdma_ga10b.h"
void ga10b_pbdma_dump_status(struct gk20a *g, struct nvgpu_debug_context *o)
{
u32 i, host_num_pbdma;
struct nvgpu_pbdma_status_info pbdma_status;
host_num_pbdma = nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_PBDMA);
gk20a_debug_output(o, "PBDMA Status - chip %-5s", g->name);
gk20a_debug_output(o, "-------------------------");
for (i = 0U; i < host_num_pbdma; i++) {
g->ops.pbdma_status.read_pbdma_status_info(g, i,
&pbdma_status);
gk20a_debug_output(o, "pbdma %d:", i);
gk20a_debug_output(o,
" id: %d - %-9s next_id: - %d %-9s | status: %s",
pbdma_status.id,
nvgpu_pbdma_status_is_id_type_tsg(&pbdma_status) ?
"[tsg]" : "[channel]",
pbdma_status.next_id,
nvgpu_pbdma_status_is_next_id_type_tsg(
&pbdma_status) ?
"[tsg]" : "[channel]",
nvgpu_fifo_decode_pbdma_ch_eng_status(
pbdma_status.pbdma_channel_status));
gk20a_debug_output(o,
" PBDMA_PUT %016llx PBDMA_GET %016llx",
(u64)nvgpu_readl(g, pbdma_put_r(i)) +
((u64)nvgpu_readl(g, pbdma_put_hi_r(i)) << 32ULL),
(u64)nvgpu_readl(g, pbdma_get_r(i)) +
((u64)nvgpu_readl(g, pbdma_get_hi_r(i)) << 32ULL));
gk20a_debug_output(o,
" GP_PUT %08x GP_GET %08x "
"FETCH %08x HEADER %08x",
nvgpu_readl(g, pbdma_gp_put_r(i)),
nvgpu_readl(g, pbdma_gp_get_r(i)),
nvgpu_readl(g, pbdma_gp_fetch_r(i)),
nvgpu_readl(g, pbdma_pb_header_r(i)));
gk20a_debug_output(o,
" HDR %08x SHADOW0 %08x SHADOW1 %08x",
g->ops.pbdma.read_data(g, i),
nvgpu_readl(g, pbdma_gp_shadow_0_r(i)),
nvgpu_readl(g, pbdma_gp_shadow_1_r(i)));
}
gk20a_debug_output(o, " ");
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2020, 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_PBDMA_GA10B_H
#define NVGPU_PBDMA_GA10B_H
#include <nvgpu/types.h>
#define HW_PBDMA_STRIDE 2048U
#define HW_PBDMA_BASE 0x040000U
#define PBDMA_PRI_BASE_INVALID U32_MAX
#define PBDMA_ID_INVALID U32_MAX
#define INTR_SIZE 0U
#define INTR_SET_SIZE 1U
#define INTR_CLEAR_SIZE 2U
struct gk20a;
struct nvgpu_debug_context;
struct nvgpu_pbdma_status_info;
struct nvgpu_device;
void ga10b_pbdma_intr_enable(struct gk20a *g, bool enable);
void ga10b_pbdma_handle_intr(struct gk20a *g, u32 pbdma_id, bool recover);
bool ga10b_pbdma_handle_intr_0(struct gk20a *g, u32 pbdma_id, u32 pbdma_intr_0,
u32 *error_notifier);
bool ga10b_pbdma_handle_intr_1(struct gk20a *g, u32 pbdma_id, u32 pbdma_intr_1,
u32 *error_notifier);
u32 ga10b_pbdma_read_data(struct gk20a *g, u32 pbdma_id);
void ga10b_pbdma_reset_header(struct gk20a *g, u32 pbdma_id);
void ga10b_pbdma_reset_method(struct gk20a *g, u32 pbdma_id,
u32 pbdma_method_index);
void ga10b_pbdma_clear_all_intr(struct gk20a *g, u32 pbdma_id);
void ga10b_pbdma_disable_and_clear_all_intr(struct gk20a *g);
u32 ga10b_pbdma_channel_fatal_0_intr_descs(void);
u32 ga10b_pbdma_device_fatal_0_intr_descs(void);
u32 ga10b_pbdma_set_channel_info_chid(u32 chid);
u32 ga10b_pbdma_set_intr_notify(u32 eng_intr_vector);
u32 ga10b_pbdma_set_clear_intr_offsets(struct gk20a *g,
u32 set_clear_size);
u32 ga10b_pbdma_get_fc_target(const struct nvgpu_device *dev);
#ifdef CONFIG_NVGPU_HAL_NON_FUSA
void ga10b_pbdma_dump_status(struct gk20a *g, struct nvgpu_debug_context *o);
#endif
u32 ga10b_pbdma_get_mmu_fault_id(struct gk20a *g, u32 pbdma_id);
u32 ga10b_pbdma_get_num_of_pbdmas(void);
#endif /* NVGPU_PBDMA_GA10B_H */

View File

@@ -0,0 +1,615 @@
/*
* Copyright (c) 2020, 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/log.h>
#include <nvgpu/log2.h>
#include <nvgpu/utils.h>
#include <nvgpu/io.h>
#include <nvgpu/bitops.h>
#include <nvgpu/error_notifier.h>
#include <nvgpu/fifo.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/pbdma_status.h>
#include <nvgpu/static_analysis.h>
#include <nvgpu/nvgpu_err.h>
#include <nvgpu/runlist.h>
#include <nvgpu/rc.h>
#include <nvgpu/device.h>
#include "pbdma_ga10b.h"
#include <nvgpu/hw/ga10b/hw_pbdma_ga10b.h>
#define PBDMA_INTR_0_EN_SET_TREE_MASK \
( \
pbdma_intr_0_en_set_tree_gpfifo_enabled_f() | \
pbdma_intr_0_en_set_tree_gpptr_enabled_f() | \
pbdma_intr_0_en_set_tree_gpentry_enabled_f() | \
pbdma_intr_0_en_set_tree_gpcrc_enabled_f() | \
pbdma_intr_0_en_set_tree_pbptr_enabled_f() | \
pbdma_intr_0_en_set_tree_pbentry_enabled_f() | \
pbdma_intr_0_en_set_tree_pbcrc_enabled_f() | \
pbdma_intr_0_en_set_tree_method_enabled_f() | \
pbdma_intr_0_en_set_tree_device_enabled_f() | \
pbdma_intr_0_en_set_tree_eng_reset_enabled_f() | \
pbdma_intr_0_en_set_tree_semaphore_enabled_f() | \
pbdma_intr_0_en_set_tree_acquire_enabled_f() | \
pbdma_intr_0_en_set_tree_pri_enabled_f() | \
pbdma_intr_0_en_set_tree_pbseg_enabled_f() | \
pbdma_intr_0_en_set_tree_signature_enabled_f() \
)
#define PBDMA_INTR_0_EN_CLEAR_TREE_MASK \
( \
pbdma_intr_0_en_clear_tree_gpfifo_enabled_f() | \
pbdma_intr_0_en_clear_tree_gpptr_enabled_f() | \
pbdma_intr_0_en_clear_tree_gpentry_enabled_f() | \
pbdma_intr_0_en_clear_tree_gpcrc_enabled_f() | \
pbdma_intr_0_en_clear_tree_pbptr_enabled_f() | \
pbdma_intr_0_en_clear_tree_pbentry_enabled_f() | \
pbdma_intr_0_en_clear_tree_pbcrc_enabled_f() | \
pbdma_intr_0_en_clear_tree_method_enabled_f() | \
pbdma_intr_0_en_clear_tree_device_enabled_f() | \
pbdma_intr_0_en_clear_tree_eng_reset_enabled_f() | \
pbdma_intr_0_en_clear_tree_semaphore_enabled_f() | \
pbdma_intr_0_en_clear_tree_acquire_enabled_f() | \
pbdma_intr_0_en_clear_tree_pri_enabled_f() | \
pbdma_intr_0_en_clear_tree_pbseg_enabled_f() | \
pbdma_intr_0_en_clear_tree_signature_enabled_f() \
)
#define PBDMA_INTR_1_EN_SET_TREE_MASK \
( \
pbdma_intr_1_en_set_tree_hce_re_illegal_op_enabled_f() | \
pbdma_intr_1_en_set_tree_hce_re_alignb_enabled_f() | \
pbdma_intr_1_en_set_tree_hce_priv_enabled_f() | \
pbdma_intr_1_en_set_tree_hce_illegal_mthd_enabled_f() | \
pbdma_intr_1_en_set_tree_hce_illegal_class_enabled_f() | \
pbdma_intr_1_en_set_tree_ctxnotvalid_enabled_f() \
)
#define PBDMA_INTR_1_EN_CLEAR_TREE_MASK \
( \
pbdma_intr_1_en_clear_tree_hce_re_illegal_op_enabled_f() | \
pbdma_intr_1_en_clear_tree_hce_re_alignb_enabled_f() | \
pbdma_intr_1_en_clear_tree_hce_priv_enabled_f() | \
pbdma_intr_1_en_clear_tree_hce_illegal_mthd_enabled_f() | \
pbdma_intr_1_en_clear_tree_hce_illegal_class_enabled_f() | \
pbdma_intr_1_en_clear_tree_ctxnotvalid_enabled_f() \
)
/**
* nvgpu will route all pbdma intr to tree_0
* The interrupt registers NV_PPBDMA_INTR_* contain and control the interrupt
* state for each PBDMA. Interrupts are set by events and are cleared by software
* running on the CPU or GSP.
*
* Interrupts in the PBDMA are divided into two interrupt trees:
* RUNLIST_INTR_0_PBDMAn_INTR_TREE_0 RUNLIST_INTR_0_PBDMAn_INTR_TREE_1
* | |
* ______^______ ______^______
* / \ / \
* | OR | | OR |
* '_______________' '_______________'
* ||||||| | | |||||||
* other tree0 | | other tree1
* ANDed intr bits ^ ^ ANDed intr bits
* AND AND
* | | | |
* _______. .______ _______. .________
* / \ / \
* | \ / |
* PPBDMA_INTR_0/1_EN_SET_TREE(p,0)_intr Y PPBDMA_INTR_0/1_EN_SET_TREE(p,1)_intr
* |
* NV_PPBDMA_INTR_0/1_intr_bit
*/
/* TBD: NVGPU-4516: Update fault_type_desc */
static const char *const pbdma_intr_fault_type_desc[] = {
"MEMREQ timeout", "MEMACK_TIMEOUT", "MEMACK_EXTRA acks",
"MEMDAT_TIMEOUT", "MEMDAT_EXTRA acks", "MEMFLUSH noack",
"MEMOP noack", "LBCONNECT noack", "NONE - was LBREQ",
"LBACK_TIMEOUT", "LBACK_EXTRA acks", "LBDAT_TIMEOUT",
"LBDAT_EXTRA acks", "GPFIFO won't fit", "GPPTR invalid",
"GPENTRY invalid", "GPCRC mismatch", "PBPTR get>put",
"PBENTRY invld", "PBCRC mismatch", "NONE - was XBARC",
"METHOD invld", "METHODCRC mismat", "DEVICE sw method",
"[ENGINE]", "SEMAPHORE invlid", "ACQUIRE timeout",
"PRI forbidden", "ILLEGAL SYNCPT", "[NO_CTXSW_SEG]",
"PBSEG badsplit", "SIGNATURE bad"
};
static bool ga10b_pbdma_is_sw_method_subch(struct gk20a *g, u32 pbdma_id,
u32 pbdma_method_index)
{
u32 pbdma_method_stride;
u32 pbdma_method_reg, pbdma_method_subch;
pbdma_method_stride = nvgpu_safe_sub_u32(pbdma_method1_r(pbdma_id),
pbdma_method0_r(pbdma_id));
pbdma_method_reg = nvgpu_safe_add_u32(pbdma_method0_r(pbdma_id),
nvgpu_safe_mult_u32(pbdma_method_index,
pbdma_method_stride));
pbdma_method_subch = pbdma_method0_subch_v(
nvgpu_readl(g, pbdma_method_reg));
if ((pbdma_method_subch == 5U) ||
(pbdma_method_subch == 6U) ||
(pbdma_method_subch == 7U)) {
return true;
}
return false;
}
u32 ga10b_pbdma_set_clear_intr_offsets(struct gk20a *g,
u32 set_clear_size)
{
u32 ret = 0U;
switch(set_clear_size) {
case INTR_SIZE:
ret = pbdma_intr_0__size_1_v();
break;
case INTR_SET_SIZE:
ret = pbdma_intr_0_en_set_tree__size_1_v();
break;
case INTR_CLEAR_SIZE:
ret = pbdma_intr_0_en_clear_tree__size_1_v();
break;
default:
nvgpu_err(g, "Invalid input for set_clear_intr_offset");
break;
}
return ret;
}
static void ga10b_pbdma_disable_all_intr(struct gk20a *g)
{
u32 pbdma_id = 0U;
u32 tree = 0U;
u32 pbdma_id_max =
g->ops.pbdma.set_clear_intr_offsets(g, INTR_CLEAR_SIZE);
for (pbdma_id = 0U; pbdma_id < pbdma_id_max; pbdma_id++) {
for (tree = 0U; tree < pbdma_intr_0_en_clear_tree__size_2_v();
tree++) {
nvgpu_writel(g, pbdma_intr_0_en_clear_tree_r(pbdma_id,
tree), PBDMA_INTR_0_EN_CLEAR_TREE_MASK);
nvgpu_writel(g, pbdma_intr_1_en_clear_tree_r(pbdma_id,
tree), PBDMA_INTR_1_EN_CLEAR_TREE_MASK);
}
}
}
void ga10b_pbdma_clear_all_intr(struct gk20a *g, u32 pbdma_id)
{
nvgpu_writel(g, pbdma_intr_0_r(pbdma_id), U32_MAX);
nvgpu_writel(g, pbdma_intr_1_r(pbdma_id), U32_MAX);
}
void ga10b_pbdma_disable_and_clear_all_intr(struct gk20a *g)
{
u32 pbdma_id = 0U;
u32 pbdma_id_max =
g->ops.pbdma.set_clear_intr_offsets(g, INTR_SIZE);
ga10b_pbdma_disable_all_intr(g);
for (pbdma_id = 0U; pbdma_id < pbdma_id_max; pbdma_id++) {
ga10b_pbdma_clear_all_intr(g, pbdma_id);
}
}
static void ga10b_pbdma_dump_intr_0(struct gk20a *g, u32 pbdma_id,
u32 pbdma_intr_0)
{
u32 header = nvgpu_readl(g, pbdma_pb_header_r(pbdma_id));
u32 data = g->ops.pbdma.read_data(g, pbdma_id);
u32 shadow_0 = nvgpu_readl(g, pbdma_gp_shadow_0_r(pbdma_id));
u32 shadow_1 = nvgpu_readl(g, pbdma_gp_shadow_1_r(pbdma_id));
u32 method0 = nvgpu_readl(g, pbdma_method0_r(pbdma_id));
u32 method1 = nvgpu_readl(g, pbdma_method1_r(pbdma_id));
u32 method2 = nvgpu_readl(g, pbdma_method2_r(pbdma_id));
u32 method3 = nvgpu_readl(g, pbdma_method3_r(pbdma_id));
nvgpu_err(g,
"pbdma_intr_0(%d):0x%08x PBH: %08x "
"SHADOW: %08x gp shadow0: %08x gp shadow1: %08x"
"M0: %08x %08x %08x %08x ",
pbdma_id, pbdma_intr_0, header, data,
shadow_0, shadow_1, method0, method1, method2, method3);
}
/* Copied static function */
static u32 pbdma_get_intr_descs(struct gk20a *g)
{
struct nvgpu_fifo *f = &g->fifo;
u32 intr_descs = (f->intr.pbdma.device_fatal_0 |
f->intr.pbdma.channel_fatal_0 |
f->intr.pbdma.restartable_0);
return intr_descs;
}
void ga10b_pbdma_reset_header(struct gk20a *g, u32 pbdma_id)
{
nvgpu_writel(g, pbdma_pb_header_r(pbdma_id),
pbdma_pb_header_first_true_f() |
pbdma_pb_header_type_non_inc_f());
}
void ga10b_pbdma_reset_method(struct gk20a *g, u32 pbdma_id,
u32 pbdma_method_index)
{
u32 pbdma_method_stride;
u32 pbdma_method_reg;
pbdma_method_stride = nvgpu_safe_sub_u32(pbdma_method1_r(pbdma_id),
pbdma_method0_r(pbdma_id));
pbdma_method_reg = nvgpu_safe_add_u32(pbdma_method0_r(pbdma_id),
nvgpu_safe_mult_u32(pbdma_method_index,
pbdma_method_stride));
nvgpu_writel(g, pbdma_method_reg,
pbdma_method0_valid_true_f() |
pbdma_method0_first_true_f() |
pbdma_method0_addr_f(
U32(pbdma_udma_nop_r()) >> 2U));
}
u32 ga10b_pbdma_read_data(struct gk20a *g, u32 pbdma_id)
{
return nvgpu_readl(g, pbdma_hdr_shadow_r(pbdma_id));
}
static void report_pbdma_error(struct gk20a *g, u32 pbdma_id,
u32 pbdma_intr_0)
{
u32 err_type = GPU_HOST_INVALID_ERROR;
/*
* Multiple errors have been grouped as part of a single
* top-level error.
*/
if ((pbdma_intr_0 & (
pbdma_intr_0_gpfifo_pending_f() |
pbdma_intr_0_gpptr_pending_f() |
pbdma_intr_0_gpentry_pending_f() |
pbdma_intr_0_gpcrc_pending_f() |
pbdma_intr_0_pbptr_pending_f() |
pbdma_intr_0_pbentry_pending_f() |
pbdma_intr_0_pbcrc_pending_f())) != 0U) {
err_type = GPU_HOST_PBDMA_GPFIFO_PB_ERROR;
}
if ((pbdma_intr_0 & (
pbdma_intr_0_method_pending_f() |
pbdma_intr_0_device_pending_f() |
pbdma_intr_0_eng_reset_pending_f() |
pbdma_intr_0_semaphore_pending_f() |
pbdma_intr_0_acquire_pending_f() |
pbdma_intr_0_pri_pending_f() |
pbdma_intr_0_pbseg_pending_f())) != 0U) {
err_type = GPU_HOST_PBDMA_METHOD_ERROR;
}
if ((pbdma_intr_0 &
pbdma_intr_0_signature_pending_f()) != 0U) {
err_type = GPU_HOST_PBDMA_SIGNATURE_ERROR;
}
if (err_type != GPU_HOST_INVALID_ERROR) {
nvgpu_report_host_err(g, NVGPU_ERR_MODULE_HOST,
pbdma_id, err_type, pbdma_intr_0);
}
return;
}
void ga10b_pbdma_intr_enable(struct gk20a *g, bool enable)
{
u32 pbdma_id = 0U;
u32 tree = 0U;
u32 pbdma_id_max =
g->ops.pbdma.set_clear_intr_offsets(g, INTR_SET_SIZE);
if (!enable) {
ga10b_pbdma_disable_and_clear_all_intr(g);
return;
}
for (pbdma_id = 0U; pbdma_id < pbdma_id_max; pbdma_id++) {
ga10b_pbdma_clear_all_intr(g, pbdma_id);
/* enable pbdma interrupts and route to tree_0 */
nvgpu_writel(g, pbdma_intr_0_en_set_tree_r(pbdma_id,
tree), PBDMA_INTR_0_EN_SET_TREE_MASK);
nvgpu_writel(g, pbdma_intr_1_en_set_tree_r(pbdma_id,
tree), PBDMA_INTR_1_EN_SET_TREE_MASK);
}
}
void ga10b_pbdma_handle_intr(struct gk20a *g, u32 pbdma_id, bool recover)
{
struct nvgpu_pbdma_status_info pbdma_status;
u32 intr_error_notifier = NVGPU_ERR_NOTIFIER_PBDMA_ERROR;
u32 pbdma_intr_0 = nvgpu_readl(g, pbdma_intr_0_r(pbdma_id));
u32 pbdma_intr_1 = nvgpu_readl(g, pbdma_intr_1_r(pbdma_id));
if (pbdma_intr_0 != 0U) {
nvgpu_log(g, gpu_dbg_info | gpu_dbg_intr,
"pbdma id %d intr_0 0x%08x pending",
pbdma_id, pbdma_intr_0);
if (g->ops.pbdma.handle_intr_0(g, pbdma_id, pbdma_intr_0,
&intr_error_notifier)) {
g->ops.pbdma_status.read_pbdma_status_info(g,
pbdma_id, &pbdma_status);
if (recover) {
nvgpu_rc_pbdma_fault(g, pbdma_id,
intr_error_notifier,
&pbdma_status);
}
}
nvgpu_writel(g, pbdma_intr_0_r(pbdma_id), pbdma_intr_0);
}
if (pbdma_intr_1 != 0U) {
nvgpu_log(g, gpu_dbg_info | gpu_dbg_intr,
"pbdma id %d intr_1 0x%08x pending",
pbdma_id, pbdma_intr_1);
if (g->ops.pbdma.handle_intr_1(g, pbdma_id, pbdma_intr_1,
&intr_error_notifier)) {
g->ops.pbdma_status.read_pbdma_status_info(g,
pbdma_id, &pbdma_status);
if (recover) {
nvgpu_rc_pbdma_fault(g, pbdma_id,
intr_error_notifier,
&pbdma_status);
}
}
nvgpu_writel(g, pbdma_intr_1_r(pbdma_id), pbdma_intr_1);
}
}
static bool ga10b_pbdma_handle_intr_0_legacy(struct gk20a *g, u32 pbdma_id,
u32 pbdma_intr_0, u32 *error_notifier)
{
bool recover = false;
u32 i;
unsigned long pbdma_intr_err;
unsigned long bit;
u32 intr_descs = pbdma_get_intr_descs(g);
if ((intr_descs & pbdma_intr_0) != 0U) {
pbdma_intr_err = (unsigned long)pbdma_intr_0;
for_each_set_bit(bit, &pbdma_intr_err, 32U) {
nvgpu_err(g, "PBDMA intr %s Error",
pbdma_intr_fault_type_desc[bit]);
}
ga10b_pbdma_dump_intr_0(g, pbdma_id, pbdma_intr_0);
recover = true;
}
if ((pbdma_intr_0 & pbdma_intr_0_acquire_pending_f()) != 0U) {
u32 val = nvgpu_readl(g, pbdma_acquire_r(pbdma_id));
val &= ~pbdma_acquire_timeout_en_enable_f();
nvgpu_writel(g, pbdma_acquire_r(pbdma_id), val);
if (nvgpu_is_timeouts_enabled(g)) {
recover = true;
nvgpu_err(g, "semaphore acquire timeout!");
/*
* Note: the error_notifier can be overwritten if
* semaphore_timeout is triggered with pbcrc_pending
* interrupt below
*/
*error_notifier =
NVGPU_ERR_NOTIFIER_GR_SEMAPHORE_TIMEOUT;
}
}
if ((pbdma_intr_0 & pbdma_intr_0_pbentry_pending_f()) != 0U) {
g->ops.pbdma.reset_header(g, pbdma_id);
ga10b_pbdma_reset_method(g, pbdma_id, 0);
recover = true;
}
if ((pbdma_intr_0 & pbdma_intr_0_method_pending_f()) != 0U) {
ga10b_pbdma_reset_method(g, pbdma_id, 0);
recover = true;
}
if ((pbdma_intr_0 & pbdma_intr_0_pbcrc_pending_f()) != 0U) {
*error_notifier =
NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH;
recover = true;
}
if ((pbdma_intr_0 & pbdma_intr_0_device_pending_f()) != 0U) {
g->ops.pbdma.reset_header(g, pbdma_id);
for (i = 0U; i < 4U; i++) {
if (ga10b_pbdma_is_sw_method_subch(g,
pbdma_id, i)) {
ga10b_pbdma_reset_method(g,
pbdma_id, i);
}
}
recover = true;
}
return recover;
}
bool ga10b_pbdma_handle_intr_0(struct gk20a *g, u32 pbdma_id, u32 pbdma_intr_0,
u32 *error_notifier)
{
bool recover = ga10b_pbdma_handle_intr_0_legacy(g, pbdma_id,
pbdma_intr_0, error_notifier);
if ((pbdma_intr_0 & pbdma_intr_0_eng_reset_pending_f()) != 0U) {
nvgpu_log(g, gpu_dbg_intr, "eng reset intr on pbdma id %d",
pbdma_id);
recover = true;
}
report_pbdma_error(g, pbdma_id, pbdma_intr_0);
return recover;
}
/*
* Pbdma which encountered the ctxnotvalid interrupt will stall and
* prevent the channel which was loaded at the time the interrupt fired
* from being swapped out until the interrupt is cleared.
* CTXNOTVALID pbdma interrupt indicates error conditions related
* to the *_CTX_VALID fields for a channel. The following
* conditions trigger the interrupt:
* * CTX_VALID bit for the targeted engine is FALSE
* * At channel start/resume, all preemptible eng have CTX_VALID FALSE but:
* - CTX_RELOAD is set in CCSR_CHANNEL_STATUS,
* - PBDMA_TARGET_SHOULD_SEND_HOST_TSG_EVENT is TRUE, or
* - PBDMA_TARGET_NEEDS_HOST_TSG_EVENT is TRUE
* The field is left NOT_PENDING and the interrupt is not raised if the PBDMA is
* currently halted. This allows SW to unblock the PBDMA and recover.
* SW may read METHOD0, CHANNEL_STATUS and TARGET to determine whether the
* interrupt was due to an engine method, CTX_RELOAD, SHOULD_SEND_HOST_TSG_EVENT
* or NEEDS_HOST_TSG_EVENT. If METHOD0 VALID is TRUE, lazy context creation
* can be used or the TSG may be destroyed.
* If METHOD0 VALID is FALSE, the error is likely a bug in SW, and the TSG
* will have to be destroyed.
*/
bool ga10b_pbdma_handle_intr_1(struct gk20a *g, u32 pbdma_id, u32 pbdma_intr_1,
u32 *error_notifier)
{
bool recover = false;
u32 pbdma_intr_1_current = nvgpu_readl(g, pbdma_intr_1_r(pbdma_id));
/* minimize race with the gpu clearing the pending interrupt */
if ((pbdma_intr_1_current &
pbdma_intr_1_ctxnotvalid_pending_f()) == 0U) {
pbdma_intr_1 &= ~pbdma_intr_1_ctxnotvalid_pending_f();
}
if (pbdma_intr_1 == 0U) {
return recover;
}
recover = true;
nvgpu_report_host_err(g, NVGPU_ERR_MODULE_HOST, pbdma_id,
GPU_HOST_PBDMA_HCE_ERROR, pbdma_intr_1);
if ((pbdma_intr_1 & pbdma_intr_1_ctxnotvalid_pending_f()) != 0U) {
nvgpu_log(g, gpu_dbg_intr, "ctxnotvalid intr on pbdma id %d",
pbdma_id);
nvgpu_err(g, "pbdma_intr_1(%d)= 0x%08x ",
pbdma_id, pbdma_intr_1);
} else{
/*
* rest of the interrupts in _intr_1 are "host copy engine"
* related, which is not supported. For now just make them
* channel fatal.
*/
nvgpu_err(g, "hce err: pbdma_intr_1(%d):0x%08x",
pbdma_id, pbdma_intr_1);
}
return recover;
}
u32 ga10b_pbdma_channel_fatal_0_intr_descs(void)
{
/*
* These are data parsing, framing errors or others which can be
* recovered from with intervention... or just resetting the
* channel
*/
u32 channel_fatal_0_intr_descs =
pbdma_intr_0_gpfifo_pending_f() |
pbdma_intr_0_gpptr_pending_f() |
pbdma_intr_0_gpentry_pending_f() |
pbdma_intr_0_gpcrc_pending_f() |
pbdma_intr_0_pbptr_pending_f() |
pbdma_intr_0_pbentry_pending_f() |
pbdma_intr_0_pbcrc_pending_f() |
pbdma_intr_0_method_pending_f() |
pbdma_intr_0_pbseg_pending_f() |
pbdma_intr_0_eng_reset_pending_f() |
pbdma_intr_0_semaphore_pending_f() |
pbdma_intr_0_signature_pending_f();
return channel_fatal_0_intr_descs;
}
u32 ga10b_pbdma_device_fatal_0_intr_descs(void)
{
/*
* These are all errors which indicate something really wrong
* going on in the device.
*/
u32 fatal_device_0_intr_descs = pbdma_intr_0_pri_pending_f();
return fatal_device_0_intr_descs;
}
u32 ga10b_pbdma_set_channel_info_chid(u32 chid)
{
return pbdma_set_channel_info_chid_f(chid);
}
u32 ga10b_pbdma_set_intr_notify(u32 eng_intr_vector)
{
return pbdma_intr_notify_vector_f(eng_intr_vector) |
pbdma_intr_notify_ctrl_gsp_disable_f() |
pbdma_intr_notify_ctrl_cpu_enable_f();
}
u32 ga10b_pbdma_get_fc_target(const struct nvgpu_device *dev)
{
return (pbdma_target_engine_f(dev->next.rleng_id) |
pbdma_target_eng_ctx_valid_true_f() |
pbdma_target_ce_ctx_valid_true_f());
}
u32 ga10b_pbdma_get_mmu_fault_id(struct gk20a *g, u32 pbdma_id)
{
u32 pbdma_cfg0 = nvgpu_readl(g, pbdma_cfg0_r(pbdma_id));
return pbdma_cfg0_pbdma_fault_id_v(pbdma_cfg0);
}
u32 ga10b_pbdma_get_num_of_pbdmas(void)
{
return pbdma_cfg0__size_1_v();
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2020, 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_PBDMA_STATUS_GA10B_H
#define NVGPU_PBDMA_STATUS_GA10B_H
#include <nvgpu/types.h>
struct gk20a;
struct nvgpu_pbdma_status_info;
void ga10b_read_pbdma_status_info(struct gk20a *g, u32 pbdma_id,
struct nvgpu_pbdma_status_info *status);
#endif /* NVGPU_PBDMA_STATUS_GA10B_H */

View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2020, 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/io.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/pbdma_status.h>
#include "pbdma_status_ga10b.h"
#include <nvgpu/hw/ga10b/hw_pbdma_ga10b.h>
static void populate_invalid_chsw_status_info(
struct nvgpu_pbdma_status_info *status_info)
{
status_info->id = PBDMA_STATUS_ID_INVALID;
status_info->id_type = PBDMA_STATUS_ID_TYPE_INVALID;
status_info->next_id = PBDMA_STATUS_NEXT_ID_INVALID;
status_info->next_id_type = PBDMA_STATUS_NEXT_ID_TYPE_INVALID;
status_info->chsw_status = NVGPU_PBDMA_CHSW_STATUS_INVALID;
}
static void populate_valid_chsw_status_info(
struct nvgpu_pbdma_status_info *status_info)
{
u32 engine_status = status_info->pbdma_reg_status;
status_info->id = pbdma_status_sched_tsgid_v(engine_status);
status_info->id_type = PBDMA_STATUS_ID_TYPE_TSGID;
status_info->next_id = PBDMA_STATUS_NEXT_ID_INVALID;
status_info->next_id_type = PBDMA_STATUS_NEXT_ID_TYPE_INVALID;
status_info->chsw_status = NVGPU_PBDMA_CHSW_STATUS_VALID;
}
static void populate_load_chsw_status_info(
struct nvgpu_pbdma_status_info *status_info)
{
u32 engine_status = status_info->pbdma_reg_status;
status_info->id = PBDMA_STATUS_ID_INVALID;
status_info->id_type = PBDMA_STATUS_ID_TYPE_INVALID;
status_info->next_id = pbdma_status_sched_next_tsgid_v(engine_status);
status_info->next_id_type = PBDMA_STATUS_NEXT_ID_TYPE_TSGID;
status_info->chsw_status = NVGPU_PBDMA_CHSW_STATUS_LOAD;
}
static void populate_save_chsw_status_info(
struct nvgpu_pbdma_status_info *status_info)
{
u32 engine_status = status_info->pbdma_reg_status;
status_info->id = pbdma_status_sched_tsgid_v(engine_status);
status_info->id_type = PBDMA_STATUS_ID_TYPE_TSGID;
status_info->next_id = PBDMA_STATUS_NEXT_ID_INVALID;
status_info->next_id_type = PBDMA_STATUS_NEXT_ID_TYPE_INVALID;
status_info->chsw_status = NVGPU_PBDMA_CHSW_STATUS_SAVE;
}
static void populate_switch_chsw_status_info(
struct nvgpu_pbdma_status_info *status_info)
{
u32 engine_status = status_info->pbdma_reg_status;
status_info->id = pbdma_status_sched_tsgid_v(engine_status);
status_info->id_type = PBDMA_STATUS_ID_TYPE_TSGID;
status_info->next_id = pbdma_status_sched_next_tsgid_v(engine_status);
status_info->next_id_type = PBDMA_STATUS_NEXT_ID_TYPE_TSGID;
status_info->chsw_status = NVGPU_PBDMA_CHSW_STATUS_SWITCH;
}
void ga10b_read_pbdma_status_info(struct gk20a *g, u32 pbdma_id,
struct nvgpu_pbdma_status_info *status)
{
u32 pbdma_reg_status;
u32 pbdma_channel_status;
(void) memset(status, 0, sizeof(*status));
pbdma_reg_status = nvgpu_readl(g, pbdma_status_sched_r(pbdma_id));
status->pbdma_reg_status = pbdma_reg_status;
/* populate the chsw related info */
pbdma_channel_status = pbdma_status_sched_chan_status_v(
pbdma_reg_status);
status->pbdma_channel_status = pbdma_channel_status;
if (pbdma_channel_status == pbdma_status_sched_chan_status_valid_v()) {
populate_valid_chsw_status_info(status);
} else if (pbdma_channel_status ==
pbdma_status_sched_chan_status_chsw_load_v()) {
populate_load_chsw_status_info(status);
} else if (pbdma_channel_status ==
pbdma_status_sched_chan_status_chsw_save_v()) {
populate_save_chsw_status_info(status);
} else if (pbdma_channel_status ==
pbdma_status_sched_chan_status_chsw_switch_v()) {
populate_switch_chsw_status_info(status);
} else {
populate_invalid_chsw_status_info(status);
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2020, 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 FIFO_PREEMPT_GA10B_H
#define FIFO_PREEMPT_GA10B_H
#include <nvgpu/types.h>
struct gk20a;
void ga10b_fifo_preempt_trigger(struct gk20a *g, u32 id, unsigned int id_type);
#endif /* FIFO_PREEMPT_GA10B_H */

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2020-2021, 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/fifo.h>
#include <nvgpu/runlist.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/preempt.h>
#include <nvgpu/nvgpu_err.h>
#include "fifo_utils_ga10b.h"
#include "preempt_ga10b.h"
#include <nvgpu/hw/ga10b/hw_runlist_ga10b.h>
void ga10b_fifo_preempt_trigger(struct gk20a *g, u32 id, unsigned int id_type)
{
struct nvgpu_runlist *runlist = NULL;
if (id == INVAL_ID) {
nvgpu_log(g, gpu_dbg_info, "Invalid id, cannot preempt");
return;
}
if (id_type == ID_TYPE_TSG) {
struct nvgpu_tsg *tsg = &g->fifo.tsg[id];
nvgpu_runlist_writel(g, tsg->runlist, runlist_preempt_r(),
runlist_preempt_id_f(id) |
runlist_preempt_type_tsg_f());
} else if (id_type == ID_TYPE_RUNLIST) {
runlist = g->fifo.runlists[id];
nvgpu_runlist_writel(g, runlist, runlist_preempt_r(),
runlist_preempt_type_runlist_f());
} else {
nvgpu_log_info(g, "id_type=%u preempt is noop", id_type);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2020, 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_RAMFC_GA10B_H
#define NVGPU_RAMFC_GA10B_H
#include <nvgpu/types.h>
struct nvgpu_channel;
struct nvgpu_channel_dump_info;
int ga10b_ramfc_setup(struct nvgpu_channel *ch, u64 gpfifo_base,
u32 gpfifo_entries, u64 pbdma_acquire_timeout, u32 flags);
void ga10b_ramfc_capture_ram_dump(struct gk20a *g, struct nvgpu_channel *ch,
struct nvgpu_channel_dump_info *info);
#endif /* NVGPU_RAMFC_GA10B_H */

View File

@@ -0,0 +1,168 @@
/*
* Copyright (c) 2020-2021, 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/log.h>
#include <nvgpu/log2.h>
#include <nvgpu/nvgpu_mem.h>
#include <nvgpu/io.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/channel.h>
#include <nvgpu/fifo.h>
#include <nvgpu/engines.h>
#include <nvgpu/runlist.h>
#include "hal/fifo/ramfc_ga10b.h"
#include <nvgpu/hw/ga10b/hw_ram_ga10b.h>
int ga10b_ramfc_setup(struct nvgpu_channel *ch, u64 gpfifo_base,
u32 gpfifo_entries, u64 pbdma_acquire_timeout, u32 flags)
{
struct gk20a *g = ch->g;
struct nvgpu_mem *mem = &ch->inst_block;
u32 data;
u32 engine_id = 0U;
u32 eng_intr_mask = 0U;
u32 eng_intr_vector = 0U;
u32 eng_bitmask = 0U;
bool replayable = false;
nvgpu_log_fn(g, " ");
/*
* ga10b can have max 3 engines on a runlist and only
* runlist 0 has more than 1 engine(gr0, grcopy0 and grcopy1).
* Since grcopy0 and grcopy1 can't schedule work directly, it
* is always safe to assume that first active engine on runlist
* will trigger pbdma intr notify.
* TODO: Add helper function to get active engine mask for
* runlist - NVGPU-5219
*/
eng_bitmask = ch->runlist->eng_bitmask;
engine_id = nvgpu_safe_sub_u32(
nvgpu_safe_cast_u64_to_u32(nvgpu_ffs(eng_bitmask)), 1U);
nvgpu_memset(g, mem, 0U, 0U, ram_fc_size_val_v());
#ifdef CONFIG_NVGPU_REPLAYABLE_FAULT
if ((flags & NVGPU_SETUP_BIND_FLAGS_REPLAYABLE_FAULTS_ENABLE) != 0U) {
replayable = true;
}
#endif
nvgpu_log_info(g, "%llu %u", pbdma_acquire_timeout,
g->ops.pbdma.acquire_val(pbdma_acquire_timeout));
g->ops.ramin.init_subctx_pdb(g, mem, ch->vm->pdb.mem,
replayable, nvgpu_channel_get_max_subctx_count(ch));
nvgpu_mem_wr32(g, mem, ram_fc_gp_base_w(),
g->ops.pbdma.get_gp_base(gpfifo_base));
nvgpu_mem_wr32(g, mem, ram_fc_gp_base_hi_w(),
g->ops.pbdma.get_gp_base_hi(gpfifo_base, gpfifo_entries));
nvgpu_mem_wr32(g, mem, ram_fc_signature_w(),
ch->g->ops.pbdma.get_signature(ch->g));
nvgpu_mem_wr32(g, mem, ram_fc_pb_header_w(),
g->ops.pbdma.get_fc_pb_header());
nvgpu_mem_wr32(g, mem, ram_fc_subdevice_w(),
g->ops.pbdma.get_fc_subdevice());
nvgpu_mem_wr32(g, mem, ram_fc_target_w(),
g->ops.pbdma.get_fc_target(
nvgpu_engine_get_active_eng_info(g, engine_id)));
nvgpu_mem_wr32(g, mem, ram_fc_acquire_w(),
g->ops.pbdma.acquire_val(pbdma_acquire_timeout));
data = nvgpu_mem_rd32(g, mem, ram_fc_set_channel_info_w());
data = data | (g->ops.pbdma.set_channel_info_veid(ch->subctx_id) |
g->ops.pbdma.set_channel_info_chid(ch->chid));
nvgpu_mem_wr32(g, mem, ram_fc_set_channel_info_w(), data);
nvgpu_mem_wr32(g, mem, ram_in_engine_wfi_veid_w(),
ram_in_engine_wfi_veid_f(ch->subctx_id));
/* get engine interrupt vector */
eng_intr_mask = nvgpu_engine_act_interrupt_mask(g, engine_id);
eng_intr_vector = nvgpu_safe_sub_u32(
nvgpu_safe_cast_u64_to_u32(nvgpu_ffs(eng_intr_mask)), 1U);
/*
* engine_intr_vector can be value between 0 and 255.
* For example, engine_intr_vector x translates to subtree x/64,
* leaf (x % 64)/32 and leaf entry interrupt bit(x % 64)%32.
* ga10b engine_intr_vectors are 0,1,2,3,4,5. They map to
* subtree_0 and leaf_0(Engine non-stall interrupts) interrupt
* bits.
*/
data = g->ops.pbdma.set_intr_notify(eng_intr_vector);
nvgpu_mem_wr32(g, mem, ram_fc_intr_notify_w(), data);
if (ch->is_privileged_channel) {
/* Set privilege level for channel */
nvgpu_mem_wr32(g, mem, ram_fc_config_w(),
g->ops.pbdma.get_config_auth_level_privileged());
/* Enable HCE priv mode for phys mode transfer */
nvgpu_mem_wr32(g, mem, ram_fc_hce_ctrl_w(),
g->ops.pbdma.get_ctrl_hce_priv_mode_yes());
}
/* Enable userd writeback */
data = nvgpu_mem_rd32(g, mem, ram_fc_config_w());
data = g->ops.pbdma.config_userd_writeback_enable(data);
nvgpu_mem_wr32(g, mem, ram_fc_config_w(), data);
return 0;
}
void ga10b_ramfc_capture_ram_dump(struct gk20a *g, struct nvgpu_channel *ch,
struct nvgpu_channel_dump_info *info)
{
struct nvgpu_mem *mem = &ch->inst_block;
info->inst.pb_top_level_get = nvgpu_mem_rd32_pair(g, mem,
ram_fc_pb_top_level_get_w(),
ram_fc_pb_top_level_get_hi_w());
info->inst.pb_put = nvgpu_mem_rd32_pair(g, mem,
ram_fc_pb_put_w(),
ram_fc_pb_put_hi_w());
info->inst.pb_get = nvgpu_mem_rd32_pair(g, mem,
ram_fc_pb_get_w(),
ram_fc_pb_get_hi_w());
info->inst.pb_header = nvgpu_mem_rd32(g, mem,
ram_fc_pb_header_w());
info->inst.pb_count = nvgpu_mem_rd32(g, mem,
ram_fc_pb_count_w());
info->inst.sem_addr = nvgpu_mem_rd32_pair(g, mem,
ram_fc_sem_addr_lo_w(),
ram_fc_sem_addr_hi_w());
info->inst.sem_payload = nvgpu_mem_rd32_pair(g, mem,
ram_fc_sem_payload_lo_w(),
ram_fc_sem_payload_hi_w());
info->inst.sem_execute = nvgpu_mem_rd32(g, mem,
ram_fc_sem_execute_w());
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2020, 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_RAMIN_GA10B_H
#define NVGPU_RAMIN_GA10B_H
#include <nvgpu/types.h>
struct gk20a;
struct nvgpu_mem;
void ga10b_ramin_init_pdb(struct gk20a *g, struct nvgpu_mem *inst_block,
u64 pdb_addr, struct nvgpu_mem *pdb_mem);
#endif /* NVGPU_RAMIN_GA10B_H */

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2020, 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/nvgpu_mem.h>
#include <nvgpu/io.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/channel.h>
#include "hal/fifo/ramin_ga10b.h"
#include <nvgpu/hw/ga10b/hw_ram_ga10b.h>
void ga10b_ramin_init_pdb(struct gk20a *g, struct nvgpu_mem *inst_block,
u64 pdb_addr, struct nvgpu_mem *pdb_mem)
{
u32 pdb_addr_lo = u64_lo32(pdb_addr >> ram_in_base_shift_v());
u32 pdb_addr_hi = u64_hi32(pdb_addr);
nvgpu_log_info(g, "pde pa=0x%llx", pdb_addr);
nvgpu_mem_wr32(g, inst_block, ram_in_page_dir_base_lo_w(),
nvgpu_aperture_mask(g, pdb_mem,
ram_in_page_dir_base_target_sys_mem_ncoh_f(),
ram_in_page_dir_base_target_sys_mem_coh_f(),
ram_in_page_dir_base_target_vid_mem_f()) |
ram_in_page_dir_base_vol_true_f() |
ram_in_big_page_size_64kb_f() |
ram_in_page_dir_base_lo_f(pdb_addr_lo) |
ram_in_use_ver2_pt_format_true_f());
nvgpu_mem_wr32(g, inst_block, ram_in_page_dir_base_hi_w(),
ram_in_page_dir_base_hi_f(pdb_addr_hi));
}

View File

@@ -0,0 +1,35 @@
/*
* GA100 runlist
*
* Copyright (c) 2020, 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_RUNLIST_FIFO_GA100_H
#define NVGPU_RUNLIST_FIFO_GA100_H
#include <nvgpu/types.h>
struct gk20a;
u32 ga100_runlist_count_max(struct gk20a *g);
void ga100_runlist_hw_submit(struct gk20a *g, u32 runlist_id,
u32 count, u32 buffer_index);
#endif /* NVGPU_RUNLIST_FIFO_GA100_H */

View File

@@ -0,0 +1,71 @@
/*
* GA100 Runlist
*
* Copyright (c) 2020-2021, 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/soc.h>
#include <nvgpu/fifo.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/engines.h>
#include <nvgpu/runlist.h>
#include <nvgpu/hw/ga100/hw_runlist_ga100.h>
#include "fifo_utils_ga10b.h"
#include "runlist_fifo_ga100.h"
u32 ga100_runlist_count_max(struct gk20a *g)
{
return nvgpu_get_litter_value(g, GPU_LIT_MAX_RUNLISTS_SUPPORTED);
}
void ga100_runlist_hw_submit(struct gk20a *g, u32 runlist_id,
u32 count, u32 buffer_index)
{
struct nvgpu_runlist *runlist = NULL;
u64 runlist_iova;
u32 runlist_iova_lo, runlist_iova_hi;
runlist = g->fifo.runlists[runlist_id];
runlist_iova = nvgpu_mem_get_addr(g, &runlist->mem[buffer_index]);
runlist_iova_lo = u64_lo32(runlist_iova) >>
runlist_submit_base_lo_ptr_align_shift_v();
runlist_iova_hi = u64_hi32(runlist_iova);
if (count != 0U) {
nvgpu_runlist_writel(g, runlist, runlist_submit_base_lo_r(),
runlist_submit_base_lo_ptr_lo_f(runlist_iova_lo) |
nvgpu_aperture_mask(g, &runlist->mem[buffer_index],
runlist_submit_base_lo_target_sys_mem_noncoherent_f(),
runlist_submit_base_lo_target_sys_mem_coherent_f(),
runlist_submit_base_lo_target_vid_mem_f()));
nvgpu_runlist_writel(g, runlist, runlist_submit_base_hi_r(),
runlist_submit_base_hi_ptr_hi_f(runlist_iova_hi));
}
/* TODO offset in runlist support */
nvgpu_runlist_writel(g, runlist, runlist_submit_r(),
runlist_submit_offset_f(0U) |
runlist_submit_length_f(count));
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright (c) 2020-2021, 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/channel.h>
#include <nvgpu/runlist.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/fifo.h>
#include <nvgpu/engine_status.h>
#include <nvgpu/engines.h>
#include <nvgpu/device.h>
#include <nvgpu/gr/gr_falcon.h>
#include "fifo_utils_ga10b.h"
#include "runlist_fifo_ga10b.h"
#include <nvgpu/hw/ga10b/hw_runlist_ga10b.h>
#ifdef CONFIG_NVGPU_CHANNEL_TSG_SCHEDULING
#define FECS_MAILBOX_0_ACK_RESTORE 0x4U
/* trigger host preempt of GR pending load ctx if that ctx is not for ch */
int ga10b_fifo_reschedule_preempt_next(struct nvgpu_channel *ch,
bool wait_preempt)
{
struct gk20a *g = ch->g;
struct nvgpu_runlist *runlist = ch->runlist;
u32 fecsstat0 = 0, fecsstat1 = 0;
u32 preempt_id;
u32 preempt_type = 0;
u32 i = 0U, eng_bitmask = 0U;
const struct nvgpu_device *dev;
struct nvgpu_engine_status_info engine_status;
/* TODO: [Jira NVGPU-5039] Re-arch function */
for (i = 0U; i < nvgpu_device_count(g, NVGPU_DEVTYPE_GRAPHICS); i++) {
dev = nvgpu_device_get(g, NVGPU_DEVTYPE_GRAPHICS, i);
nvgpu_assert(dev != NULL);
eng_bitmask |= BIT32(dev->engine_id);
}
if ((runlist->eng_bitmask & eng_bitmask) == 0U) {
/* Given runlist doesn't serve any GR engines */
return 0;
}
if (wait_preempt) {
u32 val = nvgpu_runlist_readl(g, runlist, runlist_preempt_r());
if ((val & runlist_preempt_runlist_preempt_pending_true_f()) ||
(val & runlist_preempt_tsg_preempt_pending_true_f()) !=
0U) {
/* Current runlist/tsg preemption is pending */
return 0;
}
}
fecsstat0 = g->ops.gr.falcon.read_fecs_ctxsw_mailbox(g,
NVGPU_GR_FALCON_FECS_CTXSW_MAILBOX0);
g->ops.engine_status.read_engine_status_info(g, nvgpu_safe_sub_u32(
nvgpu_ffs(runlist->eng_bitmask & eng_bitmask), 1U),
&engine_status);
if (nvgpu_engine_status_is_ctxsw_switch(&engine_status)) {
nvgpu_engine_status_get_next_ctx_id_type(&engine_status,
&preempt_id, &preempt_type);
} else {
/* GR engine is in CTXSW state */
return 0;
}
if ((preempt_id == ch->tsgid) &&
(preempt_type != ENGINE_STATUS_CTX_ID_TYPE_TSGID)) {
/* Next ctx is not TSG type */
return 0;
}
fecsstat1 = g->ops.gr.falcon.read_fecs_ctxsw_mailbox(g,
NVGPU_GR_FALCON_FECS_CTXSW_MAILBOX0);
if (fecsstat0 != FECS_MAILBOX_0_ACK_RESTORE ||
fecsstat1 != FECS_MAILBOX_0_ACK_RESTORE) {
/* preempt useless if FECS acked save and started restore */
return 0;
}
g->ops.fifo.preempt_trigger(g, preempt_id, preempt_type != 0U);
#ifdef TRACEPOINTS_ENABLED
trace_gk20a_reschedule_preempt_next(ch->chid, fecsstat0,
engine_status.reg_data, fecsstat1,
g->ops.gr.falcon.read_fecs_ctxsw_mailbox(g,
NVGPU_GR_FALCON_FECS_CTXSW_MAILBOX0),
nvgpu_runlist_readl(g, runlist, runlist_preempt_r());
#endif
if (wait_preempt) {
if (g->ops.fifo.is_preempt_pending(g, preempt_id,
preempt_type, false) != 0) {
nvgpu_err(g, "fifo preempt timed out");
/*
* This function does not care if preempt
* times out since it is here only to improve
* latency. If a timeout happens, it will be
* handled by other fifo handling code.
*/
}
}
#ifdef TRACEPOINTS_ENABLED
trace_gk20a_reschedule_preempted_next(ch->chid);
#endif
return 0;
}
#endif

View File

@@ -0,0 +1,44 @@
/*
* GA10B runlist
*
* Copyright (c) 2020, 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_RUNLIST_FIFO_GA10B_H
#define NVGPU_RUNLIST_FIFO_GA10B_H
#include <nvgpu/types.h>
struct gk20a;
u32 ga10b_runlist_count_max(struct gk20a *g);
u32 ga10b_runlist_length_max(struct gk20a *g);
void ga10b_runlist_hw_submit(struct gk20a *g, u32 runlist_id,
u32 count, u32 buffer_index);
int ga10b_runlist_wait_pending(struct gk20a *g, u32 runlist_id);
void ga10b_runlist_write_state(struct gk20a *g, u32 runlists_mask,
u32 runlist_state);
#ifdef CONFIG_NVGPU_CHANNEL_TSG_SCHEDULING
int ga10b_fifo_reschedule_preempt_next(struct nvgpu_channel *ch,
bool wait_preempt);
#endif
#endif /* NVGPU_RUNLIST_FIFO_GA10B_H */

View File

@@ -0,0 +1,135 @@
/*
* GA10B Runlist
*
* Copyright (c) 2020-2021, 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/log.h>
#include <nvgpu/soc.h>
#include <nvgpu/fifo.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/power_features/cg.h>
#include <nvgpu/static_analysis.h>
#include <nvgpu/mc.h>
#include <nvgpu/engines.h>
#include <nvgpu/runlist.h>
#include <nvgpu/hw/ga10b/hw_runlist_ga10b.h>
#include "fifo_utils_ga10b.h"
#include "runlist_fifo_ga10b.h"
u32 ga10b_runlist_count_max(struct gk20a *g)
{
/* TODO Needs to be read from litter values */
return 4U;
}
u32 ga10b_runlist_length_max(struct gk20a *g)
{
return runlist_submit_length_max_v();
}
void ga10b_runlist_hw_submit(struct gk20a *g, u32 runlist_id,
u32 count, u32 buffer_index)
{
struct nvgpu_runlist *runlist = NULL;
u64 runlist_iova;
u32 runlist_iova_lo, runlist_iova_hi;
runlist = g->fifo.runlists[runlist_id];
runlist_iova = nvgpu_mem_get_addr(g, &runlist->mem[buffer_index]);
runlist_iova_lo = u64_lo32(runlist_iova) >>
runlist_submit_base_lo_ptr_align_shift_v();
runlist_iova_hi = u64_hi32(runlist_iova);
if (count != 0U) {
nvgpu_runlist_writel(g, runlist, runlist_submit_base_lo_r(),
runlist_submit_base_lo_ptr_lo_f(runlist_iova_lo) |
nvgpu_aperture_mask(g, &runlist->mem[buffer_index],
runlist_submit_base_lo_target_sys_mem_noncoherent_f(),
runlist_submit_base_lo_target_sys_mem_coherent_f(),
runlist_submit_base_lo_target_vid_mem_f()));
nvgpu_runlist_writel(g, runlist, runlist_submit_base_hi_r(),
runlist_submit_base_hi_ptr_hi_f(runlist_iova_hi));
}
/* TODO offset in runlist support */
nvgpu_runlist_writel(g, runlist, runlist_submit_r(),
runlist_submit_offset_f(0U) |
runlist_submit_length_f(count));
}
int ga10b_runlist_wait_pending(struct gk20a *g, u32 runlist_id)
{
struct nvgpu_timeout timeout;
u32 delay = POLL_DELAY_MIN_US;
int ret;
struct nvgpu_runlist *runlist = NULL;
runlist = g->fifo.runlists[runlist_id];
ret = nvgpu_timeout_init(g, &timeout, nvgpu_get_poll_timeout(g),
NVGPU_TIMER_CPU_TIMER);
if (ret != 0) {
return ret;
}
ret = -ETIMEDOUT;
do {
if ((nvgpu_runlist_readl(g, runlist, runlist_submit_info_r()) &
runlist_submit_info_pending_true_f()) == 0U) {
ret = 0;
break;
}
nvgpu_usleep_range(delay, delay * 2U);
delay = min_t(u32, delay << 1, POLL_DELAY_MAX_US);
} while (nvgpu_timeout_expired(&timeout) == 0);
return ret;
}
void ga10b_runlist_write_state(struct gk20a *g, u32 runlists_mask,
u32 runlist_state)
{
u32 reg_val;
u32 runlist_id = 0U;
struct nvgpu_runlist *runlist = NULL;
if (runlist_state == RUNLIST_DISABLED) {
reg_val = runlist_sched_disable_runlist_disabled_v();
} else {
reg_val = runlist_sched_disable_runlist_enabled_v();
}
while (runlists_mask != 0U) {
if ((runlists_mask & BIT32(runlist_id)) != 0U) {
runlist = g->fifo.runlists[runlist_id];
nvgpu_runlist_writel(g, runlist,
runlist_sched_disable_r(), reg_val);
}
runlists_mask &= ~BIT32(runlist_id);
runlist_id++;
}
}

Some files were not shown because too many files have changed in this diff Show More