From 01e6fac4d61fdd7fff5433942ec93fc2ea1e4df1 Mon Sep 17 00:00:00 2001 From: Joshua Bakita Date: Wed, 28 Jun 2023 18:24:25 -0400 Subject: Include nvgpu headers These are needed to build on NVIDIA's Jetson boards for the time being. Only a couple structs are required, so it should be fairly easy to remove this dependency at some point in the future. --- include/boardobj/boardobj.c | 102 + include/boardobj/boardobj.h | 104 + include/boardobj/boardobjgrp.c | 1046 +++ include/boardobj/boardobjgrp.h | 441 + include/boardobj/boardobjgrp_e255.c | 91 + include/boardobj/boardobjgrp_e255.h | 51 + include/boardobj/boardobjgrp_e32.c | 89 + include/boardobj/boardobjgrp_e32.h | 66 + include/boardobj/boardobjgrpmask.c | 411 + include/boardobj/boardobjgrpmask.h | 119 + include/clk/clk.c | 942 ++ include/clk/clk.h | 144 + include/clk/clk_arb.c | 1087 +++ include/clk/clk_domain.c | 1666 ++++ include/clk/clk_domain.h | 157 + include/clk/clk_fll.c | 495 ++ include/clk/clk_fll.h | 81 + include/clk/clk_freq_controller.c | 462 + include/clk/clk_freq_controller.h | 84 + include/clk/clk_mclk.h | 60 + include/clk/clk_prog.c | 1152 +++ include/clk/clk_prog.h | 100 + include/clk/clk_vf_point.c | 433 + include/clk/clk_vf_point.h | 83 + include/clk/clk_vin.c | 573 ++ include/clk/clk_vin.h | 79 + include/ctrl/ctrlboardobj.h | 89 + include/ctrl/ctrlclk.h | 212 + include/ctrl/ctrlclkavfs.h | 112 + include/ctrl/ctrlperf.h | 103 + include/ctrl/ctrlpmgr.h | 98 + include/ctrl/ctrltherm.h | 33 + include/ctrl/ctrlvolt.h | 143 + include/gk20a/ce2_gk20a.c | 576 ++ include/gk20a/ce2_gk20a.h | 156 + include/gk20a/clk_gk20a.h | 134 + include/gk20a/css_gr_gk20a.c | 636 ++ include/gk20a/css_gr_gk20a.h | 151 + include/gk20a/dbg_gpu_gk20a.c | 388 + include/gk20a/dbg_gpu_gk20a.h | 147 + include/gk20a/fecs_trace_gk20a.c | 744 ++ include/gk20a/fecs_trace_gk20a.h | 45 + include/gk20a/fence_gk20a.c | 319 + include/gk20a/fence_gk20a.h | 100 + include/gk20a/fifo_gk20a.c | 4649 ++++++++++ include/gk20a/fifo_gk20a.h | 471 + include/gk20a/flcn_gk20a.c | 759 ++ include/gk20a/flcn_gk20a.h | 29 + include/gk20a/gk20a.c | 590 ++ include/gk20a/gk20a.h | 33 + include/gk20a/gr_ctx_gk20a.c | 486 ++ include/gk20a/gr_ctx_gk20a.h | 206 + include/gk20a/gr_ctx_gk20a_sim.c | 356 + include/gk20a/gr_gk20a.c | 8998 ++++++++++++++++++++ include/gk20a/gr_gk20a.h | 851 ++ include/gk20a/gr_pri_gk20a.h | 261 + include/gk20a/hw_bus_gk20a.h | 171 + include/gk20a/hw_ccsr_gk20a.h | 163 + include/gk20a/hw_ce2_gk20a.h | 87 + include/gk20a/hw_ctxsw_prog_gk20a.h | 447 + include/gk20a/hw_falcon_gk20a.h | 559 ++ include/gk20a/hw_fb_gk20a.h | 263 + include/gk20a/hw_fifo_gk20a.h | 619 ++ include/gk20a/hw_flush_gk20a.h | 187 + include/gk20a/hw_gmmu_gk20a.h | 283 + include/gk20a/hw_gr_gk20a.h | 3807 +++++++++ include/gk20a/hw_ltc_gk20a.h | 455 + include/gk20a/hw_mc_gk20a.h | 291 + include/gk20a/hw_pbdma_gk20a.h | 575 ++ include/gk20a/hw_perf_gk20a.h | 211 + include/gk20a/hw_pram_gk20a.h | 63 + include/gk20a/hw_pri_ringmaster_gk20a.h | 159 + include/gk20a/hw_pri_ringstation_fbp_gk20a.h | 231 + include/gk20a/hw_pri_ringstation_gpc_gk20a.h | 79 + include/gk20a/hw_pri_ringstation_sys_gk20a.h | 91 + include/gk20a/hw_proj_gk20a.h | 167 + include/gk20a/hw_pwr_gk20a.h | 823 ++ include/gk20a/hw_ram_gk20a.h | 443 + include/gk20a/hw_therm_gk20a.h | 367 + include/gk20a/hw_timer_gk20a.h | 127 + include/gk20a/hw_top_gk20a.h | 211 + include/gk20a/hw_trim_gk20a.h | 315 + include/gk20a/mm_gk20a.c | 654 ++ include/gk20a/mm_gk20a.h | 155 + include/gk20a/pmu_gk20a.c | 879 ++ include/gk20a/pmu_gk20a.h | 80 + include/gk20a/regops_gk20a.c | 472 + include/gk20a/regops_gk20a.h | 90 + include/lpwr/lpwr.c | 448 + include/lpwr/lpwr.h | 101 + include/lpwr/rppg.c | 160 + include/lpwr/rppg.h | 26 + include/nvgpu/acr/acr_flcnbl.h | 144 + include/nvgpu/acr/acr_lsfm.h | 328 + include/nvgpu/acr/acr_objflcn.h | 91 + include/nvgpu/acr/acr_objlsfm.h | 97 + include/nvgpu/acr/nvgpu_acr.h | 188 + include/nvgpu/allocator.h | 331 + include/nvgpu/as.h | 54 + include/nvgpu/atomic.h | 130 + include/nvgpu/barrier.h | 61 + include/nvgpu/bios.h | 1123 +++ include/nvgpu/bitops.h | 44 + include/nvgpu/bsearch.h | 31 + include/nvgpu/bug.h | 33 + include/nvgpu/channel.h | 478 ++ include/nvgpu/channel_sync.h | 113 + include/nvgpu/circ_buf.h | 31 + include/nvgpu/clk.h | 42 + include/nvgpu/clk_arb.h | 378 + include/nvgpu/comptags.h | 104 + include/nvgpu/cond.h | 106 + include/nvgpu/ctxsw_trace.h | 94 + include/nvgpu/debug.h | 63 + include/nvgpu/defaults.h | 33 + include/nvgpu/dma.h | 361 + include/nvgpu/dt.h | 28 + include/nvgpu/ecc.h | 162 + include/nvgpu/enabled.h | 216 + include/nvgpu/errno.h | 41 + include/nvgpu/error_notifier.h | 49 + include/nvgpu/falcon.h | 335 + include/nvgpu/fecs_trace.h | 60 + include/nvgpu/firmware.h | 74 + include/nvgpu/flcnif_cmn.h | 121 + include/nvgpu/fuse.h | 38 + include/nvgpu/gk20a.h | 1803 ++++ include/nvgpu/gmmu.h | 369 + include/nvgpu/hal_init.h | 33 + include/nvgpu/hashtable.h | 29 + include/nvgpu/hw/gk20a/hw_bus_gk20a.h | 171 + include/nvgpu/hw/gk20a/hw_ccsr_gk20a.h | 163 + include/nvgpu/hw/gk20a/hw_ce2_gk20a.h | 87 + include/nvgpu/hw/gk20a/hw_ctxsw_prog_gk20a.h | 447 + include/nvgpu/hw/gk20a/hw_falcon_gk20a.h | 559 ++ include/nvgpu/hw/gk20a/hw_fb_gk20a.h | 263 + include/nvgpu/hw/gk20a/hw_fifo_gk20a.h | 619 ++ include/nvgpu/hw/gk20a/hw_flush_gk20a.h | 187 + include/nvgpu/hw/gk20a/hw_gmmu_gk20a.h | 283 + include/nvgpu/hw/gk20a/hw_gr_gk20a.h | 3807 +++++++++ include/nvgpu/hw/gk20a/hw_ltc_gk20a.h | 455 + include/nvgpu/hw/gk20a/hw_mc_gk20a.h | 291 + include/nvgpu/hw/gk20a/hw_pbdma_gk20a.h | 575 ++ include/nvgpu/hw/gk20a/hw_perf_gk20a.h | 211 + include/nvgpu/hw/gk20a/hw_pram_gk20a.h | 63 + include/nvgpu/hw/gk20a/hw_pri_ringmaster_gk20a.h | 159 + .../nvgpu/hw/gk20a/hw_pri_ringstation_fbp_gk20a.h | 231 + .../nvgpu/hw/gk20a/hw_pri_ringstation_gpc_gk20a.h | 79 + .../nvgpu/hw/gk20a/hw_pri_ringstation_sys_gk20a.h | 91 + include/nvgpu/hw/gk20a/hw_proj_gk20a.h | 167 + include/nvgpu/hw/gk20a/hw_pwr_gk20a.h | 827 ++ include/nvgpu/hw/gk20a/hw_ram_gk20a.h | 443 + include/nvgpu/hw/gk20a/hw_therm_gk20a.h | 367 + include/nvgpu/hw/gk20a/hw_timer_gk20a.h | 127 + include/nvgpu/hw/gk20a/hw_top_gk20a.h | 211 + include/nvgpu/hw/gk20a/hw_trim_gk20a.h | 315 + include/nvgpu/hw/gm20b/hw_bus_gm20b.h | 223 + include/nvgpu/hw/gm20b/hw_ccsr_gm20b.h | 163 + include/nvgpu/hw/gm20b/hw_ce2_gm20b.h | 87 + include/nvgpu/hw/gm20b/hw_ctxsw_prog_gm20b.h | 475 ++ include/nvgpu/hw/gm20b/hw_falcon_gm20b.h | 599 ++ include/nvgpu/hw/gm20b/hw_fb_gm20b.h | 339 + include/nvgpu/hw/gm20b/hw_fifo_gm20b.h | 571 ++ include/nvgpu/hw/gm20b/hw_flush_gm20b.h | 187 + include/nvgpu/hw/gm20b/hw_fuse_gm20b.h | 147 + include/nvgpu/hw/gm20b/hw_gmmu_gm20b.h | 283 + include/nvgpu/hw/gm20b/hw_gr_gm20b.h | 3927 +++++++++ include/nvgpu/hw/gm20b/hw_ltc_gm20b.h | 527 ++ include/nvgpu/hw/gm20b/hw_mc_gm20b.h | 287 + include/nvgpu/hw/gm20b/hw_pbdma_gm20b.h | 579 ++ include/nvgpu/hw/gm20b/hw_perf_gm20b.h | 219 + include/nvgpu/hw/gm20b/hw_pram_gm20b.h | 63 + include/nvgpu/hw/gm20b/hw_pri_ringmaster_gm20b.h | 167 + .../nvgpu/hw/gm20b/hw_pri_ringstation_gpc_gm20b.h | 79 + .../nvgpu/hw/gm20b/hw_pri_ringstation_sys_gm20b.h | 91 + include/nvgpu/hw/gm20b/hw_proj_gm20b.h | 171 + include/nvgpu/hw/gm20b/hw_pwr_gm20b.h | 879 ++ include/nvgpu/hw/gm20b/hw_ram_gm20b.h | 459 + include/nvgpu/hw/gm20b/hw_therm_gm20b.h | 355 + include/nvgpu/hw/gm20b/hw_timer_gm20b.h | 127 + include/nvgpu/hw/gm20b/hw_top_gm20b.h | 235 + include/nvgpu/hw/gm20b/hw_trim_gm20b.h | 503 ++ include/nvgpu/hw/gp106/hw_bus_gp106.h | 223 + include/nvgpu/hw/gp106/hw_ccsr_gp106.h | 163 + include/nvgpu/hw/gp106/hw_ce_gp106.h | 87 + include/nvgpu/hw/gp106/hw_ctxsw_prog_gp106.h | 295 + include/nvgpu/hw/gp106/hw_falcon_gp106.h | 603 ++ include/nvgpu/hw/gp106/hw_fb_gp106.h | 563 ++ include/nvgpu/hw/gp106/hw_fbpa_gp106.h | 67 + include/nvgpu/hw/gp106/hw_fifo_gp106.h | 695 ++ include/nvgpu/hw/gp106/hw_flush_gp106.h | 187 + include/nvgpu/hw/gp106/hw_fuse_gp106.h | 275 + include/nvgpu/hw/gp106/hw_gc6_gp106.h | 62 + include/nvgpu/hw/gp106/hw_gmmu_gp106.h | 331 + include/nvgpu/hw/gp106/hw_gr_gp106.h | 4163 +++++++++ include/nvgpu/hw/gp106/hw_ltc_gp106.h | 559 ++ include/nvgpu/hw/gp106/hw_mc_gp106.h | 251 + include/nvgpu/hw/gp106/hw_pbdma_gp106.h | 535 ++ include/nvgpu/hw/gp106/hw_perf_gp106.h | 219 + include/nvgpu/hw/gp106/hw_pram_gp106.h | 63 + include/nvgpu/hw/gp106/hw_pri_ringmaster_gp106.h | 151 + .../nvgpu/hw/gp106/hw_pri_ringstation_gpc_gp106.h | 79 + .../nvgpu/hw/gp106/hw_pri_ringstation_sys_gp106.h | 91 + include/nvgpu/hw/gp106/hw_proj_gp106.h | 179 + include/nvgpu/hw/gp106/hw_psec_gp106.h | 615 ++ include/nvgpu/hw/gp106/hw_pwr_gp106.h | 895 ++ include/nvgpu/hw/gp106/hw_ram_gp106.h | 507 ++ include/nvgpu/hw/gp106/hw_therm_gp106.h | 183 + include/nvgpu/hw/gp106/hw_timer_gp106.h | 115 + include/nvgpu/hw/gp106/hw_top_gp106.h | 255 + include/nvgpu/hw/gp106/hw_trim_gp106.h | 195 + include/nvgpu/hw/gp106/hw_xp_gp106.h | 143 + include/nvgpu/hw/gp106/hw_xve_gp106.h | 207 + include/nvgpu/hw/gp10b/hw_bus_gp10b.h | 223 + include/nvgpu/hw/gp10b/hw_ccsr_gp10b.h | 163 + include/nvgpu/hw/gp10b/hw_ce_gp10b.h | 87 + include/nvgpu/hw/gp10b/hw_ctxsw_prog_gp10b.h | 491 ++ include/nvgpu/hw/gp10b/hw_falcon_gp10b.h | 603 ++ include/nvgpu/hw/gp10b/hw_fb_gp10b.h | 463 + include/nvgpu/hw/gp10b/hw_fifo_gp10b.h | 699 ++ include/nvgpu/hw/gp10b/hw_flush_gp10b.h | 187 + include/nvgpu/hw/gp10b/hw_fuse_gp10b.h | 155 + include/nvgpu/hw/gp10b/hw_gmmu_gp10b.h | 331 + include/nvgpu/hw/gp10b/hw_gr_gp10b.h | 4415 ++++++++++ include/nvgpu/hw/gp10b/hw_ltc_gp10b.h | 587 ++ include/nvgpu/hw/gp10b/hw_mc_gp10b.h | 255 + include/nvgpu/hw/gp10b/hw_pbdma_gp10b.h | 615 ++ include/nvgpu/hw/gp10b/hw_perf_gp10b.h | 219 + include/nvgpu/hw/gp10b/hw_pram_gp10b.h | 63 + include/nvgpu/hw/gp10b/hw_pri_ringmaster_gp10b.h | 167 + .../nvgpu/hw/gp10b/hw_pri_ringstation_gpc_gp10b.h | 87 + .../nvgpu/hw/gp10b/hw_pri_ringstation_sys_gp10b.h | 99 + include/nvgpu/hw/gp10b/hw_proj_gp10b.h | 179 + include/nvgpu/hw/gp10b/hw_pwr_gp10b.h | 883 ++ include/nvgpu/hw/gp10b/hw_ram_gp10b.h | 519 ++ include/nvgpu/hw/gp10b/hw_therm_gp10b.h | 415 + include/nvgpu/hw/gp10b/hw_timer_gp10b.h | 127 + include/nvgpu/hw/gp10b/hw_top_gp10b.h | 231 + include/nvgpu/hw/gv100/hw_bus_gv100.h | 227 + include/nvgpu/hw/gv100/hw_ccsr_gv100.h | 187 + include/nvgpu/hw/gv100/hw_ce_gv100.h | 107 + include/nvgpu/hw/gv100/hw_ctxsw_prog_gv100.h | 459 + include/nvgpu/hw/gv100/hw_falcon_gv100.h | 603 ++ include/nvgpu/hw/gv100/hw_fb_gv100.h | 1923 +++++ include/nvgpu/hw/gv100/hw_fifo_gv100.h | 531 ++ include/nvgpu/hw/gv100/hw_flush_gv100.h | 187 + include/nvgpu/hw/gv100/hw_fuse_gv100.h | 147 + include/nvgpu/hw/gv100/hw_gmmu_gv100.h | 355 + include/nvgpu/hw/gv100/hw_gr_gv100.h | 4119 +++++++++ include/nvgpu/hw/gv100/hw_ioctrl_gv100.h | 331 + include/nvgpu/hw/gv100/hw_ioctrlmif_gv100.h | 331 + include/nvgpu/hw/gv100/hw_ltc_gv100.h | 631 ++ include/nvgpu/hw/gv100/hw_mc_gv100.h | 259 + include/nvgpu/hw/gv100/hw_minion_gv100.h | 943 ++ include/nvgpu/hw/gv100/hw_nvl_gv100.h | 1571 ++++ .../nvgpu/hw/gv100/hw_nvlinkip_discovery_gv100.h | 311 + include/nvgpu/hw/gv100/hw_nvlipt_gv100.h | 279 + include/nvgpu/hw/gv100/hw_nvtlc_gv100.h | 95 + include/nvgpu/hw/gv100/hw_pbdma_gv100.h | 651 ++ include/nvgpu/hw/gv100/hw_perf_gv100.h | 263 + include/nvgpu/hw/gv100/hw_pgsp_gv100.h | 643 ++ include/nvgpu/hw/gv100/hw_pram_gv100.h | 63 + include/nvgpu/hw/gv100/hw_pri_ringmaster_gv100.h | 167 + .../nvgpu/hw/gv100/hw_pri_ringstation_gpc_gv100.h | 79 + .../nvgpu/hw/gv100/hw_pri_ringstation_sys_gv100.h | 91 + include/nvgpu/hw/gv100/hw_proj_gv100.h | 199 + include/nvgpu/hw/gv100/hw_pwr_gv100.h | 983 +++ include/nvgpu/hw/gv100/hw_ram_gv100.h | 791 ++ include/nvgpu/hw/gv100/hw_therm_gv100.h | 299 + include/nvgpu/hw/gv100/hw_timer_gv100.h | 115 + include/nvgpu/hw/gv100/hw_top_gv100.h | 343 + include/nvgpu/hw/gv100/hw_trim_gv100.h | 247 + include/nvgpu/hw/gv100/hw_usermode_gv100.h | 95 + include/nvgpu/hw/gv100/hw_xp_gv100.h | 143 + include/nvgpu/hw/gv100/hw_xve_gv100.h | 207 + include/nvgpu/hw/gv11b/hw_bus_gv11b.h | 223 + include/nvgpu/hw/gv11b/hw_ccsr_gv11b.h | 187 + include/nvgpu/hw/gv11b/hw_ce_gv11b.h | 115 + include/nvgpu/hw/gv11b/hw_ctxsw_prog_gv11b.h | 463 + include/nvgpu/hw/gv11b/hw_falcon_gv11b.h | 603 ++ include/nvgpu/hw/gv11b/hw_fb_gv11b.h | 1867 ++++ include/nvgpu/hw/gv11b/hw_fifo_gv11b.h | 667 ++ include/nvgpu/hw/gv11b/hw_flush_gv11b.h | 187 + include/nvgpu/hw/gv11b/hw_fuse_gv11b.h | 155 + include/nvgpu/hw/gv11b/hw_gmmu_gv11b.h | 571 ++ include/nvgpu/hw/gv11b/hw_gr_gv11b.h | 5699 +++++++++++++ include/nvgpu/hw/gv11b/hw_ltc_gv11b.h | 815 ++ include/nvgpu/hw/gv11b/hw_mc_gv11b.h | 231 + include/nvgpu/hw/gv11b/hw_pbdma_gv11b.h | 651 ++ include/nvgpu/hw/gv11b/hw_perf_gv11b.h | 263 + include/nvgpu/hw/gv11b/hw_pram_gv11b.h | 63 + include/nvgpu/hw/gv11b/hw_pri_ringmaster_gv11b.h | 167 + .../nvgpu/hw/gv11b/hw_pri_ringstation_gpc_gv11b.h | 79 + .../nvgpu/hw/gv11b/hw_pri_ringstation_sys_gv11b.h | 91 + include/nvgpu/hw/gv11b/hw_proj_gv11b.h | 191 + include/nvgpu/hw/gv11b/hw_pwr_gv11b.h | 1219 +++ include/nvgpu/hw/gv11b/hw_ram_gv11b.h | 791 ++ include/nvgpu/hw/gv11b/hw_therm_gv11b.h | 487 ++ include/nvgpu/hw/gv11b/hw_timer_gv11b.h | 127 + include/nvgpu/hw/gv11b/hw_top_gv11b.h | 235 + include/nvgpu/hw/gv11b/hw_usermode_gv11b.h | 95 + include/nvgpu/hw_sim.h | 2153 +++++ include/nvgpu/hw_sim_pci.h | 2169 +++++ include/nvgpu/io.h | 49 + include/nvgpu/io_usermode.h | 27 + include/nvgpu/kmem.h | 285 + include/nvgpu/kref.h | 87 + include/nvgpu/linux/atomic.h | 149 + include/nvgpu/linux/barrier.h | 37 + include/nvgpu/linux/cond.h | 81 + include/nvgpu/linux/dma.h | 38 + include/nvgpu/linux/kmem.h | 47 + include/nvgpu/linux/lock.h | 81 + include/nvgpu/linux/nvgpu_mem.h | 89 + include/nvgpu/linux/nvlink.h | 31 + include/nvgpu/linux/os_fence_android.h | 48 + include/nvgpu/linux/rwsem.h | 26 + include/nvgpu/linux/sim.h | 38 + include/nvgpu/linux/sim_pci.h | 26 + include/nvgpu/linux/thread.h | 29 + include/nvgpu/linux/vm.h | 92 + include/nvgpu/list.h | 104 + include/nvgpu/lock.h | 75 + include/nvgpu/log.h | 183 + include/nvgpu/log2.h | 31 + include/nvgpu/ltc.h | 35 + include/nvgpu/mc.h | 35 + include/nvgpu/mm.h | 223 + include/nvgpu/nvgpu_common.h | 36 + include/nvgpu/nvgpu_mem.h | 359 + include/nvgpu/nvhost.h | 112 + include/nvgpu/nvlink.h | 237 + include/nvgpu/os_fence.h | 138 + include/nvgpu/os_sched.h | 51 + include/nvgpu/page_allocator.h | 185 + include/nvgpu/pci.h | 39 + include/nvgpu/pmu.h | 527 ++ include/nvgpu/pmuif/gpmu_super_surf_if.h | 77 + include/nvgpu/pmuif/gpmuif_acr.h | 159 + include/nvgpu/pmuif/gpmuif_ap.h | 256 + include/nvgpu/pmuif/gpmuif_cmn.h | 142 + include/nvgpu/pmuif/gpmuif_perfmon.h | 241 + include/nvgpu/pmuif/gpmuif_pg.h | 412 + include/nvgpu/pmuif/gpmuif_pg_rppg.h | 110 + include/nvgpu/pmuif/gpmuif_pmu.h | 193 + include/nvgpu/pmuif/gpmuifbios.h | 50 + include/nvgpu/pmuif/gpmuifboardobj.h | 234 + include/nvgpu/pmuif/gpmuifclk.h | 573 ++ include/nvgpu/pmuif/gpmuifperf.h | 154 + include/nvgpu/pmuif/gpmuifperfvfe.h | 206 + include/nvgpu/pmuif/gpmuifpmgr.h | 443 + include/nvgpu/pmuif/gpmuifseq.h | 82 + include/nvgpu/pmuif/gpmuiftherm.h | 102 + include/nvgpu/pmuif/gpmuifthermsensor.h | 105 + include/nvgpu/pmuif/gpmuifvolt.h | 402 + include/nvgpu/pmuif/nvgpu_gpmu_cmdif.h | 143 + include/nvgpu/posix/atomic.h | 191 + include/nvgpu/posix/barrier.h | 44 + include/nvgpu/posix/bitops.h | 95 + include/nvgpu/posix/bug.h | 56 + include/nvgpu/posix/circ_buf.h | 44 + include/nvgpu/posix/cond.h | 59 + include/nvgpu/posix/io.h | 114 + include/nvgpu/posix/kmem.h | 36 + include/nvgpu/posix/lock.h | 69 + include/nvgpu/posix/log2.h | 37 + include/nvgpu/posix/nvgpu_mem.h | 32 + include/nvgpu/posix/nvlink.h | 24 + include/nvgpu/posix/pci.h | 28 + include/nvgpu/posix/probe.h | 31 + include/nvgpu/posix/rwsem.h | 35 + include/nvgpu/posix/sizes.h | 38 + include/nvgpu/posix/sort.h | 35 + include/nvgpu/posix/thread.h | 51 + include/nvgpu/posix/types.h | 221 + include/nvgpu/posix/vm.h | 41 + include/nvgpu/power_features/cg.h | 57 + include/nvgpu/power_features/pg.h | 36 + include/nvgpu/power_features/power_features.h | 34 + include/nvgpu/pramin.h | 39 + include/nvgpu/ptimer.h | 55 + include/nvgpu/rbtree.h | 130 + include/nvgpu/rwsem.h | 48 + include/nvgpu/sched.h | 42 + include/nvgpu/sec2.h | 97 + include/nvgpu/sec2if/sec2_cmd_if.h | 50 + include/nvgpu/sec2if/sec2_if_acr.h | 96 + include/nvgpu/sec2if/sec2_if_cmn.h | 73 + include/nvgpu/sec2if/sec2_if_sec2.h | 75 + include/nvgpu/semaphore.h | 206 + include/nvgpu/sim.h | 58 + include/nvgpu/sizes.h | 33 + include/nvgpu/soc.h | 37 + include/nvgpu/sort.h | 33 + include/nvgpu/therm.h | 29 + include/nvgpu/thread.h | 92 + include/nvgpu/timers.h | 116 + include/nvgpu/tsg.h | 132 + include/nvgpu/types.h | 71 + include/nvgpu/unit.h | 41 + include/nvgpu/utils.h | 58 + include/nvgpu/vgpu/tegra_vgpu.h | 817 ++ include/nvgpu/vgpu/vgpu.h | 110 + include/nvgpu/vgpu/vgpu_ivc.h | 45 + include/nvgpu/vgpu/vgpu_ivm.h | 37 + include/nvgpu/vgpu/vm.h | 31 + include/nvgpu/vidmem.h | 148 + include/nvgpu/vm.h | 330 + include/nvgpu/vm_area.h | 75 + include/nvgpu/vpr.h | 30 + include/nvgpu/xve.h | 68 + include/os/linux/cde.c | 1794 ++++ include/os/linux/cde.h | 326 + include/os/linux/cde_gm20b.c | 59 + include/os/linux/cde_gm20b.h | 33 + include/os/linux/cde_gp10b.c | 153 + include/os/linux/cde_gp10b.h | 40 + include/os/linux/channel.h | 102 + include/os/linux/clk.c | 286 + include/os/linux/clk.h | 22 + include/os/linux/comptags.c | 140 + include/os/linux/cond.c | 73 + include/os/linux/ctxsw_trace.c | 792 ++ include/os/linux/ctxsw_trace.h | 39 + include/os/linux/debug.c | 457 + include/os/linux/debug_allocator.c | 69 + include/os/linux/debug_allocator.h | 21 + include/os/linux/debug_bios.c | 60 + include/os/linux/debug_bios.h | 21 + include/os/linux/debug_cde.c | 53 + include/os/linux/debug_cde.h | 21 + include/os/linux/debug_ce.c | 30 + include/os/linux/debug_ce.h | 21 + include/os/linux/debug_clk_gm20b.c | 280 + include/os/linux/debug_clk_gm20b.h | 29 + include/os/linux/debug_clk_gp106.c | 193 + include/os/linux/debug_clk_gp106.h | 29 + include/os/linux/debug_clk_gv100.c | 193 + include/os/linux/debug_clk_gv100.h | 29 + include/os/linux/debug_fecs_trace.c | 151 + include/os/linux/debug_fecs_trace.h | 30 + include/os/linux/debug_fifo.c | 376 + include/os/linux/debug_fifo.h | 22 + include/os/linux/debug_gr.c | 31 + include/os/linux/debug_gr.h | 21 + include/os/linux/debug_hal.c | 95 + include/os/linux/debug_hal.h | 22 + include/os/linux/debug_kmem.c | 312 + include/os/linux/debug_kmem.h | 23 + include/os/linux/debug_ltc.c | 94 + include/os/linux/debug_ltc.h | 21 + include/os/linux/debug_pmgr.c | 104 + include/os/linux/debug_pmgr.h | 28 + include/os/linux/debug_pmu.c | 484 ++ include/os/linux/debug_pmu.h | 21 + include/os/linux/debug_sched.c | 79 + include/os/linux/debug_sched.h | 21 + include/os/linux/debug_therm_gp106.c | 49 + include/os/linux/debug_therm_gp106.h | 29 + include/os/linux/debug_xve.c | 177 + include/os/linux/debug_xve.h | 21 + include/os/linux/dmabuf.c | 219 + include/os/linux/dmabuf.h | 62 + include/os/linux/dmabuf_vidmem.c | 269 + include/os/linux/dmabuf_vidmem.h | 78 + include/os/linux/driver_common.c | 351 + include/os/linux/driver_common.h | 22 + include/os/linux/dt.c | 29 + include/os/linux/ecc_sysfs.c | 80 + include/os/linux/firmware.c | 117 + include/os/linux/fuse.c | 55 + include/os/linux/intr.c | 136 + include/os/linux/intr.h | 22 + include/os/linux/io.c | 130 + include/os/linux/io_usermode.c | 29 + include/os/linux/ioctl.c | 297 + include/os/linux/ioctl.h | 23 + include/os/linux/ioctl_as.c | 427 + include/os/linux/ioctl_as.h | 30 + include/os/linux/ioctl_channel.c | 1388 +++ include/os/linux/ioctl_channel.h | 57 + include/os/linux/ioctl_clk_arb.c | 574 ++ include/os/linux/ioctl_ctrl.c | 2106 +++++ include/os/linux/ioctl_ctrl.h | 27 + include/os/linux/ioctl_dbg.c | 2210 +++++ include/os/linux/ioctl_dbg.h | 38 + include/os/linux/ioctl_tsg.c | 750 ++ include/os/linux/ioctl_tsg.h | 28 + include/os/linux/kmem.c | 653 ++ include/os/linux/kmem_priv.h | 105 + include/os/linux/linux-channel.c | 657 ++ include/os/linux/linux-dma.c | 534 ++ include/os/linux/log.c | 132 + include/os/linux/ltc.c | 60 + include/os/linux/module.c | 1529 ++++ include/os/linux/module.h | 35 + include/os/linux/module_usermode.c | 62 + include/os/linux/module_usermode.h | 27 + include/os/linux/nvgpu_mem.c | 348 + include/os/linux/nvhost.c | 295 + include/os/linux/nvhost_priv.h | 24 + include/os/linux/nvidia_p2p.c | 299 + include/os/linux/nvlink.c | 132 + include/os/linux/nvlink.h | 22 + include/os/linux/os_fence_android.c | 79 + include/os/linux/os_fence_android_sema.c | 112 + include/os/linux/os_fence_android_syncpt.c | 121 + include/os/linux/os_linux.h | 187 + include/os/linux/os_ops.c | 61 + include/os/linux/os_ops.h | 22 + include/os/linux/os_ops_gm20b.c | 47 + include/os/linux/os_ops_gm20b.h | 22 + include/os/linux/os_ops_gp106.c | 40 + include/os/linux/os_ops_gp106.h | 22 + include/os/linux/os_ops_gp10b.c | 41 + include/os/linux/os_ops_gp10b.h | 22 + include/os/linux/os_ops_gv100.c | 40 + include/os/linux/os_ops_gv100.h | 22 + include/os/linux/os_ops_gv11b.c | 30 + include/os/linux/os_ops_gv11b.h | 24 + include/os/linux/os_sched.c | 32 + include/os/linux/pci.c | 854 ++ include/os/linux/pci.h | 27 + include/os/linux/pci_usermode.c | 24 + include/os/linux/pci_usermode.h | 23 + include/os/linux/platform_gk20a.h | 329 + include/os/linux/platform_gk20a_tegra.c | 966 +++ include/os/linux/platform_gk20a_tegra.h | 23 + include/os/linux/platform_gp10b.h | 39 + include/os/linux/platform_gp10b_tegra.c | 510 ++ include/os/linux/platform_gp10b_tegra.h | 22 + include/os/linux/platform_gv11b_tegra.c | 331 + include/os/linux/rwsem.c | 39 + include/os/linux/scale.c | 435 + include/os/linux/scale.h | 66 + include/os/linux/sched.c | 666 ++ include/os/linux/sched.h | 36 + include/os/linux/sim.c | 96 + include/os/linux/sim_pci.c | 93 + include/os/linux/soc.c | 122 + include/os/linux/sync_sema_android.c | 418 + include/os/linux/sync_sema_android.h | 51 + include/os/linux/sysfs.c | 1275 +++ include/os/linux/sysfs.h | 24 + include/os/linux/thread.c | 70 + include/os/linux/timers.c | 269 + include/os/linux/vgpu/fecs_trace_vgpu.c | 225 + .../linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c | 103 + include/os/linux/vgpu/platform_vgpu_tegra.c | 97 + include/os/linux/vgpu/platform_vgpu_tegra.h | 24 + include/os/linux/vgpu/sysfs_vgpu.c | 143 + include/os/linux/vgpu/vgpu_ivc.c | 77 + include/os/linux/vgpu/vgpu_ivm.c | 53 + include/os/linux/vgpu/vgpu_linux.c | 525 ++ include/os/linux/vgpu/vgpu_linux.h | 68 + include/os/linux/vm.c | 356 + include/os/linux/vpr.c | 22 + include/os/posix/bitmap.c | 227 + include/os/posix/bug.c | 67 + include/os/posix/clk_arb.c | 198 + include/os/posix/cond.c | 55 + include/os/posix/error_notifier.c | 40 + include/os/posix/firmware.c | 35 + include/os/posix/fuse.c | 54 + include/os/posix/io.c | 371 + include/os/posix/kmem.c | 134 + include/os/posix/lock.c | 79 + include/os/posix/log.c | 95 + include/os/posix/nvgpu.c | 149 + include/os/posix/nvlink.c | 33 + include/os/posix/os_posix.h | 58 + include/os/posix/posix-channel.c | 32 + include/os/posix/posix-comptags.c | 49 + include/os/posix/posix-dma.c | 88 + include/os/posix/posix-nvgpu_mem.c | 140 + include/os/posix/posix-tsg.c | 28 + include/os/posix/posix-vm.c | 52 + include/os/posix/posix-vpr.c | 19 + include/os/posix/rwsem.c | 117 + include/os/posix/soc.c | 53 + include/os/posix/stubs.c | 50 + include/os/posix/thread.c | 101 + include/os/posix/timers.c | 169 + include/pmgr/pmgr.c | 111 + include/pmgr/pmgr.h | 43 + include/pmgr/pmgrpmu.c | 546 ++ include/pmgr/pmgrpmu.h | 39 + include/pmgr/pwrdev.c | 319 + include/pmgr/pwrdev.h | 60 + include/pmgr/pwrmonitor.c | 376 + include/pmgr/pwrmonitor.h | 69 + include/pmgr/pwrpolicy.c | 782 ++ include/pmgr/pwrpolicy.h | 136 + include/pmu_perf/pmu_perf.c | 128 + include/pmu_perf/pmu_perf.h | 85 + include/pmu_perf/vfe_equ.c | 607 ++ include/pmu_perf/vfe_equ.h | 84 + include/pmu_perf/vfe_var.c | 1091 +++ include/pmu_perf/vfe_var.h | 109 + include/pstate/pstate.c | 488 ++ include/pstate/pstate.h | 74 + include/therm/thrm.c | 55 + include/therm/thrm.h | 38 + include/therm/thrmchannel.c | 256 + include/therm/thrmchannel.h | 51 + include/therm/thrmdev.c | 370 + include/therm/thrmdev.h | 58 + include/therm/thrmpmu.c | 271 + include/therm/thrmpmu.h | 31 + include/volt/volt.h | 39 + include/volt/volt_dev.c | 609 ++ include/volt/volt_dev.h | 77 + include/volt/volt_pmu.c | 384 + include/volt/volt_pmu.h | 46 + include/volt/volt_policy.c | 513 ++ include/volt/volt_policy.h | 80 + include/volt/volt_rail.c | 485 ++ include/volt/volt_rail.h | 90 + 618 files changed, 196752 insertions(+) create mode 100644 include/boardobj/boardobj.c create mode 100644 include/boardobj/boardobj.h create mode 100644 include/boardobj/boardobjgrp.c create mode 100644 include/boardobj/boardobjgrp.h create mode 100644 include/boardobj/boardobjgrp_e255.c create mode 100644 include/boardobj/boardobjgrp_e255.h create mode 100644 include/boardobj/boardobjgrp_e32.c create mode 100644 include/boardobj/boardobjgrp_e32.h create mode 100644 include/boardobj/boardobjgrpmask.c create mode 100644 include/boardobj/boardobjgrpmask.h create mode 100644 include/clk/clk.c create mode 100644 include/clk/clk.h create mode 100644 include/clk/clk_arb.c create mode 100644 include/clk/clk_domain.c create mode 100644 include/clk/clk_domain.h create mode 100644 include/clk/clk_fll.c create mode 100644 include/clk/clk_fll.h create mode 100644 include/clk/clk_freq_controller.c create mode 100644 include/clk/clk_freq_controller.h create mode 100644 include/clk/clk_mclk.h create mode 100644 include/clk/clk_prog.c create mode 100644 include/clk/clk_prog.h create mode 100644 include/clk/clk_vf_point.c create mode 100644 include/clk/clk_vf_point.h create mode 100644 include/clk/clk_vin.c create mode 100644 include/clk/clk_vin.h create mode 100644 include/ctrl/ctrlboardobj.h create mode 100644 include/ctrl/ctrlclk.h create mode 100644 include/ctrl/ctrlclkavfs.h create mode 100644 include/ctrl/ctrlperf.h create mode 100644 include/ctrl/ctrlpmgr.h create mode 100644 include/ctrl/ctrltherm.h create mode 100644 include/ctrl/ctrlvolt.h create mode 100644 include/gk20a/ce2_gk20a.c create mode 100644 include/gk20a/ce2_gk20a.h create mode 100644 include/gk20a/clk_gk20a.h create mode 100644 include/gk20a/css_gr_gk20a.c create mode 100644 include/gk20a/css_gr_gk20a.h create mode 100644 include/gk20a/dbg_gpu_gk20a.c create mode 100644 include/gk20a/dbg_gpu_gk20a.h create mode 100644 include/gk20a/fecs_trace_gk20a.c create mode 100644 include/gk20a/fecs_trace_gk20a.h create mode 100644 include/gk20a/fence_gk20a.c create mode 100644 include/gk20a/fence_gk20a.h create mode 100644 include/gk20a/fifo_gk20a.c create mode 100644 include/gk20a/fifo_gk20a.h create mode 100644 include/gk20a/flcn_gk20a.c create mode 100644 include/gk20a/flcn_gk20a.h create mode 100644 include/gk20a/gk20a.c create mode 100644 include/gk20a/gk20a.h create mode 100644 include/gk20a/gr_ctx_gk20a.c create mode 100644 include/gk20a/gr_ctx_gk20a.h create mode 100644 include/gk20a/gr_ctx_gk20a_sim.c create mode 100644 include/gk20a/gr_gk20a.c create mode 100644 include/gk20a/gr_gk20a.h create mode 100644 include/gk20a/gr_pri_gk20a.h create mode 100644 include/gk20a/hw_bus_gk20a.h create mode 100644 include/gk20a/hw_ccsr_gk20a.h create mode 100644 include/gk20a/hw_ce2_gk20a.h create mode 100644 include/gk20a/hw_ctxsw_prog_gk20a.h create mode 100644 include/gk20a/hw_falcon_gk20a.h create mode 100644 include/gk20a/hw_fb_gk20a.h create mode 100644 include/gk20a/hw_fifo_gk20a.h create mode 100644 include/gk20a/hw_flush_gk20a.h create mode 100644 include/gk20a/hw_gmmu_gk20a.h create mode 100644 include/gk20a/hw_gr_gk20a.h create mode 100644 include/gk20a/hw_ltc_gk20a.h create mode 100644 include/gk20a/hw_mc_gk20a.h create mode 100644 include/gk20a/hw_pbdma_gk20a.h create mode 100644 include/gk20a/hw_perf_gk20a.h create mode 100644 include/gk20a/hw_pram_gk20a.h create mode 100644 include/gk20a/hw_pri_ringmaster_gk20a.h create mode 100644 include/gk20a/hw_pri_ringstation_fbp_gk20a.h create mode 100644 include/gk20a/hw_pri_ringstation_gpc_gk20a.h create mode 100644 include/gk20a/hw_pri_ringstation_sys_gk20a.h create mode 100644 include/gk20a/hw_proj_gk20a.h create mode 100644 include/gk20a/hw_pwr_gk20a.h create mode 100644 include/gk20a/hw_ram_gk20a.h create mode 100644 include/gk20a/hw_therm_gk20a.h create mode 100644 include/gk20a/hw_timer_gk20a.h create mode 100644 include/gk20a/hw_top_gk20a.h create mode 100644 include/gk20a/hw_trim_gk20a.h create mode 100644 include/gk20a/mm_gk20a.c create mode 100644 include/gk20a/mm_gk20a.h create mode 100644 include/gk20a/pmu_gk20a.c create mode 100644 include/gk20a/pmu_gk20a.h create mode 100644 include/gk20a/regops_gk20a.c create mode 100644 include/gk20a/regops_gk20a.h create mode 100644 include/lpwr/lpwr.c create mode 100644 include/lpwr/lpwr.h create mode 100644 include/lpwr/rppg.c create mode 100644 include/lpwr/rppg.h create mode 100644 include/nvgpu/acr/acr_flcnbl.h create mode 100644 include/nvgpu/acr/acr_lsfm.h create mode 100644 include/nvgpu/acr/acr_objflcn.h create mode 100644 include/nvgpu/acr/acr_objlsfm.h create mode 100644 include/nvgpu/acr/nvgpu_acr.h create mode 100644 include/nvgpu/allocator.h create mode 100644 include/nvgpu/as.h create mode 100644 include/nvgpu/atomic.h create mode 100644 include/nvgpu/barrier.h create mode 100644 include/nvgpu/bios.h create mode 100644 include/nvgpu/bitops.h create mode 100644 include/nvgpu/bsearch.h create mode 100644 include/nvgpu/bug.h create mode 100644 include/nvgpu/channel.h create mode 100644 include/nvgpu/channel_sync.h create mode 100644 include/nvgpu/circ_buf.h create mode 100644 include/nvgpu/clk.h create mode 100644 include/nvgpu/clk_arb.h create mode 100644 include/nvgpu/comptags.h create mode 100644 include/nvgpu/cond.h create mode 100644 include/nvgpu/ctxsw_trace.h create mode 100644 include/nvgpu/debug.h create mode 100644 include/nvgpu/defaults.h create mode 100644 include/nvgpu/dma.h create mode 100644 include/nvgpu/dt.h create mode 100644 include/nvgpu/ecc.h create mode 100644 include/nvgpu/enabled.h create mode 100644 include/nvgpu/errno.h create mode 100644 include/nvgpu/error_notifier.h create mode 100644 include/nvgpu/falcon.h create mode 100644 include/nvgpu/fecs_trace.h create mode 100644 include/nvgpu/firmware.h create mode 100644 include/nvgpu/flcnif_cmn.h create mode 100644 include/nvgpu/fuse.h create mode 100644 include/nvgpu/gk20a.h create mode 100644 include/nvgpu/gmmu.h create mode 100644 include/nvgpu/hal_init.h create mode 100644 include/nvgpu/hashtable.h create mode 100644 include/nvgpu/hw/gk20a/hw_bus_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_ccsr_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_ce2_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_ctxsw_prog_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_falcon_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_fb_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_fifo_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_flush_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_gmmu_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_gr_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_ltc_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_mc_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_pbdma_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_perf_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_pram_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_pri_ringmaster_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_pri_ringstation_fbp_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_pri_ringstation_gpc_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_pri_ringstation_sys_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_proj_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_pwr_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_ram_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_therm_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_timer_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_top_gk20a.h create mode 100644 include/nvgpu/hw/gk20a/hw_trim_gk20a.h create mode 100644 include/nvgpu/hw/gm20b/hw_bus_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_ccsr_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_ce2_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_ctxsw_prog_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_falcon_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_fb_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_fifo_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_flush_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_fuse_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_gmmu_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_gr_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_ltc_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_mc_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_pbdma_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_perf_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_pram_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_pri_ringmaster_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_pri_ringstation_gpc_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_pri_ringstation_sys_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_proj_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_pwr_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_ram_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_therm_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_timer_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_top_gm20b.h create mode 100644 include/nvgpu/hw/gm20b/hw_trim_gm20b.h create mode 100644 include/nvgpu/hw/gp106/hw_bus_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_ccsr_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_ce_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_ctxsw_prog_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_falcon_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_fb_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_fbpa_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_fifo_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_flush_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_fuse_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_gc6_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_gmmu_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_gr_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_ltc_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_mc_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_pbdma_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_perf_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_pram_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_pri_ringmaster_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_pri_ringstation_gpc_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_pri_ringstation_sys_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_proj_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_psec_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_pwr_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_ram_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_therm_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_timer_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_top_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_trim_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_xp_gp106.h create mode 100644 include/nvgpu/hw/gp106/hw_xve_gp106.h create mode 100644 include/nvgpu/hw/gp10b/hw_bus_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_ccsr_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_ce_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_ctxsw_prog_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_falcon_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_fb_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_fifo_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_flush_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_fuse_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_gmmu_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_gr_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_ltc_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_mc_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_pbdma_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_perf_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_pram_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_pri_ringmaster_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_pri_ringstation_gpc_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_pri_ringstation_sys_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_proj_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_pwr_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_ram_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_therm_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_timer_gp10b.h create mode 100644 include/nvgpu/hw/gp10b/hw_top_gp10b.h create mode 100644 include/nvgpu/hw/gv100/hw_bus_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_ccsr_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_ce_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_ctxsw_prog_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_falcon_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_fb_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_fifo_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_flush_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_fuse_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_gmmu_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_gr_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_ioctrl_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_ioctrlmif_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_ltc_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_mc_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_minion_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_nvl_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_nvlinkip_discovery_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_nvlipt_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_nvtlc_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_pbdma_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_perf_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_pgsp_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_pram_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_pri_ringmaster_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_pri_ringstation_gpc_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_pri_ringstation_sys_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_proj_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_pwr_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_ram_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_therm_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_timer_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_top_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_trim_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_usermode_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_xp_gv100.h create mode 100644 include/nvgpu/hw/gv100/hw_xve_gv100.h create mode 100644 include/nvgpu/hw/gv11b/hw_bus_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_ccsr_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_ce_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_ctxsw_prog_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_falcon_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_fb_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_fifo_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_flush_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_fuse_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_gmmu_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_gr_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_ltc_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_mc_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_pbdma_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_perf_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_pram_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_pri_ringmaster_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_pri_ringstation_gpc_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_pri_ringstation_sys_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_proj_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_pwr_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_ram_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_therm_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_timer_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_top_gv11b.h create mode 100644 include/nvgpu/hw/gv11b/hw_usermode_gv11b.h create mode 100644 include/nvgpu/hw_sim.h create mode 100644 include/nvgpu/hw_sim_pci.h create mode 100644 include/nvgpu/io.h create mode 100644 include/nvgpu/io_usermode.h create mode 100644 include/nvgpu/kmem.h create mode 100644 include/nvgpu/kref.h create mode 100644 include/nvgpu/linux/atomic.h create mode 100644 include/nvgpu/linux/barrier.h create mode 100644 include/nvgpu/linux/cond.h create mode 100644 include/nvgpu/linux/dma.h create mode 100644 include/nvgpu/linux/kmem.h create mode 100644 include/nvgpu/linux/lock.h create mode 100644 include/nvgpu/linux/nvgpu_mem.h create mode 100644 include/nvgpu/linux/nvlink.h create mode 100644 include/nvgpu/linux/os_fence_android.h create mode 100644 include/nvgpu/linux/rwsem.h create mode 100644 include/nvgpu/linux/sim.h create mode 100644 include/nvgpu/linux/sim_pci.h create mode 100644 include/nvgpu/linux/thread.h create mode 100644 include/nvgpu/linux/vm.h create mode 100644 include/nvgpu/list.h create mode 100644 include/nvgpu/lock.h create mode 100644 include/nvgpu/log.h create mode 100644 include/nvgpu/log2.h create mode 100644 include/nvgpu/ltc.h create mode 100644 include/nvgpu/mc.h create mode 100644 include/nvgpu/mm.h create mode 100644 include/nvgpu/nvgpu_common.h create mode 100644 include/nvgpu/nvgpu_mem.h create mode 100644 include/nvgpu/nvhost.h create mode 100644 include/nvgpu/nvlink.h create mode 100644 include/nvgpu/os_fence.h create mode 100644 include/nvgpu/os_sched.h create mode 100644 include/nvgpu/page_allocator.h create mode 100644 include/nvgpu/pci.h create mode 100644 include/nvgpu/pmu.h create mode 100644 include/nvgpu/pmuif/gpmu_super_surf_if.h create mode 100644 include/nvgpu/pmuif/gpmuif_acr.h create mode 100644 include/nvgpu/pmuif/gpmuif_ap.h create mode 100644 include/nvgpu/pmuif/gpmuif_cmn.h create mode 100644 include/nvgpu/pmuif/gpmuif_perfmon.h create mode 100644 include/nvgpu/pmuif/gpmuif_pg.h create mode 100644 include/nvgpu/pmuif/gpmuif_pg_rppg.h create mode 100644 include/nvgpu/pmuif/gpmuif_pmu.h create mode 100644 include/nvgpu/pmuif/gpmuifbios.h create mode 100644 include/nvgpu/pmuif/gpmuifboardobj.h create mode 100644 include/nvgpu/pmuif/gpmuifclk.h create mode 100644 include/nvgpu/pmuif/gpmuifperf.h create mode 100644 include/nvgpu/pmuif/gpmuifperfvfe.h create mode 100644 include/nvgpu/pmuif/gpmuifpmgr.h create mode 100644 include/nvgpu/pmuif/gpmuifseq.h create mode 100644 include/nvgpu/pmuif/gpmuiftherm.h create mode 100644 include/nvgpu/pmuif/gpmuifthermsensor.h create mode 100644 include/nvgpu/pmuif/gpmuifvolt.h create mode 100644 include/nvgpu/pmuif/nvgpu_gpmu_cmdif.h create mode 100644 include/nvgpu/posix/atomic.h create mode 100644 include/nvgpu/posix/barrier.h create mode 100644 include/nvgpu/posix/bitops.h create mode 100644 include/nvgpu/posix/bug.h create mode 100644 include/nvgpu/posix/circ_buf.h create mode 100644 include/nvgpu/posix/cond.h create mode 100644 include/nvgpu/posix/io.h create mode 100644 include/nvgpu/posix/kmem.h create mode 100644 include/nvgpu/posix/lock.h create mode 100644 include/nvgpu/posix/log2.h create mode 100644 include/nvgpu/posix/nvgpu_mem.h create mode 100644 include/nvgpu/posix/nvlink.h create mode 100644 include/nvgpu/posix/pci.h create mode 100644 include/nvgpu/posix/probe.h create mode 100644 include/nvgpu/posix/rwsem.h create mode 100644 include/nvgpu/posix/sizes.h create mode 100644 include/nvgpu/posix/sort.h create mode 100644 include/nvgpu/posix/thread.h create mode 100644 include/nvgpu/posix/types.h create mode 100644 include/nvgpu/posix/vm.h create mode 100644 include/nvgpu/power_features/cg.h create mode 100644 include/nvgpu/power_features/pg.h create mode 100644 include/nvgpu/power_features/power_features.h create mode 100644 include/nvgpu/pramin.h create mode 100644 include/nvgpu/ptimer.h create mode 100644 include/nvgpu/rbtree.h create mode 100644 include/nvgpu/rwsem.h create mode 100644 include/nvgpu/sched.h create mode 100644 include/nvgpu/sec2.h create mode 100644 include/nvgpu/sec2if/sec2_cmd_if.h create mode 100644 include/nvgpu/sec2if/sec2_if_acr.h create mode 100644 include/nvgpu/sec2if/sec2_if_cmn.h create mode 100644 include/nvgpu/sec2if/sec2_if_sec2.h create mode 100644 include/nvgpu/semaphore.h create mode 100644 include/nvgpu/sim.h create mode 100644 include/nvgpu/sizes.h create mode 100644 include/nvgpu/soc.h create mode 100644 include/nvgpu/sort.h create mode 100644 include/nvgpu/therm.h create mode 100644 include/nvgpu/thread.h create mode 100644 include/nvgpu/timers.h create mode 100644 include/nvgpu/tsg.h create mode 100644 include/nvgpu/types.h create mode 100644 include/nvgpu/unit.h create mode 100644 include/nvgpu/utils.h create mode 100644 include/nvgpu/vgpu/tegra_vgpu.h create mode 100644 include/nvgpu/vgpu/vgpu.h create mode 100644 include/nvgpu/vgpu/vgpu_ivc.h create mode 100644 include/nvgpu/vgpu/vgpu_ivm.h create mode 100644 include/nvgpu/vgpu/vm.h create mode 100644 include/nvgpu/vidmem.h create mode 100644 include/nvgpu/vm.h create mode 100644 include/nvgpu/vm_area.h create mode 100644 include/nvgpu/vpr.h create mode 100644 include/nvgpu/xve.h create mode 100644 include/os/linux/cde.c create mode 100644 include/os/linux/cde.h create mode 100644 include/os/linux/cde_gm20b.c create mode 100644 include/os/linux/cde_gm20b.h create mode 100644 include/os/linux/cde_gp10b.c create mode 100644 include/os/linux/cde_gp10b.h create mode 100644 include/os/linux/channel.h create mode 100644 include/os/linux/clk.c create mode 100644 include/os/linux/clk.h create mode 100644 include/os/linux/comptags.c create mode 100644 include/os/linux/cond.c create mode 100644 include/os/linux/ctxsw_trace.c create mode 100644 include/os/linux/ctxsw_trace.h create mode 100644 include/os/linux/debug.c create mode 100644 include/os/linux/debug_allocator.c create mode 100644 include/os/linux/debug_allocator.h create mode 100644 include/os/linux/debug_bios.c create mode 100644 include/os/linux/debug_bios.h create mode 100644 include/os/linux/debug_cde.c create mode 100644 include/os/linux/debug_cde.h create mode 100644 include/os/linux/debug_ce.c create mode 100644 include/os/linux/debug_ce.h create mode 100644 include/os/linux/debug_clk_gm20b.c create mode 100644 include/os/linux/debug_clk_gm20b.h create mode 100644 include/os/linux/debug_clk_gp106.c create mode 100644 include/os/linux/debug_clk_gp106.h create mode 100644 include/os/linux/debug_clk_gv100.c create mode 100644 include/os/linux/debug_clk_gv100.h create mode 100644 include/os/linux/debug_fecs_trace.c create mode 100644 include/os/linux/debug_fecs_trace.h create mode 100644 include/os/linux/debug_fifo.c create mode 100644 include/os/linux/debug_fifo.h create mode 100644 include/os/linux/debug_gr.c create mode 100644 include/os/linux/debug_gr.h create mode 100644 include/os/linux/debug_hal.c create mode 100644 include/os/linux/debug_hal.h create mode 100644 include/os/linux/debug_kmem.c create mode 100644 include/os/linux/debug_kmem.h create mode 100644 include/os/linux/debug_ltc.c create mode 100644 include/os/linux/debug_ltc.h create mode 100644 include/os/linux/debug_pmgr.c create mode 100644 include/os/linux/debug_pmgr.h create mode 100644 include/os/linux/debug_pmu.c create mode 100644 include/os/linux/debug_pmu.h create mode 100644 include/os/linux/debug_sched.c create mode 100644 include/os/linux/debug_sched.h create mode 100644 include/os/linux/debug_therm_gp106.c create mode 100644 include/os/linux/debug_therm_gp106.h create mode 100644 include/os/linux/debug_xve.c create mode 100644 include/os/linux/debug_xve.h create mode 100644 include/os/linux/dmabuf.c create mode 100644 include/os/linux/dmabuf.h create mode 100644 include/os/linux/dmabuf_vidmem.c create mode 100644 include/os/linux/dmabuf_vidmem.h create mode 100644 include/os/linux/driver_common.c create mode 100644 include/os/linux/driver_common.h create mode 100644 include/os/linux/dt.c create mode 100644 include/os/linux/ecc_sysfs.c create mode 100644 include/os/linux/firmware.c create mode 100644 include/os/linux/fuse.c create mode 100644 include/os/linux/intr.c create mode 100644 include/os/linux/intr.h create mode 100644 include/os/linux/io.c create mode 100644 include/os/linux/io_usermode.c create mode 100644 include/os/linux/ioctl.c create mode 100644 include/os/linux/ioctl.h create mode 100644 include/os/linux/ioctl_as.c create mode 100644 include/os/linux/ioctl_as.h create mode 100644 include/os/linux/ioctl_channel.c create mode 100644 include/os/linux/ioctl_channel.h create mode 100644 include/os/linux/ioctl_clk_arb.c create mode 100644 include/os/linux/ioctl_ctrl.c create mode 100644 include/os/linux/ioctl_ctrl.h create mode 100644 include/os/linux/ioctl_dbg.c create mode 100644 include/os/linux/ioctl_dbg.h create mode 100644 include/os/linux/ioctl_tsg.c create mode 100644 include/os/linux/ioctl_tsg.h create mode 100644 include/os/linux/kmem.c create mode 100644 include/os/linux/kmem_priv.h create mode 100644 include/os/linux/linux-channel.c create mode 100644 include/os/linux/linux-dma.c create mode 100644 include/os/linux/log.c create mode 100644 include/os/linux/ltc.c create mode 100644 include/os/linux/module.c create mode 100644 include/os/linux/module.h create mode 100644 include/os/linux/module_usermode.c create mode 100644 include/os/linux/module_usermode.h create mode 100644 include/os/linux/nvgpu_mem.c create mode 100644 include/os/linux/nvhost.c create mode 100644 include/os/linux/nvhost_priv.h create mode 100644 include/os/linux/nvidia_p2p.c create mode 100644 include/os/linux/nvlink.c create mode 100644 include/os/linux/nvlink.h create mode 100644 include/os/linux/os_fence_android.c create mode 100644 include/os/linux/os_fence_android_sema.c create mode 100644 include/os/linux/os_fence_android_syncpt.c create mode 100644 include/os/linux/os_linux.h create mode 100644 include/os/linux/os_ops.c create mode 100644 include/os/linux/os_ops.h create mode 100644 include/os/linux/os_ops_gm20b.c create mode 100644 include/os/linux/os_ops_gm20b.h create mode 100644 include/os/linux/os_ops_gp106.c create mode 100644 include/os/linux/os_ops_gp106.h create mode 100644 include/os/linux/os_ops_gp10b.c create mode 100644 include/os/linux/os_ops_gp10b.h create mode 100644 include/os/linux/os_ops_gv100.c create mode 100644 include/os/linux/os_ops_gv100.h create mode 100644 include/os/linux/os_ops_gv11b.c create mode 100644 include/os/linux/os_ops_gv11b.h create mode 100644 include/os/linux/os_sched.c create mode 100644 include/os/linux/pci.c create mode 100644 include/os/linux/pci.h create mode 100644 include/os/linux/pci_usermode.c create mode 100644 include/os/linux/pci_usermode.h create mode 100644 include/os/linux/platform_gk20a.h create mode 100644 include/os/linux/platform_gk20a_tegra.c create mode 100644 include/os/linux/platform_gk20a_tegra.h create mode 100644 include/os/linux/platform_gp10b.h create mode 100644 include/os/linux/platform_gp10b_tegra.c create mode 100644 include/os/linux/platform_gp10b_tegra.h create mode 100644 include/os/linux/platform_gv11b_tegra.c create mode 100644 include/os/linux/rwsem.c create mode 100644 include/os/linux/scale.c create mode 100644 include/os/linux/scale.h create mode 100644 include/os/linux/sched.c create mode 100644 include/os/linux/sched.h create mode 100644 include/os/linux/sim.c create mode 100644 include/os/linux/sim_pci.c create mode 100644 include/os/linux/soc.c create mode 100644 include/os/linux/sync_sema_android.c create mode 100644 include/os/linux/sync_sema_android.h create mode 100644 include/os/linux/sysfs.c create mode 100644 include/os/linux/sysfs.h create mode 100644 include/os/linux/thread.c create mode 100644 include/os/linux/timers.c create mode 100644 include/os/linux/vgpu/fecs_trace_vgpu.c create mode 100644 include/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c create mode 100644 include/os/linux/vgpu/platform_vgpu_tegra.c create mode 100644 include/os/linux/vgpu/platform_vgpu_tegra.h create mode 100644 include/os/linux/vgpu/sysfs_vgpu.c create mode 100644 include/os/linux/vgpu/vgpu_ivc.c create mode 100644 include/os/linux/vgpu/vgpu_ivm.c create mode 100644 include/os/linux/vgpu/vgpu_linux.c create mode 100644 include/os/linux/vgpu/vgpu_linux.h create mode 100644 include/os/linux/vm.c create mode 100644 include/os/linux/vpr.c create mode 100644 include/os/posix/bitmap.c create mode 100644 include/os/posix/bug.c create mode 100644 include/os/posix/clk_arb.c create mode 100644 include/os/posix/cond.c create mode 100644 include/os/posix/error_notifier.c create mode 100644 include/os/posix/firmware.c create mode 100644 include/os/posix/fuse.c create mode 100644 include/os/posix/io.c create mode 100644 include/os/posix/kmem.c create mode 100644 include/os/posix/lock.c create mode 100644 include/os/posix/log.c create mode 100644 include/os/posix/nvgpu.c create mode 100644 include/os/posix/nvlink.c create mode 100644 include/os/posix/os_posix.h create mode 100644 include/os/posix/posix-channel.c create mode 100644 include/os/posix/posix-comptags.c create mode 100644 include/os/posix/posix-dma.c create mode 100644 include/os/posix/posix-nvgpu_mem.c create mode 100644 include/os/posix/posix-tsg.c create mode 100644 include/os/posix/posix-vm.c create mode 100644 include/os/posix/posix-vpr.c create mode 100644 include/os/posix/rwsem.c create mode 100644 include/os/posix/soc.c create mode 100644 include/os/posix/stubs.c create mode 100644 include/os/posix/thread.c create mode 100644 include/os/posix/timers.c create mode 100644 include/pmgr/pmgr.c create mode 100644 include/pmgr/pmgr.h create mode 100644 include/pmgr/pmgrpmu.c create mode 100644 include/pmgr/pmgrpmu.h create mode 100644 include/pmgr/pwrdev.c create mode 100644 include/pmgr/pwrdev.h create mode 100644 include/pmgr/pwrmonitor.c create mode 100644 include/pmgr/pwrmonitor.h create mode 100644 include/pmgr/pwrpolicy.c create mode 100644 include/pmgr/pwrpolicy.h create mode 100644 include/pmu_perf/pmu_perf.c create mode 100644 include/pmu_perf/pmu_perf.h create mode 100644 include/pmu_perf/vfe_equ.c create mode 100644 include/pmu_perf/vfe_equ.h create mode 100644 include/pmu_perf/vfe_var.c create mode 100644 include/pmu_perf/vfe_var.h create mode 100644 include/pstate/pstate.c create mode 100644 include/pstate/pstate.h create mode 100644 include/therm/thrm.c create mode 100644 include/therm/thrm.h create mode 100644 include/therm/thrmchannel.c create mode 100644 include/therm/thrmchannel.h create mode 100644 include/therm/thrmdev.c create mode 100644 include/therm/thrmdev.h create mode 100644 include/therm/thrmpmu.c create mode 100644 include/therm/thrmpmu.h create mode 100644 include/volt/volt.h create mode 100644 include/volt/volt_dev.c create mode 100644 include/volt/volt_dev.h create mode 100644 include/volt/volt_pmu.c create mode 100644 include/volt/volt_pmu.h create mode 100644 include/volt/volt_policy.c create mode 100644 include/volt/volt_policy.h create mode 100644 include/volt/volt_rail.c create mode 100644 include/volt/volt_rail.h diff --git a/include/boardobj/boardobj.c b/include/boardobj/boardobj.c new file mode 100644 index 0000000..2044b5b --- /dev/null +++ b/include/boardobj/boardobj.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "boardobj.h" +#include "ctrl/ctrlboardobj.h" + +int boardobj_construct_super(struct gk20a *g, struct boardobj **ppboardobj, + u16 size, void *args) +{ + struct boardobj *pboardobj = NULL; + struct boardobj *devtmp = (struct boardobj *)args; + + nvgpu_log_info(g, " "); + + if (devtmp == NULL) { + return -EINVAL; + } + + if (*ppboardobj == NULL) { + *ppboardobj = nvgpu_kzalloc(g, size); + if (*ppboardobj == NULL) { + return -ENOMEM; + } + (*ppboardobj)->allocated = true; + } + + pboardobj = *ppboardobj; + pboardobj->g = g; + pboardobj->type = devtmp->type; + pboardobj->idx = CTRL_BOARDOBJ_IDX_INVALID; + pboardobj->type_mask = BIT(pboardobj->type) | devtmp->type_mask; + + pboardobj->implements = boardobj_implements_super; + pboardobj->destruct = boardobj_destruct_super; + pboardobj->pmudatainit = boardobj_pmudatainit_super; + + nvgpu_list_add(&pboardobj->node, &g->boardobj_head); + + return 0; +} + +int boardobj_destruct_super(struct boardobj *pboardobj) +{ + struct gk20a *g = pboardobj->g; + + nvgpu_log_info(g, " "); + if (pboardobj == NULL) { + return -EINVAL; + } + + nvgpu_list_del(&pboardobj->node); + if (pboardobj->allocated) { + nvgpu_kfree(pboardobj->g, pboardobj); + } + + return 0; +} + +bool boardobj_implements_super(struct gk20a *g, struct boardobj *pboardobj, + u8 type) +{ + nvgpu_log_info(g, " "); + + return (0 != (pboardobj->type_mask & BIT(type))); +} + +int boardobj_pmudatainit_super(struct gk20a *g, struct boardobj *pboardobj, + struct nv_pmu_boardobj *pmudata) +{ + nvgpu_log_info(g, " "); + if (pboardobj == NULL) { + return -EINVAL; + } + if (pmudata == NULL) { + return -EINVAL; + } + pmudata->type = pboardobj->type; + nvgpu_log_info(g, " Done"); + return 0; +} diff --git a/include/boardobj/boardobj.h b/include/boardobj/boardobj.h new file mode 100644 index 0000000..b1be9bd --- /dev/null +++ b/include/boardobj/boardobj.h @@ -0,0 +1,104 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_BOARDOBJ_H +#define NVGPU_BOARDOBJ_H + +#include +#include + +#include "ctrl/ctrlboardobj.h" + +struct boardobj; +struct nvgpu_list_node; + +/* +* check whether the specified BOARDOBJ object implements the queried +* type/class enumeration. +*/ +typedef bool boardobj_implements(struct gk20a *g, struct boardobj *pboardobj, + u8 type); + +/* +* Fills out the appropriate the nv_pmu_xxxx_device_desc_ driver->PMU +* description structure, describing this BOARDOBJ board device to the PMU. +* +*/ +typedef int boardobj_pmudatainit(struct gk20a *g, struct boardobj *pboardobj, + struct nv_pmu_boardobj *pmudata); + +/* +* Constructor for the base Board Object. Called by each device-specific +* implementation of the BOARDOBJ interface to initialize the board object. +*/ +typedef int boardobj_construct(struct gk20a *g, struct boardobj **pboardobj, + u16 size, void *args); + +/* +* Destructor for the base board object. Called by each device-Specific +* implementation of the BOARDOBJ interface to destroy the board object. +* This has to be explicitly set by each device that extends from the +* board object. +*/ +typedef int boardobj_destruct(struct boardobj *pboardobj); + +/* +* Base Class for all physical or logical device on the PCB. +* Contains fields common to all devices on the board. Specific types of +* devices may extend this object adding any details specific to that +* device or device-type. +*/ + +struct boardobj { + struct gk20a *g; + + u8 type; /*type of the device*/ + u8 idx; /*index of boardobj within in its group*/ + /* true if allocated in constructor. destructor should free */ + u8 allocated; + u32 type_mask; /*mask of types this boardobjimplements*/ + boardobj_implements *implements; + boardobj_destruct *destruct; + /* + * Access interface apis which will be overridden by the devices + * that inherit from BOARDOBJ + */ + boardobj_pmudatainit *pmudatainit; + struct nvgpu_list_node node; +}; + +boardobj_construct boardobj_construct_super; +boardobj_destruct boardobj_destruct_super; +boardobj_implements boardobj_implements_super; +boardobj_pmudatainit boardobj_pmudatainit_super; + +#define BOARDOBJ_GET_TYPE(pobj) (((struct boardobj *)(pobj))->type) +#define BOARDOBJ_GET_IDX(pobj) (((struct boardobj *)(pobj))->idx) + +static inline struct boardobj * +boardobj_from_node(struct nvgpu_list_node *node) +{ + return (struct boardobj *) + ((uintptr_t)node - offsetof(struct boardobj, node)); +}; + +#endif /* NVGPU_BOARDOBJ_H */ diff --git a/include/boardobj/boardobjgrp.c b/include/boardobj/boardobjgrp.c new file mode 100644 index 0000000..6832070 --- /dev/null +++ b/include/boardobj/boardobjgrp.c @@ -0,0 +1,1046 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ +#include +#include + +#include "boardobjgrp.h" +#include "ctrl/ctrlboardobj.h" +#include "boardobj.h" + +static boardobjgrp_objinsert boardobjgrp_objinsert_final; +static boardobjgrp_objgetbyidx boardobjgrp_objgetbyidx_final; +static boardobjgrp_objgetnext boardobjgrp_objgetnext_final; +static boardobjgrp_objremoveanddestroy boardobjgrp_objremoveanddestroy_final; +static boardobjgrp_pmudatainstget boardobjgrp_pmudatainstget_stub; +static boardobjgrp_pmustatusinstget boardobjgrp_pmustatusinstget_stub; +static int boardobjgrp_pmucmdsend(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd); +static int boardobjgrp_pmucmdsend_rpc(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd, + bool copy_out); +struct boardobjgrp_pmucmdhandler_params { + /* Pointer to the BOARDOBJGRP associated with this CMD */ + struct boardobjgrp *pboardobjgrp; + /* Pointer to structure representing this NV_PMU_BOARDOBJ_CMD_GRP */ + struct boardobjgrp_pmu_cmd *pcmd; + /* Boolean indicating whether the PMU successfully handled the CMD */ + u32 success; +}; + +int boardobjgrp_construct_super(struct gk20a *g, + struct boardobjgrp *pboardobjgrp) +{ + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (pboardobjgrp->ppobjects == NULL) { + return -EINVAL; + } + + if (pboardobjgrp->mask == NULL) { + return -EINVAL; + } + + pboardobjgrp->g = g; + pboardobjgrp->objmask = 0; + + pboardobjgrp->classid = 0; + pboardobjgrp->pmu.unitid = BOARDOBJGRP_UNIT_ID_INVALID; + pboardobjgrp->pmu.classid = BOARDOBJGRP_GRP_CLASS_ID_INVALID; + pboardobjgrp->pmu.bset = false; + pboardobjgrp->pmu.rpc_func_id = BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID; + pboardobjgrp->pmu.set.id = BOARDOBJGRP_GRP_CMD_ID_INVALID; + pboardobjgrp->pmu.getstatus.id = BOARDOBJGRP_GRP_CMD_ID_INVALID; + + /* Initialize basic interfaces */ + pboardobjgrp->destruct = boardobjgrp_destruct_super; + pboardobjgrp->objinsert = boardobjgrp_objinsert_final; + pboardobjgrp->objgetbyidx = boardobjgrp_objgetbyidx_final; + pboardobjgrp->objgetnext = boardobjgrp_objgetnext_final; + pboardobjgrp->objremoveanddestroy = + boardobjgrp_objremoveanddestroy_final; + + pboardobjgrp->pmuinithandle = boardobjgrp_pmuinithandle_impl; + pboardobjgrp->pmuhdrdatainit = boardobjgrp_pmuhdrdatainit_super; + pboardobjgrp->pmudatainit = boardobjgrp_pmudatainit_super; + pboardobjgrp->pmuset = + g->ops.pmu_ver.boardobj.boardobjgrp_pmuset_impl; + pboardobjgrp->pmugetstatus = + g->ops.pmu_ver.boardobj.boardobjgrp_pmugetstatus_impl; + + pboardobjgrp->pmudatainstget = boardobjgrp_pmudatainstget_stub; + pboardobjgrp->pmustatusinstget = boardobjgrp_pmustatusinstget_stub; + + pboardobjgrp->objmaxidx = CTRL_BOARDOBJ_IDX_INVALID; + pboardobjgrp->bconstructed = true; + + nvgpu_list_add(&pboardobjgrp->node, &g->boardobjgrp_head); + + return 0; +} + +int boardobjgrp_destruct_impl(struct boardobjgrp *pboardobjgrp) +{ + struct gk20a *g = pboardobjgrp->g; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (!pboardobjgrp->bconstructed) { + return 0; + } + + return pboardobjgrp->destruct(pboardobjgrp); +} + +int boardobjgrp_destruct_super(struct boardobjgrp *pboardobjgrp) +{ + struct boardobj *pboardobj; + struct gk20a *g = pboardobjgrp->g; + int status = 0; + int stat; + u8 index; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp->mask == NULL) { + return -EINVAL; + } + if (pboardobjgrp->ppobjects == NULL) { + return -EINVAL; + } + + BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) { + stat = pboardobjgrp->objremoveanddestroy(pboardobjgrp, index); + if (status == 0) { + status = stat; + } + + pboardobjgrp->ppobjects[index] = NULL; + pboardobjgrp->objmask &= ~BIT(index); + } + + pboardobjgrp->objmask = 0; + + if (pboardobjgrp->objmaxidx != CTRL_BOARDOBJ_IDX_INVALID) { + if (status == 0) { + status = -EINVAL; + } + + WARN_ON(true); + } + + /* Destroy the PMU CMD data */ + stat = boardobjgrp_pmucmd_destroy_impl(g, &pboardobjgrp->pmu.set); + if (status == 0) { + status = stat; + } + + stat = boardobjgrp_pmucmd_destroy_impl(g, &pboardobjgrp->pmu.getstatus); + if (status == 0) { + status = stat; + } + + nvgpu_list_del(&pboardobjgrp->node); + + pboardobjgrp->bconstructed = false; + + return status; +} + +int boardobjgrp_pmucmd_construct_impl(struct gk20a *g, struct boardobjgrp + *pboardobjgrp, struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid, + u16 hdrsize, u16 entrysize, u16 fbsize, u32 ss_offset, u8 rpc_func_id) +{ + nvgpu_log_info(g, " "); + + /* Copy the parameters into the CMD*/ + cmd->id = id; + cmd->msgid = msgid; + cmd->hdrsize = (u8) hdrsize; + cmd->entrysize = (u8) entrysize; + cmd->fbsize = fbsize; + + return 0; +} + +int boardobjgrp_pmucmd_construct_impl_v1(struct gk20a *g, struct boardobjgrp + *pboardobjgrp, struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid, + u16 hdrsize, u16 entrysize, u16 fbsize, u32 ss_offset, u8 rpc_func_id) +{ + nvgpu_log_fn(g, " "); + + /* Copy the parameters into the CMD*/ + cmd->dmem_buffer_size = ((hdrsize > entrysize) ? hdrsize : entrysize); + cmd->super_surface_offset = ss_offset; + pboardobjgrp->pmu.rpc_func_id = rpc_func_id; + cmd->fbsize = fbsize; + + nvgpu_log_fn(g, "DONE"); + return 0; +} + +int boardobjgrp_pmucmd_destroy_impl(struct gk20a *g, + struct boardobjgrp_pmu_cmd *cmd) +{ + struct nvgpu_mem *mem = &cmd->surf.sysmem_desc; + + nvgpu_pmu_surface_free(g, mem); + return 0; +} + +int is_boardobjgrp_pmucmd_id_valid_v0(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd) +{ + int err = 0; + + if (pcmd->id == BOARDOBJGRP_GRP_CMD_ID_INVALID) { + err = -EINVAL; + } + + return err; +} + +int is_boardobjgrp_pmucmd_id_valid_v1(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd) +{ + int err = 0; + + if (pboardobjgrp->pmu.rpc_func_id == + BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID) { + err = -EINVAL; + } + + return err; +} + +int boardobjgrp_pmucmd_pmuinithandle_impl(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd) +{ + int status = 0; + struct nvgpu_mem *sysmem_desc = &pcmd->surf.sysmem_desc; + + nvgpu_log_info(g, " "); + + if (g->ops.pmu_ver.boardobj.is_boardobjgrp_pmucmd_id_valid(g, + pboardobjgrp, pcmd)) { + goto boardobjgrp_pmucmd_pmuinithandle_exit; + } + + if (!pcmd->fbsize) { + goto boardobjgrp_pmucmd_pmuinithandle_exit; + } + + nvgpu_pmu_sysmem_surface_alloc(g, sysmem_desc, pcmd->fbsize); + /* we only have got sysmem later this will get copied to vidmem + surface*/ + pcmd->surf.vidmem_desc.size = 0; + + pcmd->buf = (struct nv_pmu_boardobjgrp_super *)sysmem_desc->cpu_va; + +boardobjgrp_pmucmd_pmuinithandle_exit: + return status; +} + +int boardobjgrp_pmuinithandle_impl(struct gk20a *g, + struct boardobjgrp *pboardobjgrp) +{ + int status = 0; + + nvgpu_log_info(g, " "); + + status = boardobjgrp_pmucmd_pmuinithandle_impl(g, pboardobjgrp, + &pboardobjgrp->pmu.set); + if (status) { + nvgpu_err(g, "failed to init pmu set cmd"); + goto boardobjgrp_pmuinithandle_exit; + } + + status = boardobjgrp_pmucmd_pmuinithandle_impl(g, pboardobjgrp, + &pboardobjgrp->pmu.getstatus); + if (status) { + nvgpu_err(g, "failed to init get status command"); + goto boardobjgrp_pmuinithandle_exit; + } + + /* If the GRP_SET CMD has not been allocated, nothing left to do. */ + if ((g->ops.pmu_ver.boardobj.is_boardobjgrp_pmucmd_id_valid(g, + pboardobjgrp, &pboardobjgrp->pmu.set))|| + (BOARDOBJGRP_IS_EMPTY(pboardobjgrp))) { + goto boardobjgrp_pmuinithandle_exit; + } + + /* Send the BOARDOBJGRP to the pmu via RM_PMU_BOARDOBJ_CMD_GRP. */ + status = pboardobjgrp->pmuset(g, pboardobjgrp); + if (status) { + nvgpu_err(g, "failed to send boardobg grp to PMU"); + } + +boardobjgrp_pmuinithandle_exit: + return status; +} + + +int boardobjgrp_pmuhdrdatainit_super(struct gk20a *g, struct boardobjgrp + *pboardobjgrp, struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, + struct boardobjgrpmask *mask) +{ + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + if (pboardobjgrppmu == NULL) { + return -EINVAL; + } + pboardobjgrppmu->type = pboardobjgrp->type; + pboardobjgrppmu->class_id = pboardobjgrp->classid; + pboardobjgrppmu->obj_slots = BOARDOBJGRP_PMU_SLOTS_GET(pboardobjgrp); + pboardobjgrppmu->flags = 0; + + nvgpu_log_info(g, " Done"); + return 0; +} + +static int boardobjgrp_pmudatainstget_stub(struct gk20a *g, + struct nv_pmu_boardobjgrp *boardobjgrppmu, + struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx) +{ + nvgpu_log_info(g, " "); + return -EINVAL; +} + + +static int boardobjgrp_pmustatusinstget_stub(struct gk20a *g, + void *pboardobjgrppmu, + struct nv_pmu_boardobj_query **ppBoardobjpmustatus, u8 idx) +{ + nvgpu_log_info(g, " "); + return -EINVAL; +} + +int boardobjgrp_pmudatainit_legacy(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + int status = 0; + struct boardobj *pboardobj = NULL; + struct nv_pmu_boardobj *ppmudata = NULL; + u8 index; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + if (pboardobjgrppmu == NULL) { + return -EINVAL; + } + + boardobjgrpe32hdrset((struct nv_pmu_boardobjgrp *)pboardobjgrppmu, + pboardobjgrp->objmask); + + BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK(32, index, pboardobjgrp->objmask) { + /* Obtain pointer to the current instance of the Object from the Group */ + pboardobj = pboardobjgrp->objgetbyidx(pboardobjgrp, index); + if (NULL == pboardobj) { + nvgpu_err(g, "could not get object instance"); + status = -EINVAL; + goto boardobjgrppmudatainit_legacy_done; + } + + status = pboardobjgrp->pmudatainstget(g, + (struct nv_pmu_boardobjgrp *)pboardobjgrppmu, + &ppmudata, index); + if (status) { + nvgpu_err(g, "could not get object instance"); + goto boardobjgrppmudatainit_legacy_done; + } + + /* Initialize the PMU Data */ + status = pboardobj->pmudatainit(g, pboardobj, ppmudata); + if (status) { + nvgpu_err(g, + "could not parse pmu for device %d", index); + goto boardobjgrppmudatainit_legacy_done; + } + } + BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK_END + +boardobjgrppmudatainit_legacy_done: + nvgpu_log_info(g, " Done"); + return status; +} + +int boardobjgrp_pmudatainit_super(struct gk20a *g, struct boardobjgrp + *pboardobjgrp, struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + int status = 0; + struct boardobj *pboardobj = NULL; + struct nv_pmu_boardobj *ppmudata = NULL; + u8 index; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + if (pboardobjgrppmu == NULL) { + return -EINVAL; + } + + /* Initialize the PMU HDR data.*/ + status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, pboardobjgrppmu, + pboardobjgrp->mask); + if (status) { + nvgpu_err(g, "unable to init boardobjgrp pmuhdr data"); + goto boardobjgrppmudatainit_super_done; + } + + BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) { + status = pboardobjgrp->pmudatainstget(g, + (struct nv_pmu_boardobjgrp *)pboardobjgrppmu, + &ppmudata, index); + if (status) { + nvgpu_err(g, "could not get object instance"); + goto boardobjgrppmudatainit_super_done; + } + + /* Initialize the PMU Data and send to PMU */ + status = pboardobj->pmudatainit(g, pboardobj, ppmudata); + if (status) { + nvgpu_err(g, + "could not parse pmu for device %d", index); + goto boardobjgrppmudatainit_super_done; + } + } + +boardobjgrppmudatainit_super_done: + nvgpu_log_info(g, " Done"); + return status; +} + +static int check_boardobjgrp_param(struct gk20a *g, + struct boardobjgrp *pboardobjgrp) +{ + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + if (pboardobjgrp->pmu.unitid == BOARDOBJGRP_UNIT_ID_INVALID) { + return -EINVAL; + } + + if (pboardobjgrp->pmu.classid == BOARDOBJGRP_GRP_CLASS_ID_INVALID) { + return -EINVAL; + } + + /* If no objects in the group, return early */ + if (BOARDOBJGRP_IS_EMPTY(pboardobjgrp)) { + return -EINVAL; + } + + return 0; +} + +int boardobjgrp_pmuset_impl(struct gk20a *g, struct boardobjgrp *pboardobjgrp) +{ + int status = 0; + struct boardobjgrp_pmu_cmd *pcmd = + (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.set); + + nvgpu_log_info(g, " "); + + if (check_boardobjgrp_param(g, pboardobjgrp)) { + return -EINVAL; + } + + if (pboardobjgrp->pmu.set.id == BOARDOBJGRP_GRP_CMD_ID_INVALID) { + return -EINVAL; + } + + if ((pcmd->hdrsize == 0) || + (pcmd->entrysize == 0) || + (pcmd->buf == NULL)) { + return -EINVAL; + } + + /* Initialize PMU buffer with BOARDOBJGRP data. */ + memset(pcmd->buf, 0x0, pcmd->fbsize); + status = pboardobjgrp->pmudatainit(g, pboardobjgrp, + pcmd->buf); + if (status) { + nvgpu_err(g, "could not parse pmu data"); + goto boardobjgrp_pmuset_exit; + } + + /* + * Reset the boolean that indicates set status for most recent + * instance of BOARDOBJGRP. + */ + pboardobjgrp->pmu.bset = false; + + /* + * alloc mem in vidmem & copy constructed pmu boardobjgrp data from + * sysmem to vidmem + */ + if (pcmd->surf.vidmem_desc.size == 0) { + nvgpu_pmu_vidmem_surface_alloc(g, &pcmd->surf.vidmem_desc, + pcmd->fbsize); + } + nvgpu_mem_wr_n(g, &pcmd->surf.vidmem_desc, 0, pcmd->buf, pcmd->fbsize); + + /* Send the SET PMU CMD to the PMU */ + status = boardobjgrp_pmucmdsend(g, pboardobjgrp, + pcmd); + if (status) { + nvgpu_err(g, "could not send SET CMD to PMU"); + goto boardobjgrp_pmuset_exit; + } + + pboardobjgrp->pmu.bset = true; + +boardobjgrp_pmuset_exit: + return status; +} + +int boardobjgrp_pmuset_impl_v1(struct gk20a *g, + struct boardobjgrp *pboardobjgrp) +{ + struct nvgpu_pmu *pmu = &g->pmu; + int status = 0; + struct boardobjgrp_pmu_cmd *pcmd = + (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.set); + + nvgpu_log_info(g, " "); + + if (check_boardobjgrp_param(g, pboardobjgrp)) { + return -EINVAL; + } + + if ((pcmd->buf == NULL) && + (pboardobjgrp->pmu.rpc_func_id == + BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID)) { + return -EINVAL; + } + + /* Initialize PMU buffer with BOARDOBJGRP data. */ + memset(pcmd->buf, 0x0, pcmd->fbsize); + status = pboardobjgrp->pmudatainit(g, pboardobjgrp, + pcmd->buf); + if (status) { + nvgpu_err(g, "could not parse pmu data"); + goto boardobjgrp_pmuset_exit; + } + + /* + * Reset the boolean that indicates set status + * for most recent instance of BOARDOBJGRP. + */ + pboardobjgrp->pmu.bset = false; + + /* + * copy constructed pmu boardobjgrp data from + * sysmem to pmu super surface present in FB + */ + nvgpu_mem_wr_n(g, &pmu->super_surface_buf, + pcmd->super_surface_offset, pcmd->buf, + pcmd->fbsize); + + /* Send the SET PMU CMD to the PMU using RPC*/ + status = boardobjgrp_pmucmdsend_rpc(g, pboardobjgrp, + pcmd, false); + if (status) { + nvgpu_err(g, "could not send SET CMD to PMU"); + goto boardobjgrp_pmuset_exit; + } + + pboardobjgrp->pmu.bset = true; + +boardobjgrp_pmuset_exit: + return status; +} + +int +boardobjgrp_pmugetstatus_impl(struct gk20a *g, struct boardobjgrp *pboardobjgrp, + struct boardobjgrpmask *mask) +{ + int status = 0; + struct boardobjgrp_pmu_cmd *pcmd = + (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.getstatus); + struct boardobjgrp_pmu_cmd *pset = + (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.set); + + nvgpu_log_info(g, " "); + + if (check_boardobjgrp_param(g, pboardobjgrp)) { + return -EINVAL; + } + + if (pset->id == BOARDOBJGRP_GRP_CMD_ID_INVALID) { + return -EINVAL; + } + + if ((pcmd->hdrsize == 0) || + (pcmd->entrysize == 0) || + (pcmd->buf == NULL)) { + return -EINVAL; + } + + /* + * Can only GET_STATUS if the BOARDOBJGRP has been previously SET to the + * PMU + */ + if (!pboardobjgrp->pmu.bset) { + return -EINVAL; + } + + /* + * alloc mem in vidmem & copy constructed pmu boardobjgrp data from + * sysmem to vidmem + */ + if (pcmd->surf.vidmem_desc.size == 0) { + nvgpu_pmu_vidmem_surface_alloc(g, &pcmd->surf.vidmem_desc, + pcmd->fbsize); + } + + /* + * Initialize PMU buffer with the mask of BOARDOBJGRPs for which to + * retrieve status + */ + + memset(pcmd->buf, 0x0, pcmd->fbsize); + status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, + pcmd->buf, mask); + if (status) { + nvgpu_err(g, "could not init PMU HDR data"); + goto boardobjgrp_pmugetstatus_exit; + } + + nvgpu_mem_wr_n(g, &pcmd->surf.vidmem_desc, 0, pset->buf, pset->hdrsize); + /* Send the GET_STATUS PMU CMD to the PMU */ + status = boardobjgrp_pmucmdsend(g, pboardobjgrp, + &pboardobjgrp->pmu.getstatus); + if (status) { + nvgpu_err(g, "could not send GET_STATUS cmd to PMU"); + goto boardobjgrp_pmugetstatus_exit; + } + + /*copy the data back to sysmem buffer that belongs to command*/ + nvgpu_mem_rd_n(g, &pcmd->surf.vidmem_desc, 0, pcmd->buf, pcmd->fbsize); + +boardobjgrp_pmugetstatus_exit: + return status; +} + +int +boardobjgrp_pmugetstatus_impl_v1(struct gk20a *g, struct boardobjgrp *pboardobjgrp, + struct boardobjgrpmask *mask) +{ + struct nvgpu_pmu *pmu = &g->pmu; + int status = 0; + struct boardobjgrp_pmu_cmd *pcmd = + (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.getstatus); + + nvgpu_log_info(g, " "); + + if (check_boardobjgrp_param(g, pboardobjgrp)) { + return -EINVAL; + } + + if ((pcmd->buf == NULL) && + (pboardobjgrp->pmu.rpc_func_id == + BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID)) { + return -EINVAL; + } + + /* + * Can only GET_STATUS if the BOARDOBJGRP has been + * previously SET to the PMU + */ + if (!pboardobjgrp->pmu.bset) { + return -EINVAL; + } + + /* + * Initialize PMU buffer with the mask of + * BOARDOBJGRPs for which to retrieve status + */ + memset(pcmd->buf, 0x0, pcmd->fbsize); + status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, + pcmd->buf, mask); + if (status) { + nvgpu_err(g, "could not init PMU HDR data"); + goto boardobjgrp_pmugetstatus_exit; + } + + /* + * copy constructed pmu boardobjgrp data from + * sysmem to pmu super surface present in FB + */ + nvgpu_mem_wr_n(g, &pmu->super_surface_buf, pcmd->super_surface_offset, + pcmd->buf, pcmd->fbsize); + /* Send the GET_STATUS PMU CMD to the PMU */ + status = boardobjgrp_pmucmdsend_rpc(g, pboardobjgrp, + pcmd, true); + if (status) { + nvgpu_err(g, "could not send GET_STATUS cmd to PMU"); + goto boardobjgrp_pmugetstatus_exit; + } + + /*copy the data back to sysmem buffer that belongs to command*/ + nvgpu_mem_rd_n(g, &pmu->super_surface_buf,pcmd->super_surface_offset, + pcmd->buf, pcmd->fbsize); + +boardobjgrp_pmugetstatus_exit: + return status; +} + +static int +boardobjgrp_objinsert_final(struct boardobjgrp *pboardobjgrp, + struct boardobj *pboardobj, u8 index) +{ + struct gk20a *g = pboardobjgrp->g; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (pboardobj == NULL) { + return -EINVAL; + } + + if (index > pboardobjgrp->objslots) { + return -EINVAL; + } + + if (pboardobjgrp->ppobjects[index] != NULL) { + return -EINVAL; + } + + /* + * Check that this BOARDOBJ has not already been added to a + * BOARDOBJGRP + */ + if (pboardobj->idx != CTRL_BOARDOBJ_IDX_INVALID) { + return -EINVAL; + } + + pboardobjgrp->ppobjects[index] = pboardobj; + pboardobjgrp->objmaxidx = (u8)(BOARDOBJGRP_IS_EMPTY(pboardobjgrp) ? + index : max(pboardobjgrp->objmaxidx, index)); + pboardobj->idx = index; + + pboardobjgrp->objmask |= BIT(index); + + nvgpu_log_info(g, " Done"); + + return boardobjgrpmask_bitset(pboardobjgrp->mask, index); +} + +static struct boardobj *boardobjgrp_objgetbyidx_final( + struct boardobjgrp *pboardobjgrp, u8 index) +{ + if (!boardobjgrp_idxisvalid(pboardobjgrp, index)) { + return NULL; + } + return pboardobjgrp->ppobjects[index]; +} + +static struct boardobj *boardobjgrp_objgetnext_final( + struct boardobjgrp *pboardobjgrp, u8 *currentindex, + struct boardobjgrpmask *mask) +{ + struct boardobj *pboardobjnext = NULL; + u8 objmaxidx; + u8 index; + + if (currentindex == NULL) { + return NULL; + } + + if (pboardobjgrp == NULL) { + return NULL; + } + + /* Search from next element unless first object was requested */ + index = (*currentindex != CTRL_BOARDOBJ_IDX_INVALID) ? + (*currentindex + 1) : 0; + + /* For the cases below in which we have to return NULL */ + *currentindex = CTRL_BOARDOBJ_IDX_INVALID; + + + /* Validate provided mask */ + if (mask != NULL) { + if (!(boardobjgrpmask_sizeeq(pboardobjgrp->mask, mask))) { + return NULL; + } + } + + objmaxidx = pboardobjgrp->objmaxidx; + + if (objmaxidx != CTRL_BOARDOBJ_IDX_INVALID) { + for (; index <= objmaxidx; index++) { + pboardobjnext = pboardobjgrp->ppobjects[index]; + if (pboardobjnext != NULL) { + /* Filter results using client provided mask.*/ + if (mask != NULL) { + if (!boardobjgrpmask_bitget(mask, + index)) { + pboardobjnext = NULL; + continue; + } + } + *currentindex = index; + break; + } + } + } + + return pboardobjnext; +} + +static int boardobjgrp_objremoveanddestroy_final( + struct boardobjgrp *pboardobjgrp, + u8 index) +{ + int status = 0; + int stat; + struct gk20a *g = pboardobjgrp->g; + + nvgpu_log_info(g, " "); + + if (!boardobjgrp_idxisvalid(pboardobjgrp, index)) { + return -EINVAL; + } + + if (pboardobjgrp->objmaxidx == CTRL_BOARDOBJ_IDX_INVALID) { + return -EINVAL; + } + + status = pboardobjgrp->ppobjects[index]->destruct( + pboardobjgrp->ppobjects[index]); + + pboardobjgrp->ppobjects[index] = NULL; + + pboardobjgrp->objmask &= ~BIT(index); + + stat = boardobjgrpmask_bitclr(pboardobjgrp->mask, index); + if (stat) { + if (status == 0) { + status = stat; + } + } + + /* objmaxidx requires update only if that very object was removed */ + if (pboardobjgrp->objmaxidx == index) { + pboardobjgrp->objmaxidx = + boardobjgrpmask_bitidxhighest(pboardobjgrp->mask); + } + + return status; +} + +void boardobjgrpe32hdrset(struct nv_pmu_boardobjgrp *hdr, u32 objmask) +{ + u32 slots = objmask; + + HIGHESTBITIDX_32(slots); + slots++; + + hdr->super.type = CTRL_BOARDOBJGRP_TYPE_E32; + hdr->super.class_id = 0; + hdr->super.obj_slots = (u8)slots; + hdr->obj_mask = objmask; +} + +static void boardobjgrp_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg, + void *param, u32 handle, u32 status) +{ + struct nv_pmu_boardobj_msg_grp *pgrpmsg; + struct boardobjgrp_pmucmdhandler_params *phandlerparams = + (struct boardobjgrp_pmucmdhandler_params *)param; + struct boardobjgrp *pboardobjgrp = phandlerparams->pboardobjgrp; + struct boardobjgrp_pmu_cmd *pgrpcmd = phandlerparams->pcmd; + + nvgpu_log_info(g, " "); + + pgrpmsg = &msg->msg.boardobj.grp; + + if (pgrpmsg->class_id != pboardobjgrp->pmu.classid) { + nvgpu_err(g, + "Unrecognized GRP type: unit %x class id=0x%02x cmd id %x", + msg->hdr.unit_id, pboardobjgrp->pmu.classid, + pgrpcmd->id); + return; + } + + if (msg->msg.boardobj.msg_type != pgrpcmd->msgid) { + nvgpu_err(g, + "unsupported msg for unit %x class %x cmd id %x msg %x", + msg->hdr.unit_id, pboardobjgrp->pmu.classid, + pgrpcmd->id, msg->msg.boardobj.msg_type); + return; + } + + if (msg->msg.boardobj.grp_set.flcn_status != 0) { + nvgpu_err(g, + "cmd abort for unit %x class %x cmd id %x status %x", + msg->hdr.unit_id, pboardobjgrp->pmu.classid, + pgrpcmd->id, + msg->msg.boardobj.grp_set.flcn_status); + return; + } + + phandlerparams->success = pgrpmsg->b_success ? 1 : 0; + + if (!pgrpmsg->b_success) { + nvgpu_err(g, + "failed GRPCMD: msgtype=0x%x, classid=0x%x, cmd id %x", + pgrpmsg->msg_type, pgrpmsg->class_id, + pgrpcmd->id); + return; + } +} + +static int boardobjgrp_pmucmdsend(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd) +{ + struct boardobjgrp_pmucmdhandler_params handlerparams; + struct pmu_payload payload; + struct nv_pmu_boardobj_cmd_grp *pgrpcmd; + struct pmu_cmd cmd; + u32 seqdesc; + int status = 0; + + nvgpu_log_info(g, " "); + + memset(&payload, 0, sizeof(payload)); + memset(&handlerparams, 0, sizeof(handlerparams)); + memset(&cmd, 0, sizeof(struct pmu_cmd)); + cmd.hdr.unit_id = pboardobjgrp->pmu.unitid; + cmd.hdr.size = sizeof(struct nv_pmu_boardobj_cmd_grp) + + sizeof(struct pmu_hdr); + + pgrpcmd = &cmd.cmd.boardobj.grp; + pgrpcmd->cmd_type = pcmd->id; + pgrpcmd->class_id = pboardobjgrp->pmu.classid; + pgrpcmd->grp.hdr_size = pcmd->hdrsize; + pgrpcmd->grp.entry_size = pcmd->entrysize; + + /* + * copy vidmem information to boardobj_cmd_grp + */ + nvgpu_pmu_surface_describe(g, &pcmd->surf.vidmem_desc, + &pgrpcmd->grp.fb); + + /* + * PMU reads command from sysmem so assigned + * "payload.in.buf = pcmd->buf" + * but PMU access pmu boardobjgrp data from vidmem copied above + */ + payload.in.buf = pcmd->buf; + payload.in.size = max(pcmd->hdrsize, pcmd->entrysize); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = offsetof(struct nv_pmu_boardobj_cmd_grp, grp); + + /* Setup the handler params to communicate back results.*/ + handlerparams.pboardobjgrp = pboardobjgrp; + handlerparams.pcmd = pcmd; + handlerparams.success = 0; + + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + boardobjgrp_pmucmdhandler, + (void *)&handlerparams, + &seqdesc, ~0); + if (status) { + nvgpu_err(g, + "unable to post boardobj grp cmd for unit %x cmd id %x", + cmd.hdr.unit_id, pcmd->id); + goto boardobjgrp_pmucmdsend_exit; + } + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handlerparams.success, 1); + if (handlerparams.success == 0) { + nvgpu_err(g, "could not process cmd"); + status = -ETIMEDOUT; + goto boardobjgrp_pmucmdsend_exit; + } + +boardobjgrp_pmucmdsend_exit: + return status; +} + +static int boardobjgrp_pmucmdsend_rpc(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd, + bool copy_out) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct nv_pmu_rpc_struct_board_obj_grp_cmd rpc; + int status = 0; + + nvgpu_log_fn(g, " "); + + memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_board_obj_grp_cmd)); + + rpc.class_id = pboardobjgrp->pmu.classid; + rpc.command_id = copy_out ? + NV_PMU_BOARDOBJGRP_CMD_GET_STATUS : + NV_PMU_BOARDOBJGRP_CMD_SET; + + rpc.hdr.unit_id = pboardobjgrp->pmu.unitid; + rpc.hdr.function = pboardobjgrp->pmu.rpc_func_id; + rpc.hdr.flags = 0x0; + + status = nvgpu_pmu_rpc_execute(pmu, &(rpc.hdr), + (sizeof(rpc) - sizeof(rpc.scratch)), + pcmd->dmem_buffer_size, + NULL, NULL, copy_out); + + if (status) { + nvgpu_err(g, "Failed to execute RPC, status=0x%x", status); + } + + return status; +} diff --git a/include/boardobj/boardobjgrp.h b/include/boardobj/boardobjgrp.h new file mode 100644 index 0000000..cd13b85 --- /dev/null +++ b/include/boardobj/boardobjgrp.h @@ -0,0 +1,441 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_BOARDOBJGRP_H +#define NVGPU_BOARDOBJGRP_H + +struct boardobjgrp; +struct gk20a; +struct nvgpu_list_node; +struct pmu_surface; + + +/* ------------------------ Includes ----------------------------------------*/ +#include "ctrl/ctrlboardobj.h" +#include "boardobj.h" +#include "boardobjgrpmask.h" +#include +#include + +/* +* Board Object Group destructor. +* +*/ +typedef int boardobjgrp_destruct(struct boardobjgrp *pboardobjgrp); + +/* +* Inserts a previously constructed Board Object into a Board Object Group for +* tracking. Objects are inserted in the array based on the given index. +*/ +typedef int boardobjgrp_objinsert(struct boardobjgrp *pboardobjgrp, + struct boardobj *pboardobj, u8 index); + +/* +* Retrieves a Board Object from a Board Object Group using the group's index. +* +*/ +typedef struct boardobj *boardobjgrp_objgetbyidx( + struct boardobjgrp *pBobrdobjgrp, u8 index); + +/* +* Retrieve Board Object immediately following one pointed by @ref pcurrentindex +* filtered out by the provided mask. If (pMask == NULL) => no filtering. +*/ +typedef struct boardobj *boardobjgrp_objgetnext( + struct boardobjgrp *pboardobjgrp, + u8 *currentindex, struct boardobjgrpmask *mask); + +/* +* Board Object Group Remover and destructor. This is used to remove and +* destruct specific entry from the Board Object Group. +*/ +typedef int boardobjgrp_objremoveanddestroy(struct boardobjgrp *pboardobjgrp, + u8 index); + +/* +* BOARDOBJGRP handler for PMU_UNIT_INIT. Calls the PMU_UNIT_INIT handlers +* for the constructed PMU CMDs, and then sets the object via the +* PMU_BOARDOBJ_CMD_GRP interface (if constructed). +*/ +typedef int boardobjgrp_pmuinithandle(struct gk20a *g, + struct boardobjgrp *pboardobjGrp); + +/* +* Fills out the appropriate the PMU_BOARDOBJGRP_ driver<->PMU description +* header structure, more specifically a mask of BOARDOBJs. +*/ +typedef int boardobjgrp_pmuhdrdatainit(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, + struct boardobjgrpmask *mask); + +/* +* Fills out the appropriate the PMU_BOARDOBJGRP_ driver->PMU description +* structure, describing the BOARDOBJGRP and all of its BOARDOBJs to the PMU. +*/ +typedef int boardobjgrp_pmudatainit(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu); + +/* +* Sends a BOARDOBJGRP to the PMU via the PMU_BOARDOBJ_CMD_GRP interface. +* This interface leverages @ref boardobjgrp_pmudatainit to populate the +* structure. +*/ +typedef int boardobjgrp_pmuset(struct gk20a *g, + struct boardobjgrp *pboardobjgrp); + +/* +* Gets the dynamic status of the PMU BOARDOBJGRP via the +* PMU_BOARDOBJ_CMD_GRP GET_STATUS interface. +*/ +typedef int boardobjgrp_pmugetstatus(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrpmask *mask); + +typedef int boardobjgrp_pmudatainstget(struct gk20a *g, + struct nv_pmu_boardobjgrp *boardobjgrppmu, + struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx); + +typedef int boardobjgrp_pmustatusinstget(struct gk20a *g, void *pboardobjgrppmu, + struct nv_pmu_boardobj_query **ppBoardobjpmustatus, u8 idx); + +/* +* Structure describing an PMU CMD for interacting with the representaition +* of this BOARDOBJGRP within the PMU. +*/ +struct boardobjgrp_pmu_cmd { + u8 id; + u8 msgid; + u8 hdrsize; + u8 entrysize; + u16 dmem_buffer_size; + u32 super_surface_offset; + u32 fbsize; + struct nv_pmu_boardobjgrp_super *buf; + struct pmu_surface surf; +}; + +/* +* Structure of state describing how to communicate with representation of this +* BOARDOBJGRP in the PMU. +*/ +struct boardobjgrp_pmu { + u8 unitid; + u8 classid; + bool bset; + u8 rpc_func_id; + struct boardobjgrp_pmu_cmd set; + struct boardobjgrp_pmu_cmd getstatus; +}; + +/* +* Function by which a class which implements BOARDOBJGRP can construct a PMU +* CMD. This provides the various information describing the PMU CMD including +* the CMD and MSG ID and the size of the various sturctures in the payload. +*/ +typedef int boardobjgrp_pmucmd_construct(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid, + u16 hdrsize, u16 entrysize, u16 fbsize, u32 ss_offset, u8 rpc_func_id); + +/* +* Destroys BOARDOBJGRP PMU SW state. CMD. +*/ +typedef int boardobjgrp_pmucmd_destroy(struct gk20a *g, + struct boardobjgrp_pmu_cmd *cmd); + +/* +* init handler for the BOARDOBJGRP PMU CMD. Allocates and maps the +* PMU CMD payload within both the PMU and driver so that it can be referenced +* at run-time. +*/ +typedef int boardobjgrp_pmucmd_pmuinithandle(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd); + +/* +* Base Class Group for all physical or logical device on the PCB. +* Contains fields common to all devices on the board. Specific types of +* devices groups may extend this object adding any details specific to that +* device group or device-type. +*/ +struct boardobjgrp { + struct gk20a *g; + u32 objmask; + bool bconstructed; + u8 type; + u8 classid; + struct boardobj **ppobjects; + struct boardobjgrpmask *mask; + u8 objslots; + u8 objmaxidx; + struct boardobjgrp_pmu pmu; + + /* Basic interfaces */ + boardobjgrp_destruct *destruct; + boardobjgrp_objinsert *objinsert; + boardobjgrp_objgetbyidx *objgetbyidx; + boardobjgrp_objgetnext *objgetnext; + boardobjgrp_objremoveanddestroy *objremoveanddestroy; + + /* PMU interfaces */ + boardobjgrp_pmuinithandle *pmuinithandle; + boardobjgrp_pmuhdrdatainit *pmuhdrdatainit; + boardobjgrp_pmudatainit *pmudatainit; + boardobjgrp_pmuset *pmuset; + boardobjgrp_pmugetstatus *pmugetstatus; + + boardobjgrp_pmudatainstget *pmudatainstget; + boardobjgrp_pmustatusinstget *pmustatusinstget; + struct nvgpu_list_node node; +}; + +/* +* Macro test whether a specified index into the BOARDOBJGRP is valid. +* +*/ +#define boardobjgrp_idxisvalid(_pboardobjgrp, _idx) \ + (((_idx) < (_pboardobjgrp)->objslots) && \ + ((_pboardobjgrp)->ppobjects[(_idx)] != NULL)) + +/* +* Macro test whether a specified BOARDOBJGRP is empty. +*/ +#define BOARDOBJGRP_IS_EMPTY(_pboardobjgrp) \ + ((!((_pboardobjgrp)->bconstructed)) || \ + ((_pboardobjgrp)->objmaxidx == CTRL_BOARDOBJ_IDX_INVALID)) + +#define boardobjgrp_objinsert(_pboardobjgrp, _pboardobj, _idx) \ + ((_pboardobjgrp)->objinsert((_pboardobjgrp), (_pboardobj), (_idx))) + +/* +* Helper macro to determine the "next" open/empty index after all allocated +* objects. This is intended to be used to find the index at which objects can +* be inserted contiguously (i.e. w/o fear of colliding with existing objects). +*/ +#define BOARDOBJGRP_NEXT_EMPTY_IDX(_pboardobjgrp) \ + ((CTRL_BOARDOBJ_IDX_INVALID == (_pboardobjgrp)->objmaxidx) ? 0U : \ + ((((_pboardobjgrp)->objmaxidx + 1U) >= (_pboardobjgrp)->objslots) ? \ + (u8)CTRL_BOARDOBJ_IDX_INVALID : (u8)((_pboardobjgrp)->objmaxidx + 1U))) + +/* +* Helper macro to determine the number of @ref BOARDOBJ pointers +* that are required to be allocated in PMU @ref ppObjects. +*/ +#define BOARDOBJGRP_PMU_SLOTS_GET(_pboardobjgrp) \ + ((CTRL_BOARDOBJ_IDX_INVALID == (_pboardobjgrp)->objmaxidx) ? 0U : \ + (u8)((_pboardobjgrp)->objmaxidx + 1U)) + +#define BOARDOBJGRP_OBJ_GET_BY_IDX(_pboardobjgrp, _idx) \ + ((_pboardobjgrp)->objgetbyidx((_pboardobjgrp), (_idx))) + +/* +* macro to look-up next object while tolerating error if +* Board Object Group is not constructed. +*/ + +#define boardobjgrpobjgetnextsafe(_pgrp, _pindex, _pmask) \ + ((_pgrp)->bconstructed ? \ + (_pgrp)->objgetnext((_pgrp), (_pindex), (_pmask)) : NULL) + +/* +* Used to traverse all Board Objects stored within @ref _pgrp in the increasing +* index order. +* If @ref _pmask is provided only objects specified by the mask are traversed. +*/ +#define BOARDOBJGRP_ITERATOR(_pgrp, _ptype, _pobj, _index, _pmask) \ + for (_index = CTRL_BOARDOBJ_IDX_INVALID, \ + _pobj = (_ptype)boardobjgrpobjgetnextsafe((_pgrp), &_index, (_pmask));\ + _pobj != NULL; \ + _pobj = (_ptype)boardobjgrpobjgetnextsafe((_pgrp), &_index, (_pmask))) +#define BOARDOBJGRP_FOR_EACH(_pgrp, _ptype, _pobj, _index) \ + BOARDOBJGRP_ITERATOR(_pgrp, _ptype, _pobj, _index, NULL) + +#define BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK(mask_width, index, mask) \ +{ \ + u##mask_width lcl_msk = (u##mask_width)(mask); \ + for (index = 0; lcl_msk != 0U; index++, lcl_msk >>= 1U) { \ + if (((u##mask_width)((u64)1) & lcl_msk) == 0U) { \ + continue; \ + } + +#define BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK_END \ + } \ +} + + +/*! +* Invalid UNIT_ID. Used to indicate that the implementing class has not set +* @ref BOARDOBJGRP::unitId and, thus, certain BOARDOBJGRP PMU interfaces are +* not supported. +*/ +#define BOARDOBJGRP_UNIT_ID_INVALID 255U + +/*! +* Invalid UNIT_ID. Used to indicate that the implementing class has not set +* @ref BOARDOBJGRP::grpType and, thus, certain BOARDOBJGRP PMU interfaces are +* not supported. +*/ +#define BOARDOBJGRP_GRP_CLASS_ID_INVALID 255U + +/*! +* Invalid UNIT_ID. Used to indicate that the implementing class has not set +* @ref BOARDOBJGRP::grpSetCmdId and, thus, certain BOARDOBJGRP PMU interfaces +* are not supported. +*/ +#define BOARDOBJGRP_GRP_CMD_ID_INVALID 255U +#define BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID 255U + +/*! +* Helper macro to construct a BOARDOBJGRP's PMU SW state. +* +* @param[out] pboardobjgrp BOARDOBJGRP pointer +* @param[in] _eng +* Implementing engine/unit which manages the BOARDOBJGRP. +* @param[in] _class +* Class ID of BOARDOBJGRP. +*/ +#define BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, _ENG, _CLASS) \ +do { \ + (pboardobjgrp)->pmu.unitid = PMU_UNIT_##_ENG; \ + (pboardobjgrp)->pmu.classid = \ + NV_PMU_##_ENG##_BOARDOBJGRP_CLASS_ID_##_CLASS; \ +} while (0) + +#define BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, eng, ENG, \ + class, CLASS) \ + g->ops.pmu_ver.boardobj.boardobjgrp_pmucmd_construct_impl( \ + g, /* pgpu */ \ + pboardobjgrp, /* pboardobjgrp */ \ + &((pboardobjgrp)->pmu.set), /* pcmd */ \ + NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_SET, /* id */ \ + NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_SET, /* msgid */ \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_set_header_aligned), \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_set_union_aligned), \ + (u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_set), \ + (u32)offsetof(struct nv_pmu_super_surface, eng.class##_grp_set), \ + NV_PMU_RPC_ID_##ENG##_BOARD_OBJ_GRP_CMD) + +#define BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, pboardobjgrp, \ + eng, ENG, class, CLASS) \ + g->ops.pmu_ver.boardobj.boardobjgrp_pmucmd_construct_impl( \ + g, /* pGpu */ \ + pboardobjgrp, /* pBoardObjGrp */ \ + &((pboardobjgrp)->pmu.getstatus), /* pCmd */ \ + NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_GET_STATUS, /* id */ \ + NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_GET_STATUS, /* msgid */ \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_get_status_header_aligned), \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_get_status_union_aligned), \ + (u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_get_status), \ + (u32)offsetof(struct nv_pmu_super_surface, eng.class##_grp_get_status), \ + NV_PMU_RPC_ID_##ENG##_BOARD_OBJ_GRP_CMD) + +/* ------------------------ Function Prototypes ----------------------------- */ +/* Constructor and destructor */ +int boardobjgrp_construct_super(struct gk20a *g, + struct boardobjgrp *pboardobjgrp); +boardobjgrp_destruct boardobjgrp_destruct_impl; +boardobjgrp_destruct boardobjgrp_destruct_super; + +/* PMU_CMD interfaces */ +boardobjgrp_pmucmd_construct boardobjgrp_pmucmd_construct_impl; +boardobjgrp_pmucmd_destroy boardobjgrp_pmucmd_destroy_impl; +boardobjgrp_pmucmd_pmuinithandle boardobjgrp_pmucmd_pmuinithandle_impl; + +boardobjgrp_pmucmd_construct boardobjgrp_pmucmd_construct_impl_v1; + +/* BOARDOBJGRP interfaces */ +boardobjgrp_pmuinithandle boardobjgrp_pmuinithandle_impl; +boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_super; +boardobjgrp_pmudatainit boardobjgrp_pmudatainit_super; + +boardobjgrp_pmudatainit boardobjgrp_pmudatainit_legacy; +boardobjgrp_pmuset boardobjgrp_pmuset_impl; +boardobjgrp_pmugetstatus boardobjgrp_pmugetstatus_impl; +boardobjgrp_pmuset boardobjgrp_pmuset_impl_v1; +boardobjgrp_pmugetstatus boardobjgrp_pmugetstatus_impl_v1; + +void boardobjgrpe32hdrset(struct nv_pmu_boardobjgrp *hdr, u32 objmask); + +#define HIGHESTBITIDX_32(n32) \ +{ \ + u32 count = 0U; \ + while (n32 >>= 1U) { \ + count++; \ + } \ + n32 = count; \ +} + +#define LOWESTBIT(x) ((x) & (((x)-1U) ^ (x))) + +#define HIGHESTBIT(n32) \ +{ \ + HIGHESTBITIDX_32(n32); \ + n32 = NVBIT(n32); \ +} + +#define ONEBITSET(x) ((x) && (((x) & ((x)-1U)) == 0U)) + +#define LOWESTBITIDX_32(n32) \ +{ \ + n32 = LOWESTBIT(n32); \ + IDX_32(n32); \ +} + +#define NUMSETBITS_32(n32) \ +{ \ + n32 = n32 - ((n32 >> 1U) & 0x55555555U); \ + n32 = (n32 & 0x33333333U) + ((n32 >> 2U) & 0x33333333U); \ + n32 = (((n32 + (n32 >> 4U)) & 0x0F0F0F0FU) * 0x01010101U) >> 24U; \ +} + +#define IDX_32(n32) \ +{ \ + u32 idx = 0U; \ + if ((n32) & 0xFFFF0000U) \ + idx += 16U; \ + if ((n32) & 0xFF00FF00U) \ + idx += 8U; \ + if ((n32) & 0xF0F0F0F0U) \ + idx += 4U; \ + if ((n32) & 0xCCCCCCCCU) \ + idx += 2U; \ + if ((n32) & 0xAAAAAAAAU) \ + idx += 1U; \ + (n32) = idx; \ +} + +static inline struct boardobjgrp * +boardobjgrp_from_node(struct nvgpu_list_node *node) +{ + return (struct boardobjgrp *) + ((uintptr_t)node - offsetof(struct boardobjgrp, node)); +}; + +int is_boardobjgrp_pmucmd_id_valid_v0(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd); +int is_boardobjgrp_pmucmd_id_valid_v1(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd); +#endif /* NVGPU_BOARDOBJGRP_H */ diff --git a/include/boardobj/boardobjgrp_e255.c b/include/boardobj/boardobjgrp_e255.c new file mode 100644 index 0000000..63546a9 --- /dev/null +++ b/include/boardobj/boardobjgrp_e255.c @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "boardobj.h" +#include "boardobjgrp_e255.h" +#include "ctrl/ctrlboardobj.h" +#include "boardobjgrp.h" +#include "boardobjgrpmask.h" + +int boardobjgrpconstruct_e255(struct gk20a *g, + struct boardobjgrp_e255 *pboardobjgrp_e255) +{ + int status = 0; + u8 objslots; + + nvgpu_log_info(g, " "); + + objslots = 255; + status = boardobjgrpmask_e255_init(&pboardobjgrp_e255->mask, NULL); + if (status) { + goto boardobjgrpconstruct_e255_exit; + } + + pboardobjgrp_e255->super.type = CTRL_BOARDOBJGRP_TYPE_E255; + pboardobjgrp_e255->super.ppobjects = pboardobjgrp_e255->objects; + pboardobjgrp_e255->super.objslots = objslots; + pboardobjgrp_e255->super.mask = &(pboardobjgrp_e255->mask.super); + + status = boardobjgrp_construct_super(g, &pboardobjgrp_e255->super); + if (status) { + goto boardobjgrpconstruct_e255_exit; + } + + pboardobjgrp_e255->super.pmuhdrdatainit = + boardobjgrp_pmuhdrdatainit_e255; + +boardobjgrpconstruct_e255_exit: + return status; +} + +int boardobjgrp_pmuhdrdatainit_e255(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, + struct boardobjgrpmask *mask) +{ + struct nv_pmu_boardobjgrp_e255 *pgrpe255 = + (struct nv_pmu_boardobjgrp_e255 *)pboardobjgrppmu; + int status; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (pboardobjgrppmu == NULL) { + return -EINVAL; + } + + status = boardobjgrpmask_export(mask, + mask->bitcount, + &pgrpe255->obj_mask.super); + if (status) { + nvgpu_err(g, "e255 init:failed export grpmask"); + return status; + } + + return boardobjgrp_pmuhdrdatainit_super(g, + pboardobjgrp, pboardobjgrppmu, mask); +} diff --git a/include/boardobj/boardobjgrp_e255.h b/include/boardobj/boardobjgrp_e255.h new file mode 100644 index 0000000..bc40541 --- /dev/null +++ b/include/boardobj/boardobjgrp_e255.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_BOARDOBJGRP_E255_H +#define NVGPU_BOARDOBJGRP_E255_H + +#include "ctrl/ctrlboardobj.h" +#include "boardobj.h" +#include "boardobjgrpmask.h" +#include "boardobj/boardobjgrp.h" + +/* + * boardobjgrp_e255 is @ref BOARDOBJGRP child class allowing storage of up + * to 255 @ref BOARDOBJ object pointers with single static 255-bit mask denoting + * valid object pointers. + */ +struct boardobjgrp_e255 { + struct boardobjgrp super; + struct boardobj *objects[CTRL_BOARDOBJGRP_E255_MAX_OBJECTS]; + struct boardobjgrpmask_e255 mask; +}; + +#define boardobjgrp_pmudatainit_e255(g, pboardpbjgrp, pboardobjgrppmu) \ + boardobjgrp_pmudatainit_super(g, pboardpbjgrp, pboardobjgrppmu) + +/* Constructor and destructor */ +int boardobjgrpconstruct_e255(struct gk20a *g, + struct boardobjgrp_e255 *pboardobjgrp); +boardobjgrp_destruct boardobjgrpdestruct_e255; +boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_e255; + +#endif /* NVGPU_BOARDOBJGRP_E255_H */ diff --git a/include/boardobj/boardobjgrp_e32.c b/include/boardobj/boardobjgrp_e32.c new file mode 100644 index 0000000..d72e8cb --- /dev/null +++ b/include/boardobj/boardobjgrp_e32.c @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ +#include + +#include "boardobj.h" +#include "boardobjgrp.h" +#include "boardobjgrp_e32.h" +#include "ctrl/ctrlboardobj.h" +#include "boardobjgrpmask.h" + + +int boardobjgrpconstruct_e32(struct gk20a *g, + struct boardobjgrp_e32 *pboardobjgrp_e32) +{ + int status; + u8 objslots; + + nvgpu_log_info(g, " "); + objslots = 32; + + status = boardobjgrpmask_e32_init(&pboardobjgrp_e32->mask, NULL); + if (status) { + goto boardobjgrpconstruct_e32_exit; + } + + pboardobjgrp_e32->super.type = CTRL_BOARDOBJGRP_TYPE_E32; + pboardobjgrp_e32->super.ppobjects = pboardobjgrp_e32->objects; + pboardobjgrp_e32->super.objslots = objslots; + pboardobjgrp_e32->super.mask = &(pboardobjgrp_e32->mask.super); + + status = boardobjgrp_construct_super(g, &pboardobjgrp_e32->super); + if (status) { + goto boardobjgrpconstruct_e32_exit; + } + + pboardobjgrp_e32->super.pmuhdrdatainit = boardobjgrp_pmuhdrdatainit_e32; + +boardobjgrpconstruct_e32_exit: + return status; +} + +int boardobjgrp_pmuhdrdatainit_e32(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, + struct boardobjgrpmask *mask) +{ + struct nv_pmu_boardobjgrp_e32 *pgrpe32 = + (struct nv_pmu_boardobjgrp_e32 *)pboardobjgrppmu; + int status; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (pboardobjgrppmu == NULL) { + return -EINVAL; + } + status = boardobjgrpmask_export(mask, + mask->bitcount, + &pgrpe32->obj_mask.super); + if (status) { + nvgpu_err(g, "e32 init:failed export grpmask"); + return status; + } + + return boardobjgrp_pmuhdrdatainit_super(g, + pboardobjgrp, pboardobjgrppmu, mask); +} diff --git a/include/boardobj/boardobjgrp_e32.h b/include/boardobj/boardobjgrp_e32.h new file mode 100644 index 0000000..d4beb47 --- /dev/null +++ b/include/boardobj/boardobjgrp_e32.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_BOARDOBJGRP_E32_H +#define NVGPU_BOARDOBJGRP_E32_H + +#include "ctrl/ctrlboardobj.h" +#include "boardobj.h" +#include "boardobjgrp.h" +#include "boardobjgrpmask.h" +#include "boardobj/boardobjgrp.h" + +/* + * boardobjgrp_e32 is @ref BOARDOBJGRP child class allowing storage of up to 32 + * @ref BOARDOBJ object pointers with single static 32-bit mask denoting valid + * object pointers. + */ +struct boardobjgrp_e32 { + /* + * BOARDOBJGRP super-class. Must be first element of the structure. + */ + struct boardobjgrp super; + /* + * Statically allocated array of PBOARDOBJ-s + */ + struct boardobj *objects[CTRL_BOARDOBJGRP_E32_MAX_OBJECTS]; + + /* + * Statically allocated mask strcuture referenced by super::pMask. + */ + struct boardobjgrpmask_e32 mask; +}; + +/* + * Wrapper to the _SUPER implementation. Provided for the child classes which + * implement this interface. + */ +#define boardobjgrp_pmudatainit_e32(g, pboardpbjgrp, pboardobjgrppmu) \ + boardobjgrp_pmudatainit_super(g, pboardpbjgrp, pboardobjgrppmu) + +/* Constructor and destructor */ +int boardobjgrpconstruct_e32(struct gk20a *g, + struct boardobjgrp_e32 *pboardobjgrp); +boardobjgrp_destruct boardobjgrpdestruct_e32; +boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_e32; + +#endif /* NVGPU_BOARDOBJGRP_E32_H */ diff --git a/include/boardobj/boardobjgrpmask.c b/include/boardobj/boardobjgrpmask.c new file mode 100644 index 0000000..a1dcd6d --- /dev/null +++ b/include/boardobj/boardobjgrpmask.c @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include + +#include "boardobjgrp.h" +#include "ctrl/ctrlboardobj.h" + +/* +* Assures that unused bits (size .. (maskDataCount * 32 - 1)) are always zero. +*/ +#define BOARDOBJGRPMASK_NORMALIZE(_pmask) \ + ((_pmask)->data[(_pmask)->maskdatacount-1] &= (_pmask)->lastmaskfilter) + +u32 boardobjgrpmask_init(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask) +{ + if (mask == NULL) { + return -EINVAL; + } + if ((bitsize != CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) && + (bitsize != CTRL_BOARDOBJGRP_E255_MAX_OBJECTS)) { + return -EINVAL; + } + + mask->bitcount = bitsize; + mask->maskdatacount = CTRL_BOARDOBJGRP_MASK_DATA_SIZE(bitsize); + mask->lastmaskfilter = bitsize % + CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; + + mask->lastmaskfilter = (mask->lastmaskfilter == 0) ? + 0xFFFFFFFF : (u32)(BIT(mask->lastmaskfilter) - 1); + + return (extmask == NULL) ? + boardobjgrpmask_clr(mask) : + boardobjgrpmask_import(mask, bitsize, extmask); +} + +u32 boardobjgrpmask_import(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask) +{ + u8 index; + + if (mask == NULL) { + return -EINVAL; + } + if (extmask == NULL) { + return -EINVAL; + } + if (mask->bitcount != bitsize) { + return -EINVAL; + } + + for (index = 0; index < mask->maskdatacount; index++) { + mask->data[index] = extmask->data[index]; + } + + BOARDOBJGRPMASK_NORMALIZE(mask); + + return 0; +} + +u32 boardobjgrpmask_export(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask) +{ + u8 index; + + if (mask == NULL) { + return -EINVAL; + } + if (extmask == NULL) { + return -EINVAL; + } + if (mask->bitcount != bitsize) { + return -EINVAL; + } + + for (index = 0; index < mask->maskdatacount; index++) { + extmask->data[index] = mask->data[index]; + } + + return 0; +} + +u32 boardobjgrpmask_clr(struct boardobjgrpmask *mask) +{ + u8 index; + + if (mask == NULL) { + return -EINVAL; + } + for (index = 0; index < mask->maskdatacount; index++) { + mask->data[index] = 0; + } + + return 0; +} + +u32 boardobjgrpmask_set(struct boardobjgrpmask *mask) +{ + u8 index; + + if (mask == NULL) { + return -EINVAL; + } + for (index = 0; index < mask->maskdatacount; index++) { + mask->data[index] = 0xFFFFFFFF; + } + BOARDOBJGRPMASK_NORMALIZE(mask); + return 0; +} + +u32 boardobjgrpmask_inv(struct boardobjgrpmask *mask) +{ + u8 index; + + if (mask == NULL) { + return -EINVAL; + } + for (index = 0; index < mask->maskdatacount; index++) { + mask->data[index] = ~mask->data[index]; + } + BOARDOBJGRPMASK_NORMALIZE(mask); + return 0; +} + +bool boardobjgrpmask_iszero(struct boardobjgrpmask *mask) +{ + u8 index; + + if (mask == NULL) { + return true; + } + for (index = 0; index < mask->maskdatacount; index++) { + if (mask->data[index] != 0) { + return false; + } + } + return true; +} + +u8 boardobjgrpmask_bitsetcount(struct boardobjgrpmask *mask) +{ + u8 index; + u8 result = 0; + + if (mask == NULL) { + return result; + } + + for (index = 0; index < mask->maskdatacount; index++) { + u32 m = mask->data[index]; + + NUMSETBITS_32(m); + result += (u8)m; + } + + return result; +} + +u8 boardobjgrpmask_bitidxlowest(struct boardobjgrpmask *mask) +{ + u8 index; + u8 result = CTRL_BOARDOBJ_IDX_INVALID; + + if (mask == NULL) { + return result; + } + + for (index = 0; index < mask->maskdatacount; index++) { + u32 m = mask->data[index]; + + if (m != 0) { + LOWESTBITIDX_32(m); + result = (u8)m + index * + CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; + break; + } + } + + return result; +} + +u8 boardobjgrpmask_bitidxhighest(struct boardobjgrpmask *mask) +{ + u8 index; + u8 result = CTRL_BOARDOBJ_IDX_INVALID; + + if (mask == NULL) { + return result; + } + + for (index = 0; index < mask->maskdatacount; index++) { + u32 m = mask->data[index]; + + if (m != 0) { + HIGHESTBITIDX_32(m); + result = (u8)m + index * + CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; + break; + } + } + + return result; +} + +int boardobjgrpmask_bitclr(struct boardobjgrpmask *mask, u8 bitidx) +{ + u8 index; + u8 offset; + + if (mask == NULL) { + return -EINVAL; + } + if (bitidx >= mask->bitcount) { + return -EINVAL; + } + + index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); + offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); + + mask->data[index] &= ~BIT(offset); + + return 0; +} + +int boardobjgrpmask_bitset(struct boardobjgrpmask *mask, u8 bitidx) +{ + u8 index; + u8 offset; + + if (mask == NULL) { + return -EINVAL; + } + if (bitidx >= mask->bitcount) { + return -EINVAL; + } + + index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); + offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); + + mask->data[index] |= BIT(offset); + + return 0; +} + +u32 boardobjgrpmask_bitinv(struct boardobjgrpmask *mask, u8 bitidx) +{ + u8 index; + u8 offset; + + if (mask == NULL) { + return -EINVAL; + } + if (bitidx >= mask->bitcount) { + return -EINVAL; + } + + index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); + offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); + + mask->data[index] ^= ~BIT(offset); + + return 0; +} + +bool boardobjgrpmask_bitget(struct boardobjgrpmask *mask, u8 bitidx) +{ + u8 index; + u8 offset; + + if (mask == NULL) { + return false; + } + if (bitidx >= mask->bitcount) { + return false; + } + + index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); + offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); + + return (mask->data[index] & BIT(offset)) != 0; +} + +u32 boardobjgrpmask_and(struct boardobjgrpmask *dst, + struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2) +{ + u8 index; + + if (!boardobjgrpmask_sizeeq(dst, op1)) { + return -EINVAL; + } + if (!boardobjgrpmask_sizeeq(dst, op2)) { + return -EINVAL; + } + + for (index = 0; index < dst->maskdatacount; index++) { + dst->data[index] = op1->data[index] & op2->data[index]; + } + + return 0; +} + +u32 boardobjgrpmask_or(struct boardobjgrpmask *dst, + struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2) +{ + u8 index; + + if (!boardobjgrpmask_sizeeq(dst, op1)) { + return -EINVAL; + } + if (!boardobjgrpmask_sizeeq(dst, op2)) { + return -EINVAL; + } + + for (index = 0; index < dst->maskdatacount; index++) { + dst->data[index] = op1->data[index] | op2->data[index]; + } + + return 0; +} + +u32 boardobjgrpmask_xor(struct boardobjgrpmask *dst, + struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2) +{ + u8 index; + + if (!boardobjgrpmask_sizeeq(dst, op1)) { + return -EINVAL; + } + if (!boardobjgrpmask_sizeeq(dst, op2)) { + return -EINVAL; + } + + for (index = 0; index < dst->maskdatacount; index++) { + dst->data[index] = op1->data[index] ^ op2->data[index]; + } + + return 0; +} + +u32 boardobjgrpmask_copy(struct boardobjgrpmask *dst, + struct boardobjgrpmask *src) +{ + u8 index; + + if (!boardobjgrpmask_sizeeq(dst, src)) { + return -EINVAL; + } + + for (index = 0; index < dst->maskdatacount; index++) { + dst->data[index] = src->data[index]; + } + + return 0; +} + +bool boardobjgrpmask_sizeeq(struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2) +{ + if (op1 == NULL) { + return false; + } + if (op2 == NULL) { + return false; + } + + return op1->bitcount == op2->bitcount; +} + +bool boardobjgrpmask_issubset(struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2) +{ + u8 index; + + if (!boardobjgrpmask_sizeeq(op2, op1)) { + return false; + } + + for (index = 0; index < op1->maskdatacount; index++) { + u32 op_1 = op1->data[index]; + u32 op_2 = op2->data[index]; + + if ((op_1 & op_2) != op_1) { + return false; + } + } + + return true; +} diff --git a/include/boardobj/boardobjgrpmask.h b/include/boardobj/boardobjgrpmask.h new file mode 100644 index 0000000..f4ed0af --- /dev/null +++ b/include/boardobj/boardobjgrpmask.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_BOARDOBJGRPMASK_H +#define NVGPU_BOARDOBJGRPMASK_H + +#include "ctrl/ctrlboardobj.h" + + +/* +* Board Object Group Mask super-structure. +* Used to unify access to all BOARDOBJGRPMASK_E** child classes +*/ +struct boardobjgrpmask { + /* Number of bits supported by the mask */ + u8 bitcount; + /* Number of 32-bit words required to store all @ref bitCount bits */ + u8 maskdatacount; + /* + * Bit-mask of used-bits within last 32-bit word. Used to + * normalize data + */ + u32 lastmaskfilter; + /* + * Start of the array of 32-bit words representing the bit-mask + * Must be the last element of the structure. + */ + u32 data[CTRL_BOARDOBJGRP_MASK_ARRAY_START_SIZE]; +}; + +struct boardobjgrpmask_e32 { + /* + * BOARDOBJGRPMASK super-class. Must be the first element of the + * structure. + */ + struct boardobjgrpmask super; + /*u32 data_e32[1]; */ +}; + +struct boardobjgrpmask_e255 { + /* + * BOARDOBJGRPMASK super-class. Must be the first element of the + * structure. + */ + struct boardobjgrpmask super; + u32 data_e255[254]; +}; + +/* Init and I/O operations.*/ +u32 boardobjgrpmask_init(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask); +u32 boardobjgrpmask_import(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask); +u32 boardobjgrpmask_export(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask); + +/* Operations on all bits of a single mask.*/ +u32 boardobjgrpmask_clr(struct boardobjgrpmask *mask); +u32 boardobjgrpmask_set(struct boardobjgrpmask *mask); +u32 boardobjgrpmask_inv(struct boardobjgrpmask *mask); +bool boardobjgrpmask_iszero(struct boardobjgrpmask *mask); +u8 boardobjgrpmask_bitsetcount(struct boardobjgrpmask *mask); +u8 boardobjgrpmask_bitidxlowest(struct boardobjgrpmask *mask); +u8 boardobjgrpmask_bitidxhighest(struct boardobjgrpmask *mask); + +/* Operations on a single bit of a single mask */ +int boardobjgrpmask_bitclr(struct boardobjgrpmask *mask, u8 bitidx); +int boardobjgrpmask_bitset(struct boardobjgrpmask *mask, u8 bitidx); +u32 boardobjgrpmask_bitinv(struct boardobjgrpmask *mask, u8 bitidx); +bool boardobjgrpmask_bitget(struct boardobjgrpmask *mask, u8 bitidx); + +/* Operations on a multiple masks */ +u32 boardobjgrpmask_and(struct boardobjgrpmask *dst, + struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2); +u32 boardobjgrpmask_or(struct boardobjgrpmask *dst, struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2); +u32 boardobjgrpmask_xor(struct boardobjgrpmask *dst, + struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2); + +/* Special interfaces */ +u32 boardobjgrpmask_copy(struct boardobjgrpmask *dst, + struct boardobjgrpmask *src); +bool boardobjgrpmask_sizeeq(struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2); +bool boardobjgrpmask_issubset(struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2); + +/* init boardobjgrpmask_e32 structure */ +#define boardobjgrpmask_e32_init(pmaske32, pextmask) \ + boardobjgrpmask_init(&(pmaske32)->super, \ + CTRL_BOARDOBJGRP_E32_MAX_OBJECTS, (pextmask)) + +/* init boardobjgrpmask_e255 structure */ +#define boardobjgrpmask_e255_init(pmaske255, pextmask) \ + boardobjgrpmask_init(&(pmaske255)->super, \ + CTRL_BOARDOBJGRP_E255_MAX_OBJECTS, (pextmask)) + +#endif /* NVGPU_BOARDOBJGRPMASK_H */ diff --git a/include/clk/clk.c b/include/clk/clk.c new file mode 100644 index 0000000..d8e30c4 --- /dev/null +++ b/include/clk/clk.c @@ -0,0 +1,942 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "clk.h" +#include "ctrl/ctrlclk.h" +#include "ctrl/ctrlvolt.h" +#include "volt/volt.h" + +#define BOOT_GPC2CLK_MHZ 2581 +#define BOOT_MCLK_MHZ 3003 + +struct clkrpc_pmucmdhandler_params { + struct nv_pmu_clk_rpc *prpccall; + u32 success; +}; + +static void clkrpc_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg, + void *param, u32 handle, u32 status) +{ + struct clkrpc_pmucmdhandler_params *phandlerparams = + (struct clkrpc_pmucmdhandler_params *)param; + + nvgpu_log_info(g, " "); + + if (msg->msg.clk.msg_type != NV_PMU_CLK_MSG_ID_RPC) { + nvgpu_err(g, "unsupported msg for VFE LOAD RPC %x", + msg->msg.clk.msg_type); + return; + } + + if (phandlerparams->prpccall->b_supported) { + phandlerparams->success = 1; + } +} + + +int clk_pmu_freq_effective_avg_load(struct gk20a *g, bool bload) +{ + struct pmu_cmd cmd; + struct pmu_payload payload; + u32 status; + u32 seqdesc; + struct nv_pmu_clk_rpc rpccall; + struct clkrpc_pmucmdhandler_params handler; + struct nv_pmu_clk_load *clkload; + + memset(&payload, 0, sizeof(struct pmu_payload)); + memset(&rpccall, 0, sizeof(struct nv_pmu_clk_rpc)); + memset(&handler, 0, sizeof(struct clkrpc_pmucmdhandler_params)); + memset(&cmd, 0, sizeof(struct pmu_cmd)); + + rpccall.function = NV_PMU_CLK_RPC_ID_LOAD; + clkload = &rpccall.params.clk_load; + clkload->feature = NV_NV_PMU_CLK_LOAD_FEATURE_FREQ_EFFECTIVE_AVG; + clkload->action_mask = bload ? + NV_NV_PMU_CLK_LOAD_ACTION_MASK_FREQ_EFFECTIVE_AVG_CALLBACK_YES : + NV_NV_PMU_CLK_LOAD_ACTION_MASK_FREQ_EFFECTIVE_AVG_CALLBACK_NO; + + cmd.hdr.unit_id = PMU_UNIT_CLK; + cmd.hdr.size = (u32)sizeof(struct nv_pmu_clk_cmd) + + (u32)sizeof(struct pmu_hdr); + + cmd.cmd.clk.cmd_type = NV_PMU_CLK_CMD_ID_RPC; + + payload.in.buf = (u8 *)&rpccall; + payload.in.size = (u32)sizeof(struct nv_pmu_clk_rpc); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = NV_PMU_CLK_CMD_RPC_ALLOC_OFFSET; + + payload.out.buf = (u8 *)&rpccall; + payload.out.size = (u32)sizeof(struct nv_pmu_clk_rpc); + payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.out.offset = NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET; + + handler.prpccall = &rpccall; + handler.success = 0; + + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + clkrpc_pmucmdhandler, (void *)&handler, + &seqdesc, ~0); + if (status) { + nvgpu_err(g, "unable to post clk RPC cmd %x", + cmd.cmd.clk.cmd_type); + goto done; + } + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handler.success, 1); + if (handler.success == 0) { + nvgpu_err(g, "rpc call to load Effective avg clk domain freq failed"); + status = -EINVAL; + } + +done: + return status; +} + +u32 clk_freq_effective_avg(struct gk20a *g, u32 clkDomainMask) { + + struct pmu_cmd cmd; + struct pmu_payload payload; + u32 status; + u32 seqdesc; + struct nv_pmu_clk_rpc rpccall; + struct clkrpc_pmucmdhandler_params handler; + struct nv_pmu_clk_freq_effective_avg *clk_freq_effective_avg; + + memset(&payload, 0, sizeof(struct pmu_payload)); + memset(&rpccall, 0, sizeof(struct nv_pmu_clk_rpc)); + memset(&handler, 0, sizeof(struct clkrpc_pmucmdhandler_params)); + memset(&cmd, 0, sizeof(struct pmu_cmd)); + + rpccall.function = NV_PMU_CLK_RPC_ID_CLK_FREQ_EFF_AVG; + clk_freq_effective_avg = &rpccall.params.clk_freq_effective_avg; + clk_freq_effective_avg->clkDomainMask = clkDomainMask; + + cmd.hdr.unit_id = PMU_UNIT_CLK; + cmd.hdr.size = (u32)sizeof(struct nv_pmu_clk_cmd) + + (u32)sizeof(struct pmu_hdr); + + cmd.cmd.clk.cmd_type = NV_PMU_CLK_CMD_ID_RPC; + + payload.in.buf = (u8 *)&rpccall; + payload.in.size = (u32)sizeof(struct nv_pmu_clk_rpc); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = NV_PMU_CLK_CMD_RPC_ALLOC_OFFSET; + + payload.out.buf = (u8 *)&rpccall; + payload.out.size = (u32)sizeof(struct nv_pmu_clk_rpc); + payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.out.offset = NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET; + + handler.prpccall = &rpccall; + handler.success = 0; + + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + clkrpc_pmucmdhandler, (void *)&handler, + &seqdesc, ~0); + if (status) { + nvgpu_err(g, "unable to post clk RPC cmd %x", + cmd.cmd.clk.cmd_type); + goto done; + } + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handler.success, 1); + if (handler.success == 0) { + nvgpu_err(g, "rpc call to get clk frequency average failed"); + status = -EINVAL; + goto done; + } + + return rpccall.params.clk_freq_effective_avg.freqkHz[clkDomainMask]; + +done: + return status; +} + +int clk_pmu_freq_controller_load(struct gk20a *g, bool bload, u8 bit_idx) +{ + struct pmu_cmd cmd; + struct pmu_payload payload; + u32 status; + u32 seqdesc; + struct nv_pmu_clk_rpc rpccall; + struct clkrpc_pmucmdhandler_params handler; + struct nv_pmu_clk_load *clkload; + struct clk_freq_controllers *pclk_freq_controllers; + struct ctrl_boardobjgrp_mask_e32 *load_mask; + struct boardobjgrpmask_e32 isolate_cfc_mask; + + memset(&payload, 0, sizeof(struct pmu_payload)); + memset(&rpccall, 0, sizeof(struct nv_pmu_clk_rpc)); + memset(&handler, 0, sizeof(struct clkrpc_pmucmdhandler_params)); + + pclk_freq_controllers = &g->clk_pmu.clk_freq_controllers; + rpccall.function = NV_PMU_CLK_RPC_ID_LOAD; + clkload = &rpccall.params.clk_load; + clkload->feature = NV_NV_PMU_CLK_LOAD_FEATURE_FREQ_CONTROLLER; + clkload->action_mask = bload ? + NV_NV_PMU_CLK_LOAD_ACTION_MASK_FREQ_CONTROLLER_CALLBACK_YES : + NV_NV_PMU_CLK_LOAD_ACTION_MASK_FREQ_CONTROLLER_CALLBACK_NO; + + load_mask = &rpccall.params.clk_load.payload.freq_controllers.load_mask; + + status = boardobjgrpmask_e32_init(&isolate_cfc_mask, NULL); + + if (bit_idx == CTRL_CLK_CLK_FREQ_CONTROLLER_ID_ALL) { + status = boardobjgrpmask_export( + &pclk_freq_controllers-> + freq_ctrl_load_mask.super, + pclk_freq_controllers-> + freq_ctrl_load_mask.super.bitcount, + &load_mask->super); + + + } else { + status = boardobjgrpmask_bitset(&isolate_cfc_mask.super, + bit_idx); + status = boardobjgrpmask_export(&isolate_cfc_mask.super, + isolate_cfc_mask.super.bitcount, + &load_mask->super); + if (bload) { + status = boardobjgrpmask_bitset( + &pclk_freq_controllers-> + freq_ctrl_load_mask.super, + bit_idx); + } else { + status = boardobjgrpmask_bitclr( + &pclk_freq_controllers-> + freq_ctrl_load_mask.super, + bit_idx); + } + } + + if (status) { + nvgpu_err(g, "Error in generating mask used to select CFC"); + goto done; + } + + cmd.hdr.unit_id = PMU_UNIT_CLK; + cmd.hdr.size = (u32)sizeof(struct nv_pmu_clk_cmd) + + (u32)sizeof(struct pmu_hdr); + + cmd.cmd.clk.cmd_type = NV_PMU_CLK_CMD_ID_RPC; + + payload.in.buf = (u8 *)&rpccall; + payload.in.size = (u32)sizeof(struct nv_pmu_clk_rpc); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = NV_PMU_CLK_CMD_RPC_ALLOC_OFFSET; + + payload.out.buf = (u8 *)&rpccall; + payload.out.size = (u32)sizeof(struct nv_pmu_clk_rpc); + payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.out.offset = NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET; + + handler.prpccall = &rpccall; + handler.success = 0; + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + clkrpc_pmucmdhandler, (void *)&handler, + &seqdesc, ~0); + + if (status) { + nvgpu_err(g, "unable to post clk RPC cmd %x", + cmd.cmd.clk.cmd_type); + goto done; + } + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handler.success, 1); + + if (handler.success == 0) { + nvgpu_err(g, "rpc call to load freq cntlr cal failed"); + status = -EINVAL; + } + +done: + return status; +} + +u32 clk_pmu_vin_load(struct gk20a *g) +{ + struct pmu_cmd cmd; + struct pmu_payload payload; + u32 status; + u32 seqdesc; + struct nv_pmu_clk_rpc rpccall; + struct clkrpc_pmucmdhandler_params handler; + struct nv_pmu_clk_load *clkload; + + memset(&payload, 0, sizeof(struct pmu_payload)); + memset(&rpccall, 0, sizeof(struct nv_pmu_clk_rpc)); + memset(&handler, 0, sizeof(struct clkrpc_pmucmdhandler_params)); + + rpccall.function = NV_PMU_CLK_RPC_ID_LOAD; + clkload = &rpccall.params.clk_load; + clkload->feature = NV_NV_PMU_CLK_LOAD_FEATURE_VIN; + clkload->action_mask = NV_NV_PMU_CLK_LOAD_ACTION_MASK_VIN_HW_CAL_PROGRAM_YES << 4; + + cmd.hdr.unit_id = PMU_UNIT_CLK; + cmd.hdr.size = (u32)sizeof(struct nv_pmu_clk_cmd) + + (u32)sizeof(struct pmu_hdr); + + cmd.cmd.clk.cmd_type = NV_PMU_CLK_CMD_ID_RPC; + cmd.cmd.clk.generic.b_perf_daemon_cmd =false; + + payload.in.buf = (u8 *)&rpccall; + payload.in.size = (u32)sizeof(struct nv_pmu_clk_rpc); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = NV_PMU_CLK_CMD_RPC_ALLOC_OFFSET; + + payload.out.buf = (u8 *)&rpccall; + payload.out.size = (u32)sizeof(struct nv_pmu_clk_rpc); + payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.out.offset = NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET; + + handler.prpccall = &rpccall; + handler.success = 0; + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + clkrpc_pmucmdhandler, (void *)&handler, + &seqdesc, ~0); + + if (status) { + nvgpu_err(g, "unable to post clk RPC cmd %x", + cmd.cmd.clk.cmd_type); + goto done; + } + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handler.success, 1); + + if (handler.success == 0) { + nvgpu_err(g, "rpc call to load vin cal failed"); + status = -EINVAL; + } + +done: + return status; +} + +u32 nvgpu_clk_vf_change_inject_data_fill_gp10x(struct gk20a *g, + struct nv_pmu_clk_rpc *rpccall, + struct set_fll_clk *setfllclk) +{ + struct nv_pmu_clk_vf_change_inject *vfchange; + + vfchange = &rpccall->params.clk_vf_change_inject; + vfchange->flags = 0; + vfchange->clk_list.num_domains = 3; + vfchange->clk_list.clk_domains[0].clk_domain = CTRL_CLK_DOMAIN_GPC2CLK; + vfchange->clk_list.clk_domains[0].clk_freq_khz = + setfllclk->gpc2clkmhz * 1000; + vfchange->clk_list.clk_domains[0].clk_flags = 0; + vfchange->clk_list.clk_domains[0].current_regime_id = + setfllclk->current_regime_id_gpc; + vfchange->clk_list.clk_domains[0].target_regime_id = + setfllclk->target_regime_id_gpc; + vfchange->clk_list.clk_domains[1].clk_domain = CTRL_CLK_DOMAIN_XBAR2CLK; + vfchange->clk_list.clk_domains[1].clk_freq_khz = + setfllclk->xbar2clkmhz * 1000; + vfchange->clk_list.clk_domains[1].clk_flags = 0; + vfchange->clk_list.clk_domains[1].current_regime_id = + setfllclk->current_regime_id_xbar; + vfchange->clk_list.clk_domains[1].target_regime_id = + setfllclk->target_regime_id_xbar; + vfchange->clk_list.clk_domains[2].clk_domain = CTRL_CLK_DOMAIN_SYS2CLK; + vfchange->clk_list.clk_domains[2].clk_freq_khz = + setfllclk->sys2clkmhz * 1000; + vfchange->clk_list.clk_domains[2].clk_flags = 0; + vfchange->clk_list.clk_domains[2].current_regime_id = + setfllclk->current_regime_id_sys; + vfchange->clk_list.clk_domains[2].target_regime_id = + setfllclk->target_regime_id_sys; + vfchange->volt_list.num_rails = 1; + vfchange->volt_list.rails[0].volt_domain = CTRL_VOLT_DOMAIN_LOGIC; + vfchange->volt_list.rails[0].voltage_uv = setfllclk->voltuv; + vfchange->volt_list.rails[0].voltage_min_noise_unaware_uv = + setfllclk->voltuv; + + return 0; +} + +u32 nvgpu_clk_vf_change_inject_data_fill_gv10x(struct gk20a *g, + struct nv_pmu_clk_rpc *rpccall, + struct set_fll_clk *setfllclk) +{ + struct nv_pmu_clk_vf_change_inject_v1 *vfchange; + + vfchange = &rpccall->params.clk_vf_change_inject_v1; + vfchange->flags = 0; + vfchange->clk_list.num_domains = 4; + vfchange->clk_list.clk_domains[0].clk_domain = CTRL_CLK_DOMAIN_GPCCLK; + vfchange->clk_list.clk_domains[0].clk_freq_khz = + setfllclk->gpc2clkmhz * 1000; + + vfchange->clk_list.clk_domains[1].clk_domain = CTRL_CLK_DOMAIN_XBARCLK; + vfchange->clk_list.clk_domains[1].clk_freq_khz = + setfllclk->xbar2clkmhz * 1000; + + vfchange->clk_list.clk_domains[2].clk_domain = CTRL_CLK_DOMAIN_SYSCLK; + vfchange->clk_list.clk_domains[2].clk_freq_khz = + setfllclk->sys2clkmhz * 1000; + + vfchange->clk_list.clk_domains[3].clk_domain = CTRL_CLK_DOMAIN_NVDCLK; + vfchange->clk_list.clk_domains[3].clk_freq_khz = 855 * 1000; + + vfchange->volt_list.num_rails = 1; + vfchange->volt_list.rails[0].rail_idx = 0; + vfchange->volt_list.rails[0].voltage_uv = setfllclk->voltuv; + vfchange->volt_list.rails[0].voltage_min_noise_unaware_uv = + setfllclk->voltuv; + + return 0; +} + +static u32 clk_pmu_vf_inject(struct gk20a *g, struct set_fll_clk *setfllclk) +{ + struct pmu_cmd cmd; + struct pmu_payload payload; + u32 status; + u32 seqdesc; + struct nv_pmu_clk_rpc rpccall; + struct clkrpc_pmucmdhandler_params handler; + + memset(&payload, 0, sizeof(struct pmu_payload)); + memset(&rpccall, 0, sizeof(struct nv_pmu_clk_rpc)); + memset(&handler, 0, sizeof(struct clkrpc_pmucmdhandler_params)); + memset(&cmd, 0, sizeof(struct pmu_cmd)); + + if ((setfllclk->gpc2clkmhz == 0) || (setfllclk->xbar2clkmhz == 0) || + (setfllclk->sys2clkmhz == 0) || (setfllclk->voltuv == 0)) { + return -EINVAL; + } + + if ((setfllclk->target_regime_id_gpc > CTRL_CLK_FLL_REGIME_ID_FR) || + (setfllclk->target_regime_id_sys > CTRL_CLK_FLL_REGIME_ID_FR) || + (setfllclk->target_regime_id_xbar > CTRL_CLK_FLL_REGIME_ID_FR)) { + return -EINVAL; + } + + rpccall.function = NV_PMU_CLK_RPC_ID_CLK_VF_CHANGE_INJECT; + + g->ops.pmu_ver.clk.clk_vf_change_inject_data_fill(g, + &rpccall, setfllclk); + + cmd.hdr.unit_id = PMU_UNIT_CLK; + cmd.hdr.size = (u32)sizeof(struct nv_pmu_clk_cmd) + + (u32)sizeof(struct pmu_hdr); + + cmd.cmd.clk.cmd_type = NV_PMU_CLK_CMD_ID_RPC; + + payload.in.buf = (u8 *)&rpccall; + payload.in.size = (u32)sizeof(struct nv_pmu_clk_rpc); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = NV_PMU_CLK_CMD_RPC_ALLOC_OFFSET; + + payload.out.buf = (u8 *)&rpccall; + payload.out.size = (u32)sizeof(struct nv_pmu_clk_rpc); + payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.out.offset = NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET; + + handler.prpccall = &rpccall; + handler.success = 0; + + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + clkrpc_pmucmdhandler, (void *)&handler, + &seqdesc, ~0); + + if (status) { + nvgpu_err(g, "unable to post clk RPC cmd %x", + cmd.cmd.clk.cmd_type); + goto done; + } + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handler.success, 1); + + if (handler.success == 0) { + nvgpu_err(g, "rpc call to inject clock failed"); + status = -EINVAL; + } +done: + return status; +} + +static u32 find_regime_id(struct gk20a *g, u32 domain, u16 clkmhz) +{ + struct fll_device *pflldev; + u8 j; + struct clk_pmupstate *pclk = &g->clk_pmu; + + BOARDOBJGRP_FOR_EACH(&(pclk->avfs_fllobjs.super.super), + struct fll_device *, pflldev, j) { + if (pflldev->clk_domain == domain) { + if (pflldev->regime_desc.fixed_freq_regime_limit_mhz >= + clkmhz) { + return CTRL_CLK_FLL_REGIME_ID_FFR; + } else { + return CTRL_CLK_FLL_REGIME_ID_FR; + } + } + } + return CTRL_CLK_FLL_REGIME_ID_INVALID; +} + +static int set_regime_id(struct gk20a *g, u32 domain, u32 regimeid) +{ + struct fll_device *pflldev; + u8 j; + struct clk_pmupstate *pclk = &g->clk_pmu; + + BOARDOBJGRP_FOR_EACH(&(pclk->avfs_fllobjs.super.super), + struct fll_device *, pflldev, j) { + if (pflldev->clk_domain == domain) { + pflldev->regime_desc.regime_id = regimeid; + return 0; + } + } + return -EINVAL; +} + +static int get_regime_id(struct gk20a *g, u32 domain, u32 *regimeid) +{ + struct fll_device *pflldev; + u8 j; + struct clk_pmupstate *pclk = &g->clk_pmu; + + BOARDOBJGRP_FOR_EACH(&(pclk->avfs_fllobjs.super.super), + struct fll_device *, pflldev, j) { + if (pflldev->clk_domain == domain) { + *regimeid = pflldev->regime_desc.regime_id; + return 0; + } + } + return -EINVAL; +} + +int clk_set_fll_clks(struct gk20a *g, struct set_fll_clk *setfllclk) +{ + int status = -EINVAL; + + /*set regime ids */ + status = get_regime_id(g, CTRL_CLK_DOMAIN_GPC2CLK, + &setfllclk->current_regime_id_gpc); + if (status) { + goto done; + } + + setfllclk->target_regime_id_gpc = find_regime_id(g, + CTRL_CLK_DOMAIN_GPC2CLK, setfllclk->gpc2clkmhz); + + status = get_regime_id(g, CTRL_CLK_DOMAIN_SYS2CLK, + &setfllclk->current_regime_id_sys); + if (status) { + goto done; + } + + setfllclk->target_regime_id_sys = find_regime_id(g, + CTRL_CLK_DOMAIN_SYS2CLK, setfllclk->sys2clkmhz); + + status = get_regime_id(g, CTRL_CLK_DOMAIN_XBAR2CLK, + &setfllclk->current_regime_id_xbar); + if (status) { + goto done; + } + + setfllclk->target_regime_id_xbar = find_regime_id(g, + CTRL_CLK_DOMAIN_XBAR2CLK, setfllclk->xbar2clkmhz); + + status = clk_pmu_vf_inject(g, setfllclk); + + if (status) { + nvgpu_err(g, "vf inject to change clk failed"); + } + + /* save regime ids */ + status = set_regime_id(g, CTRL_CLK_DOMAIN_XBAR2CLK, + setfllclk->target_regime_id_xbar); + if (status) { + goto done; + } + + status = set_regime_id(g, CTRL_CLK_DOMAIN_GPC2CLK, + setfllclk->target_regime_id_gpc); + if (status) { + goto done; + } + + status = set_regime_id(g, CTRL_CLK_DOMAIN_SYS2CLK, + setfllclk->target_regime_id_sys); + if (status) { + goto done; + } +done: + return status; +} + +int clk_get_fll_clks(struct gk20a *g, struct set_fll_clk *setfllclk) +{ + int status = -EINVAL; + struct clk_domain *pdomain; + u8 i; + struct clk_pmupstate *pclk = &g->clk_pmu; + u16 clkmhz = 0; + struct clk_domain_3x_master *p3xmaster; + struct clk_domain_3x_slave *p3xslave; + unsigned long slaveidxmask; + + if (setfllclk->gpc2clkmhz == 0) { + return -EINVAL; + } + + BOARDOBJGRP_FOR_EACH(&(pclk->clk_domainobjs.super.super), + struct clk_domain *, pdomain, i) { + + if (pdomain->api_domain == CTRL_CLK_DOMAIN_GPC2CLK) { + + if (!pdomain->super.implements(g, &pdomain->super, + CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER)) { + status = -EINVAL; + goto done; + } + p3xmaster = (struct clk_domain_3x_master *)pdomain; + slaveidxmask = p3xmaster->slave_idxs_mask; + for_each_set_bit(i, &slaveidxmask, 32) { + p3xslave = (struct clk_domain_3x_slave *) + CLK_CLK_DOMAIN_GET(pclk, i); + if ((p3xslave->super.super.super.api_domain != + CTRL_CLK_DOMAIN_XBAR2CLK) && + (p3xslave->super.super.super.api_domain != + CTRL_CLK_DOMAIN_SYS2CLK)) { + continue; + } + clkmhz = 0; + status = p3xslave->clkdomainclkgetslaveclk(g, + pclk, + (struct clk_domain *)p3xslave, + &clkmhz, + setfllclk->gpc2clkmhz); + if (status) { + status = -EINVAL; + goto done; + } + if (p3xslave->super.super.super.api_domain == + CTRL_CLK_DOMAIN_XBAR2CLK) { + setfllclk->xbar2clkmhz = clkmhz; + } + if (p3xslave->super.super.super.api_domain == + CTRL_CLK_DOMAIN_SYS2CLK) { + setfllclk->sys2clkmhz = clkmhz; + } + } + } + } +done: + return status; +} + +u32 clk_domain_print_vf_table(struct gk20a *g, u32 clkapidomain) +{ + u32 status = -EINVAL; + struct clk_domain *pdomain; + u8 i; + struct clk_pmupstate *pclk = &g->clk_pmu; + u16 clkmhz = 0; + u32 volt = 0; + + BOARDOBJGRP_FOR_EACH(&(pclk->clk_domainobjs.super.super), + struct clk_domain *, pdomain, i) { + if (pdomain->api_domain == clkapidomain) { + status = pdomain->clkdomainclkvfsearch(g, pclk, + pdomain, &clkmhz, &volt, + CLK_PROG_VFE_ENTRY_LOGIC); + status = pdomain->clkdomainclkvfsearch(g, pclk, + pdomain, &clkmhz, &volt, + CLK_PROG_VFE_ENTRY_SRAM); + } + } + return status; +} + +static int clk_program_fllclks(struct gk20a *g, struct change_fll_clk *fllclk) +{ + int status = -EINVAL; + struct clk_domain *pdomain; + u8 i; + struct clk_pmupstate *pclk = &g->clk_pmu; + u16 clkmhz = 0; + struct clk_domain_3x_master *p3xmaster; + struct clk_domain_3x_slave *p3xslave; + unsigned long slaveidxmask; + struct set_fll_clk setfllclk; + + if (fllclk->api_clk_domain != CTRL_CLK_DOMAIN_GPCCLK) { + return -EINVAL; + } + if (fllclk->voltuv == 0) { + return -EINVAL; + } + if (fllclk->clkmhz == 0) { + return -EINVAL; + } + + setfllclk.voltuv = fllclk->voltuv; + setfllclk.gpc2clkmhz = fllclk->clkmhz; + + BOARDOBJGRP_FOR_EACH(&(pclk->clk_domainobjs.super.super), + struct clk_domain *, pdomain, i) { + + if (pdomain->api_domain == fllclk->api_clk_domain) { + + if (!pdomain->super.implements(g, &pdomain->super, + CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER)) { + status = -EINVAL; + goto done; + } + p3xmaster = (struct clk_domain_3x_master *)pdomain; + slaveidxmask = p3xmaster->slave_idxs_mask; + for_each_set_bit(i, &slaveidxmask, 32) { + p3xslave = (struct clk_domain_3x_slave *) + CLK_CLK_DOMAIN_GET(pclk, i); + if ((p3xslave->super.super.super.api_domain != + CTRL_CLK_DOMAIN_XBARCLK) && + (p3xslave->super.super.super.api_domain != + CTRL_CLK_DOMAIN_SYSCLK)) { + continue; + } + clkmhz = 0; + status = p3xslave->clkdomainclkgetslaveclk(g, + pclk, + (struct clk_domain *)p3xslave, + &clkmhz, + fllclk->clkmhz); + if (status) { + status = -EINVAL; + goto done; + } + if (p3xslave->super.super.super.api_domain == + CTRL_CLK_DOMAIN_XBARCLK) { + setfllclk.xbar2clkmhz = clkmhz; + } + if (p3xslave->super.super.super.api_domain == + CTRL_CLK_DOMAIN_SYSCLK) { + setfllclk.sys2clkmhz = clkmhz; + } + } + } + } + /*set regime ids */ + status = get_regime_id(g, CTRL_CLK_DOMAIN_GPCCLK, + &setfllclk.current_regime_id_gpc); + if (status) { + goto done; + } + + setfllclk.target_regime_id_gpc = find_regime_id(g, + CTRL_CLK_DOMAIN_GPCCLK, setfllclk.gpc2clkmhz); + + status = get_regime_id(g, CTRL_CLK_DOMAIN_SYSCLK, + &setfllclk.current_regime_id_sys); + if (status) { + goto done; + } + + setfllclk.target_regime_id_sys = find_regime_id(g, + CTRL_CLK_DOMAIN_SYSCLK, setfllclk.sys2clkmhz); + + status = get_regime_id(g, CTRL_CLK_DOMAIN_XBARCLK, + &setfllclk.current_regime_id_xbar); + if (status) { + goto done; + } + + setfllclk.target_regime_id_xbar = find_regime_id(g, + CTRL_CLK_DOMAIN_XBARCLK, setfllclk.xbar2clkmhz); + + status = clk_pmu_vf_inject(g, &setfllclk); + + if (status) { + nvgpu_err(g, + "vf inject to change clk failed"); + } + + /* save regime ids */ + status = set_regime_id(g, CTRL_CLK_DOMAIN_XBARCLK, + setfllclk.target_regime_id_xbar); + if (status) { + goto done; + } + + status = set_regime_id(g, CTRL_CLK_DOMAIN_GPCCLK, + setfllclk.target_regime_id_gpc); + if (status) { + goto done; + } + + status = set_regime_id(g, CTRL_CLK_DOMAIN_SYSCLK, + setfllclk.target_regime_id_sys); + if (status) { + goto done; + } +done: + return status; +} + +u32 nvgpu_clk_set_boot_fll_clk_gv10x(struct gk20a *g) +{ + int status; + struct change_fll_clk bootfllclk; + u16 gpcclk_clkmhz = BOOT_GPCCLK_MHZ; + u32 gpcclk_voltuv = 0; + u32 voltuv = 0; + + status = clk_vf_point_cache(g); + if (status) { + nvgpu_err(g,"caching failed"); + return status; + } + + status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_GPCCLK, + &gpcclk_clkmhz, &gpcclk_voltuv, CTRL_VOLT_DOMAIN_LOGIC); + if (status) { + return status; + } + + voltuv = gpcclk_voltuv; + + status = volt_set_voltage(g, voltuv, 0); + if (status) { + nvgpu_err(g, + "attempt to set boot voltage failed %d", + voltuv); + } + + bootfllclk.api_clk_domain = CTRL_CLK_DOMAIN_GPCCLK; + bootfllclk.clkmhz = gpcclk_clkmhz; + bootfllclk.voltuv = voltuv; + status = clk_program_fllclks(g, &bootfllclk); + if (status) { + nvgpu_err(g, "attempt to set boot gpcclk failed"); + } + + status = clk_pmu_freq_effective_avg_load(g, true); + + /* + * Read clocks after some delay with below method + * & extract clock data from buffer + * clk_freq_effective_avg(g, CTRL_CLK_DOMAIN_GPCCLK | + * CTRL_CLK_DOMAIN_XBARCLK | + * CTRL_CLK_DOMAIN_SYSCLK | + * CTRL_CLK_DOMAIN_NVDCLK) + * */ + + return status; +} + +int nvgpu_clk_set_fll_clk_gv10x(struct gk20a *g) +{ + int status; + struct change_fll_clk bootfllclk; + u16 gpcclk_clkmhz = BOOT_GPCCLK_MHZ; + u32 gpcclk_voltuv = 0U; + u32 voltuv = 0U; + + status = clk_vf_point_cache(g); + if (status != 0) { + nvgpu_err(g, "caching failed"); + return status; + } + + status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_GPCCLK, + &gpcclk_clkmhz, &gpcclk_voltuv, CTRL_VOLT_DOMAIN_LOGIC); + if (status != 0) { + return status; + } + + voltuv = gpcclk_voltuv; + + status = volt_set_voltage(g, voltuv, 0U); + if (status != 0) { + nvgpu_err(g, "attempt to set max voltage failed %d", voltuv); + } + + bootfllclk.api_clk_domain = CTRL_CLK_DOMAIN_GPCCLK; + bootfllclk.clkmhz = gpcclk_clkmhz; + bootfllclk.voltuv = voltuv; + status = clk_program_fllclks(g, &bootfllclk); + if (status != 0) { + nvgpu_err(g, "attempt to set max gpcclk failed"); + } + return status; +} + +u32 clk_domain_get_f_or_v( + struct gk20a *g, + u32 clkapidomain, + u16 *pclkmhz, + u32 *pvoltuv, + u8 railidx +) +{ + u32 status = -EINVAL; + struct clk_domain *pdomain; + u8 i; + struct clk_pmupstate *pclk = &g->clk_pmu; + u8 rail; + + if ((pclkmhz == NULL) || (pvoltuv == NULL)) { + return -EINVAL; + } + + if (railidx == CTRL_VOLT_DOMAIN_LOGIC) { + rail = CLK_PROG_VFE_ENTRY_LOGIC; + } else if (railidx == CTRL_VOLT_DOMAIN_SRAM) { + rail = CLK_PROG_VFE_ENTRY_SRAM; + } else { + return -EINVAL; + } + + BOARDOBJGRP_FOR_EACH(&(pclk->clk_domainobjs.super.super), + struct clk_domain *, pdomain, i) { + if (pdomain->api_domain == clkapidomain) { + status = pdomain->clkdomainclkvfsearch(g, pclk, + pdomain, pclkmhz, pvoltuv, rail); + return status; + } + } + return status; +} diff --git a/include/clk/clk.h b/include/clk/clk.h new file mode 100644 index 0000000..3f4bdf7 --- /dev/null +++ b/include/clk/clk.h @@ -0,0 +1,144 @@ +/* + * general clock structures & definitions + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_CLK_H +#define NVGPU_CLK_H + +#include "clk_vin.h" +#include "clk_fll.h" +#include "clk_domain.h" +#include "clk_prog.h" +#include "clk_vf_point.h" +#include "clk_mclk.h" +#include "clk_freq_controller.h" + +#define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_SKIP 0x10 +#define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_MASK 0x1F +#define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_SHIFT 0 +#define BOOT_GPCCLK_MHZ 952 + +struct gk20a; + +int clk_set_boot_fll_clk(struct gk20a *g); + +/* clock related defines for GPUs supporting clock control from pmu*/ +struct clk_pmupstate { + struct avfsvinobjs avfs_vinobjs; + struct avfsfllobjs avfs_fllobjs; + struct clk_domains clk_domainobjs; + struct clk_progs clk_progobjs; + struct clk_vf_points clk_vf_pointobjs; + struct clk_mclk_state clk_mclk; + struct clk_freq_controllers clk_freq_controllers; +}; + +struct clockentry { + u8 vbios_clk_domain; + u8 clk_which; + u8 perf_index; + u32 api_clk_domain; +}; + +struct change_fll_clk { + u32 api_clk_domain; + u16 clkmhz; + u32 voltuv; +}; + +struct set_fll_clk { + u32 voltuv; + u16 gpc2clkmhz; + u32 current_regime_id_gpc; + u32 target_regime_id_gpc; + u16 sys2clkmhz; + u32 current_regime_id_sys; + u32 target_regime_id_sys; + u16 xbar2clkmhz; + u32 current_regime_id_xbar; + u32 target_regime_id_xbar; +}; + +#define NV_PERF_HEADER_4X_CLOCKS_DOMAINS_MAX_NUMCLKS 9 + +struct vbios_clock_domain { + u8 clock_type; + u8 num_domains; + struct clockentry clock_entry[NV_PERF_HEADER_4X_CLOCKS_DOMAINS_MAX_NUMCLKS]; +}; + +struct vbios_clocks_table_1x_hal_clock_entry { + enum nv_pmu_clk_clkwhich domain; + bool b_noise_aware_capable; + u8 clk_vf_curve_count; +}; + +#define NV_PERF_HEADER_4X_CLOCKS_DOMAINS_4_GPC2CLK 0 +#define NV_PERF_HEADER_4X_CLOCKS_DOMAINS_4_XBAR2CLK 1 +#define NV_PERF_HEADER_4X_CLOCKS_DOMAINS_4_DRAMCLK 2 +#define NV_PERF_HEADER_4X_CLOCKS_DOMAINS_4_SYS2CLK 3 +#define NV_PERF_HEADER_4X_CLOCKS_DOMAINS_4_HUB2CLK 4 +#define NV_PERF_HEADER_4X_CLOCKS_DOMAINS_4_MSDCLK 5 +#define NV_PERF_HEADER_4X_CLOCKS_DOMAINS_4_PWRCLK 6 +#define NV_PERF_HEADER_4X_CLOCKS_DOMAINS_4_DISPCLK 7 +#define NV_PERF_HEADER_4X_CLOCKS_DOMAINS_4_NUMCLKS 8 + +#define PERF_CLK_MCLK 0 +#define PERF_CLK_DISPCLK 1 +#define PERF_CLK_GPC2CLK 2 +#define PERF_CLK_HOSTCLK 3 +#define PERF_CLK_LTC2CLK 4 +#define PERF_CLK_SYS2CLK 5 +#define PERF_CLK_HUB2CLK 6 +#define PERF_CLK_LEGCLK 7 +#define PERF_CLK_MSDCLK 8 +#define PERF_CLK_XCLK 9 +#define PERF_CLK_PWRCLK 10 +#define PERF_CLK_XBAR2CLK 11 +#define PERF_CLK_PCIEGENCLK 12 +#define PERF_CLK_NUM 13 + +#define BOOT_GPC2CLK_MHZ 2581 + +u32 clk_pmu_vin_load(struct gk20a *g); +u32 clk_domain_print_vf_table(struct gk20a *g, u32 clkapidomain); +u32 clk_domain_get_f_or_v( + struct gk20a *g, + u32 clkapidomain, + u16 *pclkmhz, + u32 *pvoltuv, + u8 railidx +); +int clk_get_fll_clks(struct gk20a *g, struct set_fll_clk *fllclk); +int clk_set_fll_clks(struct gk20a *g, struct set_fll_clk *fllclk); +int clk_pmu_freq_controller_load(struct gk20a *g, bool bload, u8 bit_idx); +u32 nvgpu_clk_vf_change_inject_data_fill_gv10x(struct gk20a *g, + struct nv_pmu_clk_rpc *rpccall, + struct set_fll_clk *setfllclk); +u32 nvgpu_clk_vf_change_inject_data_fill_gp10x(struct gk20a *g, + struct nv_pmu_clk_rpc *rpccall, + struct set_fll_clk *setfllclk); +u32 nvgpu_clk_set_boot_fll_clk_gv10x(struct gk20a *g); +int nvgpu_clk_set_fll_clk_gv10x(struct gk20a *g); +int clk_pmu_freq_effective_avg_load(struct gk20a *g, bool bload); +u32 clk_freq_effective_avg(struct gk20a *g, u32 clkDomainMask); +#endif /* NVGPU_CLK_H */ diff --git a/include/clk/clk_arb.c b/include/clk/clk_arb.c new file mode 100644 index 0000000..6cf005c --- /dev/null +++ b/include/clk/clk_arb.c @@ -0,0 +1,1087 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk/clk.h" +#include "pstate/pstate.h" +#include "lpwr/lpwr.h" +#include "volt/volt.h" + +int nvgpu_clk_notification_queue_alloc(struct gk20a *g, + struct nvgpu_clk_notification_queue *queue, + size_t events_number) { + queue->notifications = nvgpu_kcalloc(g, events_number, + sizeof(struct nvgpu_clk_notification)); + if (!queue->notifications) + return -ENOMEM; + queue->size = events_number; + + nvgpu_atomic_set(&queue->head, 0); + nvgpu_atomic_set(&queue->tail, 0); + + return 0; +} + +void nvgpu_clk_notification_queue_free(struct gk20a *g, + struct nvgpu_clk_notification_queue *queue) { + if (queue->size > 0) { + nvgpu_kfree(g, queue->notifications); + queue->size = 0; + nvgpu_atomic_set(&queue->head, 0); + nvgpu_atomic_set(&queue->tail, 0); + } +} + +static void nvgpu_clk_arb_queue_notification(struct gk20a *g, + struct nvgpu_clk_notification_queue *queue, + u32 alarm_mask) { + + u32 queue_index; + u64 timestamp; + + queue_index = (nvgpu_atomic_inc_return(&queue->tail)) % queue->size; + /* get current timestamp */ + timestamp = (u64) nvgpu_hr_timestamp(); + + queue->notifications[queue_index].timestamp = timestamp; + queue->notifications[queue_index].notification = alarm_mask; + +} + +void nvgpu_clk_arb_set_global_alarm(struct gk20a *g, u32 alarm) +{ + struct nvgpu_clk_arb *arb = g->clk_arb; + + u64 current_mask; + u32 refcnt; + u32 alarm_mask; + u64 new_mask; + + do { + current_mask = nvgpu_atomic64_read(&arb->alarm_mask); + /* atomic operations are strong so they do not need masks */ + + refcnt = ((u32) (current_mask >> 32)) + 1; + alarm_mask = (u32) (current_mask & ~0) | alarm; + new_mask = ((u64) refcnt << 32) | alarm_mask; + + } while (unlikely(current_mask != + (u64)nvgpu_atomic64_cmpxchg(&arb->alarm_mask, + current_mask, new_mask))); + + nvgpu_clk_arb_queue_notification(g, &arb->notification_queue, alarm); +} + + +int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb) +{ + struct gk20a *g = arb->g; + struct nvgpu_clk_vf_table *table; + + u32 i, j; + int status = -EINVAL; + u32 gpc2clk_voltuv = 0, mclk_voltuv = 0; + u32 gpc2clk_voltuv_sram = 0, mclk_voltuv_sram = 0; + u16 clk_cur; + u32 num_points; + + struct clk_set_info *p5_info, *p0_info; + + table = NV_ACCESS_ONCE(arb->current_vf_table); + /* make flag visible when all data has resolved in the tables */ + nvgpu_smp_rmb(); + + table = (table == &arb->vf_table_pool[0]) ? &arb->vf_table_pool[1] : + &arb->vf_table_pool[0]; + + /* Get allowed memory ranges */ + if (g->ops.clk_arb.get_arbiter_clk_range(g, CTRL_CLK_DOMAIN_GPC2CLK, + &arb->gpc2clk_min, + &arb->gpc2clk_max) < 0) { + nvgpu_err(g, "failed to fetch GPC2CLK range"); + goto exit_vf_table; + } + if (g->ops.clk_arb.get_arbiter_clk_range(g, CTRL_CLK_DOMAIN_MCLK, + &arb->mclk_min, + &arb->mclk_max) < 0) { + nvgpu_err(g, "failed to fetch MCLK range"); + goto exit_vf_table; + } + + table->gpc2clk_num_points = MAX_F_POINTS; + table->mclk_num_points = MAX_F_POINTS; + + if (g->ops.clk.clk_domain_get_f_points(arb->g, CTRL_CLK_DOMAIN_GPC2CLK, + &table->gpc2clk_num_points, arb->gpc2clk_f_points)) { + nvgpu_err(g, "failed to fetch GPC2CLK frequency points"); + goto exit_vf_table; + } + + if (g->ops.clk.clk_domain_get_f_points(arb->g, CTRL_CLK_DOMAIN_MCLK, + &table->mclk_num_points, arb->mclk_f_points)) { + nvgpu_err(g, "failed to fetch MCLK frequency points"); + goto exit_vf_table; + } + if (!table->mclk_num_points || !table->gpc2clk_num_points) { + nvgpu_err(g, "empty queries to f points mclk %d gpc2clk %d", + table->mclk_num_points, table->gpc2clk_num_points); + status = -EINVAL; + goto exit_vf_table; + } + + memset(table->mclk_points, 0, + table->mclk_num_points*sizeof(struct nvgpu_clk_vf_point)); + memset(table->gpc2clk_points, 0, + table->gpc2clk_num_points*sizeof(struct nvgpu_clk_vf_point)); + + p5_info = pstate_get_clk_set_info(g, + CTRL_PERF_PSTATE_P5, clkwhich_mclk); + if (!p5_info) { + nvgpu_err(g, "failed to get MCLK P5 info"); + goto exit_vf_table; + } + p0_info = pstate_get_clk_set_info(g, + CTRL_PERF_PSTATE_P0, clkwhich_mclk); + if (!p0_info) { + nvgpu_err(g, "failed to get MCLK P0 info"); + goto exit_vf_table; + } + + for (i = 0, j = 0, num_points = 0, clk_cur = 0; + i < table->mclk_num_points; i++) { + + if ((arb->mclk_f_points[i] >= arb->mclk_min) && + (arb->mclk_f_points[i] <= arb->mclk_max) && + (arb->mclk_f_points[i] != clk_cur)) { + + table->mclk_points[j].mem_mhz = arb->mclk_f_points[i]; + mclk_voltuv = mclk_voltuv_sram = 0; + + status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_MCLK, + &table->mclk_points[j].mem_mhz, &mclk_voltuv, + CTRL_VOLT_DOMAIN_LOGIC); + if (status < 0) { + nvgpu_err(g, + "failed to get MCLK LOGIC voltage"); + goto exit_vf_table; + } + status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_MCLK, + &table->mclk_points[j].mem_mhz, + &mclk_voltuv_sram, + CTRL_VOLT_DOMAIN_SRAM); + if (status < 0) { + nvgpu_err(g, "failed to get MCLK SRAM voltage"); + goto exit_vf_table; + } + + table->mclk_points[j].uvolt = mclk_voltuv; + table->mclk_points[j].uvolt_sram = mclk_voltuv_sram; + clk_cur = table->mclk_points[j].mem_mhz; + + if ((clk_cur >= p5_info->min_mhz) && + (clk_cur <= p5_info->max_mhz)) + VF_POINT_SET_PSTATE_SUPPORTED( + &table->mclk_points[j], + CTRL_PERF_PSTATE_P5); + if ((clk_cur >= p0_info->min_mhz) && + (clk_cur <= p0_info->max_mhz)) + VF_POINT_SET_PSTATE_SUPPORTED( + &table->mclk_points[j], + CTRL_PERF_PSTATE_P0); + + j++; + num_points++; + + } + } + table->mclk_num_points = num_points; + + p5_info = pstate_get_clk_set_info(g, + CTRL_PERF_PSTATE_P5, clkwhich_gpc2clk); + if (!p5_info) { + status = -EINVAL; + nvgpu_err(g, "failed to get GPC2CLK P5 info"); + goto exit_vf_table; + } + + p0_info = pstate_get_clk_set_info(g, + CTRL_PERF_PSTATE_P0, clkwhich_gpc2clk); + if (!p0_info) { + status = -EINVAL; + nvgpu_err(g, "failed to get GPC2CLK P0 info"); + goto exit_vf_table; + } + + /* GPC2CLK needs to be checked in two passes. The first determines the + * relationships between GPC2CLK, SYS2CLK and XBAR2CLK, while the + * second verifies that the clocks minimum is satisfied and sets + * the voltages + */ + for (i = 0, j = 0, num_points = 0, clk_cur = 0; + i < table->gpc2clk_num_points; i++) { + struct set_fll_clk setfllclk; + + if ((arb->gpc2clk_f_points[i] >= arb->gpc2clk_min) && + (arb->gpc2clk_f_points[i] <= arb->gpc2clk_max) && + (arb->gpc2clk_f_points[i] != clk_cur)) { + + table->gpc2clk_points[j].gpc_mhz = + arb->gpc2clk_f_points[i]; + setfllclk.gpc2clkmhz = arb->gpc2clk_f_points[i]; + status = clk_get_fll_clks(g, &setfllclk); + if (status < 0) { + nvgpu_err(g, + "failed to get GPC2CLK slave clocks"); + goto exit_vf_table; + } + + table->gpc2clk_points[j].sys_mhz = + setfllclk.sys2clkmhz; + table->gpc2clk_points[j].xbar_mhz = + setfllclk.xbar2clkmhz; + + clk_cur = table->gpc2clk_points[j].gpc_mhz; + + if ((clk_cur >= p5_info->min_mhz) && + (clk_cur <= p5_info->max_mhz)) + VF_POINT_SET_PSTATE_SUPPORTED( + &table->gpc2clk_points[j], + CTRL_PERF_PSTATE_P5); + if ((clk_cur >= p0_info->min_mhz) && + (clk_cur <= p0_info->max_mhz)) + VF_POINT_SET_PSTATE_SUPPORTED( + &table->gpc2clk_points[j], + CTRL_PERF_PSTATE_P0); + + j++; + num_points++; + } + } + table->gpc2clk_num_points = num_points; + + /* Second pass */ + for (i = 0, j = 0; i < table->gpc2clk_num_points; i++) { + + u16 alt_gpc2clk = table->gpc2clk_points[i].gpc_mhz; + + gpc2clk_voltuv = gpc2clk_voltuv_sram = 0; + + /* Check sysclk */ + p5_info = pstate_get_clk_set_info(g, + VF_POINT_GET_PSTATE(&table->gpc2clk_points[i]), + clkwhich_sys2clk); + if (!p5_info) { + status = -EINVAL; + nvgpu_err(g, "failed to get SYS2CLK P5 info"); + goto exit_vf_table; + } + + /* sys2clk below clk min, need to find correct clock */ + if (table->gpc2clk_points[i].sys_mhz < p5_info->min_mhz) { + for (j = i + 1; j < table->gpc2clk_num_points; j++) { + + if (table->gpc2clk_points[j].sys_mhz >= + p5_info->min_mhz) { + + + table->gpc2clk_points[i].sys_mhz = + p5_info->min_mhz; + + alt_gpc2clk = alt_gpc2clk < + table->gpc2clk_points[j]. + gpc_mhz ? + table->gpc2clk_points[j]. + gpc_mhz : + alt_gpc2clk; + break; + } + } + /* no VF exists that satisfies condition */ + if (j == table->gpc2clk_num_points) { + nvgpu_err(g, "NO SYS2CLK VF point possible"); + status = -EINVAL; + goto exit_vf_table; + } + } + + /* Check xbarclk */ + p5_info = pstate_get_clk_set_info(g, + VF_POINT_GET_PSTATE(&table->gpc2clk_points[i]), + clkwhich_xbar2clk); + if (!p5_info) { + status = -EINVAL; + nvgpu_err(g, "failed to get SYS2CLK P5 info"); + goto exit_vf_table; + } + + /* xbar2clk below clk min, need to find correct clock */ + if (table->gpc2clk_points[i].xbar_mhz < p5_info->min_mhz) { + for (j = i; j < table->gpc2clk_num_points; j++) { + if (table->gpc2clk_points[j].xbar_mhz >= + p5_info->min_mhz) { + + table->gpc2clk_points[i].xbar_mhz = + p5_info->min_mhz; + + alt_gpc2clk = alt_gpc2clk < + table->gpc2clk_points[j]. + gpc_mhz ? + table->gpc2clk_points[j]. + gpc_mhz : + alt_gpc2clk; + break; + } + } + /* no VF exists that satisfies condition */ + if (j == table->gpc2clk_num_points) { + status = -EINVAL; + nvgpu_err(g, "NO XBAR2CLK VF point possible"); + + goto exit_vf_table; + } + } + + /* Calculate voltages */ + status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_GPC2CLK, + &alt_gpc2clk, &gpc2clk_voltuv, + CTRL_VOLT_DOMAIN_LOGIC); + if (status < 0) { + nvgpu_err(g, "failed to get GPC2CLK LOGIC voltage"); + goto exit_vf_table; + } + + status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_GPC2CLK, + &alt_gpc2clk, + &gpc2clk_voltuv_sram, + CTRL_VOLT_DOMAIN_SRAM); + if (status < 0) { + nvgpu_err(g, "failed to get GPC2CLK SRAM voltage"); + goto exit_vf_table; + } + + table->gpc2clk_points[i].uvolt = gpc2clk_voltuv; + table->gpc2clk_points[i].uvolt_sram = gpc2clk_voltuv_sram; + } + + /* make table visible when all data has resolved in the tables */ + nvgpu_smp_wmb(); + arb->current_vf_table = table; + +exit_vf_table: + + if (status < 0) + nvgpu_clk_arb_set_global_alarm(g, + EVENT(ALARM_VF_TABLE_UPDATE_FAILED)); + nvgpu_clk_arb_worker_enqueue(g, &arb->update_arb_work_item); + + return status; +} + + +static void nvgpu_clk_arb_run_vf_table_cb(struct nvgpu_clk_arb *arb) +{ + struct gk20a *g = arb->g; + u32 err; + + /* get latest vf curve from pmu */ + err = clk_vf_point_cache(g); + if (err) { + nvgpu_err(g, "failed to cache VF table"); + nvgpu_clk_arb_set_global_alarm(g, + EVENT(ALARM_VF_TABLE_UPDATE_FAILED)); + nvgpu_clk_arb_worker_enqueue(g, &arb->update_arb_work_item); + + return; + } + nvgpu_clk_arb_update_vf_table(arb); +} + +u32 nvgpu_clk_arb_notify(struct nvgpu_clk_dev *dev, + struct nvgpu_clk_arb_target *target, + u32 alarm) { + + struct nvgpu_clk_session *session = dev->session; + struct nvgpu_clk_arb *arb = session->g->clk_arb; + struct nvgpu_clk_notification *notification; + + u32 queue_alarm_mask = 0; + u32 enabled_mask = 0; + u32 new_alarms_reported = 0; + u32 poll_mask = 0; + u32 tail, head; + u32 queue_index; + size_t size; + int index; + + enabled_mask = nvgpu_atomic_read(&dev->enabled_mask); + size = arb->notification_queue.size; + + /* queue global arbiter notifications in buffer */ + do { + tail = nvgpu_atomic_read(&arb->notification_queue.tail); + /* copy items to the queue */ + queue_index = nvgpu_atomic_read(&dev->queue.tail); + head = dev->arb_queue_head; + head = (tail - head) < arb->notification_queue.size ? + head : tail - arb->notification_queue.size; + + for (index = head; _WRAPGTEQ(tail, index); index++) { + u32 alarm_detected; + + notification = &arb->notification_queue. + notifications[(index+1) % size]; + alarm_detected = + NV_ACCESS_ONCE(notification->notification); + + if (!(enabled_mask & alarm_detected)) + continue; + + queue_index++; + dev->queue.notifications[ + queue_index % dev->queue.size].timestamp = + NV_ACCESS_ONCE(notification->timestamp); + + dev->queue.notifications[ + queue_index % dev->queue.size].notification = + alarm_detected; + + queue_alarm_mask |= alarm_detected; + } + } while (unlikely(nvgpu_atomic_read(&arb->notification_queue.tail) != + (int)tail)); + + nvgpu_atomic_set(&dev->queue.tail, queue_index); + /* update the last notification we processed from global queue */ + + dev->arb_queue_head = tail; + + /* Check if current session targets are met */ + if (enabled_mask & EVENT(ALARM_LOCAL_TARGET_VF_NOT_POSSIBLE)) { + if ((target->gpc2clk < session->target->gpc2clk) + || (target->mclk < session->target->mclk)) { + + poll_mask |= (NVGPU_POLLIN | NVGPU_POLLPRI); + nvgpu_clk_arb_queue_notification(arb->g, &dev->queue, + EVENT(ALARM_LOCAL_TARGET_VF_NOT_POSSIBLE)); + } + } + + /* Check if there is a new VF update */ + if (queue_alarm_mask & EVENT(VF_UPDATE)) + poll_mask |= (NVGPU_POLLIN | NVGPU_POLLRDNORM); + + /* Notify sticky alarms that were not reported on previous run*/ + new_alarms_reported = (queue_alarm_mask | + (alarm & ~dev->alarms_reported & queue_alarm_mask)); + + if (new_alarms_reported & ~LOCAL_ALARM_MASK) { + /* check that we are not re-reporting */ + if (new_alarms_reported & EVENT(ALARM_GPU_LOST)) + poll_mask |= NVGPU_POLLHUP; + + poll_mask |= (NVGPU_POLLIN | NVGPU_POLLPRI); + /* On next run do not report global alarms that were already + * reported, but report SHUTDOWN always + */ + dev->alarms_reported = new_alarms_reported & ~LOCAL_ALARM_MASK & + ~EVENT(ALARM_GPU_LOST); + } + + if (poll_mask) { + nvgpu_atomic_set(&dev->poll_mask, poll_mask); + nvgpu_clk_arb_event_post_event(dev); + } + + return new_alarms_reported; +} + +void nvgpu_clk_arb_clear_global_alarm(struct gk20a *g, u32 alarm) +{ + struct nvgpu_clk_arb *arb = g->clk_arb; + + u64 current_mask; + u32 refcnt; + u32 alarm_mask; + u64 new_mask; + + do { + current_mask = nvgpu_atomic64_read(&arb->alarm_mask); + /* atomic operations are strong so they do not need masks */ + + refcnt = ((u32) (current_mask >> 32)) + 1; + alarm_mask = (u32) (current_mask & ~alarm); + new_mask = ((u64) refcnt << 32) | alarm_mask; + + } while (unlikely(current_mask != + (u64)nvgpu_atomic64_cmpxchg(&arb->alarm_mask, + current_mask, new_mask))); +} + +/* + * Process one scheduled work item. + */ +static void nvgpu_clk_arb_worker_process_item( + struct nvgpu_clk_arb_work_item *work_item) +{ + struct gk20a *g = work_item->arb->g; + + clk_arb_dbg(g, " "); + + if (work_item->item_type == CLK_ARB_WORK_UPDATE_VF_TABLE) + nvgpu_clk_arb_run_vf_table_cb(work_item->arb); + else if (work_item->item_type == CLK_ARB_WORK_UPDATE_ARB) + g->ops.clk_arb.clk_arb_run_arbiter_cb(work_item->arb); +} + +/** + * Tell the worker that one more work needs to be done. + * + * Increase the work counter to synchronize the worker with the new work. Wake + * up the worker. If the worker was already running, it will handle this work + * before going to sleep. + */ +static int nvgpu_clk_arb_worker_wakeup(struct gk20a *g) +{ + int put; + + clk_arb_dbg(g, " "); + + put = nvgpu_atomic_inc_return(&g->clk_arb_worker.put); + nvgpu_cond_signal_interruptible(&g->clk_arb_worker.wq); + + return put; +} + +/** + * Test if there is some work pending. + * + * This is a pair for nvgpu_clk_arb_worker_wakeup to be called from the + * worker. The worker has an internal work counter which is incremented once + * per finished work item. This is compared with the number of queued jobs. + */ +static bool nvgpu_clk_arb_worker_pending(struct gk20a *g, int get) +{ + bool pending = nvgpu_atomic_read(&g->clk_arb_worker.put) != get; + + /* We don't need barriers because they are implicit in locking */ + return pending; +} + +/** + * Process the queued works for the worker thread serially. + * + * Flush all the work items in the queue one by one. This may block timeout + * handling for a short while, as these are serialized. + */ +static void nvgpu_clk_arb_worker_process(struct gk20a *g, int *get) +{ + + while (nvgpu_clk_arb_worker_pending(g, *get)) { + struct nvgpu_clk_arb_work_item *work_item = NULL; + + nvgpu_spinlock_acquire(&g->clk_arb_worker.items_lock); + if (!nvgpu_list_empty(&g->clk_arb_worker.items)) { + work_item = nvgpu_list_first_entry(&g->clk_arb_worker.items, + nvgpu_clk_arb_work_item, worker_item); + nvgpu_list_del(&work_item->worker_item); + } + nvgpu_spinlock_release(&g->clk_arb_worker.items_lock); + + if (!work_item) { + /* + * Woke up for some other reason, but there are no + * other reasons than a work item added in the items list + * currently, so warn and ack the message. + */ + nvgpu_warn(g, "Spurious worker event!"); + ++*get; + break; + } + + nvgpu_clk_arb_worker_process_item(work_item); + ++*get; + } +} + +/* + * Process all work items found in the clk arbiter work queue. + */ +static int nvgpu_clk_arb_poll_worker(void *arg) +{ + struct gk20a *g = (struct gk20a *)arg; + struct gk20a_worker *worker = &g->clk_arb_worker; + int get = 0; + + clk_arb_dbg(g, " "); + + while (!nvgpu_thread_should_stop(&worker->poll_task)) { + int ret; + + ret = NVGPU_COND_WAIT_INTERRUPTIBLE( + &worker->wq, + nvgpu_clk_arb_worker_pending(g, get), 0); + + if (nvgpu_thread_should_stop(&worker->poll_task)) { + break; + } + + if (ret == 0) + nvgpu_clk_arb_worker_process(g, &get); + } + return 0; +} + +static int __nvgpu_clk_arb_worker_start(struct gk20a *g) +{ + char thread_name[64]; + int err = 0; + + if (nvgpu_thread_is_running(&g->clk_arb_worker.poll_task)) + return err; + + nvgpu_mutex_acquire(&g->clk_arb_worker.start_lock); + + /* + * Mutexes have implicit barriers, so there is no risk of a thread + * having a stale copy of the poll_task variable as the call to + * thread_is_running is volatile + */ + + if (nvgpu_thread_is_running(&g->clk_arb_worker.poll_task)) { + nvgpu_mutex_release(&g->clk_arb_worker.start_lock); + return err; + } + + snprintf(thread_name, sizeof(thread_name), + "nvgpu_clk_arb_poll_%s", g->name); + + err = nvgpu_thread_create(&g->clk_arb_worker.poll_task, g, + nvgpu_clk_arb_poll_worker, thread_name); + + nvgpu_mutex_release(&g->clk_arb_worker.start_lock); + return err; +} + +/** + * Append a work item to the worker's list. + * + * This adds work item to the end of the list and wakes the worker + * up immediately. If the work item already existed in the list, it's not added, + * because in that case it has been scheduled already but has not yet been + * processed. + */ +void nvgpu_clk_arb_worker_enqueue(struct gk20a *g, + struct nvgpu_clk_arb_work_item *work_item) +{ + clk_arb_dbg(g, " "); + + /* + * Warn if worker thread cannot run + */ + if (WARN_ON(__nvgpu_clk_arb_worker_start(g))) { + nvgpu_warn(g, "clk arb worker cannot run!"); + return; + } + + nvgpu_spinlock_acquire(&g->clk_arb_worker.items_lock); + if (!nvgpu_list_empty(&work_item->worker_item)) { + /* + * Already queued, so will get processed eventually. + * The worker is probably awake already. + */ + nvgpu_spinlock_release(&g->clk_arb_worker.items_lock); + return; + } + nvgpu_list_add_tail(&work_item->worker_item, &g->clk_arb_worker.items); + nvgpu_spinlock_release(&g->clk_arb_worker.items_lock); + + nvgpu_clk_arb_worker_wakeup(g); +} + +/** + * Initialize the clk arb worker's metadata and start the background thread. + */ +int nvgpu_clk_arb_worker_init(struct gk20a *g) +{ + int err; + + nvgpu_atomic_set(&g->clk_arb_worker.put, 0); + nvgpu_cond_init(&g->clk_arb_worker.wq); + nvgpu_init_list_node(&g->clk_arb_worker.items); + nvgpu_spinlock_init(&g->clk_arb_worker.items_lock); + err = nvgpu_mutex_init(&g->clk_arb_worker.start_lock); + if (err) + goto error_check; + + err = __nvgpu_clk_arb_worker_start(g); +error_check: + if (err) { + nvgpu_err(g, "failed to start clk arb poller thread"); + return err; + } + return 0; +} + +int nvgpu_clk_arb_init_arbiter(struct gk20a *g) +{ + int err = 0; + + if (!g->ops.clk.support_clk_freq_controller || + !g->ops.clk_arb.get_arbiter_clk_domains) { + return 0; + } + + nvgpu_mutex_acquire(&g->clk_arb_enable_lock); + + err = g->ops.clk_arb.arbiter_clk_init(g); + + nvgpu_mutex_release(&g->clk_arb_enable_lock); + + return err; +} + +bool nvgpu_clk_arb_has_active_req(struct gk20a *g) +{ + return (nvgpu_atomic_read(&g->clk_arb_global_nr) > 0); +} + +void nvgpu_clk_arb_send_thermal_alarm(struct gk20a *g) +{ + nvgpu_clk_arb_schedule_alarm(g, + (0x1UL << NVGPU_EVENT_ALARM_THERMAL_ABOVE_THRESHOLD)); +} + +void nvgpu_clk_arb_schedule_alarm(struct gk20a *g, u32 alarm) +{ + struct nvgpu_clk_arb *arb = g->clk_arb; + + nvgpu_clk_arb_set_global_alarm(g, alarm); + nvgpu_clk_arb_worker_enqueue(g, &arb->update_arb_work_item); +} + +static void nvgpu_clk_arb_worker_deinit(struct gk20a *g) +{ + nvgpu_atomic_inc(&g->clk_arb_worker.put); + + nvgpu_mutex_acquire(&g->clk_arb_worker.start_lock); + nvgpu_thread_stop(&g->clk_arb_worker.poll_task); + nvgpu_mutex_release(&g->clk_arb_worker.start_lock); +} + +void nvgpu_clk_arb_cleanup_arbiter(struct gk20a *g) +{ + struct nvgpu_clk_arb *arb = g->clk_arb; + + nvgpu_mutex_acquire(&g->clk_arb_enable_lock); + + if (arb) { + nvgpu_clk_arb_worker_deinit(g); + g->ops.clk_arb.clk_arb_cleanup(g->clk_arb); + } + + nvgpu_mutex_release(&g->clk_arb_enable_lock); +} + +int nvgpu_clk_arb_init_session(struct gk20a *g, + struct nvgpu_clk_session **_session) +{ + struct nvgpu_clk_arb *arb = g->clk_arb; + struct nvgpu_clk_session *session = *(_session); + + clk_arb_dbg(g, " "); + + if (!g->ops.clk.support_clk_freq_controller || + !g->ops.clk_arb.get_arbiter_clk_domains) { + return 0; + } + + session = nvgpu_kzalloc(g, sizeof(struct nvgpu_clk_session)); + if (!session) + return -ENOMEM; + session->g = g; + + nvgpu_ref_init(&session->refcount); + + session->zombie = false; + session->target_pool[0].pstate = CTRL_PERF_PSTATE_P8; + /* make sure that the initialization of the pool is visible + * before the update + */ + nvgpu_smp_wmb(); + session->target = &session->target_pool[0]; + + nvgpu_init_list_node(&session->targets); + nvgpu_spinlock_init(&session->session_lock); + + nvgpu_spinlock_acquire(&arb->sessions_lock); + nvgpu_list_add_tail(&session->link, &arb->sessions); + nvgpu_spinlock_release(&arb->sessions_lock); + + *_session = session; + + return 0; +} + +void nvgpu_clk_arb_free_fd(struct nvgpu_ref *refcount) +{ + struct nvgpu_clk_dev *dev = container_of(refcount, + struct nvgpu_clk_dev, refcount); + struct nvgpu_clk_session *session = dev->session; + struct gk20a *g = session->g; + + nvgpu_clk_notification_queue_free(g, &dev->queue); + + nvgpu_atomic_dec(&g->clk_arb_global_nr); + nvgpu_kfree(g, dev); +} + +void nvgpu_clk_arb_free_session(struct nvgpu_ref *refcount) +{ + struct nvgpu_clk_session *session = container_of(refcount, + struct nvgpu_clk_session, refcount); + struct nvgpu_clk_arb *arb = session->g->clk_arb; + struct gk20a *g = session->g; + struct nvgpu_clk_dev *dev, *tmp; + + clk_arb_dbg(g, " "); + + if (arb) { + nvgpu_spinlock_acquire(&arb->sessions_lock); + nvgpu_list_del(&session->link); + nvgpu_spinlock_release(&arb->sessions_lock); + } + + nvgpu_spinlock_acquire(&session->session_lock); + nvgpu_list_for_each_entry_safe(dev, tmp, &session->targets, + nvgpu_clk_dev, node) { + nvgpu_ref_put(&dev->refcount, nvgpu_clk_arb_free_fd); + nvgpu_list_del(&dev->node); + } + nvgpu_spinlock_release(&session->session_lock); + + nvgpu_kfree(g, session); +} + +void nvgpu_clk_arb_release_session(struct gk20a *g, + struct nvgpu_clk_session *session) +{ + struct nvgpu_clk_arb *arb = g->clk_arb; + + clk_arb_dbg(g, " "); + + session->zombie = true; + nvgpu_ref_put(&session->refcount, nvgpu_clk_arb_free_session); + if (arb) + nvgpu_clk_arb_worker_enqueue(g, &arb->update_arb_work_item); +} + +void nvgpu_clk_arb_schedule_vf_table_update(struct gk20a *g) +{ + struct nvgpu_clk_arb *arb = g->clk_arb; + + nvgpu_clk_arb_worker_enqueue(g, &arb->update_vf_table_work_item); +} + +/* This function is inherently unsafe to call while arbiter is running + * arbiter must be blocked before calling this function + */ +int nvgpu_clk_arb_get_current_pstate(struct gk20a *g) +{ + return NV_ACCESS_ONCE(g->clk_arb->actual->pstate); +} + +void nvgpu_clk_arb_pstate_change_lock(struct gk20a *g, bool lock) +{ + struct nvgpu_clk_arb *arb = g->clk_arb; + + if (lock) + nvgpu_mutex_acquire(&arb->pstate_lock); + else + nvgpu_mutex_release(&arb->pstate_lock); +} + +bool nvgpu_clk_arb_is_valid_domain(struct gk20a *g, u32 api_domain) +{ + u32 clk_domains = g->ops.clk_arb.get_arbiter_clk_domains(g); + + switch (api_domain) { + case NVGPU_CLK_DOMAIN_MCLK: + return (clk_domains & CTRL_CLK_DOMAIN_MCLK) != 0; + + case NVGPU_CLK_DOMAIN_GPCCLK: + return (clk_domains & CTRL_CLK_DOMAIN_GPC2CLK) != 0; + + default: + return false; + } +} + +int nvgpu_clk_arb_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, + u16 *min_mhz, u16 *max_mhz) +{ + int ret; + + switch (api_domain) { + case NVGPU_CLK_DOMAIN_MCLK: + ret = g->ops.clk_arb.get_arbiter_clk_range(g, + CTRL_CLK_DOMAIN_MCLK, min_mhz, max_mhz); + return ret; + + case NVGPU_CLK_DOMAIN_GPCCLK: + ret = g->ops.clk_arb.get_arbiter_clk_range(g, + CTRL_CLK_DOMAIN_GPC2CLK, min_mhz, max_mhz); + if (!ret) { + *min_mhz /= 2; + *max_mhz /= 2; + } + return ret; + + default: + return -EINVAL; + } +} + +int nvgpu_clk_arb_get_arbiter_clk_f_points(struct gk20a *g, + u32 api_domain, u32 *max_points, u16 *fpoints) +{ + int err; + u32 i; + + switch (api_domain) { + case NVGPU_CLK_DOMAIN_GPCCLK: + err = g->ops.clk_arb.get_arbiter_f_points(g, + CTRL_CLK_DOMAIN_GPC2CLK, max_points, fpoints); + if (err || !fpoints) + return err; + for (i = 0; i < *max_points; i++) + fpoints[i] /= 2; + return 0; + case NVGPU_CLK_DOMAIN_MCLK: + return g->ops.clk_arb.get_arbiter_f_points(g, + CTRL_CLK_DOMAIN_MCLK, max_points, fpoints); + default: + return -EINVAL; + } +} + +int nvgpu_clk_arb_get_session_target_mhz(struct nvgpu_clk_session *session, + u32 api_domain, u16 *freq_mhz) +{ + int err = 0; + struct nvgpu_clk_arb_target *target = session->target; + + if (!nvgpu_clk_arb_is_valid_domain(session->g, api_domain)) { + return -EINVAL; + } + + switch (api_domain) { + case NVGPU_CLK_DOMAIN_MCLK: + *freq_mhz = target->mclk; + break; + + case NVGPU_CLK_DOMAIN_GPCCLK: + *freq_mhz = target->gpc2clk / 2ULL; + break; + + default: + *freq_mhz = 0; + err = -EINVAL; + } + return err; +} + +int nvgpu_clk_arb_get_arbiter_actual_mhz(struct gk20a *g, + u32 api_domain, u16 *freq_mhz) +{ + struct nvgpu_clk_arb *arb = g->clk_arb; + int err = 0; + struct nvgpu_clk_arb_target *actual = arb->actual; + + if (!nvgpu_clk_arb_is_valid_domain(g, api_domain)) { + return -EINVAL; + } + + switch (api_domain) { + case NVGPU_CLK_DOMAIN_MCLK: + *freq_mhz = actual->mclk; + break; + + case NVGPU_CLK_DOMAIN_GPCCLK: + *freq_mhz = actual->gpc2clk / 2ULL; + break; + + default: + *freq_mhz = 0; + err = -EINVAL; + } + return err; +} + +unsigned long nvgpu_clk_measure_freq(struct gk20a *g, u32 api_domain) +{ + unsigned long freq = 0UL; + + switch (api_domain) { + case CTRL_CLK_DOMAIN_GPC2CLK: + freq = g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_GPCCLK) * 2UL; + break; + default: + break; + } + return freq; +} + +int nvgpu_clk_arb_get_arbiter_effective_mhz(struct gk20a *g, + u32 api_domain, u16 *freq_mhz) +{ + if (!nvgpu_clk_arb_is_valid_domain(g, api_domain)) { + return -EINVAL; + } + + switch (api_domain) { + case NVGPU_CLK_DOMAIN_MCLK: + *freq_mhz = g->ops.clk.measure_freq(g, CTRL_CLK_DOMAIN_MCLK) / + 1000000ULL; + return 0; + + case NVGPU_CLK_DOMAIN_GPCCLK: + *freq_mhz = g->ops.clk.measure_freq(g, + CTRL_CLK_DOMAIN_GPC2CLK) / 2000000ULL; + return 0; + + default: + return -EINVAL; + } +} diff --git a/include/clk/clk_domain.c b/include/clk/clk_domain.c new file mode 100644 index 0000000..3b64f51 --- /dev/null +++ b/include/clk/clk_domain.c @@ -0,0 +1,1666 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "clk.h" +#include "clk_fll.h" +#include "clk_domain.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "ctrl/ctrlclk.h" +#include "ctrl/ctrlvolt.h" + +static struct clk_domain *construct_clk_domain(struct gk20a *g, void *pargs); + +static int devinit_get_clocks_table(struct gk20a *g, + struct clk_domains *pdomainobjs); + +static int clk_domain_pmudatainit_super(struct gk20a *g, struct boardobj + *board_obj_ptr, struct nv_pmu_boardobj *ppmudata); + +static struct vbios_clocks_table_1x_hal_clock_entry + vbiosclktbl1xhalentry_gp[] = { + { clkwhich_gpc2clk, true, 1, }, + { clkwhich_xbar2clk, true, 1, }, + { clkwhich_mclk, false, 1, }, + { clkwhich_sys2clk, true, 1, }, + { clkwhich_hub2clk, false, 1, }, + { clkwhich_nvdclk, false, 1, }, + { clkwhich_pwrclk, false, 1, }, + { clkwhich_dispclk, false, 1, }, + { clkwhich_pciegenclk, false, 1, } +}; +/* + * Updated from RM devinit_clock.c + * GV100 is 0x03 and + * GP10x is 0x02 in clocks_hal. + */ +static struct vbios_clocks_table_1x_hal_clock_entry + vbiosclktbl1xhalentry_gv[] = { + { clkwhich_gpcclk, true, 2, }, + { clkwhich_xbarclk, true, 1, }, + { clkwhich_mclk, false, 1, }, + { clkwhich_sysclk, true, 1, }, + { clkwhich_hubclk, false, 1, }, + { clkwhich_nvdclk, true, 1, }, + { clkwhich_pwrclk, false, 1, }, + { clkwhich_dispclk, false, 1, }, + { clkwhich_pciegenclk, false, 1, }, + { clkwhich_hostclk, true, 1, } +}; + +static u32 clktranslatehalmumsettoapinumset(u32 clkhaldomains) +{ + u32 clkapidomains = 0; + + if (clkhaldomains & BIT(clkwhich_gpcclk)) { + clkapidomains |= CTRL_CLK_DOMAIN_GPCCLK; + } + if (clkhaldomains & BIT(clkwhich_xbarclk)) { + clkapidomains |= CTRL_CLK_DOMAIN_XBARCLK; + } + if (clkhaldomains & BIT(clkwhich_sysclk)) { + clkapidomains |= CTRL_CLK_DOMAIN_SYSCLK; + } + if (clkhaldomains & BIT(clkwhich_hubclk)) { + clkapidomains |= CTRL_CLK_DOMAIN_HUBCLK; + } + if (clkhaldomains & BIT(clkwhich_hostclk)) { + clkapidomains |= CTRL_CLK_DOMAIN_HOSTCLK; + } + if (clkhaldomains & BIT(clkwhich_gpc2clk)) { + clkapidomains |= CTRL_CLK_DOMAIN_GPC2CLK; + } + if (clkhaldomains & BIT(clkwhich_xbar2clk)) { + clkapidomains |= CTRL_CLK_DOMAIN_XBAR2CLK; + } + if (clkhaldomains & BIT(clkwhich_sys2clk)) { + clkapidomains |= CTRL_CLK_DOMAIN_SYS2CLK; + } + if (clkhaldomains & BIT(clkwhich_hub2clk)) { + clkapidomains |= CTRL_CLK_DOMAIN_HUB2CLK; + } + if (clkhaldomains & BIT(clkwhich_pwrclk)) { + clkapidomains |= CTRL_CLK_DOMAIN_PWRCLK; + } + if (clkhaldomains & BIT(clkwhich_pciegenclk)) { + clkapidomains |= CTRL_CLK_DOMAIN_PCIEGENCLK; + } + if (clkhaldomains & BIT(clkwhich_mclk)) { + clkapidomains |= CTRL_CLK_DOMAIN_MCLK; + } + if (clkhaldomains & BIT(clkwhich_nvdclk)) { + clkapidomains |= CTRL_CLK_DOMAIN_NVDCLK; + } + if (clkhaldomains & BIT(clkwhich_dispclk)) { + clkapidomains |= CTRL_CLK_DOMAIN_DISPCLK; + } + + return clkapidomains; +} + +static int _clk_domains_pmudatainit_3x(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + struct nv_pmu_clk_clk_domain_boardobjgrp_set_header *pset = + (struct nv_pmu_clk_clk_domain_boardobjgrp_set_header *) + pboardobjgrppmu; + struct clk_domains *pdomains = (struct clk_domains *)pboardobjgrp; + int status = 0; + + status = boardobjgrp_pmudatainit_e32(g, pboardobjgrp, pboardobjgrppmu); + if (status) { + nvgpu_err(g, + "error updating pmu boardobjgrp for clk domain 0x%x", + status); + goto done; + } + + pset->vbios_domains = pdomains->vbios_domains; + pset->cntr_sampling_periodms = pdomains->cntr_sampling_periodms; + pset->version = CLK_DOMAIN_BOARDOBJGRP_VERSION; + pset->b_override_o_v_o_c = false; + pset->b_debug_mode = false; + pset->b_enforce_vf_monotonicity = pdomains->b_enforce_vf_monotonicity; + pset->b_enforce_vf_smoothening = pdomains->b_enforce_vf_smoothening; + if (g->ops.clk.split_rail_support) { + pset->volt_rails_max = 2; + } else { + pset->volt_rails_max = 1; + } + status = boardobjgrpmask_export( + &pdomains->master_domains_mask.super, + pdomains->master_domains_mask.super.bitcount, + &pset->master_domains_mask.super); + + memcpy(&pset->deltas, &pdomains->deltas, + (sizeof(struct ctrl_clk_clk_delta))); + +done: + return status; +} + +static int _clk_domains_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_clk_clk_domain_boardobj_grp_set *pgrp_set = + (struct nv_pmu_clk_clk_domain_boardobj_grp_set *) + pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + nvgpu_log_info(g, " Done"); + return 0; +} + +int clk_domain_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + struct clk_domains *pclkdomainobjs; + struct clk_domain *pdomain; + struct clk_domain_3x_master *pdomain_master; + struct clk_domain_3x_slave *pdomain_slave; + u8 i; + + nvgpu_log_info(g, " "); + + status = boardobjgrpconstruct_e32(g, &g->clk_pmu.clk_domainobjs.super); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for clk domain, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->clk_pmu.clk_domainobjs.super.super; + pclkdomainobjs = &(g->clk_pmu.clk_domainobjs); + + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, CLK, CLK_DOMAIN); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + clk, CLK, clk_domain, CLK_DOMAIN); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + pboardobjgrp->pmudatainit = _clk_domains_pmudatainit_3x; + pboardobjgrp->pmudatainstget = _clk_domains_pmudata_instget; + + /* Initialize mask to zero.*/ + boardobjgrpmask_e32_init(&pclkdomainobjs->prog_domains_mask, NULL); + boardobjgrpmask_e32_init(&pclkdomainobjs->master_domains_mask, NULL); + pclkdomainobjs->b_enforce_vf_monotonicity = true; + pclkdomainobjs->b_enforce_vf_smoothening = true; + + memset(&pclkdomainobjs->ordered_noise_aware_list, 0, + sizeof(pclkdomainobjs->ordered_noise_aware_list)); + + memset(&pclkdomainobjs->ordered_noise_unaware_list, 0, + sizeof(pclkdomainobjs->ordered_noise_unaware_list)); + + memset(&pclkdomainobjs->deltas, 0, + sizeof(struct ctrl_clk_clk_delta)); + + status = devinit_get_clocks_table(g, pclkdomainobjs); + if (status) { + goto done; + } + + BOARDOBJGRP_FOR_EACH(&(pclkdomainobjs->super.super), + struct clk_domain *, pdomain, i) { + pdomain_master = NULL; + if (pdomain->super.implements(g, &pdomain->super, + CTRL_CLK_CLK_DOMAIN_TYPE_3X_PROG)) { + status = boardobjgrpmask_bitset( + &pclkdomainobjs->prog_domains_mask.super, i); + if (status) { + goto done; + } + } + + if (pdomain->super.implements(g, &pdomain->super, + CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER)) { + status = boardobjgrpmask_bitset( + &pclkdomainobjs->master_domains_mask.super, i); + if (status) { + goto done; + } + } + + if (pdomain->super.implements(g, &pdomain->super, + CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE)) { + pdomain_slave = + (struct clk_domain_3x_slave *)pdomain; + pdomain_master = + (struct clk_domain_3x_master *) + (CLK_CLK_DOMAIN_GET((&g->clk_pmu), + pdomain_slave->master_idx)); + pdomain_master->slave_idxs_mask |= BIT(i); + } + + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int clk_domain_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + pboardobjgrp = &g->clk_pmu.clk_domainobjs.super.super; + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + nvgpu_log_info(g, "Done"); + return status; +} + +static int devinit_get_clocks_table_35(struct gk20a *g, + struct clk_domains *pclkdomainobjs, u8 *clocks_table_ptr) +{ + int status = 0; + struct vbios_clocks_table_35_header clocks_table_header = { 0 }; + struct vbios_clocks_table_35_entry clocks_table_entry = { 0 }; + struct vbios_clocks_table_1x_hal_clock_entry *vbiosclktbl1xhalentry; + u8 *clocks_tbl_entry_ptr = NULL; + u32 index = 0; + struct clk_domain *pclkdomain_dev; + union { + struct boardobj boardobj; + struct clk_domain clk_domain; + struct clk_domain_3x v3x; + struct clk_domain_3x_fixed v3x_fixed; + struct clk_domain_35_prog v35_prog; + struct clk_domain_35_master v35_master; + struct clk_domain_35_slave v35_slave; + } clk_domain_data; + + nvgpu_log_info(g, " "); + + memcpy(&clocks_table_header, clocks_table_ptr, + VBIOS_CLOCKS_TABLE_35_HEADER_SIZE_09); + if (clocks_table_header.header_size < + (u8) VBIOS_CLOCKS_TABLE_35_HEADER_SIZE_09) { + status = -EINVAL; + goto done; + } + + if (clocks_table_header.entry_size < + (u8) VBIOS_CLOCKS_TABLE_35_ENTRY_SIZE_11) { + status = -EINVAL; + goto done; + } + + switch (clocks_table_header.clocks_hal) { + case CLK_TABLE_HAL_ENTRY_GP: + { + vbiosclktbl1xhalentry = vbiosclktbl1xhalentry_gp; + break; + } + case CLK_TABLE_HAL_ENTRY_GV: + { + vbiosclktbl1xhalentry = vbiosclktbl1xhalentry_gv; + break; + } + default: + { + status = -EINVAL; + goto done; + } + } + + pclkdomainobjs->cntr_sampling_periodms = + (u16)clocks_table_header.cntr_sampling_periodms; + + /* Read table entries*/ + clocks_tbl_entry_ptr = clocks_table_ptr + + clocks_table_header.header_size; + for (index = 0; index < clocks_table_header.entry_count; index++) { + memcpy((void*) &clocks_table_entry, (void*) clocks_tbl_entry_ptr, + clocks_table_header.entry_size); + clk_domain_data.clk_domain.domain = + (u8) vbiosclktbl1xhalentry[index].domain; + clk_domain_data.clk_domain.api_domain = + clktranslatehalmumsettoapinumset( + (u32) BIT(clk_domain_data.clk_domain.domain)); + clk_domain_data.v3x.b_noise_aware_capable = + vbiosclktbl1xhalentry[index].b_noise_aware_capable; + + switch (BIOS_GET_FIELD(clocks_table_entry.flags0, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE)) { + case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_FIXED: + { + clk_domain_data.boardobj.type = + CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED; + clk_domain_data.v3x_fixed.freq_mhz = (u16)BIOS_GET_FIELD( + clocks_table_entry.param1, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_FIXED_FREQUENCY_MHZ); + break; + } + + case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_MASTER: + { + clk_domain_data.boardobj.type = + CTRL_CLK_CLK_DOMAIN_TYPE_35_MASTER; + clk_domain_data.v35_prog.super.clk_prog_idx_first = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param0, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_FIRST)); + clk_domain_data.v35_prog.super.clk_prog_idx_last = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param0, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_LAST)); + clk_domain_data.v35_prog.super.noise_unaware_ordering_index = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_UNAWARE_ORDERING_IDX)); + if (clk_domain_data.v3x.b_noise_aware_capable) { + clk_domain_data.v35_prog.super.b_force_noise_unaware_ordering = + (bool)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING)); + + } else { + clk_domain_data.v35_prog.super.noise_aware_ordering_index = + CTRL_CLK_CLK_DOMAIN_3X_PROG_ORDERING_INDEX_INVALID; + clk_domain_data.v35_prog.super.b_force_noise_unaware_ordering = false; + } + clk_domain_data.v35_prog.pre_volt_ordering_index = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_PRE_VOLT_ORDERING_IDX)); + + clk_domain_data.v35_prog.post_volt_ordering_index = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_POST_VOLT_ORDERING_IDX)); + + clk_domain_data.v35_prog.super.factory_delta.data.delta_khz = 0; + clk_domain_data.v35_prog.super.factory_delta.type = 0; + + clk_domain_data.v35_prog.super.freq_delta_min_mhz = + (u16)(BIOS_GET_FIELD(clocks_table_entry.param1, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MIN_MHZ)); + + clk_domain_data.v35_prog.super.freq_delta_max_mhz = + (u16)(BIOS_GET_FIELD(clocks_table_entry.param1, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MAX_MHZ)); + clk_domain_data.v35_prog.clk_vf_curve_count = + vbiosclktbl1xhalentry[index].clk_vf_curve_count; + break; + } + + case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_SLAVE: + { + clk_domain_data.boardobj.type = + CTRL_CLK_CLK_DOMAIN_TYPE_35_SLAVE; + clk_domain_data.v35_prog.super.clk_prog_idx_first = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param0, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_FIRST)); + clk_domain_data.v35_prog.super.clk_prog_idx_last = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param0, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_LAST)); + clk_domain_data.v35_prog.super.noise_unaware_ordering_index = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_UNAWARE_ORDERING_IDX)); + + if (clk_domain_data.v3x.b_noise_aware_capable) { + clk_domain_data.v35_prog.super.b_force_noise_unaware_ordering = + (bool)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING)); + + } else { + clk_domain_data.v35_prog.super.noise_aware_ordering_index = + CTRL_CLK_CLK_DOMAIN_3X_PROG_ORDERING_INDEX_INVALID; + clk_domain_data.v35_prog.super.b_force_noise_unaware_ordering = false; + } + clk_domain_data.v35_prog.pre_volt_ordering_index = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_PRE_VOLT_ORDERING_IDX)); + + clk_domain_data.v35_prog.post_volt_ordering_index = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_POST_VOLT_ORDERING_IDX)); + + clk_domain_data.v35_prog.super.factory_delta.data.delta_khz = 0; + clk_domain_data.v35_prog.super.factory_delta.type = 0; + clk_domain_data.v35_prog.super.freq_delta_min_mhz = 0; + clk_domain_data.v35_prog.super.freq_delta_max_mhz = 0; + clk_domain_data.v35_slave.slave.master_idx = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param1, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_SLAVE_MASTER_DOMAIN)); + break; + } + + default: + { + nvgpu_err(g, + "error reading clock domain entry %d", index); + status = -EINVAL; + goto done; + } + + } + pclkdomain_dev = construct_clk_domain(g, + (void *)&clk_domain_data); + if (pclkdomain_dev == NULL) { + nvgpu_err(g, + "unable to construct clock domain boardobj for %d", + index); + status = -EINVAL; + goto done; + } + status = boardobjgrp_objinsert( + &pclkdomainobjs->super.super, + (struct boardobj *)(void*) pclkdomain_dev, index); + if (status != 0UL) { + nvgpu_err(g, + "unable to insert clock domain boardobj for %d", index); + status = (u32) -EINVAL; + goto done; + } + clocks_tbl_entry_ptr += clocks_table_header.entry_size; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +static int devinit_get_clocks_table_1x(struct gk20a *g, + struct clk_domains *pclkdomainobjs, u8 *clocks_table_ptr) +{ + int status = 0; + struct vbios_clocks_table_1x_header clocks_table_header = { 0 }; + struct vbios_clocks_table_1x_entry clocks_table_entry = { 0 }; + struct vbios_clocks_table_1x_hal_clock_entry *vbiosclktbl1xhalentry; + u8 *clocks_tbl_entry_ptr = NULL; + u32 index = 0; + struct clk_domain *pclkdomain_dev; + union { + struct boardobj boardobj; + struct clk_domain clk_domain; + struct clk_domain_3x v3x; + struct clk_domain_3x_fixed v3x_fixed; + struct clk_domain_3x_prog v3x_prog; + struct clk_domain_3x_master v3x_master; + struct clk_domain_3x_slave v3x_slave; + } clk_domain_data; + + nvgpu_log_info(g, " "); + + memcpy(&clocks_table_header, clocks_table_ptr, + VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07); + if (clocks_table_header.header_size < + (u8) VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07) { + status = -EINVAL; + goto done; + } + + if (clocks_table_header.entry_size < + (u8) VBIOS_CLOCKS_TABLE_1X_ENTRY_SIZE_09) { + status = -EINVAL; + goto done; + } + + switch (clocks_table_header.clocks_hal) { + case CLK_TABLE_HAL_ENTRY_GP: + { + vbiosclktbl1xhalentry = vbiosclktbl1xhalentry_gp; + break; + } + case CLK_TABLE_HAL_ENTRY_GV: + { + vbiosclktbl1xhalentry = vbiosclktbl1xhalentry_gv; + break; + } + default: + { + status = -EINVAL; + goto done; + } + } + + pclkdomainobjs->cntr_sampling_periodms = + (u16)clocks_table_header.cntr_sampling_periodms; + + /* Read table entries*/ + clocks_tbl_entry_ptr = clocks_table_ptr + + VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07; + for (index = 0; index < clocks_table_header.entry_count; index++) { + memcpy((void*) &clocks_table_entry, (void*) clocks_tbl_entry_ptr, + clocks_table_header.entry_size); + clk_domain_data.clk_domain.domain = + (u8) vbiosclktbl1xhalentry[index].domain; + clk_domain_data.clk_domain.api_domain = + clktranslatehalmumsettoapinumset( + BIT(clk_domain_data.clk_domain.domain)); + clk_domain_data.v3x.b_noise_aware_capable = + vbiosclktbl1xhalentry[index].b_noise_aware_capable; + + switch (BIOS_GET_FIELD(clocks_table_entry.flags0, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE)) { + case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_FIXED: + { + clk_domain_data.boardobj.type = + CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED; + clk_domain_data.v3x_fixed.freq_mhz = (u16)BIOS_GET_FIELD( + clocks_table_entry.param1, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_FIXED_FREQUENCY_MHZ); + break; + } + + case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_MASTER: + { + clk_domain_data.boardobj.type = + CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER; + clk_domain_data.v3x_prog.clk_prog_idx_first = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param0, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_FIRST)); + clk_domain_data.v3x_prog.clk_prog_idx_last = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param0, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_LAST)); + clk_domain_data.v3x_prog.noise_unaware_ordering_index = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_UNAWARE_ORDERING_IDX)); + if (clk_domain_data.v3x.b_noise_aware_capable) { + clk_domain_data.v3x_prog.noise_aware_ordering_index = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_AWARE_ORDERING_IDX)); + clk_domain_data.v3x_prog.b_force_noise_unaware_ordering = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING)); + } else { + clk_domain_data.v3x_prog.noise_aware_ordering_index = + CTRL_CLK_CLK_DOMAIN_3X_PROG_ORDERING_INDEX_INVALID; + clk_domain_data.v3x_prog.b_force_noise_unaware_ordering = false; + } + + clk_domain_data.v3x_prog.factory_delta.data.delta_khz = 0; + clk_domain_data.v3x_prog.factory_delta.type = 0; + + clk_domain_data.v3x_prog.freq_delta_min_mhz = + (u16)(BIOS_GET_FIELD(clocks_table_entry.param1, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MIN_MHZ)); + + clk_domain_data.v3x_prog.freq_delta_max_mhz = + (u16)(BIOS_GET_FIELD(clocks_table_entry.param1, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MAX_MHZ)); + break; + } + + case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_SLAVE: + { + clk_domain_data.boardobj.type = + CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE; + clk_domain_data.v3x_prog.clk_prog_idx_first = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param0, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_FIRST)); + clk_domain_data.v3x_prog.clk_prog_idx_last = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param0, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_LAST)); + clk_domain_data.v3x_prog.noise_unaware_ordering_index = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_UNAWARE_ORDERING_IDX)); + + if (clk_domain_data.v3x.b_noise_aware_capable) { + clk_domain_data.v3x_prog.noise_aware_ordering_index = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_AWARE_ORDERING_IDX)); + clk_domain_data.v3x_prog.b_force_noise_unaware_ordering = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param2, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING)); + } else { + clk_domain_data.v3x_prog.noise_aware_ordering_index = + CTRL_CLK_CLK_DOMAIN_3X_PROG_ORDERING_INDEX_INVALID; + clk_domain_data.v3x_prog.b_force_noise_unaware_ordering = false; + } + clk_domain_data.v3x_prog.factory_delta.data.delta_khz = 0; + clk_domain_data.v3x_prog.factory_delta.type = 0; + clk_domain_data.v3x_prog.freq_delta_min_mhz = 0; + clk_domain_data.v3x_prog.freq_delta_max_mhz = 0; + clk_domain_data.v3x_slave.master_idx = + (u8)(BIOS_GET_FIELD(clocks_table_entry.param1, + NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_SLAVE_MASTER_DOMAIN)); + break; + } + + default: + { + nvgpu_err(g, + "error reading clock domain entry %d", index); + status = (u32) -EINVAL; + goto done; + } + + } + pclkdomain_dev = construct_clk_domain(g, + (void *)&clk_domain_data); + if (pclkdomain_dev == NULL) { + nvgpu_err(g, + "unable to construct clock domain boardobj for %d", + index); + status = (u32) -EINVAL; + goto done; + } + status = boardobjgrp_objinsert(&pclkdomainobjs->super.super, + (struct boardobj *)(void *)pclkdomain_dev, index); + if (status != 0UL) { + nvgpu_err(g, + "unable to insert clock domain boardobj for %d", index); + status = (u32) -EINVAL; + goto done; + } + clocks_tbl_entry_ptr += clocks_table_header.entry_size; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +static int devinit_get_clocks_table(struct gk20a *g, + struct clk_domains *pclkdomainobjs) +{ + int status = 0; + u8 *clocks_table_ptr = NULL; + struct vbios_clocks_table_1x_header clocks_table_header = { 0 }; + nvgpu_log_info(g, " "); + + clocks_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.clock_token, CLOCKS_TABLE); + if (clocks_table_ptr == NULL) { + status = -EINVAL; + goto done; + } + memcpy(&clocks_table_header, clocks_table_ptr, + VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07); + if (clocks_table_header.version == 0x35U) { + devinit_get_clocks_table_35(g, pclkdomainobjs, clocks_table_ptr); + } + else { + devinit_get_clocks_table_1x(g, pclkdomainobjs, clocks_table_ptr); + } + done: + return status; + +} + +static int clkdomainclkproglink_not_supported(struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_domain *pdomain) +{ + nvgpu_log_info(g, " "); + return -EINVAL; +} + +static int clkdomainvfsearch_stub( + struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_domain *pdomain, + u16 *clkmhz, + u32 *voltuv, + u8 rail) + +{ + nvgpu_log_info(g, " "); + return -EINVAL; +} + +static u32 clkdomaingetfpoints_stub( + struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_domain *pdomain, + u32 *pfpointscount, + u16 *pfreqpointsinmhz, + u8 rail) +{ + nvgpu_log_info(g, " "); + return -EINVAL; +} + + +static int clk_domain_construct_super(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct clk_domain *pdomain; + struct clk_domain *ptmpdomain = (struct clk_domain *)pargs; + int status = 0; + + status = boardobj_construct_super(g, ppboardobj, + size, pargs); + + if (status) { + return -EINVAL; + } + + pdomain = (struct clk_domain *)*ppboardobj; + + pdomain->super.pmudatainit = + clk_domain_pmudatainit_super; + + pdomain->clkdomainclkproglink = + clkdomainclkproglink_not_supported; + + pdomain->clkdomainclkvfsearch = + clkdomainvfsearch_stub; + + pdomain->clkdomainclkgetfpoints = + clkdomaingetfpoints_stub; + + pdomain->api_domain = ptmpdomain->api_domain; + pdomain->domain = ptmpdomain->domain; + pdomain->perf_domain_grp_idx = + ptmpdomain->perf_domain_grp_idx; + + return status; +} + +static int _clk_domain_pmudatainit_3x(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_domain_3x *pclk_domain_3x; + struct nv_pmu_clk_clk_domain_3x_boardobj_set *pset; + + nvgpu_log_info(g, " "); + + status = clk_domain_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_domain_3x = (struct clk_domain_3x *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_domain_3x_boardobj_set *)ppmudata; + + pset->b_noise_aware_capable = pclk_domain_3x->b_noise_aware_capable; + + return status; +} + +static int clk_domain_construct_3x(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_domain_3x *pdomain; + struct clk_domain_3x *ptmpdomain = + (struct clk_domain_3x *)pargs; + int status = 0; + + ptmpobj->type_mask = BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X); + status = clk_domain_construct_super(g, ppboardobj, + size, pargs); + if (status) { + return -EINVAL; + } + + pdomain = (struct clk_domain_3x *)*ppboardobj; + + pdomain->super.super.pmudatainit = + _clk_domain_pmudatainit_3x; + + pdomain->b_noise_aware_capable = ptmpdomain->b_noise_aware_capable; + + return status; +} + +static int clkdomainclkproglink_3x_prog(struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_domain *pdomain) +{ + int status = 0; + struct clk_domain_3x_prog *p3xprog = + (struct clk_domain_3x_prog *)pdomain; + struct clk_prog *pprog = NULL; + u8 i; + + nvgpu_log_info(g, " "); + + for (i = p3xprog->clk_prog_idx_first; + i <= p3xprog->clk_prog_idx_last; + i++) { + pprog = CLK_CLK_PROG_GET(pclk, i); + if (pprog == NULL) { + status = -EINVAL; + } + } + return status; +} + +static int clkdomaingetslaveclk(struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_domain *pdomain, + u16 *pclkmhz, + u16 masterclkmhz) +{ + int status = 0; + struct clk_prog *pprog = NULL; + struct clk_prog_1x_master *pprog1xmaster = NULL; + u8 slaveidx; + struct clk_domain_3x_master *p3xmaster; + + nvgpu_log_info(g, " "); + + if (pclkmhz == NULL) { + return -EINVAL; + } + + if (masterclkmhz == 0) { + return -EINVAL; + } + + slaveidx = BOARDOBJ_GET_IDX(pdomain); + p3xmaster = (struct clk_domain_3x_master *) + CLK_CLK_DOMAIN_GET(pclk, + ((struct clk_domain_3x_slave *) + pdomain)->master_idx); + pprog = CLK_CLK_PROG_GET(pclk, p3xmaster->super.clk_prog_idx_first); + pprog1xmaster = (struct clk_prog_1x_master *)pprog; + + status = pprog1xmaster->getslaveclk(g, pclk, pprog1xmaster, + slaveidx, pclkmhz, masterclkmhz); + return status; +} + +static int clkdomainvfsearch(struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_domain *pdomain, + u16 *pclkmhz, + u32 *pvoltuv, + u8 rail) +{ + int status = 0; + struct clk_domain_3x_master *p3xmaster = + (struct clk_domain_3x_master *)pdomain; + struct clk_prog *pprog = NULL; + struct clk_prog_1x_master *pprog1xmaster = NULL; + u8 i; + u8 *pslaveidx = NULL; + u8 slaveidx; + u16 clkmhz; + u32 voltuv; + u16 bestclkmhz; + u32 bestvoltuv; + + nvgpu_log_info(g, " "); + + if ((pclkmhz == NULL) || (pvoltuv == NULL)) { + return -EINVAL; + } + + if ((*pclkmhz != 0) && (*pvoltuv != 0)) { + return -EINVAL; + } + + bestclkmhz = *pclkmhz; + bestvoltuv = *pvoltuv; + + if (pdomain->super.implements(g, &pdomain->super, + CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE)) { + slaveidx = BOARDOBJ_GET_IDX(pdomain); + pslaveidx = &slaveidx; + p3xmaster = (struct clk_domain_3x_master *) + CLK_CLK_DOMAIN_GET(pclk, + ((struct clk_domain_3x_slave *) + pdomain)->master_idx); + } + /* Iterate over the set of CLK_PROGs pointed at by this domain.*/ + for (i = p3xmaster->super.clk_prog_idx_first; + i <= p3xmaster->super.clk_prog_idx_last; + i++) { + clkmhz = *pclkmhz; + voltuv = *pvoltuv; + pprog = CLK_CLK_PROG_GET(pclk, i); + + /* MASTER CLK_DOMAINs must point to MASTER CLK_PROGs.*/ + if (!pprog->super.implements(g, &pprog->super, + CTRL_CLK_CLK_PROG_TYPE_1X_MASTER)) { + status = -EINVAL; + goto done; + } + + pprog1xmaster = (struct clk_prog_1x_master *)pprog; + status = pprog1xmaster->vflookup(g, pclk, pprog1xmaster, + pslaveidx, &clkmhz, &voltuv, rail); + /* if look up has found the V or F value matching to other + exit */ + if (status == 0) { + if (*pclkmhz == 0) { + bestclkmhz = clkmhz; + } else { + bestvoltuv = voltuv; + break; + } + } + } + /* clk and volt sent as zero to print vf table */ + if ((*pclkmhz == 0) && (*pvoltuv == 0)) { + status = 0; + goto done; + } + /* atleast one search found a matching value? */ + if ((bestvoltuv != 0) && (bestclkmhz != 0)) { + *pclkmhz = bestclkmhz; + *pvoltuv = bestvoltuv; + status = 0; + goto done; + } +done: + nvgpu_log_info(g, "done status %x", status); + return status; +} + +static u32 clkdomaingetfpoints +( + struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_domain *pdomain, + u32 *pfpointscount, + u16 *pfreqpointsinmhz, + u8 rail +) +{ + u32 status = 0; + struct clk_domain_3x_master *p3xmaster = + (struct clk_domain_3x_master *)pdomain; + struct clk_prog *pprog = NULL; + struct clk_prog_1x_master *pprog1xmaster = NULL; + u32 fpointscount = 0; + u32 remainingcount; + u32 totalcount; + u16 *freqpointsdata; + u8 i; + + nvgpu_log_info(g, " "); + + if (pfpointscount == NULL) { + return -EINVAL; + } + + if ((pfreqpointsinmhz == NULL) && (*pfpointscount != 0)) { + return -EINVAL; + } + + if (pdomain->super.implements(g, &pdomain->super, + CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE)) { + return -EINVAL; + } + + freqpointsdata = pfreqpointsinmhz; + totalcount = 0; + fpointscount = *pfpointscount; + remainingcount = fpointscount; + /* Iterate over the set of CLK_PROGs pointed at by this domain.*/ + for (i = p3xmaster->super.clk_prog_idx_first; + i <= p3xmaster->super.clk_prog_idx_last; + i++) { + pprog = CLK_CLK_PROG_GET(pclk, i); + pprog1xmaster = (struct clk_prog_1x_master *)pprog; + status = pprog1xmaster->getfpoints(g, pclk, pprog1xmaster, + &fpointscount, &freqpointsdata, rail); + if (status) { + *pfpointscount = 0; + goto done; + } + totalcount += fpointscount; + if (*pfpointscount) { + remainingcount -= fpointscount; + fpointscount = remainingcount; + } else { + fpointscount = 0; + } + + } + + *pfpointscount = totalcount; +done: + nvgpu_log_info(g, "done status %x", status); + return status; +} + +static int clk_domain_pmudatainit_35_prog(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_domain_35_prog *pclk_domain_35_prog; + struct clk_domain_3x_prog *pclk_domain_3x_prog; + struct nv_pmu_clk_clk_domain_35_prog_boardobj_set *pset; + struct clk_domains *pdomains = &(g->clk_pmu.clk_domainobjs); + + nvgpu_log_info(g, " "); + + status = _clk_domain_pmudatainit_3x(g, board_obj_ptr, ppmudata); + if (status != 0UL) { + return status; + } + + pclk_domain_35_prog = (struct clk_domain_35_prog *)(void*)board_obj_ptr; + pclk_domain_3x_prog = &pclk_domain_35_prog->super; + + pset = (struct nv_pmu_clk_clk_domain_35_prog_boardobj_set *) + (void*) ppmudata; + + pset->super.clk_prog_idx_first = pclk_domain_3x_prog->clk_prog_idx_first; + pset->super.clk_prog_idx_last = pclk_domain_3x_prog->clk_prog_idx_last; + pset->super.b_force_noise_unaware_ordering = + pclk_domain_3x_prog->b_force_noise_unaware_ordering; + pset->super.factory_delta = pclk_domain_3x_prog->factory_delta; + pset->super.freq_delta_min_mhz = pclk_domain_3x_prog->freq_delta_min_mhz; + pset->super.freq_delta_max_mhz = pclk_domain_3x_prog->freq_delta_max_mhz; + memcpy(&pset->super.deltas, &pdomains->deltas, + (sizeof(struct ctrl_clk_clk_delta))); + pset->pre_volt_ordering_index = pclk_domain_35_prog->pre_volt_ordering_index; + pset->post_volt_ordering_index = pclk_domain_35_prog->post_volt_ordering_index; + pset->clk_pos = pclk_domain_35_prog->clk_pos; + pset->clk_vf_curve_count = pclk_domain_35_prog->clk_vf_curve_count; + + return status; +} + +static int _clk_domain_pmudatainit_3x_prog(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_domain_3x_prog *pclk_domain_3x_prog; + struct nv_pmu_clk_clk_domain_30_prog_boardobj_set *pset; + struct clk_domains *pdomains = &(g->clk_pmu.clk_domainobjs); + + nvgpu_log_info(g, " "); + + status = _clk_domain_pmudatainit_3x(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_domain_3x_prog = (struct clk_domain_3x_prog *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_domain_30_prog_boardobj_set *) + ppmudata; + + pset->super.clk_prog_idx_first = pclk_domain_3x_prog->clk_prog_idx_first; + pset->super.clk_prog_idx_last = pclk_domain_3x_prog->clk_prog_idx_last; + pset->noise_unaware_ordering_index = + pclk_domain_3x_prog->noise_unaware_ordering_index; + pset->noise_aware_ordering_index = + pclk_domain_3x_prog->noise_aware_ordering_index; + pset->super.b_force_noise_unaware_ordering = + pclk_domain_3x_prog->b_force_noise_unaware_ordering; + pset->super.factory_delta = pclk_domain_3x_prog->factory_delta; + pset->super.freq_delta_min_mhz = pclk_domain_3x_prog->freq_delta_min_mhz; + pset->super.freq_delta_max_mhz = pclk_domain_3x_prog->freq_delta_max_mhz; + memcpy(&pset->super.deltas, &pdomains->deltas, + (sizeof(struct ctrl_clk_clk_delta))); + + return status; +} + +static int clk_domain_construct_35_prog(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_domain_35_prog *pdomain; + struct clk_domain_35_prog *ptmpdomain = + (struct clk_domain_35_prog *)pargs; + int status = 0; + + ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X_PROG); + status = clk_domain_construct_3x(g, ppboardobj, size, pargs); + if (status != 0UL) + { + return (u32) -EINVAL; + } + + pdomain = (struct clk_domain_35_prog *)(void*) *ppboardobj; + + pdomain->super.super.super.super.pmudatainit = + clk_domain_pmudatainit_35_prog; + + pdomain->super.super.super.clkdomainclkproglink = + clkdomainclkproglink_3x_prog; + + pdomain->super.super.super.clkdomainclkvfsearch = + clkdomainvfsearch; + + pdomain->super.super.super.clkdomainclkgetfpoints = + clkdomaingetfpoints; + + pdomain->super.clk_prog_idx_first = ptmpdomain->super.clk_prog_idx_first; + pdomain->super.clk_prog_idx_last = ptmpdomain->super.clk_prog_idx_last; + pdomain->super.noise_unaware_ordering_index = + ptmpdomain->super.noise_unaware_ordering_index; + pdomain->super.noise_aware_ordering_index = + ptmpdomain->super.noise_aware_ordering_index; + pdomain->super.b_force_noise_unaware_ordering = + ptmpdomain->super.b_force_noise_unaware_ordering; + pdomain->super.factory_delta = ptmpdomain->super.factory_delta; + pdomain->super.freq_delta_min_mhz = ptmpdomain->super.freq_delta_min_mhz; + pdomain->super.freq_delta_max_mhz = ptmpdomain->super.freq_delta_max_mhz; + pdomain->pre_volt_ordering_index = ptmpdomain->pre_volt_ordering_index; + pdomain->post_volt_ordering_index = ptmpdomain->post_volt_ordering_index; + pdomain->clk_pos = ptmpdomain->clk_pos; + pdomain->clk_vf_curve_count = ptmpdomain->clk_vf_curve_count; + + return status; +} + +static int clk_domain_construct_3x_prog(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_domain_3x_prog *pdomain; + struct clk_domain_3x_prog *ptmpdomain = + (struct clk_domain_3x_prog *)pargs; + int status = 0; + + ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X_PROG); + status = clk_domain_construct_3x(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pdomain = (struct clk_domain_3x_prog *)*ppboardobj; + + pdomain->super.super.super.pmudatainit = + _clk_domain_pmudatainit_3x_prog; + + pdomain->super.super.clkdomainclkproglink = + clkdomainclkproglink_3x_prog; + + pdomain->super.super.clkdomainclkvfsearch = + clkdomainvfsearch; + + pdomain->super.super.clkdomainclkgetfpoints = + clkdomaingetfpoints; + + pdomain->clk_prog_idx_first = ptmpdomain->clk_prog_idx_first; + pdomain->clk_prog_idx_last = ptmpdomain->clk_prog_idx_last; + pdomain->noise_unaware_ordering_index = + ptmpdomain->noise_unaware_ordering_index; + pdomain->noise_aware_ordering_index = + ptmpdomain->noise_aware_ordering_index; + pdomain->b_force_noise_unaware_ordering = + ptmpdomain->b_force_noise_unaware_ordering; + pdomain->factory_delta = ptmpdomain->factory_delta; + pdomain->freq_delta_min_mhz = ptmpdomain->freq_delta_min_mhz; + pdomain->freq_delta_max_mhz = ptmpdomain->freq_delta_max_mhz; + + return status; +} + +static int _clk_domain_pmudatainit_35_slave(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_domain_35_slave *pclk_domain_35_slave; + struct nv_pmu_clk_clk_domain_35_slave_boardobj_set *pset; + + nvgpu_log_info(g, " "); + + status = clk_domain_pmudatainit_35_prog(g, board_obj_ptr, ppmudata); + if (status != 0UL) { + return status; + } + + pclk_domain_35_slave = (struct clk_domain_35_slave *)(void*)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_domain_35_slave_boardobj_set *) + (void*) ppmudata; + + pset->slave.master_idx = pclk_domain_35_slave->slave.master_idx; + + return status; +} + +static int clk_domain_pmudatainit_3x_slave(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_domain_3x_slave *pclk_domain_3x_slave; + struct nv_pmu_clk_clk_domain_3x_slave_boardobj_set *pset; + + nvgpu_log_info(g, " "); + + status = _clk_domain_pmudatainit_3x_prog(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_domain_3x_slave = (struct clk_domain_3x_slave *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_domain_3x_slave_boardobj_set *) + ppmudata; + + pset->master_idx = pclk_domain_3x_slave->master_idx; + + return status; +} + +static int clk_domain_construct_35_slave(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_domain_35_slave *pdomain; + struct clk_domain_35_slave *ptmpdomain = + (struct clk_domain_35_slave *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != (u8) CTRL_CLK_CLK_DOMAIN_TYPE_35_SLAVE) { + return (u32) -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_35_SLAVE); + status = clk_domain_construct_35_prog(g, ppboardobj, size, pargs); + if (status != 0UL) { + return (u32) -EINVAL; + } + + pdomain = (struct clk_domain_35_slave *)(void*)*ppboardobj; + + pdomain->super.super.super.super.super.pmudatainit = + _clk_domain_pmudatainit_35_slave; + + pdomain->slave.master_idx = ptmpdomain->slave.master_idx; + + pdomain->slave.clkdomainclkgetslaveclk = + clkdomaingetslaveclk; + + return status; +} + +static int clk_domain_construct_3x_slave(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_domain_3x_slave *pdomain; + struct clk_domain_3x_slave *ptmpdomain = + (struct clk_domain_3x_slave *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != (u8) CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE); + status = clk_domain_construct_3x_prog(g, ppboardobj, size, pargs); + if (status != 0UL) { + return -EINVAL; + } + + pdomain = (struct clk_domain_3x_slave *)*ppboardobj; + + pdomain->super.super.super.super.pmudatainit = + clk_domain_pmudatainit_3x_slave; + + pdomain->master_idx = ptmpdomain->master_idx; + + pdomain->clkdomainclkgetslaveclk = + clkdomaingetslaveclk; + + return status; +} + +static int clkdomainclkproglink_3x_master(struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_domain *pdomain) +{ + int status = 0; + struct clk_domain_3x_master *p3xmaster = + (struct clk_domain_3x_master *)pdomain; + struct clk_prog *pprog = NULL; + struct clk_prog_1x_master *pprog1xmaster = NULL; + u16 freq_max_last_mhz = 0; + u8 i; + + nvgpu_log_info(g, " "); + + status = clkdomainclkproglink_3x_prog(g, pclk, pdomain); + if (status) { + goto done; + } + + /* Iterate over the set of CLK_PROGs pointed at by this domain.*/ + for (i = p3xmaster->super.clk_prog_idx_first; + i <= p3xmaster->super.clk_prog_idx_last; + i++) { + pprog = CLK_CLK_PROG_GET(pclk, i); + + /* MASTER CLK_DOMAINs must point to MASTER CLK_PROGs.*/ + if (!pprog->super.implements(g, &pprog->super, + CTRL_CLK_CLK_PROG_TYPE_1X_MASTER)) { + status = -EINVAL; + goto done; + } + + pprog1xmaster = (struct clk_prog_1x_master *)pprog; + status = pprog1xmaster->vfflatten(g, pclk, pprog1xmaster, + BOARDOBJ_GET_IDX(p3xmaster), &freq_max_last_mhz); + if (status) { + goto done; + } + } +done: + nvgpu_log_info(g, "done status %x", status); + return status; +} + +static int clk_domain_pmudatainit_35_master(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_domain_35_master *pclk_domain_35_master; + struct nv_pmu_clk_clk_domain_35_master_boardobj_set *pset; + + nvgpu_log_info(g, " "); + + status = clk_domain_pmudatainit_35_prog(g, board_obj_ptr, ppmudata); + if (status != 0UL) { + return status; + } + + pclk_domain_35_master = (struct clk_domain_35_master *) + (void*) board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_domain_35_master_boardobj_set *) + (void*) ppmudata; + + pset->master.slave_idxs_mask = pclk_domain_35_master->master.slave_idxs_mask; + + return status; +} + +static int _clk_domain_pmudatainit_3x_master(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_domain_3x_master *pclk_domain_3x_master; + struct nv_pmu_clk_clk_domain_3x_master_boardobj_set *pset; + + nvgpu_log_info(g, " "); + + status = _clk_domain_pmudatainit_3x_prog(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_domain_3x_master = (struct clk_domain_3x_master *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_domain_3x_master_boardobj_set *) + ppmudata; + + pset->slave_idxs_mask = pclk_domain_3x_master->slave_idxs_mask; + + return status; +} + +static int clk_domain_construct_35_master(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_domain_35_master *pdomain; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != (u8) CTRL_CLK_CLK_DOMAIN_TYPE_35_MASTER) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_35_MASTER); + status = clk_domain_construct_35_prog(g, ppboardobj, size, pargs); + if (status != 0UL) { + return (u32) -EINVAL; + } + + pdomain = (struct clk_domain_35_master *)(void*) *ppboardobj; + + pdomain->super.super.super.super.super.pmudatainit = + clk_domain_pmudatainit_35_master; + pdomain->super.super.super.super.clkdomainclkproglink = + clkdomainclkproglink_3x_master; + + pdomain->master.slave_idxs_mask = 0; + + return status; +} + +static int clk_domain_construct_3x_master(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_domain_3x_master *pdomain; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER); + status = clk_domain_construct_3x_prog(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pdomain = (struct clk_domain_3x_master *)*ppboardobj; + + pdomain->super.super.super.super.pmudatainit = + _clk_domain_pmudatainit_3x_master; + pdomain->super.super.super.clkdomainclkproglink = + clkdomainclkproglink_3x_master; + + pdomain->slave_idxs_mask = 0; + + return status; +} + +static int clkdomainclkproglink_fixed(struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_domain *pdomain) +{ + nvgpu_log_info(g, " "); + return 0; +} + +static int _clk_domain_pmudatainit_3x_fixed(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_domain_3x_fixed *pclk_domain_3x_fixed; + struct nv_pmu_clk_clk_domain_3x_fixed_boardobj_set *pset; + + nvgpu_log_info(g, " "); + + status = _clk_domain_pmudatainit_3x(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_domain_3x_fixed = (struct clk_domain_3x_fixed *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_domain_3x_fixed_boardobj_set *) + ppmudata; + + pset->freq_mhz = pclk_domain_3x_fixed->freq_mhz; + + return status; +} + +static int clk_domain_construct_3x_fixed(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_domain_3x_fixed *pdomain; + struct clk_domain_3x_fixed *ptmpdomain = + (struct clk_domain_3x_fixed *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED); + status = clk_domain_construct_3x(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pdomain = (struct clk_domain_3x_fixed *)*ppboardobj; + + pdomain->super.super.super.pmudatainit = + _clk_domain_pmudatainit_3x_fixed; + + pdomain->super.super.clkdomainclkproglink = + clkdomainclkproglink_fixed; + + pdomain->freq_mhz = ptmpdomain->freq_mhz; + + return status; +} + +static struct clk_domain *construct_clk_domain(struct gk20a *g, void *pargs) +{ + struct boardobj *board_obj_ptr = NULL; + u32 status; + + nvgpu_log_info(g, " %d", BOARDOBJ_GET_TYPE(pargs)); + switch (BOARDOBJ_GET_TYPE(pargs)) { + case CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED: + status = clk_domain_construct_3x_fixed(g, &board_obj_ptr, + sizeof(struct clk_domain_3x_fixed), pargs); + break; + + case CTRL_CLK_CLK_DOMAIN_TYPE_35_MASTER: + status = clk_domain_construct_35_master(g, &board_obj_ptr, + sizeof(struct clk_domain_35_master), pargs); + break; + + + case CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER: + status = clk_domain_construct_3x_master(g, &board_obj_ptr, + sizeof(struct clk_domain_3x_master), pargs); + break; + + case CTRL_CLK_CLK_DOMAIN_TYPE_35_SLAVE: + status = clk_domain_construct_35_slave(g, &board_obj_ptr, + sizeof(struct clk_domain_35_slave), pargs); + break; + + case CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE: + status = clk_domain_construct_3x_slave(g, &board_obj_ptr, + sizeof(struct clk_domain_3x_slave), pargs); + break; + + default: + return NULL; + } + + if (status) { + return NULL; + } + + nvgpu_log_info(g, " Done"); + + return (struct clk_domain *)board_obj_ptr; +} + +static int clk_domain_pmudatainit_super(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_domain *pclk_domain; + struct nv_pmu_clk_clk_domain_boardobj_set *pset; + + nvgpu_log_info(g, " "); + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_domain = (struct clk_domain *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_domain_boardobj_set *)ppmudata; + + pset->domain = pclk_domain->domain; + pset->api_domain = pclk_domain->api_domain; + pset->perf_domain_grp_idx = pclk_domain->perf_domain_grp_idx; + + return status; +} + +int clk_domain_clk_prog_link(struct gk20a *g, struct clk_pmupstate *pclk) +{ + int status = 0; + struct clk_domain *pdomain; + u8 i; + + /* Iterate over all CLK_DOMAINs and flatten their VF curves.*/ + BOARDOBJGRP_FOR_EACH(&(pclk->clk_domainobjs.super.super), + struct clk_domain *, pdomain, i) { + status = pdomain->clkdomainclkproglink(g, pclk, pdomain); + if (status) { + nvgpu_err(g, + "error flattening VF for CLK DOMAIN - 0x%x", + pdomain->domain); + goto done; + } + } + +done: + return status; +} diff --git a/include/clk/clk_domain.h b/include/clk/clk_domain.h new file mode 100644 index 0000000..e5a7153 --- /dev/null +++ b/include/clk/clk_domain.h @@ -0,0 +1,157 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_CLK_DOMAIN_H +#define NVGPU_CLK_DOMAIN_H + +#include "ctrl/ctrlclk.h" +#include "ctrl/ctrlboardobj.h" +#include +#include "boardobj/boardobjgrp_e32.h" +#include "boardobj/boardobjgrpmask.h" + +#define CLK_DOMAIN_BOARDOBJGRP_VERSION 0x30 +#define CLK_TABLE_HAL_ENTRY_GP 0x02 +#define CLK_TABLE_HAL_ENTRY_GV 0x03 + +struct clk_domains; +struct clk_domain; +enum nv_pmu_clk_clkwhich; + +/*data and function definition to talk to driver*/ +int clk_domain_sw_setup(struct gk20a *g); +int clk_domain_pmu_setup(struct gk20a *g); + +typedef int clkproglink(struct gk20a *g, struct clk_pmupstate *pclk, + struct clk_domain *pdomain); + +typedef int clkvfsearch(struct gk20a *g, struct clk_pmupstate *pclk, + struct clk_domain *pdomain, u16 *clkmhz, + u32 *voltuv, u8 rail); + +typedef int clkgetslaveclk(struct gk20a *g, struct clk_pmupstate *pclk, + struct clk_domain *pdomain, u16 *clkmhz, + u16 masterclkmhz); + +typedef u32 clkgetfpoints(struct gk20a *g, struct clk_pmupstate *pclk, + struct clk_domain *pdomain, u32 *pfpointscount, + u16 *pfreqpointsinmhz, u8 rail); + +struct clk_domains { + struct boardobjgrp_e32 super; + u8 n_num_entries; + u8 version; + bool b_enforce_vf_monotonicity; + bool b_enforce_vf_smoothening; + bool b_override_o_v_o_c; + bool b_debug_mode; + u32 vbios_domains; + u16 cntr_sampling_periodms; + struct boardobjgrpmask_e32 prog_domains_mask; + struct boardobjgrpmask_e32 master_domains_mask; + struct ctrl_clk_clk_delta deltas; + + struct clk_domain *ordered_noise_aware_list[CTRL_BOARDOBJ_MAX_BOARD_OBJECTS]; + + struct clk_domain *ordered_noise_unaware_list[CTRL_BOARDOBJ_MAX_BOARD_OBJECTS]; +}; + +struct clk_domain { + struct boardobj super; + u32 api_domain; + u32 part_mask; + enum nv_pmu_clk_clkwhich domain; + u8 perf_domain_index; + u8 perf_domain_grp_idx; + u8 ratio_domain; + u8 usage; + clkproglink *clkdomainclkproglink; + clkvfsearch *clkdomainclkvfsearch; + clkgetfpoints *clkdomainclkgetfpoints; +}; + +struct clk_domain_3x { + struct clk_domain super; + bool b_noise_aware_capable; +}; + +struct clk_domain_3x_fixed { + struct clk_domain_3x super; + u16 freq_mhz; +}; + +struct clk_domain_3x_prog { + struct clk_domain_3x super; + u8 clk_prog_idx_first; + u8 clk_prog_idx_last; + bool b_force_noise_unaware_ordering; + struct ctrl_clk_freq_delta factory_delta; + short freq_delta_min_mhz; + short freq_delta_max_mhz; + struct ctrl_clk_clk_delta deltas; + u8 noise_unaware_ordering_index; + u8 noise_aware_ordering_index; +}; + +struct clk_domain_35_prog { + struct clk_domain_3x_prog super; + u8 pre_volt_ordering_index; + u8 post_volt_ordering_index; + u8 clk_pos; + u8 clk_vf_curve_count; +}; + +struct clk_domain_3x_master { + struct clk_domain_3x_prog super; + u32 slave_idxs_mask; +}; + +struct clk_domain_35_master { + struct clk_domain_35_prog super; + struct clk_domain_3x_master master; + struct boardobjgrpmask_e32 master_slave_domains_grp_mask; +}; + +struct clk_domain_3x_slave { + struct clk_domain_3x_prog super; + u8 master_idx; + clkgetslaveclk *clkdomainclkgetslaveclk; +}; + +struct clk_domain_30_slave { + u8 rsvd; + u8 master_idx; + clkgetslaveclk *clkdomainclkgetslaveclk; +}; + +struct clk_domain_35_slave { + struct clk_domain_35_prog super; + struct clk_domain_30_slave slave; +}; + +int clk_domain_clk_prog_link(struct gk20a *g, struct clk_pmupstate *pclk); + +#define CLK_CLK_DOMAIN_GET(pclk, idx) \ + ((struct clk_domain *)BOARDOBJGRP_OBJ_GET_BY_IDX( \ + &pclk->clk_domainobjs.super.super, (u8)(idx))) + +#endif /* NVGPU_CLK_DOMAIN_H */ diff --git a/include/clk/clk_fll.c b/include/clk/clk_fll.c new file mode 100644 index 0000000..e67dd35 --- /dev/null +++ b/include/clk/clk_fll.c @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "clk.h" +#include "clk_fll.h" +#include "clk_domain.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "ctrl/ctrlclk.h" +#include "ctrl/ctrlvolt.h" + +static int devinit_get_fll_device_table(struct gk20a *g, + struct avfsfllobjs *pfllobjs); +static struct fll_device *construct_fll_device(struct gk20a *g, + void *pargs); +static int fll_device_init_pmudata_super(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata); + +static int _clk_fll_devgrp_pmudatainit_super(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + struct nv_pmu_clk_clk_fll_device_boardobjgrp_set_header *pset = + (struct nv_pmu_clk_clk_fll_device_boardobjgrp_set_header *) + pboardobjgrppmu; + struct avfsfllobjs *pfll_objs = (struct avfsfllobjs *) + pboardobjgrp; + int status = 0; + + nvgpu_log_info(g, " "); + + status = boardobjgrp_pmudatainit_e32(g, pboardobjgrp, pboardobjgrppmu); + if (status) { + nvgpu_err(g, "failed to init fll pmuobjgrp"); + return status; + } + pset->lut_num_entries = pfll_objs->lut_num_entries; + pset->lut_step_size_uv = pfll_objs->lut_step_size_uv; + pset->lut_min_voltage_uv = pfll_objs->lut_min_voltage_uv; + pset->max_min_freq_mhz = pfll_objs->max_min_freq_mhz; + + status = boardobjgrpmask_export( + &pfll_objs->lut_prog_master_mask.super, + pfll_objs->lut_prog_master_mask.super.bitcount, + &pset->lut_prog_master_mask.super); + + nvgpu_log_info(g, " Done"); + return status; +} + +static int _clk_fll_devgrp_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_clk_clk_fll_device_boardobj_grp_set *pgrp_set = + (struct nv_pmu_clk_clk_fll_device_boardobj_grp_set *) + pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + nvgpu_log_info(g, " Done"); + return 0; +} + +static int _clk_fll_devgrp_pmustatus_instget(struct gk20a *g, + void *pboardobjgrppmu, + struct nv_pmu_boardobj_query **ppboardobjpmustatus, + u8 idx) +{ + struct nv_pmu_clk_clk_fll_device_boardobj_grp_get_status *pgrp_get_status = + (struct nv_pmu_clk_clk_fll_device_boardobj_grp_get_status *) + pboardobjgrppmu; + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_get_status->hdr.data.super.obj_mask.super.data[0]) == 0) { + return -EINVAL; + } + + *ppboardobjpmustatus = (struct nv_pmu_boardobj_query *) + &pgrp_get_status->objects[idx].data.board_obj; + return 0; +} + +int clk_fll_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + struct avfsfllobjs *pfllobjs; + struct fll_device *pfll; + struct fll_device *pfll_master; + struct fll_device *pfll_local; + u8 i; + u8 j; + + nvgpu_log_info(g, " "); + + status = boardobjgrpconstruct_e32(g, &g->clk_pmu.avfs_fllobjs.super); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for fll, status - 0x%x", status); + goto done; + } + pfllobjs = &(g->clk_pmu.avfs_fllobjs); + pboardobjgrp = &(g->clk_pmu.avfs_fllobjs.super.super); + + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, CLK, FLL_DEVICE); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + clk, CLK, clk_fll_device, CLK_FLL_DEVICE); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + pboardobjgrp->pmudatainit = _clk_fll_devgrp_pmudatainit_super; + pboardobjgrp->pmudatainstget = _clk_fll_devgrp_pmudata_instget; + pboardobjgrp->pmustatusinstget = _clk_fll_devgrp_pmustatus_instget; + pfllobjs = (struct avfsfllobjs *)pboardobjgrp; + pfllobjs->lut_num_entries = g->ops.clk.lut_num_entries; + pfllobjs->lut_step_size_uv = CTRL_CLK_VIN_STEP_SIZE_UV; + pfllobjs->lut_min_voltage_uv = CTRL_CLK_LUT_MIN_VOLTAGE_UV; + + /* Initialize lut prog master mask to zero.*/ + boardobjgrpmask_e32_init(&pfllobjs->lut_prog_master_mask, NULL); + + status = devinit_get_fll_device_table(g, pfllobjs); + if (status) { + goto done; + } + + status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, + &g->clk_pmu.avfs_fllobjs.super.super, + clk, CLK, clk_fll_device, CLK_FLL_DEVICE); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + BOARDOBJGRP_FOR_EACH(&(pfllobjs->super.super), + struct fll_device *, pfll, i) { + pfll_master = NULL; + j = 0; + BOARDOBJGRP_ITERATOR(&(pfllobjs->super.super), + struct fll_device *, pfll_local, j, + &pfllobjs->lut_prog_master_mask.super) { + if (pfll_local->clk_domain == pfll->clk_domain) { + pfll_master = pfll_local; + break; + } + } + + if (pfll_master == NULL) { + status = boardobjgrpmask_bitset( + &pfllobjs->lut_prog_master_mask.super, + BOARDOBJ_GET_IDX(pfll)); + if (status) { + nvgpu_err(g, "err setting lutprogmask"); + goto done; + } + pfll_master = pfll; + } + status = pfll_master->lut_broadcast_slave_register( + g, pfllobjs, pfll_master, pfll); + + if (status) { + nvgpu_err(g, "err setting lutslavemask"); + goto done; + } + } +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int clk_fll_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + pboardobjgrp = &g->clk_pmu.avfs_fllobjs.super.super; + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + nvgpu_log_info(g, "Done"); + return status; +} + +static int devinit_get_fll_device_table(struct gk20a *g, + struct avfsfllobjs *pfllobjs) +{ + int status = 0; + u8 *fll_table_ptr = NULL; + struct fll_descriptor_header fll_desc_table_header_sz = { 0 }; + struct fll_descriptor_header_10 fll_desc_table_header = { 0 }; + struct fll_descriptor_entry_10 fll_desc_table_entry = { 0 }; + u8 *fll_tbl_entry_ptr = NULL; + u32 index = 0; + struct fll_device fll_dev_data; + struct fll_device *pfll_dev; + struct vin_device *pvin_dev; + u32 desctablesize; + u32 vbios_domain = NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_SKIP; + struct avfsvinobjs *pvinobjs = &g->clk_pmu.avfs_vinobjs; + + nvgpu_log_info(g, " "); + + fll_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.clock_token, FLL_TABLE); + if (fll_table_ptr == NULL) { + status = -1; + goto done; + } + + memcpy(&fll_desc_table_header_sz, fll_table_ptr, + sizeof(struct fll_descriptor_header)); + if (fll_desc_table_header_sz.size >= FLL_DESCRIPTOR_HEADER_10_SIZE_6) { + desctablesize = FLL_DESCRIPTOR_HEADER_10_SIZE_6; + } else { + desctablesize = FLL_DESCRIPTOR_HEADER_10_SIZE_4; + } + + memcpy(&fll_desc_table_header, fll_table_ptr, desctablesize); + + if (desctablesize == FLL_DESCRIPTOR_HEADER_10_SIZE_6) { + pfllobjs->max_min_freq_mhz = + fll_desc_table_header.max_min_freq_mhz; + } else { + pfllobjs->max_min_freq_mhz = 0; + } + + /* Read table entries*/ + fll_tbl_entry_ptr = fll_table_ptr + desctablesize; + for (index = 0; index < fll_desc_table_header.entry_count; index++) { + u32 fll_id; + + memcpy(&fll_desc_table_entry, fll_tbl_entry_ptr, + sizeof(struct fll_descriptor_entry_10)); + + if (fll_desc_table_entry.fll_device_type == CTRL_CLK_FLL_TYPE_DISABLED) { + continue; + } + + fll_id = fll_desc_table_entry.fll_device_id; + + if ( (u8)fll_desc_table_entry.vin_idx_logic != CTRL_CLK_VIN_ID_UNDEFINED) { + pvin_dev = CLK_GET_VIN_DEVICE(pvinobjs, + (u8)fll_desc_table_entry.vin_idx_logic); + if (pvin_dev == NULL) { + return -EINVAL; + } else { + pvin_dev->flls_shared_mask |= BIT(fll_id); + } + } else { + /* Return if Logic ADC device index is invalid*/ + nvgpu_err(g, "Invalid Logic ADC specified for Nafll ID"); + return -EINVAL; + } + + fll_dev_data.lut_device.vselect_mode = + (u8)BIOS_GET_FIELD(fll_desc_table_entry.lut_params, + NV_FLL_DESC_LUT_PARAMS_VSELECT); + + if ( (u8)fll_desc_table_entry.vin_idx_sram != CTRL_CLK_VIN_ID_UNDEFINED) { + pvin_dev = CLK_GET_VIN_DEVICE(pvinobjs, + (u8)fll_desc_table_entry.vin_idx_sram); + if (pvin_dev == NULL) { + return -EINVAL; + } else { + pvin_dev->flls_shared_mask |= BIT(fll_id); + } + } else { + /* Make sure VSELECT mode is set correctly to _LOGIC*/ + if (fll_dev_data.lut_device.vselect_mode != CTRL_CLK_FLL_LUT_VSELECT_LOGIC) { + return -EINVAL; + } + } + + fll_dev_data.super.type = + (u8)fll_desc_table_entry.fll_device_type; + fll_dev_data.id = (u8)fll_desc_table_entry.fll_device_id; + fll_dev_data.mdiv = (u8)BIOS_GET_FIELD( + fll_desc_table_entry.fll_params, + NV_FLL_DESC_FLL_PARAMS_MDIV); + fll_dev_data.input_freq_mhz = + (u16)fll_desc_table_entry.ref_freq_mhz; + fll_dev_data.min_freq_vfe_idx = + (u8)fll_desc_table_entry.min_freq_vfe_idx; + fll_dev_data.freq_ctrl_idx = CTRL_BOARDOBJ_IDX_INVALID; + + vbios_domain = (u32)(fll_desc_table_entry.clk_domain & + NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_MASK); + fll_dev_data.clk_domain = + g->ops.pmu_ver.clk.get_vbios_clk_domain(vbios_domain); + + fll_dev_data.rail_idx_for_lut = 0; + fll_dev_data.vin_idx_logic = + (u8)fll_desc_table_entry.vin_idx_logic; + fll_dev_data.vin_idx_sram = + (u8)fll_desc_table_entry.vin_idx_sram; + fll_dev_data.b_skip_pldiv_below_dvco_min = + (bool)BIOS_GET_FIELD(fll_desc_table_entry.fll_params, + NV_FLL_DESC_FLL_PARAMS_SKIP_PLDIV_BELOW_DVCO_MIN); + fll_dev_data.lut_device.hysteresis_threshold = + (u8)BIOS_GET_FIELD(fll_desc_table_entry.lut_params, + NV_FLL_DESC_LUT_PARAMS_HYSTERISIS_THRESHOLD); + fll_dev_data.regime_desc.regime_id = + CTRL_CLK_FLL_REGIME_ID_FFR; + fll_dev_data.regime_desc.fixed_freq_regime_limit_mhz = + (u16)fll_desc_table_entry.ffr_cutoff_freq_mhz; + fll_dev_data.regime_desc.target_regime_id_override=0; + + /*construct fll device*/ + pfll_dev = construct_fll_device(g, (void *)&fll_dev_data); + + status = boardobjgrp_objinsert(&pfllobjs->super.super, + (struct boardobj *)pfll_dev, index); + fll_tbl_entry_ptr += fll_desc_table_header.entry_size; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +u32 nvgpu_clk_get_vbios_clk_domain_gv10x( u32 vbios_domain) +{ + if (vbios_domain == 0) { + return CTRL_CLK_DOMAIN_GPCCLK; + } else if (vbios_domain == 1) { + return CTRL_CLK_DOMAIN_XBARCLK; + } else if (vbios_domain == 3) { + return CTRL_CLK_DOMAIN_SYSCLK; + } else if (vbios_domain == 5) { + return CTRL_CLK_DOMAIN_NVDCLK; + } + return 0; +} + +u32 nvgpu_clk_get_vbios_clk_domain_gp10x( u32 vbios_domain) +{ + if (vbios_domain == 0) { + return CTRL_CLK_DOMAIN_GPC2CLK; + } else if (vbios_domain == 1) { + return CTRL_CLK_DOMAIN_XBAR2CLK; + } else if (vbios_domain == 3) { + return CTRL_CLK_DOMAIN_SYS2CLK; + } + return 0; +} + +static u32 lutbroadcastslaveregister(struct gk20a *g, + struct avfsfllobjs *pfllobjs, + struct fll_device *pfll, + struct fll_device *pfll_slave) +{ + if (pfll->clk_domain != pfll_slave->clk_domain) { + return -EINVAL; + } + + return boardobjgrpmask_bitset(&pfll-> + lut_prog_broadcast_slave_mask.super, + BOARDOBJ_GET_IDX(pfll_slave)); +} + +static struct fll_device *construct_fll_device(struct gk20a *g, + void *pargs) +{ + struct boardobj *board_obj_ptr = NULL; + struct fll_device *pfll_dev; + struct fll_device *board_obj_fll_ptr = NULL; + int status; + + nvgpu_log_info(g, " "); + status = boardobj_construct_super(g, &board_obj_ptr, + sizeof(struct fll_device), pargs); + if (status) { + return NULL; + } + + pfll_dev = (struct fll_device *)pargs; + board_obj_fll_ptr = (struct fll_device *)board_obj_ptr; + board_obj_ptr->pmudatainit = fll_device_init_pmudata_super; + board_obj_fll_ptr->lut_broadcast_slave_register = + lutbroadcastslaveregister; + board_obj_fll_ptr->id = pfll_dev->id; + board_obj_fll_ptr->mdiv = pfll_dev->mdiv; + board_obj_fll_ptr->rail_idx_for_lut = pfll_dev->rail_idx_for_lut; + board_obj_fll_ptr->input_freq_mhz = pfll_dev->input_freq_mhz; + board_obj_fll_ptr->clk_domain = pfll_dev->clk_domain; + board_obj_fll_ptr->vin_idx_logic = pfll_dev->vin_idx_logic; + board_obj_fll_ptr->vin_idx_sram = pfll_dev->vin_idx_sram; + board_obj_fll_ptr->min_freq_vfe_idx = + pfll_dev->min_freq_vfe_idx; + board_obj_fll_ptr->freq_ctrl_idx = pfll_dev->freq_ctrl_idx; + board_obj_fll_ptr->b_skip_pldiv_below_dvco_min = + pfll_dev->b_skip_pldiv_below_dvco_min; + memcpy(&board_obj_fll_ptr->lut_device, &pfll_dev->lut_device, + sizeof(struct nv_pmu_clk_lut_device_desc)); + memcpy(&board_obj_fll_ptr->regime_desc, &pfll_dev->regime_desc, + sizeof(struct nv_pmu_clk_regime_desc)); + boardobjgrpmask_e32_init( + &board_obj_fll_ptr->lut_prog_broadcast_slave_mask, NULL); + + nvgpu_log_info(g, " Done"); + + return (struct fll_device *)board_obj_ptr; +} + +static int fll_device_init_pmudata_super(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct fll_device *pfll_dev; + struct nv_pmu_clk_clk_fll_device_boardobj_set *perf_pmu_data; + + nvgpu_log_info(g, " "); + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pfll_dev = (struct fll_device *)board_obj_ptr; + perf_pmu_data = (struct nv_pmu_clk_clk_fll_device_boardobj_set *) + ppmudata; + + perf_pmu_data->id = pfll_dev->id; + perf_pmu_data->mdiv = pfll_dev->mdiv; + perf_pmu_data->rail_idx_for_lut = pfll_dev->rail_idx_for_lut; + perf_pmu_data->input_freq_mhz = pfll_dev->input_freq_mhz; + perf_pmu_data->vin_idx_logic = pfll_dev->vin_idx_logic; + perf_pmu_data->vin_idx_sram = pfll_dev->vin_idx_sram; + perf_pmu_data->clk_domain = pfll_dev->clk_domain; + perf_pmu_data->min_freq_vfe_idx = + pfll_dev->min_freq_vfe_idx; + perf_pmu_data->freq_ctrl_idx = pfll_dev->freq_ctrl_idx; + perf_pmu_data->b_skip_pldiv_below_dvco_min = pfll_dev->b_skip_pldiv_below_dvco_min; + memcpy(&perf_pmu_data->lut_device, &pfll_dev->lut_device, + sizeof(struct nv_pmu_clk_lut_device_desc)); + memcpy(&perf_pmu_data->regime_desc, &pfll_dev->regime_desc, + sizeof(struct nv_pmu_clk_regime_desc)); + + status = boardobjgrpmask_export( + &pfll_dev->lut_prog_broadcast_slave_mask.super, + pfll_dev->lut_prog_broadcast_slave_mask.super.bitcount, + &perf_pmu_data->lut_prog_broadcast_slave_mask.super); + + nvgpu_log_info(g, " Done"); + + return status; +} diff --git a/include/clk/clk_fll.h b/include/clk/clk_fll.h new file mode 100644 index 0000000..6cbdfe2 --- /dev/null +++ b/include/clk/clk_fll.h @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_CLK_FLL_H +#define NVGPU_CLK_FLL_H + +#include +#include "boardobj/boardobjgrp_e32.h" +#include "boardobj/boardobjgrpmask.h" + +/*data and function definition to talk to driver*/ +int clk_fll_sw_setup(struct gk20a *g); +int clk_fll_pmu_setup(struct gk20a *g); + +struct avfsfllobjs { + struct boardobjgrp_e32 super; + struct boardobjgrpmask_e32 lut_prog_master_mask; + u32 lut_step_size_uv; + u32 lut_min_voltage_uv; + u8 lut_num_entries; + u16 max_min_freq_mhz; +}; + +struct fll_device; + +typedef u32 fll_lut_broadcast_slave_register(struct gk20a *g, + struct avfsfllobjs *pfllobjs, + struct fll_device *pfll, + struct fll_device *pfll_slave); + +struct fll_device { + struct boardobj super; + u8 id; + u8 mdiv; + u16 input_freq_mhz; + u32 clk_domain; + u8 vin_idx_logic; + u8 vin_idx_sram; + u8 rail_idx_for_lut; + struct nv_pmu_clk_lut_device_desc lut_device; + struct nv_pmu_clk_regime_desc regime_desc; + u8 min_freq_vfe_idx; + u8 freq_ctrl_idx; + u8 target_regime_id_override; + bool b_skip_pldiv_below_dvco_min; + bool b_dvco_1x; + struct boardobjgrpmask_e32 lut_prog_broadcast_slave_mask; + fll_lut_broadcast_slave_register *lut_broadcast_slave_register; +}; + +u32 nvgpu_clk_get_vbios_clk_domain_gv10x( u32 vbios_domain); +u32 nvgpu_clk_get_vbios_clk_domain_gp10x( u32 vbios_domain); + +#define CLK_FLL_LUT_VF_NUM_ENTRIES(pclk) \ + (pclk->avfs_fllobjs.lut_num_entries) + +#define CLK_FLL_LUT_MIN_VOLTAGE_UV(pclk) \ + (pclk->avfs_fllobjs.lut_min_voltage_uv) +#define CLK_FLL_LUT_STEP_SIZE_UV(pclk) \ + (pclk->avfs_fllobjs.lut_step_size_uv) + +#endif /* NVGPU_CLK_FLL_H */ diff --git a/include/clk/clk_freq_controller.c b/include/clk/clk_freq_controller.c new file mode 100644 index 0000000..f4d09b0 --- /dev/null +++ b/include/clk/clk_freq_controller.c @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "clk.h" +#include "clk_fll.h" +#include "clk_domain.h" +#include "clk_freq_controller.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "ctrl/ctrlclk.h" +#include "ctrl/ctrlvolt.h" + +static int clk_freq_controller_pmudatainit_super(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + struct nv_pmu_clk_clk_freq_controller_boardobj_set *pfreq_cntlr_set; + struct clk_freq_controller *pfreq_cntlr; + int status = 0; + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status) { + return status; + } + + pfreq_cntlr_set = + (struct nv_pmu_clk_clk_freq_controller_boardobj_set *)ppmudata; + pfreq_cntlr = (struct clk_freq_controller *)board_obj_ptr; + + pfreq_cntlr_set->controller_id = pfreq_cntlr->controller_id; + pfreq_cntlr_set->clk_domain = pfreq_cntlr->clk_domain; + pfreq_cntlr_set->parts_freq_mode = pfreq_cntlr->parts_freq_mode; + pfreq_cntlr_set->bdisable = pfreq_cntlr->bdisable; + pfreq_cntlr_set->freq_cap_noise_unaware_vmin_above = + pfreq_cntlr->freq_cap_noise_unaware_vmin_above; + pfreq_cntlr_set->freq_cap_noise_unaware_vmin_below = + pfreq_cntlr->freq_cap_noise_unaware_vmin_below; + pfreq_cntlr_set->freq_hyst_pos_mhz = pfreq_cntlr->freq_hyst_pos_mhz; + pfreq_cntlr_set->freq_hyst_neg_mhz = pfreq_cntlr->freq_hyst_neg_mhz; + + return status; +} + +static int clk_freq_controller_pmudatainit_pi(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + struct nv_pmu_clk_clk_freq_controller_pi_boardobj_set + *pfreq_cntlr_pi_set; + struct clk_freq_controller_pi *pfreq_cntlr_pi; + int status = 0; + + status = clk_freq_controller_pmudatainit_super(g, + board_obj_ptr, ppmudata); + if (status) { + return -1; + } + + pfreq_cntlr_pi_set = + (struct nv_pmu_clk_clk_freq_controller_pi_boardobj_set *) + ppmudata; + pfreq_cntlr_pi = (struct clk_freq_controller_pi *)board_obj_ptr; + + pfreq_cntlr_pi_set->prop_gain = pfreq_cntlr_pi->prop_gain; + pfreq_cntlr_pi_set->integ_gain = pfreq_cntlr_pi->integ_gain; + pfreq_cntlr_pi_set->integ_decay = pfreq_cntlr_pi->integ_decay; + pfreq_cntlr_pi_set->volt_delta_min = pfreq_cntlr_pi->volt_delta_min; + pfreq_cntlr_pi_set->volt_delta_max = pfreq_cntlr_pi->volt_delta_max; + pfreq_cntlr_pi_set->slowdown_pct_min = pfreq_cntlr_pi->slowdown_pct_min; + pfreq_cntlr_pi_set->bpoison = pfreq_cntlr_pi->bpoison; + + return status; +} + +static int clk_freq_controller_construct_super(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct clk_freq_controller *pfreq_cntlr = NULL; + struct clk_freq_controller *pfreq_cntlr_tmp = NULL; + int status = 0; + + status = boardobj_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pfreq_cntlr_tmp = (struct clk_freq_controller *)pargs; + pfreq_cntlr = (struct clk_freq_controller *)*ppboardobj; + + pfreq_cntlr->super.pmudatainit = clk_freq_controller_pmudatainit_super; + + pfreq_cntlr->controller_id = pfreq_cntlr_tmp->controller_id; + pfreq_cntlr->clk_domain = pfreq_cntlr_tmp->clk_domain; + pfreq_cntlr->parts_freq_mode = pfreq_cntlr_tmp->parts_freq_mode; + pfreq_cntlr->freq_cap_noise_unaware_vmin_above = + pfreq_cntlr_tmp->freq_cap_noise_unaware_vmin_above; + pfreq_cntlr->freq_cap_noise_unaware_vmin_below = + pfreq_cntlr_tmp->freq_cap_noise_unaware_vmin_below; + pfreq_cntlr->freq_hyst_pos_mhz = pfreq_cntlr_tmp->freq_hyst_pos_mhz; + pfreq_cntlr->freq_hyst_neg_mhz = pfreq_cntlr_tmp->freq_hyst_neg_mhz; + + return status; +} + +static int clk_freq_controller_construct_pi(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct clk_freq_controller_pi *pfreq_cntlr_pi = NULL; + struct clk_freq_controller_pi *pfreq_cntlr_pi_tmp = NULL; + int status = 0; + + status = clk_freq_controller_construct_super(g, ppboardobj, + size, pargs); + if (status) { + return -EINVAL; + } + + pfreq_cntlr_pi = (struct clk_freq_controller_pi *)*ppboardobj; + pfreq_cntlr_pi_tmp = (struct clk_freq_controller_pi *)pargs; + + pfreq_cntlr_pi->super.super.pmudatainit = + clk_freq_controller_pmudatainit_pi; + + pfreq_cntlr_pi->prop_gain = pfreq_cntlr_pi_tmp->prop_gain; + pfreq_cntlr_pi->integ_gain = pfreq_cntlr_pi_tmp->integ_gain; + pfreq_cntlr_pi->integ_decay = pfreq_cntlr_pi_tmp->integ_decay; + pfreq_cntlr_pi->volt_delta_min = pfreq_cntlr_pi_tmp->volt_delta_min; + pfreq_cntlr_pi->volt_delta_max = pfreq_cntlr_pi_tmp->volt_delta_max; + pfreq_cntlr_pi->slowdown_pct_min = pfreq_cntlr_pi_tmp->slowdown_pct_min; + pfreq_cntlr_pi->bpoison = pfreq_cntlr_pi_tmp->bpoison; + + return status; +} + +static struct clk_freq_controller *clk_clk_freq_controller_construct( + struct gk20a *g, + void *pargs) +{ + struct boardobj *board_obj_ptr = NULL; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_FREQ_CONTROLLER_TYPE_PI) { + return NULL; + } + + status = clk_freq_controller_construct_pi(g, &board_obj_ptr, + sizeof(struct clk_freq_controller_pi), pargs); + if (status) { + return NULL; + } + + return (struct clk_freq_controller *)board_obj_ptr; +} + + +static int clk_get_freq_controller_table(struct gk20a *g, + struct clk_freq_controllers *pclk_freq_controllers) +{ + int status = 0; + u8 *pfreq_controller_table_ptr = NULL; + struct vbios_fct_1x_header header = { 0 }; + struct vbios_fct_1x_entry entry = { 0 }; + u8 entry_idx; + u8 *entry_offset; + struct clk_freq_controller *pclk_freq_cntr = NULL; + struct clk_freq_controller *ptmp_freq_cntr = NULL; + struct clk_freq_controller_pi *ptmp_freq_cntr_pi = NULL; + struct clk_domain *pclk_domain; + + struct freq_controller_data_type { + union { + struct boardobj board_obj; + struct clk_freq_controller freq_controller; + struct clk_freq_controller_pi freq_controller_pi; + }; + } freq_controller_data; + + pfreq_controller_table_ptr = + (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.clock_token, + FREQUENCY_CONTROLLER_TABLE); + if (pfreq_controller_table_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&header, pfreq_controller_table_ptr, + sizeof(struct vbios_fct_1x_header)); + + pclk_freq_controllers->sampling_period_ms = header.sampling_period_ms; + pclk_freq_controllers->volt_policy_idx = 0; + + /* Read in the entries. */ + for (entry_idx = 0; entry_idx < header.entry_count; entry_idx++) { + entry_offset = (pfreq_controller_table_ptr + + header.header_size + (entry_idx * header.entry_size)); + + memset(&freq_controller_data, 0x0, + sizeof(struct freq_controller_data_type)); + ptmp_freq_cntr = &freq_controller_data.freq_controller; + ptmp_freq_cntr_pi = &freq_controller_data.freq_controller_pi; + + memcpy(&entry, entry_offset, + sizeof(struct vbios_fct_1x_entry)); + + if (!BIOS_GET_FIELD(entry.flags0, + NV_VBIOS_FCT_1X_ENTRY_FLAGS0_TYPE)) { + continue; + } + + freq_controller_data.board_obj.type = (u8)BIOS_GET_FIELD( + entry.flags0, NV_VBIOS_FCT_1X_ENTRY_FLAGS0_TYPE); + + ptmp_freq_cntr->controller_id = + (u8)BIOS_GET_FIELD(entry.param0, + NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID); + + pclk_domain = CLK_CLK_DOMAIN_GET((&g->clk_pmu), + (u32)entry.clk_domain_idx); + freq_controller_data.freq_controller.clk_domain = + pclk_domain->api_domain; + + ptmp_freq_cntr->parts_freq_mode = + (u8)BIOS_GET_FIELD(entry.param0, + NV_VBIOS_FCT_1X_ENTRY_PARAM0_FREQ_MODE); + + /* Populate PI specific data */ + ptmp_freq_cntr_pi->slowdown_pct_min = + (u8)BIOS_GET_FIELD(entry.param1, + NV_VBIOS_FCT_1X_ENTRY_PARAM1_SLOWDOWN_PCT_MIN); + + ptmp_freq_cntr_pi->bpoison = + BIOS_GET_FIELD(entry.param1, + NV_VBIOS_FCT_1X_ENTRY_PARAM1_POISON); + + ptmp_freq_cntr_pi->prop_gain = + (s32)BIOS_GET_FIELD(entry.param2, + NV_VBIOS_FCT_1X_ENTRY_PARAM2_PROP_GAIN); + + ptmp_freq_cntr_pi->integ_gain = + (s32)BIOS_GET_FIELD(entry.param3, + NV_VBIOS_FCT_1X_ENTRY_PARAM3_INTEG_GAIN); + + ptmp_freq_cntr_pi->integ_decay = + (s32)BIOS_GET_FIELD(entry.param4, + NV_VBIOS_FCT_1X_ENTRY_PARAM4_INTEG_DECAY); + + ptmp_freq_cntr_pi->volt_delta_min = + (s32)BIOS_GET_FIELD(entry.param5, + NV_VBIOS_FCT_1X_ENTRY_PARAM5_VOLT_DELTA_MIN); + + ptmp_freq_cntr_pi->volt_delta_max = + (s32)BIOS_GET_FIELD(entry.param6, + NV_VBIOS_FCT_1X_ENTRY_PARAM6_VOLT_DELTA_MAX); + + ptmp_freq_cntr->freq_cap_noise_unaware_vmin_above = + (s16)BIOS_GET_FIELD(entry.param7, + NV_VBIOS_FCT_1X_ENTRY_PARAM7_FREQ_CAP_VF); + + ptmp_freq_cntr->freq_cap_noise_unaware_vmin_below = + (s16)BIOS_GET_FIELD(entry.param7, + NV_VBIOS_FCT_1X_ENTRY_PARAM7_FREQ_CAP_VMIN); + + ptmp_freq_cntr->freq_hyst_pos_mhz = + (s16)BIOS_GET_FIELD(entry.param8, + NV_VBIOS_FCT_1X_ENTRY_PARAM8_FREQ_HYST_POS); + ptmp_freq_cntr->freq_hyst_neg_mhz = + (s16)BIOS_GET_FIELD(entry.param8, + NV_VBIOS_FCT_1X_ENTRY_PARAM8_FREQ_HYST_NEG); + + if (ptmp_freq_cntr_pi->volt_delta_max < + ptmp_freq_cntr_pi->volt_delta_min) { + goto done; + } + + pclk_freq_cntr = clk_clk_freq_controller_construct(g, + (void *)&freq_controller_data); + + if (pclk_freq_cntr == NULL) { + nvgpu_err(g, + "unable to construct clock freq cntlr boardobj for %d", + entry_idx); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert( + &pclk_freq_controllers->super.super, + (struct boardobj *)pclk_freq_cntr, entry_idx); + if (status) { + nvgpu_err(g, + "unable to insert clock freq cntlr boardobj for"); + status = -EINVAL; + goto done; + } + + } + +done: + return status; +} + +int clk_freq_controller_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + pboardobjgrp = &g->clk_pmu.clk_freq_controllers.super.super; + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + nvgpu_log_info(g, "Done"); + return status; +} + +static int _clk_freq_controller_devgrp_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_clk_clk_freq_controller_boardobj_grp_set *pgrp_set = + (struct nv_pmu_clk_clk_freq_controller_boardobj_grp_set *) + pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + nvgpu_log_info(g, " Done"); + return 0; +} + +static int _clk_freq_controllers_pmudatainit(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + struct nv_pmu_clk_clk_freq_controller_boardobjgrp_set_header *pset = + (struct nv_pmu_clk_clk_freq_controller_boardobjgrp_set_header *) + pboardobjgrppmu; + struct clk_freq_controllers *pcntrs = + (struct clk_freq_controllers *)pboardobjgrp; + int status = 0; + + status = boardobjgrp_pmudatainit_e32(g, pboardobjgrp, pboardobjgrppmu); + if (status) { + nvgpu_err(g, + "error updating pmu boardobjgrp for clk freq ctrs 0x%x", + status); + goto done; + } + pset->sampling_period_ms = pcntrs->sampling_period_ms; + pset->volt_policy_idx = pcntrs->volt_policy_idx; + +done: + return status; +} + +int clk_freq_controller_sw_setup(struct gk20a *g) +{ + int status = 0; + struct boardobjgrp *pboardobjgrp = NULL; + struct clk_freq_controllers *pclk_freq_controllers; + struct avfsfllobjs *pfllobjs = &(g->clk_pmu.avfs_fllobjs); + struct fll_device *pfll; + struct clk_freq_controller *pclkfreqctrl; + u8 i; + u8 j; + + nvgpu_log_info(g, " "); + + pclk_freq_controllers = &g->clk_pmu.clk_freq_controllers; + status = boardobjgrpconstruct_e32(g, &pclk_freq_controllers->super); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for clk FCT, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->clk_pmu.clk_freq_controllers.super.super; + + pboardobjgrp->pmudatainit = _clk_freq_controllers_pmudatainit; + pboardobjgrp->pmudatainstget = + _clk_freq_controller_devgrp_pmudata_instget; + pboardobjgrp->pmustatusinstget = NULL; + + /* Initialize mask to zero.*/ + boardobjgrpmask_e32_init(&pclk_freq_controllers->freq_ctrl_load_mask, + NULL); + + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, CLK, CLK_FREQ_CONTROLLER); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + clk, CLK, clk_freq_controller, CLK_FREQ_CONTROLLER); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + status = clk_get_freq_controller_table(g, pclk_freq_controllers); + if (status) { + nvgpu_err(g, "error reading freq controller table - 0x%x", + status); + goto done; + } + + BOARDOBJGRP_FOR_EACH(&(pclk_freq_controllers->super.super), + struct clk_freq_controller *, pclkfreqctrl, i) { + pfll = NULL; + j = 0; + BOARDOBJGRP_FOR_EACH(&(pfllobjs->super.super), + struct fll_device *, pfll, j) { + if (pclkfreqctrl->controller_id == pfll->id) { + pfll->freq_ctrl_idx = i; + break; + } + } + boardobjgrpmask_bitset(&pclk_freq_controllers-> + freq_ctrl_load_mask.super, i); + } +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} diff --git a/include/clk/clk_freq_controller.h b/include/clk/clk_freq_controller.h new file mode 100644 index 0000000..7ae475c --- /dev/null +++ b/include/clk/clk_freq_controller.h @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_CLK_FREQ_CONTROLLER_H +#define NVGPU_CLK_FREQ_CONTROLLER_H + +#define CTRL_CLK_CLK_FREQ_CONTROLLER_ID_ALL 0xFF +#define CTRL_CLK_CLK_FREQ_CONTROLLER_ID_SYS 0x00 +#define CTRL_CLK_CLK_FREQ_CONTROLLER_ID_LTC 0x01 +#define CTRL_CLK_CLK_FREQ_CONTROLLER_ID_XBAR 0x02 +#define CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC0 0x03 +#define CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC1 0x04 +#define CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC2 0x05 +#define CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC3 0x06 +#define CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC4 0x07 +#define CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC5 0x08 +#define CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPCS 0x09 + +#define CTRL_CLK_CLK_FREQ_CONTROLLER_MASK_UNICAST_GPC \ + (BIT(CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC0) | \ + BIT(CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC1) | \ + BIT(CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC2) | \ + BIT(CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC3) | \ + BIT(CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC4) | \ + BIT(CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC5)) + +#define CTRL_CLK_CLK_FREQ_CONTROLLER_TYPE_DISABLED 0x00 +#define CTRL_CLK_CLK_FREQ_CONTROLLER_TYPE_PI 0x01 + + +struct clk_freq_controller { + struct boardobj super; + u8 controller_id; + u8 parts_freq_mode; + bool bdisable; + u32 clk_domain; + s16 freq_cap_noise_unaware_vmin_above; + s16 freq_cap_noise_unaware_vmin_below; + s16 freq_hyst_pos_mhz; + s16 freq_hyst_neg_mhz; +}; + +struct clk_freq_controller_pi { + struct clk_freq_controller super; + s32 prop_gain; + s32 integ_gain; + s32 integ_decay; + s32 volt_delta_min; + s32 volt_delta_max; + u8 slowdown_pct_min; + bool bpoison; +}; + +struct clk_freq_controllers { + struct boardobjgrp_e32 super; + u32 sampling_period_ms; + struct boardobjgrpmask_e32 freq_ctrl_load_mask; + u8 volt_policy_idx; + void *pprereq_load; +}; + +int clk_freq_controller_sw_setup(struct gk20a *g); +int clk_freq_controller_pmu_setup(struct gk20a *g); + +#endif /* NVGPU_CLK_FREQ_CONTROLLER_H */ diff --git a/include/clk/clk_mclk.h b/include/clk/clk_mclk.h new file mode 100644 index 0000000..47c81d1 --- /dev/null +++ b/include/clk/clk_mclk.h @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_CLK_MCLK_H +#define NVGPU_CLK_MCLK_H + +#include + +#define GP106_MCLK_LOW_SPEED 0U +#define GP106_MCLK_MID_SPEED 1U +#define GP106_MCLK_HIGH_SPEED 2U +#define GP106_MCLK_NUM_SPEED 3U + +enum gk20a_mclk_speed { + gk20a_mclk_low_speed, + gk20a_mclk_mid_speed, + gk20a_mclk_high_speed, +}; + +struct clk_mclk_state { + u32 speed; + struct nvgpu_mutex mclk_lock; + struct nvgpu_mutex data_lock; + + u16 p5_min; + u16 p0_min; + + void *vreg_buf; + bool init; + +#ifdef CONFIG_DEBUG_FS + s64 switch_max; + s64 switch_min; + u64 switch_num; + s64 switch_avg; + s64 switch_std; + bool debugfs_set; +#endif +}; + +#endif /* NVGPU_CLK_MCLK_H */ diff --git a/include/clk/clk_prog.c b/include/clk/clk_prog.c new file mode 100644 index 0000000..9d44d6d --- /dev/null +++ b/include/clk/clk_prog.c @@ -0,0 +1,1152 @@ +/* + * 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 +#include +#include + +#include "clk.h" +#include "clk_prog.h" +#include "clk_vf_point.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "gp106/bios_gp106.h" +#include "ctrl/ctrlclk.h" +#include "ctrl/ctrlvolt.h" + +static struct clk_prog *construct_clk_prog(struct gk20a *g, void *pargs); +static int devinit_get_clk_prog_table(struct gk20a *g, + struct clk_progs *pprogobjs); +static vf_flatten vfflatten_prog_1x_master; +static vf_lookup vflookup_prog_1x_master; +static get_fpoints getfpoints_prog_1x_master; +static get_slaveclk getslaveclk_prog_1x_master; + +static int _clk_progs_pmudatainit(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + struct nv_pmu_clk_clk_prog_boardobjgrp_set_header *pset = + (struct nv_pmu_clk_clk_prog_boardobjgrp_set_header *) + pboardobjgrppmu; + struct clk_progs *pprogs = (struct clk_progs *)pboardobjgrp; + u32 status = 0; + + status = boardobjgrp_pmudatainit_e32(g, pboardobjgrp, pboardobjgrppmu); + if (status) { + nvgpu_err(g, "error updating pmu boardobjgrp for clk prog 0x%x", + status); + goto done; + } + pset->slave_entry_count = pprogs->slave_entry_count; + pset->vf_entry_count = pprogs->vf_entry_count; + +done: + return status; +} + +static int _clk_progs_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_clk_clk_prog_boardobj_grp_set *pgrp_set = + (struct nv_pmu_clk_clk_prog_boardobj_grp_set *)pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + nvgpu_log_info(g, " Done"); + return 0; +} + +int clk_prog_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + struct clk_progs *pclkprogobjs; + + nvgpu_log_info(g, " "); + + status = boardobjgrpconstruct_e255(g, &g->clk_pmu.clk_progobjs.super); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for clk prog, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->clk_pmu.clk_progobjs.super.super; + pclkprogobjs = &(g->clk_pmu.clk_progobjs); + + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, CLK, CLK_PROG); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + clk, CLK, clk_prog, CLK_PROG); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + pboardobjgrp->pmudatainit = _clk_progs_pmudatainit; + pboardobjgrp->pmudatainstget = _clk_progs_pmudata_instget; + + status = devinit_get_clk_prog_table(g, pclkprogobjs); + if (status) { + goto done; + } + + status = clk_domain_clk_prog_link(g, &g->clk_pmu); + if (status) { + nvgpu_err(g, "error constructing VF point board objects"); + goto done; + } + + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int clk_prog_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + pboardobjgrp = &g->clk_pmu.clk_progobjs.super.super; + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + nvgpu_log_info(g, "Done"); + return status; +} + +static int devinit_get_clk_prog_table(struct gk20a *g, + struct clk_progs *pclkprogobjs) +{ + int status = 0; + u8 *clkprogs_tbl_ptr = NULL; + struct vbios_clock_programming_table_1x_header header = { 0 }; + struct vbios_clock_programming_table_1x_entry prog = { 0 }; + struct vbios_clock_programming_table_1x_slave_entry slaveprog = { 0 }; + struct vbios_clock_programming_table_1x_vf_entry vfprog = { 0 }; + u8 *entry = NULL; + u8 *slaveentry = NULL; + u8 *vfentry = NULL; + u32 i, j = 0; + struct clk_prog *pprog; + u8 prog_type; + u32 szfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_SIZE_0D; + u32 hszfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_1X_HEADER_SIZE_08; + u32 slaveszfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_SIZE_03; + u32 vfszfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_1X_VF_ENTRY_SIZE_02; + struct ctrl_clk_clk_prog_1x_master_vf_entry + vfentries[CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES]; + struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry + ratioslaveentries[CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES]; + struct ctrl_clk_clk_prog_1x_master_table_slave_entry + tableslaveentries[CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES]; + union { + struct boardobj board_obj; + struct clk_prog clkprog; + struct clk_prog_1x v1x; + struct clk_prog_1x_master v1x_master; + struct clk_prog_1x_master_ratio v1x_master_ratio; + struct clk_prog_1x_master_table v1x_master_table; + } prog_data; + + nvgpu_log_info(g, " "); + + clkprogs_tbl_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.clock_token, CLOCK_PROGRAMMING_TABLE); + if (clkprogs_tbl_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&header, clkprogs_tbl_ptr, hszfmt); + if (header.header_size < hszfmt) { + status = -EINVAL; + goto done; + } + hszfmt = header.header_size; + + if (header.entry_size <= VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_SIZE_05) { + szfmt = header.entry_size; + } else if (header.entry_size <= VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_SIZE_0D) { + szfmt = header.entry_size; + } else { + status = -EINVAL; + goto done; + } + + if (header.vf_entry_size < vfszfmt) { + status = -EINVAL; + goto done; + } + vfszfmt = header.vf_entry_size; + if (header.slave_entry_size < slaveszfmt) { + status = -EINVAL; + goto done; + } + slaveszfmt = header.slave_entry_size; + if (header.vf_entry_count > CTRL_CLK_CLK_DELTA_MAX_VOLT_RAILS) { + status = -EINVAL; + goto done; + } + + pclkprogobjs->slave_entry_count = header.slave_entry_count; + pclkprogobjs->vf_entry_count = header.vf_entry_count; + + for (i = 0; i < header.entry_count; i++) { + memset(&prog_data, 0x0, (u32)sizeof(prog_data)); + + /* Read table entries*/ + entry = clkprogs_tbl_ptr + hszfmt + + (i * (szfmt + (header.slave_entry_count * slaveszfmt) + + (header.vf_entry_count * vfszfmt))); + + memcpy(&prog, entry, szfmt); + memset(vfentries, 0xFF, + sizeof(struct ctrl_clk_clk_prog_1x_master_vf_entry) * + CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES); + memset(ratioslaveentries, 0xFF, + sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES); + memset(tableslaveentries, 0xFF, + sizeof(struct ctrl_clk_clk_prog_1x_master_table_slave_entry) * + CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES); + prog_type = (u8)BIOS_GET_FIELD(prog.flags0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE); + + switch (prog_type) { + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_PLL: + prog_data.v1x.source = CTRL_CLK_PROG_1X_SOURCE_PLL; + prog_data.v1x.source_data.pll.pll_idx = + (u8)BIOS_GET_FIELD(prog.param0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM0_PLL_PLL_INDEX); + prog_data.v1x.source_data.pll.freq_step_size_mhz = + (u8)BIOS_GET_FIELD(prog.param1, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM1_PLL_FREQ_STEP_SIZE); + break; + + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_ONE_SOURCE: + prog_data.v1x.source = CTRL_CLK_PROG_1X_SOURCE_ONE_SOURCE; + break; + + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_FLL: + prog_data.v1x.source = CTRL_CLK_PROG_1X_SOURCE_FLL; + break; + + default: + nvgpu_err(g, "invalid source %d", prog_type); + status = -EINVAL; + goto done; + } + + prog_data.v1x.freq_max_mhz = (u16)prog.freq_max_mhz; + + prog_type = (u8)BIOS_GET_FIELD(prog.flags0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE); + + vfentry = entry + szfmt + + header.slave_entry_count * slaveszfmt; + slaveentry = entry + szfmt; + switch (prog_type) { + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO: + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_TABLE: + prog_data.v1x_master.b_o_c_o_v_enabled = false; + for (j = 0; j < header.vf_entry_count; j++) { + memcpy(&vfprog, vfentry, vfszfmt); + + vfentries[j].vfe_idx = (u8)vfprog.vfe_idx; + if (CTRL_CLK_PROG_1X_SOURCE_FLL == + prog_data.v1x.source) { + vfentries[j].gain_vfe_idx = (u8)BIOS_GET_FIELD( + vfprog.param0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_VF_ENTRY_PARAM0_FLL_GAIN_VFE_IDX); + } else { + vfentries[j].gain_vfe_idx = CTRL_BOARDOBJ_IDX_INVALID; + } + vfentry += vfszfmt; + } + + prog_data.v1x_master.p_vf_entries = vfentries; + + for (j = 0; j < header.slave_entry_count; j++) { + memcpy(&slaveprog, slaveentry, slaveszfmt); + + switch (prog_type) { + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO: + ratioslaveentries[j].clk_dom_idx = + (u8)slaveprog.clk_dom_idx; + ratioslaveentries[j].ratio = (u8) + BIOS_GET_FIELD(slaveprog.param0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_RATIO_RATIO); + break; + + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_TABLE: + tableslaveentries[j].clk_dom_idx = + (u8)slaveprog.clk_dom_idx; + tableslaveentries[j].freq_mhz = + (u16)BIOS_GET_FIELD(slaveprog.param0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_TABLE_FREQ); + break; + } + slaveentry += slaveszfmt; + } + + switch (prog_type) { + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO: + prog_data.board_obj.type = CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO; + prog_data.v1x_master_ratio.p_slave_entries = + ratioslaveentries; + break; + + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_TABLE: + prog_data.board_obj.type = CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_TABLE; + + prog_data.v1x_master_table.p_slave_entries = + tableslaveentries; + break; + + } + break; + + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_SLAVE: + prog_data.board_obj.type = CTRL_CLK_CLK_PROG_TYPE_1X; + break; + + + default: + nvgpu_err(g, "source issue %d", prog_type); + status = -EINVAL; + goto done; + } + + pprog = construct_clk_prog(g, (void *)&prog_data); + if (pprog == NULL) { + nvgpu_err(g, + "error constructing clk_prog boardobj %d", i); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert(&pclkprogobjs->super.super, + (struct boardobj *)pprog, i); + if (status) { + nvgpu_err(g, "error adding clk_prog boardobj %d", i); + status = -EINVAL; + goto done; + } + } +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +static int _clk_prog_pmudatainit_super(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + + nvgpu_log_info(g, " "); + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + return status; +} + +static int _clk_prog_pmudatainit_1x(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_prog_1x *pclk_prog_1x; + struct nv_pmu_clk_clk_prog_1x_boardobj_set *pset; + + nvgpu_log_info(g, " "); + + status = _clk_prog_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_prog_1x = (struct clk_prog_1x *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_prog_1x_boardobj_set *) + ppmudata; + + pset->source = pclk_prog_1x->source; + pset->freq_max_mhz = pclk_prog_1x->freq_max_mhz; + pset->source_data = pclk_prog_1x->source_data; + + return status; +} + +static int _clk_prog_pmudatainit_1x_master(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_prog_1x_master *pclk_prog_1x_master; + struct nv_pmu_clk_clk_prog_1x_master_boardobj_set *pset; + u32 vfsize = sizeof(struct ctrl_clk_clk_prog_1x_master_vf_entry) * + g->clk_pmu.clk_progobjs.vf_entry_count; + + nvgpu_log_info(g, " "); + + status = _clk_prog_pmudatainit_1x(g, board_obj_ptr, ppmudata); + + pclk_prog_1x_master = + (struct clk_prog_1x_master *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_prog_1x_master_boardobj_set *) + ppmudata; + + memcpy(pset->vf_entries, pclk_prog_1x_master->p_vf_entries, vfsize); + + pset->b_o_c_o_v_enabled = pclk_prog_1x_master->b_o_c_o_v_enabled; + pset->source_data = pclk_prog_1x_master->source_data; + + memcpy(&pset->deltas, &pclk_prog_1x_master->deltas, + (u32) sizeof(struct ctrl_clk_clk_delta)); + + return status; +} + +static int _clk_prog_pmudatainit_1x_master_ratio(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_prog_1x_master_ratio *pclk_prog_1x_master_ratio; + struct nv_pmu_clk_clk_prog_1x_master_ratio_boardobj_set *pset; + u32 slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + g->clk_pmu.clk_progobjs.slave_entry_count; + + nvgpu_log_info(g, " "); + + status = _clk_prog_pmudatainit_1x_master(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_prog_1x_master_ratio = + (struct clk_prog_1x_master_ratio *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_prog_1x_master_ratio_boardobj_set *) + ppmudata; + + memcpy(pset->slave_entries, + pclk_prog_1x_master_ratio->p_slave_entries, slavesize); + + return status; +} + +static int _clk_prog_pmudatainit_1x_master_table(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_prog_1x_master_table *pclk_prog_1x_master_table; + struct nv_pmu_clk_clk_prog_1x_master_table_boardobj_set *pset; + u32 slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + g->clk_pmu.clk_progobjs.slave_entry_count; + + nvgpu_log_info(g, " "); + + status = _clk_prog_pmudatainit_1x_master(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_prog_1x_master_table = + (struct clk_prog_1x_master_table *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_prog_1x_master_table_boardobj_set *) + ppmudata; + memcpy(pset->slave_entries, + pclk_prog_1x_master_table->p_slave_entries, slavesize); + + return status; +} + +static u32 _clk_prog_1x_master_rail_construct_vf_point(struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_prog_1x_master *p1xmaster, + struct ctrl_clk_clk_prog_1x_master_vf_entry *p_vf_rail, + struct clk_vf_point *p_vf_point_tmp, + u8 *p_vf_point_idx) +{ + struct clk_vf_point *p_vf_point; + u32 status; + + nvgpu_log_info(g, " "); + + p_vf_point = construct_clk_vf_point(g, (void *)p_vf_point_tmp); + if (p_vf_point == NULL) { + status = -ENOMEM; + goto done; + } + status = pclk->clk_vf_pointobjs.super.super.objinsert( + &pclk->clk_vf_pointobjs.super.super, + &p_vf_point->super, + *p_vf_point_idx); + if (status) { + goto done; + } + + p_vf_rail->vf_point_idx_last = (*p_vf_point_idx)++; + +done: + nvgpu_log_info(g, "done status %x", status); + return status; +} + +static int clk_prog_construct_super(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct clk_prog *pclkprog; + int status = 0; + + status = boardobj_construct_super(g, ppboardobj, + size, pargs); + if (status) { + return -EINVAL; + } + + pclkprog = (struct clk_prog *)*ppboardobj; + + pclkprog->super.pmudatainit = + _clk_prog_pmudatainit_super; + return status; +} + + +static int clk_prog_construct_1x(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_prog_1x *pclkprog; + struct clk_prog_1x *ptmpprog = + (struct clk_prog_1x *)pargs; + int status = 0; + + nvgpu_log_info(g, " "); + ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_PROG_TYPE_1X); + status = clk_prog_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pclkprog = (struct clk_prog_1x *)*ppboardobj; + + pclkprog->super.super.pmudatainit = + _clk_prog_pmudatainit_1x; + + pclkprog->source = ptmpprog->source; + pclkprog->freq_max_mhz = ptmpprog->freq_max_mhz; + pclkprog->source_data = ptmpprog->source_data; + + return status; +} + +static int clk_prog_construct_1x_master(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_prog_1x_master *pclkprog; + struct clk_prog_1x_master *ptmpprog = + (struct clk_prog_1x_master *)pargs; + int status = 0; + u32 vfsize = sizeof(struct ctrl_clk_clk_prog_1x_master_vf_entry) * + g->clk_pmu.clk_progobjs.vf_entry_count; + u8 railidx; + + nvgpu_log_info(g, " type - %x", BOARDOBJ_GET_TYPE(pargs)); + + ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_PROG_TYPE_1X_MASTER); + status = clk_prog_construct_1x(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pclkprog = (struct clk_prog_1x_master *)*ppboardobj; + + pclkprog->super.super.super.pmudatainit = + _clk_prog_pmudatainit_1x_master; + + pclkprog->vfflatten = + vfflatten_prog_1x_master; + + pclkprog->vflookup = + vflookup_prog_1x_master; + + pclkprog->getfpoints = + getfpoints_prog_1x_master; + + pclkprog->getslaveclk = + getslaveclk_prog_1x_master; + + pclkprog->p_vf_entries = (struct ctrl_clk_clk_prog_1x_master_vf_entry *) + nvgpu_kzalloc(g, vfsize); + if (!pclkprog->p_vf_entries) + return -ENOMEM; + + memcpy(pclkprog->p_vf_entries, ptmpprog->p_vf_entries, vfsize); + + pclkprog->b_o_c_o_v_enabled = ptmpprog->b_o_c_o_v_enabled; + + for (railidx = 0; + railidx < g->clk_pmu.clk_progobjs.vf_entry_count; + railidx++) { + pclkprog->p_vf_entries[railidx].vf_point_idx_first = + CTRL_CLK_CLK_VF_POINT_IDX_INVALID; + pclkprog->p_vf_entries[railidx].vf_point_idx_last = + CTRL_CLK_CLK_VF_POINT_IDX_INVALID; + } + + return status; +} + +static int clk_prog_construct_1x_master_ratio(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_prog_1x_master_ratio *pclkprog; + struct clk_prog_1x_master_ratio *ptmpprog = + (struct clk_prog_1x_master_ratio *)pargs; + int status = 0; + u32 slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + g->clk_pmu.clk_progobjs.slave_entry_count; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO); + status = clk_prog_construct_1x_master(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pclkprog = (struct clk_prog_1x_master_ratio *)*ppboardobj; + + pclkprog->super.super.super.super.pmudatainit = + _clk_prog_pmudatainit_1x_master_ratio; + + pclkprog->p_slave_entries = + (struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry *) + nvgpu_kzalloc(g, slavesize); + if (!pclkprog->p_slave_entries) { + return -ENOMEM; + } + + memset(pclkprog->p_slave_entries, CTRL_CLK_CLK_DOMAIN_INDEX_INVALID, + slavesize); + + memcpy(pclkprog->p_slave_entries, ptmpprog->p_slave_entries, slavesize); + + return status; +} + +static int clk_prog_construct_1x_master_table(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_prog_1x_master_table *pclkprog; + struct clk_prog_1x_master_table *ptmpprog = + (struct clk_prog_1x_master_table *)pargs; + int status = 0; + u32 slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + g->clk_pmu.clk_progobjs.slave_entry_count; + + nvgpu_log_info(g, "type - %x", BOARDOBJ_GET_TYPE(pargs)); + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_TABLE) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_TABLE); + status = clk_prog_construct_1x_master(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pclkprog = (struct clk_prog_1x_master_table *)*ppboardobj; + + pclkprog->super.super.super.super.pmudatainit = + _clk_prog_pmudatainit_1x_master_table; + + pclkprog->p_slave_entries = + (struct ctrl_clk_clk_prog_1x_master_table_slave_entry *) + nvgpu_kzalloc(g, slavesize); + + if (!pclkprog->p_slave_entries) { + status = -ENOMEM; + goto exit; + } + + memset(pclkprog->p_slave_entries, CTRL_CLK_CLK_DOMAIN_INDEX_INVALID, + slavesize); + + memcpy(pclkprog->p_slave_entries, ptmpprog->p_slave_entries, slavesize); + +exit: + if (status) { + (*ppboardobj)->destruct(*ppboardobj); + } + + return status; +} + +static struct clk_prog *construct_clk_prog(struct gk20a *g, void *pargs) +{ + struct boardobj *board_obj_ptr = NULL; + int status; + + nvgpu_log_info(g, " type - %x", BOARDOBJ_GET_TYPE(pargs)); + switch (BOARDOBJ_GET_TYPE(pargs)) { + case CTRL_CLK_CLK_PROG_TYPE_1X: + status = clk_prog_construct_1x(g, &board_obj_ptr, + sizeof(struct clk_prog_1x), pargs); + break; + + case CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_TABLE: + status = clk_prog_construct_1x_master_table(g, &board_obj_ptr, + sizeof(struct clk_prog_1x_master_table), pargs); + break; + + case CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO: + status = clk_prog_construct_1x_master_ratio(g, &board_obj_ptr, + sizeof(struct clk_prog_1x_master_ratio), pargs); + break; + + default: + return NULL; + } + + if (status) { + if (board_obj_ptr) { + board_obj_ptr->destruct(board_obj_ptr); + } + return NULL; + } + + nvgpu_log_info(g, " Done"); + + return (struct clk_prog *)board_obj_ptr; +} + +static u32 vfflatten_prog_1x_master(struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_prog_1x_master *p1xmaster, + u8 clk_domain_idx, u16 *pfreqmaxlastmhz) +{ + struct ctrl_clk_clk_prog_1x_master_vf_entry *p_vf_rail; + union { + struct boardobj board_obj; + struct clk_vf_point vf_point; + struct clk_vf_point_freq freq; + struct clk_vf_point_volt volt; + } vf_point_data; + u32 status = 0; + u8 step_count; + u8 freq_step_size_mhz = 0; + u8 vf_point_idx; + u8 vf_rail_idx; + + nvgpu_log_info(g, " "); + memset(&vf_point_data, 0x0, sizeof(vf_point_data)); + + vf_point_idx = BOARDOBJGRP_NEXT_EMPTY_IDX( + &pclk->clk_vf_pointobjs.super.super); + + for (vf_rail_idx = 0; + vf_rail_idx < pclk->clk_progobjs.vf_entry_count; + vf_rail_idx++) { + u32 voltage_min_uv; + u32 voltage_step_size_uv; + u8 i; + + p_vf_rail = &p1xmaster->p_vf_entries[vf_rail_idx]; + if (p_vf_rail->vfe_idx == CTRL_BOARDOBJ_IDX_INVALID) { + continue; + } + + p_vf_rail->vf_point_idx_first = vf_point_idx; + + vf_point_data.vf_point.vfe_equ_idx = p_vf_rail->vfe_idx; + vf_point_data.vf_point.volt_rail_idx = vf_rail_idx; + + step_count = 0; + + switch (p1xmaster->super.source) { + case CTRL_CLK_PROG_1X_SOURCE_PLL: + freq_step_size_mhz = + p1xmaster->super.source_data.pll.freq_step_size_mhz; + step_count = (freq_step_size_mhz == 0) ? 0 : + (p1xmaster->super.freq_max_mhz - *pfreqmaxlastmhz - 1) / + freq_step_size_mhz; + /* Intentional fall-through.*/ + + case CTRL_CLK_PROG_1X_SOURCE_ONE_SOURCE: + vf_point_data.board_obj.type = + CTRL_CLK_CLK_VF_POINT_TYPE_FREQ; + do { + clkvfpointfreqmhzset(g, &vf_point_data.vf_point, + p1xmaster->super.freq_max_mhz - + step_count * freq_step_size_mhz); + + status = _clk_prog_1x_master_rail_construct_vf_point(g, pclk, + p1xmaster, p_vf_rail, + &vf_point_data.vf_point, &vf_point_idx); + if (status) { + goto done; + } + } while (step_count-- > 0); + break; + + case CTRL_CLK_PROG_1X_SOURCE_FLL: + voltage_min_uv = CLK_FLL_LUT_MIN_VOLTAGE_UV(pclk); + voltage_step_size_uv = CLK_FLL_LUT_STEP_SIZE_UV(pclk); + step_count = CLK_FLL_LUT_VF_NUM_ENTRIES(pclk); + + /* FLL sources use a voltage-based VF_POINT.*/ + vf_point_data.board_obj.type = + CTRL_CLK_CLK_VF_POINT_TYPE_VOLT; + for (i = 0; i < step_count; i++) { + vf_point_data.volt.source_voltage_uv = + voltage_min_uv + i * voltage_step_size_uv; + + status = _clk_prog_1x_master_rail_construct_vf_point(g, pclk, + p1xmaster, p_vf_rail, + &vf_point_data.vf_point, &vf_point_idx); + if (status) { + goto done; + } + } + break; + } + } + + *pfreqmaxlastmhz = p1xmaster->super.freq_max_mhz; + +done: + nvgpu_log_info(g, "done status %x", status); + return status; +} + +static u32 vflookup_prog_1x_master +( + struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_prog_1x_master *p1xmaster, + u8 *slave_clk_domain, + u16 *pclkmhz, + u32 *pvoltuv, + u8 rail +) +{ + int j; + struct ctrl_clk_clk_prog_1x_master_vf_entry + *pvfentry; + struct clk_vf_point *pvfpoint; + struct clk_progs *pclkprogobjs; + struct clk_prog_1x_master_ratio *p1xmasterratio; + u16 clkmhz; + u32 voltuv; + u8 slaveentrycount; + int i; + struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry *pslaveents; + + if ((*pclkmhz != 0) && (*pvoltuv != 0)) { + return -EINVAL; + } + + pclkprogobjs = &(pclk->clk_progobjs); + + slaveentrycount = pclkprogobjs->slave_entry_count; + + if (pclkprogobjs->vf_entry_count > + CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES) { + return -EINVAL; + } + + if (rail >= pclkprogobjs->vf_entry_count) { + return -EINVAL; + } + + pvfentry = p1xmaster->p_vf_entries; + + pvfentry = (struct ctrl_clk_clk_prog_1x_master_vf_entry *)( + (u8 *)pvfentry + + (sizeof(struct ctrl_clk_clk_prog_1x_master_vf_entry) * + rail)); + + clkmhz = *pclkmhz; + voltuv = *pvoltuv; + + /*if domain is slave domain and freq is input + then derive master clk */ + if ((slave_clk_domain != NULL) && (*pclkmhz != 0)) { + if (p1xmaster->super.super.super.implements(g, + &p1xmaster->super.super.super, + CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO)) { + + p1xmasterratio = + (struct clk_prog_1x_master_ratio *)p1xmaster; + pslaveents = p1xmasterratio->p_slave_entries; + for (i = 0; i < slaveentrycount; i++) { + if (pslaveents->clk_dom_idx == + *slave_clk_domain) { + break; + } + pslaveents++; + } + if (i == slaveentrycount) { + return -EINVAL; + } + clkmhz = (clkmhz * 100)/pslaveents->ratio; + } else { + /* only support ratio for now */ + return -EINVAL; + } + } + + /* if both volt and clks are zero simply print*/ + if ((*pvoltuv == 0) && (*pclkmhz == 0)) { + for (j = pvfentry->vf_point_idx_first; + j <= pvfentry->vf_point_idx_last; j++) { + pvfpoint = CLK_CLK_VF_POINT_GET(pclk, j); + nvgpu_err(g, "v %x c %x", + clkvfpointvoltageuvget(g, pvfpoint), + clkvfpointfreqmhzget(g, pvfpoint)); + } + return -EINVAL; + } + /* start looking up f for v for v for f */ + /* looking for volt? */ + if (*pvoltuv == 0) { + pvfpoint = CLK_CLK_VF_POINT_GET(pclk, + pvfentry->vf_point_idx_last); + /* above range? */ + if (clkmhz > clkvfpointfreqmhzget(g, pvfpoint)) { + return -EINVAL; + } + + for (j = pvfentry->vf_point_idx_last; + j >= pvfentry->vf_point_idx_first; j--) { + pvfpoint = CLK_CLK_VF_POINT_GET(pclk, j); + if (clkmhz <= clkvfpointfreqmhzget(g, pvfpoint)) { + voltuv = clkvfpointvoltageuvget(g, pvfpoint); + } else { + break; + } + } + } else { /* looking for clk? */ + + pvfpoint = CLK_CLK_VF_POINT_GET(pclk, + pvfentry->vf_point_idx_first); + /* below range? */ + if (voltuv < clkvfpointvoltageuvget(g, pvfpoint)) { + return -EINVAL; + } + + for (j = pvfentry->vf_point_idx_first; + j <= pvfentry->vf_point_idx_last; j++) { + pvfpoint = CLK_CLK_VF_POINT_GET(pclk, j); + if (voltuv >= clkvfpointvoltageuvget(g, pvfpoint)) { + clkmhz = clkvfpointfreqmhzget(g, pvfpoint); + } else { + break; + } + } + } + + /*if domain is slave domain and freq was looked up + then derive slave clk */ + if ((slave_clk_domain != NULL) && (*pclkmhz == 0)) { + if (p1xmaster->super.super.super.implements(g, + &p1xmaster->super.super.super, + CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO)) { + + p1xmasterratio = + (struct clk_prog_1x_master_ratio *)p1xmaster; + pslaveents = p1xmasterratio->p_slave_entries; + for (i = 0; i < slaveentrycount; i++) { + if (pslaveents->clk_dom_idx == + *slave_clk_domain) { + break; + } + pslaveents++; + } + if (i == slaveentrycount) { + return -EINVAL; + } + clkmhz = (clkmhz * pslaveents->ratio)/100; + } else { + /* only support ratio for now */ + return -EINVAL; + } + } + *pclkmhz = clkmhz; + *pvoltuv = voltuv; + if ((clkmhz == 0) || (voltuv == 0)) { + return -EINVAL; + } + return 0; +} + +static u32 getfpoints_prog_1x_master +( + struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_prog_1x_master *p1xmaster, + u32 *pfpointscount, + u16 **ppfreqpointsinmhz, + u8 rail +) +{ + + struct ctrl_clk_clk_prog_1x_master_vf_entry + *pvfentry; + struct clk_vf_point *pvfpoint; + struct clk_progs *pclkprogobjs; + u8 j; + u32 fpointscount = 0; + + if (pfpointscount == NULL) { + return -EINVAL; + } + + pclkprogobjs = &(pclk->clk_progobjs); + + if (pclkprogobjs->vf_entry_count > + CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES) { + return -EINVAL; + } + + if (rail >= pclkprogobjs->vf_entry_count) { + return -EINVAL; + } + + pvfentry = p1xmaster->p_vf_entries; + + pvfentry = (struct ctrl_clk_clk_prog_1x_master_vf_entry *)( + (u8 *)pvfentry + + (sizeof(struct ctrl_clk_clk_prog_1x_master_vf_entry) * + (rail+1))); + + fpointscount = pvfentry->vf_point_idx_last - + pvfentry->vf_point_idx_first + 1; + + /* if pointer for freq data is NULL simply return count */ + if (*ppfreqpointsinmhz == NULL) { + goto done; + } + + if (fpointscount > *pfpointscount) { + return -ENOMEM; + } + for (j = pvfentry->vf_point_idx_first; + j <= pvfentry->vf_point_idx_last; j++) { + pvfpoint = CLK_CLK_VF_POINT_GET(pclk, j); + **ppfreqpointsinmhz = clkvfpointfreqmhzget(g, pvfpoint); + (*ppfreqpointsinmhz)++; + } +done: + *pfpointscount = fpointscount; + return 0; +} + +static int getslaveclk_prog_1x_master(struct gk20a *g, + struct clk_pmupstate *pclk, + struct clk_prog_1x_master *p1xmaster, + u8 slave_clk_domain, + u16 *pclkmhz, + u16 masterclkmhz +) +{ + struct clk_progs *pclkprogobjs; + struct clk_prog_1x_master_ratio *p1xmasterratio; + u8 slaveentrycount; + u8 i; + struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry *pslaveents; + + if (pclkmhz == NULL) { + return -EINVAL; + } + + if (masterclkmhz == 0) { + return -EINVAL; + } + + *pclkmhz = 0; + pclkprogobjs = &(pclk->clk_progobjs); + + slaveentrycount = pclkprogobjs->slave_entry_count; + + if (p1xmaster->super.super.super.implements(g, + &p1xmaster->super.super.super, + CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO)) { + p1xmasterratio = + (struct clk_prog_1x_master_ratio *)p1xmaster; + pslaveents = p1xmasterratio->p_slave_entries; + for (i = 0; i < slaveentrycount; i++) { + if (pslaveents->clk_dom_idx == + slave_clk_domain) { + break; + } + pslaveents++; + } + if (i == slaveentrycount) { + return -EINVAL; + } + *pclkmhz = (masterclkmhz * pslaveents->ratio)/100; + } else { + /* only support ratio for now */ + return -EINVAL; + } + return 0; +} diff --git a/include/clk/clk_prog.h b/include/clk/clk_prog.h new file mode 100644 index 0000000..af6368f --- /dev/null +++ b/include/clk/clk_prog.h @@ -0,0 +1,100 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_CLK_PROG_H +#define NVGPU_CLK_PROG_H +#include "ctrl/ctrlclk.h" +#include "ctrl/ctrlboardobj.h" +#include +#include "boardobj/boardobjgrp_e32.h" +#include "boardobj/boardobjgrp_e255.h" +#include "boardobj/boardobjgrpmask.h" + +int clk_prog_sw_setup(struct gk20a *g); +int clk_prog_pmu_setup(struct gk20a *g); +struct clk_prog_1x_master; + +typedef u32 vf_flatten(struct gk20a *g, struct clk_pmupstate *pclk, + struct clk_prog_1x_master *p1xmaster, + u8 clk_domain_idx, u16 *pfreqmaxlastmhz); + +typedef u32 vf_lookup(struct gk20a *g, struct clk_pmupstate *pclk, + struct clk_prog_1x_master *p1xmaster, + u8 *slave_clk_domain_idx, u16 *pclkmhz, + u32 *pvoltuv, u8 rail); + +typedef int get_slaveclk(struct gk20a *g, struct clk_pmupstate *pclk, + struct clk_prog_1x_master *p1xmaster, + u8 slave_clk_domain_idx, u16 *pclkmhz, + u16 masterclkmhz); + +typedef u32 get_fpoints(struct gk20a *g, struct clk_pmupstate *pclk, + struct clk_prog_1x_master *p1xmaster, + u32 *pfpointscount, + u16 **ppfreqpointsinmhz, u8 rail); + + +struct clk_progs { + struct boardobjgrp_e255 super; + u8 slave_entry_count; + u8 vf_entry_count; + +}; + +struct clk_prog { + struct boardobj super; +}; + +struct clk_prog_1x { + struct clk_prog super; + u8 source; + u16 freq_max_mhz; + union ctrl_clk_clk_prog_1x_source_data source_data; +}; + +struct clk_prog_1x_master { + struct clk_prog_1x super; + bool b_o_c_o_v_enabled; + struct ctrl_clk_clk_prog_1x_master_vf_entry *p_vf_entries; + struct ctrl_clk_clk_delta deltas; + union ctrl_clk_clk_prog_1x_master_source_data source_data; + vf_flatten *vfflatten; + vf_lookup *vflookup; + get_fpoints *getfpoints; + get_slaveclk *getslaveclk; +}; + +struct clk_prog_1x_master_ratio { + struct clk_prog_1x_master super; + struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry *p_slave_entries; +}; + +struct clk_prog_1x_master_table { + struct clk_prog_1x_master super; + struct ctrl_clk_clk_prog_1x_master_table_slave_entry *p_slave_entries; +}; + +#define CLK_CLK_PROG_GET(pclk, idx) \ + ((struct clk_prog *)BOARDOBJGRP_OBJ_GET_BY_IDX( \ + &pclk->clk_progobjs.super.super, (u8)(idx))) + +#endif /* NVGPU_CLK_PROG_H */ diff --git a/include/clk/clk_vf_point.c b/include/clk/clk_vf_point.c new file mode 100644 index 0000000..96413c8 --- /dev/null +++ b/include/clk/clk_vf_point.c @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "clk.h" +#include "clk_vf_point.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "ctrl/ctrlclk.h" +#include "ctrl/ctrlvolt.h" + +static int _clk_vf_point_pmudatainit_super(struct gk20a *g, struct boardobj + *board_obj_ptr, struct nv_pmu_boardobj *ppmudata); + +static int _clk_vf_points_pmudatainit(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + u32 status = 0; + + status = boardobjgrp_pmudatainit_e32(g, pboardobjgrp, pboardobjgrppmu); + if (status) { + nvgpu_err(g, + "error updating pmu boardobjgrp for clk vfpoint 0x%x", + status); + goto done; + } + +done: + return status; +} + +static int _clk_vf_points_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_clk_clk_vf_point_boardobj_grp_set *pgrp_set = + (struct nv_pmu_clk_clk_vf_point_boardobj_grp_set *) + pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (idx >= CTRL_BOARDOBJGRP_E255_MAX_OBJECTS) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + nvgpu_log_info(g, " Done"); + return 0; +} + +static int _clk_vf_points_pmustatus_instget(struct gk20a *g, + void *pboardobjgrppmu, + struct nv_pmu_boardobj_query **ppboardobjpmustatus, + u8 idx) +{ + struct nv_pmu_clk_clk_vf_point_boardobj_grp_get_status *pgrp_get_status = + (struct nv_pmu_clk_clk_vf_point_boardobj_grp_get_status *) + pboardobjgrppmu; + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (idx >= CTRL_BOARDOBJGRP_E255_MAX_OBJECTS) { + return -EINVAL; + } + + *ppboardobjpmustatus = (struct nv_pmu_boardobj_query *) + &pgrp_get_status->objects[idx].data.board_obj; + return 0; +} + +int clk_vf_point_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + status = boardobjgrpconstruct_e255(g, &g->clk_pmu.clk_vf_pointobjs.super); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for clk vfpoint, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->clk_pmu.clk_vf_pointobjs.super.super; + + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, CLK, CLK_VF_POINT); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + clk, CLK, clk_vf_point, CLK_VF_POINT); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, + &g->clk_pmu.clk_vf_pointobjs.super.super, + clk, CLK, clk_vf_point, CLK_VF_POINT); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + pboardobjgrp->pmudatainit = _clk_vf_points_pmudatainit; + pboardobjgrp->pmudatainstget = _clk_vf_points_pmudata_instget; + pboardobjgrp->pmustatusinstget = _clk_vf_points_pmustatus_instget; + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int clk_vf_point_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + pboardobjgrp = &g->clk_pmu.clk_vf_pointobjs.super.super; + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + nvgpu_log_info(g, "Done"); + return status; +} + +static int clk_vf_point_construct_super(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct clk_vf_point *pclkvfpoint; + struct clk_vf_point *ptmpvfpoint = + (struct clk_vf_point *)pargs; + int status = 0; + + status = boardobj_construct_super(g, ppboardobj, + size, pargs); + if (status) { + return -EINVAL; + } + + pclkvfpoint = (struct clk_vf_point *)*ppboardobj; + + pclkvfpoint->super.pmudatainit = + _clk_vf_point_pmudatainit_super; + + pclkvfpoint->vfe_equ_idx = ptmpvfpoint->vfe_equ_idx; + pclkvfpoint->volt_rail_idx = ptmpvfpoint->volt_rail_idx; + + return status; +} + +static int _clk_vf_point_pmudatainit_volt(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_vf_point_volt *pclk_vf_point_volt; + struct nv_pmu_clk_clk_vf_point_volt_boardobj_set *pset; + + nvgpu_log_info(g, " "); + + status = _clk_vf_point_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_vf_point_volt = + (struct clk_vf_point_volt *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_vf_point_volt_boardobj_set *) + ppmudata; + + pset->source_voltage_uv = pclk_vf_point_volt->source_voltage_uv; + pset->freq_delta.data = pclk_vf_point_volt->freq_delta.data; + pset->freq_delta.type = pclk_vf_point_volt->freq_delta.type; + + return status; +} + +static int _clk_vf_point_pmudatainit_freq(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_vf_point_freq *pclk_vf_point_freq; + struct nv_pmu_clk_clk_vf_point_freq_boardobj_set *pset; + + nvgpu_log_info(g, " "); + + status = _clk_vf_point_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_vf_point_freq = + (struct clk_vf_point_freq *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_vf_point_freq_boardobj_set *) + ppmudata; + + pset->freq_mhz = + clkvfpointfreqmhzget(g, &pclk_vf_point_freq->super); + + pset->volt_delta_uv = pclk_vf_point_freq->volt_delta_uv; + + return status; +} + +static int clk_vf_point_construct_volt(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_vf_point_volt *pclkvfpoint; + struct clk_vf_point_volt *ptmpvfpoint = + (struct clk_vf_point_volt *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_VF_POINT_TYPE_VOLT) { + return -EINVAL; + } + + ptmpobj->type_mask = BIT(CTRL_CLK_CLK_VF_POINT_TYPE_VOLT); + status = clk_vf_point_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pclkvfpoint = (struct clk_vf_point_volt *)*ppboardobj; + + pclkvfpoint->super.super.pmudatainit = + _clk_vf_point_pmudatainit_volt; + + pclkvfpoint->source_voltage_uv = ptmpvfpoint->source_voltage_uv; + pclkvfpoint->freq_delta = ptmpvfpoint->freq_delta; + + return status; +} + +static int clk_vf_point_construct_freq(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_vf_point_freq *pclkvfpoint; + struct clk_vf_point_freq *ptmpvfpoint = + (struct clk_vf_point_freq *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_VF_POINT_TYPE_FREQ) { + return -EINVAL; + } + + ptmpobj->type_mask = BIT(CTRL_CLK_CLK_VF_POINT_TYPE_FREQ); + status = clk_vf_point_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pclkvfpoint = (struct clk_vf_point_freq *)*ppboardobj; + + pclkvfpoint->super.super.pmudatainit = + _clk_vf_point_pmudatainit_freq; + + clkvfpointfreqmhzset(g, &pclkvfpoint->super, + clkvfpointfreqmhzget(g, &ptmpvfpoint->super)); + + return status; +} + +struct clk_vf_point *construct_clk_vf_point(struct gk20a *g, void *pargs) +{ + struct boardobj *board_obj_ptr = NULL; + int status; + + nvgpu_log_info(g, " "); + switch (BOARDOBJ_GET_TYPE(pargs)) { + case CTRL_CLK_CLK_VF_POINT_TYPE_FREQ: + status = clk_vf_point_construct_freq(g, &board_obj_ptr, + sizeof(struct clk_vf_point_freq), pargs); + break; + + case CTRL_CLK_CLK_VF_POINT_TYPE_VOLT: + status = clk_vf_point_construct_volt(g, &board_obj_ptr, + sizeof(struct clk_vf_point_volt), pargs); + break; + + default: + return NULL; + } + + if (status) { + return NULL; + } + + nvgpu_log_info(g, " Done"); + + return (struct clk_vf_point *)board_obj_ptr; +} + +static int _clk_vf_point_pmudatainit_super(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_vf_point *pclk_vf_point; + struct nv_pmu_clk_clk_vf_point_boardobj_set *pset; + + nvgpu_log_info(g, " "); + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_vf_point = + (struct clk_vf_point *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_vf_point_boardobj_set *) + ppmudata; + + + pset->vfe_equ_idx = pclk_vf_point->vfe_equ_idx; + pset->volt_rail_idx = pclk_vf_point->volt_rail_idx; + return status; +} + + +static int clk_vf_point_update(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + struct clk_vf_point *pclk_vf_point; + struct nv_pmu_clk_clk_vf_point_boardobj_get_status *pstatus; + + nvgpu_log_info(g, " "); + + + pclk_vf_point = + (struct clk_vf_point *)board_obj_ptr; + + pstatus = (struct nv_pmu_clk_clk_vf_point_boardobj_get_status *) + ppmudata; + + if (pstatus->super.type != pclk_vf_point->super.type) { + nvgpu_err(g, + "pmu data and boardobj type not matching"); + return -EINVAL; + } + /* now copy VF pair */ + memcpy(&pclk_vf_point->pair, &pstatus->pair, + sizeof(struct ctrl_clk_vf_pair)); + return 0; +} + +/*get latest vf point data from PMU */ +int clk_vf_point_cache(struct gk20a *g) +{ + + struct clk_vf_points *pclk_vf_points; + struct boardobjgrp *pboardobjgrp; + struct boardobjgrpmask *pboardobjgrpmask; + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu; + struct boardobj *pboardobj = NULL; + struct nv_pmu_boardobj_query *pboardobjpmustatus = NULL; + int status; + u8 index; + + nvgpu_log_info(g, " "); + pclk_vf_points = &g->clk_pmu.clk_vf_pointobjs; + pboardobjgrp = &pclk_vf_points->super.super; + pboardobjgrpmask = &pclk_vf_points->super.mask.super; + + status = pboardobjgrp->pmugetstatus(g, pboardobjgrp, pboardobjgrpmask); + if (status) { + nvgpu_err(g, "err getting boardobjs from pmu"); + return status; + } + pboardobjgrppmu = pboardobjgrp->pmu.getstatus.buf; + + BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) { + status = pboardobjgrp->pmustatusinstget(g, + (struct nv_pmu_boardobjgrp *)pboardobjgrppmu, + &pboardobjpmustatus, index); + if (status) { + nvgpu_err(g, "could not get status object instance"); + return status; + } + + status = clk_vf_point_update(g, pboardobj, + (struct nv_pmu_boardobj *)pboardobjpmustatus); + if (status) { + nvgpu_err(g, "invalid data from pmu at %d", index); + return status; + } + } + + return 0; +} diff --git a/include/clk/clk_vf_point.h b/include/clk/clk_vf_point.h new file mode 100644 index 0000000..b72fe64 --- /dev/null +++ b/include/clk/clk_vf_point.h @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_CLK_VF_POINT_H +#define NVGPU_CLK_VF_POINT_H +#include "ctrl/ctrlclk.h" +#include "ctrl/ctrlboardobj.h" +#include +#include "boardobj/boardobjgrp_e32.h" +#include "boardobj/boardobjgrpmask.h" + +int clk_vf_point_sw_setup(struct gk20a *g); +int clk_vf_point_pmu_setup(struct gk20a *g); +int clk_vf_point_cache(struct gk20a *g); + +struct clk_vf_points { + struct boardobjgrp_e255 super; +}; + +struct clk_vf_point { + struct boardobj super; + u8 vfe_equ_idx; + u8 volt_rail_idx; + struct ctrl_clk_vf_pair pair; +}; + +struct clk_vf_point_volt { + struct clk_vf_point super; + u32 source_voltage_uv; + struct ctrl_clk_freq_delta freq_delta; +}; + +struct clk_vf_point_freq { + struct clk_vf_point super; + int volt_delta_uv; +}; + +#define CLK_CLK_VF_POINT_GET(pclk, idx) \ + ((struct clk_vf_point *)BOARDOBJGRP_OBJ_GET_BY_IDX( \ + &pclk->clk_vf_pointobjs.super.super, (u8)(idx))) + +#define clkvfpointpairget(pvfpoint) \ + (&((pvfpoint)->pair)) + +#define clkvfpointfreqmhzget(pgpu, pvfpoint) \ + CTRL_CLK_VF_PAIR_FREQ_MHZ_GET(clkvfpointpairget(pvfpoint)) + +#define clkvfpointfreqdeltamhzGet(pgpu, pvfPoint) \ + ((BOARDOBJ_GET_TYPE(pvfpoint) == CTRL_CLK_CLK_VF_POINT_TYPE_VOLT) ? \ + (((struct clk_vf_point_volt *)(pvfpoint))->freq_delta_khz / 1000) : 0) + +#define clkvfpointfreqmhzset(pgpu, pvfpoint, _freqmhz) \ + CTRL_CLK_VF_PAIR_FREQ_MHZ_SET(clkvfpointpairget(pvfpoint), _freqmhz) + +#define clkvfpointvoltageuvset(pgpu, pvfpoint, _voltageuv) \ + CTRL_CLK_VF_PAIR_VOLTAGE_UV_SET(clkvfpointpairget(pvfpoint), \ + _voltageuv) + +#define clkvfpointvoltageuvget(pgpu, pvfpoint) \ + CTRL_CLK_VF_PAIR_VOLTAGE_UV_GET(clkvfpointpairget(pvfpoint)) \ + +struct clk_vf_point *construct_clk_vf_point(struct gk20a *g, void *pargs); + +#endif /* NVGPU_CLK_VF_POINT_H */ diff --git a/include/clk/clk_vin.c b/include/clk/clk_vin.c new file mode 100644 index 0000000..e0a4a5b --- /dev/null +++ b/include/clk/clk_vin.c @@ -0,0 +1,573 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" + +#include "ctrl/ctrlvolt.h" + +#include "gp106/bios_gp106.h" + +#include "clk.h" +#include "clk_vin.h" + +static int devinit_get_vin_device_table(struct gk20a *g, + struct avfsvinobjs *pvinobjs); + +static int vin_device_construct_v10(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs); +static int vin_device_construct_v20(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs); +static int vin_device_construct_super(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs); +static struct vin_device *construct_vin_device(struct gk20a *g, void *pargs); + +static int vin_device_init_pmudata_v10(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata); +static int vin_device_init_pmudata_v20(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata); +static int vin_device_init_pmudata_super(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata); + +u32 clk_avfs_get_vin_cal_fuse_v10(struct gk20a *g, + struct avfsvinobjs *pvinobjs, + struct vin_device_v20 *pvindev) +{ + u32 status = 0; + u32 slope, intercept; + u8 i; + + if (pvinobjs->calibration_rev_vbios == g->ops.fuse.read_vin_cal_fuse_rev(g)) { + BOARDOBJGRP_FOR_EACH(&(pvinobjs->super.super), + struct vin_device_v20 *, pvindev, i) { + slope = 0; + intercept = 0; + pvindev = (struct vin_device_v20 *)CLK_GET_VIN_DEVICE(pvinobjs, i); + status = g->ops.fuse.read_vin_cal_slope_intercept_fuse(g, + pvindev->super.id, &slope, &intercept); + if (status) { + nvgpu_err(g, + "err reading vin cal for id %x", pvindev->super.id); + return status; + } + pvindev->data.vin_cal.cal_v10.slope = slope; + pvindev->data.vin_cal.cal_v10.intercept = intercept; + } + } + return status; + +} + +u32 clk_avfs_get_vin_cal_fuse_v20(struct gk20a *g, + struct avfsvinobjs *pvinobjs, + struct vin_device_v20 *pvindev) +{ + u32 status = 0; + s8 gain, offset; + u8 i; + + if (pvinobjs->calibration_rev_vbios == g->ops.fuse.read_vin_cal_fuse_rev(g)) { + BOARDOBJGRP_FOR_EACH(&(pvinobjs->super.super), + struct vin_device_v20 *, pvindev, i) { + gain = '\0'; + offset = '\0'; + pvindev = (struct vin_device_v20 *)CLK_GET_VIN_DEVICE(pvinobjs, i); + status = g->ops.fuse.read_vin_cal_gain_offset_fuse(g, + pvindev->super.id, &gain, &offset); + if (status) { + nvgpu_err(g, + "err reading vin cal for id %x", pvindev->super.id); + return status; + } + pvindev->data.vin_cal.cal_v20.gain = gain; + pvindev->data.vin_cal.cal_v20.offset = offset; + } + } + return status; + +} + +static int _clk_vin_devgrp_pmudatainit_super(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + struct nv_pmu_clk_clk_vin_device_boardobjgrp_set_header *pset = + (struct nv_pmu_clk_clk_vin_device_boardobjgrp_set_header *) + pboardobjgrppmu; + struct avfsvinobjs *pvin_obbj = (struct avfsvinobjs *)pboardobjgrp; + int status = 0; + + nvgpu_log_info(g, " "); + + status = boardobjgrp_pmudatainit_e32(g, pboardobjgrp, pboardobjgrppmu); + + pset->b_vin_is_disable_allowed = pvin_obbj->vin_is_disable_allowed; + + nvgpu_log_info(g, " Done"); + return status; +} + +static int _clk_vin_devgrp_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_clk_clk_vin_device_boardobj_grp_set *pgrp_set = + (struct nv_pmu_clk_clk_vin_device_boardobj_grp_set *) + pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + nvgpu_log_info(g, " Done"); + return 0; +} + +static int _clk_vin_devgrp_pmustatus_instget(struct gk20a *g, + void *pboardobjgrppmu, + struct nv_pmu_boardobj_query **ppboardobjpmustatus, + u8 idx) +{ + struct nv_pmu_clk_clk_vin_device_boardobj_grp_get_status *pgrp_get_status = + (struct nv_pmu_clk_clk_vin_device_boardobj_grp_get_status *) + pboardobjgrppmu; + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_get_status->hdr.data.super.obj_mask.super.data[0]) == 0) { + return -EINVAL; + } + + *ppboardobjpmustatus = (struct nv_pmu_boardobj_query *) + &pgrp_get_status->objects[idx].data.board_obj; + return 0; +} + +int clk_vin_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + struct vin_device_v20 *pvindev = NULL; + struct avfsvinobjs *pvinobjs; + + nvgpu_log_info(g, " "); + + status = boardobjgrpconstruct_e32(g, &g->clk_pmu.avfs_vinobjs.super); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for clk vin, statu - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->clk_pmu.avfs_vinobjs.super.super; + pvinobjs = &g->clk_pmu.avfs_vinobjs; + + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, CLK, VIN_DEVICE); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + clk, CLK, clk_vin_device, CLK_VIN_DEVICE); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + pboardobjgrp->pmudatainit = _clk_vin_devgrp_pmudatainit_super; + pboardobjgrp->pmudatainstget = _clk_vin_devgrp_pmudata_instget; + pboardobjgrp->pmustatusinstget = _clk_vin_devgrp_pmustatus_instget; + + status = devinit_get_vin_device_table(g, &g->clk_pmu.avfs_vinobjs); + if (status) { + goto done; + } + + /*update vin calibration to fuse */ + g->ops.pmu_ver.clk.clk_avfs_get_vin_cal_data(g, pvinobjs, pvindev); + + status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, + &g->clk_pmu.avfs_vinobjs.super.super, + clk, CLK, clk_vin_device, CLK_VIN_DEVICE); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int clk_vin_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + pboardobjgrp = &g->clk_pmu.avfs_vinobjs.super.super; + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + nvgpu_log_info(g, "Done"); + return status; +} + +static int devinit_get_vin_device_table(struct gk20a *g, + struct avfsvinobjs *pvinobjs) +{ + int status = 0; + u8 *vin_table_ptr = NULL; + struct vin_descriptor_header_10 vin_desc_table_header = { 0 }; + struct vin_descriptor_entry_10 vin_desc_table_entry = { 0 }; + u8 *vin_tbl_entry_ptr = NULL; + u32 index = 0; + u32 slope=0, intercept=0; + s8 offset='\0', gain='\0'; + struct vin_device *pvin_dev; + u32 cal_type; + + union { + struct boardobj boardobj; + struct vin_device vin_device; + struct vin_device_v10 vin_device_v10; + struct vin_device_v20 vin_device_v20; + } vin_device_data; + + nvgpu_log_info(g, " "); + + vin_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.clock_token, VIN_TABLE); + if (vin_table_ptr == NULL) { + status = -1; + goto done; + } + + memcpy(&vin_desc_table_header, vin_table_ptr, + sizeof(struct vin_descriptor_header_10)); + + pvinobjs->calibration_rev_vbios = + BIOS_GET_FIELD(vin_desc_table_header.flags0, + NV_VIN_DESC_FLAGS0_VIN_CAL_REVISION); + pvinobjs->vin_is_disable_allowed = + BIOS_GET_FIELD(vin_desc_table_header.flags0, + NV_VIN_DESC_FLAGS0_DISABLE_CONTROL); + cal_type = BIOS_GET_FIELD(vin_desc_table_header.flags0, + NV_VIN_DESC_FLAGS0_VIN_CAL_TYPE); + if (!cal_type) { + cal_type = CTRL_CLK_VIN_CAL_TYPE_V10; + } + + switch (cal_type) { + case CTRL_CLK_VIN_CAL_TYPE_V10: + /* VIN calibration slope: XX.YYY mV/code => XXYYY uV/code*/ + slope = ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal, + NV_VIN_DESC_VIN_CAL_SLOPE_INTEGER) * 1000)) + + ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal, + NV_VIN_DESC_VIN_CAL_SLOPE_FRACTION))); + + /* VIN calibration intercept: ZZZ.W mV => ZZZW00 uV */ + intercept = ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal, + NV_VIN_DESC_VIN_CAL_INTERCEPT_INTEGER) * 1000)) + + ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal, + NV_VIN_DESC_VIN_CAL_INTERCEPT_FRACTION) * 100)); + + break; + case CTRL_CLK_VIN_CAL_TYPE_V20: + offset = BIOS_GET_FIELD(vin_desc_table_header.vin_cal, + NV_VIN_DESC_VIN_CAL_OFFSET); + gain = BIOS_GET_FIELD(vin_desc_table_header.vin_cal, + NV_VIN_DESC_VIN_CAL_GAIN); + break; + default: + status = -1; + goto done; + } + /* Read table entries*/ + vin_tbl_entry_ptr = vin_table_ptr + vin_desc_table_header.header_sizee; + for (index = 0; index < vin_desc_table_header.entry_count; index++) { + memcpy(&vin_desc_table_entry, vin_tbl_entry_ptr, + sizeof(struct vin_descriptor_entry_10)); + + if (vin_desc_table_entry.vin_device_type == CTRL_CLK_VIN_TYPE_DISABLED) { + continue; + } + + vin_device_data.boardobj.type = + (u8)vin_desc_table_entry.vin_device_type; + vin_device_data.vin_device.id = (u8)vin_desc_table_entry.vin_device_id; + vin_device_data.vin_device.volt_domain_vbios = + (u8)vin_desc_table_entry.volt_domain_vbios; + vin_device_data.vin_device.flls_shared_mask = 0; + + switch (vin_device_data.boardobj.type) { + case CTRL_CLK_VIN_TYPE_V10: + vin_device_data.vin_device_v10.data.vin_cal.slope = slope; + vin_device_data.vin_device_v10.data.vin_cal.intercept = intercept; + break; + case CTRL_CLK_VIN_TYPE_V20: + vin_device_data.vin_device_v20.data.cal_type = (u8) cal_type; + vin_device_data.vin_device_v20.data.vin_cal.cal_v20.offset = offset; + vin_device_data.vin_device_v20.data.vin_cal.cal_v20.gain = gain; + break; + default: + status = -1; + goto done; + }; + + pvin_dev = construct_vin_device(g, (void *)&vin_device_data); + + status = boardobjgrp_objinsert(&pvinobjs->super.super, + (struct boardobj *)pvin_dev, index); + + vin_tbl_entry_ptr += vin_desc_table_header.entry_size; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +static int vin_device_construct_v10(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vin_device_v10 *pvin_device_v10; + struct vin_device_v10 *ptmpvin_device_v10 = (struct vin_device_v10 *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_VIN_TYPE_V10) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_CLK_VIN_TYPE_V10); + status = vin_device_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvin_device_v10 = (struct vin_device_v10 *)*ppboardobj; + + pvin_device_v10->super.super.pmudatainit = + vin_device_init_pmudata_v10; + + pvin_device_v10->data.vin_cal.slope = ptmpvin_device_v10->data.vin_cal.slope; + pvin_device_v10->data.vin_cal.intercept = ptmpvin_device_v10->data.vin_cal.intercept; + + return status; +} + +static int vin_device_construct_v20(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vin_device_v20 *pvin_device_v20; + struct vin_device_v20 *ptmpvin_device_v20 = (struct vin_device_v20 *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_VIN_TYPE_V20) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_CLK_VIN_TYPE_V20); + status = vin_device_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvin_device_v20 = (struct vin_device_v20 *)*ppboardobj; + + pvin_device_v20->super.super.pmudatainit = + vin_device_init_pmudata_v20; + + pvin_device_v20->data.cal_type = ptmpvin_device_v20->data.cal_type; + pvin_device_v20->data.vin_cal.cal_v20.offset = ptmpvin_device_v20->data.vin_cal.cal_v20.offset; + pvin_device_v20->data.vin_cal.cal_v20.gain = ptmpvin_device_v20->data.vin_cal.cal_v20.gain; + + return status; +} +static int vin_device_construct_super(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct vin_device *pvin_device; + struct vin_device *ptmpvin_device = (struct vin_device *)pargs; + int status = 0; + status = boardobj_construct_super(g, ppboardobj, size, pargs); + + if (status) { + return -EINVAL; + } + + pvin_device = (struct vin_device *)*ppboardobj; + + pvin_device->super.pmudatainit = + vin_device_init_pmudata_super; + + pvin_device->id = ptmpvin_device->id; + pvin_device->volt_domain_vbios = ptmpvin_device->volt_domain_vbios; + pvin_device->flls_shared_mask = ptmpvin_device->flls_shared_mask; + pvin_device->volt_domain = CTRL_VOLT_DOMAIN_LOGIC; + + return status; +} +static struct vin_device *construct_vin_device(struct gk20a *g, void *pargs) +{ + struct boardobj *board_obj_ptr = NULL; + int status; + + nvgpu_log_info(g, " %d", BOARDOBJ_GET_TYPE(pargs)); + switch (BOARDOBJ_GET_TYPE(pargs)) { + case CTRL_CLK_VIN_TYPE_V10: + status = vin_device_construct_v10(g, &board_obj_ptr, + sizeof(struct vin_device_v10), pargs); + break; + + case CTRL_CLK_VIN_TYPE_V20: + status = vin_device_construct_v20(g, &board_obj_ptr, + sizeof(struct vin_device_v20), pargs); + break; + + default: + return NULL; + }; + + if (status) { + return NULL; + } + + nvgpu_log_info(g, " Done"); + + return (struct vin_device *)board_obj_ptr; +} + + + +static int vin_device_init_pmudata_v10(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vin_device_v20 *pvin_dev_v20; + struct nv_pmu_clk_clk_vin_device_v10_boardobj_set *perf_pmu_data; + + nvgpu_log_info(g, " "); + + status = vin_device_init_pmudata_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvin_dev_v20 = (struct vin_device_v20 *)board_obj_ptr; + perf_pmu_data = (struct nv_pmu_clk_clk_vin_device_v10_boardobj_set *) + ppmudata; + + perf_pmu_data->data.vin_cal.intercept = pvin_dev_v20->data.vin_cal.cal_v10.intercept; + perf_pmu_data->data.vin_cal.slope = pvin_dev_v20->data.vin_cal.cal_v10.slope; + + nvgpu_log_info(g, " Done"); + + return status; +} + +static int vin_device_init_pmudata_v20(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vin_device_v20 *pvin_dev_v20; + struct nv_pmu_clk_clk_vin_device_v20_boardobj_set *perf_pmu_data; + + nvgpu_log_info(g, " "); + + status = vin_device_init_pmudata_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvin_dev_v20 = (struct vin_device_v20 *)board_obj_ptr; + perf_pmu_data = (struct nv_pmu_clk_clk_vin_device_v20_boardobj_set *) + ppmudata; + + perf_pmu_data->data.cal_type = pvin_dev_v20->data.cal_type; + perf_pmu_data->data.vin_cal.cal_v20.offset = pvin_dev_v20->data.vin_cal.cal_v20.offset; + perf_pmu_data->data.vin_cal.cal_v20.gain = pvin_dev_v20->data.vin_cal.cal_v20.gain; + + nvgpu_log_info(g, " Done"); + + return status; +} + +static int vin_device_init_pmudata_super(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vin_device *pvin_dev; + struct nv_pmu_clk_clk_vin_device_boardobj_set *perf_pmu_data; + + nvgpu_log_info(g, " "); + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvin_dev = (struct vin_device *)board_obj_ptr; + perf_pmu_data = (struct nv_pmu_clk_clk_vin_device_boardobj_set *) + ppmudata; + + perf_pmu_data->id = pvin_dev->id; + perf_pmu_data->volt_domain = pvin_dev->volt_domain; + perf_pmu_data->flls_shared_mask = pvin_dev->flls_shared_mask; + + nvgpu_log_info(g, " Done"); + + return status; +} diff --git a/include/clk/clk_vin.h b/include/clk/clk_vin.h new file mode 100644 index 0000000..73b93e4 --- /dev/null +++ b/include/clk/clk_vin.h @@ -0,0 +1,79 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_CLK_VIN_H +#define NVGPU_CLK_VIN_H + +#include "boardobj/boardobj.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" + +struct vin_device; +struct clk_pmupstate; + +struct avfsvinobjs { + struct boardobjgrp_e32 super; + u8 calibration_rev_vbios; + u8 calibration_rev_fused; + bool vin_is_disable_allowed; +}; +typedef u32 vin_device_state_load(struct gk20a *g, + struct clk_pmupstate *clk, struct vin_device *pdev); + +struct vin_device { + struct boardobj super; + u8 id; + u8 volt_domain; + u8 volt_domain_vbios; + u32 flls_shared_mask; + + vin_device_state_load *state_load; +}; + +struct vin_device_v10 { + struct vin_device super; + struct ctrl_clk_vin_device_info_data_v10 data; +}; + +struct vin_device_v20 { + struct vin_device super; + struct ctrl_clk_vin_device_info_data_v20 data; +}; + +/* get vin device object from descriptor table index*/ +#define CLK_GET_VIN_DEVICE(pvinobjs, dev_index) \ + ((struct vin_device *)BOARDOBJGRP_OBJ_GET_BY_IDX( \ + ((struct boardobjgrp *)&(pvinobjs->super.super)), (dev_index))) + +boardobj_construct construct_vindevice; +boardobj_pmudatainit vindeviceinit_pmudata_super; + +int clk_vin_sw_setup(struct gk20a *g); +int clk_vin_pmu_setup(struct gk20a *g); +u32 clk_avfs_get_vin_cal_fuse_v10(struct gk20a *g, + struct avfsvinobjs *pvinobjs, + struct vin_device_v20 *pvindev); +u32 clk_avfs_get_vin_cal_fuse_v20(struct gk20a *g, + struct avfsvinobjs *pvinobjs, + struct vin_device_v20 *pvindev); + +#endif /* NVGPU_CLK_VIN_H */ diff --git a/include/ctrl/ctrlboardobj.h b/include/ctrl/ctrlboardobj.h new file mode 100644 index 0000000..8f57e88 --- /dev/null +++ b/include/ctrl/ctrlboardobj.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_CTRLBOARDOBJ_H +#define NVGPU_CTRLBOARDOBJ_H + +struct ctrl_boardobj { + u8 type; +}; + +#define CTRL_BOARDOBJGRP_TYPE_INVALID 0x00U +#define CTRL_BOARDOBJGRP_TYPE_E32 0x01U +#define CTRL_BOARDOBJGRP_TYPE_E255 0x02U + +#define CTRL_BOARDOBJGRP_E32_MAX_OBJECTS 32U + +#define CTRL_BOARDOBJGRP_E255_MAX_OBJECTS 255U + +#define CTRL_BOARDOBJ_MAX_BOARD_OBJECTS \ + CTRL_BOARDOBJGRP_E32_MAX_OBJECTS + +#define CTRL_BOARDOBJ_IDX_INVALID 255U + +#define CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE 32U + +#define CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(_bit) \ + ((_bit) / CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE) + +#define CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(_bit) \ + ((_bit) % CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE) + +#define CTRL_BOARDOBJGRP_MASK_DATA_SIZE(_bits) \ + (CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX((_bits) - 1U) + 1U) + + +#define CTRL_BOARDOBJGRP_MASK_ARRAY_START_SIZE 1U +#define CTRL_BOARDOBJGRP_MASK_ARRAY_EXTENSION_SIZE(_bits) \ + (CTRL_BOARDOBJGRP_MASK_DATA_SIZE(_bits) - \ + CTRL_BOARDOBJGRP_MASK_ARRAY_START_SIZE) + +struct ctrl_boardobjgrp_mask { + u32 data[1]; +}; + +struct ctrl_boardobjgrp_mask_e32 { + struct ctrl_boardobjgrp_mask super; +}; + +struct ctrl_boardobjgrp_mask_e255 { + struct ctrl_boardobjgrp_mask super; + u32 data_e255[7]; +}; + +struct ctrl_boardobjgrp_super { + struct ctrl_boardobjgrp_mask obj_mask; +}; + +struct ctrl_boardobjgrp_e32 { + struct ctrl_boardobjgrp_mask_e32 obj_mask; +}; + +struct CTRL_boardobjgrp_e255 { + struct ctrl_boardobjgrp_mask_e255 obj_mask; +}; + +struct ctrl_boardobjgrp { + u32 obj_mask; +}; + +#endif /* NVGPU_CTRLBOARDOBJ_H */ diff --git a/include/ctrl/ctrlclk.h b/include/ctrl/ctrlclk.h new file mode 100644 index 0000000..fbd5677 --- /dev/null +++ b/include/ctrl/ctrlclk.h @@ -0,0 +1,212 @@ +/* + * general p state infrastructure + * + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_CTRLCLK_H +#define NVGPU_CTRLCLK_H + +#include "ctrlboardobj.h" +#include "ctrlclkavfs.h" +#include "ctrlvolt.h" + +#define CTRL_CLK_CLK_DELTA_MAX_VOLT_RAILS 4 + +/* valid clock domain values */ +#define CTRL_CLK_DOMAIN_MCLK (0x00000010) +#define CTRL_CLK_DOMAIN_HOSTCLK (0x00000020) +#define CTRL_CLK_DOMAIN_DISPCLK (0x00000040) +#define CTRL_CLK_DOMAIN_GPC2CLK (0x00010000) +#define CTRL_CLK_DOMAIN_XBAR2CLK (0x00040000) +#define CTRL_CLK_DOMAIN_SYS2CLK (0x00800000) +#define CTRL_CLK_DOMAIN_HUB2CLK (0x01000000) +#define CTRL_CLK_DOMAIN_PWRCLK (0x00080000) +#define CTRL_CLK_DOMAIN_NVDCLK (0x00100000) +#define CTRL_CLK_DOMAIN_PCIEGENCLK (0x00200000) + +#define CTRL_CLK_DOMAIN_GPCCLK (0x00000001) +#define CTRL_CLK_DOMAIN_XBARCLK (0x00000002) +#define CTRL_CLK_DOMAIN_SYSCLK (0x00000004) +#define CTRL_CLK_DOMAIN_HUBCLK (0x00000008) + +#define CTRL_CLK_CLK_DOMAIN_TYPE_3X 0x01 +#define CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED 0x02 +#define CTRL_CLK_CLK_DOMAIN_TYPE_3X_PROG 0x03 +#define CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER 0x04 +#define CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE 0x05 +#define CTRL_CLK_CLK_DOMAIN_TYPE_30_PROG 0x06 +#define CTRL_CLK_CLK_DOMAIN_TYPE_35_MASTER 0x07 +#define CTRL_CLK_CLK_DOMAIN_TYPE_35_SLAVE 0x08 +#define CTRL_CLK_CLK_DOMAIN_TYPE_35_PROG 0x09 + +#define CTRL_CLK_CLK_DOMAIN_3X_PROG_ORDERING_INDEX_INVALID 0xFF +#define CTRL_CLK_CLK_DOMAIN_INDEX_INVALID 0xFF + +#define CTRL_CLK_CLK_PROG_TYPE_1X 0x01 +#define CTRL_CLK_CLK_PROG_TYPE_1X_MASTER 0x02 +#define CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO 0x03 +#define CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_TABLE 0x04 +#define CTRL_CLK_CLK_PROG_TYPE_UNKNOWN 255 + +/*! + * Enumeration of CLK_PROG source types. + */ +#define CTRL_CLK_PROG_1X_SOURCE_PLL 0x00 +#define CTRL_CLK_PROG_1X_SOURCE_ONE_SOURCE 0x01 +#define CTRL_CLK_PROG_1X_SOURCE_FLL 0x02 +#define CTRL_CLK_PROG_1X_SOURCE_INVALID 255 + +#define CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES 4 +#define CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES 6 + +#define CTRL_CLK_CLK_VF_POINT_IDX_INVALID 255 + +#define CTRL_CLK_CLK_VF_POINT_TYPE_FREQ 0x01 +#define CTRL_CLK_CLK_VF_POINT_TYPE_VOLT 0x02 +#define CTRL_CLK_CLK_VF_POINT_TYPE_UNKNOWN 255 + +struct ctrl_clk_clk_prog_1x_master_source_fll { + u32 base_vfsmooth_volt_uv; + u32 max_vf_ramprate; + u32 max_freq_stepsize_mhz; +}; + +union ctrl_clk_clk_prog_1x_master_source_data { + struct ctrl_clk_clk_prog_1x_master_source_fll fll; +}; + +struct ctrl_clk_clk_vf_point_info_freq { + u16 freq_mhz; +}; + +struct ctrl_clk_clk_vf_point_info_volt { + u32 sourceVoltageuV; + u8 vfGainVfeEquIdx; + u8 clkDomainIdx; +}; + +struct ctrl_clk_clk_prog_1x_master_vf_entry { + u8 vfe_idx; + u8 gain_vfe_idx; + u8 vf_point_idx_first; + u8 vf_point_idx_last; +}; + +struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry { + u8 clk_dom_idx; + u8 ratio; +}; + +struct ctrl_clk_clk_prog_1x_master_table_slave_entry { + u8 clk_dom_idx; + u16 freq_mhz; +}; + +struct ctrl_clk_clk_prog_1x_source_pll { + u8 pll_idx; + u8 freq_step_size_mhz; +}; + +union ctrl_clk_freq_delta_data { + s32 delta_khz; + s16 delta_percent; +}; +struct ctrl_clk_freq_delta { + u8 type; + union ctrl_clk_freq_delta_data data; +}; + +struct ctrl_clk_clk_delta { + struct ctrl_clk_freq_delta freq_delta; + int volt_deltauv[CTRL_CLK_CLK_DELTA_MAX_VOLT_RAILS]; +}; + +struct ctrl_clk_vin_v10 { + u32 slope; + u32 intercept; +}; + +struct ctrl_clk_vin_v20 { + s8 offset; + s8 gain; +}; + +union ctrl_clk_vin_data_v20 { + struct ctrl_clk_vin_v10 cal_v10; + struct ctrl_clk_vin_v20 cal_v20; +}; + +struct ctrl_clk_vin_device_info_data_v10 { + struct ctrl_clk_vin_v10 vin_cal; +}; + +struct ctrl_clk_vin_device_info_data_v20 { + u8 cal_type; + union ctrl_clk_vin_data_v20 vin_cal; +}; + +union ctrl_clk_clk_prog_1x_source_data { + struct ctrl_clk_clk_prog_1x_source_pll pll; +}; + +struct ctrl_clk_vf_pair { + u16 freq_mhz; + u32 voltage_uv; +}; + +struct ctrl_clk_clk_domain_list_item { + u32 clk_domain; + u32 clk_freq_khz; + u32 clk_flags; + u8 current_regime_id; + u8 target_regime_id; +}; + +struct ctrl_clk_clk_domain_list_item_v1 { + u32 clk_domain; + u32 clk_freq_khz; + u8 regime_id; + u8 source; +}; + +struct ctrl_clk_clk_domain_list { + u8 num_domains; + struct ctrl_clk_clk_domain_list_item_v1 + clk_domains[CTRL_BOARDOBJ_MAX_BOARD_OBJECTS]; +}; + +#define CTRL_CLK_VF_PAIR_FREQ_MHZ_GET(pvfpair) \ + ((pvfpair)->freq_mhz) + +#define CTRL_CLK_VF_PAIR_VOLTAGE_UV_GET(pvfpair) \ + ((pvfpair)->voltage_uv) + +#define CTRL_CLK_VF_PAIR_FREQ_MHZ_SET(pvfpair, _freqmhz) \ + (((pvfpair)->freq_mhz) = (_freqmhz)) + +#define CTRL_CLK_VF_PAIR_FREQ_MHZ_SET(pvfpair, _freqmhz) \ + (((pvfpair)->freq_mhz) = (_freqmhz)) + + +#define CTRL_CLK_VF_PAIR_VOLTAGE_UV_SET(pvfpair, _voltageuv) \ + (((pvfpair)->voltage_uv) = (_voltageuv)) + +#endif /* NVGPU_CTRLCLK_H */ diff --git a/include/ctrl/ctrlclkavfs.h b/include/ctrl/ctrlclkavfs.h new file mode 100644 index 0000000..676ae7e --- /dev/null +++ b/include/ctrl/ctrlclkavfs.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_CTRLCLKAVFS_H +#define NVGPU_CTRLCLKAVFS_H + +#include "ctrlboardobj.h" +/*! + * Valid global VIN ID values + */ +#define CTRL_CLK_VIN_ID_SYS 0x00000000 +#define CTRL_CLK_VIN_ID_LTC 0x00000001 +#define CTRL_CLK_VIN_ID_XBAR 0x00000002 +#define CTRL_CLK_VIN_ID_GPC0 0x00000003 +#define CTRL_CLK_VIN_ID_GPC1 0x00000004 +#define CTRL_CLK_VIN_ID_GPC2 0x00000005 +#define CTRL_CLK_VIN_ID_GPC3 0x00000006 +#define CTRL_CLK_VIN_ID_GPC4 0x00000007 +#define CTRL_CLK_VIN_ID_GPC5 0x00000008 +#define CTRL_CLK_VIN_ID_GPCS 0x00000009 +#define CTRL_CLK_VIN_ID_SRAM 0x0000000A +#define CTRL_CLK_VIN_ID_UNDEFINED 0x000000FF + +#define CTRL_CLK_VIN_TYPE_DISABLED 0x00000000 +#define CTRL_CLK_VIN_TYPE_V10 0x00000001 +#define CTRL_CLK_VIN_TYPE_V20 0x00000002 + +/*! + * Various types of VIN calibration that the GPU can support + */ +#define CTRL_CLK_VIN_CAL_TYPE_V10 (0x00000000) +#define CTRL_CLK_VIN_CAL_TYPE_V20 (0x00000001) + +/*! + * Mask of all GPC VIN IDs supported by RM + */ +#define CTRL_CLK_VIN_MASK_UNICAST_GPC (BIT(CTRL_CLK_VIN_ID_GPC0) | \ + BIT(CTRL_CLK_VIN_ID_GPC1) | \ + BIT(CTRL_CLK_VIN_ID_GPC2) | \ + BIT(CTRL_CLK_VIN_ID_GPC3) | \ + BIT(CTRL_CLK_VIN_ID_GPC4) | \ + BIT(CTRL_CLK_VIN_ID_GPC5)) +#define CTRL_CLK_LUT_NUM_ENTRIES_MAX (128) +#define CTRL_CLK_LUT_NUM_ENTRIES_GV10x (128) +#define CTRL_CLK_LUT_NUM_ENTRIES_GP10x (100) +#define CTRL_CLK_VIN_STEP_SIZE_UV (10000) +#define CTRL_CLK_LUT_MIN_VOLTAGE_UV (450000) +#define CTRL_CLK_FLL_TYPE_DISABLED 0 + +#define CTRL_CLK_FLL_ID_SYS (0x00000000) +#define CTRL_CLK_FLL_ID_LTC (0x00000001) +#define CTRL_CLK_FLL_ID_XBAR (0x00000002) +#define CTRL_CLK_FLL_ID_GPC0 (0x00000003) +#define CTRL_CLK_FLL_ID_GPC1 (0x00000004) +#define CTRL_CLK_FLL_ID_GPC2 (0x00000005) +#define CTRL_CLK_FLL_ID_GPC3 (0x00000006) +#define CTRL_CLK_FLL_ID_GPC4 (0x00000007) +#define CTRL_CLK_FLL_ID_GPC5 (0x00000008) +#define CTRL_CLK_FLL_ID_GPCS (0x00000009) +#define CTRL_CLK_FLL_ID_UNDEFINED (0x000000FF) +#define CTRL_CLK_FLL_MASK_UNDEFINED (0x00000000) + +/*! + * Mask of all GPC FLL IDs supported by RM + */ +#define CTRL_CLK_FLL_MASK_UNICAST_GPC (BIT(CTRL_CLK_FLL_ID_GPC0) | \ + BIT(CTRL_CLK_FLL_ID_GPC1) | \ + BIT(CTRL_CLK_FLL_ID_GPC2) | \ + BIT(CTRL_CLK_FLL_ID_GPC3) | \ + BIT(CTRL_CLK_FLL_ID_GPC4) | \ + BIT(CTRL_CLK_FLL_ID_GPC5)) +/*! + * Mask of all FLL IDs supported by Nvgpu driver + */ +#define CTRL_CLK_FLL_ID_ALL_MASK (BIT(CTRL_CLK_FLL_ID_SYS) | \ + BIT(CTRL_CLK_FLL_ID_LTC) | \ + BIT(CTRL_CLK_FLL_ID_XBAR) | \ + BIT(CTRL_CLK_FLL_ID_GPC0) | \ + BIT(CTRL_CLK_FLL_ID_GPC1) | \ + BIT(CTRL_CLK_FLL_ID_GPC2) | \ + BIT(CTRL_CLK_FLL_ID_GPC3) | \ + BIT(CTRL_CLK_FLL_ID_GPC4) | \ + BIT(CTRL_CLK_FLL_ID_GPC5) | \ + BIT(CTRL_CLK_FLL_ID_GPCS)) + +#define CTRL_CLK_FLL_REGIME_ID_INVALID (0x00000000) +#define CTRL_CLK_FLL_REGIME_ID_FFR (0x00000001) +#define CTRL_CLK_FLL_REGIME_ID_FR (0x00000002) + +#define CTRL_CLK_FLL_LUT_VSELECT_LOGIC (0x00000000) +#define CTRL_CLK_FLL_LUT_VSELECT_MIN (0x00000001) +#define CTRL_CLK_FLL_LUT_VSELECT_SRAM (0x00000002) +#endif /* NVGPU_CTRLCLKAVFS_H */ diff --git a/include/ctrl/ctrlperf.h b/include/ctrl/ctrlperf.h new file mode 100644 index 0000000..2928cad --- /dev/null +++ b/include/ctrl/ctrlperf.h @@ -0,0 +1,103 @@ +/* + * general p state infrastructure + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_CTRLPERF_H +#define NVGPU_CTRLPERF_H + +struct ctrl_perf_volt_rail_list_item { + u8 volt_domain; + u32 voltage_uv; + u32 voltage_min_noise_unaware_uv; +}; + +struct ctrl_perf_volt_rail_list { + u8 num_rails; + struct ctrl_perf_volt_rail_list_item + rails[CTRL_VOLT_VOLT_RAIL_MAX_RAILS]; +}; + +union ctrl_perf_vfe_var_single_sensed_fuse_value_data { + int signed_value; + u32 unsigned_value; +}; + +struct ctrl_perf_vfe_var_single_sensed_fuse_value { + bool b_signed; + union ctrl_perf_vfe_var_single_sensed_fuse_value_data data; +}; + +struct ctrl_bios_vfield_register_segment_super { + u8 low_bit; + u8 high_bit; +}; + +struct ctrl_bios_vfield_register_segment_reg { + struct ctrl_bios_vfield_register_segment_super super; + u32 addr; +}; + +struct ctrl_bios_vfield_register_segment_index_reg { + struct ctrl_bios_vfield_register_segment_super super; + u32 addr; + u32 reg_index; + u32 index; +}; + +union ctrl_bios_vfield_register_segment_data { + struct ctrl_bios_vfield_register_segment_reg reg; + struct ctrl_bios_vfield_register_segment_index_reg index_reg; +}; + +struct ctrl_bios_vfield_register_segment { + u8 type; + union ctrl_bios_vfield_register_segment_data data; +}; + +#define NV_PMU_VFE_VAR_SINGLE_SENSED_FUSE_SEGMENTS_MAX 1 + +struct ctrl_perf_vfe_var_single_sensed_fuse_info { + u8 segment_count; + struct ctrl_bios_vfield_register_segment segments[NV_PMU_VFE_VAR_SINGLE_SENSED_FUSE_SEGMENTS_MAX]; +}; + +struct ctrl_perf_vfe_var_single_sensed_fuse_override_info { + u32 fuse_val_override; + u8 b_fuse_regkey_override; +}; + +struct ctrl_perf_vfe_var_single_sensed_fuse_vfield_info { + struct ctrl_perf_vfe_var_single_sensed_fuse_info fuse; + u32 fuse_val_default; + u32 hw_correction_scale; + int hw_correction_offset; + u8 v_field_id; +}; + +struct ctrl_perf_vfe_var_single_sensed_fuse_ver_vfield_info { + struct ctrl_perf_vfe_var_single_sensed_fuse_info fuse; + u8 ver_expected; + bool b_ver_check; + bool b_use_default_on_ver_check_fail; + u8 v_field_id_ver; +}; +#endif /* NVGPU_CTRLPERF_H */ diff --git a/include/ctrl/ctrlpmgr.h b/include/ctrl/ctrlpmgr.h new file mode 100644 index 0000000..90f6501 --- /dev/null +++ b/include/ctrl/ctrlpmgr.h @@ -0,0 +1,98 @@ +/* + * Control pmgr state infrastructure + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_CTRLPMGR_H +#define NVGPU_CTRLPMGR_H + +#include "ctrlboardobj.h" + +/* valid power domain values */ +#define CTRL_PMGR_PWR_DEVICES_MAX_DEVICES 32U +#define CTRL_PMGR_PWR_VIOLATION_MAX 0x06U + +#define CTRL_PMGR_PWR_DEVICE_TYPE_INA3221 0x4EU + +#define CTRL_PMGR_PWR_CHANNEL_INDEX_INVALID 0xFFU +#define CTRL_PMGR_PWR_CHANNEL_TYPE_SENSOR 0x08U + +#define CTRL_PMGR_PWR_POLICY_TABLE_VERSION_3X 0x30U +#define CTRL_PMGR_PWR_POLICY_TYPE_HW_THRESHOLD 0x04U +#define CTRL_PMGR_PWR_POLICY_TYPE_SW_THRESHOLD 0x0CU + +#define CTRL_PMGR_PWR_POLICY_MAX_LIMIT_INPUTS 0x8U +#define CTRL_PMGR_PWR_POLICY_IDX_NUM_INDEXES 0x08U +#define CTRL_PMGR_PWR_POLICY_INDEX_INVALID 0xFFU +#define CTRL_PMGR_PWR_POLICY_LIMIT_INPUT_CLIENT_IDX_RM 0xFEU +#define CTRL_PMGR_PWR_POLICY_LIMIT_MAX (0xFFFFFFFFU) + +struct ctrl_pmgr_pwr_device_info_rshunt { + bool use_fxp8_8; + u16 rshunt_value; +}; + +struct ctrl_pmgr_pwr_policy_info_integral { + u8 past_sample_count; + u8 next_sample_count; + u16 ratio_limit_min; + u16 ratio_limit_max; +}; + +enum ctrl_pmgr_pwr_policy_filter_type { + CTRL_PMGR_PWR_POLICY_FILTER_TYPE_NONE = 0, + CTRL_PMGR_PWR_POLICY_FILTER_TYPE_BLOCK, + CTRL_PMGR_PWR_POLICY_FILTER_TYPE_MOVING_AVERAGE, + CTRL_PMGR_PWR_POLICY_FILTER_TYPE_IIR +}; + +struct ctrl_pmgr_pwr_policy_filter_param_block { + u32 block_size; +}; + +struct ctrl_pmgr_pwr_policy_filter_param_moving_average { + u32 window_size; +}; + +struct ctrl_pmgr_pwr_policy_filter_param_iir { + u32 divisor; +}; + +union ctrl_pmgr_pwr_policy_filter_param { + struct ctrl_pmgr_pwr_policy_filter_param_block block; + struct ctrl_pmgr_pwr_policy_filter_param_moving_average moving_avg; + struct ctrl_pmgr_pwr_policy_filter_param_iir iir; +}; + +struct ctrl_pmgr_pwr_policy_limit_input { + u8 pwr_policy_idx; + u32 limit_value; +}; + +struct ctrl_pmgr_pwr_policy_limit_arbitration { + bool b_arb_max; + u8 num_inputs; + u32 output; + struct ctrl_pmgr_pwr_policy_limit_input + inputs[CTRL_PMGR_PWR_POLICY_MAX_LIMIT_INPUTS]; +}; + +#endif /* NVGPU_CTRLPMGR_H */ diff --git a/include/ctrl/ctrltherm.h b/include/ctrl/ctrltherm.h new file mode 100644 index 0000000..27af7b0 --- /dev/null +++ b/include/ctrl/ctrltherm.h @@ -0,0 +1,33 @@ +/* + * Control thermal infrastructure + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_CTRLTHERM_H +#define NVGPU_CTRLTHERM_H + +#include "ctrlboardobj.h" + +#define CTRL_THERMAL_THERM_DEVICE_CLASS_GPU 0x01 + +#define CTRL_THERMAL_THERM_CHANNEL_CLASS_DEVICE 0x01 + +#endif /* NVGPU_CTRLTHERM_H */ diff --git a/include/ctrl/ctrlvolt.h b/include/ctrl/ctrlvolt.h new file mode 100644 index 0000000..84994eb --- /dev/null +++ b/include/ctrl/ctrlvolt.h @@ -0,0 +1,143 @@ +/* + * general p state infrastructure + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_CTRLVOLT_H +#define NVGPU_CTRLVOLT_H + +#define CTRL_VOLT_VOLT_RAIL_MAX_RAILS \ + CTRL_BOARDOBJGRP_E32_MAX_OBJECTS + +#include "ctrlperf.h" +#include "ctrlboardobj.h" + +#define CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES 0x04U +#define CTRL_VOLT_VOLT_DEV_VID_VSEL_MAX_ENTRIES (8U) +#define CTRL_VOLT_DOMAIN_INVALID 0x00U +#define CTRL_VOLT_DOMAIN_LOGIC 0x01U +#define CLK_PROG_VFE_ENTRY_LOGIC 0x00U +#define CLK_PROG_VFE_ENTRY_SRAM 0x01U + +/* + * Macros for Voltage Domain HAL. + */ +#define CTRL_VOLT_DOMAIN_HAL_GP10X_SINGLE_RAIL 0x00U +#define CTRL_VOLT_DOMAIN_HAL_GP10X_SPLIT_RAIL 0x01U + +/* + * Macros for Voltage Domains. + */ +#define CTRL_VOLT_DOMAIN_INVALID 0x00U +#define CTRL_VOLT_DOMAIN_LOGIC 0x01U +#define CTRL_VOLT_DOMAIN_SRAM 0x02U + +/*! + * Special value corresponding to an invalid Voltage Rail Index. + */ +#define CTRL_VOLT_RAIL_INDEX_INVALID \ + CTRL_BOARDOBJ_IDX_INVALID + +/*! + * Special value corresponding to an invalid Voltage Device Index. + */ +#define CTRL_VOLT_DEVICE_INDEX_INVALID \ + CTRL_BOARDOBJ_IDX_INVALID + +/*! + * Special value corresponding to an invalid Voltage Policy Index. + */ +#define CTRL_VOLT_POLICY_INDEX_INVALID \ + CTRL_BOARDOBJ_IDX_INVALID + +enum nv_pmu_pmgr_pwm_source { + NV_PMU_PMGR_PWM_SOURCE_INVALID = 0, + NV_PMU_PMGR_PWM_SOURCE_THERM_VID_PWM_0 = 4, + NV_PMU_PMGR_PWM_SOURCE_THERM_VID_PWM_1, + NV_PMU_PMGR_PWM_SOURCE_RSVD_0 = 7, + NV_PMU_PMGR_PWM_SOURCE_RSVD_1 = 8, +}; + +/*! + * Macros for Voltage Device Types. + */ +#define CTRL_VOLT_DEVICE_TYPE_INVALID 0x00U +#define CTRL_VOLT_DEVICE_TYPE_PWM 0x03U + +/* + * Macros for Volt Device Operation types. + */ +#define CTRL_VOLT_DEVICE_OPERATION_TYPE_INVALID 0x00U +#define CTRL_VOLT_DEVICE_OPERATION_TYPE_DEFAULT 0x01U +#define CTRL_VOLT_DEVICE_OPERATION_TYPE_LPWR_STEADY_STATE 0x02U +#define CTRL_VOLT_DEVICE_OPERATION_TYPE_LPWR_SLEEP_STATE 0x03U +#define CTRL_VOLT_VOLT_DEVICE_OPERATION_TYPE_IPC_VMIN 0x04U + +/*! + * Macros for Voltage Domains. + */ +#define CTRL_VOLT_DOMAIN_INVALID 0x00U +#define CTRL_VOLT_DOMAIN_LOGIC 0x01U +#define CTRL_VOLT_DOMAIN_SRAM 0x02U + +/*! + * Macros for Volt Policy types. + * + * Virtual VOLT_POLICY types are indexed starting from 0xFF. + */ +#define CTRL_VOLT_POLICY_TYPE_INVALID 0x00U +#define CTRL_VOLT_POLICY_TYPE_SINGLE_RAIL 0x01U +#define CTRL_VOLT_POLICY_TYPE_SR_MULTI_STEP 0x02U +#define CTRL_VOLT_POLICY_TYPE_SR_SINGLE_STEP 0x03U +#define CTRL_VOLT_POLICY_TYPE_SINGLE_RAIL_MULTI_STEP 0x04U +#define CTRL_VOLT_POLICY_TYPE_SPLIT_RAIL 0xFEU +#define CTRL_VOLT_POLICY_TYPE_UNKNOWN 0xFFU + +/*! + * Macros for Volt Policy Client types. + */ +#define CTRL_VOLT_POLICY_CLIENT_INVALID 0x00U +#define CTRL_VOLT_POLICY_CLIENT_PERF_CORE_VF_SEQ 0x01U + +struct ctrl_volt_volt_rail_list_item { + u8 rail_idx; + u32 voltage_uv; +}; + +struct ctrl_volt_volt_rail_list { + u8 num_rails; + struct ctrl_volt_volt_rail_list_item + rails[CTRL_VOLT_VOLT_RAIL_MAX_RAILS]; +}; + +struct ctrl_volt_volt_rail_list_item_v1 { + u8 rail_idx; + u32 voltage_uv; + u32 voltage_min_noise_unaware_uv; +}; + +struct ctrl_volt_volt_rail_list_v1 { + u8 num_rails; + struct ctrl_volt_volt_rail_list_item_v1 + rails[CTRL_VOLT_VOLT_RAIL_MAX_RAILS]; +}; + +#endif /* NVGPU_CTRLVOLT_H */ diff --git a/include/gk20a/ce2_gk20a.c b/include/gk20a/ce2_gk20a.c new file mode 100644 index 0000000..2a40b08 --- /dev/null +++ b/include/gk20a/ce2_gk20a.c @@ -0,0 +1,576 @@ +/* + * GK20A Graphics Copy Engine (gr host) + * + * Copyright (c) 2011-2019, 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a.h" +#include "gk20a/fence_gk20a.h" + +#include +#include +#include +#include +#include +#include +#include + +/* + * Copy engine defines line size in pixels + */ +#define MAX_CE_SHIFT 31 /* 4Gpixels -1 */ +#define MAX_CE_MASK ((u32) (~(~0U << MAX_CE_SHIFT))) +#define MAX_CE_ALIGN(a) (a & MAX_CE_MASK) + + +static u32 ce2_nonblockpipe_isr(struct gk20a *g, u32 fifo_intr) +{ + nvgpu_log(g, gpu_dbg_intr, "ce2 non-blocking pipe interrupt\n"); + + return ce2_intr_status_nonblockpipe_pending_f(); +} + +static u32 ce2_blockpipe_isr(struct gk20a *g, u32 fifo_intr) +{ + nvgpu_log(g, gpu_dbg_intr, "ce2 blocking pipe interrupt\n"); + + return ce2_intr_status_blockpipe_pending_f(); +} + +static u32 ce2_launcherr_isr(struct gk20a *g, u32 fifo_intr) +{ + nvgpu_log(g, gpu_dbg_intr, "ce2 launch error interrupt\n"); + + return ce2_intr_status_launcherr_pending_f(); +} + +void gk20a_ce2_isr(struct gk20a *g, u32 inst_id, u32 pri_base) +{ + u32 ce2_intr = gk20a_readl(g, ce2_intr_status_r()); + u32 clear_intr = 0; + + nvgpu_log(g, gpu_dbg_intr, "ce2 isr %08x\n", ce2_intr); + + /* clear blocking interrupts: they exibit broken behavior */ + if (ce2_intr & ce2_intr_status_blockpipe_pending_f()) { + clear_intr |= ce2_blockpipe_isr(g, ce2_intr); + } + + if (ce2_intr & ce2_intr_status_launcherr_pending_f()) { + clear_intr |= ce2_launcherr_isr(g, ce2_intr); + } + + gk20a_writel(g, ce2_intr_status_r(), clear_intr); + return; +} + +u32 gk20a_ce2_nonstall_isr(struct gk20a *g, u32 inst_id, u32 pri_base) +{ + u32 ops = 0; + u32 ce2_intr = gk20a_readl(g, ce2_intr_status_r()); + + nvgpu_log(g, gpu_dbg_intr, "ce2 nonstall isr %08x\n", ce2_intr); + + if (ce2_intr & ce2_intr_status_nonblockpipe_pending_f()) { + gk20a_writel(g, ce2_intr_status_r(), + ce2_nonblockpipe_isr(g, ce2_intr)); + ops |= (GK20A_NONSTALL_OPS_WAKEUP_SEMAPHORE | + GK20A_NONSTALL_OPS_POST_EVENTS); + } + return ops; +} + +/* static CE app api */ +static void gk20a_ce_put_fences(struct gk20a_gpu_ctx *ce_ctx) +{ + u32 i; + + for (i = 0; i < NVGPU_CE_MAX_INFLIGHT_JOBS; i++) { + struct gk20a_fence **fence = &ce_ctx->postfences[i]; + if (*fence) { + gk20a_fence_put(*fence); + } + *fence = NULL; + } +} + +/* assume this api should need to call under nvgpu_mutex_acquire(&ce_app->app_mutex) */ +static void gk20a_ce_delete_gpu_context(struct gk20a_gpu_ctx *ce_ctx) +{ + struct nvgpu_list_node *list = &ce_ctx->list; + + ce_ctx->gpu_ctx_state = NVGPU_CE_GPU_CTX_DELETED; + + nvgpu_mutex_acquire(&ce_ctx->gpu_ctx_mutex); + + if (nvgpu_mem_is_valid(&ce_ctx->cmd_buf_mem)) { + gk20a_ce_put_fences(ce_ctx); + nvgpu_dma_unmap_free(ce_ctx->vm, &ce_ctx->cmd_buf_mem); + } + + /* + * free the channel + * gk20a_channel_close() will also unbind the channel from TSG + */ + gk20a_channel_close(ce_ctx->ch); + nvgpu_ref_put(&ce_ctx->tsg->refcount, gk20a_tsg_release); + + /* housekeeping on app */ + if (list->prev && list->next) { + nvgpu_list_del(list); + } + + nvgpu_mutex_release(&ce_ctx->gpu_ctx_mutex); + nvgpu_mutex_destroy(&ce_ctx->gpu_ctx_mutex); + + nvgpu_kfree(ce_ctx->g, ce_ctx); +} + +static inline unsigned int gk20a_ce_get_method_size(int request_operation, + u64 size) +{ + /* failure size */ + unsigned int methodsize = UINT_MAX; + unsigned int iterations = 0; + u32 shift; + u64 chunk = size; + u32 height, width; + + while (chunk) { + iterations++; + + shift = MAX_CE_ALIGN(chunk) ? __ffs(MAX_CE_ALIGN(chunk)) : + MAX_CE_SHIFT; + width = chunk >> shift; + height = 1 << shift; + width = MAX_CE_ALIGN(width); + + chunk -= (u64) height * width; + } + + if (request_operation & NVGPU_CE_PHYS_MODE_TRANSFER) { + methodsize = (2 + (16 * iterations)) * sizeof(u32); + } else if (request_operation & NVGPU_CE_MEMSET) { + methodsize = (2 + (15 * iterations)) * sizeof(u32); + } + + return methodsize; +} + +int gk20a_ce_prepare_submit(u64 src_buf, + u64 dst_buf, + u64 size, + u32 *cmd_buf_cpu_va, + u32 max_cmd_buf_size, + unsigned int payload, + int launch_flags, + int request_operation, + u32 dma_copy_class) +{ + u32 launch = 0; + u32 methodSize = 0; + u64 offset = 0; + u64 chunk_size = 0; + u64 chunk = size; + + /* failure case handling */ + if ((gk20a_ce_get_method_size(request_operation, size) > + max_cmd_buf_size) || (!size) || + (request_operation > NVGPU_CE_MEMSET)) { + return 0; + } + + /* set the channel object */ + cmd_buf_cpu_va[methodSize++] = 0x20018000; + cmd_buf_cpu_va[methodSize++] = dma_copy_class; + + /* + * The purpose clear the memory in 2D rectangles. We get the ffs to + * determine the number of lines to copy. The only constraint is that + * maximum number of pixels per line is 4Gpix - 1, which is awkward for + * calculation, so we settle to 2Gpix per line to make calculatione + * more agreable + */ + + /* The copy engine in 2D mode can have (2^32 - 1) x (2^32 - 1) pixels in + * a single submit, we are going to try to clear a range of up to 2Gpix + * multiple lines. Because we want to copy byte aligned we will be + * setting 1 byte pixels */ + + /* + * per iteration + * <------------------------- 40 bits ------------------------------> + * 1 <------ ffs -------> + * <-----------up to 30 bits-----------> + */ + while (chunk) { + u32 width, height, shift; + + /* + * We will be aligning to bytes, making the maximum number of + * pix per line 2Gb + */ + + shift = MAX_CE_ALIGN(chunk) ? __ffs(MAX_CE_ALIGN(chunk)) : + MAX_CE_SHIFT; + height = chunk >> shift; + width = 1 << shift; + height = MAX_CE_ALIGN(height); + + chunk_size = (u64) height * width; + + /* reset launch flag */ + launch = 0; + + if (request_operation & NVGPU_CE_PHYS_MODE_TRANSFER) { + /* setup the source */ + cmd_buf_cpu_va[methodSize++] = 0x20028100; + cmd_buf_cpu_va[methodSize++] = (u64_hi32(src_buf + + offset) & NVGPU_CE_UPPER_ADDRESS_OFFSET_MASK); + cmd_buf_cpu_va[methodSize++] = (u64_lo32(src_buf + + offset) & NVGPU_CE_LOWER_ADDRESS_OFFSET_MASK); + + cmd_buf_cpu_va[methodSize++] = 0x20018098; + if (launch_flags & NVGPU_CE_SRC_LOCATION_LOCAL_FB) { + cmd_buf_cpu_va[methodSize++] = 0x00000000; + } else if (launch_flags & + NVGPU_CE_SRC_LOCATION_NONCOHERENT_SYSMEM) { + cmd_buf_cpu_va[methodSize++] = 0x00000002; + } else { + cmd_buf_cpu_va[methodSize++] = 0x00000001; + } + + launch |= 0x00001000; + } else if (request_operation & NVGPU_CE_MEMSET) { + /* Remap from component A on 1 byte wide pixels */ + cmd_buf_cpu_va[methodSize++] = 0x200181c2; + cmd_buf_cpu_va[methodSize++] = 0x00000004; + + cmd_buf_cpu_va[methodSize++] = 0x200181c0; + cmd_buf_cpu_va[methodSize++] = payload; + + launch |= 0x00000400; + } else { + /* Illegal size */ + return 0; + } + + /* setup the destination/output */ + cmd_buf_cpu_va[methodSize++] = 0x20068102; + cmd_buf_cpu_va[methodSize++] = (u64_hi32(dst_buf + + offset) & NVGPU_CE_UPPER_ADDRESS_OFFSET_MASK); + cmd_buf_cpu_va[methodSize++] = (u64_lo32(dst_buf + + offset) & NVGPU_CE_LOWER_ADDRESS_OFFSET_MASK); + /* Pitch in/out */ + cmd_buf_cpu_va[methodSize++] = width; + cmd_buf_cpu_va[methodSize++] = width; + /* width and line count */ + cmd_buf_cpu_va[methodSize++] = width; + cmd_buf_cpu_va[methodSize++] = height; + + cmd_buf_cpu_va[methodSize++] = 0x20018099; + if (launch_flags & NVGPU_CE_DST_LOCATION_LOCAL_FB) { + cmd_buf_cpu_va[methodSize++] = 0x00000000; + } else if (launch_flags & + NVGPU_CE_DST_LOCATION_NONCOHERENT_SYSMEM) { + cmd_buf_cpu_va[methodSize++] = 0x00000002; + } else { + cmd_buf_cpu_va[methodSize++] = 0x00000001; + } + + launch |= 0x00002005; + + if (launch_flags & NVGPU_CE_SRC_MEMORY_LAYOUT_BLOCKLINEAR) { + launch |= 0x00000000; + } else { + launch |= 0x00000080; + } + + if (launch_flags & NVGPU_CE_DST_MEMORY_LAYOUT_BLOCKLINEAR) { + launch |= 0x00000000; + } else { + launch |= 0x00000100; + } + + cmd_buf_cpu_va[methodSize++] = 0x200180c0; + cmd_buf_cpu_va[methodSize++] = launch; + offset += chunk_size; + chunk -= chunk_size; + } + + return methodSize; +} + +/* global CE app related apis */ +int gk20a_init_ce_support(struct gk20a *g) +{ + struct gk20a_ce_app *ce_app = &g->ce_app; + int err; + u32 ce_reset_mask; + + ce_reset_mask = gk20a_fifo_get_all_ce_engine_reset_mask(g); + + g->ops.mc.reset(g, ce_reset_mask); + + nvgpu_cg_slcg_ce2_load_enable(g); + + nvgpu_cg_blcg_ce_load_enable(g); + + if (ce_app->initialised) { + /* assume this happen during poweron/poweroff GPU sequence */ + ce_app->app_state = NVGPU_CE_ACTIVE; + return 0; + } + + nvgpu_log(g, gpu_dbg_fn, "ce: init"); + + err = nvgpu_mutex_init(&ce_app->app_mutex); + if (err) { + return err; + } + + nvgpu_mutex_acquire(&ce_app->app_mutex); + + nvgpu_init_list_node(&ce_app->allocated_contexts); + ce_app->ctx_count = 0; + ce_app->next_ctx_id = 0; + ce_app->initialised = true; + ce_app->app_state = NVGPU_CE_ACTIVE; + + nvgpu_mutex_release(&ce_app->app_mutex); + + if (g->ops.ce2.init_prod_values != NULL) { + g->ops.ce2.init_prod_values(g); + } + + nvgpu_log(g, gpu_dbg_cde_ctx, "ce: init finished"); + + return 0; +} + +void gk20a_ce_destroy(struct gk20a *g) +{ + struct gk20a_ce_app *ce_app = &g->ce_app; + struct gk20a_gpu_ctx *ce_ctx, *ce_ctx_save; + + if (!ce_app->initialised) { + return; + } + + ce_app->app_state = NVGPU_CE_SUSPEND; + ce_app->initialised = false; + + nvgpu_mutex_acquire(&ce_app->app_mutex); + + nvgpu_list_for_each_entry_safe(ce_ctx, ce_ctx_save, + &ce_app->allocated_contexts, gk20a_gpu_ctx, list) { + gk20a_ce_delete_gpu_context(ce_ctx); + } + + nvgpu_init_list_node(&ce_app->allocated_contexts); + ce_app->ctx_count = 0; + ce_app->next_ctx_id = 0; + + nvgpu_mutex_release(&ce_app->app_mutex); + + nvgpu_mutex_destroy(&ce_app->app_mutex); +} + +void gk20a_ce_suspend(struct gk20a *g) +{ + struct gk20a_ce_app *ce_app = &g->ce_app; + + if (!ce_app->initialised) { + return; + } + + ce_app->app_state = NVGPU_CE_SUSPEND; + + return; +} + +/* CE app utility functions */ +u32 gk20a_ce_create_context(struct gk20a *g, + int runlist_id, + int timeslice, + int runlist_level) +{ + struct gk20a_gpu_ctx *ce_ctx; + struct gk20a_ce_app *ce_app = &g->ce_app; + struct nvgpu_setup_bind_args setup_bind_args; + u32 ctx_id = ~0; + int err = 0; + + if (!ce_app->initialised || ce_app->app_state != NVGPU_CE_ACTIVE) { + return ctx_id; + } + + ce_ctx = nvgpu_kzalloc(g, sizeof(*ce_ctx)); + if (!ce_ctx) { + return ctx_id; + } + + err = nvgpu_mutex_init(&ce_ctx->gpu_ctx_mutex); + if (err) { + nvgpu_kfree(g, ce_ctx); + return ctx_id; + } + + ce_ctx->g = g; + + ce_ctx->cmd_buf_read_queue_offset = 0; + + ce_ctx->vm = g->mm.ce.vm; + + /* allocate a tsg if needed */ + ce_ctx->tsg = gk20a_tsg_open(g, nvgpu_current_pid(g)); + if (!ce_ctx->tsg) { + nvgpu_err(g, "ce: gk20a tsg not available"); + err = -ENOMEM; + goto end; + } + + /* always kernel client needs privileged channel */ + ce_ctx->ch = gk20a_open_new_channel(g, runlist_id, true, + nvgpu_current_pid(g), nvgpu_current_tid(g)); + if (!ce_ctx->ch) { + nvgpu_err(g, "ce: gk20a channel not available"); + err = -ENOMEM; + goto end; + } + ce_ctx->ch->timeout.enabled = false; + + /* bind the channel to the vm */ + err = g->ops.mm.vm_bind_channel(g->mm.ce.vm, ce_ctx->ch); + if (err) { + nvgpu_err(g, "ce: could not bind vm"); + goto end; + } + + err = gk20a_tsg_bind_channel(ce_ctx->tsg, ce_ctx->ch); + if (err) { + nvgpu_err(g, "ce: unable to bind to tsg"); + goto end; + } + + setup_bind_args.num_gpfifo_entries = 1024; + setup_bind_args.num_inflight_jobs = 0; + setup_bind_args.flags = 0; + /* allocate gpfifo (1024 should be more than enough) */ + err = nvgpu_channel_setup_bind(ce_ctx->ch, &setup_bind_args); + if (err) { + nvgpu_err(g, "ce: unable to setup and bind channel"); + goto end; + } + + /* allocate command buffer from sysmem */ + err = nvgpu_dma_alloc_map_sys(ce_ctx->vm, + NVGPU_CE_MAX_INFLIGHT_JOBS * + NVGPU_CE_MAX_COMMAND_BUFF_BYTES_PER_KICKOFF, + &ce_ctx->cmd_buf_mem); + if (err) { + nvgpu_err(g, + "ce: could not allocate command buffer for CE context"); + goto end; + } + + memset(ce_ctx->cmd_buf_mem.cpu_va, 0x00, ce_ctx->cmd_buf_mem.size); + + /* -1 means default channel timeslice value */ + if (timeslice != -1) { + err = gk20a_fifo_tsg_set_timeslice(ce_ctx->tsg, timeslice); + if (err) { + nvgpu_err(g, + "ce: could not set the channel timeslice value for CE context"); + goto end; + } + } + + /* -1 means default channel runlist level */ + if (runlist_level != -1) { + err = gk20a_tsg_set_runlist_interleave(ce_ctx->tsg, + runlist_level); + if (err) { + nvgpu_err(g, + "ce: could not set the runlist interleave for CE context"); + goto end; + } + } + + nvgpu_mutex_acquire(&ce_app->app_mutex); + ctx_id = ce_ctx->ctx_id = ce_app->next_ctx_id; + nvgpu_list_add(&ce_ctx->list, &ce_app->allocated_contexts); + ++ce_app->next_ctx_id; + ++ce_app->ctx_count; + nvgpu_mutex_release(&ce_app->app_mutex); + + ce_ctx->gpu_ctx_state = NVGPU_CE_GPU_CTX_ALLOCATED; + +end: + if (ctx_id == (u32)~0) { + nvgpu_mutex_acquire(&ce_app->app_mutex); + gk20a_ce_delete_gpu_context(ce_ctx); + nvgpu_mutex_release(&ce_app->app_mutex); + } + return ctx_id; + +} + +void gk20a_ce_delete_context(struct gk20a *g, + u32 ce_ctx_id) +{ + gk20a_ce_delete_context_priv(g, ce_ctx_id); +} + +void gk20a_ce_delete_context_priv(struct gk20a *g, + u32 ce_ctx_id) +{ + struct gk20a_ce_app *ce_app = &g->ce_app; + struct gk20a_gpu_ctx *ce_ctx, *ce_ctx_save; + + if (!ce_app->initialised || ce_app->app_state != NVGPU_CE_ACTIVE) { + return; + } + + nvgpu_mutex_acquire(&ce_app->app_mutex); + + nvgpu_list_for_each_entry_safe(ce_ctx, ce_ctx_save, + &ce_app->allocated_contexts, gk20a_gpu_ctx, list) { + if (ce_ctx->ctx_id == ce_ctx_id) { + gk20a_ce_delete_gpu_context(ce_ctx); + --ce_app->ctx_count; + break; + } + } + + nvgpu_mutex_release(&ce_app->app_mutex); + return; +} diff --git a/include/gk20a/ce2_gk20a.h b/include/gk20a/ce2_gk20a.h new file mode 100644 index 0000000..df3a0e8 --- /dev/null +++ b/include/gk20a/ce2_gk20a.h @@ -0,0 +1,156 @@ +/* + * drivers/video/tegra/host/gk20a/fifo_gk20a.h + * + * GK20A graphics copy engine (gr host) + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_GK20A_CE2_GK20A_H +#define NVGPU_GK20A_CE2_GK20A_H + +struct channel_gk20a; +struct tsg_gk20a; + +void gk20a_ce2_isr(struct gk20a *g, u32 inst_id, u32 pri_base); +u32 gk20a_ce2_nonstall_isr(struct gk20a *g, u32 inst_id, u32 pri_base); + +/* CE command utility macros */ +#define NVGPU_CE_LOWER_ADDRESS_OFFSET_MASK 0xffffffff +#define NVGPU_CE_UPPER_ADDRESS_OFFSET_MASK 0xff + +#define NVGPU_CE_MAX_INFLIGHT_JOBS 32 +#define NVGPU_CE_MAX_COMMAND_BUFF_BYTES_PER_KICKOFF 256 + +/* dma launch_flags */ +enum { + /* location */ + NVGPU_CE_SRC_LOCATION_COHERENT_SYSMEM = (1 << 0), + NVGPU_CE_SRC_LOCATION_NONCOHERENT_SYSMEM = (1 << 1), + NVGPU_CE_SRC_LOCATION_LOCAL_FB = (1 << 2), + NVGPU_CE_DST_LOCATION_COHERENT_SYSMEM = (1 << 3), + NVGPU_CE_DST_LOCATION_NONCOHERENT_SYSMEM = (1 << 4), + NVGPU_CE_DST_LOCATION_LOCAL_FB = (1 << 5), + + /* memory layout */ + NVGPU_CE_SRC_MEMORY_LAYOUT_PITCH = (1 << 6), + NVGPU_CE_SRC_MEMORY_LAYOUT_BLOCKLINEAR = (1 << 7), + NVGPU_CE_DST_MEMORY_LAYOUT_PITCH = (1 << 8), + NVGPU_CE_DST_MEMORY_LAYOUT_BLOCKLINEAR = (1 << 9), + + /* transfer type */ + NVGPU_CE_DATA_TRANSFER_TYPE_PIPELINED = (1 << 10), + NVGPU_CE_DATA_TRANSFER_TYPE_NON_PIPELINED = (1 << 11), +}; + +/* CE operation mode */ +enum { + NVGPU_CE_PHYS_MODE_TRANSFER = (1 << 0), + NVGPU_CE_MEMSET = (1 << 1), +}; + +/* CE app state machine flags */ +enum { + NVGPU_CE_ACTIVE = (1 << 0), + NVGPU_CE_SUSPEND = (1 << 1), +}; + +/* gpu context state machine flags */ +enum { + NVGPU_CE_GPU_CTX_ALLOCATED = (1 << 0), + NVGPU_CE_GPU_CTX_DELETED = (1 << 1), +}; + +/* global ce app db */ +struct gk20a_ce_app { + bool initialised; + struct nvgpu_mutex app_mutex; + int app_state; + + struct nvgpu_list_node allocated_contexts; + u32 ctx_count; + u32 next_ctx_id; +}; + +/* ce context db */ +struct gk20a_gpu_ctx { + struct gk20a *g; + u32 ctx_id; + struct nvgpu_mutex gpu_ctx_mutex; + int gpu_ctx_state; + + /* tsg related data */ + struct tsg_gk20a *tsg; + + /* channel related data */ + struct channel_gk20a *ch; + struct vm_gk20a *vm; + + /* cmd buf mem_desc */ + struct nvgpu_mem cmd_buf_mem; + struct gk20a_fence *postfences[NVGPU_CE_MAX_INFLIGHT_JOBS]; + + struct nvgpu_list_node list; + + u32 cmd_buf_read_queue_offset; +}; + +static inline struct gk20a_gpu_ctx * +gk20a_gpu_ctx_from_list(struct nvgpu_list_node *node) +{ + return (struct gk20a_gpu_ctx *) + ((uintptr_t)node - offsetof(struct gk20a_gpu_ctx, list)); +}; + +/* global CE app related apis */ +int gk20a_init_ce_support(struct gk20a *g); +void gk20a_ce_suspend(struct gk20a *g); +void gk20a_ce_destroy(struct gk20a *g); + +/* CE app utility functions */ +u32 gk20a_ce_create_context(struct gk20a *g, + int runlist_id, + int timeslice, + int runlist_level); +int gk20a_ce_execute_ops(struct gk20a *g, + u32 ce_ctx_id, + u64 src_buf, + u64 dst_buf, + u64 size, + unsigned int payload, + int launch_flags, + int request_operation, + u32 submit_flags, + struct gk20a_fence **gk20a_fence_out); +void gk20a_ce_delete_context_priv(struct gk20a *g, + u32 ce_ctx_id); +void gk20a_ce_delete_context(struct gk20a *g, + u32 ce_ctx_id); +int gk20a_ce_prepare_submit(u64 src_buf, + u64 dst_buf, + u64 size, + u32 *cmd_buf_cpu_va, + u32 max_cmd_buf_size, + unsigned int payload, + int launch_flags, + int request_operation, + u32 dma_copy_class); + +#endif /*NVGPU_GK20A_CE2_GK20A_H*/ diff --git a/include/gk20a/clk_gk20a.h b/include/gk20a/clk_gk20a.h new file mode 100644 index 0000000..b8ec942 --- /dev/null +++ b/include/gk20a/clk_gk20a.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2011 - 2019, 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_GK20A_H +#define CLK_GK20A_H + +#include + +#if defined(CONFIG_COMMON_CLK) +#include +#endif + +#define GPUFREQ_TABLE_END ~(u32)1 +enum { + /* only one PLL for gk20a */ + GK20A_GPC_PLL = 0, + /* 2 PLL revisions for gm20b */ + GM20B_GPC_PLL_B1, + GM20B_GPC_PLL_C1, +}; + +enum gpc_pll_mode { + GPC_PLL_MODE_F = 0, /* fixed frequency mode a.k.a legacy mode */ + GPC_PLL_MODE_DVFS, /* DVFS mode a.k.a NA mode */ +}; + +struct na_dvfs { + u32 n_int; + u32 sdm_din; + int dfs_coeff; + int dfs_det_max; + int dfs_ext_cal; + int uv_cal; + int mv; +}; + +struct pll { + u32 id; + u32 clk_in; /* KHz */ + u32 M; + u32 N; + u32 PL; + u32 freq; /* KHz */ + bool enabled; + enum gpc_pll_mode mode; + struct na_dvfs dvfs; +}; + +struct pll_parms { + u32 min_freq, max_freq; /* KHz */ + u32 min_vco, max_vco; /* KHz */ + u32 min_u, max_u; /* KHz */ + u32 min_M, max_M; + u32 min_N, max_N; + u32 min_PL, max_PL; + /* NA mode parameters*/ + int coeff_slope, coeff_offs; /* coeff = slope * V + offs */ + int uvdet_slope, uvdet_offs; /* uV = slope * det + offs */ + u32 vco_ctrl; + /* + * Timing parameters in us. Lock timeout is applied to locking in fixed + * frequency mode and to dynamic ramp in any mode; does not affect lock + * latency, since lock/ramp done status bit is polled. NA mode lock and + * and IDDQ exit delays set the time of the respective opertaions with + * no status polling. + */ + u32 lock_timeout; + u32 na_lock_delay; + u32 iddq_exit_delay; + /* NA mode DFS control */ + u32 dfs_ctrl; +}; + +struct namemap_cfg; + +struct clk_gk20a { + struct gk20a *g; +#if defined(CONFIG_COMMON_CLK) + struct clk *tegra_clk; + struct clk *tegra_clk_parent; + struct clk_hw hw; +#endif + struct pll gpc_pll; + struct pll gpc_pll_last; + struct nvgpu_mutex clk_mutex; + struct namemap_cfg *clk_namemap; + u32 namemap_num; + u32 *namemap_xlat_table; + bool sw_ready; + bool clk_hw_on; + bool debugfs_set; + int pll_poweron_uv; + unsigned long dvfs_safe_max_freq; +}; + +#if defined(CONFIG_COMMON_CLK) +#define to_clk_gk20a(_hw) container_of(_hw, struct clk_gk20a, hw) +#endif + +struct gpu_ops; + +#define KHZ 1000 +#define MHZ 1000000 + +static inline unsigned long rate_gpc2clk_to_gpu(unsigned long rate) +{ + /* convert the kHz gpc2clk frequency to Hz gpcpll frequency */ + return (rate * KHZ) / 2; +} +static inline unsigned long rate_gpu_to_gpc2clk(unsigned long rate) +{ + /* convert the Hz gpcpll frequency to kHz gpc2clk frequency */ + return (rate * 2) / KHZ; +} + +#endif /* CLK_GK20A_H */ diff --git a/include/gk20a/css_gr_gk20a.c b/include/gk20a/css_gr_gk20a.c new file mode 100644 index 0000000..28a3d49 --- /dev/null +++ b/include/gk20a/css_gr_gk20a.c @@ -0,0 +1,636 @@ +/* + * GK20A Cycle stats snapshots support (subsystem for gr_gk20a). + * + * Copyright (c) 2015-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a.h" +#include "css_gr_gk20a.h" + +#include + +/* check client for pointed perfmon ownership */ +#define CONTAINS_PERFMON(cl, pm) \ + ((cl)->perfmon_start <= (pm) && \ + ((pm) - (cl)->perfmon_start) < (cl)->perfmon_count) + +/* address of fifo entry by offset */ +#define CSS_FIFO_ENTRY(fifo, offs) \ + ((struct gk20a_cs_snapshot_fifo_entry *)(((char *)(fifo)) + (offs))) + +/* calculate area capacity in number of fifo entries */ +#define CSS_FIFO_ENTRY_CAPACITY(s) \ + (((s) - sizeof(struct gk20a_cs_snapshot_fifo)) \ + / sizeof(struct gk20a_cs_snapshot_fifo_entry)) + +/* reserved to indicate failures with data */ +#define CSS_FIRST_PERFMON_ID 32 +/* should correlate with size of gk20a_cs_snapshot_fifo_entry::perfmon_id */ +#define CSS_MAX_PERFMON_IDS 256 + +/* reports whether the hw queue overflowed */ +bool css_hw_get_overflow_status(struct gk20a *g) +{ + const u32 st = perf_pmasys_control_membuf_status_overflowed_f(); + return st == (gk20a_readl(g, perf_pmasys_control_r()) & st); +} + +/* returns how many pending snapshot entries are pending */ +u32 css_hw_get_pending_snapshots(struct gk20a *g) +{ + return gk20a_readl(g, perf_pmasys_mem_bytes_r()) / + sizeof(struct gk20a_cs_snapshot_fifo_entry); +} + +/* informs hw how many snapshots have been processed (frees up fifo space) */ +void css_hw_set_handled_snapshots(struct gk20a *g, u32 done) +{ + if (done > 0) { + gk20a_writel(g, perf_pmasys_mem_bump_r(), + done * sizeof(struct gk20a_cs_snapshot_fifo_entry)); + } +} + +/* disable streaming to memory */ +static void css_hw_reset_streaming(struct gk20a *g) +{ + u32 engine_status; + + /* reset the perfmon */ + g->ops.mc.reset(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_PERFMON)); + + /* RBUFEMPTY must be set -- otherwise we'll pick up */ + /* snapshot that have been queued up from earlier */ + engine_status = gk20a_readl(g, perf_pmasys_enginestatus_r()); + WARN_ON(0 == (engine_status + & perf_pmasys_enginestatus_rbufempty_empty_f())); + + /* turn off writes */ + gk20a_writel(g, perf_pmasys_control_r(), + perf_pmasys_control_membuf_clear_status_doit_f()); + + /* pointing all pending snapshots as handled */ + css_hw_set_handled_snapshots(g, css_hw_get_pending_snapshots(g)); +} + +/* + * WARNING: all css_gr_XXX functions are local and expected to be called + * from locked context (protected by cs_lock) + */ + +static int css_gr_create_shared_data(struct gr_gk20a *gr) +{ + struct gk20a_cs_snapshot *data; + + if (gr->cs_data) + return 0; + + data = nvgpu_kzalloc(gr->g, sizeof(*data)); + if (!data) + return -ENOMEM; + + nvgpu_init_list_node(&data->clients); + gr->cs_data = data; + + return 0; +} + +int css_hw_enable_snapshot(struct channel_gk20a *ch, + struct gk20a_cs_snapshot_client *cs_client) +{ + struct gk20a *g = ch->g; + struct mm_gk20a *mm = &g->mm; + struct gr_gk20a *gr = &g->gr; + struct gk20a_cs_snapshot *data = gr->cs_data; + u32 snapshot_size = cs_client->snapshot_size; + int ret; + + u32 virt_addr_lo; + u32 virt_addr_hi; + u32 inst_pa_page; + + if (data->hw_snapshot) + return 0; + + if (snapshot_size < CSS_MIN_HW_SNAPSHOT_SIZE) + snapshot_size = CSS_MIN_HW_SNAPSHOT_SIZE; + + ret = nvgpu_dma_alloc_map_sys(g->mm.pmu.vm, snapshot_size, + &data->hw_memdesc); + if (ret) + return ret; + + /* perf output buffer may not cross a 4GB boundary - with a separate */ + /* va smaller than that, it won't but check anyway */ + if (!data->hw_memdesc.cpu_va || + data->hw_memdesc.size < snapshot_size || + data->hw_memdesc.gpu_va + u64_lo32(snapshot_size) > SZ_4G) { + ret = -EFAULT; + goto failed_allocation; + } + + data->hw_snapshot = + (struct gk20a_cs_snapshot_fifo_entry *)data->hw_memdesc.cpu_va; + data->hw_end = data->hw_snapshot + + snapshot_size / sizeof(struct gk20a_cs_snapshot_fifo_entry); + data->hw_get = data->hw_snapshot; + memset(data->hw_snapshot, 0xff, snapshot_size); + + /* address and size are aligned to 32 bytes, the lowest bits read back + * as zeros */ + virt_addr_lo = u64_lo32(data->hw_memdesc.gpu_va); + virt_addr_hi = u64_hi32(data->hw_memdesc.gpu_va); + + css_hw_reset_streaming(g); + + gk20a_writel(g, perf_pmasys_outbase_r(), virt_addr_lo); + gk20a_writel(g, perf_pmasys_outbaseupper_r(), + perf_pmasys_outbaseupper_ptr_f(virt_addr_hi)); + gk20a_writel(g, perf_pmasys_outsize_r(), snapshot_size); + + /* this field is aligned to 4K */ + inst_pa_page = nvgpu_inst_block_addr(g, &g->mm.hwpm.inst_block) >> 12; + + /* A write to MEM_BLOCK triggers the block bind operation. MEM_BLOCK + * should be written last */ + gk20a_writel(g, perf_pmasys_mem_block_r(), + perf_pmasys_mem_block_base_f(inst_pa_page) | + nvgpu_aperture_mask(g, &mm->hwpm.inst_block, + perf_pmasys_mem_block_target_sys_ncoh_f(), + perf_pmasys_mem_block_target_sys_coh_f(), + perf_pmasys_mem_block_target_lfb_f()) | + perf_pmasys_mem_block_valid_true_f()); + + nvgpu_log_info(g, "cyclestats: buffer for hardware snapshots enabled\n"); + + return 0; + +failed_allocation: + if (data->hw_memdesc.size) { + nvgpu_dma_unmap_free(g->mm.pmu.vm, &data->hw_memdesc); + memset(&data->hw_memdesc, 0, sizeof(data->hw_memdesc)); + } + data->hw_snapshot = NULL; + + return ret; +} + +void css_hw_disable_snapshot(struct gr_gk20a *gr) +{ + struct gk20a *g = gr->g; + struct gk20a_cs_snapshot *data = gr->cs_data; + + if (!data->hw_snapshot) + return; + + css_hw_reset_streaming(g); + + gk20a_writel(g, perf_pmasys_outbase_r(), 0); + gk20a_writel(g, perf_pmasys_outbaseupper_r(), + perf_pmasys_outbaseupper_ptr_f(0)); + gk20a_writel(g, perf_pmasys_outsize_r(), 0); + + gk20a_writel(g, perf_pmasys_mem_block_r(), + perf_pmasys_mem_block_base_f(0) | + perf_pmasys_mem_block_valid_false_f() | + perf_pmasys_mem_block_target_f(0)); + + nvgpu_dma_unmap_free(g->mm.pmu.vm, &data->hw_memdesc); + memset(&data->hw_memdesc, 0, sizeof(data->hw_memdesc)); + data->hw_snapshot = NULL; + + nvgpu_log_info(g, "cyclestats: buffer for hardware snapshots disabled\n"); +} + +static void css_gr_free_shared_data(struct gr_gk20a *gr) +{ + struct gk20a *g = gr->g; + + if (gr->cs_data) { + /* the clients list is expected to be empty */ + g->ops.css.disable_snapshot(gr); + + /* release the objects */ + nvgpu_kfree(gr->g, gr->cs_data); + gr->cs_data = NULL; + } +} + + +struct gk20a_cs_snapshot_client* +css_gr_search_client(struct nvgpu_list_node *clients, u32 perfmon) +{ + struct gk20a_cs_snapshot_client *client; + + nvgpu_list_for_each_entry(client, clients, + gk20a_cs_snapshot_client, list) { + if (CONTAINS_PERFMON(client, perfmon)) + return client; + } + + return NULL; +} + +static int css_gr_flush_snapshots(struct channel_gk20a *ch) +{ + struct gk20a *g = ch->g; + struct gr_gk20a *gr = &g->gr; + struct gk20a_cs_snapshot *css = gr->cs_data; + struct gk20a_cs_snapshot_client *cur; + u32 pending, completed; + bool hw_overflow; + int err; + + /* variables for iterating over HW entries */ + u32 sid; + struct gk20a_cs_snapshot_fifo_entry *src; + + /* due to data sharing with userspace we allowed update only */ + /* overflows and put field in the fifo header */ + struct gk20a_cs_snapshot_fifo *dst; + struct gk20a_cs_snapshot_fifo_entry *dst_get; + struct gk20a_cs_snapshot_fifo_entry *dst_put; + struct gk20a_cs_snapshot_fifo_entry *dst_nxt; + struct gk20a_cs_snapshot_fifo_entry *dst_head; + struct gk20a_cs_snapshot_fifo_entry *dst_tail; + + if (!css) + return -EINVAL; + + if (nvgpu_list_empty(&css->clients)) + return -EBADF; + + /* check data available */ + err = g->ops.css.check_data_available(ch, &pending, &hw_overflow); + if (err) + return err; + + if (!pending) + return 0; + + if (hw_overflow) { + nvgpu_list_for_each_entry(cur, &css->clients, + gk20a_cs_snapshot_client, list) { + cur->snapshot->hw_overflow_events_occured++; + } + + nvgpu_warn(g, "cyclestats: hardware overflow detected"); + } + + /* process all items in HW buffer */ + sid = 0; + completed = 0; + cur = NULL; + dst = NULL; + dst_put = NULL; + src = css->hw_get; + + /* proceed all completed records */ + while (sid < pending && 0 == src->zero0) { + /* we may have a new perfmon_id which required to */ + /* switch to a new client -> let's forget current */ + if (cur && !CONTAINS_PERFMON(cur, src->perfmon_id)) { + dst->put = (char *)dst_put - (char *)dst; + dst = NULL; + cur = NULL; + } + + /* now we have to select a new current client */ + /* the client selection rate depends from experiment */ + /* activity but on Android usually happened 1-2 times */ + if (!cur) { + cur = css_gr_search_client(&css->clients, + src->perfmon_id); + if (cur) { + /* found - setup all required data */ + dst = cur->snapshot; + dst_get = CSS_FIFO_ENTRY(dst, dst->get); + dst_put = CSS_FIFO_ENTRY(dst, dst->put); + dst_head = CSS_FIFO_ENTRY(dst, dst->start); + dst_tail = CSS_FIFO_ENTRY(dst, dst->end); + + dst_nxt = dst_put + 1; + if (dst_nxt == dst_tail) + dst_nxt = dst_head; + } else { + /* client not found - skipping this entry */ + nvgpu_warn(g, "cyclestats: orphaned perfmon %u", + src->perfmon_id); + goto next_hw_fifo_entry; + } + } + + /* check for software overflows */ + if (dst_nxt == dst_get) { + /* no data copy, no pointer updates */ + dst->sw_overflow_events_occured++; + nvgpu_warn(g, "cyclestats: perfmon %u soft overflow", + src->perfmon_id); + } else { + *dst_put = *src; + completed++; + + dst_put = dst_nxt++; + + if (dst_nxt == dst_tail) + dst_nxt = dst_head; + } + +next_hw_fifo_entry: + sid++; + if (++src >= css->hw_end) + src = css->hw_snapshot; + } + + /* update client put pointer if necessary */ + if (cur && dst) + dst->put = (char *)dst_put - (char *)dst; + + /* re-set HW buffer after processing taking wrapping into account */ + if (css->hw_get < src) { + memset(css->hw_get, 0xff, (src - css->hw_get) * sizeof(*src)); + } else { + memset(css->hw_snapshot, 0xff, + (src - css->hw_snapshot) * sizeof(*src)); + memset(css->hw_get, 0xff, + (css->hw_end - css->hw_get) * sizeof(*src)); + } + gr->cs_data->hw_get = src; + + if (g->ops.css.set_handled_snapshots) + g->ops.css.set_handled_snapshots(g, sid); + + if (completed != sid) { + /* not all entries proceed correctly. some of problems */ + /* reported as overflows, some as orphaned perfmons, */ + /* but it will be better notify with summary about it */ + nvgpu_warn(g, "cyclestats: completed %u from %u entries", + completed, pending); + } + + return 0; +} + +u32 css_gr_allocate_perfmon_ids(struct gk20a_cs_snapshot *data, + u32 count) +{ + unsigned long *pids = data->perfmon_ids; + unsigned int f; + + f = bitmap_find_next_zero_area(pids, CSS_MAX_PERFMON_IDS, + CSS_FIRST_PERFMON_ID, count, 0); + if (f > CSS_MAX_PERFMON_IDS) + f = 0; + else + bitmap_set(pids, f, count); + + return f; +} + +u32 css_gr_release_perfmon_ids(struct gk20a_cs_snapshot *data, + u32 start, + u32 count) +{ + unsigned long *pids = data->perfmon_ids; + u32 end = start + count; + u32 cnt = 0; + + if (start >= CSS_FIRST_PERFMON_ID && end <= CSS_MAX_PERFMON_IDS) { + bitmap_clear(pids, start, count); + cnt = count; + } + + return cnt; +} + + +static int css_gr_free_client_data(struct gk20a *g, + struct gk20a_cs_snapshot *data, + struct gk20a_cs_snapshot_client *client) +{ + int ret = 0; + + if (client->list.next && client->list.prev) + nvgpu_list_del(&client->list); + + if (client->perfmon_start && client->perfmon_count + && g->ops.css.release_perfmon_ids) { + if (client->perfmon_count != g->ops.css.release_perfmon_ids(data, + client->perfmon_start, client->perfmon_count)) + ret = -EINVAL; + } + + return ret; +} + +static int css_gr_create_client_data(struct gk20a *g, + struct gk20a_cs_snapshot *data, + u32 perfmon_count, + struct gk20a_cs_snapshot_client *cur) +{ + /* + * Special handling in-case of rm-server + * + * client snapshot buffer will not be mapped + * in-case of rm-server its only mapped in + * guest side + */ + if (cur->snapshot) { + memset(cur->snapshot, 0, sizeof(*cur->snapshot)); + cur->snapshot->start = sizeof(*cur->snapshot); + /* we should be ensure that can fit all fifo entries here */ + cur->snapshot->end = + CSS_FIFO_ENTRY_CAPACITY(cur->snapshot_size) + * sizeof(struct gk20a_cs_snapshot_fifo_entry) + + sizeof(struct gk20a_cs_snapshot_fifo); + cur->snapshot->get = cur->snapshot->start; + cur->snapshot->put = cur->snapshot->start; + } + + cur->perfmon_count = perfmon_count; + + /* In virtual case, perfmon ID allocation is handled by the server + * at the time of the attach (allocate_perfmon_ids is NULL in this case) + */ + if (cur->perfmon_count && g->ops.css.allocate_perfmon_ids) { + cur->perfmon_start = g->ops.css.allocate_perfmon_ids(data, + cur->perfmon_count); + if (!cur->perfmon_start) + return -ENOENT; + } + + nvgpu_list_add_tail(&cur->list, &data->clients); + + return 0; +} + + +int gr_gk20a_css_attach(struct channel_gk20a *ch, + u32 perfmon_count, + u32 *perfmon_start, + struct gk20a_cs_snapshot_client *cs_client) +{ + int ret = 0; + struct gk20a *g = ch->g; + struct gr_gk20a *gr; + + /* we must have a placeholder to store pointer to client structure */ + if (!cs_client) + return -EINVAL; + + if (!perfmon_count || + perfmon_count > CSS_MAX_PERFMON_IDS - CSS_FIRST_PERFMON_ID) + return -EINVAL; + + nvgpu_speculation_barrier(); + + gr = &g->gr; + + nvgpu_mutex_acquire(&gr->cs_lock); + + ret = css_gr_create_shared_data(gr); + if (ret) + goto failed; + + ret = css_gr_create_client_data(g, gr->cs_data, + perfmon_count, + cs_client); + if (ret) + goto failed; + + ret = g->ops.css.enable_snapshot(ch, cs_client); + if (ret) + goto failed; + + if (perfmon_start) + *perfmon_start = cs_client->perfmon_start; + + nvgpu_mutex_release(&gr->cs_lock); + + return 0; + +failed: + if (gr->cs_data) { + if (cs_client) { + css_gr_free_client_data(g, gr->cs_data, cs_client); + cs_client = NULL; + } + + if (nvgpu_list_empty(&gr->cs_data->clients)) + css_gr_free_shared_data(gr); + } + nvgpu_mutex_release(&gr->cs_lock); + + if (perfmon_start) + *perfmon_start = 0; + + return ret; +} + +int gr_gk20a_css_detach(struct channel_gk20a *ch, + struct gk20a_cs_snapshot_client *cs_client) +{ + int ret = 0; + struct gk20a *g = ch->g; + struct gr_gk20a *gr; + + if (!cs_client) + return -EINVAL; + + gr = &g->gr; + nvgpu_mutex_acquire(&gr->cs_lock); + if (gr->cs_data) { + struct gk20a_cs_snapshot *data = gr->cs_data; + + if (g->ops.css.detach_snapshot) + g->ops.css.detach_snapshot(ch, cs_client); + + ret = css_gr_free_client_data(g, data, cs_client); + if (nvgpu_list_empty(&data->clients)) + css_gr_free_shared_data(gr); + } else { + ret = -EBADF; + } + nvgpu_mutex_release(&gr->cs_lock); + + return ret; +} + +int gr_gk20a_css_flush(struct channel_gk20a *ch, + struct gk20a_cs_snapshot_client *cs_client) +{ + int ret = 0; + struct gk20a *g = ch->g; + struct gr_gk20a *gr; + + if (!cs_client) + return -EINVAL; + + gr = &g->gr; + nvgpu_mutex_acquire(&gr->cs_lock); + ret = css_gr_flush_snapshots(ch); + nvgpu_mutex_release(&gr->cs_lock); + + return ret; +} + +/* helper function with locking to cleanup snapshot code code in gr_gk20a.c */ +void gr_gk20a_free_cyclestats_snapshot_data(struct gk20a *g) +{ + struct gr_gk20a *gr = &g->gr; + + nvgpu_mutex_acquire(&gr->cs_lock); + css_gr_free_shared_data(gr); + nvgpu_mutex_release(&gr->cs_lock); + nvgpu_mutex_destroy(&gr->cs_lock); +} + +int css_hw_check_data_available(struct channel_gk20a *ch, u32 *pending, + bool *hw_overflow) +{ + struct gk20a *g = ch->g; + struct gr_gk20a *gr = &g->gr; + struct gk20a_cs_snapshot *css = gr->cs_data; + + if (!css->hw_snapshot) + return -EINVAL; + + *pending = css_hw_get_pending_snapshots(g); + if (!*pending) + return 0; + + *hw_overflow = css_hw_get_overflow_status(g); + return 0; +} diff --git a/include/gk20a/css_gr_gk20a.h b/include/gk20a/css_gr_gk20a.h new file mode 100644 index 0000000..bf8890b --- /dev/null +++ b/include/gk20a/css_gr_gk20a.h @@ -0,0 +1,151 @@ +/* + * GK20A Cycle stats snapshots support (subsystem for gr_gk20a). + * + * Copyright (c) 2016-2017, 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 CSS_GR_GK20A_H +#define CSS_GR_GK20A_H + +#include +#include + +/* the minimal size of HW buffer - should be enough to avoid HW overflows */ +#define CSS_MIN_HW_SNAPSHOT_SIZE (8 * 1024 * 1024) + +struct gk20a; +struct gr_gk20a; +struct channel_gk20a; + +/* cycle stats fifo header (must match NvSnapshotBufferFifo) */ +struct gk20a_cs_snapshot_fifo { + /* layout description of the buffer */ + u32 start; + u32 end; + + /* snafu bits */ + u32 hw_overflow_events_occured; + u32 sw_overflow_events_occured; + + /* the kernel copies new entries to put and + * increment the put++. if put == get then + * overflowEventsOccured++ + */ + u32 put; + u32 _reserved10; + u32 _reserved11; + u32 _reserved12; + + /* the driver/client reads from get until + * put==get, get++ */ + u32 get; + u32 _reserved20; + u32 _reserved21; + u32 _reserved22; + + /* unused */ + u32 _reserved30; + u32 _reserved31; + u32 _reserved32; + u32 _reserved33; +}; + +/* cycle stats fifo entry (must match NvSnapshotBufferFifoEntry) */ +struct gk20a_cs_snapshot_fifo_entry { + /* global 48 timestamp */ + u32 timestamp31_00:32; + u32 timestamp39_32:8; + + /* id of perfmon, should correlate with CSS_MAX_PERFMON_IDS */ + u32 perfmon_id:8; + + /* typically samples_counter is wired to #pmtrigger count */ + u32 samples_counter:12; + + /* DS=Delay Sample, SZ=Size (0=32B, 1=16B) */ + u32 ds:1; + u32 sz:1; + u32 zero0:1; + u32 zero1:1; + + /* counter results */ + u32 event_cnt:32; + u32 trigger0_cnt:32; + u32 trigger1_cnt:32; + u32 sample_cnt:32; + + /* Local PmTrigger results for Maxwell+ or padding otherwise */ + u16 local_trigger_b_count:16; + u16 book_mark_b:16; + u16 local_trigger_a_count:16; + u16 book_mark_a:16; +}; + +/* cycle stats snapshot client data (e.g. associated with channel) */ +struct gk20a_cs_snapshot_client { + struct nvgpu_list_node list; + struct gk20a_cs_snapshot_fifo *snapshot; + u32 snapshot_size; + u32 perfmon_start; + u32 perfmon_count; +}; + +static inline struct gk20a_cs_snapshot_client * +gk20a_cs_snapshot_client_from_list(struct nvgpu_list_node *node) +{ + return (struct gk20a_cs_snapshot_client *) + ((uintptr_t)node - offsetof(struct gk20a_cs_snapshot_client, list)); +}; + +/* should correlate with size of gk20a_cs_snapshot_fifo_entry::perfmon_id */ +#define CSS_MAX_PERFMON_IDS 256 + +/* local definitions to avoid hardcodes sizes and shifts */ +#define PM_BITMAP_SIZE DIV_ROUND_UP(CSS_MAX_PERFMON_IDS, BITS_PER_LONG) + +/* cycle stats snapshot control structure for one HW entry and many clients */ +struct gk20a_cs_snapshot { + unsigned long perfmon_ids[PM_BITMAP_SIZE]; + struct nvgpu_list_node clients; + struct nvgpu_mem hw_memdesc; + /* pointer to allocated cpu_va memory where GPU place data */ + struct gk20a_cs_snapshot_fifo_entry *hw_snapshot; + struct gk20a_cs_snapshot_fifo_entry *hw_end; + struct gk20a_cs_snapshot_fifo_entry *hw_get; +}; + +bool css_hw_get_overflow_status(struct gk20a *g); +u32 css_hw_get_pending_snapshots(struct gk20a *g); +void css_hw_set_handled_snapshots(struct gk20a *g, u32 done); +int css_hw_enable_snapshot(struct channel_gk20a *ch, + struct gk20a_cs_snapshot_client *cs_client); +void css_hw_disable_snapshot(struct gr_gk20a *gr); +u32 css_gr_allocate_perfmon_ids(struct gk20a_cs_snapshot *data, + u32 count); +u32 css_gr_release_perfmon_ids(struct gk20a_cs_snapshot *data, + u32 start, + u32 count); +int css_hw_check_data_available(struct channel_gk20a *ch, u32 *pending, + bool *hw_overflow); +struct gk20a_cs_snapshot_client* +css_gr_search_client(struct nvgpu_list_node *clients, u32 perfmon); + +#endif /* CSS_GR_GK20A_H */ diff --git a/include/gk20a/dbg_gpu_gk20a.c b/include/gk20a/dbg_gpu_gk20a.c new file mode 100644 index 0000000..1686d01 --- /dev/null +++ b/include/gk20a/dbg_gpu_gk20a.c @@ -0,0 +1,388 @@ +/* + * Tegra GK20A GPU Debugger/Profiler Driver + * + * Copyright (c) 2013-2019, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a.h" +#include "gr_gk20a.h" +#include "dbg_gpu_gk20a.h" +#include "regops_gk20a.h" + +#include +#include + +static void gk20a_perfbuf_reset_streaming(struct gk20a *g) +{ + u32 engine_status; + u32 num_unread_bytes; + + g->ops.mc.reset(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_PERFMON)); + + engine_status = gk20a_readl(g, perf_pmasys_enginestatus_r()); + WARN_ON(0u == + (engine_status & perf_pmasys_enginestatus_rbufempty_empty_f())); + + gk20a_writel(g, perf_pmasys_control_r(), + perf_pmasys_control_membuf_clear_status_doit_f()); + + num_unread_bytes = gk20a_readl(g, perf_pmasys_mem_bytes_r()); + if (num_unread_bytes != 0u) { + gk20a_writel(g, perf_pmasys_mem_bump_r(), num_unread_bytes); + } +} + +/* + * API to get first channel from the list of all channels + * bound to the debug session + */ +struct channel_gk20a * +nvgpu_dbg_gpu_get_session_channel(struct dbg_session_gk20a *dbg_s) +{ + struct dbg_session_channel_data *ch_data; + struct channel_gk20a *ch; + struct gk20a *g = dbg_s->g; + + nvgpu_mutex_acquire(&dbg_s->ch_list_lock); + if (nvgpu_list_empty(&dbg_s->ch_list)) { + nvgpu_mutex_release(&dbg_s->ch_list_lock); + return NULL; + } + + ch_data = nvgpu_list_first_entry(&dbg_s->ch_list, + dbg_session_channel_data, + ch_entry); + ch = g->fifo.channel + ch_data->chid; + + nvgpu_mutex_release(&dbg_s->ch_list_lock); + + return ch; +} + +void gk20a_dbg_gpu_post_events(struct channel_gk20a *ch) +{ + struct dbg_session_data *session_data; + struct dbg_session_gk20a *dbg_s; + struct gk20a *g = ch->g; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + /* guard against the session list being modified */ + nvgpu_mutex_acquire(&ch->dbg_s_lock); + + nvgpu_list_for_each_entry(session_data, &ch->dbg_s_list, + dbg_session_data, dbg_s_entry) { + dbg_s = session_data->dbg_s; + if (dbg_s->dbg_events.events_enabled) { + nvgpu_log(g, gpu_dbg_gpu_dbg, "posting event on session id %d", + dbg_s->id); + nvgpu_log(g, gpu_dbg_gpu_dbg, "%d events pending", + dbg_s->dbg_events.num_pending_events); + + dbg_s->dbg_events.num_pending_events++; + + nvgpu_dbg_session_post_event(dbg_s); + } + } + + nvgpu_mutex_release(&ch->dbg_s_lock); +} + +bool gk20a_dbg_gpu_broadcast_stop_trigger(struct channel_gk20a *ch) +{ + struct dbg_session_data *session_data; + struct dbg_session_gk20a *dbg_s; + bool broadcast = false; + struct gk20a *g = ch->g; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr, " "); + + /* guard against the session list being modified */ + nvgpu_mutex_acquire(&ch->dbg_s_lock); + + nvgpu_list_for_each_entry(session_data, &ch->dbg_s_list, + dbg_session_data, dbg_s_entry) { + dbg_s = session_data->dbg_s; + if (dbg_s->broadcast_stop_trigger) { + nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn | gpu_dbg_intr, + "stop trigger broadcast enabled"); + broadcast = true; + break; + } + } + + nvgpu_mutex_release(&ch->dbg_s_lock); + + return broadcast; +} + +int gk20a_dbg_gpu_clear_broadcast_stop_trigger(struct channel_gk20a *ch) +{ + struct dbg_session_data *session_data; + struct dbg_session_gk20a *dbg_s; + struct gk20a *g = ch->g; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr, " "); + + /* guard against the session list being modified */ + nvgpu_mutex_acquire(&ch->dbg_s_lock); + + nvgpu_list_for_each_entry(session_data, &ch->dbg_s_list, + dbg_session_data, dbg_s_entry) { + dbg_s = session_data->dbg_s; + if (dbg_s->broadcast_stop_trigger) { + nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn | gpu_dbg_intr, + "stop trigger broadcast disabled"); + dbg_s->broadcast_stop_trigger = false; + } + } + + nvgpu_mutex_release(&ch->dbg_s_lock); + + return 0; +} + +u32 nvgpu_set_powergate_locked(struct dbg_session_gk20a *dbg_s, + bool mode) +{ + u32 err = 0U; + struct gk20a *g = dbg_s->g; + + if (dbg_s->is_pg_disabled != mode) { + if (mode == false) { + g->dbg_powergating_disabled_refcount--; + } + + /* + * Allow powergate disable or enable only if + * the global pg disabled refcount is zero + */ + if (g->dbg_powergating_disabled_refcount == 0) { + err = g->ops.dbg_session_ops.dbg_set_powergate(dbg_s, + mode); + } + + if (mode) { + g->dbg_powergating_disabled_refcount++; + } + + dbg_s->is_pg_disabled = mode; + } + + return err; +} + +int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate) +{ + int err = 0; + struct gk20a *g = dbg_s->g; + + /* This function must be called with g->dbg_sessions_lock held */ + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %s", + g->name, disable_powergate ? "disable" : "enable"); + + /* + * Powergate mode here refers to railgate+powergate+clockgate + * so in case slcg/blcg/elcg are disabled and railgating is enabled, + * disable railgating and then set is_pg_disabled = true + * Similarly re-enable railgating and not other features if they are not + * enabled when powermode=MODE_ENABLE + */ + if (disable_powergate) { + /* save off current powergate, clk state. + * set gpu module's can_powergate = 0. + * set gpu module's clk to max. + * while *a* debug session is active there will be no power or + * clocking state changes allowed from mainline code (but they + * should be saved). + */ + + nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, + "module busy"); + err = gk20a_busy(g); + if (err) { + return err; + } + + err = nvgpu_cg_pg_disable(g); + + if (err == 0) { + dbg_s->is_pg_disabled = true; + nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, + "pg disabled"); + } + } else { + /* restore (can) powergate, clk state */ + /* release pending exceptions to fault/be handled as usual */ + /*TBD: ordering of these? */ + + err = nvgpu_cg_pg_enable(g); + + nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, "module idle"); + gk20a_idle(g); + + if (err == 0) { + dbg_s->is_pg_disabled = false; + nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, + "pg enabled"); + } + } + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %s done", + g->name, disable_powergate ? "disable" : "enable"); + return err; +} + +bool nvgpu_check_and_set_global_reservation( + struct dbg_session_gk20a *dbg_s, + struct dbg_profiler_object_data *prof_obj) +{ + struct gk20a *g = dbg_s->g; + + if (g->profiler_reservation_count == 0) { + g->global_profiler_reservation_held = true; + g->profiler_reservation_count = 1; + dbg_s->has_profiler_reservation = true; + prof_obj->has_reservation = true; + return true; + } + return false; +} + +bool nvgpu_check_and_set_context_reservation( + struct dbg_session_gk20a *dbg_s, + struct dbg_profiler_object_data *prof_obj) +{ + struct gk20a *g = dbg_s->g; + + /* Assumes that we've already checked that no global reservation + * is in effect. + */ + g->profiler_reservation_count++; + dbg_s->has_profiler_reservation = true; + prof_obj->has_reservation = true; + return true; +} + +void nvgpu_release_profiler_reservation(struct dbg_session_gk20a *dbg_s, + struct dbg_profiler_object_data *prof_obj) +{ + struct gk20a *g = dbg_s->g; + + g->profiler_reservation_count--; + if (g->profiler_reservation_count < 0) { + nvgpu_err(g, "Negative reservation count!"); + } + dbg_s->has_profiler_reservation = false; + prof_obj->has_reservation = false; + if (prof_obj->ch == NULL) { + g->global_profiler_reservation_held = false; + } +} + +int gk20a_perfbuf_enable_locked(struct gk20a *g, u64 offset, u32 size) +{ + struct mm_gk20a *mm = &g->mm; + u32 virt_addr_lo; + u32 virt_addr_hi; + u32 inst_pa_page; + int err; + + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to poweron"); + return err; + } + + err = g->ops.mm.alloc_inst_block(g, &mm->perfbuf.inst_block); + if (err) { + return err; + } + + g->ops.mm.init_inst_block(&mm->perfbuf.inst_block, mm->perfbuf.vm, 0); + + gk20a_perfbuf_reset_streaming(g); + + virt_addr_lo = u64_lo32(offset); + virt_addr_hi = u64_hi32(offset); + + /* address and size are aligned to 32 bytes, the lowest bits read back + * as zeros */ + gk20a_writel(g, perf_pmasys_outbase_r(), virt_addr_lo); + gk20a_writel(g, perf_pmasys_outbaseupper_r(), + perf_pmasys_outbaseupper_ptr_f(virt_addr_hi)); + gk20a_writel(g, perf_pmasys_outsize_r(), size); + + /* this field is aligned to 4K */ + inst_pa_page = nvgpu_inst_block_addr(g, &mm->perfbuf.inst_block) >> 12; + + /* A write to MEM_BLOCK triggers the block bind operation. MEM_BLOCK + * should be written last */ + gk20a_writel(g, perf_pmasys_mem_block_r(), + perf_pmasys_mem_block_base_f(inst_pa_page) | + nvgpu_aperture_mask(g, &mm->perfbuf.inst_block, + perf_pmasys_mem_block_target_sys_ncoh_f(), + perf_pmasys_mem_block_target_sys_coh_f(), + perf_pmasys_mem_block_target_lfb_f()) | + perf_pmasys_mem_block_valid_true_f()); + + gk20a_idle(g); + return 0; +} + +/* must be called with dbg_sessions_lock held */ +int gk20a_perfbuf_disable_locked(struct gk20a *g) +{ + int err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to poweron"); + return err; + } + + gk20a_perfbuf_reset_streaming(g); + + gk20a_writel(g, perf_pmasys_outbase_r(), 0); + gk20a_writel(g, perf_pmasys_outbaseupper_r(), + perf_pmasys_outbaseupper_ptr_f(0)); + gk20a_writel(g, perf_pmasys_outsize_r(), 0); + + gk20a_writel(g, perf_pmasys_mem_block_r(), + perf_pmasys_mem_block_base_f(0) | + perf_pmasys_mem_block_valid_false_f() | + perf_pmasys_mem_block_target_f(0)); + + gk20a_idle(g); + + return 0; +} diff --git a/include/gk20a/dbg_gpu_gk20a.h b/include/gk20a/dbg_gpu_gk20a.h new file mode 100644 index 0000000..fb5ae1f --- /dev/null +++ b/include/gk20a/dbg_gpu_gk20a.h @@ -0,0 +1,147 @@ +/* + * Tegra GK20A GPU Debugger Driver + * + * Copyright (c) 2013-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef DBG_GPU_H +#define DBG_GPU_H + +#include +#include +#include + +struct gk20a; +struct channel_gk20a; +struct dbg_session_gk20a; + +/* used by the interrupt handler to post events */ +void gk20a_dbg_gpu_post_events(struct channel_gk20a *fault_ch); + +struct channel_gk20a * +nvgpu_dbg_gpu_get_session_channel(struct dbg_session_gk20a *dbg_s); + +struct dbg_gpu_session_events { + struct nvgpu_cond wait_queue; + bool events_enabled; + int num_pending_events; +}; + +struct dbg_session_gk20a { + /* dbg session id used for trace/prints */ + int id; + + /* profiler session, if any */ + bool is_profiler; + + /* has a valid profiler reservation */ + bool has_profiler_reservation; + + /* power enabled or disabled */ + bool is_pg_disabled; + + /* timeouts enabled or disabled */ + bool is_timeout_disabled; + + struct gk20a *g; + + /* list of bound channels, if any */ + struct nvgpu_list_node ch_list; + struct nvgpu_mutex ch_list_lock; + + /* event support */ + struct dbg_gpu_session_events dbg_events; + + bool broadcast_stop_trigger; + + struct nvgpu_mutex ioctl_lock; +}; + +struct dbg_session_data { + struct dbg_session_gk20a *dbg_s; + struct nvgpu_list_node dbg_s_entry; +}; + +static inline struct dbg_session_data * +dbg_session_data_from_dbg_s_entry(struct nvgpu_list_node *node) +{ + return (struct dbg_session_data *) + ((uintptr_t)node - offsetof(struct dbg_session_data, dbg_s_entry)); +}; + +struct dbg_session_channel_data { + int channel_fd; + u32 chid; + struct nvgpu_list_node ch_entry; + struct dbg_session_data *session_data; + int (*unbind_single_channel)(struct dbg_session_gk20a *dbg_s, + struct dbg_session_channel_data *ch_data); +}; + +static inline struct dbg_session_channel_data * +dbg_session_channel_data_from_ch_entry(struct nvgpu_list_node *node) +{ + return (struct dbg_session_channel_data *) + ((uintptr_t)node - offsetof(struct dbg_session_channel_data, ch_entry)); +}; + +struct dbg_profiler_object_data { + int session_id; + u32 prof_handle; + struct channel_gk20a *ch; + bool has_reservation; + struct nvgpu_list_node prof_obj_entry; +}; + +static inline struct dbg_profiler_object_data * +dbg_profiler_object_data_from_prof_obj_entry(struct nvgpu_list_node *node) +{ + return (struct dbg_profiler_object_data *) + ((uintptr_t)node - offsetof(struct dbg_profiler_object_data, prof_obj_entry)); +}; + +bool gk20a_dbg_gpu_broadcast_stop_trigger(struct channel_gk20a *ch); +int gk20a_dbg_gpu_clear_broadcast_stop_trigger(struct channel_gk20a *ch); + +int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate); +bool nvgpu_check_and_set_global_reservation( + struct dbg_session_gk20a *dbg_s, + struct dbg_profiler_object_data *prof_obj); +bool nvgpu_check_and_set_context_reservation( + struct dbg_session_gk20a *dbg_s, + struct dbg_profiler_object_data *prof_obj); +void nvgpu_release_profiler_reservation(struct dbg_session_gk20a *dbg_s, + struct dbg_profiler_object_data *prof_obj); +int gk20a_perfbuf_enable_locked(struct gk20a *g, u64 offset, u32 size); +int gk20a_perfbuf_disable_locked(struct gk20a *g); + +void nvgpu_dbg_session_post_event(struct dbg_session_gk20a *dbg_s); +u32 nvgpu_set_powergate_locked(struct dbg_session_gk20a *dbg_s, + bool mode); + + /* PM Context Switch Mode */ +/*This mode says that the pms are not to be context switched. */ +#define NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW (0x00000000) +/* This mode says that the pms in Mode-B are to be context switched */ +#define NVGPU_DBG_HWPM_CTXSW_MODE_CTXSW (0x00000001) +/* This mode says that the pms in Mode-E (stream out) are to be context switched. */ +#define NVGPU_DBG_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW (0x00000002) + +#endif /* DBG_GPU_GK20A_H */ diff --git a/include/gk20a/fecs_trace_gk20a.c b/include/gk20a/fecs_trace_gk20a.c new file mode 100644 index 0000000..5c1c5e0 --- /dev/null +++ b/include/gk20a/fecs_trace_gk20a.c @@ -0,0 +1,744 @@ +/* + * Copyright (c) 2016-2019, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fecs_trace_gk20a.h" +#include "gk20a.h" +#include "gr_gk20a.h" + +#include +#include + +#include +#include + +struct gk20a_fecs_trace_hash_ent { + u32 context_ptr; + pid_t pid; + struct hlist_node node; +}; + +struct gk20a_fecs_trace { + + DECLARE_HASHTABLE(pid_hash_table, GK20A_FECS_TRACE_HASH_BITS); + struct nvgpu_mutex hash_lock; + struct nvgpu_mutex poll_lock; + struct nvgpu_thread poll_task; + bool init; + struct nvgpu_mutex enable_lock; + u32 enable_count; +}; + +#ifdef CONFIG_GK20A_CTXSW_TRACE +u32 gk20a_fecs_trace_record_ts_tag_invalid_ts_v(void) +{ + return ctxsw_prog_record_timestamp_timestamp_hi_tag_invalid_timestamp_v(); +} + +u32 gk20a_fecs_trace_record_ts_tag_v(u64 ts) +{ + return ctxsw_prog_record_timestamp_timestamp_hi_tag_v((u32) (ts >> 32)); +} + +u64 gk20a_fecs_trace_record_ts_timestamp_v(u64 ts) +{ + return ts & ~(((u64)ctxsw_prog_record_timestamp_timestamp_hi_tag_m()) << 32); +} + +static u32 gk20a_fecs_trace_fecs_context_ptr(struct gk20a *g, struct channel_gk20a *ch) +{ + return (u32) (nvgpu_inst_block_addr(g, &ch->inst_block) >> 12LL); +} + +int gk20a_fecs_trace_num_ts(void) +{ + return (ctxsw_prog_record_timestamp_record_size_in_bytes_v() + - sizeof(struct gk20a_fecs_trace_record)) / sizeof(u64); +} + +struct gk20a_fecs_trace_record *gk20a_fecs_trace_get_record( + struct gk20a *g, int idx) +{ + struct nvgpu_mem *mem = &g->gr.global_ctx_buffer[FECS_TRACE_BUFFER].mem; + + return (struct gk20a_fecs_trace_record *) + ((u8 *) mem->cpu_va + + (idx * ctxsw_prog_record_timestamp_record_size_in_bytes_v())); +} + +bool gk20a_fecs_trace_is_valid_record(struct gk20a_fecs_trace_record *r) +{ + /* + * testing magic_hi should suffice. magic_lo is sometimes used + * as a sequence number in experimental ucode. + */ + return (r->magic_hi + == ctxsw_prog_record_timestamp_magic_value_hi_v_value_v()); +} + +int gk20a_fecs_trace_get_read_index(struct gk20a *g) +{ + return gr_gk20a_elpg_protected_call(g, + gk20a_readl(g, gr_fecs_mailbox1_r())); +} + +int gk20a_fecs_trace_get_write_index(struct gk20a *g) +{ + return gr_gk20a_elpg_protected_call(g, + gk20a_readl(g, gr_fecs_mailbox0_r())); +} + +static int gk20a_fecs_trace_set_read_index(struct gk20a *g, int index) +{ + nvgpu_log(g, gpu_dbg_ctxsw, "set read=%d", index); + return gr_gk20a_elpg_protected_call(g, + (gk20a_writel(g, gr_fecs_mailbox1_r(), index), 0)); +} + +void gk20a_fecs_trace_hash_dump(struct gk20a *g) +{ + u32 bkt; + struct gk20a_fecs_trace_hash_ent *ent; + struct gk20a_fecs_trace *trace = g->fecs_trace; + + nvgpu_log(g, gpu_dbg_ctxsw, "dumping hash table"); + + nvgpu_mutex_acquire(&trace->hash_lock); + hash_for_each(trace->pid_hash_table, bkt, ent, node) + { + nvgpu_log(g, gpu_dbg_ctxsw, " ent=%p bkt=%x context_ptr=%x pid=%d", + ent, bkt, ent->context_ptr, ent->pid); + + } + nvgpu_mutex_release(&trace->hash_lock); +} + +static int gk20a_fecs_trace_hash_add(struct gk20a *g, u32 context_ptr, pid_t pid) +{ + struct gk20a_fecs_trace_hash_ent *he; + struct gk20a_fecs_trace *trace = g->fecs_trace; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_ctxsw, + "adding hash entry context_ptr=%x -> pid=%d", context_ptr, pid); + + he = nvgpu_kzalloc(g, sizeof(*he)); + if (unlikely(!he)) { + nvgpu_warn(g, + "can't alloc new hash entry for context_ptr=%x pid=%d", + context_ptr, pid); + return -ENOMEM; + } + + he->context_ptr = context_ptr; + he->pid = pid; + nvgpu_mutex_acquire(&trace->hash_lock); + hash_add(trace->pid_hash_table, &he->node, context_ptr); + nvgpu_mutex_release(&trace->hash_lock); + return 0; +} + +static void gk20a_fecs_trace_hash_del(struct gk20a *g, u32 context_ptr) +{ + struct hlist_node *tmp; + struct gk20a_fecs_trace_hash_ent *ent; + struct gk20a_fecs_trace *trace = g->fecs_trace; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_ctxsw, + "freeing hash entry context_ptr=%x", context_ptr); + + nvgpu_mutex_acquire(&trace->hash_lock); + hash_for_each_possible_safe(trace->pid_hash_table, ent, tmp, node, + context_ptr) { + if (ent->context_ptr == context_ptr) { + hash_del(&ent->node); + nvgpu_log(g, gpu_dbg_ctxsw, + "freed hash entry=%p context_ptr=%x", ent, + ent->context_ptr); + nvgpu_kfree(g, ent); + break; + } + } + nvgpu_mutex_release(&trace->hash_lock); +} + +static void gk20a_fecs_trace_free_hash_table(struct gk20a *g) +{ + u32 bkt; + struct hlist_node *tmp; + struct gk20a_fecs_trace_hash_ent *ent; + struct gk20a_fecs_trace *trace = g->fecs_trace; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_ctxsw, "trace=%p", trace); + + nvgpu_mutex_acquire(&trace->hash_lock); + hash_for_each_safe(trace->pid_hash_table, bkt, tmp, ent, node) { + hash_del(&ent->node); + nvgpu_kfree(g, ent); + } + nvgpu_mutex_release(&trace->hash_lock); + +} + +static pid_t gk20a_fecs_trace_find_pid(struct gk20a *g, u32 context_ptr) +{ + struct gk20a_fecs_trace_hash_ent *ent; + struct gk20a_fecs_trace *trace = g->fecs_trace; + pid_t pid = 0; + + nvgpu_mutex_acquire(&trace->hash_lock); + hash_for_each_possible(trace->pid_hash_table, ent, node, context_ptr) { + if (ent->context_ptr == context_ptr) { + nvgpu_log(g, gpu_dbg_ctxsw, + "found context_ptr=%x -> pid=%d", + ent->context_ptr, ent->pid); + pid = ent->pid; + break; + } + } + nvgpu_mutex_release(&trace->hash_lock); + + return pid; +} + +/* + * Converts HW entry format to userspace-facing format and pushes it to the + * queue. + */ +static int gk20a_fecs_trace_ring_read(struct gk20a *g, int index) +{ + int i; + struct nvgpu_gpu_ctxsw_trace_entry entry = { }; + struct gk20a_fecs_trace *trace = g->fecs_trace; + pid_t cur_pid; + pid_t new_pid; + int count = 0; + + /* for now, only one VM */ + const int vmid = 0; + + struct gk20a_fecs_trace_record *r = + gk20a_fecs_trace_get_record(g, index); + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_ctxsw, + "consuming record trace=%p read=%d record=%p", trace, index, r); + + if (unlikely(!gk20a_fecs_trace_is_valid_record(r))) { + nvgpu_warn(g, + "trace=%p read=%d record=%p magic_lo=%08x magic_hi=%08x (invalid)", + trace, index, r, r->magic_lo, r->magic_hi); + return -EINVAL; + } + + /* Clear magic_hi to detect cases where CPU could read write index + * before FECS record is actually written to DRAM. This should not + * as we force FECS writes to SYSMEM by reading through PRAMIN. + */ + r->magic_hi = 0; + + cur_pid = gk20a_fecs_trace_find_pid(g, r->context_ptr); + new_pid = gk20a_fecs_trace_find_pid(g, r->new_context_ptr); + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_ctxsw, + "context_ptr=%x (pid=%d) new_context_ptr=%x (pid=%d)", + r->context_ptr, cur_pid, r->new_context_ptr, new_pid); + + entry.context_id = r->context_id; + entry.vmid = vmid; + + /* break out FECS record into trace events */ + for (i = 0; i < gk20a_fecs_trace_num_ts(); i++) { + + entry.tag = gk20a_fecs_trace_record_ts_tag_v(r->ts[i]); + entry.timestamp = gk20a_fecs_trace_record_ts_timestamp_v(r->ts[i]); + entry.timestamp <<= GK20A_FECS_TRACE_PTIMER_SHIFT; + + nvgpu_log(g, gpu_dbg_ctxsw, + "tag=%x timestamp=%llx context_id=%08x new_context_id=%08x", + entry.tag, entry.timestamp, r->context_id, + r->new_context_id); + + switch (nvgpu_gpu_ctxsw_tags_to_common_tags(entry.tag)) { + case NVGPU_GPU_CTXSW_TAG_RESTORE_START: + case NVGPU_GPU_CTXSW_TAG_CONTEXT_START: + entry.context_id = r->new_context_id; + entry.pid = new_pid; + break; + + case NVGPU_GPU_CTXSW_TAG_CTXSW_REQ_BY_HOST: + case NVGPU_GPU_CTXSW_TAG_FE_ACK: + case NVGPU_GPU_CTXSW_TAG_FE_ACK_WFI: + case NVGPU_GPU_CTXSW_TAG_FE_ACK_GFXP: + case NVGPU_GPU_CTXSW_TAG_FE_ACK_CTAP: + case NVGPU_GPU_CTXSW_TAG_FE_ACK_CILP: + case NVGPU_GPU_CTXSW_TAG_SAVE_END: + entry.context_id = r->context_id; + entry.pid = cur_pid; + break; + + default: + /* tags are not guaranteed to start at the beginning */ + WARN_ON(entry.tag && (entry.tag != NVGPU_GPU_CTXSW_TAG_INVALID_TIMESTAMP)); + continue; + } + + nvgpu_log(g, gpu_dbg_ctxsw, "tag=%x context_id=%x pid=%lld", + entry.tag, entry.context_id, entry.pid); + + if (!entry.context_id) + continue; + + gk20a_ctxsw_trace_write(g, &entry); + count++; + } + + gk20a_ctxsw_trace_wake_up(g, vmid); + return count; +} + +int gk20a_fecs_trace_poll(struct gk20a *g) +{ + struct gk20a_fecs_trace *trace = g->fecs_trace; + + int read = 0; + int write = 0; + int cnt; + int err; + + err = gk20a_busy(g); + if (unlikely(err)) + return err; + + nvgpu_mutex_acquire(&trace->poll_lock); + write = gk20a_fecs_trace_get_write_index(g); + if (unlikely((write < 0) || (write >= GK20A_FECS_TRACE_NUM_RECORDS))) { + nvgpu_err(g, + "failed to acquire write index, write=%d", write); + err = write; + goto done; + } + + read = gk20a_fecs_trace_get_read_index(g); + + cnt = CIRC_CNT(write, read, GK20A_FECS_TRACE_NUM_RECORDS); + if (!cnt) + goto done; + + nvgpu_log(g, gpu_dbg_ctxsw, + "circular buffer: read=%d (mailbox=%d) write=%d cnt=%d", + read, gk20a_fecs_trace_get_read_index(g), write, cnt); + + /* Ensure all FECS writes have made it to SYSMEM */ + g->ops.mm.fb_flush(g); + + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* Bits 30:0 of MAILBOX1 represents actual read pointer value */ + read = read & (~(BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT))); + } + + while (read != write) { + cnt = gk20a_fecs_trace_ring_read(g, read); + if (cnt > 0) { + nvgpu_log(g, gpu_dbg_ctxsw, + "number of trace entries added: %d", cnt); + } + + /* Get to next record. */ + read = (read + 1) & (GK20A_FECS_TRACE_NUM_RECORDS - 1); + } + + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* + * In the next step, read pointer is going to be updated. + * So, MSB of read pointer should be set back to 1. This will + * keep FECS trace enabled. + */ + read = read | (BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT)); + } + + /* ensure FECS records has been updated before incrementing read index */ + nvgpu_wmb(); + gk20a_fecs_trace_set_read_index(g, read); + +done: + nvgpu_mutex_release(&trace->poll_lock); + gk20a_idle(g); + return err; +} + +static int gk20a_fecs_trace_periodic_polling(void *arg) +{ + struct gk20a *g = (struct gk20a *)arg; + struct gk20a_fecs_trace *trace = g->fecs_trace; + + pr_info("%s: running\n", __func__); + + while (!nvgpu_thread_should_stop(&trace->poll_task)) { + + nvgpu_usleep_range(GK20A_FECS_TRACE_FRAME_PERIOD_US, + GK20A_FECS_TRACE_FRAME_PERIOD_US * 2); + + gk20a_fecs_trace_poll(g); + } + + return 0; +} + +size_t gk20a_fecs_trace_buffer_size(struct gk20a *g) +{ + return GK20A_FECS_TRACE_NUM_RECORDS + * ctxsw_prog_record_timestamp_record_size_in_bytes_v(); +} + +int gk20a_fecs_trace_init(struct gk20a *g) +{ + struct gk20a_fecs_trace *trace; + int err; + + trace = nvgpu_kzalloc(g, sizeof(struct gk20a_fecs_trace)); + if (!trace) { + nvgpu_warn(g, "failed to allocate fecs_trace"); + return -ENOMEM; + } + g->fecs_trace = trace; + + err = nvgpu_mutex_init(&trace->poll_lock); + if (err) + goto clean; + err = nvgpu_mutex_init(&trace->hash_lock); + if (err) + goto clean_poll_lock; + + err = nvgpu_mutex_init(&trace->enable_lock); + if (err) + goto clean_hash_lock; + + BUG_ON(!is_power_of_2(GK20A_FECS_TRACE_NUM_RECORDS)); + hash_init(trace->pid_hash_table); + + __nvgpu_set_enabled(g, NVGPU_SUPPORT_FECS_CTXSW_TRACE, true); + + trace->enable_count = 0; + trace->init = true; + + return 0; + +clean_hash_lock: + nvgpu_mutex_destroy(&trace->hash_lock); + +clean_poll_lock: + nvgpu_mutex_destroy(&trace->poll_lock); +clean: + nvgpu_kfree(g, trace); + g->fecs_trace = NULL; + return err; +} + +int gk20a_fecs_trace_bind_channel(struct gk20a *g, + struct channel_gk20a *ch) +{ + /* + * map our circ_buf to the context space and store the GPU VA + * in the context header. + */ + + u32 lo; + u32 hi; + u64 addr; + struct tsg_gk20a *tsg; + struct nvgpu_gr_ctx *ch_ctx; + struct gk20a_fecs_trace *trace = g->fecs_trace; + struct nvgpu_mem *mem; + u32 context_ptr = gk20a_fecs_trace_fecs_context_ptr(g, ch); + u32 aperture_mask; + + tsg = tsg_gk20a_from_ch(ch); + if (tsg == NULL) { + nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); + return -EINVAL; + } + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, + "chid=%d context_ptr=%x inst_block=%llx", + ch->chid, context_ptr, + nvgpu_inst_block_addr(g, &ch->inst_block)); + + tsg = tsg_gk20a_from_ch(ch); + if (!tsg) + return -EINVAL; + + ch_ctx = &tsg->gr_ctx; + mem = &ch_ctx->mem; + + if (!trace) + return -ENOMEM; + + mem = &g->gr.global_ctx_buffer[FECS_TRACE_BUFFER].mem; + + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_VA)) { + addr = ch_ctx->global_ctx_buffer_va[FECS_TRACE_BUFFER_VA]; + nvgpu_log(g, gpu_dbg_ctxsw, "gpu_va=%llx", addr); + aperture_mask = 0; + } else { + addr = nvgpu_inst_block_addr(g, mem); + nvgpu_log(g, gpu_dbg_ctxsw, "pa=%llx", addr); + aperture_mask = nvgpu_aperture_mask(g, mem, + ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_sys_mem_noncoherent_f(), + ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_sys_mem_coherent_f(), + ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_vid_mem_f()); + } + if (!addr) + return -ENOMEM; + + lo = u64_lo32(addr); + hi = u64_hi32(addr); + + mem = &ch_ctx->mem; + + nvgpu_log(g, gpu_dbg_ctxsw, "addr_hi=%x addr_lo=%x count=%d", hi, + lo, GK20A_FECS_TRACE_NUM_RECORDS); + + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_context_timestamp_buffer_control_o(), + ctxsw_prog_main_image_context_timestamp_buffer_control_num_records_f( + GK20A_FECS_TRACE_NUM_RECORDS)); + + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_VA)) + mem = &ch->ctx_header; + + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_context_timestamp_buffer_ptr_o(), + lo); + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_o(), + ctxsw_prog_main_image_context_timestamp_buffer_ptr_v_f(hi) | + aperture_mask); + + /* pid (process identifier) in user space, corresponds to tgid (thread + * group id) in kernel space. + */ + gk20a_fecs_trace_hash_add(g, context_ptr, tsg->tgid); + + return 0; +} + +int gk20a_fecs_trace_unbind_channel(struct gk20a *g, struct channel_gk20a *ch) +{ + u32 context_ptr = gk20a_fecs_trace_fecs_context_ptr(g, ch); + + if (g->fecs_trace) { + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, + "ch=%p context_ptr=%x", ch, context_ptr); + + if (g->ops.fecs_trace.is_enabled(g)) { + if (g->ops.fecs_trace.flush) + g->ops.fecs_trace.flush(g); + gk20a_fecs_trace_poll(g); + } + gk20a_fecs_trace_hash_del(g, context_ptr); + } + return 0; +} + +int gk20a_fecs_trace_reset(struct gk20a *g) +{ + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, " "); + + if (!g->ops.fecs_trace.is_enabled(g)) + return 0; + + gk20a_fecs_trace_poll(g); + return gk20a_fecs_trace_set_read_index(g, 0); +} + +int gk20a_fecs_trace_deinit(struct gk20a *g) +{ + struct gk20a_fecs_trace *trace = g->fecs_trace; + + if (!trace->init) + return 0; + + /* + * Check if tracer was enabled before attempting to stop the + * tracer thread. + */ + if (trace->enable_count > 0) { + nvgpu_thread_stop(&trace->poll_task); + } + gk20a_fecs_trace_free_hash_table(g); + + nvgpu_mutex_destroy(&g->fecs_trace->hash_lock); + nvgpu_mutex_destroy(&g->fecs_trace->poll_lock); + nvgpu_mutex_destroy(&g->fecs_trace->enable_lock); + + nvgpu_kfree(g, g->fecs_trace); + g->fecs_trace = NULL; + return 0; +} + +int gk20a_gr_max_entries(struct gk20a *g, + struct nvgpu_gpu_ctxsw_trace_filter *filter) +{ + int n; + int tag; + + /* Compute number of entries per record, with given filter */ + for (n = 0, tag = 0; tag < gk20a_fecs_trace_num_ts(); tag++) + n += (NVGPU_GPU_CTXSW_FILTER_ISSET(tag, filter) != 0); + + /* Return max number of entries generated for the whole ring */ + return n * GK20A_FECS_TRACE_NUM_RECORDS; +} + +int gk20a_fecs_trace_enable(struct gk20a *g) +{ + struct gk20a_fecs_trace *trace = g->fecs_trace; + int write; + int err = 0; + + if (!trace) + return -EINVAL; + + nvgpu_mutex_acquire(&trace->enable_lock); + trace->enable_count++; + + if (trace->enable_count == 1U) { + /* drop data in hw buffer */ + if (g->ops.fecs_trace.flush) + g->ops.fecs_trace.flush(g); + + write = gk20a_fecs_trace_get_write_index(g); + + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* + * For enabling FECS trace support, MAILBOX1's MSB + * (Bit 31:31) should be set to 1. Bits 30:0 represents + * actual pointer value. + */ + write = write | + (BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT)); + } + gk20a_fecs_trace_set_read_index(g, write); + + /* + * FECS ucode does a priv holdoff around the assertion of + * context reset. So, pri transactions (e.g. mailbox1 register + * write) might fail due to this. Hence, do write with ack + * i.e. write and read it back to make sure write happened for + * mailbox1. + */ + while (gk20a_fecs_trace_get_read_index(g) != write) { + nvgpu_log(g, gpu_dbg_ctxsw, "mailbox1 update failed"); + gk20a_fecs_trace_set_read_index(g, write); + } + + err = nvgpu_thread_create(&trace->poll_task, g, + gk20a_fecs_trace_periodic_polling, __func__); + if (err) { + nvgpu_warn(g, + "failed to create FECS polling task"); + goto done; + } + } + +done: + nvgpu_mutex_release(&trace->enable_lock); + return err; +} + +int gk20a_fecs_trace_disable(struct gk20a *g) +{ + struct gk20a_fecs_trace *trace = g->fecs_trace; + int read = 0; + + if (trace == NULL) { + return -EINVAL; + } + + nvgpu_mutex_acquire(&trace->enable_lock); + if (trace->enable_count <= 0U) { + nvgpu_mutex_release(&trace->enable_lock); + return 0; + } + trace->enable_count--; + if (trace->enable_count == 0U) { + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* + * For disabling FECS trace support, MAILBOX1's MSB + * (Bit 31:31) should be set to 0. + */ + read = gk20a_fecs_trace_get_read_index(g) & + (~(BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT))); + + gk20a_fecs_trace_set_read_index(g, read); + + /* + * FECS ucode does a priv holdoff around the assertion + * of context reset. So, pri transactions (e.g. + * mailbox1 register write) might fail due to this. + * Hence, do write with ack i.e. write and read it back + * to make sure write happened for mailbox1. + */ + while (gk20a_fecs_trace_get_read_index(g) != read) { + nvgpu_log(g, gpu_dbg_ctxsw, + "mailbox1 update failed"); + gk20a_fecs_trace_set_read_index(g, read); + } + } + + nvgpu_thread_stop(&trace->poll_task); + + } + nvgpu_mutex_release(&trace->enable_lock); + + return -EPERM; +} + +bool gk20a_fecs_trace_is_enabled(struct gk20a *g) +{ + struct gk20a_fecs_trace *trace = g->fecs_trace; + + return (trace && nvgpu_thread_is_running(&trace->poll_task)); +} + +void gk20a_fecs_trace_reset_buffer(struct gk20a *g) +{ + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, " "); + + gk20a_fecs_trace_set_read_index(g, + gk20a_fecs_trace_get_write_index(g)); +} +#endif /* CONFIG_GK20A_CTXSW_TRACE */ diff --git a/include/gk20a/fecs_trace_gk20a.h b/include/gk20a/fecs_trace_gk20a.h new file mode 100644 index 0000000..d33e619 --- /dev/null +++ b/include/gk20a/fecs_trace_gk20a.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_GK20A_FECS_TRACE_GK20A_H +#define NVGPU_GK20A_FECS_TRACE_GK20A_H + +struct gk20a; +struct channel_gk20a; +struct nvgpu_gpu_ctxsw_trace_filter; + +int gk20a_fecs_trace_poll(struct gk20a *g); +int gk20a_fecs_trace_init(struct gk20a *g); +int gk20a_fecs_trace_bind_channel(struct gk20a *g, + struct channel_gk20a *ch); +int gk20a_fecs_trace_unbind_channel(struct gk20a *g, struct channel_gk20a *ch); +int gk20a_fecs_trace_reset(struct gk20a *g); +int gk20a_fecs_trace_deinit(struct gk20a *g); +int gk20a_gr_max_entries(struct gk20a *g, + struct nvgpu_gpu_ctxsw_trace_filter *filter); +int gk20a_fecs_trace_enable(struct gk20a *g); +int gk20a_fecs_trace_disable(struct gk20a *g); +bool gk20a_fecs_trace_is_enabled(struct gk20a *g); +size_t gk20a_fecs_trace_buffer_size(struct gk20a *g); +void gk20a_fecs_trace_reset_buffer(struct gk20a *g); + +#endif /* NVGPU_GK20A_FECS_TRACE_GK20A_H */ diff --git a/include/gk20a/fence_gk20a.c b/include/gk20a/fence_gk20a.c new file mode 100644 index 0000000..af42130 --- /dev/null +++ b/include/gk20a/fence_gk20a.c @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "fence_gk20a.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a.h" + +struct gk20a_fence_ops { + int (*wait)(struct gk20a_fence *, long timeout); + bool (*is_expired)(struct gk20a_fence *); + void *(*free)(struct nvgpu_ref *); +}; + +static void gk20a_fence_free(struct nvgpu_ref *ref) +{ + struct gk20a_fence *f = + container_of(ref, struct gk20a_fence, ref); + struct gk20a *g = f->g; + + if (nvgpu_os_fence_is_initialized(&f->os_fence)) { + f->os_fence.ops->drop_ref(&f->os_fence); + } + + if (f->semaphore) { + nvgpu_semaphore_put(f->semaphore); + } + + if (f->allocator) { + if (nvgpu_alloc_initialized(f->allocator)) { + nvgpu_free(f->allocator, (u64)(uintptr_t)f); + } + } else { + nvgpu_kfree(g, f); + } +} + +void gk20a_fence_put(struct gk20a_fence *f) +{ + if (f) { + nvgpu_ref_put(&f->ref, gk20a_fence_free); + } +} + +struct gk20a_fence *gk20a_fence_get(struct gk20a_fence *f) +{ + if (f) { + nvgpu_ref_get(&f->ref); + } + return f; +} + +inline bool gk20a_fence_is_valid(struct gk20a_fence *f) +{ + bool valid = f->valid; + + nvgpu_smp_rmb(); + return valid; +} + +int gk20a_fence_install_fd(struct gk20a_fence *f, int fd) +{ + if (!f || !gk20a_fence_is_valid(f) || + !nvgpu_os_fence_is_initialized(&f->os_fence)) { + return -EINVAL; + } + + f->os_fence.ops->install_fence(&f->os_fence, fd); + + return 0; +} + +int gk20a_fence_wait(struct gk20a *g, struct gk20a_fence *f, + unsigned long timeout) +{ + if (f && gk20a_fence_is_valid(f)) { + if (!nvgpu_platform_is_silicon(g)) { + timeout = MAX_SCHEDULE_TIMEOUT; + } + return f->ops->wait(f, timeout); + } + return 0; +} + +bool gk20a_fence_is_expired(struct gk20a_fence *f) +{ + if (f && gk20a_fence_is_valid(f) && f->ops) { + return f->ops->is_expired(f); + } else { + return true; + } +} + +int gk20a_alloc_fence_pool(struct channel_gk20a *c, unsigned int count) +{ + int err; + size_t size; + struct gk20a_fence *fence_pool = NULL; + + size = sizeof(struct gk20a_fence); + if (count <= UINT_MAX / size) { + size = count * size; + fence_pool = nvgpu_vzalloc(c->g, size); + } + + if (!fence_pool) { + return -ENOMEM; + } + + err = nvgpu_lockless_allocator_init(c->g, &c->fence_allocator, + "fence_pool", (size_t)fence_pool, size, + sizeof(struct gk20a_fence), 0); + if (err) { + goto fail; + } + + return 0; + +fail: + nvgpu_vfree(c->g, fence_pool); + return err; +} + +void gk20a_free_fence_pool(struct channel_gk20a *c) +{ + if (nvgpu_alloc_initialized(&c->fence_allocator)) { + struct gk20a_fence *fence_pool; + fence_pool = (struct gk20a_fence *)(uintptr_t) + nvgpu_alloc_base(&c->fence_allocator); + nvgpu_alloc_destroy(&c->fence_allocator); + nvgpu_vfree(c->g, fence_pool); + } +} + +struct gk20a_fence *gk20a_alloc_fence(struct channel_gk20a *c) +{ + struct gk20a_fence *fence = NULL; + + if (channel_gk20a_is_prealloc_enabled(c)) { + if (nvgpu_alloc_initialized(&c->fence_allocator)) { + fence = (struct gk20a_fence *)(uintptr_t) + nvgpu_alloc(&c->fence_allocator, + sizeof(struct gk20a_fence)); + + /* clear the node and reset the allocator pointer */ + if (fence) { + memset(fence, 0, sizeof(*fence)); + fence->allocator = &c->fence_allocator; + } + } + } else { + fence = nvgpu_kzalloc(c->g, sizeof(struct gk20a_fence)); + } + + if (fence) { + nvgpu_ref_init(&fence->ref); + fence->g = c->g; + } + + return fence; +} + +void gk20a_init_fence(struct gk20a_fence *f, + const struct gk20a_fence_ops *ops, + struct nvgpu_os_fence os_fence) +{ + if (!f) { + return; + } + f->ops = ops; + f->syncpt_id = -1; + f->semaphore = NULL; + f->os_fence = os_fence; +} + +/* Fences that are backed by GPU semaphores: */ + +static int nvgpu_semaphore_fence_wait(struct gk20a_fence *f, long timeout) +{ + if (!nvgpu_semaphore_is_acquired(f->semaphore)) { + return 0; + } + + return NVGPU_COND_WAIT_INTERRUPTIBLE( + f->semaphore_wq, + !nvgpu_semaphore_is_acquired(f->semaphore), + timeout); +} + +static bool nvgpu_semaphore_fence_is_expired(struct gk20a_fence *f) +{ + return !nvgpu_semaphore_is_acquired(f->semaphore); +} + +static const struct gk20a_fence_ops nvgpu_semaphore_fence_ops = { + .wait = &nvgpu_semaphore_fence_wait, + .is_expired = &nvgpu_semaphore_fence_is_expired, +}; + +/* This function takes ownership of the semaphore as well as the os_fence */ +int gk20a_fence_from_semaphore( + struct gk20a_fence *fence_out, + struct nvgpu_semaphore *semaphore, + struct nvgpu_cond *semaphore_wq, + struct nvgpu_os_fence os_fence) +{ + struct gk20a_fence *f = fence_out; + + gk20a_init_fence(f, &nvgpu_semaphore_fence_ops, os_fence); + if (!f) { + return -EINVAL; + } + + + f->semaphore = semaphore; + f->semaphore_wq = semaphore_wq; + + /* commit previous writes before setting the valid flag */ + nvgpu_smp_wmb(); + f->valid = true; + + return 0; +} + +#ifdef CONFIG_TEGRA_GK20A_NVHOST +/* Fences that are backed by host1x syncpoints: */ + +static int gk20a_syncpt_fence_wait(struct gk20a_fence *f, long timeout) +{ + return nvgpu_nvhost_syncpt_wait_timeout_ext( + f->nvhost_dev, f->syncpt_id, f->syncpt_value, + (u32)timeout, NULL, NULL); +} + +static bool gk20a_syncpt_fence_is_expired(struct gk20a_fence *f) +{ + + /* + * In cases we don't register a notifier, we can't expect the + * syncpt value to be updated. For this case, we force a read + * of the value from HW, and then check for expiration. + */ + if (!nvgpu_nvhost_syncpt_is_expired_ext(f->nvhost_dev, f->syncpt_id, + f->syncpt_value)) { + u32 val; + + if (!nvgpu_nvhost_syncpt_read_ext_check(f->nvhost_dev, + f->syncpt_id, &val)) { + return nvgpu_nvhost_syncpt_is_expired_ext( + f->nvhost_dev, + f->syncpt_id, f->syncpt_value); + } + } + + return true; +} + +static const struct gk20a_fence_ops gk20a_syncpt_fence_ops = { + .wait = &gk20a_syncpt_fence_wait, + .is_expired = &gk20a_syncpt_fence_is_expired, +}; + +/* This function takes the ownership of the os_fence */ +int gk20a_fence_from_syncpt( + struct gk20a_fence *fence_out, + struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 value, struct nvgpu_os_fence os_fence) +{ + struct gk20a_fence *f = fence_out; + + gk20a_init_fence(f, &gk20a_syncpt_fence_ops, os_fence); + if (!f) + return -EINVAL; + + f->nvhost_dev = nvhost_dev; + f->syncpt_id = id; + f->syncpt_value = value; + + /* commit previous writes before setting the valid flag */ + nvgpu_smp_wmb(); + f->valid = true; + + return 0; +} +#else +int gk20a_fence_from_syncpt( + struct gk20a_fence *fence_out, + struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 value, struct nvgpu_os_fence os_fence) +{ + return -EINVAL; +} +#endif diff --git a/include/gk20a/fence_gk20a.h b/include/gk20a/fence_gk20a.h new file mode 100644 index 0000000..0311279 --- /dev/null +++ b/include/gk20a/fence_gk20a.h @@ -0,0 +1,100 @@ +/* + * drivers/video/tegra/host/gk20a/fence_gk20a.h + * + * GK20A Fences + * + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_GK20A_FENCE_GK20A_H +#define NVGPU_GK20A_FENCE_GK20A_H + +#include +#include +#include + +struct platform_device; +struct nvgpu_semaphore; +struct channel_gk20a; +struct gk20a; +struct nvgpu_os_fence; + +struct gk20a_fence_ops; + +struct gk20a_fence { + struct gk20a *g; + + /* Valid for all fence types: */ + bool valid; + struct nvgpu_ref ref; + const struct gk20a_fence_ops *ops; + + struct nvgpu_os_fence os_fence; + + /* Valid for fences created from semaphores: */ + struct nvgpu_semaphore *semaphore; + struct nvgpu_cond *semaphore_wq; + + /* Valid for fences created from syncpoints: */ + struct nvgpu_nvhost_dev *nvhost_dev; + u32 syncpt_id; + u32 syncpt_value; + + /* Valid for fences part of a pre-allocated fence pool */ + struct nvgpu_allocator *allocator; +}; + +/* Fences can be created from semaphores or syncpoint (id, value) pairs */ +int gk20a_fence_from_semaphore( + struct gk20a_fence *fence_out, + struct nvgpu_semaphore *semaphore, + struct nvgpu_cond *semaphore_wq, + struct nvgpu_os_fence os_fence); + +int gk20a_fence_from_syncpt( + struct gk20a_fence *fence_out, + struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 value, + struct nvgpu_os_fence os_fence); + +int gk20a_alloc_fence_pool( + struct channel_gk20a *c, + unsigned int count); + +void gk20a_free_fence_pool( + struct channel_gk20a *c); + +struct gk20a_fence *gk20a_alloc_fence( + struct channel_gk20a *c); + +void gk20a_init_fence(struct gk20a_fence *f, + const struct gk20a_fence_ops *ops, + struct nvgpu_os_fence os_fence); + +/* Fence operations */ +void gk20a_fence_put(struct gk20a_fence *f); +struct gk20a_fence *gk20a_fence_get(struct gk20a_fence *f); +int gk20a_fence_wait(struct gk20a *g, struct gk20a_fence *f, + unsigned long timeout); +bool gk20a_fence_is_expired(struct gk20a_fence *f); +bool gk20a_fence_is_valid(struct gk20a_fence *f); +int gk20a_fence_install_fd(struct gk20a_fence *f, int fd); + +#endif /* NVGPU_GK20A_FENCE_GK20A_H */ diff --git a/include/gk20a/fifo_gk20a.c b/include/gk20a/fifo_gk20a.c new file mode 100644 index 0000000..4477f7c --- /dev/null +++ b/include/gk20a/fifo_gk20a.c @@ -0,0 +1,4649 @@ +/* + * GK20A Graphics FIFO (gr host) + * + * Copyright (c) 2011-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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a.h" +#include "mm_gk20a.h" + +#include +#include +#include +#include +#include +#include + +#include + +#define FECS_METHOD_WFI_RESTORE 0x80000 +#define FECS_MAILBOX_0_ACK_RESTORE 0x4 + + +static u32 gk20a_fifo_engines_on_id(struct gk20a *g, u32 id, bool is_tsg); + +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" +}; + +u32 gk20a_fifo_get_engine_ids(struct gk20a *g, + u32 engine_id[], u32 engine_id_sz, + u32 engine_enum) +{ + struct fifo_gk20a *f = NULL; + u32 instance_cnt = 0; + u32 engine_id_idx; + u32 active_engine_id = 0; + struct fifo_engine_info_gk20a *info = NULL; + + if (g && engine_id_sz && (engine_enum < ENGINE_INVAL_GK20A)) { + f = &g->fifo; + for (engine_id_idx = 0; engine_id_idx < f->num_engines; ++engine_id_idx) { + active_engine_id = f->active_engines_list[engine_id_idx]; + info = &f->engine_info[active_engine_id]; + + if (info->engine_enum == engine_enum) { + if (instance_cnt < engine_id_sz) { + engine_id[instance_cnt] = active_engine_id; + ++instance_cnt; + } else { + nvgpu_log_info(g, "warning engine_id table sz is small %d", + engine_id_sz); + } + } + } + } + return instance_cnt; +} + +struct fifo_engine_info_gk20a *gk20a_fifo_get_engine_info(struct gk20a *g, u32 engine_id) +{ + struct fifo_gk20a *f = NULL; + u32 engine_id_idx; + struct fifo_engine_info_gk20a *info = NULL; + + if (!g) { + return info; + } + + f = &g->fifo; + + if (engine_id < f->max_engines) { + for (engine_id_idx = 0; engine_id_idx < f->num_engines; ++engine_id_idx) { + if (engine_id == f->active_engines_list[engine_id_idx]) { + info = &f->engine_info[engine_id]; + break; + } + } + } + + if (!info) { + nvgpu_err(g, "engine_id is not in active list/invalid %d", engine_id); + } + + return info; +} + +bool gk20a_fifo_is_valid_engine_id(struct gk20a *g, u32 engine_id) +{ + struct fifo_gk20a *f = NULL; + u32 engine_id_idx; + bool valid = false; + + if (!g) { + return valid; + } + + f = &g->fifo; + + if (engine_id < f->max_engines) { + for (engine_id_idx = 0; engine_id_idx < f->num_engines; ++engine_id_idx) { + if (engine_id == f->active_engines_list[engine_id_idx]) { + valid = true; + break; + } + } + } + + if (!valid) { + nvgpu_err(g, "engine_id is not in active list/invalid %d", engine_id); + } + + return valid; +} + +u32 gk20a_fifo_get_gr_engine_id(struct gk20a *g) +{ + u32 gr_engine_cnt = 0; + u32 gr_engine_id = FIFO_INVAL_ENGINE_ID; + + /* Consider 1st available GR engine */ + gr_engine_cnt = gk20a_fifo_get_engine_ids(g, &gr_engine_id, + 1, ENGINE_GR_GK20A); + + if (!gr_engine_cnt) { + nvgpu_err(g, "No GR engine available on this device!"); + } + + return gr_engine_id; +} + +u32 gk20a_fifo_get_all_ce_engine_reset_mask(struct gk20a *g) +{ + u32 reset_mask = 0; + u32 engine_enum = ENGINE_INVAL_GK20A; + struct fifo_gk20a *f = NULL; + u32 engine_id_idx; + struct fifo_engine_info_gk20a *engine_info; + u32 active_engine_id = 0; + + if (!g) { + return reset_mask; + } + + f = &g->fifo; + + for (engine_id_idx = 0; engine_id_idx < f->num_engines; ++engine_id_idx) { + active_engine_id = f->active_engines_list[engine_id_idx]; + engine_info = &f->engine_info[active_engine_id]; + engine_enum = engine_info->engine_enum; + + if ((engine_enum == ENGINE_GRCE_GK20A) || + (engine_enum == ENGINE_ASYNC_CE_GK20A)) { + reset_mask |= engine_info->reset_mask; + } + } + + return reset_mask; +} + +u32 gk20a_fifo_get_fast_ce_runlist_id(struct gk20a *g) +{ + u32 ce_runlist_id = gk20a_fifo_get_gr_runlist_id(g); + u32 engine_enum = ENGINE_INVAL_GK20A; + struct fifo_gk20a *f = NULL; + u32 engine_id_idx; + struct fifo_engine_info_gk20a *engine_info; + u32 active_engine_id = 0; + + if (!g) { + return ce_runlist_id; + } + + f = &g->fifo; + + for (engine_id_idx = 0; engine_id_idx < f->num_engines; ++engine_id_idx) { + active_engine_id = f->active_engines_list[engine_id_idx]; + engine_info = &f->engine_info[active_engine_id]; + engine_enum = engine_info->engine_enum; + + /* selecet last available ASYNC_CE if available */ + if (engine_enum == ENGINE_ASYNC_CE_GK20A) { + ce_runlist_id = engine_info->runlist_id; + } + } + + return ce_runlist_id; +} + +u32 gk20a_fifo_get_gr_runlist_id(struct gk20a *g) +{ + u32 gr_engine_cnt = 0; + u32 gr_engine_id = FIFO_INVAL_ENGINE_ID; + struct fifo_engine_info_gk20a *engine_info; + u32 gr_runlist_id = ~0; + + /* Consider 1st available GR engine */ + gr_engine_cnt = gk20a_fifo_get_engine_ids(g, &gr_engine_id, + 1, ENGINE_GR_GK20A); + + if (!gr_engine_cnt) { + nvgpu_err(g, + "No GR engine available on this device!"); + goto end; + } + + engine_info = gk20a_fifo_get_engine_info(g, gr_engine_id); + + if (engine_info) { + gr_runlist_id = engine_info->runlist_id; + } else { + nvgpu_err(g, + "gr_engine_id is not in active list/invalid %d", gr_engine_id); + } + +end: + return gr_runlist_id; +} + +bool gk20a_fifo_is_valid_runlist_id(struct gk20a *g, u32 runlist_id) +{ + struct fifo_gk20a *f = NULL; + u32 engine_id_idx; + u32 active_engine_id; + struct fifo_engine_info_gk20a *engine_info; + + if (!g) { + return false; + } + + f = &g->fifo; + + for (engine_id_idx = 0; engine_id_idx < f->num_engines; ++engine_id_idx) { + active_engine_id = f->active_engines_list[engine_id_idx]; + engine_info = gk20a_fifo_get_engine_info(g, active_engine_id); + if (engine_info && (engine_info->runlist_id == runlist_id)) { + return true; + } + } + + return false; +} + +/* + * Link engine IDs to MMU IDs and vice versa. + */ + +static inline u32 gk20a_engine_id_to_mmu_id(struct gk20a *g, u32 engine_id) +{ + u32 fault_id = FIFO_INVAL_ENGINE_ID; + struct fifo_engine_info_gk20a *engine_info; + + engine_info = gk20a_fifo_get_engine_info(g, engine_id); + + if (engine_info) { + fault_id = engine_info->fault_id; + } else { + nvgpu_err(g, "engine_id is not in active list/invalid %d", engine_id); + } + return fault_id; +} + +static inline u32 gk20a_mmu_id_to_engine_id(struct gk20a *g, u32 fault_id) +{ + u32 engine_id; + u32 active_engine_id; + struct fifo_engine_info_gk20a *engine_info; + struct fifo_gk20a *f = &g->fifo; + + for (engine_id = 0; engine_id < f->num_engines; engine_id++) { + active_engine_id = f->active_engines_list[engine_id]; + engine_info = &g->fifo.engine_info[active_engine_id]; + + if (engine_info->fault_id == fault_id) { + break; + } + active_engine_id = FIFO_INVAL_ENGINE_ID; + } + return active_engine_id; +} + +int gk20a_fifo_engine_enum_from_type(struct gk20a *g, u32 engine_type, + u32 *inst_id) +{ + int ret = ENGINE_INVAL_GK20A; + + nvgpu_log_info(g, "engine type %d", engine_type); + if (engine_type == top_device_info_type_enum_graphics_v()) { + ret = ENGINE_GR_GK20A; + } else if ((engine_type >= top_device_info_type_enum_copy0_v()) && + (engine_type <= top_device_info_type_enum_copy2_v())) { + /* Lets consider all the CE engine have separate runlist at this point + * We can identify the ENGINE_GRCE_GK20A type CE using runlist_id + * comparsion logic with GR runlist_id in init_engine_info() */ + ret = ENGINE_ASYNC_CE_GK20A; + /* inst_id starts from CE0 to CE2 */ + if (inst_id) { + *inst_id = (engine_type - top_device_info_type_enum_copy0_v()); + } + } + + return ret; +} + +int gk20a_fifo_init_engine_info(struct fifo_gk20a *f) +{ + struct gk20a *g = f->g; + u32 i; + u32 max_info_entries = top_device_info__size_1_v(); + u32 engine_enum = ENGINE_INVAL_GK20A; + u32 engine_id = FIFO_INVAL_ENGINE_ID; + u32 runlist_id = ~0; + u32 pbdma_id = ~0; + u32 intr_id = ~0; + u32 reset_id = ~0; + u32 inst_id = 0; + u32 pri_base = 0; + u32 fault_id = 0; + u32 gr_runlist_id = ~0; + bool found_pbdma_for_runlist = false; + + nvgpu_log_fn(g, " "); + + f->num_engines = 0; + + for (i = 0; i < max_info_entries; i++) { + u32 table_entry = gk20a_readl(f->g, top_device_info_r(i)); + u32 entry = top_device_info_entry_v(table_entry); + u32 runlist_bit; + + if (entry == top_device_info_entry_enum_v()) { + if (top_device_info_engine_v(table_entry)) { + engine_id = + top_device_info_engine_enum_v(table_entry); + nvgpu_log_info(g, "info: engine_id %d", + top_device_info_engine_enum_v(table_entry)); + } + + + if (top_device_info_runlist_v(table_entry)) { + runlist_id = + top_device_info_runlist_enum_v(table_entry); + nvgpu_log_info(g, "gr info: runlist_id %d", runlist_id); + + runlist_bit = BIT(runlist_id); + + found_pbdma_for_runlist = false; + for (pbdma_id = 0; pbdma_id < f->num_pbdma; + pbdma_id++) { + if (f->pbdma_map[pbdma_id] & + runlist_bit) { + nvgpu_log_info(g, + "gr info: pbdma_map[%d]=%d", + pbdma_id, + f->pbdma_map[pbdma_id]); + found_pbdma_for_runlist = true; + break; + } + } + + if (!found_pbdma_for_runlist) { + nvgpu_err(g, "busted pbdma map"); + return -EINVAL; + } + } + + if (top_device_info_intr_v(table_entry)) { + intr_id = + top_device_info_intr_enum_v(table_entry); + nvgpu_log_info(g, "gr info: intr_id %d", intr_id); + } + + if (top_device_info_reset_v(table_entry)) { + reset_id = + top_device_info_reset_enum_v(table_entry); + nvgpu_log_info(g, "gr info: reset_id %d", + reset_id); + } + } else if (entry == top_device_info_entry_engine_type_v()) { + u32 engine_type = + top_device_info_type_enum_v(table_entry); + engine_enum = + g->ops.fifo.engine_enum_from_type(g, + engine_type, &inst_id); + } else if (entry == top_device_info_entry_data_v()) { + /* gk20a doesn't support device_info_data packet parsing */ + if (g->ops.fifo.device_info_data_parse) { + g->ops.fifo.device_info_data_parse(g, + table_entry, &inst_id, &pri_base, + &fault_id); + } + } + + if (!top_device_info_chain_v(table_entry)) { + if (engine_enum < ENGINE_INVAL_GK20A) { + struct fifo_engine_info_gk20a *info = + &g->fifo.engine_info[engine_id]; + + info->intr_mask |= BIT(intr_id); + info->reset_mask |= BIT(reset_id); + info->runlist_id = runlist_id; + info->pbdma_id = pbdma_id; + info->inst_id = inst_id; + info->pri_base = pri_base; + + if (engine_enum == ENGINE_GR_GK20A) { + gr_runlist_id = runlist_id; + } + + /* GR and GR_COPY shares same runlist_id */ + if ((engine_enum == ENGINE_ASYNC_CE_GK20A) && + (gr_runlist_id == runlist_id)) { + engine_enum = ENGINE_GRCE_GK20A; + } + + info->engine_enum = engine_enum; + + if (!fault_id && (engine_enum == ENGINE_GRCE_GK20A)) { + fault_id = 0x1b; + } + info->fault_id = fault_id; + + /* engine_id starts from 0 to NV_HOST_NUM_ENGINES */ + f->active_engines_list[f->num_engines] = engine_id; + + ++f->num_engines; + + engine_enum = ENGINE_INVAL_GK20A; + } + } + } + + return 0; +} + +u32 gk20a_fifo_act_eng_interrupt_mask(struct gk20a *g, u32 act_eng_id) +{ + struct fifo_engine_info_gk20a *engine_info = NULL; + + engine_info = gk20a_fifo_get_engine_info(g, act_eng_id); + if (engine_info) { + return engine_info->intr_mask; + } + + return 0; +} + +u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g) +{ + u32 eng_intr_mask = 0; + unsigned int i; + u32 active_engine_id = 0; + u32 engine_enum = ENGINE_INVAL_GK20A; + + for (i = 0; i < g->fifo.num_engines; i++) { + u32 intr_mask; + active_engine_id = g->fifo.active_engines_list[i]; + intr_mask = g->fifo.engine_info[active_engine_id].intr_mask; + engine_enum = g->fifo.engine_info[active_engine_id].engine_enum; + if (((engine_enum == ENGINE_GRCE_GK20A) || + (engine_enum == ENGINE_ASYNC_CE_GK20A)) && + (!g->ops.ce2.isr_stall || !g->ops.ce2.isr_nonstall)) { + continue; + } + + eng_intr_mask |= intr_mask; + } + + return eng_intr_mask; +} + +void gk20a_fifo_delete_runlist(struct fifo_gk20a *f) +{ + u32 i; + u32 runlist_id; + struct fifo_runlist_info_gk20a *runlist; + struct gk20a *g = NULL; + + if (!f || !f->runlist_info) { + return; + } + + g = f->g; + + for (runlist_id = 0; runlist_id < f->max_runlists; runlist_id++) { + runlist = &f->runlist_info[runlist_id]; + for (i = 0; i < MAX_RUNLIST_BUFFERS; i++) { + nvgpu_dma_free(g, &runlist->mem[i]); + } + + nvgpu_kfree(g, runlist->active_channels); + runlist->active_channels = NULL; + + nvgpu_kfree(g, runlist->active_tsgs); + runlist->active_tsgs = NULL; + + nvgpu_mutex_destroy(&runlist->runlist_lock); + + } + memset(f->runlist_info, 0, (sizeof(struct fifo_runlist_info_gk20a) * + f->max_runlists)); + + nvgpu_kfree(g, f->runlist_info); + f->runlist_info = NULL; + f->max_runlists = 0; +} + +static void gk20a_remove_fifo_support(struct fifo_gk20a *f) +{ + struct gk20a *g = f->g; + unsigned int i = 0; + + nvgpu_log_fn(g, " "); + + nvgpu_channel_worker_deinit(g); + /* + * Make sure all channels are closed before deleting them. + */ + for (; i < f->num_channels; i++) { + struct channel_gk20a *c = f->channel + i; + struct tsg_gk20a *tsg = f->tsg + i; + + /* + * Could race but worst that happens is we get an error message + * from gk20a_free_channel() complaining about multiple closes. + */ + if (c->referenceable) { + __gk20a_channel_kill(c); + } + + nvgpu_mutex_destroy(&tsg->event_id_list_lock); + + nvgpu_mutex_destroy(&c->ioctl_lock); + nvgpu_mutex_destroy(&c->joblist.cleanup_lock); + nvgpu_mutex_destroy(&c->joblist.pre_alloc.read_lock); + nvgpu_mutex_destroy(&c->sync_lock); +#if defined(CONFIG_GK20A_CYCLE_STATS) + nvgpu_mutex_destroy(&c->cyclestate.cyclestate_buffer_mutex); + nvgpu_mutex_destroy(&c->cs_client_mutex); +#endif + nvgpu_mutex_destroy(&c->dbg_s_lock); + + } + + nvgpu_vfree(g, f->channel); + nvgpu_vfree(g, f->tsg); + if (g->ops.mm.is_bar1_supported(g)) { + nvgpu_dma_unmap_free(g->mm.bar1.vm, &f->userd); + } else { + nvgpu_dma_free(g, &f->userd); + } + + gk20a_fifo_delete_runlist(f); + + nvgpu_kfree(g, f->pbdma_map); + f->pbdma_map = NULL; + nvgpu_kfree(g, f->engine_info); + f->engine_info = NULL; + nvgpu_kfree(g, f->active_engines_list); + f->active_engines_list = NULL; +} + +/* reads info from hardware and fills in pbmda exception info record */ +static inline void get_exception_pbdma_info( + struct gk20a *g, + struct fifo_engine_info_gk20a *eng_info) +{ + struct fifo_pbdma_exception_info_gk20a *e = + &eng_info->pbdma_exception_info; + + u32 pbdma_status_r = e->status_r = gk20a_readl(g, + fifo_pbdma_status_r(eng_info->pbdma_id)); + e->id = fifo_pbdma_status_id_v(pbdma_status_r); /* vs. id_hw_v()? */ + e->id_is_chid = fifo_pbdma_status_id_type_v(pbdma_status_r) == + fifo_pbdma_status_id_type_chid_v(); + e->chan_status_v = fifo_pbdma_status_chan_status_v(pbdma_status_r); + e->next_id_is_chid = + fifo_pbdma_status_next_id_type_v(pbdma_status_r) == + fifo_pbdma_status_next_id_type_chid_v(); + e->next_id = fifo_pbdma_status_next_id_v(pbdma_status_r); + e->chsw_in_progress = + fifo_pbdma_status_chsw_v(pbdma_status_r) == + fifo_pbdma_status_chsw_in_progress_v(); +} + +static void fifo_pbdma_exception_status(struct gk20a *g, + struct fifo_engine_info_gk20a *eng_info) +{ + struct fifo_pbdma_exception_info_gk20a *e; + get_exception_pbdma_info(g, eng_info); + e = &eng_info->pbdma_exception_info; + + nvgpu_log_fn(g, "pbdma_id %d, " + "id_type %s, id %d, chan_status %d, " + "next_id_type %s, next_id %d, " + "chsw_in_progress %d", + eng_info->pbdma_id, + e->id_is_chid ? "chid" : "tsgid", e->id, e->chan_status_v, + e->next_id_is_chid ? "chid" : "tsgid", e->next_id, + e->chsw_in_progress); +} + +/* reads info from hardware and fills in pbmda exception info record */ +static inline void get_exception_engine_info( + struct gk20a *g, + struct fifo_engine_info_gk20a *eng_info) +{ + struct fifo_engine_exception_info_gk20a *e = + &eng_info->engine_exception_info; + u32 engine_status_r = e->status_r = + gk20a_readl(g, fifo_engine_status_r(eng_info->engine_id)); + e->id = fifo_engine_status_id_v(engine_status_r); /* vs. id_hw_v()? */ + e->id_is_chid = fifo_engine_status_id_type_v(engine_status_r) == + fifo_engine_status_id_type_chid_v(); + e->ctx_status_v = fifo_engine_status_ctx_status_v(engine_status_r); + e->faulted = + fifo_engine_status_faulted_v(engine_status_r) == + fifo_engine_status_faulted_true_v(); + e->idle = + fifo_engine_status_engine_v(engine_status_r) == + fifo_engine_status_engine_idle_v(); + e->ctxsw_in_progress = + fifo_engine_status_ctxsw_v(engine_status_r) == + fifo_engine_status_ctxsw_in_progress_v(); +} + +static void fifo_engine_exception_status(struct gk20a *g, + struct fifo_engine_info_gk20a *eng_info) +{ + struct fifo_engine_exception_info_gk20a *e; + get_exception_engine_info(g, eng_info); + e = &eng_info->engine_exception_info; + + nvgpu_log_fn(g, "engine_id %d, id_type %s, id %d, ctx_status %d, " + "faulted %d, idle %d, ctxsw_in_progress %d, ", + eng_info->engine_id, e->id_is_chid ? "chid" : "tsgid", + e->id, e->ctx_status_v, + e->faulted, e->idle, e->ctxsw_in_progress); +} + +static int init_runlist(struct gk20a *g, struct fifo_gk20a *f) +{ + struct fifo_runlist_info_gk20a *runlist; + struct fifo_engine_info_gk20a *engine_info; + unsigned int runlist_id; + u32 i; + size_t runlist_size; + u32 active_engine_id, pbdma_id, engine_id; + int flags = nvgpu_is_enabled(g, NVGPU_MM_USE_PHYSICAL_SG) ? + NVGPU_DMA_FORCE_CONTIGUOUS : 0; + int err = 0; + + nvgpu_log_fn(g, " "); + + f->max_runlists = g->ops.fifo.eng_runlist_base_size(); + f->runlist_info = nvgpu_kzalloc(g, + sizeof(struct fifo_runlist_info_gk20a) * + f->max_runlists); + if (!f->runlist_info) { + goto clean_up_runlist; + } + + memset(f->runlist_info, 0, (sizeof(struct fifo_runlist_info_gk20a) * + f->max_runlists)); + + for (runlist_id = 0; runlist_id < f->max_runlists; runlist_id++) { + runlist = &f->runlist_info[runlist_id]; + + runlist->active_channels = + nvgpu_kzalloc(g, DIV_ROUND_UP(f->num_channels, + BITS_PER_BYTE)); + if (!runlist->active_channels) { + goto clean_up_runlist; + } + + runlist->active_tsgs = + nvgpu_kzalloc(g, DIV_ROUND_UP(f->num_channels, + BITS_PER_BYTE)); + if (!runlist->active_tsgs) { + goto clean_up_runlist; + } + + runlist_size = f->runlist_entry_size * f->num_runlist_entries; + nvgpu_log(g, gpu_dbg_info, + "runlist_entries %d runlist size %zu", + f->num_runlist_entries, runlist_size); + + for (i = 0; i < MAX_RUNLIST_BUFFERS; i++) { + err = nvgpu_dma_alloc_flags_sys(g, flags, + runlist_size, + &runlist->mem[i]); + if (err) { + nvgpu_err(g, "memory allocation failed"); + goto clean_up_runlist; + } + } + + err = nvgpu_mutex_init(&runlist->runlist_lock); + if (err != 0) { + nvgpu_err(g, + "Error in runlist_lock mutex initialization"); + goto clean_up_runlist; + } + + /* None of buffers is pinned if this value doesn't change. + Otherwise, one of them (cur_buffer) must have been pinned. */ + runlist->cur_buffer = MAX_RUNLIST_BUFFERS; + + for (pbdma_id = 0; pbdma_id < f->num_pbdma; pbdma_id++) { + if (f->pbdma_map[pbdma_id] & BIT(runlist_id)) { + runlist->pbdma_bitmask |= BIT(pbdma_id); + } + } + nvgpu_log(g, gpu_dbg_info, "runlist %d : pbdma bitmask 0x%x", + runlist_id, runlist->pbdma_bitmask); + + for (engine_id = 0; engine_id < f->num_engines; ++engine_id) { + active_engine_id = f->active_engines_list[engine_id]; + engine_info = &f->engine_info[active_engine_id]; + + if (engine_info && engine_info->runlist_id == runlist_id) { + runlist->eng_bitmask |= BIT(active_engine_id); + } + } + nvgpu_log(g, gpu_dbg_info, "runlist %d : act eng bitmask 0x%x", + runlist_id, runlist->eng_bitmask); + } + + nvgpu_log_fn(g, "done"); + return 0; + +clean_up_runlist: + gk20a_fifo_delete_runlist(f); + nvgpu_log_fn(g, "fail"); + return err; +} + +u32 gk20a_fifo_intr_0_error_mask(struct gk20a *g) +{ + u32 intr_0_error_mask = + fifo_intr_0_bind_error_pending_f() | + fifo_intr_0_sched_error_pending_f() | + fifo_intr_0_chsw_error_pending_f() | + fifo_intr_0_fb_flush_timeout_pending_f() | + fifo_intr_0_dropped_mmu_fault_pending_f() | + fifo_intr_0_mmu_fault_pending_f() | + fifo_intr_0_lb_error_pending_f() | + fifo_intr_0_pio_error_pending_f(); + + return intr_0_error_mask; +} + +static u32 gk20a_fifo_intr_0_en_mask(struct gk20a *g) +{ + u32 intr_0_en_mask; + + intr_0_en_mask = g->ops.fifo.intr_0_error_mask(g); + + intr_0_en_mask |= fifo_intr_0_runlist_event_pending_f() | + fifo_intr_0_pbdma_intr_pending_f(); + + return intr_0_en_mask; +} + +int gk20a_init_fifo_reset_enable_hw(struct gk20a *g) +{ + u32 intr_stall; + u32 mask; + u32 timeout; + unsigned int i; + u32 host_num_pbdma = nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_PBDMA); + + nvgpu_log_fn(g, " "); + + /* enable pmc pfifo */ + g->ops.mc.reset(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_FIFO)); + + nvgpu_cg_slcg_fifo_load_enable(g); + + nvgpu_cg_blcg_fifo_load_enable(g); + + timeout = gk20a_readl(g, fifo_fb_timeout_r()); + timeout = set_field(timeout, fifo_fb_timeout_period_m(), + fifo_fb_timeout_period_max_f()); + nvgpu_log_info(g, "fifo_fb_timeout reg val = 0x%08x", timeout); + gk20a_writel(g, fifo_fb_timeout_r(), timeout); + + /* write pbdma timeout value */ + for (i = 0; i < host_num_pbdma; i++) { + timeout = gk20a_readl(g, pbdma_timeout_r(i)); + timeout = set_field(timeout, pbdma_timeout_period_m(), + pbdma_timeout_period_max_f()); + nvgpu_log_info(g, "pbdma_timeout reg val = 0x%08x", timeout); + gk20a_writel(g, pbdma_timeout_r(i), timeout); + } + if (g->ops.fifo.apply_pb_timeout) { + g->ops.fifo.apply_pb_timeout(g); + } + + if (g->ops.fifo.apply_ctxsw_timeout_intr) { + g->ops.fifo.apply_ctxsw_timeout_intr(g); + } else { + timeout = g->fifo_eng_timeout_us; + timeout = scale_ptimer(timeout, + ptimer_scalingfactor10x(g->ptimer_src_freq)); + timeout |= fifo_eng_timeout_detection_enabled_f(); + gk20a_writel(g, fifo_eng_timeout_r(), timeout); + } + + /* clear and enable pbdma interrupt */ + for (i = 0; i < host_num_pbdma; i++) { + gk20a_writel(g, pbdma_intr_0_r(i), 0xFFFFFFFF); + gk20a_writel(g, pbdma_intr_1_r(i), 0xFFFFFFFF); + + intr_stall = gk20a_readl(g, pbdma_intr_stall_r(i)); + intr_stall &= ~pbdma_intr_stall_lbreq_enabled_f(); + gk20a_writel(g, pbdma_intr_stall_r(i), intr_stall); + nvgpu_log_info(g, "pbdma id:%u, intr_en_0 0x%08x", i, intr_stall); + gk20a_writel(g, pbdma_intr_en_0_r(i), intr_stall); + intr_stall = gk20a_readl(g, pbdma_intr_stall_1_r(i)); + /* + * For bug 2082123 + * Mask the unused HCE_RE_ILLEGAL_OP bit from the interrupt. + */ + intr_stall &= ~pbdma_intr_stall_1_hce_illegal_op_enabled_f(); + nvgpu_log_info(g, "pbdma id:%u, intr_en_1 0x%08x", i, intr_stall); + gk20a_writel(g, pbdma_intr_en_1_r(i), intr_stall); + } + + /* reset runlist interrupts */ + gk20a_writel(g, fifo_intr_runlist_r(), ~0); + + /* clear and enable pfifo interrupt */ + gk20a_writel(g, fifo_intr_0_r(), 0xFFFFFFFF); + mask = gk20a_fifo_intr_0_en_mask(g); + nvgpu_log_info(g, "fifo_intr_en_0 0x%08x", mask); + gk20a_writel(g, fifo_intr_en_0_r(), mask); + nvgpu_log_info(g, "fifo_intr_en_1 = 0x80000000"); + gk20a_writel(g, fifo_intr_en_1_r(), 0x80000000); + + nvgpu_log_fn(g, "done"); + + return 0; +} + +int gk20a_init_fifo_setup_sw_common(struct gk20a *g) +{ + struct fifo_gk20a *f = &g->fifo; + unsigned int chid, i; + int err = 0; + + nvgpu_log_fn(g, " "); + + f->g = g; + + err = nvgpu_mutex_init(&f->intr.isr.mutex); + if (err) { + nvgpu_err(g, "failed to init isr.mutex"); + return err; + } + + err = nvgpu_mutex_init(&f->engines_reset_mutex); + if (err) { + nvgpu_err(g, "failed to init engines_reset_mutex"); + return err; + } + + g->ops.fifo.init_pbdma_intr_descs(f); /* just filling in data/tables */ + + f->num_channels = g->ops.fifo.get_num_fifos(g); + f->runlist_entry_size = g->ops.fifo.runlist_entry_size(); + f->num_runlist_entries = fifo_eng_runlist_length_max_v(); + f->num_pbdma = nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_PBDMA); + f->max_engines = nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_ENGINES); + + f->userd_entry_size = 1 << ram_userd_base_shift_v(); + + f->channel = nvgpu_vzalloc(g, f->num_channels * sizeof(*f->channel)); + f->tsg = nvgpu_vzalloc(g, f->num_channels * sizeof(*f->tsg)); + f->pbdma_map = nvgpu_kzalloc(g, f->num_pbdma * sizeof(*f->pbdma_map)); + f->engine_info = nvgpu_kzalloc(g, f->max_engines * + sizeof(*f->engine_info)); + f->active_engines_list = nvgpu_kzalloc(g, f->max_engines * sizeof(u32)); + + if (!(f->channel && f->tsg && f->pbdma_map && f->engine_info && + f->active_engines_list)) { + err = -ENOMEM; + goto clean_up; + } + memset(f->active_engines_list, 0xff, (f->max_engines * sizeof(u32))); + + /* pbdma map needs to be in place before calling engine info init */ + for (i = 0; i < f->num_pbdma; ++i) { + f->pbdma_map[i] = gk20a_readl(g, fifo_pbdma_map_r(i)); + } + + g->ops.fifo.init_engine_info(f); + + err = init_runlist(g, f); + if (err) { + nvgpu_err(g, "failed to init runlist"); + goto clean_up; + } + + nvgpu_init_list_node(&f->free_chs); + + err = nvgpu_mutex_init(&f->free_chs_mutex); + if (err) { + nvgpu_err(g, "failed to init free_chs_mutex"); + goto clean_up; + } + + for (chid = 0; chid < f->num_channels; chid++) { + gk20a_init_channel_support(g, chid); + gk20a_init_tsg_support(g, chid); + } + + err = nvgpu_mutex_init(&f->tsg_inuse_mutex); + if (err) { + nvgpu_err(g, "failed to init tsg_inuse_mutex"); + goto clean_up; + } + + f->remove_support = gk20a_remove_fifo_support; + + f->deferred_reset_pending = false; + + err = nvgpu_mutex_init(&f->deferred_reset_mutex); + if (err) { + nvgpu_err(g, "failed to init deferred_reset_mutex"); + goto clean_up; + } + + nvgpu_log_fn(g, "done"); + return 0; + +clean_up: + nvgpu_err(g, "fail"); + + nvgpu_vfree(g, f->channel); + f->channel = NULL; + nvgpu_vfree(g, f->tsg); + f->tsg = NULL; + nvgpu_kfree(g, f->pbdma_map); + f->pbdma_map = NULL; + nvgpu_kfree(g, f->engine_info); + f->engine_info = NULL; + nvgpu_kfree(g, f->active_engines_list); + f->active_engines_list = NULL; + + return err; +} + +int gk20a_init_fifo_setup_sw(struct gk20a *g) +{ + struct fifo_gk20a *f = &g->fifo; + unsigned int chid; + u64 userd_base; + int err = 0; + + nvgpu_log_fn(g, " "); + + if (f->sw_ready) { + nvgpu_log_fn(g, "skip init"); + return 0; + } + + err = gk20a_init_fifo_setup_sw_common(g); + if (err) { + nvgpu_err(g, "fail: err: %d", err); + return err; + } + + if (g->ops.mm.is_bar1_supported(g)) { + err = nvgpu_dma_alloc_map_sys(g->mm.bar1.vm, + f->userd_entry_size * f->num_channels, + &f->userd); + } else { + err = nvgpu_dma_alloc_sys(g, f->userd_entry_size * + f->num_channels, &f->userd); + } + if (err) { + nvgpu_err(g, "userd memory allocation failed"); + goto clean_up; + } + nvgpu_log(g, gpu_dbg_map, "userd gpu va = 0x%llx", f->userd.gpu_va); + + userd_base = nvgpu_mem_get_addr(g, &f->userd); + for (chid = 0; chid < f->num_channels; chid++) { + f->channel[chid].userd_iova = userd_base + + chid * f->userd_entry_size; + f->channel[chid].userd_gpu_va = + f->userd.gpu_va + chid * f->userd_entry_size; + } + + err = nvgpu_channel_worker_init(g); + if (err) { + goto clean_up; + } + + f->sw_ready = true; + + nvgpu_log_fn(g, "done"); + return 0; + +clean_up: + nvgpu_log_fn(g, "fail"); + if (nvgpu_mem_is_valid(&f->userd)) { + if (g->ops.mm.is_bar1_supported(g)) { + nvgpu_dma_unmap_free(g->mm.bar1.vm, &f->userd); + } else { + nvgpu_dma_free(g, &f->userd); + } + } + + return err; +} + +void gk20a_fifo_handle_runlist_event(struct gk20a *g) +{ + u32 runlist_event = gk20a_readl(g, fifo_intr_runlist_r()); + + nvgpu_log(g, gpu_dbg_intr, "runlist event %08x", + runlist_event); + + gk20a_writel(g, fifo_intr_runlist_r(), runlist_event); +} + +int gk20a_init_fifo_setup_hw(struct gk20a *g) +{ + struct fifo_gk20a *f = &g->fifo; + + nvgpu_log_fn(g, " "); + + /* test write, read through bar1 @ userd region before + * turning on the snooping */ + { + struct fifo_gk20a *f = &g->fifo; + u32 v, v1 = 0x33, v2 = 0x55; + + u32 bar1_vaddr = f->userd.gpu_va; + volatile u32 *cpu_vaddr = f->userd.cpu_va; + + nvgpu_log_info(g, "test bar1 @ vaddr 0x%x", + bar1_vaddr); + + v = gk20a_bar1_readl(g, bar1_vaddr); + + *cpu_vaddr = v1; + nvgpu_mb(); + + if (v1 != gk20a_bar1_readl(g, bar1_vaddr)) { + nvgpu_err(g, "bar1 broken @ gk20a: CPU wrote 0x%x, \ + GPU read 0x%x", *cpu_vaddr, gk20a_bar1_readl(g, bar1_vaddr)); + return -EINVAL; + } + + gk20a_bar1_writel(g, bar1_vaddr, v2); + + if (v2 != gk20a_bar1_readl(g, bar1_vaddr)) { + nvgpu_err(g, "bar1 broken @ gk20a: GPU wrote 0x%x, \ + CPU read 0x%x", gk20a_bar1_readl(g, bar1_vaddr), *cpu_vaddr); + return -EINVAL; + } + + /* is it visible to the cpu? */ + if (*cpu_vaddr != v2) { + nvgpu_err(g, + "cpu didn't see bar1 write @ %p!", + cpu_vaddr); + } + + /* put it back */ + gk20a_bar1_writel(g, bar1_vaddr, v); + } + + /*XXX all manner of flushes and caching worries, etc */ + + /* set the base for the userd region now */ + gk20a_writel(g, fifo_bar1_base_r(), + fifo_bar1_base_ptr_f(f->userd.gpu_va >> 12) | + fifo_bar1_base_valid_true_f()); + + nvgpu_log_fn(g, "done"); + + return 0; +} + +int gk20a_init_fifo_support(struct gk20a *g) +{ + u32 err; + + err = g->ops.fifo.setup_sw(g); + if (err) { + return err; + } + + if (g->ops.fifo.init_fifo_setup_hw) { + err = g->ops.fifo.init_fifo_setup_hw(g); + } + if (err) { + return err; + } + + return err; +} + +/* return with a reference to the channel, caller must put it back */ +struct channel_gk20a * +gk20a_refch_from_inst_ptr(struct gk20a *g, u64 inst_ptr) +{ + struct fifo_gk20a *f = &g->fifo; + unsigned int ci; + if (unlikely(!f->channel)) { + return NULL; + } + for (ci = 0; ci < f->num_channels; ci++) { + struct channel_gk20a *ch; + u64 ch_inst_ptr; + + ch = gk20a_channel_from_id(g, ci); + /* only alive channels are searched */ + if (!ch) { + continue; + } + + ch_inst_ptr = nvgpu_inst_block_addr(g, &ch->inst_block); + if (inst_ptr == ch_inst_ptr) { + return ch; + } + + gk20a_channel_put(ch); + } + return NULL; +} + +/* fault info/descriptions. + * tbd: move to setup + * */ +static const char * const gk20a_fault_type_descs[] = { + "pde", /*fifo_intr_mmu_fault_info_type_pde_v() == 0 */ + "pde size", + "pte", + "va limit viol", + "unbound inst", + "priv viol", + "ro viol", + "wo viol", + "pitch mask", + "work creation", + "bad aperture", + "compression failure", + "bad kind", + "region viol", + "dual ptes", + "poisoned", +}; +/* engine descriptions */ +static const char * const engine_subid_descs[] = { + "gpc", + "hub", +}; + +static const char * const gk20a_hub_client_descs[] = { + "vip", "ce0", "ce1", "dniso", "fe", "fecs", "host", "host cpu", + "host cpu nb", "iso", "mmu", "mspdec", "msppp", "msvld", + "niso", "p2p", "pd", "perf", "pmu", "raster twod", "scc", + "scc nb", "sec", "ssync", "gr copy", "xv", "mmu nb", + "msenc", "d falcon", "sked", "a falcon", "n/a", +}; + +static const char * const gk20a_gpc_client_descs[] = { + "l1 0", "t1 0", "pe 0", + "l1 1", "t1 1", "pe 1", + "l1 2", "t1 2", "pe 2", + "l1 3", "t1 3", "pe 3", + "rast", "gcc", "gpccs", + "prop 0", "prop 1", "prop 2", "prop 3", + "l1 4", "t1 4", "pe 4", + "l1 5", "t1 5", "pe 5", + "l1 6", "t1 6", "pe 6", + "l1 7", "t1 7", "pe 7", +}; + +static const char * const does_not_exist[] = { + "does not exist" +}; + +/* fill in mmu fault desc */ +void gk20a_fifo_get_mmu_fault_desc(struct mmu_fault_info *mmfault) +{ + if (mmfault->fault_type >= ARRAY_SIZE(gk20a_fault_type_descs)) { + WARN_ON(mmfault->fault_type >= + ARRAY_SIZE(gk20a_fault_type_descs)); + } else { + mmfault->fault_type_desc = + gk20a_fault_type_descs[mmfault->fault_type]; + } +} + +/* fill in mmu fault client description */ +void gk20a_fifo_get_mmu_fault_client_desc(struct mmu_fault_info *mmfault) +{ + if (mmfault->client_id >= ARRAY_SIZE(gk20a_hub_client_descs)) { + WARN_ON(mmfault->client_id >= + ARRAY_SIZE(gk20a_hub_client_descs)); + } else { + mmfault->client_id_desc = + gk20a_hub_client_descs[mmfault->client_id]; + } +} + +/* fill in mmu fault gpc description */ +void gk20a_fifo_get_mmu_fault_gpc_desc(struct mmu_fault_info *mmfault) +{ + if (mmfault->client_id >= ARRAY_SIZE(gk20a_gpc_client_descs)) { + WARN_ON(mmfault->client_id >= + ARRAY_SIZE(gk20a_gpc_client_descs)); + } else { + mmfault->client_id_desc = + gk20a_gpc_client_descs[mmfault->client_id]; + } +} + +static void get_exception_mmu_fault_info(struct gk20a *g, u32 mmu_fault_id, + struct mmu_fault_info *mmfault) +{ + g->ops.fifo.get_mmu_fault_info(g, mmu_fault_id, mmfault); + + /* parse info */ + mmfault->fault_type_desc = does_not_exist[0]; + if (g->ops.fifo.get_mmu_fault_desc) { + g->ops.fifo.get_mmu_fault_desc(mmfault); + } + + if (mmfault->client_type >= ARRAY_SIZE(engine_subid_descs)) { + WARN_ON(mmfault->client_type >= ARRAY_SIZE(engine_subid_descs)); + mmfault->client_type_desc = does_not_exist[0]; + } else { + mmfault->client_type_desc = + engine_subid_descs[mmfault->client_type]; + } + + mmfault->client_id_desc = does_not_exist[0]; + if ((mmfault->client_type == + fifo_intr_mmu_fault_info_engine_subid_hub_v()) + && g->ops.fifo.get_mmu_fault_client_desc) { + g->ops.fifo.get_mmu_fault_client_desc(mmfault); + } else if ((mmfault->client_type == + fifo_intr_mmu_fault_info_engine_subid_gpc_v()) + && g->ops.fifo.get_mmu_fault_gpc_desc) { + g->ops.fifo.get_mmu_fault_gpc_desc(mmfault); + } +} + +/* reads info from hardware and fills in mmu fault info record */ +void gk20a_fifo_get_mmu_fault_info(struct gk20a *g, u32 mmu_fault_id, + struct mmu_fault_info *mmfault) +{ + u32 fault_info; + u32 addr_lo, addr_hi; + + nvgpu_log_fn(g, "mmu_fault_id %d", mmu_fault_id); + + memset(mmfault, 0, sizeof(*mmfault)); + + fault_info = gk20a_readl(g, + fifo_intr_mmu_fault_info_r(mmu_fault_id)); + mmfault->fault_type = + fifo_intr_mmu_fault_info_type_v(fault_info); + mmfault->access_type = + fifo_intr_mmu_fault_info_write_v(fault_info); + mmfault->client_type = + fifo_intr_mmu_fault_info_engine_subid_v(fault_info); + mmfault->client_id = + fifo_intr_mmu_fault_info_client_v(fault_info); + + addr_lo = gk20a_readl(g, fifo_intr_mmu_fault_lo_r(mmu_fault_id)); + addr_hi = gk20a_readl(g, fifo_intr_mmu_fault_hi_r(mmu_fault_id)); + mmfault->fault_addr = hi32_lo32_to_u64(addr_hi, addr_lo); + /* note:ignoring aperture on gk20a... */ + mmfault->inst_ptr = fifo_intr_mmu_fault_inst_ptr_v( + gk20a_readl(g, fifo_intr_mmu_fault_inst_r(mmu_fault_id))); + /* note: inst_ptr is a 40b phys addr. */ + mmfault->inst_ptr <<= fifo_intr_mmu_fault_inst_ptr_align_shift_v(); +} + +void gk20a_fifo_reset_engine(struct gk20a *g, u32 engine_id) +{ + u32 engine_enum = ENGINE_INVAL_GK20A; + struct fifo_engine_info_gk20a *engine_info; + + nvgpu_log_fn(g, " "); + + if (!g) { + return; + } + + engine_info = gk20a_fifo_get_engine_info(g, engine_id); + + if (engine_info) { + engine_enum = engine_info->engine_enum; + } + + if (engine_enum == ENGINE_INVAL_GK20A) { + nvgpu_err(g, "unsupported engine_id %d", engine_id); + } + + if (engine_enum == ENGINE_GR_GK20A) { + if (g->support_pmu) { + if (nvgpu_pg_elpg_disable(g) != 0 ) { + nvgpu_err(g, "failed to set disable elpg"); + } + } + +#ifdef CONFIG_GK20A_CTXSW_TRACE + /* + * Resetting engine will alter read/write index. Need to flush + * circular buffer before re-enabling FECS. + */ + if (g->ops.fecs_trace.reset) + g->ops.fecs_trace.reset(g); +#endif + if (!nvgpu_platform_is_simulation(g)) { + /*HALT_PIPELINE method, halt GR engine*/ + if (gr_gk20a_halt_pipe(g)) { + nvgpu_err(g, "failed to HALT gr pipe"); + } + /* + * resetting engine using mc_enable_r() is not + * enough, we do full init sequence + */ + nvgpu_log(g, gpu_dbg_info, "resetting gr engine"); + gk20a_gr_reset(g); + } else { + nvgpu_log(g, gpu_dbg_info, + "HALT gr pipe not supported and " + "gr cannot be reset without halting gr pipe"); + } + if (g->support_pmu) { + if (nvgpu_pg_elpg_enable(g) != 0 ) { + nvgpu_err(g, "failed to set enable elpg"); + } + } + } + if ((engine_enum == ENGINE_GRCE_GK20A) || + (engine_enum == ENGINE_ASYNC_CE_GK20A)) { + g->ops.mc.reset(g, engine_info->reset_mask); + } +} + +static void gk20a_fifo_handle_chsw_fault(struct gk20a *g) +{ + u32 intr; + + intr = gk20a_readl(g, fifo_intr_chsw_error_r()); + nvgpu_err(g, "chsw: %08x", intr); + gk20a_fecs_dump_falcon_stats(g); + gk20a_writel(g, fifo_intr_chsw_error_r(), intr); +} + +static void gk20a_fifo_handle_dropped_mmu_fault(struct gk20a *g) +{ + u32 fault_id = gk20a_readl(g, fifo_intr_mmu_fault_id_r()); + nvgpu_err(g, "dropped mmu fault (0x%08x)", fault_id); +} + +bool gk20a_is_fault_engine_subid_gpc(struct gk20a *g, u32 engine_subid) +{ + return (engine_subid == fifo_intr_mmu_fault_info_engine_subid_gpc_v()); +} + +bool gk20a_fifo_should_defer_engine_reset(struct gk20a *g, u32 engine_id, + u32 engine_subid, bool fake_fault) +{ + u32 engine_enum = ENGINE_INVAL_GK20A; + struct fifo_engine_info_gk20a *engine_info; + + if (!g) { + return false; + } + + engine_info = gk20a_fifo_get_engine_info(g, engine_id); + + if (engine_info) { + engine_enum = engine_info->engine_enum; + } + + if (engine_enum == ENGINE_INVAL_GK20A) { + return false; + } + + /* channel recovery is only deferred if an sm debugger + is attached and has MMU debug mode is enabled */ + if (!g->ops.gr.sm_debugger_attached(g) || + !g->ops.fb.is_debug_mode_enabled(g)) { + return false; + } + + /* if this fault is fake (due to RC recovery), don't defer recovery */ + if (fake_fault) { + return false; + } + + if (engine_enum != ENGINE_GR_GK20A) { + return false; + } + + return g->ops.fifo.is_fault_engine_subid_gpc(g, engine_subid); +} + +/* caller must hold a channel reference */ +static bool gk20a_fifo_ch_timeout_debug_dump_state(struct gk20a *g, + struct channel_gk20a *refch) +{ + bool verbose = false; + if (!refch) { + return verbose; + } + + if (nvgpu_is_error_notifier_set(refch, + NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT)) { + verbose = refch->timeout_debug_dump; + } + + return verbose; +} + +/* caller must hold a channel reference */ +static void gk20a_fifo_set_has_timedout_and_wake_up_wqs(struct gk20a *g, + struct channel_gk20a *refch) +{ + if (refch) { + /* mark channel as faulted */ + gk20a_channel_set_timedout(refch); + + /* unblock pending waits */ + nvgpu_cond_broadcast_interruptible(&refch->semaphore_wq); + nvgpu_cond_broadcast_interruptible(&refch->notifier_wq); + } +} + +/* caller must hold a channel reference */ +bool gk20a_fifo_error_ch(struct gk20a *g, + struct channel_gk20a *refch) +{ + bool verbose; + + verbose = gk20a_fifo_ch_timeout_debug_dump_state(g, refch); + gk20a_fifo_set_has_timedout_and_wake_up_wqs(g, refch); + + return verbose; +} + +bool gk20a_fifo_error_tsg(struct gk20a *g, + struct tsg_gk20a *tsg) +{ + struct channel_gk20a *ch = NULL; + bool verbose = false; + + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + nvgpu_list_for_each_entry(ch, &tsg->ch_list, channel_gk20a, ch_entry) { + if (gk20a_channel_get(ch)) { + if (gk20a_fifo_error_ch(g, ch)) { + verbose = true; + } + gk20a_channel_put(ch); + } + } + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + + return verbose; + +} +/* caller must hold a channel reference */ +void gk20a_fifo_set_ctx_mmu_error_ch(struct gk20a *g, + struct channel_gk20a *refch) +{ + nvgpu_err(g, + "channel %d generated a mmu fault", refch->chid); + g->ops.fifo.set_error_notifier(refch, + NVGPU_ERR_NOTIFIER_FIFO_ERROR_MMU_ERR_FLT); +} + +void gk20a_fifo_set_ctx_mmu_error_tsg(struct gk20a *g, + struct tsg_gk20a *tsg) +{ + struct channel_gk20a *ch = NULL; + + nvgpu_err(g, + "TSG %d generated a mmu fault", tsg->tsgid); + + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + nvgpu_list_for_each_entry(ch, &tsg->ch_list, channel_gk20a, ch_entry) { + if (gk20a_channel_get(ch)) { + gk20a_fifo_set_ctx_mmu_error_ch(g, ch); + gk20a_channel_put(ch); + } + } + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + +} + +void gk20a_fifo_abort_tsg(struct gk20a *g, struct tsg_gk20a *tsg, bool preempt) +{ + struct channel_gk20a *ch = NULL; + + nvgpu_log_fn(g, " "); + + g->ops.fifo.disable_tsg(tsg); + + if (preempt) { + g->ops.fifo.preempt_tsg(g, tsg); + } + + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + nvgpu_list_for_each_entry(ch, &tsg->ch_list, channel_gk20a, ch_entry) { + if (gk20a_channel_get(ch)) { + gk20a_channel_set_timedout(ch); + if (ch->g->ops.fifo.ch_abort_clean_up) { + ch->g->ops.fifo.ch_abort_clean_up(ch); + } + gk20a_channel_put(ch); + } + } + nvgpu_rwsem_up_read(&tsg->ch_list_lock); +} + +int gk20a_fifo_deferred_reset(struct gk20a *g, struct channel_gk20a *ch) +{ + unsigned long engine_id, engines = 0U; + struct tsg_gk20a *tsg; + bool deferred_reset_pending; + struct fifo_gk20a *f = &g->fifo; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + nvgpu_mutex_acquire(&f->deferred_reset_mutex); + deferred_reset_pending = g->fifo.deferred_reset_pending; + nvgpu_mutex_release(&f->deferred_reset_mutex); + + if (!deferred_reset_pending) { + nvgpu_mutex_release(&g->dbg_sessions_lock); + return 0; + } + + gr_gk20a_disable_ctxsw(g); + + tsg = tsg_gk20a_from_ch(ch); + if (tsg != NULL) { + engines = gk20a_fifo_engines_on_id(g, tsg->tsgid, true); + } else { + nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); + } + + if (engines == 0U) { + goto clean_up; + } + + /* + * If deferred reset is set for an engine, and channel is running + * on that engine, reset it + */ + for_each_set_bit(engine_id, &g->fifo.deferred_fault_engines, 32) { + if (BIT(engine_id) & engines) { + gk20a_fifo_reset_engine(g, engine_id); + } + } + + nvgpu_mutex_acquire(&f->deferred_reset_mutex); + g->fifo.deferred_fault_engines = 0; + g->fifo.deferred_reset_pending = false; + nvgpu_mutex_release(&f->deferred_reset_mutex); + +clean_up: + gr_gk20a_enable_ctxsw(g); + nvgpu_mutex_release(&g->dbg_sessions_lock); + + return 0; +} + +static bool gk20a_fifo_handle_mmu_fault_locked( + struct gk20a *g, + u32 mmu_fault_engines, /* queried from HW if 0 */ + u32 hw_id, /* queried from HW if ~(u32)0 OR mmu_fault_engines == 0*/ + bool id_is_tsg) +{ + bool fake_fault; + unsigned long fault_id; + unsigned long engine_mmu_fault_id; + bool verbose = true; + u32 grfifo_ctl; + + bool deferred_reset_pending = false; + struct fifo_gk20a *f = &g->fifo; + + nvgpu_log_fn(g, " "); + + /* Disable power management */ + if (g->support_pmu) { + if (nvgpu_cg_pg_disable(g) != 0) { + nvgpu_warn(g, "fail to disable power mgmt"); + } + } + + /* Disable fifo access */ + grfifo_ctl = gk20a_readl(g, gr_gpfifo_ctl_r()); + grfifo_ctl &= ~gr_gpfifo_ctl_semaphore_access_f(1); + grfifo_ctl &= ~gr_gpfifo_ctl_access_f(1); + + gk20a_writel(g, gr_gpfifo_ctl_r(), + grfifo_ctl | gr_gpfifo_ctl_access_f(0) | + gr_gpfifo_ctl_semaphore_access_f(0)); + + if (mmu_fault_engines) { + fault_id = mmu_fault_engines; + fake_fault = true; + } else { + fault_id = gk20a_readl(g, fifo_intr_mmu_fault_id_r()); + fake_fault = false; + gk20a_debug_dump(g); + } + + nvgpu_mutex_acquire(&f->deferred_reset_mutex); + g->fifo.deferred_reset_pending = false; + nvgpu_mutex_release(&f->deferred_reset_mutex); + + /* go through all faulted engines */ + for_each_set_bit(engine_mmu_fault_id, &fault_id, 32) { + /* bits in fifo_intr_mmu_fault_id_r do not correspond 1:1 to + * engines. Convert engine_mmu_id to engine_id */ + u32 engine_id = gk20a_mmu_id_to_engine_id(g, + engine_mmu_fault_id); + struct mmu_fault_info mmfault_info; + struct channel_gk20a *ch = NULL; + struct tsg_gk20a *tsg = NULL; + struct channel_gk20a *refch = NULL; + /* read and parse engine status */ + u32 status = gk20a_readl(g, fifo_engine_status_r(engine_id)); + u32 ctx_status = fifo_engine_status_ctx_status_v(status); + bool ctxsw = (ctx_status == + fifo_engine_status_ctx_status_ctxsw_switch_v() + || ctx_status == + fifo_engine_status_ctx_status_ctxsw_save_v() + || ctx_status == + fifo_engine_status_ctx_status_ctxsw_load_v()); + + get_exception_mmu_fault_info(g, engine_mmu_fault_id, + &mmfault_info); + trace_gk20a_mmu_fault(mmfault_info.fault_addr, + mmfault_info.fault_type, + mmfault_info.access_type, + mmfault_info.inst_ptr, + engine_id, + mmfault_info.client_type_desc, + mmfault_info.client_id_desc, + mmfault_info.fault_type_desc); + nvgpu_err(g, "%s mmu fault on engine %d, " + "engine subid %d (%s), client %d (%s), " + "addr 0x%llx, type %d (%s), access_type 0x%08x," + "inst_ptr 0x%llx", + fake_fault ? "fake" : "", + engine_id, + mmfault_info.client_type, + mmfault_info.client_type_desc, + mmfault_info.client_id, mmfault_info.client_id_desc, + mmfault_info.fault_addr, + mmfault_info.fault_type, + mmfault_info.fault_type_desc, + mmfault_info.access_type, mmfault_info.inst_ptr); + + if (ctxsw) { + gk20a_fecs_dump_falcon_stats(g); + nvgpu_err(g, "gr_status_r : 0x%x", + gk20a_readl(g, gr_status_r())); + } + + /* get the channel/TSG */ + if (fake_fault) { + /* use next_id if context load is failing */ + u32 id, type; + + if (hw_id == ~(u32)0) { + id = (ctx_status == + fifo_engine_status_ctx_status_ctxsw_load_v()) ? + fifo_engine_status_next_id_v(status) : + fifo_engine_status_id_v(status); + type = (ctx_status == + fifo_engine_status_ctx_status_ctxsw_load_v()) ? + fifo_engine_status_next_id_type_v(status) : + fifo_engine_status_id_type_v(status); + } else { + id = hw_id; + type = id_is_tsg ? + fifo_engine_status_id_type_tsgid_v() : + fifo_engine_status_id_type_chid_v(); + } + + if (type == fifo_engine_status_id_type_tsgid_v()) { + tsg = &g->fifo.tsg[id]; + } else if (type == fifo_engine_status_id_type_chid_v()) { + ch = &g->fifo.channel[id]; + refch = gk20a_channel_get(ch); + if (refch != NULL) { + tsg = tsg_gk20a_from_ch(refch); + } + } + } else { + /* read channel based on instruction pointer */ + ch = gk20a_refch_from_inst_ptr(g, + mmfault_info.inst_ptr); + refch = ch; + if (refch != NULL) { + tsg = tsg_gk20a_from_ch(refch); + } + } + + /* check if engine reset should be deferred */ + if (engine_id != FIFO_INVAL_ENGINE_ID) { + bool defer = gk20a_fifo_should_defer_engine_reset(g, + engine_id, mmfault_info.client_type, + fake_fault); + if ((ch || tsg) && defer) { + g->fifo.deferred_fault_engines |= BIT(engine_id); + + /* handled during channel free */ + nvgpu_mutex_acquire(&f->deferred_reset_mutex); + g->fifo.deferred_reset_pending = true; + nvgpu_mutex_release(&f->deferred_reset_mutex); + + deferred_reset_pending = true; + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "sm debugger attached," + " deferring channel recovery to channel free"); + } else { + gk20a_fifo_reset_engine(g, engine_id); + } + } + +#ifdef CONFIG_GK20A_CTXSW_TRACE + if (tsg) { + gk20a_ctxsw_trace_tsg_reset(g, tsg); + } +#endif + /* + * Disable the channel/TSG from hw and increment syncpoints. + */ + if (tsg) { + if (deferred_reset_pending) { + gk20a_disable_tsg(tsg); + } else { + if (!fake_fault) { + gk20a_fifo_set_ctx_mmu_error_tsg(g, + tsg); + } + verbose = gk20a_fifo_error_tsg(g, tsg); + gk20a_fifo_abort_tsg(g, tsg, false); + } + + /* put back the ref taken early above */ + if (refch) { + gk20a_channel_put(ch); + } + } else if (refch != NULL) { + nvgpu_err(g, "mmu error in unbound channel %d", + ch->chid); + gk20a_channel_put(ch); + } else if (mmfault_info.inst_ptr == + nvgpu_inst_block_addr(g, &g->mm.bar1.inst_block)) { + nvgpu_err(g, "mmu fault from bar1"); + } else if (mmfault_info.inst_ptr == + nvgpu_inst_block_addr(g, &g->mm.pmu.inst_block)) { + nvgpu_err(g, "mmu fault from pmu"); + } else { + nvgpu_err(g, "couldn't locate channel for mmu fault"); + } + } + + /* clear interrupt */ + gk20a_writel(g, fifo_intr_mmu_fault_id_r(), fault_id); + + /* resume scheduler */ + gk20a_writel(g, fifo_error_sched_disable_r(), + gk20a_readl(g, fifo_error_sched_disable_r())); + + /* Re-enable fifo access */ + gk20a_writel(g, gr_gpfifo_ctl_r(), + gr_gpfifo_ctl_access_enabled_f() | + gr_gpfifo_ctl_semaphore_access_enabled_f()); + + /* It is safe to enable ELPG again. */ + if (g->support_pmu) { + if (nvgpu_cg_pg_enable(g) != 0) { + nvgpu_warn(g, "fail to enable power mgmt"); + } + } + + return verbose; +} + +static bool gk20a_fifo_handle_mmu_fault( + struct gk20a *g, + u32 mmu_fault_engines, /* queried from HW if 0 */ + u32 hw_id, /* queried from HW if ~(u32)0 OR mmu_fault_engines == 0*/ + bool id_is_tsg) +{ + u32 rlid; + bool verbose; + + nvgpu_log_fn(g, " "); + + nvgpu_log_info(g, "acquire engines_reset_mutex"); + nvgpu_mutex_acquire(&g->fifo.engines_reset_mutex); + + nvgpu_log_info(g, "acquire runlist_lock for all runlists"); + for (rlid = 0; rlid < g->fifo.max_runlists; rlid++) { + nvgpu_mutex_acquire(&g->fifo.runlist_info[rlid].runlist_lock); + } + + verbose = gk20a_fifo_handle_mmu_fault_locked(g, mmu_fault_engines, + hw_id, id_is_tsg); + + nvgpu_log_info(g, "release runlist_lock for all runlists"); + for (rlid = 0; rlid < g->fifo.max_runlists; rlid++) { + nvgpu_mutex_release(&g->fifo.runlist_info[rlid].runlist_lock); + } + + nvgpu_log_info(g, "release engines_reset_mutex"); + nvgpu_mutex_release(&g->fifo.engines_reset_mutex); + + return verbose; +} + +static void gk20a_fifo_get_faulty_id_type(struct gk20a *g, int engine_id, + u32 *id, u32 *type) +{ + u32 status = gk20a_readl(g, fifo_engine_status_r(engine_id)); + u32 ctx_status = fifo_engine_status_ctx_status_v(status); + + /* use next_id if context load is failing */ + *id = (ctx_status == + fifo_engine_status_ctx_status_ctxsw_load_v()) ? + fifo_engine_status_next_id_v(status) : + fifo_engine_status_id_v(status); + + *type = (ctx_status == + fifo_engine_status_ctx_status_ctxsw_load_v()) ? + fifo_engine_status_next_id_type_v(status) : + fifo_engine_status_id_type_v(status); +} + +static u32 gk20a_fifo_engines_on_id(struct gk20a *g, u32 id, bool is_tsg) +{ + unsigned int i; + u32 engines = 0; + + for (i = 0; i < g->fifo.num_engines; i++) { + u32 active_engine_id = g->fifo.active_engines_list[i]; + u32 status = gk20a_readl(g, fifo_engine_status_r(active_engine_id)); + u32 ctx_status = + fifo_engine_status_ctx_status_v(status); + u32 ctx_id = (ctx_status == + fifo_engine_status_ctx_status_ctxsw_load_v()) ? + fifo_engine_status_next_id_v(status) : + fifo_engine_status_id_v(status); + u32 type = (ctx_status == + fifo_engine_status_ctx_status_ctxsw_load_v()) ? + fifo_engine_status_next_id_type_v(status) : + fifo_engine_status_id_type_v(status); + bool busy = fifo_engine_status_engine_v(status) == + fifo_engine_status_engine_busy_v(); + if (busy && ctx_id == id) { + if ((is_tsg && type == + fifo_engine_status_id_type_tsgid_v()) || + (!is_tsg && type == + fifo_engine_status_id_type_chid_v())) { + engines |= BIT(active_engine_id); + } + } + } + + return engines; +} + +void gk20a_fifo_recover_ch(struct gk20a *g, struct channel_gk20a *ch, + bool verbose, u32 rc_type) +{ + u32 engines; + + /* stop context switching to prevent engine assignments from + changing until channel is recovered */ + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + gr_gk20a_disable_ctxsw(g); + + engines = gk20a_fifo_engines_on_id(g, ch->chid, false); + + if (engines) { + gk20a_fifo_recover(g, engines, ch->chid, false, true, verbose, + rc_type); + } else { + gk20a_channel_abort(ch, false); + + if (gk20a_fifo_error_ch(g, ch)) { + gk20a_debug_dump(g); + } + } + + gr_gk20a_enable_ctxsw(g); + nvgpu_mutex_release(&g->dbg_sessions_lock); +} + +void gk20a_fifo_recover_tsg(struct gk20a *g, struct tsg_gk20a *tsg, + bool verbose, u32 rc_type) +{ + u32 engines = 0U; + int err; + + /* stop context switching to prevent engine assignments from + changing until TSG is recovered */ + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + /* disable tsg so that it does not get scheduled again */ + g->ops.fifo.disable_tsg(tsg); + + /* + * On hitting engine reset, h/w drops the ctxsw_status to INVALID in + * fifo_engine_status register. Also while the engine is held in reset + * h/w passes busy/idle straight through. fifo_engine_status registers + * are correct in that there is no context switch outstanding + * as the CTXSW is aborted when reset is asserted. + */ + nvgpu_log_info(g, "acquire engines_reset_mutex"); + nvgpu_mutex_acquire(&g->fifo.engines_reset_mutex); + + /* + * stop context switching to prevent engine assignments from + * changing until engine status is checked to make sure tsg + * being recovered is not loaded on the engines + */ + err = gr_gk20a_disable_ctxsw(g); + + if (err != 0) { + /* if failed to disable ctxsw, just abort tsg */ + nvgpu_err(g, "failed to disable ctxsw"); + } else { + /* recover engines if tsg is loaded on the engines */ + engines = gk20a_fifo_engines_on_id(g, tsg->tsgid, true); + + /* + * it is ok to enable ctxsw before tsg is recovered. If engines + * is 0, no engine recovery is needed and if it is non zero, + * gk20a_fifo_recover will call get_engines_mask_on_id again. + * By that time if tsg is not on the engine, engine need not + * be reset. + */ + err = gr_gk20a_enable_ctxsw(g); + if (err != 0) { + nvgpu_err(g, "failed to enable ctxsw"); + } + } + + nvgpu_log_info(g, "release engines_reset_mutex"); + nvgpu_mutex_release(&g->fifo.engines_reset_mutex); + + if (engines) { + gk20a_fifo_recover(g, engines, tsg->tsgid, true, true, verbose, + rc_type); + } else { + if (gk20a_fifo_error_tsg(g, tsg) && verbose) { + gk20a_debug_dump(g); + } + + gk20a_fifo_abort_tsg(g, tsg, false); + } + + nvgpu_mutex_release(&g->dbg_sessions_lock); +} + +void gk20a_fifo_teardown_mask_intr(struct gk20a *g) +{ + u32 val; + + val = gk20a_readl(g, fifo_intr_en_0_r()); + val &= ~(fifo_intr_en_0_sched_error_m() | + fifo_intr_en_0_mmu_fault_m()); + gk20a_writel(g, fifo_intr_en_0_r(), val); + gk20a_writel(g, fifo_intr_0_r(), fifo_intr_0_sched_error_reset_f()); +} + +void gk20a_fifo_teardown_unmask_intr(struct gk20a *g) +{ + u32 val; + + val = gk20a_readl(g, fifo_intr_en_0_r()); + val |= fifo_intr_en_0_mmu_fault_f(1) | fifo_intr_en_0_sched_error_f(1); + gk20a_writel(g, fifo_intr_en_0_r(), val); + +} + +void gk20a_fifo_teardown_ch_tsg(struct gk20a *g, u32 __engine_ids, + u32 hw_id, unsigned int id_type, unsigned int rc_type, + struct mmu_fault_info *mmfault) +{ + unsigned long engine_id, i; + unsigned long _engine_ids = __engine_ids; + unsigned long engine_ids = 0; + u32 mmu_fault_engines = 0; + u32 ref_type; + u32 ref_id; + u32 ref_id_is_tsg = false; + bool id_is_known = (id_type != ID_TYPE_UNKNOWN) ? true : false; + bool id_is_tsg = (id_type == ID_TYPE_TSG) ? true : false; + u32 rlid; + + nvgpu_log_info(g, "acquire engines_reset_mutex"); + nvgpu_mutex_acquire(&g->fifo.engines_reset_mutex); + + nvgpu_log_info(g, "acquire runlist_lock for all runlists"); + for (rlid = 0; rlid < g->fifo.max_runlists; rlid++) { + nvgpu_mutex_acquire(&g->fifo.runlist_info[rlid].runlist_lock); + } + + if (id_is_known) { + engine_ids = gk20a_fifo_engines_on_id(g, hw_id, id_is_tsg); + ref_id = hw_id; + ref_type = id_is_tsg ? + fifo_engine_status_id_type_tsgid_v() : + fifo_engine_status_id_type_chid_v(); + ref_id_is_tsg = id_is_tsg; + /* atleast one engine will get passed during sched err*/ + engine_ids |= __engine_ids; + for_each_set_bit(engine_id, &engine_ids, 32) { + u32 mmu_id = gk20a_engine_id_to_mmu_id(g, engine_id); + + if (mmu_id != FIFO_INVAL_ENGINE_ID) { + mmu_fault_engines |= BIT(mmu_id); + } + } + } else { + /* store faulted engines in advance */ + for_each_set_bit(engine_id, &_engine_ids, 32) { + gk20a_fifo_get_faulty_id_type(g, engine_id, &ref_id, + &ref_type); + if (ref_type == fifo_engine_status_id_type_tsgid_v()) { + ref_id_is_tsg = true; + } else { + ref_id_is_tsg = false; + } + /* Reset *all* engines that use the + * same channel as faulty engine */ + for (i = 0; i < g->fifo.num_engines; i++) { + u32 active_engine_id = g->fifo.active_engines_list[i]; + u32 type; + u32 id; + + gk20a_fifo_get_faulty_id_type(g, active_engine_id, &id, &type); + if (ref_type == type && ref_id == id) { + u32 mmu_id = gk20a_engine_id_to_mmu_id(g, active_engine_id); + + engine_ids |= BIT(active_engine_id); + if (mmu_id != FIFO_INVAL_ENGINE_ID) { + mmu_fault_engines |= BIT(mmu_id); + } + } + } + } + } + + if (mmu_fault_engines) { + g->ops.fifo.teardown_mask_intr(g); + g->ops.fifo.trigger_mmu_fault(g, engine_ids); + gk20a_fifo_handle_mmu_fault_locked(g, mmu_fault_engines, ref_id, + ref_id_is_tsg); + + g->ops.fifo.teardown_unmask_intr(g); + } + + nvgpu_log_info(g, "release runlist_lock for all runlists"); + for (rlid = 0; rlid < g->fifo.max_runlists; rlid++) { + nvgpu_mutex_release(&g->fifo.runlist_info[rlid].runlist_lock); + } + + nvgpu_log_info(g, "release engines_reset_mutex"); + nvgpu_mutex_release(&g->fifo.engines_reset_mutex); +} + +void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids, + u32 hw_id, bool id_is_tsg, + bool id_is_known, bool verbose, int rc_type) +{ + unsigned int id_type; + + if (verbose) { + gk20a_debug_dump(g); + } + + if (g->ops.ltc.flush) { + g->ops.ltc.flush(g); + } + + if (id_is_known) { + id_type = id_is_tsg ? ID_TYPE_TSG : ID_TYPE_CHANNEL; + } else { + id_type = ID_TYPE_UNKNOWN; + } + + g->ops.fifo.teardown_ch_tsg(g, __engine_ids, hw_id, id_type, + rc_type, NULL); +} + +/* force reset channel and tsg */ +int gk20a_fifo_force_reset_ch(struct channel_gk20a *ch, + u32 err_code, bool verbose) +{ + struct channel_gk20a *ch_tsg = NULL; + struct gk20a *g = ch->g; + + struct tsg_gk20a *tsg = tsg_gk20a_from_ch(ch); + + if (tsg != NULL) { + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + + nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list, + channel_gk20a, ch_entry) { + if (gk20a_channel_get(ch_tsg)) { + g->ops.fifo.set_error_notifier(ch_tsg, + err_code); + gk20a_channel_put(ch_tsg); + } + } + + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + gk20a_fifo_recover_tsg(g, tsg, verbose, + RC_TYPE_FORCE_RESET); + } else { + nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); + } + + return 0; +} + +int gk20a_fifo_tsg_unbind_channel_verify_status(struct channel_gk20a *ch) +{ + struct gk20a *g = ch->g; + + if (gk20a_fifo_channel_status_is_next(g, ch->chid)) { + nvgpu_err(g, "Channel %d to be removed from TSG %d has NEXT set!", + ch->chid, ch->tsgid); + return -EINVAL; + } + + if (g->ops.fifo.tsg_verify_status_ctx_reload) { + g->ops.fifo.tsg_verify_status_ctx_reload(ch); + } + + if (g->ops.fifo.tsg_verify_status_faulted) { + g->ops.fifo.tsg_verify_status_faulted(ch); + } + + return 0; +} + +static bool gk20a_fifo_tsg_is_multi_channel(struct tsg_gk20a *tsg) +{ + bool ret = false; + + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + if (nvgpu_list_first_entry(&tsg->ch_list, channel_gk20a, + ch_entry) != + nvgpu_list_last_entry(&tsg->ch_list, channel_gk20a, + ch_entry)) { + ret = true; + } + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + + return ret; +} + +int gk20a_fifo_tsg_unbind_channel(struct channel_gk20a *ch) +{ + struct gk20a *g = ch->g; + struct tsg_gk20a *tsg = tsg_gk20a_from_ch(ch); + int err; + bool tsg_timedout = false; + + if (tsg == NULL) { + nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); + return 0; + } + + /* If one channel in TSG times out, we disable all channels */ + nvgpu_rwsem_down_write(&tsg->ch_list_lock); + tsg_timedout = gk20a_channel_check_timedout(ch); + nvgpu_rwsem_up_write(&tsg->ch_list_lock); + + /* Disable TSG and examine status before unbinding channel */ + g->ops.fifo.disable_tsg(tsg); + + err = g->ops.fifo.preempt_tsg(g, tsg); + if (err != 0) { + goto fail_enable_tsg; + } + + /* + * State validation is only necessary if there are multiple channels in + * the TSG. + */ + if (gk20a_fifo_tsg_is_multi_channel(tsg) && + g->ops.fifo.tsg_verify_channel_status && !tsg_timedout) { + err = g->ops.fifo.tsg_verify_channel_status(ch); + if (err) { + goto fail_enable_tsg; + } + } + + /* Channel should be seen as TSG channel while updating runlist */ + err = channel_gk20a_update_runlist(ch, false); + if (err) { + goto fail_enable_tsg; + } + + while (ch->mmu_debug_mode_refcnt > 0U) { + err = nvgpu_tsg_set_mmu_debug_mode(ch, false); + if (err != 0) { + nvgpu_err(g, "disable mmu debug mode failed ch:%u", + ch->chid); + break; + } + } + + /* Remove channel from TSG and re-enable rest of the channels */ + nvgpu_rwsem_down_write(&tsg->ch_list_lock); + nvgpu_list_del(&ch->ch_entry); + ch->tsgid = NVGPU_INVALID_TSG_ID; + + /* another thread could have re-enabled the channel because it was + * still on the list at that time, so make sure it's truly disabled + */ + g->ops.fifo.disable_channel(ch); + nvgpu_rwsem_up_write(&tsg->ch_list_lock); + + /* + * Don't re-enable all channels if TSG has timed out already + * + * Note that we can skip disabling and preempting TSG too in case of + * time out, but we keep that to ensure TSG is kicked out + */ + if (!tsg_timedout) { + g->ops.fifo.enable_tsg(tsg); + } + + if (ch->g->ops.fifo.ch_abort_clean_up) { + ch->g->ops.fifo.ch_abort_clean_up(ch); + } + + return 0; + +fail_enable_tsg: + if (!tsg_timedout) { + g->ops.fifo.enable_tsg(tsg); + } + return err; +} + +u32 gk20a_fifo_get_failing_engine_data(struct gk20a *g, + int *__id, bool *__is_tsg) +{ + u32 engine_id; + int id = -1; + bool is_tsg = false; + u32 mailbox2; + u32 active_engine_id = FIFO_INVAL_ENGINE_ID; + + for (engine_id = 0; engine_id < g->fifo.num_engines; engine_id++) { + u32 status; + u32 ctx_status; + bool failing_engine; + + active_engine_id = g->fifo.active_engines_list[engine_id]; + status = gk20a_readl(g, fifo_engine_status_r(active_engine_id)); + ctx_status = fifo_engine_status_ctx_status_v(status); + + /* we are interested in busy engines */ + failing_engine = fifo_engine_status_engine_v(status) == + fifo_engine_status_engine_busy_v(); + + /* ..that are doing context switch */ + failing_engine = failing_engine && + (ctx_status == + fifo_engine_status_ctx_status_ctxsw_switch_v() + || ctx_status == + fifo_engine_status_ctx_status_ctxsw_save_v() + || ctx_status == + fifo_engine_status_ctx_status_ctxsw_load_v()); + + if (!failing_engine) { + active_engine_id = FIFO_INVAL_ENGINE_ID; + continue; + } + + if (ctx_status == + fifo_engine_status_ctx_status_ctxsw_load_v()) { + id = fifo_engine_status_next_id_v(status); + is_tsg = fifo_engine_status_next_id_type_v(status) != + fifo_engine_status_next_id_type_chid_v(); + } else if (ctx_status == + fifo_engine_status_ctx_status_ctxsw_switch_v()) { + mailbox2 = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(2)); + if (mailbox2 & FECS_METHOD_WFI_RESTORE) { + id = fifo_engine_status_next_id_v(status); + is_tsg = fifo_engine_status_next_id_type_v(status) != + fifo_engine_status_next_id_type_chid_v(); + } else { + id = fifo_engine_status_id_v(status); + is_tsg = fifo_engine_status_id_type_v(status) != + fifo_engine_status_id_type_chid_v(); + } + } else { + id = fifo_engine_status_id_v(status); + is_tsg = fifo_engine_status_id_type_v(status) != + fifo_engine_status_id_type_chid_v(); + } + break; + } + + *__id = id; + *__is_tsg = is_tsg; + + return active_engine_id; +} + +bool gk20a_fifo_check_ch_ctxsw_timeout(struct channel_gk20a *ch, + bool *verbose, u32 *ms) +{ + bool recover = false; + bool progress = false; + struct gk20a *g = ch->g; + + if (gk20a_channel_get(ch)) { + recover = gk20a_channel_update_and_check_timeout(ch, + g->fifo_eng_timeout_us / 1000, + &progress); + *verbose = ch->timeout_debug_dump; + *ms = ch->timeout_accumulated_ms; + if (recover) { + g->ops.fifo.set_error_notifier(ch, + NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT); + } + + gk20a_channel_put(ch); + } + return recover; +} + +bool gk20a_fifo_check_tsg_ctxsw_timeout(struct tsg_gk20a *tsg, + bool *verbose, u32 *ms) +{ + struct channel_gk20a *ch; + bool recover = false; + bool progress = false; + struct gk20a *g = tsg->g; + + *verbose = false; + *ms = g->fifo_eng_timeout_us / 1000; + + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + + /* check if there was some progress on any of the TSG channels. + * fifo recovery is needed if at least one channel reached the + * maximum timeout without progress (update in gpfifo pointers). + */ + nvgpu_list_for_each_entry(ch, &tsg->ch_list, channel_gk20a, ch_entry) { + if (gk20a_channel_get(ch)) { + recover = gk20a_channel_update_and_check_timeout(ch, + *ms, &progress); + if (progress || recover) { + break; + } + gk20a_channel_put(ch); + } + } + + if (recover) { + /* + * if one channel is presumed dead (no progress for too long), + * then fifo recovery is needed. we can't really figure out + * which channel caused the problem, so set timeout error + * notifier for all channels. + */ + nvgpu_log_info(g, "timeout on tsg=%d ch=%d", + tsg->tsgid, ch->chid); + *ms = ch->timeout_accumulated_ms; + gk20a_channel_put(ch); + nvgpu_list_for_each_entry(ch, &tsg->ch_list, + channel_gk20a, ch_entry) { + if (gk20a_channel_get(ch)) { + ch->g->ops.fifo.set_error_notifier(ch, + NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT); + if (ch->timeout_debug_dump) { + *verbose = true; + } + gk20a_channel_put(ch); + } + } + } else if (progress) { + /* + * if at least one channel in the TSG made some progress, reset + * accumulated timeout for all channels in the TSG. In + * particular, this resets timeout for channels that already + * completed their work + */ + nvgpu_log_info(g, "progress on tsg=%d ch=%d", + tsg->tsgid, ch->chid); + gk20a_channel_put(ch); + *ms = g->fifo_eng_timeout_us / 1000; + nvgpu_list_for_each_entry(ch, &tsg->ch_list, + channel_gk20a, ch_entry) { + if (gk20a_channel_get(ch)) { + ch->timeout_accumulated_ms = *ms; + gk20a_channel_put(ch); + } + } + } + + /* if we could not detect progress on any of the channel, but none + * of them has reached the timeout, there is nothing more to do: + * timeout_accumulated_ms has been updated for all of them. + */ + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + return recover; +} + +bool gk20a_fifo_handle_sched_error(struct gk20a *g) +{ + u32 sched_error; + u32 engine_id; + int id = -1; + bool is_tsg = false; + bool ret = false; + + /* read the scheduler error register */ + sched_error = gk20a_readl(g, fifo_intr_sched_error_r()); + + engine_id = gk20a_fifo_get_failing_engine_data(g, &id, &is_tsg); + /* + * Could not find the engine + * Possible Causes: + * a) + * On hitting engine reset, h/w drops the ctxsw_status to INVALID in + * fifo_engine_status register. Also while the engine is held in reset + * h/w passes busy/idle straight through. fifo_engine_status registers + * are correct in that there is no context switch outstanding + * as the CTXSW is aborted when reset is asserted. + * This is just a side effect of how gv100 and earlier versions of + * ctxsw_timeout behave. + * With gv11b and later, h/w snaps the context at the point of error + * so that s/w can see the tsg_id which caused the HW timeout. + * b) + * If engines are not busy and ctxsw state is valid then intr occurred + * in the past and if the ctxsw state has moved on to VALID from LOAD + * or SAVE, it means that whatever timed out eventually finished + * anyways. The problem with this is that s/w cannot conclude which + * context caused the problem as maybe more switches occurred before + * intr is handled. + */ + if (engine_id == FIFO_INVAL_ENGINE_ID) { + nvgpu_info(g, "fifo sched error: 0x%08x, failed to find engine " + "that is busy doing ctxsw. " + "May be ctxsw already happened", sched_error); + ret = false; + goto err; + } + + /* could not find the engine - should never happen */ + if (!gk20a_fifo_is_valid_engine_id(g, engine_id)) { + nvgpu_err(g, "fifo sched error : 0x%08x, failed to find engine", + sched_error); + ret = false; + goto err; + } + + if (fifo_intr_sched_error_code_f(sched_error) == + fifo_intr_sched_error_code_ctxsw_timeout_v()) { + struct fifo_gk20a *f = &g->fifo; + u32 ms = 0; + bool verbose = false; + + if (is_tsg) { + ret = g->ops.fifo.check_tsg_ctxsw_timeout( + &f->tsg[id], &verbose, &ms); + } else { + ret = g->ops.fifo.check_ch_ctxsw_timeout( + &f->channel[id], &verbose, &ms); + } + + if (ret) { + nvgpu_err(g, + "fifo sched ctxsw timeout error: " + "engine=%u, %s=%d, ms=%u", + engine_id, is_tsg ? "tsg" : "ch", id, ms); + /* + * Cancel all channels' timeout since SCHED error might + * trigger multiple watchdogs at a time + */ + gk20a_channel_timeout_restart_all_channels(g); + gk20a_fifo_recover(g, BIT(engine_id), id, + is_tsg, true, verbose, + RC_TYPE_CTXSW_TIMEOUT); + } else { + nvgpu_log_info(g, + "fifo is waiting for ctx switch for %d ms, " + "%s=%d", ms, is_tsg ? "tsg" : "ch", id); + } + } else { + nvgpu_err(g, + "fifo sched error : 0x%08x, engine=%u, %s=%d", + sched_error, engine_id, is_tsg ? "tsg" : "ch", id); + } + +err: + return ret; +} + +static u32 fifo_error_isr(struct gk20a *g, u32 fifo_intr) +{ + bool print_channel_reset_log = false; + u32 handled = 0; + + nvgpu_log_fn(g, "fifo_intr=0x%08x", fifo_intr); + + if (fifo_intr & fifo_intr_0_pio_error_pending_f()) { + /* pio mode is unused. this shouldn't happen, ever. */ + /* should we clear it or just leave it pending? */ + nvgpu_err(g, "fifo pio error!"); + BUG_ON(1); + } + + if (fifo_intr & fifo_intr_0_bind_error_pending_f()) { + u32 bind_error = gk20a_readl(g, fifo_intr_bind_error_r()); + nvgpu_err(g, "fifo bind error: 0x%08x", bind_error); + print_channel_reset_log = true; + handled |= fifo_intr_0_bind_error_pending_f(); + } + + if (fifo_intr & fifo_intr_0_sched_error_pending_f()) { + print_channel_reset_log = g->ops.fifo.handle_sched_error(g); + handled |= fifo_intr_0_sched_error_pending_f(); + } + + if (fifo_intr & fifo_intr_0_chsw_error_pending_f()) { + gk20a_fifo_handle_chsw_fault(g); + handled |= fifo_intr_0_chsw_error_pending_f(); + } + + if (fifo_intr & fifo_intr_0_mmu_fault_pending_f()) { + if (gk20a_fifo_handle_mmu_fault(g, 0, ~(u32)0, false)) { + print_channel_reset_log = true; + } + handled |= fifo_intr_0_mmu_fault_pending_f(); + } + + if (fifo_intr & fifo_intr_0_dropped_mmu_fault_pending_f()) { + gk20a_fifo_handle_dropped_mmu_fault(g); + handled |= fifo_intr_0_dropped_mmu_fault_pending_f(); + } + + print_channel_reset_log = !g->fifo.deferred_reset_pending + && print_channel_reset_log; + + if (print_channel_reset_log) { + unsigned int engine_id; + nvgpu_err(g, + "channel reset initiated from %s; intr=0x%08x", + __func__, fifo_intr); + for (engine_id = 0; + engine_id < g->fifo.num_engines; + engine_id++) { + u32 active_engine_id = g->fifo.active_engines_list[engine_id]; + u32 engine_enum = g->fifo.engine_info[active_engine_id].engine_enum; + nvgpu_log_fn(g, "enum:%d -> engine_id:%d", engine_enum, + active_engine_id); + fifo_pbdma_exception_status(g, + &g->fifo.engine_info[active_engine_id]); + fifo_engine_exception_status(g, + &g->fifo.engine_info[active_engine_id]); + } + } + + return handled; +} + +static inline void gk20a_fifo_reset_pbdma_header(struct gk20a *g, int pbdma_id) +{ + gk20a_writel(g, pbdma_pb_header_r(pbdma_id), + pbdma_pb_header_first_true_f() | + pbdma_pb_header_type_non_inc_f()); +} + +void gk20a_fifo_reset_pbdma_method(struct gk20a *g, int pbdma_id, + int pbdma_method_index) +{ + u32 pbdma_method_stride; + u32 pbdma_method_reg; + + pbdma_method_stride = pbdma_method1_r(pbdma_id) - + pbdma_method0_r(pbdma_id); + + pbdma_method_reg = pbdma_method0_r(pbdma_id) + + (pbdma_method_index * pbdma_method_stride); + + gk20a_writel(g, pbdma_method_reg, + pbdma_method0_valid_true_f() | + pbdma_method0_first_true_f() | + pbdma_method0_addr_f( + pbdma_udma_nop_r() >> 2)); +} + +static bool gk20a_fifo_is_sw_method_subch(struct gk20a *g, int pbdma_id, + int pbdma_method_index) +{ + u32 pbdma_method_stride; + u32 pbdma_method_reg, pbdma_method_subch; + + pbdma_method_stride = pbdma_method1_r(pbdma_id) - + pbdma_method0_r(pbdma_id); + + pbdma_method_reg = pbdma_method0_r(pbdma_id) + + (pbdma_method_index * pbdma_method_stride); + + pbdma_method_subch = pbdma_method0_subch_v( + gk20a_readl(g, pbdma_method_reg)); + + if (pbdma_method_subch == 5 || + pbdma_method_subch == 6 || + pbdma_method_subch == 7) { + return true; + } + + return false; +} + +unsigned int gk20a_fifo_handle_pbdma_intr_0(struct gk20a *g, u32 pbdma_id, + u32 pbdma_intr_0, u32 *handled, u32 *error_notifier) +{ + struct fifo_gk20a *f = &g->fifo; + unsigned int rc_type = RC_TYPE_NO_RC; + int i; + unsigned long pbdma_intr_err; + u32 bit; + + if ((f->intr.pbdma.device_fatal_0 | + f->intr.pbdma.channel_fatal_0 | + f->intr.pbdma.restartable_0) & pbdma_intr_0) { + + pbdma_intr_err = (unsigned long)pbdma_intr_0; + for_each_set_bit(bit, &pbdma_intr_err, 32) { + nvgpu_err(g, "PBDMA intr %s Error", + pbdma_intr_fault_type_desc[bit]); + } + + 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, + gk20a_readl(g, pbdma_pb_header_r(pbdma_id)), + gk20a_readl(g, pbdma_hdr_shadow_r(pbdma_id)), + gk20a_readl(g, pbdma_gp_shadow_0_r(pbdma_id)), + gk20a_readl(g, pbdma_gp_shadow_1_r(pbdma_id)), + gk20a_readl(g, pbdma_method0_r(pbdma_id)), + gk20a_readl(g, pbdma_method1_r(pbdma_id)), + gk20a_readl(g, pbdma_method2_r(pbdma_id)), + gk20a_readl(g, pbdma_method3_r(pbdma_id)) + ); + + rc_type = RC_TYPE_PBDMA_FAULT; + *handled |= ((f->intr.pbdma.device_fatal_0 | + f->intr.pbdma.channel_fatal_0 | + f->intr.pbdma.restartable_0) & + pbdma_intr_0); + } + + if (pbdma_intr_0 & pbdma_intr_0_acquire_pending_f()) { + u32 val = gk20a_readl(g, pbdma_acquire_r(pbdma_id)); + + val &= ~pbdma_acquire_timeout_en_enable_f(); + gk20a_writel(g, pbdma_acquire_r(pbdma_id), val); + if (nvgpu_is_timeouts_enabled(g)) { + rc_type = RC_TYPE_PBDMA_FAULT; + nvgpu_err(g, + "semaphore acquire timeout!"); + *error_notifier = NVGPU_ERR_NOTIFIER_GR_SEMAPHORE_TIMEOUT; + } + *handled |= pbdma_intr_0_acquire_pending_f(); + } + + if (pbdma_intr_0 & pbdma_intr_0_pbentry_pending_f()) { + gk20a_fifo_reset_pbdma_header(g, pbdma_id); + gk20a_fifo_reset_pbdma_method(g, pbdma_id, 0); + rc_type = RC_TYPE_PBDMA_FAULT; + } + + if (pbdma_intr_0 & pbdma_intr_0_method_pending_f()) { + gk20a_fifo_reset_pbdma_method(g, pbdma_id, 0); + rc_type = RC_TYPE_PBDMA_FAULT; + } + + if (pbdma_intr_0 & pbdma_intr_0_pbcrc_pending_f()) { + *error_notifier = + NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH; + rc_type = RC_TYPE_PBDMA_FAULT; + } + + if (pbdma_intr_0 & pbdma_intr_0_device_pending_f()) { + gk20a_fifo_reset_pbdma_header(g, pbdma_id); + + for (i = 0; i < 4; i++) { + if (gk20a_fifo_is_sw_method_subch(g, + pbdma_id, i)) { + gk20a_fifo_reset_pbdma_method(g, + pbdma_id, i); + } + } + rc_type = RC_TYPE_PBDMA_FAULT; + } + + return rc_type; +} + +unsigned int gk20a_fifo_handle_pbdma_intr_1(struct gk20a *g, + u32 pbdma_id, u32 pbdma_intr_1, + u32 *handled, u32 *error_notifier) +{ + unsigned int rc_type = RC_TYPE_PBDMA_FAULT; + + /* + * all 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); + *handled |= pbdma_intr_1; + + return rc_type; +} + +static void gk20a_fifo_pbdma_fault_rc(struct gk20a *g, + struct fifo_gk20a *f, u32 pbdma_id, + u32 error_notifier, u32 status) +{ + u32 id; + + nvgpu_log(g, gpu_dbg_info, "pbdma id %d error notifier %d", + pbdma_id, error_notifier); + /* Remove channel from runlist */ + id = fifo_pbdma_status_id_v(status); + if (fifo_pbdma_status_id_type_v(status) + == fifo_pbdma_status_id_type_chid_v()) { + struct channel_gk20a *ch = gk20a_channel_from_id(g, id); + + if (ch != NULL) { + g->ops.fifo.set_error_notifier(ch, error_notifier); + gk20a_fifo_recover_ch(g, ch, true, RC_TYPE_PBDMA_FAULT); + gk20a_channel_put(ch); + } + } else if (fifo_pbdma_status_id_type_v(status) + == fifo_pbdma_status_id_type_tsgid_v()) { + struct tsg_gk20a *tsg = &f->tsg[id]; + struct channel_gk20a *ch = NULL; + + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + nvgpu_list_for_each_entry(ch, &tsg->ch_list, + channel_gk20a, ch_entry) { + if (gk20a_channel_get(ch)) { + g->ops.fifo.set_error_notifier(ch, + error_notifier); + gk20a_channel_put(ch); + } + } + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + gk20a_fifo_recover_tsg(g, tsg, true, RC_TYPE_PBDMA_FAULT); + } +} + +u32 gk20a_fifo_handle_pbdma_intr(struct gk20a *g, struct fifo_gk20a *f, + u32 pbdma_id, unsigned int rc) +{ + u32 pbdma_intr_0 = gk20a_readl(g, pbdma_intr_0_r(pbdma_id)); + u32 pbdma_intr_1 = gk20a_readl(g, pbdma_intr_1_r(pbdma_id)); + + u32 handled = 0; + u32 error_notifier = NVGPU_ERR_NOTIFIER_PBDMA_ERROR; + unsigned int rc_type = RC_TYPE_NO_RC; + u32 pbdma_status_info = 0; + + if (pbdma_intr_0) { + 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.fifo.handle_pbdma_intr_0(g, pbdma_id, pbdma_intr_0, + &handled, &error_notifier) != RC_TYPE_NO_RC) { + rc_type = RC_TYPE_PBDMA_FAULT; + + pbdma_status_info = gk20a_readl(g, + fifo_pbdma_status_r(pbdma_id)); + } + gk20a_writel(g, pbdma_intr_0_r(pbdma_id), pbdma_intr_0); + } + + if (pbdma_intr_1) { + 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.fifo.handle_pbdma_intr_1(g, pbdma_id, pbdma_intr_1, + &handled, &error_notifier) != RC_TYPE_NO_RC) { + rc_type = RC_TYPE_PBDMA_FAULT; + + pbdma_status_info = gk20a_readl(g, + fifo_pbdma_status_r(pbdma_id)); + } + gk20a_writel(g, pbdma_intr_1_r(pbdma_id), pbdma_intr_1); + } + + if (rc == RC_YES && rc_type == RC_TYPE_PBDMA_FAULT) { + gk20a_fifo_pbdma_fault_rc(g, f, pbdma_id, error_notifier, + pbdma_status_info); + } + + return handled; +} + +static u32 fifo_pbdma_isr(struct gk20a *g, u32 fifo_intr) +{ + struct fifo_gk20a *f = &g->fifo; + u32 clear_intr = 0, i; + u32 host_num_pbdma = nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_PBDMA); + u32 pbdma_pending = gk20a_readl(g, fifo_intr_pbdma_id_r()); + + for (i = 0; i < host_num_pbdma; i++) { + if (fifo_intr_pbdma_id_status_v(pbdma_pending, i)) { + nvgpu_log(g, gpu_dbg_intr, "pbdma id %d intr pending", i); + clear_intr |= + gk20a_fifo_handle_pbdma_intr(g, f, i, RC_YES); + } + } + return fifo_intr_0_pbdma_intr_pending_f(); +} + +void gk20a_fifo_isr(struct gk20a *g) +{ + u32 error_intr_mask; + u32 clear_intr = 0; + u32 fifo_intr = gk20a_readl(g, fifo_intr_0_r()); + + error_intr_mask = g->ops.fifo.intr_0_error_mask(g); + + if (g->fifo.sw_ready) { + /* note we're not actually in an "isr", but rather + * in a threaded interrupt context... */ + nvgpu_mutex_acquire(&g->fifo.intr.isr.mutex); + + nvgpu_log(g, gpu_dbg_intr, "fifo isr %08x\n", fifo_intr); + + /* handle runlist update */ + if (fifo_intr & fifo_intr_0_runlist_event_pending_f()) { + gk20a_fifo_handle_runlist_event(g); + clear_intr |= fifo_intr_0_runlist_event_pending_f(); + } + if (fifo_intr & fifo_intr_0_pbdma_intr_pending_f()) { + clear_intr |= fifo_pbdma_isr(g, fifo_intr); + } + + if (g->ops.fifo.handle_ctxsw_timeout) { + g->ops.fifo.handle_ctxsw_timeout(g, fifo_intr); + } + + if (unlikely((fifo_intr & error_intr_mask) != 0U)) { + clear_intr |= fifo_error_isr(g, fifo_intr); + } + + nvgpu_mutex_release(&g->fifo.intr.isr.mutex); + } + gk20a_writel(g, fifo_intr_0_r(), clear_intr); + + return; +} + +u32 gk20a_fifo_nonstall_isr(struct gk20a *g) +{ + u32 fifo_intr = gk20a_readl(g, fifo_intr_0_r()); + u32 clear_intr = 0; + + nvgpu_log(g, gpu_dbg_intr, "fifo nonstall isr %08x\n", fifo_intr); + + if (fifo_intr & fifo_intr_0_channel_intr_pending_f()) { + clear_intr = fifo_intr_0_channel_intr_pending_f(); + } + + gk20a_writel(g, fifo_intr_0_r(), clear_intr); + + return GK20A_NONSTALL_OPS_WAKEUP_SEMAPHORE; +} + +void gk20a_fifo_issue_preempt(struct gk20a *g, u32 id, bool is_tsg) +{ + if (is_tsg) { + gk20a_writel(g, fifo_preempt_r(), + fifo_preempt_id_f(id) | + fifo_preempt_type_tsg_f()); + } else { + gk20a_writel(g, fifo_preempt_r(), + fifo_preempt_chid_f(id) | + fifo_preempt_type_channel_f()); + } +} + +static u32 gk20a_fifo_get_preempt_timeout(struct gk20a *g) +{ + /* Use fifo_eng_timeout converted to ms for preempt + * polling. gr_idle_timeout i.e 3000 ms is and not appropriate + * for polling preempt done as context switch timeout gets + * triggered every 100 ms and context switch recovery + * happens every 3000 ms */ + + return g->fifo_eng_timeout_us / 1000; +} + +int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, + unsigned int id_type) +{ + struct nvgpu_timeout timeout; + u32 delay = GR_IDLE_CHECK_DEFAULT; + int ret = -EBUSY; + + nvgpu_timeout_init(g, &timeout, gk20a_fifo_get_preempt_timeout(g), + NVGPU_TIMER_CPU_TIMER); + do { + if (!(gk20a_readl(g, fifo_preempt_r()) & + fifo_preempt_pending_true_f())) { + ret = 0; + break; + } + + nvgpu_usleep_range(delay, delay * 2); + delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); + } while (!nvgpu_timeout_expired(&timeout)); + + if (ret) { + nvgpu_err(g, "preempt timeout: id: %u id_type: %d ", + id, id_type); + } + return ret; +} + +void gk20a_fifo_preempt_timeout_rc_tsg(struct gk20a *g, struct tsg_gk20a *tsg) +{ + struct channel_gk20a *ch = NULL; + + nvgpu_err(g, "preempt TSG %d timeout", tsg->tsgid); + + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + nvgpu_list_for_each_entry(ch, &tsg->ch_list, + channel_gk20a, ch_entry) { + if (!gk20a_channel_get(ch)) { + continue; + } + g->ops.fifo.set_error_notifier(ch, + NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT); + gk20a_channel_put(ch); + } + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + gk20a_fifo_recover_tsg(g, tsg, true, RC_TYPE_PREEMPT_TIMEOUT); +} + +void gk20a_fifo_preempt_timeout_rc(struct gk20a *g, struct channel_gk20a *ch) +{ + nvgpu_err(g, "preempt channel %d timeout", ch->chid); + + g->ops.fifo.set_error_notifier(ch, + NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT); + gk20a_fifo_recover_ch(g, ch, true, + RC_TYPE_PREEMPT_TIMEOUT); +} + +int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) +{ + int ret; + unsigned int id_type; + + nvgpu_log_fn(g, "id: %d is_tsg: %d", id, is_tsg); + + /* issue preempt */ + gk20a_fifo_issue_preempt(g, id, is_tsg); + + id_type = is_tsg ? ID_TYPE_TSG : ID_TYPE_CHANNEL; + + /* wait for preempt */ + ret = g->ops.fifo.is_preempt_pending(g, id, id_type); + + return ret; +} + +int gk20a_fifo_preempt_channel(struct gk20a *g, struct channel_gk20a *ch) +{ + struct fifo_gk20a *f = &g->fifo; + u32 ret = 0; + u32 token = PMU_INVALID_MUTEX_OWNER_ID; + u32 mutex_ret = 0; + u32 i; + + nvgpu_log_fn(g, "chid: %d", ch->chid); + + /* we have no idea which runlist we are using. lock all */ + for (i = 0; i < g->fifo.max_runlists; i++) { + nvgpu_mutex_acquire(&f->runlist_info[i].runlist_lock); + } + + mutex_ret = nvgpu_pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token); + + ret = __locked_fifo_preempt(g, ch->chid, false); + + if (!mutex_ret) { + nvgpu_pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token); + } + + for (i = 0; i < g->fifo.max_runlists; i++) { + nvgpu_mutex_release(&f->runlist_info[i].runlist_lock); + } + + if (ret) { + if (nvgpu_platform_is_silicon(g)) { + nvgpu_err(g, "preempt timed out for chid: %u, " + "ctxsw timeout will trigger recovery if needed", + ch->chid); + } else { + gk20a_fifo_preempt_timeout_rc(g, ch); + } + } + + return ret; +} + +int gk20a_fifo_preempt_tsg(struct gk20a *g, struct tsg_gk20a *tsg) +{ + struct fifo_gk20a *f = &g->fifo; + u32 ret = 0; + u32 token = PMU_INVALID_MUTEX_OWNER_ID; + u32 mutex_ret = 0; + u32 i; + + nvgpu_log_fn(g, "tsgid: %d", tsg->tsgid); + + /* we have no idea which runlist we are using. lock all */ + for (i = 0; i < g->fifo.max_runlists; i++) { + nvgpu_mutex_acquire(&f->runlist_info[i].runlist_lock); + } + + mutex_ret = nvgpu_pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token); + + ret = __locked_fifo_preempt(g, tsg->tsgid, true); + + if (!mutex_ret) { + nvgpu_pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token); + } + + for (i = 0; i < g->fifo.max_runlists; i++) { + nvgpu_mutex_release(&f->runlist_info[i].runlist_lock); + } + + if (ret) { + if (nvgpu_platform_is_silicon(g)) { + nvgpu_err(g, "preempt timed out for tsgid: %u, " + "ctxsw timeout will trigger recovery if needed", + tsg->tsgid); + } else { + gk20a_fifo_preempt_timeout_rc_tsg(g, tsg); + } + } + + return ret; +} + +int gk20a_fifo_preempt(struct gk20a *g, struct channel_gk20a *ch) +{ + int err; + struct tsg_gk20a *tsg = tsg_gk20a_from_ch(ch); + + if (tsg != NULL) { + err = g->ops.fifo.preempt_tsg(ch->g, tsg); + } else { + err = g->ops.fifo.preempt_channel(ch->g, ch); + } + + return err; +} + +static void gk20a_fifo_sched_disable_rw(struct gk20a *g, u32 runlists_mask, + u32 runlist_state) +{ + u32 reg_val; + + reg_val = gk20a_readl(g, fifo_sched_disable_r()); + + if (runlist_state == RUNLIST_DISABLED) { + reg_val |= runlists_mask; + } else { + reg_val &= (~runlists_mask); + } + + gk20a_writel(g, fifo_sched_disable_r(), reg_val); + +} + +void gk20a_fifo_set_runlist_state(struct gk20a *g, u32 runlists_mask, + u32 runlist_state) +{ + u32 token = PMU_INVALID_MUTEX_OWNER_ID; + u32 mutex_ret; + + nvgpu_log(g, gpu_dbg_info, "runlist mask = 0x%08x state = 0x%08x", + runlists_mask, runlist_state); + + mutex_ret = nvgpu_pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token); + + gk20a_fifo_sched_disable_rw(g, runlists_mask, runlist_state); + + if (!mutex_ret) { + nvgpu_pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token); + } +} + +void gk20a_fifo_enable_tsg_sched(struct gk20a *g, struct tsg_gk20a *tsg) +{ + gk20a_fifo_set_runlist_state(g, fifo_sched_disable_runlist_m( + tsg->runlist_id), RUNLIST_ENABLED); + +} + +void gk20a_fifo_disable_tsg_sched(struct gk20a *g, struct tsg_gk20a *tsg) +{ + gk20a_fifo_set_runlist_state(g, fifo_sched_disable_runlist_m( + tsg->runlist_id), RUNLIST_DISABLED); +} + +int gk20a_fifo_enable_engine_activity(struct gk20a *g, + struct fifo_engine_info_gk20a *eng_info) +{ + nvgpu_log(g, gpu_dbg_info, "start"); + + gk20a_fifo_set_runlist_state(g, fifo_sched_disable_runlist_m( + eng_info->runlist_id), RUNLIST_ENABLED); + return 0; +} + +int gk20a_fifo_enable_all_engine_activity(struct gk20a *g) +{ + unsigned int i; + int err = 0, ret = 0; + + for (i = 0; i < g->fifo.num_engines; i++) { + u32 active_engine_id = g->fifo.active_engines_list[i]; + err = gk20a_fifo_enable_engine_activity(g, + &g->fifo.engine_info[active_engine_id]); + if (err) { + nvgpu_err(g, + "failed to enable engine %d activity", active_engine_id); + ret = err; + } + } + + return ret; +} + +int gk20a_fifo_disable_engine_activity(struct gk20a *g, + struct fifo_engine_info_gk20a *eng_info, + bool wait_for_idle) +{ + u32 gr_stat, pbdma_stat, chan_stat, eng_stat, ctx_stat; + u32 pbdma_chid = FIFO_INVAL_CHANNEL_ID; + u32 engine_chid = FIFO_INVAL_CHANNEL_ID; + u32 token = PMU_INVALID_MUTEX_OWNER_ID; + int mutex_ret; + struct channel_gk20a *ch = NULL; + int err = 0; + + nvgpu_log_fn(g, " "); + + gr_stat = + gk20a_readl(g, fifo_engine_status_r(eng_info->engine_id)); + if (fifo_engine_status_engine_v(gr_stat) == + fifo_engine_status_engine_busy_v() && !wait_for_idle) { + return -EBUSY; + } + + mutex_ret = nvgpu_pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token); + + gk20a_fifo_set_runlist_state(g, fifo_sched_disable_runlist_m( + eng_info->runlist_id), RUNLIST_DISABLED); + + /* chid from pbdma status */ + pbdma_stat = gk20a_readl(g, fifo_pbdma_status_r(eng_info->pbdma_id)); + chan_stat = fifo_pbdma_status_chan_status_v(pbdma_stat); + if (chan_stat == fifo_pbdma_status_chan_status_valid_v() || + chan_stat == fifo_pbdma_status_chan_status_chsw_save_v()) { + pbdma_chid = fifo_pbdma_status_id_v(pbdma_stat); + } else if (chan_stat == fifo_pbdma_status_chan_status_chsw_load_v() || + chan_stat == fifo_pbdma_status_chan_status_chsw_switch_v()) { + pbdma_chid = fifo_pbdma_status_next_id_v(pbdma_stat); + } + + if (pbdma_chid != FIFO_INVAL_CHANNEL_ID) { + ch = gk20a_channel_from_id(g, pbdma_chid); + if (ch != NULL) { + err = g->ops.fifo.preempt_channel(g, ch); + gk20a_channel_put(ch); + } + if (err != 0) { + goto clean_up; + } + } + + /* chid from engine status */ + eng_stat = gk20a_readl(g, fifo_engine_status_r(eng_info->engine_id)); + ctx_stat = fifo_engine_status_ctx_status_v(eng_stat); + if (ctx_stat == fifo_engine_status_ctx_status_valid_v() || + ctx_stat == fifo_engine_status_ctx_status_ctxsw_save_v()) { + engine_chid = fifo_engine_status_id_v(eng_stat); + } else if (ctx_stat == fifo_engine_status_ctx_status_ctxsw_load_v() || + ctx_stat == fifo_engine_status_ctx_status_ctxsw_switch_v()) { + engine_chid = fifo_engine_status_next_id_v(eng_stat); + } + + if (engine_chid != FIFO_INVAL_ENGINE_ID && engine_chid != pbdma_chid) { + ch = gk20a_channel_from_id(g, engine_chid); + if (ch != NULL) { + err = g->ops.fifo.preempt_channel(g, ch); + gk20a_channel_put(ch); + } + if (err != 0) { + goto clean_up; + } + } + +clean_up: + if (!mutex_ret) { + nvgpu_pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token); + } + + if (err) { + nvgpu_log_fn(g, "failed"); + if (gk20a_fifo_enable_engine_activity(g, eng_info)) { + nvgpu_err(g, + "failed to enable gr engine activity"); + } + } else { + nvgpu_log_fn(g, "done"); + } + return err; +} + +int gk20a_fifo_disable_all_engine_activity(struct gk20a *g, + bool wait_for_idle) +{ + unsigned int i; + int err = 0, ret = 0; + u32 active_engine_id; + + for (i = 0; i < g->fifo.num_engines; i++) { + active_engine_id = g->fifo.active_engines_list[i]; + err = gk20a_fifo_disable_engine_activity(g, + &g->fifo.engine_info[active_engine_id], + wait_for_idle); + if (err) { + nvgpu_err(g, "failed to disable engine %d activity", + active_engine_id); + ret = err; + break; + } + } + + if (err) { + while (i-- != 0) { + active_engine_id = g->fifo.active_engines_list[i]; + err = gk20a_fifo_enable_engine_activity(g, + &g->fifo.engine_info[active_engine_id]); + if (err) { + nvgpu_err(g, + "failed to re-enable engine %d activity", + active_engine_id); + } + } + } + + return ret; +} + +static void gk20a_fifo_runlist_reset_engines(struct gk20a *g, u32 runlist_id) +{ + struct fifo_gk20a *f = &g->fifo; + u32 engines = 0; + unsigned int i; + + for (i = 0; i < f->num_engines; i++) { + u32 active_engine_id = g->fifo.active_engines_list[i]; + u32 status = gk20a_readl(g, fifo_engine_status_r(active_engine_id)); + bool engine_busy = fifo_engine_status_engine_v(status) == + fifo_engine_status_engine_busy_v(); + + if (engine_busy && + (f->engine_info[active_engine_id].runlist_id == runlist_id)) { + engines |= BIT(active_engine_id); + } + } + + if (engines) { + gk20a_fifo_recover(g, engines, ~(u32)0, false, false, true, + RC_TYPE_RUNLIST_UPDATE_TIMEOUT); + } +} + +int gk20a_fifo_runlist_wait_pending(struct gk20a *g, u32 runlist_id) +{ + struct nvgpu_timeout timeout; + unsigned long delay = GR_IDLE_CHECK_DEFAULT; + int ret = -ETIMEDOUT; + + nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); + + do { + if ((gk20a_readl(g, fifo_eng_runlist_r(runlist_id)) & + fifo_eng_runlist_pending_true_f()) == 0) { + ret = 0; + break; + } + + nvgpu_usleep_range(delay, delay * 2); + delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); + } while (!nvgpu_timeout_expired(&timeout)); + + if (ret) { + nvgpu_err(g, "runlist wait timeout: runlist id: %u", + runlist_id); + } + + return ret; +} + +void gk20a_get_tsg_runlist_entry(struct tsg_gk20a *tsg, u32 *runlist) +{ + + u32 runlist_entry_0 = ram_rl_entry_id_f(tsg->tsgid) | + ram_rl_entry_type_tsg_f() | + ram_rl_entry_tsg_length_f(tsg->num_active_channels); + + if (tsg->timeslice_timeout) { + runlist_entry_0 |= + ram_rl_entry_timeslice_scale_f(tsg->timeslice_scale) | + ram_rl_entry_timeslice_timeout_f(tsg->timeslice_timeout); + } else { + runlist_entry_0 |= + ram_rl_entry_timeslice_scale_f( + NVGPU_FIFO_DEFAULT_TIMESLICE_SCALE) | + ram_rl_entry_timeslice_timeout_f( + NVGPU_FIFO_DEFAULT_TIMESLICE_TIMEOUT); + } + + runlist[0] = runlist_entry_0; + runlist[1] = 0; + +} + +u32 gk20a_fifo_default_timeslice_us(struct gk20a *g) +{ + return (((u64)(NVGPU_FIFO_DEFAULT_TIMESLICE_TIMEOUT << + NVGPU_FIFO_DEFAULT_TIMESLICE_SCALE) * + (u64)g->ptimer_src_freq) / + (u64)PTIMER_REF_FREQ_HZ); +} + +void gk20a_get_ch_runlist_entry(struct channel_gk20a *ch, u32 *runlist) +{ + runlist[0] = ram_rl_entry_chid_f(ch->chid); + runlist[1] = 0; +} + +/* recursively construct a runlist with interleaved bare channels and TSGs */ +u32 *gk20a_runlist_construct_locked(struct fifo_gk20a *f, + struct fifo_runlist_info_gk20a *runlist, + u32 cur_level, + u32 *runlist_entry, + bool interleave_enabled, + bool prev_empty, + u32 *entries_left) +{ + bool last_level = cur_level == NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_HIGH; + struct channel_gk20a *ch; + bool skip_next = false; + u32 tsgid, count = 0; + u32 runlist_entry_words = f->runlist_entry_size / sizeof(u32); + struct gk20a *g = f->g; + + nvgpu_log_fn(g, " "); + + /* for each TSG, T, on this level, insert all higher-level channels + and TSGs before inserting T. */ + for_each_set_bit(tsgid, runlist->active_tsgs, f->num_channels) { + struct tsg_gk20a *tsg = &f->tsg[tsgid]; + + if (tsg->interleave_level != cur_level) { + continue; + } + + if (!last_level && !skip_next) { + runlist_entry = gk20a_runlist_construct_locked(f, + runlist, + cur_level + 1, + runlist_entry, + interleave_enabled, + false, + entries_left); + if (!interleave_enabled) { + skip_next = true; + } + } + + if (*entries_left == 0U) { + return NULL; + } + + /* add TSG entry */ + nvgpu_log_info(g, "add TSG %d to runlist", tsg->tsgid); + f->g->ops.fifo.get_tsg_runlist_entry(tsg, runlist_entry); + nvgpu_log_info(g, "tsg runlist count %d runlist [0] %x [1] %x\n", + count, runlist_entry[0], runlist_entry[1]); + runlist_entry += runlist_entry_words; + count++; + (*entries_left)--; + + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + /* add runnable channels bound to this TSG */ + nvgpu_list_for_each_entry(ch, &tsg->ch_list, + channel_gk20a, ch_entry) { + if (!test_bit((int)ch->chid, + runlist->active_channels)) { + continue; + } + + if (*entries_left == 0U) { + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + return NULL; + } + + nvgpu_log_info(g, "add channel %d to runlist", + ch->chid); + f->g->ops.fifo.get_ch_runlist_entry(ch, runlist_entry); + nvgpu_log_info(g, + "run list count %d runlist [0] %x [1] %x\n", + count, runlist_entry[0], runlist_entry[1]); + count++; + runlist_entry += runlist_entry_words; + (*entries_left)--; + } + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + } + + /* append entries from higher level if this level is empty */ + if (!count && !last_level) { + runlist_entry = gk20a_runlist_construct_locked(f, + runlist, + cur_level + 1, + runlist_entry, + interleave_enabled, + true, + entries_left); + } + + /* + * if previous and this level have entries, append + * entries from higher level. + * + * ex. dropping from MEDIUM to LOW, need to insert HIGH + */ + if (interleave_enabled && count && !prev_empty && !last_level) { + runlist_entry = gk20a_runlist_construct_locked(f, + runlist, + cur_level + 1, + runlist_entry, + interleave_enabled, + false, + entries_left); + } + return runlist_entry; +} + +int gk20a_fifo_set_runlist_interleave(struct gk20a *g, + u32 id, + u32 runlist_id, + u32 new_level) +{ + nvgpu_log_fn(g, " "); + + g->fifo.tsg[id].interleave_level = new_level; + + return 0; +} + +int gk20a_fifo_tsg_set_timeslice(struct tsg_gk20a *tsg, u32 timeslice) +{ + struct gk20a *g = tsg->g; + + if (timeslice < g->min_timeslice_us || + timeslice > g->max_timeslice_us) { + return -EINVAL; + } + + gk20a_channel_get_timescale_from_timeslice(g, timeslice, + &tsg->timeslice_timeout, &tsg->timeslice_scale); + + tsg->timeslice_us = timeslice; + + return g->ops.fifo.update_runlist(g, tsg->runlist_id, ~0, true, true); +} + +void gk20a_fifo_runlist_hw_submit(struct gk20a *g, u32 runlist_id, + u32 count, u32 buffer_index) +{ + struct fifo_runlist_info_gk20a *runlist = NULL; + u64 runlist_iova; + u32 val_wrote; + struct nvgpu_os_linux *l; + + runlist = &g->fifo.runlist_info[runlist_id]; + runlist_iova = nvgpu_mem_get_addr(g, &runlist->mem[buffer_index]); + + + if (count != 0) { + printk(KERN_INFO "Runlist base register: %0x\n", fifo_runlist_base_r()); + printk(KERN_INFO "Runlist KVA: %px\n", (void*)(runlist->mem[buffer_index].cpu_va)); + printk(KERN_INFO "Runlist PA: %px\n", (void*)virt_to_phys((runlist->mem[buffer_index].cpu_va))); + printk(KERN_INFO "Runlist dma_address: %px\n", (void*)(runlist->mem[buffer_index].priv.sgt->sgl->dma_address)); + printk(KERN_INFO "Runlist pages KVA: %px\n", (void*)(runlist->mem[buffer_index].priv.pages)); + printk(KERN_INFO "Runlist pages PA: %px\n", (void*)virt_to_phys(runlist->mem[buffer_index].priv.pages)); + printk(KERN_INFO "Runlist dma_address: %px\n", (void*)(runlist->mem[buffer_index].priv.sgt->sgl->dma_address)); + printk(KERN_INFO "Runlist page_to_phys %px + offset %px\n", (void*)(page_to_phys(sg_page(runlist->mem[buffer_index].priv.sgt->sgl))), (void*)(runlist->mem[buffer_index].priv.sgt->sgl->offset)); + printk(KERN_INFO "Runlist IOVA: %px\n", (void*)runlist_iova); + printk(KERN_INFO "Using struct gk20* %px\n", g); + printk(KERN_INFO "g->name: %s, g->power_on: %d, g->sw_ready: %d, g->is_virtual %d\n", g->name, g->power_on, g->sw_ready, g->is_virtual); + printk(KERN_INFO "COHERENT_SYSMEM? %d, iommuable? %d\n", nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM), nvgpu_iommuable(g)); + l = container_of(g, struct nvgpu_os_linux, g); + printk(KERN_INFO "l->regs %px\n", l->regs); + gk20a_writel(g, fifo_runlist_base_r(), + fifo_runlist_base_ptr_f(u64_lo32(runlist_iova >> 12)) | + nvgpu_aperture_mask(g, &runlist->mem[buffer_index], + fifo_runlist_base_target_sys_mem_ncoh_f(), + fifo_runlist_base_target_sys_mem_coh_f(), + fifo_runlist_base_target_vid_mem_f())); + val_wrote = nvgpu_readl(g, 0x2270); + printk(KERN_INFO "Wrote runlist base as %0llx\n", (u64)(val_wrote & 0x0fffffff) << 12); + } + + gk20a_writel(g, fifo_runlist_r(), + fifo_runlist_engine_f(runlist_id) | + fifo_eng_runlist_length_f(count)); +} + +int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, + u32 chid, bool add, + bool wait_for_finish) +{ + int ret = 0; + struct fifo_gk20a *f = &g->fifo; + struct fifo_runlist_info_gk20a *runlist = NULL; + u32 *runlist_entry_base = NULL; + u64 runlist_iova; + u32 new_buf; + struct channel_gk20a *ch = NULL; + struct tsg_gk20a *tsg = NULL; + u32 runlist_entry_words = f->runlist_entry_size / sizeof(u32); + + runlist = &f->runlist_info[runlist_id]; + + /* valid channel, add/remove it from active list. + Otherwise, keep active list untouched for suspend/resume. */ + if (chid != FIFO_INVAL_CHANNEL_ID) { + ch = &f->channel[chid]; + tsg = tsg_gk20a_from_ch(ch); + + if (add) { + if (test_and_set_bit(chid, + runlist->active_channels) == 1) { + return 0; + } + if (tsg && ++tsg->num_active_channels) { + set_bit((int)f->channel[chid].tsgid, + runlist->active_tsgs); + } + } else { + if (test_and_clear_bit(chid, + runlist->active_channels) == 0) { + return 0; + } + if (tsg && --tsg->num_active_channels == 0) { + clear_bit((int)f->channel[chid].tsgid, + runlist->active_tsgs); + } + } + } + + new_buf = !runlist->cur_buffer; + + runlist_iova = nvgpu_mem_get_addr(g, &runlist->mem[new_buf]); + + nvgpu_log_info(g, "runlist_id : %d, switch to new buffer 0x%16llx", + runlist_id, (u64)runlist_iova); + + if (!runlist_iova) { + ret = -EINVAL; + goto clean_up; + } + + runlist_entry_base = runlist->mem[new_buf].cpu_va; + if (!runlist_entry_base) { + ret = -ENOMEM; + goto clean_up; + } + + if (chid != FIFO_INVAL_CHANNEL_ID || /* add/remove a valid channel */ + add /* resume to add all channels back */) { + u32 max_entries = f->num_runlist_entries; + u32 *runlist_end; + + runlist_end = gk20a_runlist_construct_locked(f, + runlist, + 0, + runlist_entry_base, + g->runlist_interleave, + true, + &max_entries); + if (!runlist_end) { + ret = -E2BIG; + goto clean_up; + } + runlist->count = (runlist_end - runlist_entry_base) / + runlist_entry_words; + WARN_ON(runlist->count > f->num_runlist_entries); + } else { + /* suspend to remove all channels */ + runlist->count = 0; + } + + g->ops.fifo.runlist_hw_submit(g, runlist_id, runlist->count, new_buf); + + if (wait_for_finish) { + ret = g->ops.fifo.runlist_wait_pending(g, runlist_id); + + if (ret == -ETIMEDOUT) { + nvgpu_err(g, "runlist %d update timeout", runlist_id); + /* trigger runlist update timeout recovery */ + return ret; + + } else if (ret == -EINTR) { + nvgpu_err(g, "runlist update interrupted"); + } + } + + runlist->cur_buffer = new_buf; + +clean_up: + return ret; +} + +int gk20a_fifo_update_runlist_ids(struct gk20a *g, u32 runlist_ids, u32 chid, + bool add, bool wait_for_finish) +{ + u32 ret = -EINVAL; + u32 runlist_id = 0; + u32 errcode; + unsigned long ulong_runlist_ids = (unsigned long)runlist_ids; + + if (!g) { + goto end; + } + + ret = 0; + for_each_set_bit(runlist_id, &ulong_runlist_ids, 32) { + /* Capture the last failure error code */ + errcode = g->ops.fifo.update_runlist(g, runlist_id, chid, add, wait_for_finish); + if (errcode) { + nvgpu_err(g, + "failed to update_runlist %d %d", runlist_id, errcode); + ret = errcode; + } + } +end: + return ret; +} + +/* trigger host preempt of GR pending load ctx if that ctx is not for ch */ +static int __locked_fifo_reschedule_preempt_next(struct channel_gk20a *ch, + bool wait_preempt) +{ + struct gk20a *g = ch->g; + struct fifo_runlist_info_gk20a *runlist = + &g->fifo.runlist_info[ch->runlist_id]; + int ret = 0; + u32 gr_eng_id = 0; + u32 engstat = 0, ctxstat = 0, fecsstat0 = 0, fecsstat1 = 0; + u32 preempt_id; + u32 preempt_type = 0; + + if (1 != gk20a_fifo_get_engine_ids( + g, &gr_eng_id, 1, ENGINE_GR_GK20A)) { + return ret; + } + if (!(runlist->eng_bitmask & (1 << gr_eng_id))) { + return ret; + } + + if (wait_preempt && gk20a_readl(g, fifo_preempt_r()) & + fifo_preempt_pending_true_f()) { + return ret; + } + + fecsstat0 = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(0)); + engstat = gk20a_readl(g, fifo_engine_status_r(gr_eng_id)); + ctxstat = fifo_engine_status_ctx_status_v(engstat); + if (ctxstat == fifo_engine_status_ctx_status_ctxsw_switch_v()) { + /* host switching to next context, preempt that if needed */ + preempt_id = fifo_engine_status_next_id_v(engstat); + preempt_type = fifo_engine_status_next_id_type_v(engstat); + } else { + return ret; + } + if (preempt_id == ch->tsgid && preempt_type) { + return ret; + } + fecsstat1 = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(0)); + if (fecsstat0 != FECS_MAILBOX_0_ACK_RESTORE || + fecsstat1 != FECS_MAILBOX_0_ACK_RESTORE) { + /* preempt useless if FECS acked save and started restore */ + return ret; + } + + gk20a_fifo_issue_preempt(g, preempt_id, preempt_type); +#ifdef TRACEPOINTS_ENABLED + trace_gk20a_reschedule_preempt_next(ch->chid, fecsstat0, engstat, + fecsstat1, gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(0)), + gk20a_readl(g, fifo_preempt_r())); +#endif + if (wait_preempt) { + g->ops.fifo.is_preempt_pending(g, preempt_id, preempt_type); + } +#ifdef TRACEPOINTS_ENABLED + trace_gk20a_reschedule_preempted_next(ch->chid); +#endif + return ret; +} + +int gk20a_fifo_reschedule_runlist(struct channel_gk20a *ch, bool preempt_next) +{ + return nvgpu_fifo_reschedule_runlist(ch, preempt_next, true); +} + +/* trigger host to expire current timeslice and reschedule runlist from front */ +int nvgpu_fifo_reschedule_runlist(struct channel_gk20a *ch, bool preempt_next, + bool wait_preempt) +{ + struct gk20a *g = ch->g; + struct fifo_runlist_info_gk20a *runlist; + u32 token = PMU_INVALID_MUTEX_OWNER_ID; + u32 mutex_ret; + int ret = 0; + + runlist = &g->fifo.runlist_info[ch->runlist_id]; + if (!nvgpu_mutex_tryacquire(&runlist->runlist_lock)) { + return -EBUSY; + } + + mutex_ret = nvgpu_pmu_mutex_acquire( + &g->pmu, PMU_MUTEX_ID_FIFO, &token); + + g->ops.fifo.runlist_hw_submit( + g, ch->runlist_id, runlist->count, runlist->cur_buffer); + + if (preempt_next) { + __locked_fifo_reschedule_preempt_next(ch, wait_preempt); + } + + gk20a_fifo_runlist_wait_pending(g, ch->runlist_id); + + if (!mutex_ret) { + nvgpu_pmu_mutex_release( + &g->pmu, PMU_MUTEX_ID_FIFO, &token); + } + nvgpu_mutex_release(&runlist->runlist_lock); + + return ret; +} + +/* add/remove a channel from runlist + special cases below: runlist->active_channels will NOT be changed. + (chid == ~0 && !add) means remove all active channels from runlist. + (chid == ~0 && add) means restore all active channels on runlist. */ +int gk20a_fifo_update_runlist(struct gk20a *g, u32 runlist_id, u32 chid, + bool add, bool wait_for_finish) +{ + struct fifo_runlist_info_gk20a *runlist = NULL; + struct fifo_gk20a *f = &g->fifo; + u32 token = PMU_INVALID_MUTEX_OWNER_ID; + u32 mutex_ret; + int ret = 0; + + nvgpu_log_fn(g, " "); + + runlist = &f->runlist_info[runlist_id]; + + nvgpu_mutex_acquire(&runlist->runlist_lock); + + mutex_ret = nvgpu_pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token); + + ret = gk20a_fifo_update_runlist_locked(g, runlist_id, chid, add, + wait_for_finish); + + if (!mutex_ret) { + nvgpu_pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token); + } + + nvgpu_mutex_release(&runlist->runlist_lock); + + if (ret == -ETIMEDOUT) { + gk20a_fifo_runlist_reset_engines(g, runlist_id); + } + + return ret; +} + +int gk20a_fifo_suspend(struct gk20a *g) +{ + nvgpu_log_fn(g, " "); + + /* stop bar1 snooping */ + if (g->ops.mm.is_bar1_supported(g)) { + gk20a_writel(g, fifo_bar1_base_r(), + fifo_bar1_base_valid_false_f()); + } + + /* disable fifo intr */ + gk20a_writel(g, fifo_intr_en_0_r(), 0); + gk20a_writel(g, fifo_intr_en_1_r(), 0); + + nvgpu_log_fn(g, "done"); + return 0; +} + +bool gk20a_fifo_mmu_fault_pending(struct gk20a *g) +{ + if (gk20a_readl(g, fifo_intr_0_r()) & + fifo_intr_0_mmu_fault_pending_f()) { + return true; + } else { + return false; + } +} + +bool gk20a_fifo_is_engine_busy(struct gk20a *g) +{ + u32 i, host_num_engines; + + host_num_engines = nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_ENGINES); + + for (i = 0; i < host_num_engines; i++) { + u32 status = gk20a_readl(g, fifo_engine_status_r(i)); + if (fifo_engine_status_engine_v(status) == + fifo_engine_status_engine_busy_v()) { + return true; + } + } + return false; +} + +int gk20a_fifo_wait_engine_idle(struct gk20a *g) +{ + struct nvgpu_timeout timeout; + unsigned long delay = GR_IDLE_CHECK_DEFAULT; + int ret = -ETIMEDOUT; + u32 i, host_num_engines; + + nvgpu_log_fn(g, " "); + + host_num_engines = + nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_ENGINES); + + nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); + + for (i = 0; i < host_num_engines; i++) { + do { + u32 status = gk20a_readl(g, fifo_engine_status_r(i)); + if (!fifo_engine_status_engine_v(status)) { + ret = 0; + break; + } + + nvgpu_usleep_range(delay, delay * 2); + delay = min_t(unsigned long, + delay << 1, GR_IDLE_CHECK_MAX); + } while (!nvgpu_timeout_expired(&timeout)); + + if (ret) { + nvgpu_log_info(g, "cannot idle engine %u", i); + break; + } + } + + nvgpu_log_fn(g, "done"); + + return ret; +} + +u32 gk20a_fifo_get_pbdma_signature(struct gk20a *g) +{ + return pbdma_signature_hw_valid_f() | pbdma_signature_sw_zero_f(); +} + +static const char * const ccsr_chan_status_str[] = { + "idle", + "pending", + "pending_ctx_reload", + "pending_acquire", + "pending_acq_ctx_reload", + "on_pbdma", + "on_pbdma_and_eng", + "on_eng", + "on_eng_pending_acquire", + "on_eng_pending", + "on_pbdma_ctx_reload", + "on_pbdma_and_eng_ctx_reload", + "on_eng_ctx_reload", + "on_eng_pending_ctx_reload", + "on_eng_pending_acq_ctx_reload", +}; + +static const char * const pbdma_chan_eng_ctx_status_str[] = { + "invalid", + "valid", + "NA", + "NA", + "NA", + "load", + "save", + "switch", +}; + +static const char * const not_found_str[] = { + "NOT FOUND" +}; + +const char *gk20a_decode_ccsr_chan_status(u32 index) +{ + if (index >= ARRAY_SIZE(ccsr_chan_status_str)) { + return not_found_str[0]; + } else { + return ccsr_chan_status_str[index]; + } +} + +const char *gk20a_decode_pbdma_chan_eng_ctx_status(u32 index) +{ + if (index >= ARRAY_SIZE(pbdma_chan_eng_ctx_status_str)) { + return not_found_str[0]; + } else { + return pbdma_chan_eng_ctx_status_str[index]; + } +} + +bool gk20a_fifo_channel_status_is_next(struct gk20a *g, u32 chid) +{ + u32 channel = gk20a_readl(g, ccsr_channel_r(chid)); + + return ccsr_channel_next_v(channel) == ccsr_channel_next_true_v(); +} + +bool gk20a_fifo_channel_status_is_ctx_reload(struct gk20a *g, u32 chid) +{ + u32 channel = gk20a_readl(g, ccsr_channel_r(chid)); + u32 status = ccsr_channel_status_v(channel); + + return (status == ccsr_channel_status_pending_ctx_reload_v() || + status == ccsr_channel_status_pending_acq_ctx_reload_v() || + status == ccsr_channel_status_on_pbdma_ctx_reload_v() || + status == ccsr_channel_status_on_pbdma_and_eng_ctx_reload_v() || + status == ccsr_channel_status_on_eng_ctx_reload_v() || + status == ccsr_channel_status_on_eng_pending_ctx_reload_v() || + status == ccsr_channel_status_on_eng_pending_acq_ctx_reload_v()); +} + +void gk20a_dump_channel_status_ramfc(struct gk20a *g, + struct gk20a_debug_output *o, + u32 chid, + struct ch_state *ch_state) +{ + u32 channel = gk20a_readl(g, ccsr_channel_r(chid)); + u32 status = ccsr_channel_status_v(channel); + u32 syncpointa, syncpointb; + u32 *inst_mem; + struct channel_gk20a *c = g->fifo.channel + chid; + struct nvgpu_semaphore_int *hw_sema = NULL; + + if (c->hw_sema) { + hw_sema = c->hw_sema; + } + + if (!ch_state) { + return; + } + + inst_mem = &ch_state->inst_block[0]; + + syncpointa = inst_mem[ram_fc_syncpointa_w()]; + syncpointb = inst_mem[ram_fc_syncpointb_w()]; + + gk20a_debug_output(o, "%d-%s, pid %d, refs %d%s: ", chid, + g->name, + ch_state->pid, + ch_state->refs, + ch_state->deterministic ? ", deterministic" : ""); + gk20a_debug_output(o, "channel status: %s in use %s %s\n", + ccsr_channel_enable_v(channel) ? "" : "not", + gk20a_decode_ccsr_chan_status(status), + ccsr_channel_busy_v(channel) ? "busy" : "not busy"); + gk20a_debug_output(o, "RAMFC : TOP: %016llx PUT: %016llx GET: %016llx " + "FETCH: %016llx\nHEADER: %08x COUNT: %08x\n" + "SYNCPOINT %08x %08x SEMAPHORE %08x %08x %08x %08x\n", + (u64)inst_mem[ram_fc_pb_top_level_get_w()] + + ((u64)inst_mem[ram_fc_pb_top_level_get_hi_w()] << 32ULL), + (u64)inst_mem[ram_fc_pb_put_w()] + + ((u64)inst_mem[ram_fc_pb_put_hi_w()] << 32ULL), + (u64)inst_mem[ram_fc_pb_get_w()] + + ((u64)inst_mem[ram_fc_pb_get_hi_w()] << 32ULL), + (u64)inst_mem[ram_fc_pb_fetch_w()] + + ((u64)inst_mem[ram_fc_pb_fetch_hi_w()] << 32ULL), + inst_mem[ram_fc_pb_header_w()], + inst_mem[ram_fc_pb_count_w()], + syncpointa, + syncpointb, + inst_mem[ram_fc_semaphorea_w()], + inst_mem[ram_fc_semaphoreb_w()], + inst_mem[ram_fc_semaphorec_w()], + inst_mem[ram_fc_semaphored_w()]); + if (hw_sema) { + gk20a_debug_output(o, "SEMA STATE: value: 0x%08x " + "next_val: 0x%08x addr: 0x%010llx\n", + __nvgpu_semaphore_read(hw_sema), + nvgpu_atomic_read(&hw_sema->next_value), + nvgpu_hw_sema_addr(hw_sema)); + } + +#ifdef CONFIG_TEGRA_GK20A_NVHOST + if ((pbdma_syncpointb_op_v(syncpointb) == pbdma_syncpointb_op_wait_v()) + && (pbdma_syncpointb_wait_switch_v(syncpointb) == + pbdma_syncpointb_wait_switch_en_v())) + gk20a_debug_output(o, "%s on syncpt %u (%s) val %u\n", + (status == 3 || status == 8) ? "Waiting" : "Waited", + pbdma_syncpointb_syncpt_index_v(syncpointb), + nvgpu_nvhost_syncpt_get_name(g->nvhost_dev, + pbdma_syncpointb_syncpt_index_v(syncpointb)), + pbdma_syncpointa_payload_v(syncpointa)); +#endif + + gk20a_debug_output(o, "\n"); +} + +void gk20a_debug_dump_all_channel_status_ramfc(struct gk20a *g, + struct gk20a_debug_output *o) +{ + struct fifo_gk20a *f = &g->fifo; + u32 chid; + struct ch_state **ch_state; + + ch_state = nvgpu_kzalloc(g, sizeof(*ch_state) * f->num_channels); + if (!ch_state) { + gk20a_debug_output(o, "cannot alloc memory for channels\n"); + return; + } + + for (chid = 0; chid < f->num_channels; chid++) { + struct channel_gk20a *ch = gk20a_channel_from_id(g, chid); + if (ch != NULL) { + ch_state[chid] = + nvgpu_kmalloc(g, sizeof(struct ch_state) + + ram_in_alloc_size_v()); + /* ref taken stays to below loop with + * successful allocs */ + if (!ch_state[chid]) { + gk20a_channel_put(ch); + } + } + } + + for (chid = 0; chid < f->num_channels; chid++) { + struct channel_gk20a *ch = &f->channel[chid]; + if (!ch_state[chid]) { + continue; + } + + ch_state[chid]->pid = ch->pid; + ch_state[chid]->refs = nvgpu_atomic_read(&ch->ref_count); + ch_state[chid]->deterministic = ch->deterministic; + nvgpu_mem_rd_n(g, &ch->inst_block, 0, + &ch_state[chid]->inst_block[0], + ram_in_alloc_size_v()); + gk20a_channel_put(ch); + } + for (chid = 0; chid < f->num_channels; chid++) { + if (ch_state[chid]) { + g->ops.fifo.dump_channel_status_ramfc(g, o, chid, + ch_state[chid]); + nvgpu_kfree(g, ch_state[chid]); + } + } + nvgpu_kfree(g, ch_state); +} + +void gk20a_dump_pbdma_status(struct gk20a *g, + struct gk20a_debug_output *o) +{ + u32 i, host_num_pbdma; + + host_num_pbdma = nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_PBDMA); + + for (i = 0; i < host_num_pbdma; i++) { + u32 status = gk20a_readl(g, fifo_pbdma_status_r(i)); + u32 chan_status = fifo_pbdma_status_chan_status_v(status); + + gk20a_debug_output(o, "%s pbdma %d: ", g->name, i); + gk20a_debug_output(o, + "id: %d (%s), next_id: %d (%s) chan status: %s\n", + fifo_pbdma_status_id_v(status), + fifo_pbdma_status_id_type_v(status) ? + "tsg" : "channel", + fifo_pbdma_status_next_id_v(status), + fifo_pbdma_status_next_id_type_v(status) ? + "tsg" : "channel", + gk20a_decode_pbdma_chan_eng_ctx_status(chan_status)); + gk20a_debug_output(o, "PBDMA_PUT: %016llx PBDMA_GET: %016llx " + "GP_PUT: %08x GP_GET: %08x " + "FETCH: %08x HEADER: %08x\n" + "HDR: %08x SHADOW0: %08x SHADOW1: %08x", + (u64)gk20a_readl(g, pbdma_put_r(i)) + + ((u64)gk20a_readl(g, pbdma_put_hi_r(i)) << 32ULL), + (u64)gk20a_readl(g, pbdma_get_r(i)) + + ((u64)gk20a_readl(g, pbdma_get_hi_r(i)) << 32ULL), + gk20a_readl(g, pbdma_gp_put_r(i)), + gk20a_readl(g, pbdma_gp_get_r(i)), + gk20a_readl(g, pbdma_gp_fetch_r(i)), + gk20a_readl(g, pbdma_pb_header_r(i)), + gk20a_readl(g, pbdma_hdr_shadow_r(i)), + gk20a_readl(g, pbdma_gp_shadow_0_r(i)), + gk20a_readl(g, pbdma_gp_shadow_1_r(i))); + } + gk20a_debug_output(o, "\n"); +} + +void gk20a_dump_eng_status(struct gk20a *g, + struct gk20a_debug_output *o) +{ + u32 i, host_num_engines; + + host_num_engines = nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_ENGINES); + + for (i = 0; i < host_num_engines; i++) { + u32 status = gk20a_readl(g, fifo_engine_status_r(i)); + u32 ctx_status = fifo_engine_status_ctx_status_v(status); + + gk20a_debug_output(o, "%s eng %d: ", g->name, i); + gk20a_debug_output(o, + "id: %d (%s), next_id: %d (%s), ctx status: %s ", + fifo_engine_status_id_v(status), + fifo_engine_status_id_type_v(status) ? + "tsg" : "channel", + fifo_engine_status_next_id_v(status), + fifo_engine_status_next_id_type_v(status) ? + "tsg" : "channel", + gk20a_decode_pbdma_chan_eng_ctx_status(ctx_status)); + + if (fifo_engine_status_faulted_v(status)) { + gk20a_debug_output(o, "faulted "); + } + if (fifo_engine_status_engine_v(status)) { + gk20a_debug_output(o, "busy "); + } + gk20a_debug_output(o, "\n"); + } + gk20a_debug_output(o, "\n"); +} + +void gk20a_fifo_enable_channel(struct channel_gk20a *ch) +{ + gk20a_writel(ch->g, ccsr_channel_r(ch->chid), + gk20a_readl(ch->g, ccsr_channel_r(ch->chid)) | + ccsr_channel_enable_set_true_f()); +} + +void gk20a_fifo_disable_channel(struct channel_gk20a *ch) +{ + gk20a_writel(ch->g, ccsr_channel_r(ch->chid), + gk20a_readl(ch->g, + ccsr_channel_r(ch->chid)) | + ccsr_channel_enable_clr_true_f()); +} + +void gk20a_fifo_channel_unbind(struct channel_gk20a *ch_gk20a) +{ + struct gk20a *g = ch_gk20a->g; + + nvgpu_log_fn(g, " "); + + if (nvgpu_atomic_cmpxchg(&ch_gk20a->bound, true, false)) { + gk20a_writel(g, ccsr_channel_inst_r(ch_gk20a->chid), + ccsr_channel_inst_ptr_f(0) | + ccsr_channel_inst_bind_false_f()); + } +} + +static int gk20a_fifo_commit_userd(struct channel_gk20a *c) +{ + u32 addr_lo; + u32 addr_hi; + struct gk20a *g = c->g; + + nvgpu_log_fn(g, " "); + + addr_lo = u64_lo32(c->userd_iova >> ram_userd_base_shift_v()); + addr_hi = u64_hi32(c->userd_iova); + + nvgpu_log_info(g, "channel %d : set ramfc userd 0x%16llx", + c->chid, (u64)c->userd_iova); + + nvgpu_mem_wr32(g, &c->inst_block, + ram_in_ramfc_w() + ram_fc_userd_w(), + nvgpu_aperture_mask(g, &g->fifo.userd, + pbdma_userd_target_sys_mem_ncoh_f(), + pbdma_userd_target_sys_mem_coh_f(), + pbdma_userd_target_vid_mem_f()) | + pbdma_userd_addr_f(addr_lo)); + + nvgpu_mem_wr32(g, &c->inst_block, + ram_in_ramfc_w() + ram_fc_userd_hi_w(), + pbdma_userd_hi_addr_f(addr_hi)); + + return 0; +} + +int gk20a_fifo_setup_ramfc(struct channel_gk20a *c, + u64 gpfifo_base, u32 gpfifo_entries, + unsigned long timeout, + u32 flags) +{ + struct gk20a *g = c->g; + struct nvgpu_mem *mem = &c->inst_block; + + nvgpu_log_fn(g, " "); + + nvgpu_memset(g, mem, 0, 0, ram_fc_size_val_v()); + + nvgpu_mem_wr32(g, mem, ram_fc_gp_base_w(), + pbdma_gp_base_offset_f( + u64_lo32(gpfifo_base >> pbdma_gp_base_rsvd_s()))); + + nvgpu_mem_wr32(g, mem, ram_fc_gp_base_hi_w(), + pbdma_gp_base_hi_offset_f(u64_hi32(gpfifo_base)) | + pbdma_gp_base_hi_limit2_f(ilog2(gpfifo_entries))); + + nvgpu_mem_wr32(g, mem, ram_fc_signature_w(), + c->g->ops.fifo.get_pbdma_signature(c->g)); + + nvgpu_mem_wr32(g, mem, ram_fc_formats_w(), + pbdma_formats_gp_fermi0_f() | + pbdma_formats_pb_fermi1_f() | + pbdma_formats_mp_fermi0_f()); + + nvgpu_mem_wr32(g, mem, ram_fc_pb_header_w(), + pbdma_pb_header_priv_user_f() | + pbdma_pb_header_method_zero_f() | + pbdma_pb_header_subchannel_zero_f() | + pbdma_pb_header_level_main_f() | + pbdma_pb_header_first_true_f() | + pbdma_pb_header_type_inc_f()); + + nvgpu_mem_wr32(g, mem, ram_fc_subdevice_w(), + pbdma_subdevice_id_f(1) | + pbdma_subdevice_status_active_f() | + pbdma_subdevice_channel_dma_enable_f()); + + nvgpu_mem_wr32(g, mem, ram_fc_target_w(), pbdma_target_engine_sw_f()); + + nvgpu_mem_wr32(g, mem, ram_fc_acquire_w(), + g->ops.fifo.pbdma_acquire_val(timeout)); + + nvgpu_mem_wr32(g, mem, ram_fc_runlist_timeslice_w(), + fifo_runlist_timeslice_timeout_128_f() | + fifo_runlist_timeslice_timescale_3_f() | + fifo_runlist_timeslice_enable_true_f()); + + nvgpu_mem_wr32(g, mem, ram_fc_pb_timeslice_w(), + fifo_pb_timeslice_timeout_16_f() | + fifo_pb_timeslice_timescale_0_f() | + fifo_pb_timeslice_enable_true_f()); + + nvgpu_mem_wr32(g, mem, ram_fc_chid_w(), ram_fc_chid_id_f(c->chid)); + + if (c->is_privileged_channel) { + gk20a_fifo_setup_ramfc_for_privileged_channel(c); + } + + return gk20a_fifo_commit_userd(c); +} + +void gk20a_fifo_setup_ramfc_for_privileged_channel(struct channel_gk20a *c) +{ + struct gk20a *g = c->g; + struct nvgpu_mem *mem = &c->inst_block; + + nvgpu_log_info(g, "channel %d : set ramfc privileged_channel", c->chid); + + /* Enable HCE priv mode for phys mode transfer */ + nvgpu_mem_wr32(g, mem, ram_fc_hce_ctrl_w(), + pbdma_hce_ctrl_hce_priv_mode_yes_f()); +} + +int gk20a_fifo_setup_userd(struct channel_gk20a *c) +{ + struct gk20a *g = c->g; + struct nvgpu_mem *mem; + u32 offset; + + nvgpu_log_fn(g, " "); + + if (nvgpu_mem_is_valid(&c->usermode_userd)) { + mem = &c->usermode_userd; + offset = 0; + } else { + mem = &g->fifo.userd; + offset = c->chid * g->fifo.userd_entry_size / sizeof(u32); + } + + nvgpu_mem_wr32(g, mem, offset + ram_userd_put_w(), 0); + nvgpu_mem_wr32(g, mem, offset + ram_userd_get_w(), 0); + nvgpu_mem_wr32(g, mem, offset + ram_userd_ref_w(), 0); + nvgpu_mem_wr32(g, mem, offset + ram_userd_put_hi_w(), 0); + nvgpu_mem_wr32(g, mem, offset + ram_userd_ref_threshold_w(), 0); + nvgpu_mem_wr32(g, mem, offset + ram_userd_gp_top_level_get_w(), 0); + nvgpu_mem_wr32(g, mem, offset + ram_userd_gp_top_level_get_hi_w(), 0); + nvgpu_mem_wr32(g, mem, offset + ram_userd_get_hi_w(), 0); + nvgpu_mem_wr32(g, mem, offset + ram_userd_gp_get_w(), 0); + nvgpu_mem_wr32(g, mem, offset + ram_userd_gp_put_w(), 0); + + return 0; +} + +int gk20a_fifo_alloc_inst(struct gk20a *g, struct channel_gk20a *ch) +{ + int err; + + nvgpu_log_fn(g, " "); + + err = g->ops.mm.alloc_inst_block(g, &ch->inst_block); + if (err) { + return err; + } + + nvgpu_log_info(g, "channel %d inst block physical addr: 0x%16llx", + ch->chid, nvgpu_inst_block_addr(g, &ch->inst_block)); + + nvgpu_log_fn(g, "done"); + return 0; +} + +void gk20a_fifo_free_inst(struct gk20a *g, struct channel_gk20a *ch) +{ + nvgpu_free_inst_block(g, &ch->inst_block); +} + +u32 gk20a_fifo_userd_gp_get(struct gk20a *g, struct channel_gk20a *c) +{ + return gk20a_bar1_readl(g, + c->userd_gpu_va + sizeof(u32) * ram_userd_gp_get_w()); +} + +u64 gk20a_fifo_userd_pb_get(struct gk20a *g, struct channel_gk20a *c) +{ + u32 lo = gk20a_bar1_readl(g, + c->userd_gpu_va + sizeof(u32) * ram_userd_get_w()); + u32 hi = gk20a_bar1_readl(g, + c->userd_gpu_va + sizeof(u32) * ram_userd_get_hi_w()); + + return ((u64)hi << 32) | lo; +} + +void gk20a_fifo_userd_gp_put(struct gk20a *g, struct channel_gk20a *c) +{ + gk20a_bar1_writel(g, + c->userd_gpu_va + sizeof(u32) * ram_userd_gp_put_w(), + c->gpfifo.put); +} + +u32 gk20a_fifo_pbdma_acquire_val(u64 timeout) +{ + u32 val, exp, man; + unsigned int val_len; + + val = pbdma_acquire_retry_man_2_f() | + pbdma_acquire_retry_exp_2_f(); + + if (!timeout) { + return val; + } + + timeout *= 80UL; + do_div(timeout, 100); /* set acquire timeout to 80% of channel wdt */ + timeout *= 1000000UL; /* ms -> ns */ + do_div(timeout, 1024); /* in unit of 1024ns */ + val_len = fls(timeout >> 32) + 32; + if (val_len == 32) { + val_len = fls(timeout); + } + if (val_len > 16U + pbdma_acquire_timeout_exp_max_v()) { /* man: 16bits */ + exp = pbdma_acquire_timeout_exp_max_v(); + man = pbdma_acquire_timeout_man_max_v(); + } else if (val_len > 16) { + exp = val_len - 16; + man = timeout >> exp; + } else { + exp = 0; + man = timeout; + } + + val |= pbdma_acquire_timeout_exp_f(exp) | + pbdma_acquire_timeout_man_f(man) | + pbdma_acquire_timeout_en_enable_f(); + + return val; +} + +const char *gk20a_fifo_interleave_level_name(u32 interleave_level) +{ + switch (interleave_level) { + case NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_LOW: + return "LOW"; + + case NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_MEDIUM: + return "MEDIUM"; + + case NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_HIGH: + return "HIGH"; + + default: + return "?"; + } +} + +u32 gk20a_fifo_get_sema_wait_cmd_size(void) +{ + return 8; +} + +u32 gk20a_fifo_get_sema_incr_cmd_size(void) +{ + return 10; +} + +void gk20a_fifo_add_sema_cmd(struct gk20a *g, + struct nvgpu_semaphore *s, u64 sema_va, + struct priv_cmd_entry *cmd, + u32 off, bool acquire, bool wfi) +{ + nvgpu_log_fn(g, " "); + + /* semaphore_a */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010004); + /* offset_upper */ + nvgpu_mem_wr32(g, cmd->mem, off++, (sema_va >> 32) & 0xff); + /* semaphore_b */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010005); + /* offset */ + nvgpu_mem_wr32(g, cmd->mem, off++, sema_va & 0xffffffff); + + if (acquire) { + /* semaphore_c */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010006); + /* payload */ + nvgpu_mem_wr32(g, cmd->mem, off++, + nvgpu_semaphore_get_value(s)); + /* semaphore_d */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010007); + /* operation: acq_geq, switch_en */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x4 | (0x1 << 12)); + } else { + /* semaphore_c */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010006); + /* payload */ + nvgpu_mem_wr32(g, cmd->mem, off++, + nvgpu_semaphore_get_value(s)); + /* semaphore_d */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010007); + /* operation: release, wfi */ + nvgpu_mem_wr32(g, cmd->mem, off++, + 0x2 | ((wfi ? 0x0 : 0x1) << 20)); + /* non_stall_int */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010008); + /* ignored */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0); + } +} + +#ifdef CONFIG_TEGRA_GK20A_NVHOST +void gk20a_fifo_add_syncpt_wait_cmd(struct gk20a *g, + struct priv_cmd_entry *cmd, u32 off, + u32 id, u32 thresh, u64 gpu_va) +{ + nvgpu_log_fn(g, " "); + + off = cmd->off + off; + /* syncpoint_a */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x2001001C); + /* payload */ + nvgpu_mem_wr32(g, cmd->mem, off++, thresh); + /* syncpoint_b */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x2001001D); + /* syncpt_id, switch_en, wait */ + nvgpu_mem_wr32(g, cmd->mem, off++, (id << 8) | 0x10); +} + +u32 gk20a_fifo_get_syncpt_wait_cmd_size(void) +{ + return 4; +} + +u32 gk20a_fifo_get_syncpt_incr_per_release(void) +{ + return 2; +} + +void gk20a_fifo_add_syncpt_incr_cmd(struct gk20a *g, + bool wfi_cmd, struct priv_cmd_entry *cmd, + u32 id, u64 gpu_va) +{ + u32 off = cmd->off; + + nvgpu_log_fn(g, " "); + if (wfi_cmd) { + /* wfi */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x2001001E); + /* handle, ignored */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x00000000); + } + /* syncpoint_a */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x2001001C); + /* payload, ignored */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0); + /* syncpoint_b */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x2001001D); + /* syncpt_id, incr */ + nvgpu_mem_wr32(g, cmd->mem, off++, (id << 8) | 0x1); + /* syncpoint_b */ + nvgpu_mem_wr32(g, cmd->mem, off++, 0x2001001D); + /* syncpt_id, incr */ + nvgpu_mem_wr32(g, cmd->mem, off++, (id << 8) | 0x1); + +} + +u32 gk20a_fifo_get_syncpt_incr_cmd_size(bool wfi_cmd) +{ + if (wfi_cmd) + return 8; + else + return 6; +} + +void gk20a_fifo_free_syncpt_buf(struct channel_gk20a *c, + struct nvgpu_mem *syncpt_buf) +{ + +} + +int gk20a_fifo_alloc_syncpt_buf(struct channel_gk20a *c, + u32 syncpt_id, struct nvgpu_mem *syncpt_buf) +{ + return 0; +} +#endif diff --git a/include/gk20a/fifo_gk20a.h b/include/gk20a/fifo_gk20a.h new file mode 100644 index 0000000..26365ca --- /dev/null +++ b/include/gk20a/fifo_gk20a.h @@ -0,0 +1,471 @@ +/* + * GK20A graphics fifo (gr host) + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef FIFO_GK20A_H +#define FIFO_GK20A_H + +#include + +struct gk20a_debug_output; +struct mmu_fault_info; +struct nvgpu_semaphore; +struct channel_gk20a; +struct tsg_gk20a; + +enum { + NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_LOW = 0, + NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_MEDIUM, + NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_HIGH, + NVGPU_FIFO_RUNLIST_INTERLEAVE_NUM_LEVELS, +}; + +#define MAX_RUNLIST_BUFFERS 2 + +#define FIFO_INVAL_ENGINE_ID ((u32)~0) +#define FIFO_INVAL_CHANNEL_ID ((u32)~0) +#define FIFO_INVAL_TSG_ID ((u32)~0) +#define FIFO_INVAL_RUNLIST_ID ((u32)~0) + +#define ID_TYPE_CHANNEL 0 +#define ID_TYPE_TSG 1 +#define ID_TYPE_UNKNOWN ((u32)~0) + +#define RC_YES 1 +#define RC_NO 0 + +#define GRFIFO_TIMEOUT_CHECK_PERIOD_US 100000 + +#define RC_TYPE_NO_RC 0 +#define RC_TYPE_MMU_FAULT 1 +#define RC_TYPE_PBDMA_FAULT 2 +#define RC_TYPE_GR_FAULT 3 +#define RC_TYPE_PREEMPT_TIMEOUT 4 +#define RC_TYPE_CTXSW_TIMEOUT 5 +#define RC_TYPE_RUNLIST_UPDATE_TIMEOUT 6 +#define RC_TYPE_FORCE_RESET 7 +#define RC_TYPE_SCHED_ERR 8 + +#define NVGPU_FIFO_DEFAULT_TIMESLICE_TIMEOUT 128UL +#define NVGPU_FIFO_DEFAULT_TIMESLICE_SCALE 3UL + +/* + * Number of entries in the kickoff latency buffer, used to calculate + * the profiling and histogram. This number is calculated to be statistically + * significative on a histogram on a 5% step + */ +#ifdef CONFIG_DEBUG_FS +#define FIFO_PROFILING_ENTRIES 16384 +#endif + +#define RUNLIST_DISABLED 0 +#define RUNLIST_ENABLED 1 + +/* generally corresponds to the "pbdma" engine */ + +struct fifo_runlist_info_gk20a { + unsigned long *active_channels; + unsigned long *active_tsgs; + /* Each engine has its own SW and HW runlist buffer.*/ + struct nvgpu_mem mem[MAX_RUNLIST_BUFFERS]; + u32 cur_buffer; + u32 total_entries; + u32 pbdma_bitmask; /* pbdmas supported for this runlist*/ + u32 eng_bitmask; /* engines using this runlist */ + u32 reset_eng_bitmask; /* engines to be reset during recovery */ + u32 count; /* cached runlist_hw_submit parameter */ + bool stopped; + bool support_tsg; + /* protect ch/tsg/runlist preempt & runlist update */ + struct nvgpu_mutex runlist_lock; +}; + +enum { + ENGINE_GR_GK20A = 0U, + ENGINE_GRCE_GK20A = 1U, + ENGINE_ASYNC_CE_GK20A = 2U, + ENGINE_INVAL_GK20A = 3U, +}; + +struct fifo_pbdma_exception_info_gk20a { + u32 status_r; /* raw register value from hardware */ + u32 id, next_id; + u32 chan_status_v; /* raw value from hardware */ + bool id_is_chid, next_id_is_chid; + bool chsw_in_progress; +}; + +struct fifo_engine_exception_info_gk20a { + u32 status_r; /* raw register value from hardware */ + u32 id, next_id; + u32 ctx_status_v; /* raw value from hardware */ + bool id_is_chid, next_id_is_chid; + bool faulted, idle, ctxsw_in_progress; +}; + +struct fifo_engine_info_gk20a { + u32 engine_id; + u32 runlist_id; + u32 intr_mask; + u32 reset_mask; + u32 pbdma_id; + u32 inst_id; + u32 pri_base; + u32 fault_id; + u32 engine_enum; + struct fifo_pbdma_exception_info_gk20a pbdma_exception_info; + struct fifo_engine_exception_info_gk20a engine_exception_info; +}; + +enum { + PROFILE_IOCTL_ENTRY = 0U, + PROFILE_ENTRY, + PROFILE_JOB_TRACKING, + PROFILE_APPEND, + PROFILE_END, + PROFILE_IOCTL_EXIT, + PROFILE_MAX +}; + +struct fifo_profile_gk20a { + u64 timestamp[PROFILE_MAX]; +}; + +struct fifo_gk20a { + struct gk20a *g; + unsigned int num_channels; + unsigned int runlist_entry_size; + unsigned int num_runlist_entries; + + unsigned int num_pbdma; + u32 *pbdma_map; + + struct fifo_engine_info_gk20a *engine_info; + u32 max_engines; + u32 num_engines; + u32 *active_engines_list; + + struct fifo_runlist_info_gk20a *runlist_info; + u32 max_runlists; +#ifdef CONFIG_DEBUG_FS + struct { + struct fifo_profile_gk20a *data; + nvgpu_atomic_t get; + bool enabled; + u64 *sorted; + struct nvgpu_ref ref; + struct nvgpu_mutex lock; + } profile; +#endif + struct nvgpu_mem userd; + u32 userd_entry_size; + + unsigned int used_channels; + struct channel_gk20a *channel; + /* zero-kref'd channels here */ + struct nvgpu_list_node free_chs; + struct nvgpu_mutex free_chs_mutex; + struct nvgpu_mutex engines_reset_mutex; + + struct tsg_gk20a *tsg; + struct nvgpu_mutex tsg_inuse_mutex; + + void (*remove_support)(struct fifo_gk20a *); + bool sw_ready; + struct { + /* share info between isrs and non-isr code */ + struct { + struct nvgpu_mutex mutex; + } isr; + struct { + u32 device_fatal_0; + u32 channel_fatal_0; + u32 restartable_0; + } pbdma; + struct { + + } engine; + + + } intr; + + unsigned long deferred_fault_engines; + bool deferred_reset_pending; + struct nvgpu_mutex deferred_reset_mutex; + + u32 max_subctx_count; + u32 channel_base; +}; + +struct ch_state { + int pid; + int refs; + bool deterministic; + u32 inst_block[0]; +}; + +int gk20a_init_fifo_support(struct gk20a *g); + +int gk20a_init_fifo_setup_hw(struct gk20a *g); + +void gk20a_fifo_isr(struct gk20a *g); +u32 gk20a_fifo_nonstall_isr(struct gk20a *g); + +int gk20a_fifo_preempt_channel(struct gk20a *g, struct channel_gk20a *ch); +int gk20a_fifo_preempt_tsg(struct gk20a *g, struct tsg_gk20a *tsg); +int gk20a_fifo_preempt(struct gk20a *g, struct channel_gk20a *ch); + +int gk20a_fifo_enable_engine_activity(struct gk20a *g, + struct fifo_engine_info_gk20a *eng_info); +int gk20a_fifo_enable_all_engine_activity(struct gk20a *g); +int gk20a_fifo_disable_engine_activity(struct gk20a *g, + struct fifo_engine_info_gk20a *eng_info, + bool wait_for_idle); +int gk20a_fifo_disable_all_engine_activity(struct gk20a *g, + bool wait_for_idle); +void gk20a_fifo_enable_tsg_sched(struct gk20a *g, struct tsg_gk20a *tsg); +void gk20a_fifo_disable_tsg_sched(struct gk20a *g, struct tsg_gk20a *tsg); + +u32 gk20a_fifo_engines_on_ch(struct gk20a *g, u32 chid); + +int gk20a_fifo_reschedule_runlist(struct channel_gk20a *ch, bool preempt_next); +int nvgpu_fifo_reschedule_runlist(struct channel_gk20a *ch, bool preempt_next, + bool wait_preempt); + +int gk20a_fifo_update_runlist(struct gk20a *g, u32 engine_id, u32 chid, + bool add, bool wait_for_finish); + +int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, + u32 chid, bool add, + bool wait_for_finish); +int gk20a_fifo_suspend(struct gk20a *g); + +bool gk20a_fifo_mmu_fault_pending(struct gk20a *g); + +void gk20a_fifo_recover(struct gk20a *g, + u32 engine_ids, /* if zero, will be queried from HW */ + u32 hw_id, /* if ~0, will be queried from HW */ + bool id_is_tsg, /* ignored if hw_id == ~0 */ + bool id_is_known, bool verbose, int rc_type); +void gk20a_fifo_recover_ch(struct gk20a *g, struct channel_gk20a *ch, + bool verbose, u32 rc_type); +void gk20a_fifo_recover_tsg(struct gk20a *g, struct tsg_gk20a *tsg, + bool verbose, u32 rc_type); +int gk20a_fifo_force_reset_ch(struct channel_gk20a *ch, + u32 err_code, bool verbose); +void gk20a_fifo_reset_engine(struct gk20a *g, u32 engine_id); +int gk20a_init_fifo_reset_enable_hw(struct gk20a *g); +int gk20a_fifo_tsg_unbind_channel(struct channel_gk20a *ch); + +void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, + unsigned long fault_id); +int gk20a_fifo_wait_engine_idle(struct gk20a *g); +bool gk20a_fifo_is_engine_busy(struct gk20a *g); +u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g); +u32 gk20a_fifo_act_eng_interrupt_mask(struct gk20a *g, u32 act_eng_id); +u32 gk20a_fifo_get_pbdma_signature(struct gk20a *g); +u32 gk20a_fifo_get_failing_engine_data(struct gk20a *g, + int *__id, bool *__is_tsg); +void gk20a_fifo_set_ctx_mmu_error_tsg(struct gk20a *g, + struct tsg_gk20a *tsg); +void gk20a_fifo_abort_tsg(struct gk20a *g, struct tsg_gk20a *tsg, bool preempt); +void gk20a_fifo_set_ctx_mmu_error_ch(struct gk20a *g, + struct channel_gk20a *refch); +bool gk20a_fifo_error_tsg(struct gk20a *g, struct tsg_gk20a *tsg); +bool gk20a_fifo_error_ch(struct gk20a *g, struct channel_gk20a *refch); + +void gk20a_fifo_issue_preempt(struct gk20a *g, u32 id, bool is_tsg); +int gk20a_fifo_set_runlist_interleave(struct gk20a *g, + u32 id, + u32 runlist_id, + u32 new_level); +int gk20a_fifo_tsg_set_timeslice(struct tsg_gk20a *tsg, u32 timeslice); + +const char *gk20a_fifo_interleave_level_name(u32 interleave_level); + +int gk20a_fifo_engine_enum_from_type(struct gk20a *g, u32 engine_type, + u32 *inst_id); + +u32 gk20a_fifo_get_engine_ids(struct gk20a *g, u32 engine_id[], + u32 engine_id_sz, u32 engine_enum); + +void gk20a_fifo_delete_runlist(struct fifo_gk20a *f); + +struct fifo_engine_info_gk20a *gk20a_fifo_get_engine_info(struct gk20a *g, + u32 engine_id); + +bool gk20a_fifo_is_valid_engine_id(struct gk20a *g, u32 engine_id); + +u32 gk20a_fifo_get_gr_engine_id(struct gk20a *g); + +int gk20a_fifo_deferred_reset(struct gk20a *g, struct channel_gk20a *ch); + +u32 gk20a_fifo_get_all_ce_engine_reset_mask(struct gk20a *g); + +u32 gk20a_fifo_get_fast_ce_runlist_id(struct gk20a *g); + +u32 gk20a_fifo_get_gr_runlist_id(struct gk20a *g); + +bool gk20a_fifo_is_valid_runlist_id(struct gk20a *g, u32 runlist_id); + +int gk20a_fifo_update_runlist_ids(struct gk20a *g, u32 runlist_ids, u32 chid, + bool add, bool wait_for_finish); + +int gk20a_fifo_init_engine_info(struct fifo_gk20a *f); + +void gk20a_get_tsg_runlist_entry(struct tsg_gk20a *tsg, u32 *runlist); +void gk20a_get_ch_runlist_entry(struct channel_gk20a *ch, u32 *runlist); +void gk20a_fifo_set_runlist_state(struct gk20a *g, u32 runlists_mask, + u32 runlist_state); + +u32 gk20a_fifo_userd_gp_get(struct gk20a *g, struct channel_gk20a *c); +void gk20a_fifo_userd_gp_put(struct gk20a *g, struct channel_gk20a *c); +u64 gk20a_fifo_userd_pb_get(struct gk20a *g, struct channel_gk20a *c); + +bool gk20a_is_fault_engine_subid_gpc(struct gk20a *g, u32 engine_subid); +#ifdef CONFIG_DEBUG_FS +struct fifo_profile_gk20a *gk20a_fifo_profile_acquire(struct gk20a *g); +void gk20a_fifo_profile_release(struct gk20a *g, + struct fifo_profile_gk20a *profile); +void gk20a_fifo_profile_snapshot(struct fifo_profile_gk20a *profile, int idx); +#else +static inline struct fifo_profile_gk20a * +gk20a_fifo_profile_acquire(struct gk20a *g) +{ + return NULL; +} +static inline void gk20a_fifo_profile_release(struct gk20a *g, + struct fifo_profile_gk20a *profile) +{ +} +static inline void gk20a_fifo_profile_snapshot( + struct fifo_profile_gk20a *profile, int idx) +{ +} +#endif + +void gk20a_dump_channel_status_ramfc(struct gk20a *g, + struct gk20a_debug_output *o, + u32 chid, + struct ch_state *ch_state); +void gk20a_debug_dump_all_channel_status_ramfc(struct gk20a *g, + struct gk20a_debug_output *o); +void gk20a_dump_pbdma_status(struct gk20a *g, + struct gk20a_debug_output *o); +void gk20a_dump_eng_status(struct gk20a *g, + struct gk20a_debug_output *o); +const char *gk20a_decode_ccsr_chan_status(u32 index); +const char *gk20a_decode_pbdma_chan_eng_ctx_status(u32 index); +void gk20a_fifo_enable_channel(struct channel_gk20a *ch); +void gk20a_fifo_disable_channel(struct channel_gk20a *ch); + +bool gk20a_fifo_channel_status_is_next(struct gk20a *g, u32 chid); +bool gk20a_fifo_channel_status_is_ctx_reload(struct gk20a *g, u32 chid); +int gk20a_fifo_tsg_unbind_channel_verify_status(struct channel_gk20a *ch); + +struct channel_gk20a *gk20a_refch_from_inst_ptr(struct gk20a *g, u64 inst_ptr); +void gk20a_fifo_channel_unbind(struct channel_gk20a *ch_gk20a); + +u32 gk20a_fifo_intr_0_error_mask(struct gk20a *g); + +int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, + unsigned int id_type); +int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg); +void gk20a_fifo_preempt_timeout_rc_tsg(struct gk20a *g, struct tsg_gk20a *tsg); +void gk20a_fifo_preempt_timeout_rc(struct gk20a *g, struct channel_gk20a *ch); +int gk20a_fifo_setup_ramfc(struct channel_gk20a *c, + u64 gpfifo_base, u32 gpfifo_entries, + unsigned long timeout, u32 flags); +void gk20a_fifo_setup_ramfc_for_privileged_channel(struct channel_gk20a *c); +int gk20a_fifo_alloc_inst(struct gk20a *g, struct channel_gk20a *ch); +void gk20a_fifo_free_inst(struct gk20a *g, struct channel_gk20a *ch); +int gk20a_fifo_setup_userd(struct channel_gk20a *c); +u32 gk20a_fifo_pbdma_acquire_val(u64 timeout); + + +u32 *gk20a_runlist_construct_locked(struct fifo_gk20a *f, + struct fifo_runlist_info_gk20a *runlist, + u32 cur_level, + u32 *runlist_entry, + bool interleave_enabled, + bool prev_empty, + u32 *entries_left); +void gk20a_fifo_runlist_hw_submit(struct gk20a *g, u32 runlist_id, + u32 count, u32 buffer_index); +int gk20a_fifo_runlist_wait_pending(struct gk20a *g, u32 runlist_id); +int gk20a_init_fifo_setup_sw_common(struct gk20a *g); +int gk20a_init_fifo_setup_sw(struct gk20a *g); +void gk20a_fifo_handle_runlist_event(struct gk20a *g); +bool gk20a_fifo_should_defer_engine_reset(struct gk20a *g, u32 engine_id, + u32 engine_subid, bool fake_fault); + +void gk20a_fifo_teardown_ch_tsg(struct gk20a *g, u32 __engine_ids, + u32 hw_id, unsigned int id_type, unsigned int rc_type, + struct mmu_fault_info *mmfault); + +bool gk20a_fifo_check_ch_ctxsw_timeout(struct channel_gk20a *ch, + bool *verbose, u32 *ms); +bool gk20a_fifo_check_tsg_ctxsw_timeout(struct tsg_gk20a *tsg, + bool *verbose, u32 *ms); +void gk20a_fifo_teardown_mask_intr(struct gk20a *g); +void gk20a_fifo_teardown_unmask_intr(struct gk20a *g); +bool gk20a_fifo_handle_sched_error(struct gk20a *g); + +void gk20a_fifo_reset_pbdma_method(struct gk20a *g, int pbdma_id, + int pbdma_method_index); +unsigned int gk20a_fifo_handle_pbdma_intr_0(struct gk20a *g, u32 pbdma_id, + u32 pbdma_intr_0, u32 *handled, u32 *error_notifier); +unsigned int gk20a_fifo_handle_pbdma_intr_1(struct gk20a *g, u32 pbdma_id, + u32 pbdma_intr_1, u32 *handled, u32 *error_notifier); +u32 gk20a_fifo_handle_pbdma_intr(struct gk20a *g, struct fifo_gk20a *f, + u32 pbdma_id, unsigned int rc); + +u32 gk20a_fifo_default_timeslice_us(struct gk20a *g); + +#ifdef CONFIG_TEGRA_GK20A_NVHOST +void gk20a_fifo_add_syncpt_wait_cmd(struct gk20a *g, + struct priv_cmd_entry *cmd, u32 off, + u32 id, u32 thresh, u64 gpu_va); +u32 gk20a_fifo_get_syncpt_wait_cmd_size(void); +u32 gk20a_fifo_get_syncpt_incr_per_release(void); +void gk20a_fifo_add_syncpt_incr_cmd(struct gk20a *g, + bool wfi_cmd, struct priv_cmd_entry *cmd, + u32 id, u64 gpu_va); +u32 gk20a_fifo_get_syncpt_incr_cmd_size(bool wfi_cmd); +void gk20a_fifo_free_syncpt_buf(struct channel_gk20a *c, + struct nvgpu_mem *syncpt_buf); +int gk20a_fifo_alloc_syncpt_buf(struct channel_gk20a *c, + u32 syncpt_id, struct nvgpu_mem *syncpt_buf); +#endif + +void gk20a_fifo_get_mmu_fault_info(struct gk20a *g, u32 mmu_fault_id, + struct mmu_fault_info *mmfault); +void gk20a_fifo_get_mmu_fault_desc(struct mmu_fault_info *mmfault); +void gk20a_fifo_get_mmu_fault_client_desc(struct mmu_fault_info *mmfault); +void gk20a_fifo_get_mmu_fault_gpc_desc(struct mmu_fault_info *mmfault); +u32 gk20a_fifo_get_sema_wait_cmd_size(void); +u32 gk20a_fifo_get_sema_incr_cmd_size(void); +void gk20a_fifo_add_sema_cmd(struct gk20a *g, + struct nvgpu_semaphore *s, u64 sema_va, + struct priv_cmd_entry *cmd, + u32 off, bool acquire, bool wfi); +#endif /* FIFO_GK20A_H */ diff --git a/include/gk20a/flcn_gk20a.c b/include/gk20a/flcn_gk20a.c new file mode 100644 index 0000000..fdcaef9 --- /dev/null +++ b/include/gk20a/flcn_gk20a.c @@ -0,0 +1,759 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include +#include +#include + +#include "gk20a/gk20a.h" +#include "gk20a/flcn_gk20a.h" + +#include + +static int gk20a_flcn_reset(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 unit_status = 0; + int status = 0; + + if (flcn->flcn_engine_dep_ops.reset_eng) { + /* falcon & engine reset */ + status = flcn->flcn_engine_dep_ops.reset_eng(g); + } else { + /* do falcon CPU hard reset */ + unit_status = gk20a_readl(g, base_addr + + falcon_falcon_cpuctl_r()); + gk20a_writel(g, base_addr + falcon_falcon_cpuctl_r(), + (unit_status | falcon_falcon_cpuctl_hreset_f(1))); + } + + return status; +} + +static bool gk20a_flcn_clear_halt_interrupt_status(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 data = 0; + bool status = false; + + gk20a_writel(g, base_addr + falcon_falcon_irqsclr_r(), + gk20a_readl(g, base_addr + falcon_falcon_irqsclr_r()) | + (0x10)); + data = gk20a_readl(g, (base_addr + falcon_falcon_irqstat_r())); + + if ((data & falcon_falcon_irqstat_halt_true_f()) != + falcon_falcon_irqstat_halt_true_f()) { + /*halt irq is clear*/ + status = true; + } + + return status; +} + +static void gk20a_flcn_set_irq(struct nvgpu_falcon *flcn, bool enable) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + + if (!flcn->is_interrupt_enabled) { + nvgpu_warn(g, "Interrupt not supported on flcn 0x%x ", + flcn->flcn_id); + /* Keep interrupt disabled */ + enable = false; + } + + if (enable) { + gk20a_writel(g, base_addr + falcon_falcon_irqmset_r(), + flcn->intr_mask); + gk20a_writel(g, base_addr + falcon_falcon_irqdest_r(), + flcn->intr_dest); + } else { + gk20a_writel(g, base_addr + falcon_falcon_irqmclr_r(), + 0xffffffff); + } +} + +static bool gk20a_is_falcon_cpu_halted(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + + return (gk20a_readl(g, base_addr + falcon_falcon_cpuctl_r()) & + falcon_falcon_cpuctl_halt_intr_m() ? + true : false); +} + +static bool gk20a_is_falcon_idle(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 unit_status = 0; + bool status = false; + + unit_status = gk20a_readl(g, + base_addr + falcon_falcon_idlestate_r()); + + if (falcon_falcon_idlestate_falcon_busy_v(unit_status) == 0 && + falcon_falcon_idlestate_ext_busy_v(unit_status) == 0) { + status = true; + } else { + status = false; + } + + return status; +} + +static bool gk20a_is_falcon_scrubbing_done(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 unit_status = 0; + bool status = false; + + unit_status = gk20a_readl(g, + base_addr + falcon_falcon_dmactl_r()); + + if (unit_status & (falcon_falcon_dmactl_dmem_scrubbing_m() | + falcon_falcon_dmactl_imem_scrubbing_m())) { + status = false; + } else { + status = true; + } + + return status; +} + +static u32 gk20a_falcon_get_mem_size(struct nvgpu_falcon *flcn, + enum flcn_mem_type mem_type) +{ + struct gk20a *g = flcn->g; + u32 mem_size = 0; + u32 hw_cfg_reg = gk20a_readl(g, + flcn->flcn_base + falcon_falcon_hwcfg_r()); + + if (mem_type == MEM_DMEM) { + mem_size = falcon_falcon_hwcfg_dmem_size_v(hw_cfg_reg) + << GK20A_PMU_DMEM_BLKSIZE2; + } else { + mem_size = falcon_falcon_hwcfg_imem_size_v(hw_cfg_reg) + << GK20A_PMU_DMEM_BLKSIZE2; + } + + return mem_size; +} + +static int flcn_mem_overflow_check(struct nvgpu_falcon *flcn, + u32 offset, u32 size, enum flcn_mem_type mem_type) +{ + struct gk20a *g = flcn->g; + u32 mem_size = 0; + + if (size == 0) { + nvgpu_err(g, "size is zero"); + return -EINVAL; + } + + if (offset & 0x3) { + nvgpu_err(g, "offset (0x%08x) not 4-byte aligned", offset); + return -EINVAL; + } + + mem_size = gk20a_falcon_get_mem_size(flcn, mem_type); + if (!(offset <= mem_size && (offset + size) <= mem_size)) { + nvgpu_err(g, "flcn-id 0x%x, copy overflow ", + flcn->flcn_id); + nvgpu_err(g, "total size 0x%x, offset 0x%x, copy size 0x%x", + mem_size, offset, size); + return -EINVAL; + } + + return 0; +} + +static int gk20a_flcn_copy_from_dmem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 i, words, bytes; + u32 data, addr_mask; + u32 *dst_u32 = (u32 *)dst; + + nvgpu_log_fn(g, " src dmem offset - %x, size - %x", src, size); + + if (flcn_mem_overflow_check(flcn, src, size, MEM_DMEM)) { + nvgpu_err(g, "incorrect parameters"); + return -EINVAL; + } + + nvgpu_mutex_acquire(&flcn->copy_lock); + + words = size >> 2; + bytes = size & 0x3; + + addr_mask = falcon_falcon_dmemc_offs_m() | + falcon_falcon_dmemc_blk_m(); + + src &= addr_mask; + + gk20a_writel(g, base_addr + falcon_falcon_dmemc_r(port), + src | falcon_falcon_dmemc_aincr_f(1)); + + for (i = 0; i < words; i++) { + dst_u32[i] = gk20a_readl(g, + base_addr + falcon_falcon_dmemd_r(port)); + } + + if (bytes > 0) { + data = gk20a_readl(g, base_addr + falcon_falcon_dmemd_r(port)); + for (i = 0; i < bytes; i++) { + dst[(words << 2) + i] = ((u8 *)&data)[i]; + } + } + + nvgpu_mutex_release(&flcn->copy_lock); + return 0; +} + +static int gk20a_flcn_copy_to_dmem(struct nvgpu_falcon *flcn, + u32 dst, u8 *src, u32 size, u8 port) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 i, words, bytes; + u32 data, addr_mask; + u32 *src_u32 = (u32 *)src; + + nvgpu_log_fn(g, "dest dmem offset - %x, size - %x", dst, size); + + if (flcn_mem_overflow_check(flcn, dst, size, MEM_DMEM)) { + nvgpu_err(g, "incorrect parameters"); + return -EINVAL; + } + + nvgpu_mutex_acquire(&flcn->copy_lock); + + words = size >> 2; + bytes = size & 0x3; + + addr_mask = falcon_falcon_dmemc_offs_m() | + falcon_falcon_dmemc_blk_m(); + + dst &= addr_mask; + + gk20a_writel(g, base_addr + falcon_falcon_dmemc_r(port), + dst | falcon_falcon_dmemc_aincw_f(1)); + + for (i = 0; i < words; i++) { + gk20a_writel(g, + base_addr + falcon_falcon_dmemd_r(port), src_u32[i]); + } + + if (bytes > 0) { + data = 0; + for (i = 0; i < bytes; i++) { + ((u8 *)&data)[i] = src[(words << 2) + i]; + } + gk20a_writel(g, base_addr + falcon_falcon_dmemd_r(port), data); + } + + size = ALIGN(size, 4); + data = gk20a_readl(g, + base_addr + falcon_falcon_dmemc_r(port)) & addr_mask; + if (data != ((dst + size) & addr_mask)) { + nvgpu_warn(g, "copy failed. bytes written %d, expected %d", + data - dst, size); + } + + nvgpu_mutex_release(&flcn->copy_lock); + + return 0; +} + +static int gk20a_flcn_copy_from_imem(struct nvgpu_falcon *flcn, u32 src, + u8 *dst, u32 size, u8 port) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 *dst_u32 = (u32 *)dst; + u32 words = 0; + u32 bytes = 0; + u32 data = 0; + u32 blk = 0; + u32 i = 0; + + nvgpu_log_info(g, "download %d bytes from 0x%x", size, src); + + if (flcn_mem_overflow_check(flcn, src, size, MEM_IMEM)) { + nvgpu_err(g, "incorrect parameters"); + return -EINVAL; + } + + nvgpu_mutex_acquire(&flcn->copy_lock); + + words = size >> 2; + bytes = size & 0x3; + blk = src >> 8; + + nvgpu_log_info(g, "download %d words from 0x%x block %d", + words, src, blk); + + gk20a_writel(g, base_addr + falcon_falcon_imemc_r(port), + falcon_falcon_imemc_offs_f(src >> 2) | + falcon_falcon_imemc_blk_f(blk) | + falcon_falcon_dmemc_aincr_f(1)); + + for (i = 0; i < words; i++) { + dst_u32[i] = gk20a_readl(g, + base_addr + falcon_falcon_imemd_r(port)); + } + + if (bytes > 0) { + data = gk20a_readl(g, base_addr + falcon_falcon_imemd_r(port)); + for (i = 0; i < bytes; i++) { + dst[(words << 2) + i] = ((u8 *)&data)[i]; + } + } + + nvgpu_mutex_release(&flcn->copy_lock); + + return 0; +} + +static int gk20a_flcn_copy_to_imem(struct nvgpu_falcon *flcn, u32 dst, + u8 *src, u32 size, u8 port, bool sec, u32 tag) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 *src_u32 = (u32 *)src; + u32 words = 0; + u32 blk = 0; + u32 i = 0; + + nvgpu_log_info(g, "upload %d bytes to 0x%x", size, dst); + + if (flcn_mem_overflow_check(flcn, dst, size, MEM_IMEM)) { + nvgpu_err(g, "incorrect parameters"); + return -EINVAL; + } + + nvgpu_mutex_acquire(&flcn->copy_lock); + + words = size >> 2; + blk = dst >> 8; + + nvgpu_log_info(g, "upload %d words to 0x%x block %d, tag 0x%x", + words, dst, blk, tag); + + gk20a_writel(g, base_addr + falcon_falcon_imemc_r(port), + falcon_falcon_imemc_offs_f(dst >> 2) | + falcon_falcon_imemc_blk_f(blk) | + /* Set Auto-Increment on write */ + falcon_falcon_imemc_aincw_f(1) | + falcon_falcon_imemc_secure_f(sec ? 1U : 0U)); + + for (i = 0; i < words; i++) { + if (i % 64 == 0) { + /* tag is always 256B aligned */ + gk20a_writel(g, base_addr + falcon_falcon_imemt_r(0), + tag); + tag++; + } + + gk20a_writel(g, base_addr + falcon_falcon_imemd_r(port), + src_u32[i]); + } + + /* WARNING : setting remaining bytes in block to 0x0 */ + while (i % 64) { + gk20a_writel(g, base_addr + falcon_falcon_imemd_r(port), 0); + i++; + } + + nvgpu_mutex_release(&flcn->copy_lock); + + return 0; +} + +static int gk20a_falcon_bootstrap(struct nvgpu_falcon *flcn, + u32 boot_vector) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + + nvgpu_log_info(g, "boot vec 0x%x", boot_vector); + + gk20a_writel(g, base_addr + falcon_falcon_dmactl_r(), + falcon_falcon_dmactl_require_ctx_f(0)); + + gk20a_writel(g, base_addr + falcon_falcon_bootvec_r(), + falcon_falcon_bootvec_vec_f(boot_vector)); + + gk20a_writel(g, base_addr + falcon_falcon_cpuctl_r(), + falcon_falcon_cpuctl_startcpu_f(1)); + + return 0; +} + +static u32 gk20a_falcon_mailbox_read(struct nvgpu_falcon *flcn, + u32 mailbox_index) +{ + struct gk20a *g = flcn->g; + u32 data = 0; + + if (mailbox_index < FALCON_MAILBOX_COUNT) { + data = gk20a_readl(g, flcn->flcn_base + (mailbox_index ? + falcon_falcon_mailbox1_r() : + falcon_falcon_mailbox0_r())); + } else { + nvgpu_err(g, "incorrect mailbox id %d", mailbox_index); + } + + return data; +} + +static void gk20a_falcon_mailbox_write(struct nvgpu_falcon *flcn, + u32 mailbox_index, u32 data) +{ + struct gk20a *g = flcn->g; + + if (mailbox_index < FALCON_MAILBOX_COUNT) { + gk20a_writel(g, flcn->flcn_base + (mailbox_index ? + falcon_falcon_mailbox1_r() : + falcon_falcon_mailbox0_r()), + data); + } else { + nvgpu_err(g, "incorrect mailbox id %d", mailbox_index); + } +} + +static int gk20a_falcon_bl_bootstrap(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_bl_info *bl_info) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 virt_addr = 0; + u32 dst = 0; + int err = 0; + + /*copy bootloader interface structure to dmem*/ + err = gk20a_flcn_copy_to_dmem(flcn, 0, (u8 *)bl_info->bl_desc, + bl_info->bl_desc_size, (u8)0); + if (err != 0) { + goto exit; + } + + /* copy bootloader to TOP of IMEM */ + dst = (falcon_falcon_hwcfg_imem_size_v(gk20a_readl(g, + base_addr + falcon_falcon_hwcfg_r())) << 8) - bl_info->bl_size; + + err = gk20a_flcn_copy_to_imem(flcn, dst, (u8 *)(bl_info->bl_src), + bl_info->bl_size, (u8)0, false, bl_info->bl_start_tag); + if (err != 0) { + goto exit; + } + + gk20a_falcon_mailbox_write(flcn, FALCON_MAILBOX_0, 0xDEADA5A5U); + + virt_addr = bl_info->bl_start_tag << 8; + + err = gk20a_falcon_bootstrap(flcn, virt_addr); + +exit: + if (err != 0) { + nvgpu_err(g, "falcon id-0x%x bootstrap failed", flcn->flcn_id); + } + + return err; +} + +static void gk20a_falcon_dump_imblk(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 i = 0, j = 0; + u32 data[8] = {0}; + u32 block_count = 0; + + block_count = falcon_falcon_hwcfg_imem_size_v(gk20a_readl(g, + flcn->flcn_base + falcon_falcon_hwcfg_r())); + + /* block_count must be multiple of 8 */ + block_count &= ~0x7; + nvgpu_err(g, "FALCON IMEM BLK MAPPING (PA->VA) (%d TOTAL):", + block_count); + + for (i = 0; i < block_count; i += 8) { + for (j = 0; j < 8; j++) { + gk20a_writel(g, flcn->flcn_base + + falcon_falcon_imctl_debug_r(), + falcon_falcon_imctl_debug_cmd_f(0x2) | + falcon_falcon_imctl_debug_addr_blk_f(i + j)); + + data[j] = gk20a_readl(g, base_addr + + falcon_falcon_imstat_r()); + } + + nvgpu_err(g, " %#04x: %#010x %#010x %#010x %#010x", + i, data[0], data[1], data[2], data[3]); + nvgpu_err(g, " %#04x: %#010x %#010x %#010x %#010x", + i + 4, data[4], data[5], data[6], data[7]); + } +} + +static void gk20a_falcon_dump_pc_trace(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 trace_pc_count = 0; + u32 pc = 0; + u32 i = 0; + + if (gk20a_readl(g, base_addr + falcon_falcon_sctl_r()) & 0x02) { + nvgpu_err(g, " falcon is in HS mode, PC TRACE dump not supported"); + return; + } + + trace_pc_count = falcon_falcon_traceidx_maxidx_v(gk20a_readl(g, + base_addr + falcon_falcon_traceidx_r())); + nvgpu_err(g, + "PC TRACE (TOTAL %d ENTRIES. entry 0 is the most recent branch):", + trace_pc_count); + + for (i = 0; i < trace_pc_count; i++) { + gk20a_writel(g, base_addr + falcon_falcon_traceidx_r(), + falcon_falcon_traceidx_idx_f(i)); + + pc = falcon_falcon_tracepc_pc_v(gk20a_readl(g, + base_addr + falcon_falcon_tracepc_r())); + nvgpu_err(g, "FALCON_TRACEPC(%d) : %#010x", i, pc); + } +} + +void gk20a_falcon_dump_stats(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + unsigned int i; + + nvgpu_err(g, "<<< FALCON id-%d DEBUG INFORMATION - START >>>", + flcn->flcn_id); + + /* imblk dump */ + gk20a_falcon_dump_imblk(flcn); + /* PC trace dump */ + gk20a_falcon_dump_pc_trace(flcn); + + nvgpu_err(g, "FALCON ICD REGISTERS DUMP"); + + for (i = 0; i < 4; i++) { + gk20a_writel(g, base_addr + falcon_falcon_icd_cmd_r(), + falcon_falcon_icd_cmd_opc_rreg_f() | + falcon_falcon_icd_cmd_idx_f(FALCON_REG_PC)); + nvgpu_err(g, "FALCON_REG_PC : 0x%x", + gk20a_readl(g, base_addr + + falcon_falcon_icd_rdata_r())); + + gk20a_writel(g, base_addr + falcon_falcon_icd_cmd_r(), + falcon_falcon_icd_cmd_opc_rreg_f() | + falcon_falcon_icd_cmd_idx_f(FALCON_REG_SP)); + nvgpu_err(g, "FALCON_REG_SP : 0x%x", + gk20a_readl(g, base_addr + + falcon_falcon_icd_rdata_r())); + } + + gk20a_writel(g, base_addr + falcon_falcon_icd_cmd_r(), + falcon_falcon_icd_cmd_opc_rreg_f() | + falcon_falcon_icd_cmd_idx_f(FALCON_REG_IMB)); + nvgpu_err(g, "FALCON_REG_IMB : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_icd_rdata_r())); + + gk20a_writel(g, base_addr + falcon_falcon_icd_cmd_r(), + falcon_falcon_icd_cmd_opc_rreg_f() | + falcon_falcon_icd_cmd_idx_f(FALCON_REG_DMB)); + nvgpu_err(g, "FALCON_REG_DMB : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_icd_rdata_r())); + + gk20a_writel(g, base_addr + falcon_falcon_icd_cmd_r(), + falcon_falcon_icd_cmd_opc_rreg_f() | + falcon_falcon_icd_cmd_idx_f(FALCON_REG_CSW)); + nvgpu_err(g, "FALCON_REG_CSW : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_icd_rdata_r())); + + gk20a_writel(g, base_addr + falcon_falcon_icd_cmd_r(), + falcon_falcon_icd_cmd_opc_rreg_f() | + falcon_falcon_icd_cmd_idx_f(FALCON_REG_CTX)); + nvgpu_err(g, "FALCON_REG_CTX : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_icd_rdata_r())); + + gk20a_writel(g, base_addr + falcon_falcon_icd_cmd_r(), + falcon_falcon_icd_cmd_opc_rreg_f() | + falcon_falcon_icd_cmd_idx_f(FALCON_REG_EXCI)); + nvgpu_err(g, "FALCON_REG_EXCI : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_icd_rdata_r())); + + for (i = 0; i < 6; i++) { + gk20a_writel(g, base_addr + falcon_falcon_icd_cmd_r(), + falcon_falcon_icd_cmd_opc_rreg_f() | + falcon_falcon_icd_cmd_idx_f( + falcon_falcon_icd_cmd_opc_rstat_f())); + nvgpu_err(g, "FALCON_REG_RSTAT[%d] : 0x%x", i, + gk20a_readl(g, base_addr + + falcon_falcon_icd_rdata_r())); + } + + nvgpu_err(g, " FALCON REGISTERS DUMP"); + nvgpu_err(g, "falcon_falcon_os_r : %d", + gk20a_readl(g, base_addr + falcon_falcon_os_r())); + nvgpu_err(g, "falcon_falcon_cpuctl_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_cpuctl_r())); + nvgpu_err(g, "falcon_falcon_idlestate_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_idlestate_r())); + nvgpu_err(g, "falcon_falcon_mailbox0_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_mailbox0_r())); + nvgpu_err(g, "falcon_falcon_mailbox1_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_mailbox1_r())); + nvgpu_err(g, "falcon_falcon_irqstat_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_irqstat_r())); + nvgpu_err(g, "falcon_falcon_irqmode_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_irqmode_r())); + nvgpu_err(g, "falcon_falcon_irqmask_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_irqmask_r())); + nvgpu_err(g, "falcon_falcon_irqdest_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_irqdest_r())); + nvgpu_err(g, "falcon_falcon_debug1_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_debug1_r())); + nvgpu_err(g, "falcon_falcon_debuginfo_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_debuginfo_r())); + nvgpu_err(g, "falcon_falcon_bootvec_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_bootvec_r())); + nvgpu_err(g, "falcon_falcon_hwcfg_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_hwcfg_r())); + nvgpu_err(g, "falcon_falcon_engctl_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_engctl_r())); + nvgpu_err(g, "falcon_falcon_curctx_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_curctx_r())); + nvgpu_err(g, "falcon_falcon_nxtctx_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_nxtctx_r())); + nvgpu_err(g, "falcon_falcon_exterrstat_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_exterrstat_r())); + nvgpu_err(g, "falcon_falcon_exterraddr_r : 0x%x", + gk20a_readl(g, base_addr + falcon_falcon_exterraddr_r())); +} + +static void gk20a_falcon_engine_dependency_ops(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + struct nvgpu_falcon_engine_dependency_ops *flcn_eng_dep_ops = + &flcn->flcn_engine_dep_ops; + + switch (flcn->flcn_id) { + case FALCON_ID_PMU: + flcn_eng_dep_ops->reset_eng = nvgpu_pmu_reset; + flcn_eng_dep_ops->queue_head = g->ops.pmu.pmu_queue_head; + flcn_eng_dep_ops->queue_tail = g->ops.pmu.pmu_queue_tail; + break; + default: + /* NULL assignment make sure + * CPU hard reset in gk20a_flcn_reset() gets execute + * if falcon doesn't need specific reset implementation + */ + flcn_eng_dep_ops->reset_eng = NULL; + break; + } +} + +void gk20a_falcon_ops(struct nvgpu_falcon *flcn) +{ + struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops; + + flcn_ops->reset = gk20a_flcn_reset; + flcn_ops->set_irq = gk20a_flcn_set_irq; + flcn_ops->clear_halt_interrupt_status = + gk20a_flcn_clear_halt_interrupt_status; + flcn_ops->is_falcon_cpu_halted = gk20a_is_falcon_cpu_halted; + flcn_ops->is_falcon_idle = gk20a_is_falcon_idle; + flcn_ops->is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done; + flcn_ops->copy_from_dmem = gk20a_flcn_copy_from_dmem; + flcn_ops->copy_to_dmem = gk20a_flcn_copy_to_dmem; + flcn_ops->copy_to_imem = gk20a_flcn_copy_to_imem; + flcn_ops->copy_from_imem = gk20a_flcn_copy_from_imem; + flcn_ops->bootstrap = gk20a_falcon_bootstrap; + flcn_ops->dump_falcon_stats = gk20a_falcon_dump_stats; + flcn_ops->mailbox_read = gk20a_falcon_mailbox_read; + flcn_ops->mailbox_write = gk20a_falcon_mailbox_write; + flcn_ops->bl_bootstrap = gk20a_falcon_bl_bootstrap; + + gk20a_falcon_engine_dependency_ops(flcn); +} + +int gk20a_falcon_hal_sw_init(struct nvgpu_falcon *flcn) +{ + struct gk20a *g = flcn->g; + int err = 0; + + switch (flcn->flcn_id) { + case FALCON_ID_PMU: + flcn->flcn_base = FALCON_PWR_BASE; + flcn->is_falcon_supported = true; + flcn->is_interrupt_enabled = true; + break; + case FALCON_ID_SEC2: + flcn->flcn_base = FALCON_SEC_BASE; + flcn->is_falcon_supported = false; + flcn->is_interrupt_enabled = false; + break; + case FALCON_ID_FECS: + flcn->flcn_base = FALCON_FECS_BASE; + flcn->is_falcon_supported = true; + flcn->is_interrupt_enabled = false; + break; + case FALCON_ID_GPCCS: + flcn->flcn_base = FALCON_GPCCS_BASE; + flcn->is_falcon_supported = true; + flcn->is_interrupt_enabled = false; + break; + case FALCON_ID_NVDEC: + flcn->flcn_base = FALCON_NVDEC_BASE; + flcn->is_falcon_supported = false; + flcn->is_interrupt_enabled = false; + break; + default: + flcn->is_falcon_supported = false; + break; + } + + if (flcn->is_falcon_supported) { + err = nvgpu_mutex_init(&flcn->copy_lock); + if (err != 0) { + nvgpu_err(g, "Error in flcn.copy_lock mutex initialization"); + } else { + gk20a_falcon_ops(flcn); + } + } else { + nvgpu_log_info(g, "falcon 0x%x not supported on %s", + flcn->flcn_id, g->name); + } + + return err; +} diff --git a/include/gk20a/flcn_gk20a.h b/include/gk20a/flcn_gk20a.h new file mode 100644 index 0000000..9d27b38 --- /dev/null +++ b/include/gk20a/flcn_gk20a.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_GK20A_FLCN_GK20A_H +#define NVGPU_GK20A_FLCN_GK20A_H + +void gk20a_falcon_ops(struct nvgpu_falcon *flcn); +int gk20a_falcon_hal_sw_init(struct nvgpu_falcon *flcn); +void gk20a_falcon_dump_stats(struct nvgpu_falcon *flcn); + +#endif /* NVGPU_GK20A_FLCN_GK20A_H */ diff --git a/include/gk20a/gk20a.c b/include/gk20a/gk20a.c new file mode 100644 index 0000000..c3068b7 --- /dev/null +++ b/include/gk20a/gk20a.c @@ -0,0 +1,590 @@ +/* + * GK20A Graphics + * + * Copyright (c) 2011-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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "gk20a.h" + +#include "dbg_gpu_gk20a.h" +#include "pstate/pstate.h" + +void __nvgpu_check_gpu_state(struct gk20a *g) +{ + u32 boot_0 = 0xffffffff; + + boot_0 = nvgpu_mc_boot_0(g, NULL, NULL, NULL); + if (boot_0 == 0xffffffff) { + nvgpu_err(g, "GPU has disappeared from bus!!"); + nvgpu_err(g, "Rebooting system!!"); + nvgpu_kernel_restart(NULL); + } +} + +void __gk20a_warn_on_no_regs(void) +{ + WARN_ONCE(1, "Attempted access to GPU regs after unmapping!"); +} + +static void gk20a_mask_interrupts(struct gk20a *g) +{ + if (g->ops.mc.intr_mask != NULL) { + g->ops.mc.intr_mask(g); + } + + if (g->ops.mc.log_pending_intrs != NULL) { + g->ops.mc.log_pending_intrs(g); + } +} + +int gk20a_prepare_poweroff(struct gk20a *g) +{ + int ret = 0; + + nvgpu_log_fn(g, " "); + + if (g->ops.fifo.channel_suspend) { + ret = g->ops.fifo.channel_suspend(g); + if (ret) { + return ret; + } + } + + /* disable elpg before gr or fifo suspend */ + if (g->ops.pmu.is_pmu_supported(g)) { + ret |= nvgpu_pmu_destroy(g); + } + + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) { + ret |= nvgpu_sec2_destroy(g); + } + + ret |= gk20a_gr_suspend(g); + ret |= nvgpu_mm_suspend(g); + ret |= gk20a_fifo_suspend(g); + + gk20a_ce_suspend(g); + + /* Disable GPCPLL */ + if (g->ops.clk.suspend_clk_support) { + ret |= g->ops.clk.suspend_clk_support(g); + } + + if (nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) { + gk20a_deinit_pstate_support(g); + } + + gk20a_mask_interrupts(g); + + g->power_on = false; + + return ret; +} + +int gk20a_finalize_poweron(struct gk20a *g) +{ + int err = 0; +#if defined(CONFIG_TEGRA_GK20A_NVHOST) + u32 nr_pages; +#endif + + u32 fuse_status; + + nvgpu_log_fn(g, " "); + + if (g->power_on) { + return 0; + } + + g->power_on = true; + + /* + * Before probing the GPU make sure the GPU's state is cleared. This is + * relevant for rebind operations. + */ + if (g->ops.xve.reset_gpu && !g->gpu_reset_done) { + g->ops.xve.reset_gpu(g); + g->gpu_reset_done = true; + } + + if (g->ops.clock_gating.slcg_acb_load_gating_prod != NULL) { + g->ops.clock_gating.slcg_acb_load_gating_prod(g, true); + } + + /* + * Do this early so any early VMs that get made are capable of mapping + * buffers. + */ + err = nvgpu_pd_cache_init(g); + if (err) { + return err; + } + + /* init interface layer support for PMU falcon */ + err = nvgpu_flcn_sw_init(g, FALCON_ID_PMU); + if (err != 0) { + nvgpu_err(g, "failed to sw init FALCON_ID_PMU"); + goto done; + } + err = nvgpu_flcn_sw_init(g, FALCON_ID_SEC2); + if (err != 0) { + nvgpu_err(g, "failed to sw init FALCON_ID_SEC2"); + goto done; + } + err = nvgpu_flcn_sw_init(g, FALCON_ID_NVDEC); + if (err != 0) { + nvgpu_err(g, "failed to sw init FALCON_ID_NVDEC"); + goto done; + } + err = nvgpu_flcn_sw_init(g, FALCON_ID_GSPLITE); + if (err != 0) { + nvgpu_err(g, "failed to sw init FALCON_ID_GSPLITE"); + goto done; + } + + if (g->ops.acr.acr_sw_init != NULL && + nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) { + g->ops.acr.acr_sw_init(g, &g->acr); + } + + if (g->ops.bios.init) { + err = g->ops.bios.init(g); + } + if (err) { + goto done; + } + + g->ops.bus.init_hw(g); + + if (g->ops.clk.disable_slowboot) { + g->ops.clk.disable_slowboot(g); + } + + g->ops.priv_ring.enable_priv_ring(g); + + /* TBD: move this after graphics init in which blcg/slcg is enabled. + This function removes SlowdownOnBoot which applies 32x divider + on gpcpll bypass path. The purpose of slowdown is to save power + during boot but it also significantly slows down gk20a init on + simulation and emulation. We should remove SOB after graphics power + saving features (blcg/slcg) are enabled. For now, do it here. */ + if (g->ops.clk.init_clk_support) { + err = g->ops.clk.init_clk_support(g); + if (err) { + nvgpu_err(g, "failed to init gk20a clk"); + goto done; + } + } + + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_NVLINK)) { + err = g->ops.nvlink.init(g); + if (err) { + nvgpu_err(g, "failed to init nvlink"); + goto done; + } + } + + if (g->ops.fb.init_fbpa) { + err = g->ops.fb.init_fbpa(g); + if (err) { + nvgpu_err(g, "failed to init fbpa"); + goto done; + } + } + + if (g->ops.fb.mem_unlock) { + err = g->ops.fb.mem_unlock(g); + if (err) { + nvgpu_err(g, "failed to unlock memory"); + goto done; + } + } + + err = g->ops.fifo.reset_enable_hw(g); + + if (err) { + nvgpu_err(g, "failed to reset gk20a fifo"); + goto done; + } + + err = nvgpu_init_ltc_support(g); + if (err) { + nvgpu_err(g, "failed to init ltc"); + goto done; + } + + err = nvgpu_init_mm_support(g); + if (err) { + nvgpu_err(g, "failed to init gk20a mm"); + goto done; + } + + err = gk20a_init_fifo_support(g); + if (err) { + nvgpu_err(g, "failed to init gk20a fifo"); + goto done; + } + + if (g->ops.therm.elcg_init_idle_filters) { + g->ops.therm.elcg_init_idle_filters(g); + } + + g->ops.mc.intr_enable(g); + + /* + * Power gate the chip as per the TPC PG mask + * and the fuse_status register. + * If TPC PG mask is invalid halt the GPU poweron. + */ + g->can_tpc_powergate = false; + fuse_status = g->ops.fuse.fuse_status_opt_tpc_gpc(g, 0); + + if (g->ops.tpc.tpc_powergate) { + err = g->ops.tpc.tpc_powergate(g, fuse_status); + } + + if (err) { + nvgpu_err(g, "failed to power ON GPU"); + goto done; + } + + nvgpu_mutex_acquire(&g->tpc_pg_lock); + + if (g->can_tpc_powergate) { + if (g->ops.gr.powergate_tpc != NULL) + g->ops.gr.powergate_tpc(g); + } + + err = gk20a_enable_gr_hw(g); + if (err) { + nvgpu_err(g, "failed to enable gr"); + nvgpu_mutex_release(&g->tpc_pg_lock); + goto done; + } + + if (g->ops.pmu.is_pmu_supported(g)) { + if (g->ops.pmu.prepare_ucode) { + err = g->ops.pmu.prepare_ucode(g); + } + if (err) { + nvgpu_err(g, "failed to init pmu ucode"); + nvgpu_mutex_release(&g->tpc_pg_lock); + goto done; + } + } + + if (nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) { + err = gk20a_init_pstate_support(g); + if (err) { + nvgpu_err(g, "failed to init pstates"); + nvgpu_mutex_release(&g->tpc_pg_lock); + goto done; + } + } + + if (g->acr.bootstrap_hs_acr != NULL && + nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) { + err = g->acr.bootstrap_hs_acr(g, &g->acr, &g->acr.acr); + if (err != 0) { + nvgpu_err(g, "ACR bootstrap failed"); + nvgpu_mutex_release(&g->tpc_pg_lock); + goto done; + } + } + + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) { + err = nvgpu_init_sec2_support(g); + if (err != 0) { + nvgpu_err(g, "failed to init sec2"); + nvgpu_mutex_release(&g->tpc_pg_lock); + goto done; + } + } + + if (g->ops.pmu.is_pmu_supported(g)) { + err = nvgpu_init_pmu_support(g); + if (err) { + nvgpu_err(g, "failed to init gk20a pmu"); + nvgpu_mutex_release(&g->tpc_pg_lock); + goto done; + } + } + + err = gk20a_init_gr_support(g); + if (err) { + nvgpu_err(g, "failed to init gk20a gr"); + nvgpu_mutex_release(&g->tpc_pg_lock); + goto done; + } + + nvgpu_mutex_release(&g->tpc_pg_lock); + + if (nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) { + err = gk20a_init_pstate_pmu_support(g); + if (err) { + nvgpu_err(g, "failed to init pstates"); + goto done; + } + } + + if (g->ops.pmu_ver.clk.clk_set_boot_clk && nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) { + g->ops.pmu_ver.clk.clk_set_boot_clk(g); + } else { + err = nvgpu_clk_arb_init_arbiter(g); + if (err) { + nvgpu_err(g, "failed to init clk arb"); + goto done; + } + } + + err = nvgpu_init_therm_support(g); + if (err) { + nvgpu_err(g, "failed to init gk20a therm"); + goto done; + } + + err = g->ops.chip_init_gpu_characteristics(g); + if (err) { + nvgpu_err(g, "failed to init gk20a gpu characteristics"); + goto done; + } + +#ifdef CONFIG_GK20A_CTXSW_TRACE + err = gk20a_ctxsw_trace_init(g); + if (err) + nvgpu_warn(g, "could not initialize ctxsw tracing"); +#endif + + /* Restore the debug setting */ + g->ops.fb.set_debug_mode(g, g->mmu_debug_ctrl); + + gk20a_init_ce_support(g); + + if (g->ops.xve.available_speeds) { + u32 speed; + + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_ASPM) && g->ops.xve.disable_aspm) { + g->ops.xve.disable_aspm(g); + } + + g->ops.xve.available_speeds(g, &speed); + + /* Set to max speed */ + speed = 1 << (fls(speed) - 1); + err = g->ops.xve.set_speed(g, speed); + if (err) { + nvgpu_err(g, "Failed to set PCIe bus speed!"); + goto done; + } + } + +#if defined(CONFIG_TEGRA_GK20A_NVHOST) + if (nvgpu_has_syncpoints(g) && g->syncpt_unit_size) { + if (!nvgpu_mem_is_valid(&g->syncpt_mem)) { + nr_pages = DIV_ROUND_UP(g->syncpt_unit_size, PAGE_SIZE); + __nvgpu_mem_create_from_phys(g, &g->syncpt_mem, + g->syncpt_unit_base, nr_pages); + } + } +#endif + + if (g->ops.fifo.channel_resume) { + g->ops.fifo.channel_resume(g); + } + +done: + if (err) { + g->power_on = false; + } + + return err; +} + +int gk20a_wait_for_idle(struct gk20a *g) +{ + int wait_length = 150; /* 3 second overall max wait. */ + int target_usage_count = 0; + + if (!g) { + return -ENODEV; + } + + while ((nvgpu_atomic_read(&g->usage_count) != target_usage_count) + && (wait_length-- >= 0)) { + nvgpu_msleep(20); + } + + if (wait_length < 0) { + nvgpu_warn(g, "Timed out waiting for idle (%d)!\n", + nvgpu_atomic_read(&g->usage_count)); + return -ETIMEDOUT; + } + + return 0; +} + +int gk20a_init_gpu_characteristics(struct gk20a *g) +{ + __nvgpu_set_enabled(g, NVGPU_SUPPORT_PARTIAL_MAPPINGS, true); + __nvgpu_set_enabled(g, NVGPU_SUPPORT_MAP_DIRECT_KIND_CTRL, true); + __nvgpu_set_enabled(g, NVGPU_SUPPORT_MAP_BUFFER_BATCH, true); + + if (IS_ENABLED(CONFIG_SYNC)) { + __nvgpu_set_enabled(g, NVGPU_SUPPORT_SYNC_FENCE_FDS, true); + } + + if (g->ops.mm.support_sparse && g->ops.mm.support_sparse(g)) { + __nvgpu_set_enabled(g, NVGPU_SUPPORT_SPARSE_ALLOCS, true); + } + + /* + * Fast submits are supported as long as the user doesn't request + * anything that depends on job tracking. (Here, fast means strictly no + * metadata, just the gpfifo contents are copied and gp_put updated). + */ + __nvgpu_set_enabled(g, + NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_NO_JOBTRACKING, + true); + + /* + * Sync framework requires deferred job cleanup, wrapping syncs in FDs, + * and other heavy stuff, which prevents deterministic submits. This is + * supported otherwise, provided that the user doesn't request anything + * that depends on deferred cleanup. + */ + if (!nvgpu_channel_sync_needs_os_fence_framework(g)) { + __nvgpu_set_enabled(g, + NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_FULL, + true); + } + + __nvgpu_set_enabled(g, NVGPU_SUPPORT_DETERMINISTIC_OPTS, true); + + __nvgpu_set_enabled(g, NVGPU_SUPPORT_USERSPACE_MANAGED_AS, true); + __nvgpu_set_enabled(g, NVGPU_SUPPORT_TSG, true); + + if (g->ops.clk_arb.get_arbiter_clk_domains != NULL && + g->ops.clk.support_clk_freq_controller) { + __nvgpu_set_enabled(g, NVGPU_SUPPORT_CLOCK_CONTROLS, true); + } + + g->ops.gr.detect_sm_arch(g); + + if (g->ops.gr.init_cyclestats) { + g->ops.gr.init_cyclestats(g); + } + + g->ops.gr.get_rop_l2_en_mask(g); + + return 0; +} + +/* + * Free the gk20a struct. + */ +static void gk20a_free_cb(struct nvgpu_ref *refcount) +{ + struct gk20a *g = container_of(refcount, + struct gk20a, refcount); + + nvgpu_log(g, gpu_dbg_shutdown, "Freeing GK20A struct!"); + + gk20a_ce_destroy(g); + + if (g->remove_support) { + g->remove_support(g); + } + + if (g->free) { + g->free(g); + } +} + +/** + * gk20a_get() - Increment ref count on driver + * + * @g The driver to increment + * This will fail if the driver is in the process of being released. In that + * case it will return NULL. Otherwise a pointer to the driver passed in will + * be returned. + */ +struct gk20a * __must_check gk20a_get(struct gk20a *g) +{ + int success; + + /* + * Handle the possibility we are still freeing the gk20a struct while + * gk20a_get() is called. Unlikely but plausible race condition. Ideally + * the code will never be in such a situation that this race is + * possible. + */ + success = nvgpu_ref_get_unless_zero(&g->refcount); + + nvgpu_log(g, gpu_dbg_shutdown, "GET: refs currently %d %s", + nvgpu_atomic_read(&g->refcount.refcount), + success ? "" : "(FAILED)"); + + return success ? g : NULL; +} + +/** + * gk20a_put() - Decrement ref count on driver + * + * @g - The driver to decrement + * + * Decrement the driver ref-count. If neccesary also free the underlying driver + * memory + */ +void gk20a_put(struct gk20a *g) +{ + /* + * Note - this is racy, two instances of this could run before the + * actual kref_put(0 runs, you could see something like: + * + * ... PUT: refs currently 2 + * ... PUT: refs currently 2 + * ... Freeing GK20A struct! + */ + nvgpu_log(g, gpu_dbg_shutdown, "PUT: refs currently %d", + nvgpu_atomic_read(&g->refcount.refcount)); + + nvgpu_ref_put(&g->refcount, gk20a_free_cb); +} diff --git a/include/gk20a/gk20a.h b/include/gk20a/gk20a.h new file mode 100644 index 0000000..16a2453 --- /dev/null +++ b/include/gk20a/gk20a.h @@ -0,0 +1,33 @@ +/* + * This file is used as a temporary redirection header for + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * GK20A Graphics + * + * 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 GK20A_GK20A_H +#define GK20A_GK20A_H + +/* no new headers should be added here */ +#include + +#endif diff --git a/include/gk20a/gr_ctx_gk20a.c b/include/gk20a/gr_ctx_gk20a.c new file mode 100644 index 0000000..8b9ac32 --- /dev/null +++ b/include/gk20a/gr_ctx_gk20a.c @@ -0,0 +1,486 @@ +/* + * GK20A Graphics Context + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "gk20a.h" +#include "gr_ctx_gk20a.h" + +#include + +static int gr_gk20a_alloc_load_netlist_u32(struct gk20a *g, u32 *src, u32 len, + struct u32_list_gk20a *u32_list) +{ + u32_list->count = (len + sizeof(u32) - 1) / sizeof(u32); + if (!alloc_u32_list_gk20a(g, u32_list)) { + return -ENOMEM; + } + + memcpy(u32_list->l, src, len); + + return 0; +} + +static int gr_gk20a_alloc_load_netlist_av(struct gk20a *g, u32 *src, u32 len, + struct av_list_gk20a *av_list) +{ + av_list->count = len / sizeof(struct av_gk20a); + if (!alloc_av_list_gk20a(g, av_list)) { + return -ENOMEM; + } + + memcpy(av_list->l, src, len); + + return 0; +} + +static int gr_gk20a_alloc_load_netlist_av64(struct gk20a *g, u32 *src, u32 len, + struct av64_list_gk20a *av64_list) +{ + av64_list->count = len / sizeof(struct av64_gk20a); + if (!alloc_av64_list_gk20a(g, av64_list)) { + return -ENOMEM; + } + + memcpy(av64_list->l, src, len); + + return 0; +} + +static int gr_gk20a_alloc_load_netlist_aiv(struct gk20a *g, u32 *src, u32 len, + struct aiv_list_gk20a *aiv_list) +{ + aiv_list->count = len / sizeof(struct aiv_gk20a); + if (!alloc_aiv_list_gk20a(g, aiv_list)) { + return -ENOMEM; + } + + memcpy(aiv_list->l, src, len); + + return 0; +} + +static int gr_gk20a_init_ctx_vars_fw(struct gk20a *g, struct gr_gk20a *gr) +{ + struct nvgpu_firmware *netlist_fw; + struct netlist_image *netlist = NULL; + char name[MAX_NETLIST_NAME]; + u32 i, major_v = ~0, major_v_hw, netlist_num; + int net, max, err = -ENOENT; + + nvgpu_log_fn(g, " "); + + if (g->ops.gr_ctx.is_fw_defined()) { + net = NETLIST_FINAL; + max = 0; + major_v_hw = ~0; + g->gr.ctx_vars.dynamic = false; + } else { + net = NETLIST_SLOT_A; + max = MAX_NETLIST; + major_v_hw = gk20a_readl(g, + gr_fecs_ctx_state_store_major_rev_id_r()); + g->gr.ctx_vars.dynamic = true; + } + + for (; net < max; net++) { + if (g->ops.gr_ctx.get_netlist_name(g, net, name) != 0) { + nvgpu_warn(g, "invalid netlist index %d", net); + continue; + } + + netlist_fw = nvgpu_request_firmware(g, name, 0); + if (!netlist_fw) { + nvgpu_warn(g, "failed to load netlist %s", name); + continue; + } + + netlist = (struct netlist_image *)netlist_fw->data; + + for (i = 0; i < netlist->header.regions; i++) { + u32 *src = (u32 *)((u8 *)netlist + netlist->regions[i].data_offset); + u32 size = netlist->regions[i].data_size; + + switch (netlist->regions[i].region_id) { + case NETLIST_REGIONID_FECS_UCODE_DATA: + nvgpu_log_info(g, "NETLIST_REGIONID_FECS_UCODE_DATA"); + err = gr_gk20a_alloc_load_netlist_u32(g, + src, size, &g->gr.ctx_vars.ucode.fecs.data); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_FECS_UCODE_INST: + nvgpu_log_info(g, "NETLIST_REGIONID_FECS_UCODE_INST"); + err = gr_gk20a_alloc_load_netlist_u32(g, + src, size, &g->gr.ctx_vars.ucode.fecs.inst); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_GPCCS_UCODE_DATA: + nvgpu_log_info(g, "NETLIST_REGIONID_GPCCS_UCODE_DATA"); + err = gr_gk20a_alloc_load_netlist_u32(g, + src, size, &g->gr.ctx_vars.ucode.gpccs.data); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_GPCCS_UCODE_INST: + nvgpu_log_info(g, "NETLIST_REGIONID_GPCCS_UCODE_INST"); + err = gr_gk20a_alloc_load_netlist_u32(g, + src, size, &g->gr.ctx_vars.ucode.gpccs.inst); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_SW_BUNDLE_INIT: + nvgpu_log_info(g, "NETLIST_REGIONID_SW_BUNDLE_INIT"); + err = gr_gk20a_alloc_load_netlist_av(g, + src, size, &g->gr.ctx_vars.sw_bundle_init); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_SW_METHOD_INIT: + nvgpu_log_info(g, "NETLIST_REGIONID_SW_METHOD_INIT"); + err = gr_gk20a_alloc_load_netlist_av(g, + src, size, &g->gr.ctx_vars.sw_method_init); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_SW_CTX_LOAD: + nvgpu_log_info(g, "NETLIST_REGIONID_SW_CTX_LOAD"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.sw_ctx_load); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_SW_NON_CTX_LOAD: + nvgpu_log_info(g, "NETLIST_REGIONID_SW_NON_CTX_LOAD"); + err = gr_gk20a_alloc_load_netlist_av(g, + src, size, &g->gr.ctx_vars.sw_non_ctx_load); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_SWVEIDBUNDLEINIT: + nvgpu_log_info(g, + "NETLIST_REGIONID_SW_VEID_BUNDLE_INIT"); + err = gr_gk20a_alloc_load_netlist_av(g, + src, size, + &g->gr.ctx_vars.sw_veid_bundle_init); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_SYS: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_SYS"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.sys); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_GPC: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_GPC"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.gpc); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_TPC: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_TPC"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.tpc); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_ZCULL_GPC: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_ZCULL_GPC"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.zcull_gpc); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_PPC: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_PPC"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.ppc); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_PM_SYS: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_PM_SYS"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.pm_sys); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_PM_GPC: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_PM_GPC"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.pm_gpc); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_PM_TPC: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_PM_TPC"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.pm_tpc); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_BUFFER_SIZE: + g->gr.ctx_vars.buffer_size = *src; + nvgpu_log_info(g, "NETLIST_REGIONID_BUFFER_SIZE : %d", + g->gr.ctx_vars.buffer_size); + break; + case NETLIST_REGIONID_CTXSW_REG_BASE_INDEX: + g->gr.ctx_vars.regs_base_index = *src; + nvgpu_log_info(g, "NETLIST_REGIONID_CTXSW_REG_BASE_INDEX : %u", + g->gr.ctx_vars.regs_base_index); + break; + case NETLIST_REGIONID_MAJORV: + major_v = *src; + nvgpu_log_info(g, "NETLIST_REGIONID_MAJORV : %d", + major_v); + break; + case NETLIST_REGIONID_NETLIST_NUM: + netlist_num = *src; + nvgpu_log_info(g, "NETLIST_REGIONID_NETLIST_NUM : %d", + netlist_num); + break; + case NETLIST_REGIONID_CTXREG_PMPPC: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_PMPPC"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.pm_ppc); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_NVPERF_CTXREG_SYS: + nvgpu_log_info(g, "NETLIST_REGIONID_NVPERF_CTXREG_SYS"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.perf_sys); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_NVPERF_FBP_CTXREGS: + nvgpu_log_info(g, "NETLIST_REGIONID_NVPERF_FBP_CTXREGS"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.fbp); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_NVPERF_CTXREG_GPC: + nvgpu_log_info(g, "NETLIST_REGIONID_NVPERF_CTXREG_GPC"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.perf_gpc); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_NVPERF_FBP_ROUTER: + nvgpu_log_info(g, "NETLIST_REGIONID_NVPERF_FBP_ROUTER"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.fbp_router); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_NVPERF_GPC_ROUTER: + nvgpu_log_info(g, "NETLIST_REGIONID_NVPERF_GPC_ROUTER"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.gpc_router); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_PMLTC: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_PMLTC"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.pm_ltc); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_PMFBPA: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_PMFBPA"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.pm_fbpa); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_NVPERF_SYS_ROUTER: + nvgpu_log_info(g, "NETLIST_REGIONID_NVPERF_SYS_ROUTER"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.perf_sys_router); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_NVPERF_PMA: + nvgpu_log_info(g, "NETLIST_REGIONID_NVPERF_PMA"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.perf_pma); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_PMROP: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_PMROP"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.pm_rop); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_PMUCGPC: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_PMUCGPC"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.pm_ucgpc); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_CTXREG_ETPC: + nvgpu_log_info(g, "NETLIST_REGIONID_CTXREG_ETPC"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, &g->gr.ctx_vars.ctxsw_regs.etpc); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_SW_BUNDLE64_INIT: + nvgpu_log_info(g, "NETLIST_REGIONID_SW_BUNDLE64_INIT"); + err = gr_gk20a_alloc_load_netlist_av64(g, + src, size, + &g->gr.ctx_vars.sw_bundle64_init); + if (err) { + goto clean_up; + } + break; + case NETLIST_REGIONID_NVPERF_PMCAU: + nvgpu_log_info(g, "NETLIST_REGIONID_NVPERF_PMCAU"); + err = gr_gk20a_alloc_load_netlist_aiv(g, + src, size, + &g->gr.ctx_vars.ctxsw_regs.pm_cau); + if (err) { + goto clean_up; + } + break; + + default: + nvgpu_log_info(g, "unrecognized region %d skipped", i); + break; + } + } + + if (net != NETLIST_FINAL && major_v != major_v_hw) { + nvgpu_log_info(g, "skip %s: major_v 0x%08x doesn't match hw 0x%08x", + name, major_v, major_v_hw); + goto clean_up; + } + + g->gr.ctx_vars.valid = true; + g->gr.netlist = net; + + nvgpu_release_firmware(g, netlist_fw); + nvgpu_log_fn(g, "done"); + goto done; + +clean_up: + g->gr.ctx_vars.valid = false; + nvgpu_kfree(g, g->gr.ctx_vars.ucode.fecs.inst.l); + nvgpu_kfree(g, g->gr.ctx_vars.ucode.fecs.data.l); + nvgpu_kfree(g, g->gr.ctx_vars.ucode.gpccs.inst.l); + nvgpu_kfree(g, g->gr.ctx_vars.ucode.gpccs.data.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_bundle_init.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_method_init.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_ctx_load.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_non_ctx_load.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_veid_bundle_init.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.sys.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.gpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.tpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.zcull_gpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.ppc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_sys.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_gpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_tpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_ppc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.perf_sys.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.fbp.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.perf_gpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.fbp_router.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.gpc_router.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_ltc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_fbpa.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.perf_sys_router.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.perf_pma.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_rop.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_ucgpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.etpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_bundle64_init.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_cau.l); + nvgpu_release_firmware(g, netlist_fw); + err = -ENOENT; + } + +done: + if (g->gr.ctx_vars.valid) { + nvgpu_log_info(g, "netlist image %s loaded", name); + return 0; + } else { + nvgpu_err(g, "failed to load netlist image!!"); + return err; + } +} + +int gr_gk20a_init_ctx_vars(struct gk20a *g, struct gr_gk20a *gr) +{ + if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) { + return gr_gk20a_init_ctx_vars_sim(g, gr); + } else { + return gr_gk20a_init_ctx_vars_fw(g, gr); + } +} diff --git a/include/gk20a/gr_ctx_gk20a.h b/include/gk20a/gr_ctx_gk20a.h new file mode 100644 index 0000000..e75472c --- /dev/null +++ b/include/gk20a/gr_ctx_gk20a.h @@ -0,0 +1,206 @@ +/* + * GK20A Graphics Context + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_GK20A_GR_CTX_GK20A_H +#define NVGPU_GK20A_GR_CTX_GK20A_H + +#include + +struct gr_gk20a; + +/* emulation netlists, match majorV with HW */ +#define GK20A_NETLIST_IMAGE_A "NETA_img.bin" +#define GK20A_NETLIST_IMAGE_B "NETB_img.bin" +#define GK20A_NETLIST_IMAGE_C "NETC_img.bin" +#define GK20A_NETLIST_IMAGE_D "NETD_img.bin" + +/* + * Need to support multiple ARCH in same GPU family + * then need to provide path like ARCH/NETIMAGE to + * point to correct netimage within GPU family, + * Example, gm20x can support gm204 or gm206,so path + * for netimage is gm204/NETC_img.bin, and '/' char + * will inserted at null terminator char of "GAxxx" + * to get complete path like gm204/NETC_img.bin + */ +#define GPU_ARCH "GAxxx" + +union __max_name { +#ifdef GK20A_NETLIST_IMAGE_A + char __name_a[sizeof(GK20A_NETLIST_IMAGE_A)]; +#endif +#ifdef GK20A_NETLIST_IMAGE_B + char __name_b[sizeof(GK20A_NETLIST_IMAGE_B)]; +#endif +#ifdef GK20A_NETLIST_IMAGE_C + char __name_c[sizeof(GK20A_NETLIST_IMAGE_C)]; +#endif +#ifdef GK20A_NETLIST_IMAGE_D + char __name_d[sizeof(GK20A_NETLIST_IMAGE_D)]; +#endif +}; + +#define MAX_NETLIST_NAME (sizeof(GPU_ARCH) + sizeof(union __max_name)) + +/* index for emulation netlists */ +#define NETLIST_FINAL -1 +#define NETLIST_SLOT_A 0 +#define NETLIST_SLOT_B 1 +#define NETLIST_SLOT_C 2 +#define NETLIST_SLOT_D 3 +#define MAX_NETLIST 4 + +/* netlist regions */ +#define NETLIST_REGIONID_FECS_UCODE_DATA 0 +#define NETLIST_REGIONID_FECS_UCODE_INST 1 +#define NETLIST_REGIONID_GPCCS_UCODE_DATA 2 +#define NETLIST_REGIONID_GPCCS_UCODE_INST 3 +#define NETLIST_REGIONID_SW_BUNDLE_INIT 4 +#define NETLIST_REGIONID_SW_CTX_LOAD 5 +#define NETLIST_REGIONID_SW_NON_CTX_LOAD 6 +#define NETLIST_REGIONID_SW_METHOD_INIT 7 +#define NETLIST_REGIONID_CTXREG_SYS 8 +#define NETLIST_REGIONID_CTXREG_GPC 9 +#define NETLIST_REGIONID_CTXREG_TPC 10 +#define NETLIST_REGIONID_CTXREG_ZCULL_GPC 11 +#define NETLIST_REGIONID_CTXREG_PM_SYS 12 +#define NETLIST_REGIONID_CTXREG_PM_GPC 13 +#define NETLIST_REGIONID_CTXREG_PM_TPC 14 +#define NETLIST_REGIONID_MAJORV 15 +#define NETLIST_REGIONID_BUFFER_SIZE 16 +#define NETLIST_REGIONID_CTXSW_REG_BASE_INDEX 17 +#define NETLIST_REGIONID_NETLIST_NUM 18 +#define NETLIST_REGIONID_CTXREG_PPC 19 +#define NETLIST_REGIONID_CTXREG_PMPPC 20 +#define NETLIST_REGIONID_NVPERF_CTXREG_SYS 21 +#define NETLIST_REGIONID_NVPERF_FBP_CTXREGS 22 +#define NETLIST_REGIONID_NVPERF_CTXREG_GPC 23 +#define NETLIST_REGIONID_NVPERF_FBP_ROUTER 24 +#define NETLIST_REGIONID_NVPERF_GPC_ROUTER 25 +#define NETLIST_REGIONID_CTXREG_PMLTC 26 +#define NETLIST_REGIONID_CTXREG_PMFBPA 27 +#define NETLIST_REGIONID_SWVEIDBUNDLEINIT 28 +#define NETLIST_REGIONID_NVPERF_SYS_ROUTER 29 +#define NETLIST_REGIONID_NVPERF_PMA 30 +#define NETLIST_REGIONID_CTXREG_PMROP 31 +#define NETLIST_REGIONID_CTXREG_PMUCGPC 32 +#define NETLIST_REGIONID_CTXREG_ETPC 33 +#define NETLIST_REGIONID_SW_BUNDLE64_INIT 34 +#define NETLIST_REGIONID_NVPERF_PMCAU 35 + +struct netlist_region { + u32 region_id; + u32 data_size; + u32 data_offset; +}; + +struct netlist_image_header { + u32 version; + u32 regions; +}; + +struct netlist_image { + struct netlist_image_header header; + struct netlist_region regions[1]; +}; + +struct av_gk20a { + u32 addr; + u32 value; +}; +struct av64_gk20a { + u32 addr; + u32 value_lo; + u32 value_hi; +}; +struct aiv_gk20a { + u32 addr; + u32 index; + u32 value; +}; +struct aiv_list_gk20a { + struct aiv_gk20a *l; + u32 count; +}; +struct av_list_gk20a { + struct av_gk20a *l; + u32 count; +}; +struct av64_list_gk20a { + struct av64_gk20a *l; + u32 count; +}; +struct u32_list_gk20a { + u32 *l; + u32 count; +}; + +struct ctxsw_buf_offset_map_entry { + u32 addr; /* Register address */ + u32 offset; /* Offset in ctxt switch buffer */ +}; + +static inline +struct av_gk20a *alloc_av_list_gk20a(struct gk20a *g, struct av_list_gk20a *avl) +{ + avl->l = nvgpu_kzalloc(g, avl->count * sizeof(*avl->l)); + return avl->l; +} + +static inline +struct av64_gk20a *alloc_av64_list_gk20a(struct gk20a *g, struct av64_list_gk20a *avl) +{ + avl->l = nvgpu_kzalloc(g, avl->count * sizeof(*avl->l)); + return avl->l; +} + +static inline +struct aiv_gk20a *alloc_aiv_list_gk20a(struct gk20a *g, + struct aiv_list_gk20a *aivl) +{ + aivl->l = nvgpu_kzalloc(g, aivl->count * sizeof(*aivl->l)); + return aivl->l; +} + +static inline +u32 *alloc_u32_list_gk20a(struct gk20a *g, struct u32_list_gk20a *u32l) +{ + u32l->l = nvgpu_kzalloc(g, u32l->count * sizeof(*u32l->l)); + return u32l->l; +} + +struct gr_ucode_gk20a { + struct { + struct u32_list_gk20a inst; + struct u32_list_gk20a data; + } gpccs, fecs; +}; + +/* main entry for grctx loading */ +int gr_gk20a_init_ctx_vars(struct gk20a *g, struct gr_gk20a *gr); +int gr_gk20a_init_ctx_vars_sim(struct gk20a *g, struct gr_gk20a *gr); + +struct gpu_ops; +void gk20a_init_gr_ctx(struct gpu_ops *gops); + +#endif /*NVGPU_GK20A_GR_CTX_GK20A_H*/ diff --git a/include/gk20a/gr_ctx_gk20a_sim.c b/include/gk20a/gr_ctx_gk20a_sim.c new file mode 100644 index 0000000..ce65c77 --- /dev/null +++ b/include/gk20a/gr_ctx_gk20a_sim.c @@ -0,0 +1,356 @@ +/* + * GK20A Graphics Context for Simulation + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "gk20a.h" +#include +#include "gr_ctx_gk20a.h" + +#include + +int gr_gk20a_init_ctx_vars_sim(struct gk20a *g, struct gr_gk20a *gr) +{ + int err = -ENOMEM; + u32 i, temp; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_info, + "querying grctx info from chiplib"); + + g->gr.ctx_vars.dynamic = true; + g->gr.netlist = GR_NETLIST_DYNAMIC; + + if (g->sim->esc_readl == NULL) { + nvgpu_err(g, "Invalid pointer to query function."); + err = -ENOENT; + goto fail; + } + + /* query sizes and counts */ + g->sim->esc_readl(g, "GRCTX_UCODE_INST_FECS_COUNT", 0, + &g->gr.ctx_vars.ucode.fecs.inst.count); + g->sim->esc_readl(g, "GRCTX_UCODE_DATA_FECS_COUNT", 0, + &g->gr.ctx_vars.ucode.fecs.data.count); + g->sim->esc_readl(g, "GRCTX_UCODE_INST_GPCCS_COUNT", 0, + &g->gr.ctx_vars.ucode.gpccs.inst.count); + g->sim->esc_readl(g, "GRCTX_UCODE_DATA_GPCCS_COUNT", 0, + &g->gr.ctx_vars.ucode.gpccs.data.count); + g->sim->esc_readl(g, "GRCTX_ALL_CTX_TOTAL_WORDS", 0, &temp); + g->gr.ctx_vars.buffer_size = temp << 2; + g->sim->esc_readl(g, "GRCTX_SW_BUNDLE_INIT_SIZE", 0, + &g->gr.ctx_vars.sw_bundle_init.count); + g->sim->esc_readl(g, "GRCTX_SW_METHOD_INIT_SIZE", 0, + &g->gr.ctx_vars.sw_method_init.count); + g->sim->esc_readl(g, "GRCTX_SW_CTX_LOAD_SIZE", 0, + &g->gr.ctx_vars.sw_ctx_load.count); + g->sim->esc_readl(g, "GRCTX_SW_VEID_BUNDLE_INIT_SIZE", 0, + &g->gr.ctx_vars.sw_veid_bundle_init.count); + g->sim->esc_readl(g, "GRCTX_SW_BUNDLE64_INIT_SIZE", 0, + &g->gr.ctx_vars.sw_bundle64_init.count); + + g->sim->esc_readl(g, "GRCTX_NONCTXSW_REG_SIZE", 0, + &g->gr.ctx_vars.sw_non_ctx_load.count); + g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS_COUNT", 0, + &g->gr.ctx_vars.ctxsw_regs.sys.count); + g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC_COUNT", 0, + &g->gr.ctx_vars.ctxsw_regs.gpc.count); + g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC_COUNT", 0, + &g->gr.ctx_vars.ctxsw_regs.tpc.count); + g->sim->esc_readl(g, "GRCTX_REG_LIST_ZCULL_GPC_COUNT", 0, + &g->gr.ctx_vars.ctxsw_regs.zcull_gpc.count); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_SYS_COUNT", 0, + &g->gr.ctx_vars.ctxsw_regs.pm_sys.count); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_GPC_COUNT", 0, + &g->gr.ctx_vars.ctxsw_regs.pm_gpc.count); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_TPC_COUNT", 0, + &g->gr.ctx_vars.ctxsw_regs.pm_tpc.count); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC_COUNT", 0, + &g->gr.ctx_vars.ctxsw_regs.ppc.count); + g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC_COUNT", 0, + &g->gr.ctx_vars.ctxsw_regs.etpc.count); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC_COUNT", 0, + &g->gr.ctx_vars.ctxsw_regs.ppc.count); + + if (alloc_u32_list_gk20a(g, &g->gr.ctx_vars.ucode.fecs.inst) == NULL) { + goto fail; + } + if (alloc_u32_list_gk20a(g, &g->gr.ctx_vars.ucode.fecs.data) == NULL) { + goto fail; + } + if (alloc_u32_list_gk20a(g, &g->gr.ctx_vars.ucode.gpccs.inst) == NULL) { + goto fail; + } + if (alloc_u32_list_gk20a(g, &g->gr.ctx_vars.ucode.gpccs.data) == NULL) { + goto fail; + } + if (alloc_av_list_gk20a(g, &g->gr.ctx_vars.sw_bundle_init) == NULL) { + goto fail; + } + if (alloc_av64_list_gk20a(g, + &g->gr.ctx_vars.sw_bundle64_init) == NULL) { + goto fail; + } + if (alloc_av_list_gk20a(g, &g->gr.ctx_vars.sw_method_init) == NULL) { + goto fail; + } + if (alloc_aiv_list_gk20a(g, &g->gr.ctx_vars.sw_ctx_load) == NULL) { + goto fail; + } + if (alloc_av_list_gk20a(g, &g->gr.ctx_vars.sw_non_ctx_load) == NULL) { + goto fail; + } + if (alloc_av_list_gk20a(g, + &g->gr.ctx_vars.sw_veid_bundle_init) == NULL) { + goto fail; + } + if (alloc_aiv_list_gk20a(g, &g->gr.ctx_vars.ctxsw_regs.sys) == NULL) { + goto fail; + } + if (alloc_aiv_list_gk20a(g, &g->gr.ctx_vars.ctxsw_regs.gpc) == NULL) { + goto fail; + } + if (alloc_aiv_list_gk20a(g, &g->gr.ctx_vars.ctxsw_regs.tpc) == NULL) { + goto fail; + } + if (alloc_aiv_list_gk20a(g, + &g->gr.ctx_vars.ctxsw_regs.zcull_gpc) == NULL) { + goto fail; + } + if (alloc_aiv_list_gk20a(g, &g->gr.ctx_vars.ctxsw_regs.ppc) == NULL) { + goto fail; + } + if (alloc_aiv_list_gk20a(g, + &g->gr.ctx_vars.ctxsw_regs.pm_sys) == NULL) { + goto fail; + } + if (alloc_aiv_list_gk20a(g, + &g->gr.ctx_vars.ctxsw_regs.pm_gpc) == NULL) { + goto fail; + } + if (alloc_aiv_list_gk20a(g, + &g->gr.ctx_vars.ctxsw_regs.pm_tpc) == NULL) { + goto fail; + } + if (alloc_aiv_list_gk20a(g, &g->gr.ctx_vars.ctxsw_regs.etpc) == NULL) { + goto fail; + } + + for (i = 0; i < g->gr.ctx_vars.ucode.fecs.inst.count; i++) { + g->sim->esc_readl(g, "GRCTX_UCODE_INST_FECS", + i, &g->gr.ctx_vars.ucode.fecs.inst.l[i]); + } + + for (i = 0; i < g->gr.ctx_vars.ucode.fecs.data.count; i++) { + g->sim->esc_readl(g, "GRCTX_UCODE_DATA_FECS", + i, &g->gr.ctx_vars.ucode.fecs.data.l[i]); + } + + for (i = 0; i < g->gr.ctx_vars.ucode.gpccs.inst.count; i++) { + g->sim->esc_readl(g, "GRCTX_UCODE_INST_GPCCS", + i, &g->gr.ctx_vars.ucode.gpccs.inst.l[i]); + } + + for (i = 0; i < g->gr.ctx_vars.ucode.gpccs.data.count; i++) { + g->sim->esc_readl(g, "GRCTX_UCODE_DATA_GPCCS", + i, &g->gr.ctx_vars.ucode.gpccs.data.l[i]); + } + + for (i = 0; i < g->gr.ctx_vars.sw_bundle_init.count; i++) { + struct av_gk20a *l = g->gr.ctx_vars.sw_bundle_init.l; + g->sim->esc_readl(g, "GRCTX_SW_BUNDLE_INIT:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_SW_BUNDLE_INIT:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.sw_method_init.count; i++) { + struct av_gk20a *l = g->gr.ctx_vars.sw_method_init.l; + g->sim->esc_readl(g, "GRCTX_SW_METHOD_INIT:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_SW_METHOD_INIT:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.sw_ctx_load.count; i++) { + struct aiv_gk20a *l = g->gr.ctx_vars.sw_ctx_load.l; + g->sim->esc_readl(g, "GRCTX_SW_CTX_LOAD:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_SW_CTX_LOAD:INDEX", + i, &l[i].index); + g->sim->esc_readl(g, "GRCTX_SW_CTX_LOAD:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.sw_non_ctx_load.count; i++) { + struct av_gk20a *l = g->gr.ctx_vars.sw_non_ctx_load.l; + g->sim->esc_readl(g, "GRCTX_NONCTXSW_REG:REG", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_NONCTXSW_REG:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.sw_veid_bundle_init.count; i++) { + struct av_gk20a *l = g->gr.ctx_vars.sw_veid_bundle_init.l; + + g->sim->esc_readl(g, "GRCTX_SW_VEID_BUNDLE_INIT:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_SW_VEID_BUNDLE_INIT:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.sw_bundle64_init.count; i++) { + struct av64_gk20a *l = g->gr.ctx_vars.sw_bundle64_init.l; + + g->sim->esc_readl(g, "GRCTX_SW_BUNDLE64_INIT:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_SW_BUNDLE64_INIT:VALUE_LO", + i, &l[i].value_lo); + g->sim->esc_readl(g, "GRCTX_SW_BUNDLE64_INIT:VALUE_HI", + i, &l[i].value_hi); + } + + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.sys.count; i++) { + struct aiv_gk20a *l = g->gr.ctx_vars.ctxsw_regs.sys.l; + g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS:INDEX", + i, &l[i].index); + g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.gpc.count; i++) { + struct aiv_gk20a *l = g->gr.ctx_vars.ctxsw_regs.gpc.l; + g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC:INDEX", + i, &l[i].index); + g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.tpc.count; i++) { + struct aiv_gk20a *l = g->gr.ctx_vars.ctxsw_regs.tpc.l; + g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC:INDEX", + i, &l[i].index); + g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.ppc.count; i++) { + struct aiv_gk20a *l = g->gr.ctx_vars.ctxsw_regs.ppc.l; + g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC:INDEX", + i, &l[i].index); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.zcull_gpc.count; i++) { + struct aiv_gk20a *l = g->gr.ctx_vars.ctxsw_regs.zcull_gpc.l; + g->sim->esc_readl(g, "GRCTX_REG_LIST_ZCULL_GPC:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_REG_LIST_ZCULL_GPC:INDEX", + i, &l[i].index); + g->sim->esc_readl(g, "GRCTX_REG_LIST_ZCULL_GPC:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.pm_sys.count; i++) { + struct aiv_gk20a *l = g->gr.ctx_vars.ctxsw_regs.pm_sys.l; + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_SYS:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_SYS:INDEX", + i, &l[i].index); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_SYS:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.pm_gpc.count; i++) { + struct aiv_gk20a *l = g->gr.ctx_vars.ctxsw_regs.pm_gpc.l; + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_GPC:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_GPC:INDEX", + i, &l[i].index); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_GPC:VALUE", + i, &l[i].value); + } + + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.pm_tpc.count; i++) { + struct aiv_gk20a *l = g->gr.ctx_vars.ctxsw_regs.pm_tpc.l; + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_TPC:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_TPC:INDEX", + i, &l[i].index); + g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_TPC:VALUE", + i, &l[i].value); + } + + nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_ETPC"); + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.etpc.count; i++) { + struct aiv_gk20a *l = g->gr.ctx_vars.ctxsw_regs.etpc.l; + g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC:ADDR", + i, &l[i].addr); + g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC:INDEX", + i, &l[i].index); + g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC:VALUE", + i, &l[i].value); + nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, + "addr:0x%#08x index:0x%08x value:0x%08x", + l[i].addr, l[i].index, l[i].value); + } + + g->gr.ctx_vars.valid = true; + + g->sim->esc_readl(g, "GRCTX_GEN_CTX_REGS_BASE_INDEX", 0, + &g->gr.ctx_vars.regs_base_index); + + nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "finished querying grctx info from chiplib"); + return 0; +fail: + nvgpu_err(g, "failed querying grctx info from chiplib"); + + nvgpu_kfree(g, g->gr.ctx_vars.ucode.fecs.inst.l); + nvgpu_kfree(g, g->gr.ctx_vars.ucode.fecs.data.l); + nvgpu_kfree(g, g->gr.ctx_vars.ucode.gpccs.inst.l); + nvgpu_kfree(g, g->gr.ctx_vars.ucode.gpccs.data.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_bundle_init.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_bundle64_init.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_method_init.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_ctx_load.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_non_ctx_load.l); + nvgpu_kfree(g, g->gr.ctx_vars.sw_veid_bundle_init.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.sys.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.gpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.tpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.zcull_gpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.ppc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_sys.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_gpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_tpc.l); + nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.etpc.l); + + return err; +} diff --git a/include/gk20a/gr_gk20a.c b/include/gk20a/gr_gk20a.c new file mode 100644 index 0000000..7bcf528 --- /dev/null +++ b/include/gk20a/gr_gk20a.c @@ -0,0 +1,8998 @@ +/* + * GK20A Graphics + * + * Copyright (c) 2011-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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a.h" +#include "gr_gk20a.h" +#include "gk20a/fecs_trace_gk20a.h" +#include "gr_ctx_gk20a.h" +#include "gr_pri_gk20a.h" +#include "regops_gk20a.h" +#include "dbg_gpu_gk20a.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BLK_SIZE (256) +#define NV_PERF_PMM_FBP_ROUTER_STRIDE 0x0200 +#define NV_PERF_PMMGPCROUTER_STRIDE 0x0200 +#define NV_PCFG_BASE 0x00088000 +#define NV_XBAR_MXBAR_PRI_GPC_GNIC_STRIDE 0x0020 +#define FE_PWR_MODE_TIMEOUT_MAX 2000 +#define FE_PWR_MODE_TIMEOUT_DEFAULT 10 +#define CTXSW_MEM_SCRUBBING_TIMEOUT_MAX 1000 +#define CTXSW_MEM_SCRUBBING_TIMEOUT_DEFAULT 10 +#define FECS_ARB_CMD_TIMEOUT_MAX 40 +#define FECS_ARB_CMD_TIMEOUT_DEFAULT 2 + +static int gk20a_init_gr_bind_fecs_elpg(struct gk20a *g); + +static void gr_gk20a_free_channel_pm_ctx(struct gk20a *g, + struct vm_gk20a *vm, + struct nvgpu_gr_ctx *gr_ctx); + +/* channel patch ctx buffer */ +static int gr_gk20a_alloc_channel_patch_ctx(struct gk20a *g, + struct channel_gk20a *c); +static void gr_gk20a_free_channel_patch_ctx(struct gk20a *g, + struct vm_gk20a *vm, + struct nvgpu_gr_ctx *gr_ctx); + +/* golden ctx image */ +static int gr_gk20a_init_golden_ctx_image(struct gk20a *g, + struct channel_gk20a *c); + +int gr_gk20a_get_ctx_id(struct gk20a *g, + struct channel_gk20a *c, + u32 *ctx_id) +{ + struct tsg_gk20a *tsg; + struct nvgpu_gr_ctx *gr_ctx = NULL; + struct nvgpu_mem *mem = NULL; + + tsg = tsg_gk20a_from_ch(c); + if (tsg == NULL) { + return -EINVAL; + } + + gr_ctx = &tsg->gr_ctx; + mem = &gr_ctx->mem; + + /* Channel gr_ctx buffer is gpu cacheable. + Flush and invalidate before cpu update. */ + g->ops.mm.l2_flush(g, true); + + *ctx_id = nvgpu_mem_rd(g, mem, + ctxsw_prog_main_image_context_id_o()); + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_intr, "ctx_id: 0x%x", *ctx_id); + + return 0; +} + +void gk20a_fecs_dump_falcon_stats(struct gk20a *g) +{ + unsigned int i; + + nvgpu_err(g, "gr_fecs_os_r : %d", + gk20a_readl(g, gr_fecs_os_r())); + nvgpu_err(g, "gr_fecs_cpuctl_r : 0x%x", + gk20a_readl(g, gr_fecs_cpuctl_r())); + nvgpu_err(g, "gr_fecs_idlestate_r : 0x%x", + gk20a_readl(g, gr_fecs_idlestate_r())); + nvgpu_err(g, "gr_fecs_mailbox0_r : 0x%x", + gk20a_readl(g, gr_fecs_mailbox0_r())); + nvgpu_err(g, "gr_fecs_mailbox1_r : 0x%x", + gk20a_readl(g, gr_fecs_mailbox1_r())); + nvgpu_err(g, "gr_fecs_irqstat_r : 0x%x", + gk20a_readl(g, gr_fecs_irqstat_r())); + nvgpu_err(g, "gr_fecs_irqmode_r : 0x%x", + gk20a_readl(g, gr_fecs_irqmode_r())); + nvgpu_err(g, "gr_fecs_irqmask_r : 0x%x", + gk20a_readl(g, gr_fecs_irqmask_r())); + nvgpu_err(g, "gr_fecs_irqdest_r : 0x%x", + gk20a_readl(g, gr_fecs_irqdest_r())); + nvgpu_err(g, "gr_fecs_debug1_r : 0x%x", + gk20a_readl(g, gr_fecs_debug1_r())); + nvgpu_err(g, "gr_fecs_debuginfo_r : 0x%x", + gk20a_readl(g, gr_fecs_debuginfo_r())); + nvgpu_err(g, "gr_fecs_ctxsw_status_1_r : 0x%x", + gk20a_readl(g, gr_fecs_ctxsw_status_1_r())); + + for (i = 0; i < g->ops.gr.fecs_ctxsw_mailbox_size(); i++) { + nvgpu_err(g, "gr_fecs_ctxsw_mailbox_r(%d) : 0x%x", + i, gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(i))); + } + + nvgpu_err(g, "gr_fecs_engctl_r : 0x%x", + gk20a_readl(g, gr_fecs_engctl_r())); + nvgpu_err(g, "gr_fecs_curctx_r : 0x%x", + gk20a_readl(g, gr_fecs_curctx_r())); + nvgpu_err(g, "gr_fecs_nxtctx_r : 0x%x", + gk20a_readl(g, gr_fecs_nxtctx_r())); + + gk20a_writel(g, gr_fecs_icd_cmd_r(), + gr_fecs_icd_cmd_opc_rreg_f() | + gr_fecs_icd_cmd_idx_f(PMU_FALCON_REG_IMB)); + nvgpu_err(g, "FECS_FALCON_REG_IMB : 0x%x", + gk20a_readl(g, gr_fecs_icd_rdata_r())); + + gk20a_writel(g, gr_fecs_icd_cmd_r(), + gr_fecs_icd_cmd_opc_rreg_f() | + gr_fecs_icd_cmd_idx_f(PMU_FALCON_REG_DMB)); + nvgpu_err(g, "FECS_FALCON_REG_DMB : 0x%x", + gk20a_readl(g, gr_fecs_icd_rdata_r())); + + gk20a_writel(g, gr_fecs_icd_cmd_r(), + gr_fecs_icd_cmd_opc_rreg_f() | + gr_fecs_icd_cmd_idx_f(PMU_FALCON_REG_CSW)); + nvgpu_err(g, "FECS_FALCON_REG_CSW : 0x%x", + gk20a_readl(g, gr_fecs_icd_rdata_r())); + + gk20a_writel(g, gr_fecs_icd_cmd_r(), + gr_fecs_icd_cmd_opc_rreg_f() | + gr_fecs_icd_cmd_idx_f(PMU_FALCON_REG_CTX)); + nvgpu_err(g, "FECS_FALCON_REG_CTX : 0x%x", + gk20a_readl(g, gr_fecs_icd_rdata_r())); + + gk20a_writel(g, gr_fecs_icd_cmd_r(), + gr_fecs_icd_cmd_opc_rreg_f() | + gr_fecs_icd_cmd_idx_f(PMU_FALCON_REG_EXCI)); + nvgpu_err(g, "FECS_FALCON_REG_EXCI : 0x%x", + gk20a_readl(g, gr_fecs_icd_rdata_r())); + + for (i = 0; i < 4; i++) { + gk20a_writel(g, gr_fecs_icd_cmd_r(), + gr_fecs_icd_cmd_opc_rreg_f() | + gr_fecs_icd_cmd_idx_f(PMU_FALCON_REG_PC)); + nvgpu_err(g, "FECS_FALCON_REG_PC : 0x%x", + gk20a_readl(g, gr_fecs_icd_rdata_r())); + + gk20a_writel(g, gr_fecs_icd_cmd_r(), + gr_fecs_icd_cmd_opc_rreg_f() | + gr_fecs_icd_cmd_idx_f(PMU_FALCON_REG_SP)); + nvgpu_err(g, "FECS_FALCON_REG_SP : 0x%x", + gk20a_readl(g, gr_fecs_icd_rdata_r())); + } +} + +static void gr_gk20a_load_falcon_dmem(struct gk20a *g) +{ + u32 i, ucode_u32_size; + const u32 *ucode_u32_data; + u32 checksum; + + nvgpu_log_fn(g, " "); + + gk20a_writel(g, gr_gpccs_dmemc_r(0), (gr_gpccs_dmemc_offs_f(0) | + gr_gpccs_dmemc_blk_f(0) | + gr_gpccs_dmemc_aincw_f(1))); + + ucode_u32_size = g->gr.ctx_vars.ucode.gpccs.data.count; + ucode_u32_data = (const u32 *)g->gr.ctx_vars.ucode.gpccs.data.l; + + for (i = 0, checksum = 0; i < ucode_u32_size; i++) { + gk20a_writel(g, gr_gpccs_dmemd_r(0), ucode_u32_data[i]); + checksum += ucode_u32_data[i]; + } + + gk20a_writel(g, gr_fecs_dmemc_r(0), (gr_fecs_dmemc_offs_f(0) | + gr_fecs_dmemc_blk_f(0) | + gr_fecs_dmemc_aincw_f(1))); + + ucode_u32_size = g->gr.ctx_vars.ucode.fecs.data.count; + ucode_u32_data = (const u32 *)g->gr.ctx_vars.ucode.fecs.data.l; + + for (i = 0, checksum = 0; i < ucode_u32_size; i++) { + gk20a_writel(g, gr_fecs_dmemd_r(0), ucode_u32_data[i]); + checksum += ucode_u32_data[i]; + } + nvgpu_log_fn(g, "done"); +} + +static void gr_gk20a_load_falcon_imem(struct gk20a *g) +{ + u32 cfg, fecs_imem_size, gpccs_imem_size, ucode_u32_size; + const u32 *ucode_u32_data; + u32 tag, i, pad_start, pad_end; + u32 checksum; + + nvgpu_log_fn(g, " "); + + cfg = gk20a_readl(g, gr_fecs_cfg_r()); + fecs_imem_size = gr_fecs_cfg_imem_sz_v(cfg); + + cfg = gk20a_readl(g, gr_gpc0_cfg_r()); + gpccs_imem_size = gr_gpc0_cfg_imem_sz_v(cfg); + + /* Use the broadcast address to access all of the GPCCS units. */ + gk20a_writel(g, gr_gpccs_imemc_r(0), (gr_gpccs_imemc_offs_f(0) | + gr_gpccs_imemc_blk_f(0) | + gr_gpccs_imemc_aincw_f(1))); + + /* Setup the tags for the instruction memory. */ + tag = 0; + gk20a_writel(g, gr_gpccs_imemt_r(0), gr_gpccs_imemt_tag_f(tag)); + + ucode_u32_size = g->gr.ctx_vars.ucode.gpccs.inst.count; + ucode_u32_data = (const u32 *)g->gr.ctx_vars.ucode.gpccs.inst.l; + + for (i = 0, checksum = 0; i < ucode_u32_size; i++) { + if ((i != 0U) && ((i % (256U/sizeof(u32))) == 0U)) { + tag++; + gk20a_writel(g, gr_gpccs_imemt_r(0), + gr_gpccs_imemt_tag_f(tag)); + } + gk20a_writel(g, gr_gpccs_imemd_r(0), ucode_u32_data[i]); + checksum += ucode_u32_data[i]; + } + + pad_start = i * 4U; + pad_end = pad_start + (256U - pad_start % 256U) + 256U; + for (i = pad_start; + (i < gpccs_imem_size * 256U) && (i < pad_end); + i += 4U) { + if ((i != 0U) && ((i % 256U) == 0U)) { + tag++; + gk20a_writel(g, gr_gpccs_imemt_r(0), + gr_gpccs_imemt_tag_f(tag)); + } + gk20a_writel(g, gr_gpccs_imemd_r(0), 0); + } + + gk20a_writel(g, gr_fecs_imemc_r(0), (gr_fecs_imemc_offs_f(0) | + gr_fecs_imemc_blk_f(0) | + gr_fecs_imemc_aincw_f(1))); + + /* Setup the tags for the instruction memory. */ + tag = 0; + gk20a_writel(g, gr_fecs_imemt_r(0), gr_fecs_imemt_tag_f(tag)); + + ucode_u32_size = g->gr.ctx_vars.ucode.fecs.inst.count; + ucode_u32_data = (const u32 *)g->gr.ctx_vars.ucode.fecs.inst.l; + + for (i = 0, checksum = 0; i < ucode_u32_size; i++) { + if ((i != 0U) && ((i % (256U/sizeof(u32))) == 0U)) { + tag++; + gk20a_writel(g, gr_fecs_imemt_r(0), + gr_fecs_imemt_tag_f(tag)); + } + gk20a_writel(g, gr_fecs_imemd_r(0), ucode_u32_data[i]); + checksum += ucode_u32_data[i]; + } + + pad_start = i * 4U; + pad_end = pad_start + (256U - pad_start % 256U) + 256U; + for (i = pad_start; + (i < fecs_imem_size * 256U) && i < pad_end; + i += 4U) { + if ((i != 0U) && ((i % 256U) == 0U)) { + tag++; + gk20a_writel(g, gr_fecs_imemt_r(0), + gr_fecs_imemt_tag_f(tag)); + } + gk20a_writel(g, gr_fecs_imemd_r(0), 0); + } +} + +int gr_gk20a_wait_idle(struct gk20a *g, unsigned long duration_ms, + u32 expect_delay) +{ + u32 delay = expect_delay; + bool ctxsw_active; + bool gr_busy; + u32 gr_engine_id; + u32 engine_status; + bool ctx_status_invalid; + struct nvgpu_timeout timeout; + + nvgpu_log_fn(g, " "); + + gr_engine_id = gk20a_fifo_get_gr_engine_id(g); + + nvgpu_timeout_init(g, &timeout, duration_ms, NVGPU_TIMER_CPU_TIMER); + + do { + /* fmodel: host gets fifo_engine_status(gr) from gr + only when gr_status is read */ + (void) gk20a_readl(g, gr_status_r()); + + engine_status = gk20a_readl(g, + fifo_engine_status_r(gr_engine_id)); + + ctxsw_active = engine_status & + fifo_engine_status_ctxsw_in_progress_f(); + + ctx_status_invalid = + (fifo_engine_status_ctx_status_v(engine_status) == + fifo_engine_status_ctx_status_invalid_v()); + + gr_busy = gk20a_readl(g, gr_engine_status_r()) & + gr_engine_status_value_busy_f(); + + if (ctx_status_invalid || (!gr_busy && !ctxsw_active)) { + nvgpu_log_fn(g, "done"); + return 0; + } + + nvgpu_usleep_range(delay, delay * 2); + delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); + + } while (nvgpu_timeout_expired(&timeout) == 0); + + nvgpu_err(g, + "timeout, ctxsw busy : %d, gr busy : %d", + ctxsw_active, gr_busy); + + return -EAGAIN; +} + +int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long duration_ms, + u32 expect_delay) +{ + u32 val; + u32 delay = expect_delay; + struct nvgpu_timeout timeout; + + if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) { + return 0; + } + + nvgpu_log_fn(g, " "); + + nvgpu_timeout_init(g, &timeout, duration_ms, NVGPU_TIMER_CPU_TIMER); + + do { + val = gk20a_readl(g, gr_status_r()); + + if (gr_status_fe_method_lower_v(val) == 0U) { + nvgpu_log_fn(g, "done"); + return 0; + } + + nvgpu_usleep_range(delay, delay * 2); + delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); + } while (nvgpu_timeout_expired(&timeout) == 0); + + nvgpu_err(g, + "timeout, fe busy : %x", val); + + return -EAGAIN; +} + +int gr_gk20a_ctx_wait_ucode(struct gk20a *g, u32 mailbox_id, + u32 *mailbox_ret, u32 opc_success, + u32 mailbox_ok, u32 opc_fail, + u32 mailbox_fail, bool sleepduringwait) +{ + struct nvgpu_timeout timeout; + u32 delay = GR_FECS_POLL_INTERVAL; + u32 check = WAIT_UCODE_LOOP; + u32 reg; + + nvgpu_log_fn(g, " "); + + if (sleepduringwait) { + delay = GR_IDLE_CHECK_DEFAULT; + } + + nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); + + while (check == WAIT_UCODE_LOOP) { + if (nvgpu_timeout_expired(&timeout)) { + check = WAIT_UCODE_TIMEOUT; + } + + reg = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(mailbox_id)); + + if (mailbox_ret) { + *mailbox_ret = reg; + } + + switch (opc_success) { + case GR_IS_UCODE_OP_EQUAL: + if (reg == mailbox_ok) { + check = WAIT_UCODE_OK; + } + break; + case GR_IS_UCODE_OP_NOT_EQUAL: + if (reg != mailbox_ok) { + check = WAIT_UCODE_OK; + } + break; + case GR_IS_UCODE_OP_AND: + if (reg & mailbox_ok) { + check = WAIT_UCODE_OK; + } + break; + case GR_IS_UCODE_OP_LESSER: + if (reg < mailbox_ok) { + check = WAIT_UCODE_OK; + } + break; + case GR_IS_UCODE_OP_LESSER_EQUAL: + if (reg <= mailbox_ok) { + check = WAIT_UCODE_OK; + } + break; + case GR_IS_UCODE_OP_SKIP: + /* do no success check */ + break; + default: + nvgpu_err(g, + "invalid success opcode 0x%x", opc_success); + + check = WAIT_UCODE_ERROR; + break; + } + + switch (opc_fail) { + case GR_IS_UCODE_OP_EQUAL: + if (reg == mailbox_fail) { + check = WAIT_UCODE_ERROR; + } + break; + case GR_IS_UCODE_OP_NOT_EQUAL: + if (reg != mailbox_fail) { + check = WAIT_UCODE_ERROR; + } + break; + case GR_IS_UCODE_OP_AND: + if (reg & mailbox_fail) { + check = WAIT_UCODE_ERROR; + } + break; + case GR_IS_UCODE_OP_LESSER: + if (reg < mailbox_fail) { + check = WAIT_UCODE_ERROR; + } + break; + case GR_IS_UCODE_OP_LESSER_EQUAL: + if (reg <= mailbox_fail) { + check = WAIT_UCODE_ERROR; + } + break; + case GR_IS_UCODE_OP_SKIP: + /* do no check on fail*/ + break; + default: + nvgpu_err(g, + "invalid fail opcode 0x%x", opc_fail); + check = WAIT_UCODE_ERROR; + break; + } + + if (sleepduringwait) { + nvgpu_usleep_range(delay, delay * 2); + delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); + } else { + nvgpu_udelay(delay); + } + } + + if (check == WAIT_UCODE_TIMEOUT) { + nvgpu_err(g, + "timeout waiting on mailbox=%d value=0x%08x", + mailbox_id, reg); + gk20a_fecs_dump_falcon_stats(g); + gk20a_gr_debug_dump(g); + return -1; + } else if (check == WAIT_UCODE_ERROR) { + nvgpu_err(g, + "ucode method failed on mailbox=%d value=0x%08x", + mailbox_id, reg); + gk20a_fecs_dump_falcon_stats(g); + return -1; + } + + nvgpu_log_fn(g, "done"); + return 0; +} + +int gr_gk20a_submit_fecs_method_op_locked(struct gk20a *g, + struct fecs_method_op_gk20a op, + bool sleepduringwait) +{ + int ret; + + if (op.mailbox.id != 0) { + gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(op.mailbox.id), + op.mailbox.data); + } + + gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), + gr_fecs_ctxsw_mailbox_clear_value_f(op.mailbox.clr)); + + gk20a_writel(g, gr_fecs_method_data_r(), op.method.data); + gk20a_writel(g, gr_fecs_method_push_r(), + gr_fecs_method_push_adr_f(op.method.addr)); + + /* op.mailbox.id == 4 cases require waiting for completion on + * for op.mailbox.id == 0 */ + if (op.mailbox.id == 4) { + op.mailbox.id = 0; + } + + ret = gr_gk20a_ctx_wait_ucode(g, op.mailbox.id, op.mailbox.ret, + op.cond.ok, op.mailbox.ok, + op.cond.fail, op.mailbox.fail, + sleepduringwait); + if (ret) { + nvgpu_err(g,"fecs method: data=0x%08x push adr=0x%08x", + op.method.data, op.method.addr); + } + + return ret; +} + +/* The following is a less brittle way to call gr_gk20a_submit_fecs_method(...) + * We should replace most, if not all, fecs method calls to this instead. */ +int gr_gk20a_submit_fecs_method_op(struct gk20a *g, + struct fecs_method_op_gk20a op, + bool sleepduringwait) +{ + struct gr_gk20a *gr = &g->gr; + int ret; + + nvgpu_mutex_acquire(&gr->fecs_mutex); + + ret = gr_gk20a_submit_fecs_method_op_locked(g, op, sleepduringwait); + + nvgpu_mutex_release(&gr->fecs_mutex); + + return ret; +} + +/* Sideband mailbox writes are done a bit differently */ +int gr_gk20a_submit_fecs_sideband_method_op(struct gk20a *g, + struct fecs_method_op_gk20a op) +{ + struct gr_gk20a *gr = &g->gr; + int ret; + + nvgpu_mutex_acquire(&gr->fecs_mutex); + + gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(op.mailbox.id), + gr_fecs_ctxsw_mailbox_clear_value_f(op.mailbox.clr)); + + gk20a_writel(g, gr_fecs_method_data_r(), op.method.data); + gk20a_writel(g, gr_fecs_method_push_r(), + gr_fecs_method_push_adr_f(op.method.addr)); + + ret = gr_gk20a_ctx_wait_ucode(g, op.mailbox.id, op.mailbox.ret, + op.cond.ok, op.mailbox.ok, + op.cond.fail, op.mailbox.fail, + false); + if (ret) { + nvgpu_err(g,"fecs method: data=0x%08x push adr=0x%08x", + op.method.data, op.method.addr); + } + + nvgpu_mutex_release(&gr->fecs_mutex); + + return ret; +} + +static int gr_gk20a_ctrl_ctxsw(struct gk20a *g, u32 fecs_method, u32 *ret) +{ + return gr_gk20a_submit_fecs_method_op(g, + (struct fecs_method_op_gk20a) { + .method.addr = fecs_method, + .method.data = ~0, + .mailbox = { .id = 1, /*sideband?*/ + .data = ~0, .clr = ~0, .ret = ret, + .ok = gr_fecs_ctxsw_mailbox_value_pass_v(), + .fail = gr_fecs_ctxsw_mailbox_value_fail_v(), }, + .cond.ok = GR_IS_UCODE_OP_EQUAL, + .cond.fail = GR_IS_UCODE_OP_EQUAL }, true); +} + +/** + * Stop processing (stall) context switches at FECS:- + * If fecs is sent stop_ctxsw method, elpg entry/exit cannot happen + * and may timeout. It could manifest as different error signatures + * depending on when stop_ctxsw fecs method gets sent with respect + * to pmu elpg sequence. It could come as pmu halt or abort or + * maybe ext error too. +*/ +int gr_gk20a_disable_ctxsw(struct gk20a *g) +{ + int err = 0; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + nvgpu_mutex_acquire(&g->ctxsw_disable_lock); + g->ctxsw_disable_count++; + if (g->ctxsw_disable_count == 1) { + err = nvgpu_pg_elpg_disable(g); + if (err != 0) { + nvgpu_err(g, "failed to disable elpg. not safe to " + "stop_ctxsw"); + /* stop ctxsw command is not sent */ + g->ctxsw_disable_count--; + } else { + err = gr_gk20a_ctrl_ctxsw(g, + gr_fecs_method_push_adr_stop_ctxsw_v(), NULL); + if (err != 0) { + nvgpu_err(g, "failed to stop fecs ctxsw"); + /* stop ctxsw failed */ + g->ctxsw_disable_count--; + } + } + } else { + nvgpu_log_info(g, "ctxsw disabled, ctxsw_disable_count: %d", + g->ctxsw_disable_count); + } + nvgpu_mutex_release(&g->ctxsw_disable_lock); + + return err; +} + +/* Start processing (continue) context switches at FECS */ +int gr_gk20a_enable_ctxsw(struct gk20a *g) +{ + int err = 0; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + nvgpu_mutex_acquire(&g->ctxsw_disable_lock); + + if (g->ctxsw_disable_count == 0) { + goto ctxsw_already_enabled; + } + g->ctxsw_disable_count--; + WARN_ON(g->ctxsw_disable_count < 0); + if (g->ctxsw_disable_count == 0) { + err = gr_gk20a_ctrl_ctxsw(g, + gr_fecs_method_push_adr_start_ctxsw_v(), NULL); + if (err != 0) { + nvgpu_err(g, "failed to start fecs ctxsw"); + } else { + if (nvgpu_pg_elpg_enable(g) != 0) { + nvgpu_err(g, "failed to enable elpg " + "after start_ctxsw"); + } + } + } else { + nvgpu_log_info(g, "ctxsw_disable_count: %d is not 0 yet", + g->ctxsw_disable_count); + } +ctxsw_already_enabled: + nvgpu_mutex_release(&g->ctxsw_disable_lock); + + return err; +} + +int gr_gk20a_halt_pipe(struct gk20a *g) +{ + return gr_gk20a_submit_fecs_method_op(g, + (struct fecs_method_op_gk20a) { + .method.addr = + gr_fecs_method_push_adr_halt_pipeline_v(), + .method.data = ~0, + .mailbox = { .id = 1, /*sideband?*/ + .data = ~0, .clr = ~0, .ret = NULL, + .ok = gr_fecs_ctxsw_mailbox_value_pass_v(), + .fail = gr_fecs_ctxsw_mailbox_value_fail_v(), }, + .cond.ok = GR_IS_UCODE_OP_EQUAL, + .cond.fail = GR_IS_UCODE_OP_EQUAL }, false); +} + + +int gr_gk20a_commit_inst(struct channel_gk20a *c, u64 gpu_va) +{ + u32 addr_lo; + u32 addr_hi; + + nvgpu_log_fn(c->g, " "); + + addr_lo = u64_lo32(gpu_va) >> 12; + addr_hi = u64_hi32(gpu_va); + + nvgpu_mem_wr32(c->g, &c->inst_block, ram_in_gr_wfi_target_w(), + ram_in_gr_cs_wfi_f() | ram_in_gr_wfi_mode_virtual_f() | + ram_in_gr_wfi_ptr_lo_f(addr_lo)); + + nvgpu_mem_wr32(c->g, &c->inst_block, ram_in_gr_wfi_ptr_hi_w(), + ram_in_gr_wfi_ptr_hi_f(addr_hi)); + + return 0; +} + +/* + * Context state can be written directly, or "patched" at times. So that code + * can be used in either situation it is written using a series of + * _ctx_patch_write(..., patch) statements. However any necessary map overhead + * should be minimized; thus, bundle the sequence of these writes together, and + * set them up and close with _ctx_patch_write_begin/_ctx_patch_write_end. + */ + +int gr_gk20a_ctx_patch_write_begin(struct gk20a *g, + struct nvgpu_gr_ctx *gr_ctx, + bool update_patch_count) +{ + if (update_patch_count) { + /* reset patch count if ucode has already processed it */ + gr_ctx->patch_ctx.data_count = nvgpu_mem_rd(g, + &gr_ctx->mem, + ctxsw_prog_main_image_patch_count_o()); + nvgpu_log(g, gpu_dbg_info, "patch count reset to %d", + gr_ctx->patch_ctx.data_count); + } + return 0; +} + +void gr_gk20a_ctx_patch_write_end(struct gk20a *g, + struct nvgpu_gr_ctx *gr_ctx, + bool update_patch_count) +{ + /* Write context count to context image if it is mapped */ + if (update_patch_count) { + nvgpu_mem_wr(g, &gr_ctx->mem, + ctxsw_prog_main_image_patch_count_o(), + gr_ctx->patch_ctx.data_count); + nvgpu_log(g, gpu_dbg_info, "write patch count %d", + gr_ctx->patch_ctx.data_count); + } +} + +void gr_gk20a_ctx_patch_write(struct gk20a *g, + struct nvgpu_gr_ctx *gr_ctx, + u32 addr, u32 data, bool patch) +{ + if (patch) { + u32 patch_slot = gr_ctx->patch_ctx.data_count * + PATCH_CTX_SLOTS_REQUIRED_PER_ENTRY; + if (patch_slot > (PATCH_CTX_ENTRIES_FROM_SIZE( + gr_ctx->patch_ctx.mem.size) - + PATCH_CTX_SLOTS_REQUIRED_PER_ENTRY)) { + nvgpu_err(g, "failed to access patch_slot %d", + patch_slot); + return; + } + nvgpu_mem_wr32(g, &gr_ctx->patch_ctx.mem, patch_slot, addr); + nvgpu_mem_wr32(g, &gr_ctx->patch_ctx.mem, patch_slot + 1, data); + gr_ctx->patch_ctx.data_count++; + nvgpu_log(g, gpu_dbg_info, + "patch addr = 0x%x data = 0x%x data_count %d", + addr, data, gr_ctx->patch_ctx.data_count); + } else { + gk20a_writel(g, addr, data); + } +} + +static u32 fecs_current_ctx_data(struct gk20a *g, struct nvgpu_mem *inst_block) +{ + u64 ptr = nvgpu_inst_block_addr(g, inst_block) >> + ram_in_base_shift_v(); + u32 aperture = nvgpu_aperture_mask(g, inst_block, + gr_fecs_current_ctx_target_sys_mem_ncoh_f(), + gr_fecs_current_ctx_target_sys_mem_coh_f(), + gr_fecs_current_ctx_target_vid_mem_f()); + + return gr_fecs_current_ctx_ptr_f(u64_lo32(ptr)) | aperture | + gr_fecs_current_ctx_valid_f(1); +} + +int gr_gk20a_fecs_ctx_bind_channel(struct gk20a *g, + struct channel_gk20a *c) +{ + u32 inst_base_ptr = u64_lo32(nvgpu_inst_block_addr(g, &c->inst_block) + >> ram_in_base_shift_v()); + u32 data = fecs_current_ctx_data(g, &c->inst_block); + u32 ret; + + nvgpu_log_info(g, "bind channel %d inst ptr 0x%08x", + c->chid, inst_base_ptr); + + ret = gr_gk20a_submit_fecs_method_op(g, + (struct fecs_method_op_gk20a) { + .method.addr = gr_fecs_method_push_adr_bind_pointer_v(), + .method.data = data, + .mailbox = { .id = 0, .data = 0, + .clr = 0x30, + .ret = NULL, + .ok = 0x10, + .fail = 0x20, }, + .cond.ok = GR_IS_UCODE_OP_AND, + .cond.fail = GR_IS_UCODE_OP_AND}, true); + if (ret) { + nvgpu_err(g, + "bind channel instance failed"); + } + + return ret; +} + +void gr_gk20a_write_zcull_ptr(struct gk20a *g, + struct nvgpu_mem *mem, u64 gpu_va) +{ + u32 va = u64_lo32(gpu_va >> 8); + + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_zcull_ptr_o(), va); +} + +void gr_gk20a_write_pm_ptr(struct gk20a *g, + struct nvgpu_mem *mem, u64 gpu_va) +{ + u32 va = u64_lo32(gpu_va >> 8); + + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_pm_ptr_o(), va); +} + +static int gr_gk20a_ctx_zcull_setup(struct gk20a *g, struct channel_gk20a *c) +{ + struct tsg_gk20a *tsg; + struct nvgpu_gr_ctx *gr_ctx = NULL; + struct nvgpu_mem *mem = NULL; + struct nvgpu_mem *ctxheader = &c->ctx_header; + int ret = 0; + + nvgpu_log_fn(g, " "); + + tsg = tsg_gk20a_from_ch(c); + if (tsg == NULL) { + return -EINVAL; + } + + gr_ctx = &tsg->gr_ctx; + mem = &gr_ctx->mem; + + if (gr_ctx->zcull_ctx.gpu_va == 0 && + gr_ctx->zcull_ctx.ctx_sw_mode == + ctxsw_prog_main_image_zcull_mode_separate_buffer_v()) { + return -EINVAL; + } + + ret = gk20a_disable_channel_tsg(g, c); + if (ret) { + nvgpu_err(g, "failed to disable channel/TSG"); + return ret; + } + ret = gk20a_fifo_preempt(g, c); + if (ret) { + gk20a_enable_channel_tsg(g, c); + nvgpu_err(g, "failed to preempt channel/TSG"); + return ret; + } + + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_zcull_o(), + gr_ctx->zcull_ctx.ctx_sw_mode); + + if (ctxheader->gpu_va) { + g->ops.gr.write_zcull_ptr(g, ctxheader, + gr_ctx->zcull_ctx.gpu_va); + } else { + g->ops.gr.write_zcull_ptr(g, mem, gr_ctx->zcull_ctx.gpu_va); + } + + gk20a_enable_channel_tsg(g, c); + + return ret; +} + +u32 gk20a_gr_gpc_offset(struct gk20a *g, u32 gpc) +{ + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 gpc_offset = gpc_stride * gpc; + + return gpc_offset; +} + +u32 gk20a_gr_tpc_offset(struct gk20a *g, u32 tpc) +{ + u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, + GPU_LIT_TPC_IN_GPC_STRIDE); + u32 tpc_offset = tpc_in_gpc_stride * tpc; + + return tpc_offset; +} + +int gr_gk20a_commit_global_ctx_buffers(struct gk20a *g, + struct channel_gk20a *c, bool patch) +{ + struct gr_gk20a *gr = &g->gr; + struct tsg_gk20a *tsg; + struct nvgpu_gr_ctx *gr_ctx = NULL; + u64 addr; + u32 size; + + nvgpu_log_fn(g, " "); + + tsg = tsg_gk20a_from_ch(c); + if (tsg == NULL) { + return -EINVAL; + } + + gr_ctx = &tsg->gr_ctx; + if (patch) { + int err; + err = gr_gk20a_ctx_patch_write_begin(g, gr_ctx, false); + if (err != 0) { + return err; + } + } + + /* global pagepool buffer */ + addr = (u64_lo32(gr_ctx->global_ctx_buffer_va[PAGEPOOL_VA]) >> + gr_scc_pagepool_base_addr_39_8_align_bits_v()) | + (u64_hi32(gr_ctx->global_ctx_buffer_va[PAGEPOOL_VA]) << + (32 - gr_scc_pagepool_base_addr_39_8_align_bits_v())); + + size = gr->global_ctx_buffer[PAGEPOOL].mem.size / + gr_scc_pagepool_total_pages_byte_granularity_v(); + + if (size == g->ops.gr.pagepool_default_size(g)) { + size = gr_scc_pagepool_total_pages_hwmax_v(); + } + + nvgpu_log_info(g, "pagepool buffer addr : 0x%016llx, size : %d", + addr, size); + + g->ops.gr.commit_global_pagepool(g, gr_ctx, addr, size, patch); + + /* global bundle cb */ + addr = (u64_lo32(gr_ctx->global_ctx_buffer_va[CIRCULAR_VA]) >> + gr_scc_bundle_cb_base_addr_39_8_align_bits_v()) | + (u64_hi32(gr_ctx->global_ctx_buffer_va[CIRCULAR_VA]) << + (32 - gr_scc_bundle_cb_base_addr_39_8_align_bits_v())); + + size = gr->bundle_cb_default_size; + + nvgpu_log_info(g, "bundle cb addr : 0x%016llx, size : %d", + addr, size); + + g->ops.gr.commit_global_bundle_cb(g, gr_ctx, addr, size, patch); + + /* global attrib cb */ + addr = (u64_lo32(gr_ctx->global_ctx_buffer_va[ATTRIBUTE_VA]) >> + gr_gpcs_setup_attrib_cb_base_addr_39_12_align_bits_v()) | + (u64_hi32(gr_ctx->global_ctx_buffer_va[ATTRIBUTE_VA]) << + (32 - gr_gpcs_setup_attrib_cb_base_addr_39_12_align_bits_v())); + + nvgpu_log_info(g, "attrib cb addr : 0x%016llx", addr); + g->ops.gr.commit_global_attrib_cb(g, gr_ctx, addr, patch); + g->ops.gr.commit_global_cb_manager(g, c, patch); + + if (patch) { + gr_gk20a_ctx_patch_write_end(g, gr_ctx, false); + } + + return 0; +} + +int gr_gk20a_commit_global_timeslice(struct gk20a *g, struct channel_gk20a *c) +{ + struct gr_gk20a *gr = &g->gr; + struct nvgpu_gr_ctx *gr_ctx = NULL; + u32 gpm_pd_cfg; + u32 pd_ab_dist_cfg0; + u32 ds_debug; + u32 mpc_vtg_debug; + u32 pe_vaf; + u32 pe_vsc_vpc; + + nvgpu_log_fn(g, " "); + + gpm_pd_cfg = gk20a_readl(g, gr_gpcs_gpm_pd_cfg_r()); + pd_ab_dist_cfg0 = gk20a_readl(g, gr_pd_ab_dist_cfg0_r()); + ds_debug = gk20a_readl(g, gr_ds_debug_r()); + mpc_vtg_debug = gk20a_readl(g, gr_gpcs_tpcs_mpc_vtg_debug_r()); + + if (gr->timeslice_mode == gr_gpcs_ppcs_cbm_cfg_timeslice_mode_enable_v()) { + pe_vaf = gk20a_readl(g, gr_gpcs_tpcs_pe_vaf_r()); + pe_vsc_vpc = gk20a_readl(g, gr_gpcs_tpcs_pes_vsc_vpc_r()); + + gpm_pd_cfg = gr_gpcs_gpm_pd_cfg_timeslice_mode_enable_f() | gpm_pd_cfg; + pe_vaf = gr_gpcs_tpcs_pe_vaf_fast_mode_switch_true_f() | pe_vaf; + pe_vsc_vpc = gr_gpcs_tpcs_pes_vsc_vpc_fast_mode_switch_true_f() | pe_vsc_vpc; + pd_ab_dist_cfg0 = gr_pd_ab_dist_cfg0_timeslice_enable_en_f() | pd_ab_dist_cfg0; + ds_debug = gr_ds_debug_timeslice_mode_enable_f() | ds_debug; + mpc_vtg_debug = gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_enabled_f() | mpc_vtg_debug; + + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_gpcs_gpm_pd_cfg_r(), gpm_pd_cfg, false); + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_gpcs_tpcs_pe_vaf_r(), pe_vaf, false); + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_gpcs_tpcs_pes_vsc_vpc_r(), pe_vsc_vpc, false); + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_pd_ab_dist_cfg0_r(), pd_ab_dist_cfg0, false); + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_ds_debug_r(), ds_debug, false); + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_gpcs_tpcs_mpc_vtg_debug_r(), mpc_vtg_debug, false); + } else { + gpm_pd_cfg = gr_gpcs_gpm_pd_cfg_timeslice_mode_disable_f() | gpm_pd_cfg; + pd_ab_dist_cfg0 = gr_pd_ab_dist_cfg0_timeslice_enable_dis_f() | pd_ab_dist_cfg0; + ds_debug = gr_ds_debug_timeslice_mode_disable_f() | ds_debug; + mpc_vtg_debug = gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_disabled_f() | mpc_vtg_debug; + + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_gpcs_gpm_pd_cfg_r(), gpm_pd_cfg, false); + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_pd_ab_dist_cfg0_r(), pd_ab_dist_cfg0, false); + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_ds_debug_r(), ds_debug, false); + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_gpcs_tpcs_mpc_vtg_debug_r(), mpc_vtg_debug, false); + } + + return 0; +} + +/* + * Return map tiles count for given index + * Return 0 if index is out-of-bounds + */ +static u32 gr_gk20a_get_map_tile_count(struct gr_gk20a *gr, u32 index) +{ + if (index >= gr->map_tile_count) { + return 0; + } + + return gr->map_tiles[index]; +} + +int gr_gk20a_setup_rop_mapping(struct gk20a *g, struct gr_gk20a *gr) +{ + u32 norm_entries, norm_shift; + u32 coeff5_mod, coeff6_mod, coeff7_mod, coeff8_mod, coeff9_mod, coeff10_mod, coeff11_mod; + u32 map0, map1, map2, map3, map4, map5; + + if (gr->map_tiles == NULL) { + return -1; + } + + nvgpu_log_fn(g, " "); + + gk20a_writel(g, gr_crstr_map_table_cfg_r(), + gr_crstr_map_table_cfg_row_offset_f(gr->map_row_offset) | + gr_crstr_map_table_cfg_num_entries_f(gr->tpc_count)); + + map0 = gr_crstr_gpc_map0_tile0_f(gr_gk20a_get_map_tile_count(gr, 0)) | + gr_crstr_gpc_map0_tile1_f(gr_gk20a_get_map_tile_count(gr, 1)) | + gr_crstr_gpc_map0_tile2_f(gr_gk20a_get_map_tile_count(gr, 2)) | + gr_crstr_gpc_map0_tile3_f(gr_gk20a_get_map_tile_count(gr, 3)) | + gr_crstr_gpc_map0_tile4_f(gr_gk20a_get_map_tile_count(gr, 4)) | + gr_crstr_gpc_map0_tile5_f(gr_gk20a_get_map_tile_count(gr, 5)); + + map1 = gr_crstr_gpc_map1_tile6_f(gr_gk20a_get_map_tile_count(gr, 6)) | + gr_crstr_gpc_map1_tile7_f(gr_gk20a_get_map_tile_count(gr, 7)) | + gr_crstr_gpc_map1_tile8_f(gr_gk20a_get_map_tile_count(gr, 8)) | + gr_crstr_gpc_map1_tile9_f(gr_gk20a_get_map_tile_count(gr, 9)) | + gr_crstr_gpc_map1_tile10_f(gr_gk20a_get_map_tile_count(gr, 10)) | + gr_crstr_gpc_map1_tile11_f(gr_gk20a_get_map_tile_count(gr, 11)); + + map2 = gr_crstr_gpc_map2_tile12_f(gr_gk20a_get_map_tile_count(gr, 12)) | + gr_crstr_gpc_map2_tile13_f(gr_gk20a_get_map_tile_count(gr, 13)) | + gr_crstr_gpc_map2_tile14_f(gr_gk20a_get_map_tile_count(gr, 14)) | + gr_crstr_gpc_map2_tile15_f(gr_gk20a_get_map_tile_count(gr, 15)) | + gr_crstr_gpc_map2_tile16_f(gr_gk20a_get_map_tile_count(gr, 16)) | + gr_crstr_gpc_map2_tile17_f(gr_gk20a_get_map_tile_count(gr, 17)); + + map3 = gr_crstr_gpc_map3_tile18_f(gr_gk20a_get_map_tile_count(gr, 18)) | + gr_crstr_gpc_map3_tile19_f(gr_gk20a_get_map_tile_count(gr, 19)) | + gr_crstr_gpc_map3_tile20_f(gr_gk20a_get_map_tile_count(gr, 20)) | + gr_crstr_gpc_map3_tile21_f(gr_gk20a_get_map_tile_count(gr, 21)) | + gr_crstr_gpc_map3_tile22_f(gr_gk20a_get_map_tile_count(gr, 22)) | + gr_crstr_gpc_map3_tile23_f(gr_gk20a_get_map_tile_count(gr, 23)); + + map4 = gr_crstr_gpc_map4_tile24_f(gr_gk20a_get_map_tile_count(gr, 24)) | + gr_crstr_gpc_map4_tile25_f(gr_gk20a_get_map_tile_count(gr, 25)) | + gr_crstr_gpc_map4_tile26_f(gr_gk20a_get_map_tile_count(gr, 26)) | + gr_crstr_gpc_map4_tile27_f(gr_gk20a_get_map_tile_count(gr, 27)) | + gr_crstr_gpc_map4_tile28_f(gr_gk20a_get_map_tile_count(gr, 28)) | + gr_crstr_gpc_map4_tile29_f(gr_gk20a_get_map_tile_count(gr, 29)); + + map5 = gr_crstr_gpc_map5_tile30_f(gr_gk20a_get_map_tile_count(gr, 30)) | + gr_crstr_gpc_map5_tile31_f(gr_gk20a_get_map_tile_count(gr, 31)) | + gr_crstr_gpc_map5_tile32_f(0) | + gr_crstr_gpc_map5_tile33_f(0) | + gr_crstr_gpc_map5_tile34_f(0) | + gr_crstr_gpc_map5_tile35_f(0); + + gk20a_writel(g, gr_crstr_gpc_map0_r(), map0); + gk20a_writel(g, gr_crstr_gpc_map1_r(), map1); + gk20a_writel(g, gr_crstr_gpc_map2_r(), map2); + gk20a_writel(g, gr_crstr_gpc_map3_r(), map3); + gk20a_writel(g, gr_crstr_gpc_map4_r(), map4); + gk20a_writel(g, gr_crstr_gpc_map5_r(), map5); + + switch (gr->tpc_count) { + case 1: + norm_shift = 4; + break; + case 2: + case 3: + norm_shift = 3; + break; + case 4: + case 5: + case 6: + case 7: + norm_shift = 2; + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + norm_shift = 1; + break; + default: + norm_shift = 0; + break; + } + + norm_entries = gr->tpc_count << norm_shift; + coeff5_mod = (1 << 5) % norm_entries; + coeff6_mod = (1 << 6) % norm_entries; + coeff7_mod = (1 << 7) % norm_entries; + coeff8_mod = (1 << 8) % norm_entries; + coeff9_mod = (1 << 9) % norm_entries; + coeff10_mod = (1 << 10) % norm_entries; + coeff11_mod = (1 << 11) % norm_entries; + + gk20a_writel(g, gr_ppcs_wwdx_map_table_cfg_r(), + gr_ppcs_wwdx_map_table_cfg_row_offset_f(gr->map_row_offset) | + gr_ppcs_wwdx_map_table_cfg_normalized_num_entries_f(norm_entries) | + gr_ppcs_wwdx_map_table_cfg_normalized_shift_value_f(norm_shift) | + gr_ppcs_wwdx_map_table_cfg_coeff5_mod_value_f(coeff5_mod) | + gr_ppcs_wwdx_map_table_cfg_num_entries_f(gr->tpc_count)); + + gk20a_writel(g, gr_ppcs_wwdx_map_table_cfg2_r(), + gr_ppcs_wwdx_map_table_cfg2_coeff6_mod_value_f(coeff6_mod) | + gr_ppcs_wwdx_map_table_cfg2_coeff7_mod_value_f(coeff7_mod) | + gr_ppcs_wwdx_map_table_cfg2_coeff8_mod_value_f(coeff8_mod) | + gr_ppcs_wwdx_map_table_cfg2_coeff9_mod_value_f(coeff9_mod) | + gr_ppcs_wwdx_map_table_cfg2_coeff10_mod_value_f(coeff10_mod) | + gr_ppcs_wwdx_map_table_cfg2_coeff11_mod_value_f(coeff11_mod)); + + gk20a_writel(g, gr_ppcs_wwdx_map_gpc_map0_r(), map0); + gk20a_writel(g, gr_ppcs_wwdx_map_gpc_map1_r(), map1); + gk20a_writel(g, gr_ppcs_wwdx_map_gpc_map2_r(), map2); + gk20a_writel(g, gr_ppcs_wwdx_map_gpc_map3_r(), map3); + gk20a_writel(g, gr_ppcs_wwdx_map_gpc_map4_r(), map4); + gk20a_writel(g, gr_ppcs_wwdx_map_gpc_map5_r(), map5); + + gk20a_writel(g, gr_rstr2d_map_table_cfg_r(), + gr_rstr2d_map_table_cfg_row_offset_f(gr->map_row_offset) | + gr_rstr2d_map_table_cfg_num_entries_f(gr->tpc_count)); + + gk20a_writel(g, gr_rstr2d_gpc_map0_r(), map0); + gk20a_writel(g, gr_rstr2d_gpc_map1_r(), map1); + gk20a_writel(g, gr_rstr2d_gpc_map2_r(), map2); + gk20a_writel(g, gr_rstr2d_gpc_map3_r(), map3); + gk20a_writel(g, gr_rstr2d_gpc_map4_r(), map4); + gk20a_writel(g, gr_rstr2d_gpc_map5_r(), map5); + + return 0; +} + +static inline u32 count_bits(u32 mask) +{ + u32 temp = mask; + u32 count; + for (count = 0; temp != 0; count++) { + temp &= temp - 1; + } + + return count; +} + +int gr_gk20a_init_sm_id_table(struct gk20a *g) +{ + u32 gpc, tpc; + u32 sm_id = 0; + + for (tpc = 0; tpc < g->gr.max_tpc_per_gpc_count; tpc++) { + for (gpc = 0; gpc < g->gr.gpc_count; gpc++) { + + if (tpc < g->gr.gpc_tpc_count[gpc]) { + g->gr.sm_to_cluster[sm_id].tpc_index = tpc; + g->gr.sm_to_cluster[sm_id].gpc_index = gpc; + g->gr.sm_to_cluster[sm_id].sm_index = 0; + g->gr.sm_to_cluster[sm_id].global_tpc_index = + sm_id; + sm_id++; + } + } + } + g->gr.no_of_sm = sm_id; + return 0; +} + +/* + * Return number of TPCs in a GPC + * Return 0 if GPC index is invalid i.e. GPC is disabled + */ +u32 gr_gk20a_get_tpc_count(struct gr_gk20a *gr, u32 gpc_index) +{ + if (gpc_index >= gr->gpc_count) { + return 0; + } + + return gr->gpc_tpc_count[gpc_index]; +} + +int gr_gk20a_init_fs_state(struct gk20a *g) +{ + struct gr_gk20a *gr = &g->gr; + u32 tpc_index, gpc_index; + u32 sm_id = 0, gpc_id = 0; + u32 tpc_per_gpc; + u32 fuse_tpc_mask; + u32 reg_index; + int err; + + nvgpu_log_fn(g, " "); + + if (g->ops.gr.init_sm_id_table) { + err = g->ops.gr.init_sm_id_table(g); + if (err != 0) { + return err; + } + + /* Is table empty ? */ + if (g->gr.no_of_sm == 0) { + return -EINVAL; + } + } + + for (sm_id = 0; sm_id < g->gr.no_of_sm; sm_id++) { + tpc_index = g->gr.sm_to_cluster[sm_id].tpc_index; + gpc_index = g->gr.sm_to_cluster[sm_id].gpc_index; + + g->ops.gr.program_sm_id_numbering(g, gpc_index, tpc_index, sm_id); + + if (g->ops.gr.program_active_tpc_counts) { + g->ops.gr.program_active_tpc_counts(g, gpc_index); + } + } + + for (reg_index = 0, gpc_id = 0; + reg_index < gr_pd_num_tpc_per_gpc__size_1_v(); + reg_index++, gpc_id += 8) { + + tpc_per_gpc = + gr_pd_num_tpc_per_gpc_count0_f(gr_gk20a_get_tpc_count(gr, gpc_id + 0)) | + gr_pd_num_tpc_per_gpc_count1_f(gr_gk20a_get_tpc_count(gr, gpc_id + 1)) | + gr_pd_num_tpc_per_gpc_count2_f(gr_gk20a_get_tpc_count(gr, gpc_id + 2)) | + gr_pd_num_tpc_per_gpc_count3_f(gr_gk20a_get_tpc_count(gr, gpc_id + 3)) | + gr_pd_num_tpc_per_gpc_count4_f(gr_gk20a_get_tpc_count(gr, gpc_id + 4)) | + gr_pd_num_tpc_per_gpc_count5_f(gr_gk20a_get_tpc_count(gr, gpc_id + 5)) | + gr_pd_num_tpc_per_gpc_count6_f(gr_gk20a_get_tpc_count(gr, gpc_id + 6)) | + gr_pd_num_tpc_per_gpc_count7_f(gr_gk20a_get_tpc_count(gr, gpc_id + 7)); + + gk20a_writel(g, gr_pd_num_tpc_per_gpc_r(reg_index), tpc_per_gpc); + gk20a_writel(g, gr_ds_num_tpc_per_gpc_r(reg_index), tpc_per_gpc); + } + + /* gr__setup_pd_mapping stubbed for gk20a */ + g->ops.gr.setup_rop_mapping(g, gr); + if (g->ops.gr.setup_alpha_beta_tables) { + g->ops.gr.setup_alpha_beta_tables(g, gr); + } + + for (gpc_index = 0; + gpc_index < gr_pd_dist_skip_table__size_1_v() * 4; + gpc_index += 4) { + + gk20a_writel(g, gr_pd_dist_skip_table_r(gpc_index/4), + (gr_pd_dist_skip_table_gpc_4n0_mask_f(gr->gpc_skip_mask[gpc_index]) != 0U) || + (gr_pd_dist_skip_table_gpc_4n1_mask_f(gr->gpc_skip_mask[gpc_index + 1]) != 0U) || + (gr_pd_dist_skip_table_gpc_4n2_mask_f(gr->gpc_skip_mask[gpc_index + 2]) != 0U) || + (gr_pd_dist_skip_table_gpc_4n3_mask_f(gr->gpc_skip_mask[gpc_index + 3]) != 0U)); + } + + fuse_tpc_mask = g->ops.gr.get_gpc_tpc_mask(g, 0); + if ((g->tpc_fs_mask_user != 0U) && + (fuse_tpc_mask == BIT32(gr->max_tpc_count) - 1U)) { + u32 val = g->tpc_fs_mask_user; + val &= (0x1U << gr->max_tpc_count) - 1U; + gk20a_writel(g, gr_cwd_fs_r(), + gr_cwd_fs_num_gpcs_f(gr->gpc_count) | + gr_cwd_fs_num_tpcs_f(hweight32(val))); + } else { + gk20a_writel(g, gr_cwd_fs_r(), + gr_cwd_fs_num_gpcs_f(gr->gpc_count) | + gr_cwd_fs_num_tpcs_f(gr->tpc_count)); + } + + gk20a_writel(g, gr_bes_zrop_settings_r(), + gr_bes_zrop_settings_num_active_fbps_f(gr->num_fbps)); + gk20a_writel(g, gr_bes_crop_settings_r(), + gr_bes_crop_settings_num_active_fbps_f(gr->num_fbps)); + + return 0; +} + +int gr_gk20a_fecs_ctx_image_save(struct channel_gk20a *c, u32 save_type) +{ + struct gk20a *g = c->g; + int ret; + + nvgpu_log_fn(g, " "); + + ret = gr_gk20a_submit_fecs_method_op(g, + (struct fecs_method_op_gk20a) { + .method.addr = save_type, + .method.data = fecs_current_ctx_data(g, &c->inst_block), + .mailbox = {.id = 0, .data = 0, .clr = 3, .ret = NULL, + .ok = 1, .fail = 2, + }, + .cond.ok = GR_IS_UCODE_OP_AND, + .cond.fail = GR_IS_UCODE_OP_AND, + }, true); + + if (ret) { + nvgpu_err(g, "save context image failed"); + } + + return ret; +} + +u32 gk20a_init_sw_bundle(struct gk20a *g) +{ + struct av_list_gk20a *sw_bundle_init = &g->gr.ctx_vars.sw_bundle_init; + u32 last_bundle_data = 0; + u32 err = 0; + unsigned int i; + + /* disable fe_go_idle */ + gk20a_writel(g, gr_fe_go_idle_timeout_r(), + gr_fe_go_idle_timeout_count_disabled_f()); + /* enable pipe mode override */ + gk20a_writel(g, gr_pipe_bundle_config_r(), + gr_pipe_bundle_config_override_pipe_mode_enabled_f()); + + /* load bundle init */ + for (i = 0; i < sw_bundle_init->count; i++) { + if (i == 0 || last_bundle_data != sw_bundle_init->l[i].value) { + gk20a_writel(g, gr_pipe_bundle_data_r(), + sw_bundle_init->l[i].value); + last_bundle_data = sw_bundle_init->l[i].value; + } + + gk20a_writel(g, gr_pipe_bundle_address_r(), + sw_bundle_init->l[i].addr); + + if (gr_pipe_bundle_address_value_v(sw_bundle_init->l[i].addr) == + GR_GO_IDLE_BUNDLE) { + err = gr_gk20a_wait_idle(g, + gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + if (err != 0U) { + goto error; + } + } + + err = gr_gk20a_wait_fe_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + if (err != 0U) { + goto error; + } + } + + if ((err == 0U) && (g->ops.gr.init_sw_veid_bundle != NULL)) { + err = g->ops.gr.init_sw_veid_bundle(g); + if (err != 0U) { + goto error; + } + } + + if (g->ops.gr.init_sw_bundle64) { + err = g->ops.gr.init_sw_bundle64(g); + if (err != 0U) { + goto error; + } + } + + /* disable pipe mode override */ + gk20a_writel(g, gr_pipe_bundle_config_r(), + gr_pipe_bundle_config_override_pipe_mode_disabled_f()); + + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + + /* restore fe_go_idle */ + gk20a_writel(g, gr_fe_go_idle_timeout_r(), + gr_fe_go_idle_timeout_count_prod_f()); + + return err; + +error: + /* in case of error skip waiting for GR idle - just restore state */ + gk20a_writel(g, gr_pipe_bundle_config_r(), + gr_pipe_bundle_config_override_pipe_mode_disabled_f()); + + /* restore fe_go_idle */ + gk20a_writel(g, gr_fe_go_idle_timeout_r(), + gr_fe_go_idle_timeout_count_prod_f()); + + return err; +} + +/* init global golden image from a fresh gr_ctx in channel ctx. + save a copy in local_golden_image in ctx_vars */ +static int gr_gk20a_init_golden_ctx_image(struct gk20a *g, + struct channel_gk20a *c) +{ + struct gr_gk20a *gr = &g->gr; + struct tsg_gk20a *tsg; + struct nvgpu_gr_ctx *gr_ctx = NULL; + u32 ctx_header_bytes = ctxsw_prog_fecs_header_v(); + u32 ctx_header_words; + u32 i; + u32 data; + struct nvgpu_mem *gold_mem = &gr->global_ctx_buffer[GOLDEN_CTX].mem; + struct nvgpu_mem *gr_mem; + u32 err = 0; + struct aiv_list_gk20a *sw_ctx_load = &g->gr.ctx_vars.sw_ctx_load; + struct av_list_gk20a *sw_method_init = &g->gr.ctx_vars.sw_method_init; + u32 last_method_data = 0; + + nvgpu_log_fn(g, " "); + + tsg = tsg_gk20a_from_ch(c); + if (tsg == NULL) { + return -EINVAL; + } + + gr_ctx = &tsg->gr_ctx; + gr_mem = &gr_ctx->mem; + + /* golden ctx is global to all channels. Although only the first + channel initializes golden image, driver needs to prevent multiple + channels from initializing golden ctx at the same time */ + nvgpu_mutex_acquire(&gr->ctx_mutex); + + if (gr->ctx_vars.golden_image_initialized) { + goto clean_up; + } + if (!nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) { + struct nvgpu_timeout timeout; + + nvgpu_timeout_init(g, &timeout, + FE_PWR_MODE_TIMEOUT_MAX / + FE_PWR_MODE_TIMEOUT_DEFAULT, + NVGPU_TIMER_RETRY_TIMER); + gk20a_writel(g, gr_fe_pwr_mode_r(), + gr_fe_pwr_mode_req_send_f() | gr_fe_pwr_mode_mode_force_on_f()); + do { + u32 req = gr_fe_pwr_mode_req_v(gk20a_readl(g, gr_fe_pwr_mode_r())); + if (req == gr_fe_pwr_mode_req_done_v()) { + break; + } + nvgpu_udelay(FE_PWR_MODE_TIMEOUT_DEFAULT); + } while (nvgpu_timeout_expired_msg(&timeout, + "timeout forcing FE on") == 0); + } + + + gk20a_writel(g, gr_fecs_ctxsw_reset_ctl_r(), + gr_fecs_ctxsw_reset_ctl_sys_halt_disabled_f() | + gr_fecs_ctxsw_reset_ctl_gpc_halt_disabled_f() | + gr_fecs_ctxsw_reset_ctl_be_halt_disabled_f() | + gr_fecs_ctxsw_reset_ctl_sys_engine_reset_disabled_f() | + gr_fecs_ctxsw_reset_ctl_gpc_engine_reset_disabled_f() | + gr_fecs_ctxsw_reset_ctl_be_engine_reset_disabled_f() | + gr_fecs_ctxsw_reset_ctl_sys_context_reset_enabled_f() | + gr_fecs_ctxsw_reset_ctl_gpc_context_reset_enabled_f() | + gr_fecs_ctxsw_reset_ctl_be_context_reset_enabled_f()); + (void) gk20a_readl(g, gr_fecs_ctxsw_reset_ctl_r()); + nvgpu_udelay(10); + + gk20a_writel(g, gr_fecs_ctxsw_reset_ctl_r(), + gr_fecs_ctxsw_reset_ctl_sys_halt_disabled_f() | + gr_fecs_ctxsw_reset_ctl_gpc_halt_disabled_f() | + gr_fecs_ctxsw_reset_ctl_be_halt_disabled_f() | + gr_fecs_ctxsw_reset_ctl_sys_engine_reset_disabled_f() | + gr_fecs_ctxsw_reset_ctl_gpc_engine_reset_disabled_f() | + gr_fecs_ctxsw_reset_ctl_be_engine_reset_disabled_f() | + gr_fecs_ctxsw_reset_ctl_sys_context_reset_disabled_f() | + gr_fecs_ctxsw_reset_ctl_gpc_context_reset_disabled_f() | + gr_fecs_ctxsw_reset_ctl_be_context_reset_disabled_f()); + (void) gk20a_readl(g, gr_fecs_ctxsw_reset_ctl_r()); + nvgpu_udelay(10); + + if (!nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) { + struct nvgpu_timeout timeout; + + nvgpu_timeout_init(g, &timeout, + FE_PWR_MODE_TIMEOUT_MAX / + FE_PWR_MODE_TIMEOUT_DEFAULT, + NVGPU_TIMER_RETRY_TIMER); + gk20a_writel(g, gr_fe_pwr_mode_r(), + gr_fe_pwr_mode_req_send_f() | gr_fe_pwr_mode_mode_auto_f()); + + do { + u32 req = gr_fe_pwr_mode_req_v(gk20a_readl(g, gr_fe_pwr_mode_r())); + if (req == gr_fe_pwr_mode_req_done_v()) { + break; + } + nvgpu_udelay(FE_PWR_MODE_TIMEOUT_DEFAULT); + } while (nvgpu_timeout_expired_msg(&timeout, + "timeout setting FE power to auto") == 0); + } + + /* clear scc ram */ + gk20a_writel(g, gr_scc_init_r(), + gr_scc_init_ram_trigger_f()); + + err = gr_gk20a_fecs_ctx_bind_channel(g, c); + if (err != 0U) { + goto clean_up; + } + + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + + /* load ctx init */ + for (i = 0; i < sw_ctx_load->count; i++) { + gk20a_writel(g, sw_ctx_load->l[i].addr, + sw_ctx_load->l[i].value); + } + + if (g->ops.gr.init_preemption_state) { + g->ops.gr.init_preemption_state(g); + } + + if (g->ops.clock_gating.blcg_gr_load_gating_prod) { + g->ops.clock_gating.blcg_gr_load_gating_prod(g, g->blcg_enabled); + } + + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + if (err != 0U) { + goto clean_up; + } + + /* disable fe_go_idle */ + gk20a_writel(g, gr_fe_go_idle_timeout_r(), + gr_fe_go_idle_timeout_count_disabled_f()); + + err = g->ops.gr.commit_global_ctx_buffers(g, c, false); + if (err != 0U) { + goto clean_up; + } + + /* override a few ctx state registers */ + g->ops.gr.commit_global_timeslice(g, c); + + /* floorsweep anything left */ + err = g->ops.gr.init_fs_state(g); + if (err != 0U) { + goto clean_up; + } + + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + if (err != 0U) { + goto restore_fe_go_idle; + } + + err = gk20a_init_sw_bundle(g); + if (err != 0U) { + goto clean_up; + } + +restore_fe_go_idle: + /* restore fe_go_idle */ + gk20a_writel(g, gr_fe_go_idle_timeout_r(), + gr_fe_go_idle_timeout_count_prod_f()); + + if ((err != 0U) || (gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT) != 0)) { + goto clean_up; + } + + /* load method init */ + if (sw_method_init->count) { + gk20a_writel(g, gr_pri_mme_shadow_raw_data_r(), + sw_method_init->l[0].value); + gk20a_writel(g, gr_pri_mme_shadow_raw_index_r(), + gr_pri_mme_shadow_raw_index_write_trigger_f() | + sw_method_init->l[0].addr); + last_method_data = sw_method_init->l[0].value; + } + for (i = 1; i < sw_method_init->count; i++) { + if (sw_method_init->l[i].value != last_method_data) { + gk20a_writel(g, gr_pri_mme_shadow_raw_data_r(), + sw_method_init->l[i].value); + last_method_data = sw_method_init->l[i].value; + } + gk20a_writel(g, gr_pri_mme_shadow_raw_index_r(), + gr_pri_mme_shadow_raw_index_write_trigger_f() | + sw_method_init->l[i].addr); + } + + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + if (err != 0U) { + goto clean_up; + } + + ctx_header_words = roundup(ctx_header_bytes, sizeof(u32)); + ctx_header_words >>= 2; + + g->ops.mm.l2_flush(g, true); + + for (i = 0; i < ctx_header_words; i++) { + data = nvgpu_mem_rd32(g, gr_mem, i); + nvgpu_mem_wr32(g, gold_mem, i, data); + } + nvgpu_mem_wr(g, gold_mem, ctxsw_prog_main_image_zcull_o(), + ctxsw_prog_main_image_zcull_mode_no_ctxsw_v()); + + g->ops.gr.write_zcull_ptr(g, gold_mem, 0); + + err = g->ops.gr.commit_inst(c, gr_ctx->global_ctx_buffer_va[GOLDEN_CTX_VA]); + if (err != 0U) { + goto clean_up; + } + + gr_gk20a_fecs_ctx_image_save(c, gr_fecs_method_push_adr_wfi_golden_save_v()); + + + + if (gr->ctx_vars.local_golden_image == NULL) { + + gr->ctx_vars.local_golden_image = + nvgpu_vzalloc(g, gr->ctx_vars.golden_image_size); + + if (gr->ctx_vars.local_golden_image == NULL) { + err = -ENOMEM; + goto clean_up; + } + nvgpu_mem_rd_n(g, gold_mem, 0, + gr->ctx_vars.local_golden_image, + gr->ctx_vars.golden_image_size); + + } + + err = g->ops.gr.commit_inst(c, gr_mem->gpu_va); + if (err != 0U) { + goto clean_up; + } + + gr->ctx_vars.golden_image_initialized = true; + + gk20a_writel(g, gr_fecs_current_ctx_r(), + gr_fecs_current_ctx_valid_false_f()); + +clean_up: + if (err != 0U) { + nvgpu_err(g, "fail"); + } else { + nvgpu_log_fn(g, "done"); + } + + nvgpu_mutex_release(&gr->ctx_mutex); + return err; +} + +int gr_gk20a_update_smpc_ctxsw_mode(struct gk20a *g, + struct channel_gk20a *c, + bool enable_smpc_ctxsw) +{ + struct tsg_gk20a *tsg; + struct nvgpu_gr_ctx *gr_ctx = NULL; + struct nvgpu_mem *mem = NULL; + u32 data; + int ret; + + nvgpu_log_fn(g, " "); + + tsg = tsg_gk20a_from_ch(c); + if (tsg == NULL) { + return -EINVAL; + } + + gr_ctx = &tsg->gr_ctx; + mem = &gr_ctx->mem; + if (!nvgpu_mem_is_valid(mem)) { + nvgpu_err(g, "no graphics context allocated"); + return -EFAULT; + } + + ret = gk20a_disable_channel_tsg(g, c); + if (ret) { + nvgpu_err(g, "failed to disable channel/TSG"); + goto out; + } + ret = gk20a_fifo_preempt(g, c); + if (ret) { + gk20a_enable_channel_tsg(g, c); + nvgpu_err(g, "failed to preempt channel/TSG"); + goto out; + } + + /* Channel gr_ctx buffer is gpu cacheable. + Flush and invalidate before cpu update. */ + g->ops.mm.l2_flush(g, true); + + data = nvgpu_mem_rd(g, mem, + ctxsw_prog_main_image_pm_o()); + + data = data & ~ctxsw_prog_main_image_pm_smpc_mode_m(); + data |= enable_smpc_ctxsw ? + ctxsw_prog_main_image_pm_smpc_mode_ctxsw_f() : + ctxsw_prog_main_image_pm_smpc_mode_no_ctxsw_f(); + + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_pm_o(), data); + +out: + gk20a_enable_channel_tsg(g, c); + return ret; +} + +int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, + struct channel_gk20a *c, + u64 gpu_va, + u32 mode) +{ + struct tsg_gk20a *tsg; + struct nvgpu_mem *gr_mem = NULL; + struct nvgpu_gr_ctx *gr_ctx; + struct pm_ctx_desc *pm_ctx; + u32 data; + u64 virt_addr = 0; + struct nvgpu_mem *ctxheader = &c->ctx_header; + int ret; + + nvgpu_log_fn(g, " "); + + tsg = tsg_gk20a_from_ch(c); + if (tsg == NULL) { + return -EINVAL; + } + + gr_ctx = &tsg->gr_ctx; + pm_ctx = &gr_ctx->pm_ctx; + gr_mem = &gr_ctx->mem; + if (!nvgpu_mem_is_valid(gr_mem)) { + nvgpu_err(g, "no graphics context allocated"); + return -EFAULT; + } + + if ((mode == NVGPU_DBG_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW) && + (g->ops.gr.get_hw_accessor_stream_out_mode == NULL)) { + nvgpu_err(g, "Mode-E hwpm context switch mode is not supported"); + return -EINVAL; + } + + switch (mode) { + case NVGPU_DBG_HWPM_CTXSW_MODE_CTXSW: + if (pm_ctx->pm_mode == ctxsw_prog_main_image_pm_mode_ctxsw_f()) { + return 0; + } + break; + case NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW: + if (pm_ctx->pm_mode == ctxsw_prog_main_image_pm_mode_no_ctxsw_f()) { + return 0; + } + break; + case NVGPU_DBG_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW: + if (pm_ctx->pm_mode == g->ops.gr.get_hw_accessor_stream_out_mode()) { + return 0; + } + break; + default: + nvgpu_err(g, "invalid hwpm context switch mode"); + return -EINVAL; + } + + ret = gk20a_disable_channel_tsg(g, c); + if (ret) { + nvgpu_err(g, "failed to disable channel/TSG"); + return ret; + } + + ret = gk20a_fifo_preempt(g, c); + if (ret) { + gk20a_enable_channel_tsg(g, c); + nvgpu_err(g, "failed to preempt channel/TSG"); + return ret; + } + + /* Channel gr_ctx buffer is gpu cacheable. + Flush and invalidate before cpu update. */ + g->ops.mm.l2_flush(g, true); + + if (mode != NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW) { + /* Allocate buffer if necessary */ + if (pm_ctx->mem.gpu_va == 0) { + ret = nvgpu_dma_alloc_sys(g, + g->gr.ctx_vars.pm_ctxsw_image_size, + &pm_ctx->mem); + if (ret) { + c->g->ops.fifo.enable_channel(c); + nvgpu_err(g, + "failed to allocate pm ctxt buffer"); + return ret; + } + + pm_ctx->mem.gpu_va = nvgpu_gmmu_map_fixed(c->vm, + &pm_ctx->mem, + gpu_va, + pm_ctx->mem.size, + NVGPU_VM_MAP_CACHEABLE, + gk20a_mem_flag_none, true, + pm_ctx->mem.aperture); + if (pm_ctx->mem.gpu_va == 0ULL) { + nvgpu_err(g, + "failed to map pm ctxt buffer"); + nvgpu_dma_free(g, &pm_ctx->mem); + c->g->ops.fifo.enable_channel(c); + return -ENOMEM; + } + } + + if ((mode == NVGPU_DBG_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW) && + (g->ops.gr.init_hwpm_pmm_register != NULL)) { + g->ops.gr.init_hwpm_pmm_register(g); + } + } + + data = nvgpu_mem_rd(g, gr_mem, ctxsw_prog_main_image_pm_o()); + data = data & ~ctxsw_prog_main_image_pm_mode_m(); + + switch (mode) { + case NVGPU_DBG_HWPM_CTXSW_MODE_CTXSW: + pm_ctx->pm_mode = ctxsw_prog_main_image_pm_mode_ctxsw_f(); + virt_addr = pm_ctx->mem.gpu_va; + break; + case NVGPU_DBG_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW: + pm_ctx->pm_mode = g->ops.gr.get_hw_accessor_stream_out_mode(); + virt_addr = pm_ctx->mem.gpu_va; + break; + case NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW: + pm_ctx->pm_mode = ctxsw_prog_main_image_pm_mode_no_ctxsw_f(); + virt_addr = 0; + } + + data |= pm_ctx->pm_mode; + + nvgpu_mem_wr(g, gr_mem, ctxsw_prog_main_image_pm_o(), data); + + if (ctxheader->gpu_va) { + struct channel_gk20a *ch; + + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + nvgpu_list_for_each_entry(ch, &tsg->ch_list, channel_gk20a, ch_entry) { + g->ops.gr.write_pm_ptr(g, &ch->ctx_header, virt_addr); + } + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + } else { + g->ops.gr.write_pm_ptr(g, gr_mem, virt_addr); + } + + /* enable channel */ + gk20a_enable_channel_tsg(g, c); + + return 0; +} + +void gk20a_gr_init_ctxsw_hdr_data(struct gk20a *g, + struct nvgpu_mem *mem) +{ + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_num_save_ops_o(), 0); + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_num_restore_ops_o(), 0); +} + +/* load saved fresh copy of gloden image into channel gr_ctx */ +int gr_gk20a_load_golden_ctx_image(struct gk20a *g, + struct channel_gk20a *c) +{ + struct gr_gk20a *gr = &g->gr; + struct tsg_gk20a *tsg; + struct nvgpu_gr_ctx *gr_ctx; + u32 virt_addr_lo; + u32 virt_addr_hi; + u64 virt_addr = 0; + u32 v, data; + int ret = 0; + struct nvgpu_mem *mem; + + nvgpu_log_fn(g, " "); + + tsg = tsg_gk20a_from_ch(c); + if (tsg == NULL) { + return -EINVAL; + } + + gr_ctx = &tsg->gr_ctx; + mem = &gr_ctx->mem; + if (gr->ctx_vars.local_golden_image == NULL) { + return -EINVAL; + } + + /* Channel gr_ctx buffer is gpu cacheable. + Flush and invalidate before cpu update. */ + g->ops.mm.l2_flush(g, true); + + nvgpu_mem_wr_n(g, mem, 0, + gr->ctx_vars.local_golden_image, + gr->ctx_vars.golden_image_size); + + if (g->ops.gr.init_ctxsw_hdr_data) { + g->ops.gr.init_ctxsw_hdr_data(g, mem); + } + + if ((g->ops.gr.enable_cde_in_fecs != NULL) && c->cde) { + g->ops.gr.enable_cde_in_fecs(g, mem); + } + + /* set priv access map */ + virt_addr_lo = + u64_lo32(gr_ctx->global_ctx_buffer_va[PRIV_ACCESS_MAP_VA]); + virt_addr_hi = + u64_hi32(gr_ctx->global_ctx_buffer_va[PRIV_ACCESS_MAP_VA]); + + if (g->allow_all) { + data = ctxsw_prog_main_image_priv_access_map_config_mode_allow_all_f(); + } else { + data = ctxsw_prog_main_image_priv_access_map_config_mode_use_map_f(); + } + + nvgpu_mem_wr(g, mem, ctxsw_prog_main_image_priv_access_map_config_o(), + data); + + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_priv_access_map_addr_lo_o(), + virt_addr_lo); + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_priv_access_map_addr_hi_o(), + virt_addr_hi); + + /* disable verif features */ + v = nvgpu_mem_rd(g, mem, ctxsw_prog_main_image_misc_options_o()); + v = v & ~(ctxsw_prog_main_image_misc_options_verif_features_m()); + v = v | ctxsw_prog_main_image_misc_options_verif_features_disabled_f(); + nvgpu_mem_wr(g, mem, ctxsw_prog_main_image_misc_options_o(), v); + + if (g->ops.gr.update_ctxsw_preemption_mode) { + g->ops.gr.update_ctxsw_preemption_mode(g, c, mem); + } + + if (g->ops.gr.update_boosted_ctx) { + g->ops.gr.update_boosted_ctx(g, mem, gr_ctx); + } + + virt_addr_lo = u64_lo32(gr_ctx->patch_ctx.mem.gpu_va); + virt_addr_hi = u64_hi32(gr_ctx->patch_ctx.mem.gpu_va); + + nvgpu_log(g, gpu_dbg_info, "write patch count = %d", + gr_ctx->patch_ctx.data_count); + nvgpu_mem_wr(g, mem, ctxsw_prog_main_image_patch_count_o(), + gr_ctx->patch_ctx.data_count); + + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_patch_adr_lo_o(), + virt_addr_lo); + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_patch_adr_hi_o(), + virt_addr_hi); + + /* Update main header region of the context buffer with the info needed + * for PM context switching, including mode and possibly a pointer to + * the PM backing store. + */ + if (gr_ctx->pm_ctx.pm_mode != ctxsw_prog_main_image_pm_mode_no_ctxsw_f()) { + if (gr_ctx->pm_ctx.mem.gpu_va == 0) { + nvgpu_err(g, + "context switched pm with no pm buffer!"); + return -EFAULT; + } + + virt_addr = gr_ctx->pm_ctx.mem.gpu_va; + } else { + virt_addr = 0; + } + + data = nvgpu_mem_rd(g, mem, ctxsw_prog_main_image_pm_o()); + data = data & ~ctxsw_prog_main_image_pm_mode_m(); + data |= gr_ctx->pm_ctx.pm_mode; + + nvgpu_mem_wr(g, mem, ctxsw_prog_main_image_pm_o(), data); + + g->ops.gr.write_pm_ptr(g, mem, virt_addr); + + return ret; +} + +static void gr_gk20a_start_falcon_ucode(struct gk20a *g) +{ + nvgpu_log_fn(g, " "); + + gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), + gr_fecs_ctxsw_mailbox_clear_value_f(~0)); + + gk20a_writel(g, gr_gpccs_dmactl_r(), gr_gpccs_dmactl_require_ctx_f(0)); + gk20a_writel(g, gr_fecs_dmactl_r(), gr_fecs_dmactl_require_ctx_f(0)); + + gk20a_writel(g, gr_gpccs_cpuctl_r(), gr_gpccs_cpuctl_startcpu_f(1)); + gk20a_writel(g, gr_fecs_cpuctl_r(), gr_fecs_cpuctl_startcpu_f(1)); + + nvgpu_log_fn(g, "done"); +} + +static int gr_gk20a_init_ctxsw_ucode_vaspace(struct gk20a *g) +{ + struct mm_gk20a *mm = &g->mm; + struct vm_gk20a *vm = mm->pmu.vm; + struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; + int err; + + err = g->ops.mm.alloc_inst_block(g, &ucode_info->inst_blk_desc); + if (err != 0) { + return err; + } + + g->ops.mm.init_inst_block(&ucode_info->inst_blk_desc, vm, 0); + + /* Map ucode surface to GMMU */ + ucode_info->surface_desc.gpu_va = nvgpu_gmmu_map(vm, + &ucode_info->surface_desc, + ucode_info->surface_desc.size, + 0, /* flags */ + gk20a_mem_flag_read_only, + false, + ucode_info->surface_desc.aperture); + if (ucode_info->surface_desc.gpu_va == 0ULL) { + nvgpu_err(g, "failed to update gmmu ptes"); + return -ENOMEM; + } + + return 0; +} + +static void gr_gk20a_init_ctxsw_ucode_segment( + struct gk20a_ctxsw_ucode_segment *p_seg, u32 *offset, u32 size) +{ + p_seg->offset = *offset; + p_seg->size = size; + *offset = ALIGN(*offset + size, BLK_SIZE); +} + +static void gr_gk20a_init_ctxsw_ucode_segments( + struct gk20a_ctxsw_ucode_segments *segments, u32 *offset, + struct gk20a_ctxsw_bootloader_desc *bootdesc, + u32 code_size, u32 data_size) +{ + u32 boot_size = ALIGN(bootdesc->size, sizeof(u32)); + segments->boot_entry = bootdesc->entry_point; + segments->boot_imem_offset = bootdesc->imem_offset; + gr_gk20a_init_ctxsw_ucode_segment(&segments->boot, offset, boot_size); + gr_gk20a_init_ctxsw_ucode_segment(&segments->code, offset, code_size); + gr_gk20a_init_ctxsw_ucode_segment(&segments->data, offset, data_size); +} + +static int gr_gk20a_copy_ctxsw_ucode_segments( + struct gk20a *g, + struct nvgpu_mem *dst, + struct gk20a_ctxsw_ucode_segments *segments, + u32 *bootimage, + u32 *code, u32 *data) +{ + unsigned int i; + + nvgpu_mem_wr_n(g, dst, segments->boot.offset, bootimage, + segments->boot.size); + nvgpu_mem_wr_n(g, dst, segments->code.offset, code, + segments->code.size); + nvgpu_mem_wr_n(g, dst, segments->data.offset, data, + segments->data.size); + + /* compute a "checksum" for the boot binary to detect its version */ + segments->boot_signature = 0; + for (i = 0; i < segments->boot.size / sizeof(u32); i++) { + segments->boot_signature += bootimage[i]; + } + + return 0; +} + +int gr_gk20a_init_ctxsw_ucode(struct gk20a *g) +{ + struct mm_gk20a *mm = &g->mm; + struct vm_gk20a *vm = mm->pmu.vm; + struct gk20a_ctxsw_bootloader_desc *fecs_boot_desc; + struct gk20a_ctxsw_bootloader_desc *gpccs_boot_desc; + struct nvgpu_firmware *fecs_fw; + struct nvgpu_firmware *gpccs_fw; + u32 *fecs_boot_image; + u32 *gpccs_boot_image; + struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; + u32 ucode_size; + int err = 0; + + fecs_fw = nvgpu_request_firmware(g, GK20A_FECS_UCODE_IMAGE, 0); + if (fecs_fw == NULL) { + nvgpu_err(g, "failed to load fecs ucode!!"); + return -ENOENT; + } + + fecs_boot_desc = (void *)fecs_fw->data; + fecs_boot_image = (void *)(fecs_fw->data + + sizeof(struct gk20a_ctxsw_bootloader_desc)); + + gpccs_fw = nvgpu_request_firmware(g, GK20A_GPCCS_UCODE_IMAGE, 0); + if (gpccs_fw == NULL) { + nvgpu_release_firmware(g, fecs_fw); + nvgpu_err(g, "failed to load gpccs ucode!!"); + return -ENOENT; + } + + gpccs_boot_desc = (void *)gpccs_fw->data; + gpccs_boot_image = (void *)(gpccs_fw->data + + sizeof(struct gk20a_ctxsw_bootloader_desc)); + + ucode_size = 0; + gr_gk20a_init_ctxsw_ucode_segments(&ucode_info->fecs, &ucode_size, + fecs_boot_desc, + g->gr.ctx_vars.ucode.fecs.inst.count * sizeof(u32), + g->gr.ctx_vars.ucode.fecs.data.count * sizeof(u32)); + gr_gk20a_init_ctxsw_ucode_segments(&ucode_info->gpccs, &ucode_size, + gpccs_boot_desc, + g->gr.ctx_vars.ucode.gpccs.inst.count * sizeof(u32), + g->gr.ctx_vars.ucode.gpccs.data.count * sizeof(u32)); + + err = nvgpu_dma_alloc_sys(g, ucode_size, &ucode_info->surface_desc); + if (err != 0) { + goto clean_up; + } + + gr_gk20a_copy_ctxsw_ucode_segments(g, &ucode_info->surface_desc, + &ucode_info->fecs, + fecs_boot_image, + g->gr.ctx_vars.ucode.fecs.inst.l, + g->gr.ctx_vars.ucode.fecs.data.l); + + nvgpu_release_firmware(g, fecs_fw); + fecs_fw = NULL; + + gr_gk20a_copy_ctxsw_ucode_segments(g, &ucode_info->surface_desc, + &ucode_info->gpccs, + gpccs_boot_image, + g->gr.ctx_vars.ucode.gpccs.inst.l, + g->gr.ctx_vars.ucode.gpccs.data.l); + + nvgpu_release_firmware(g, gpccs_fw); + gpccs_fw = NULL; + + err = gr_gk20a_init_ctxsw_ucode_vaspace(g); + if (err != 0) { + goto clean_up; + } + + return 0; + +clean_up: + if (ucode_info->surface_desc.gpu_va) { + nvgpu_gmmu_unmap(vm, &ucode_info->surface_desc, + ucode_info->surface_desc.gpu_va); + } + nvgpu_dma_free(g, &ucode_info->surface_desc); + + nvgpu_release_firmware(g, gpccs_fw); + gpccs_fw = NULL; + nvgpu_release_firmware(g, fecs_fw); + fecs_fw = NULL; + + return err; +} + +static void gr_gk20a_wait_for_fecs_arb_idle(struct gk20a *g) +{ + int retries = FECS_ARB_CMD_TIMEOUT_MAX / FECS_ARB_CMD_TIMEOUT_DEFAULT; + u32 val; + + val = gk20a_readl(g, gr_fecs_arb_ctx_cmd_r()); + while ((gr_fecs_arb_ctx_cmd_cmd_v(val) != 0U) && (retries != 0)) { + nvgpu_udelay(FECS_ARB_CMD_TIMEOUT_DEFAULT); + retries--; + val = gk20a_readl(g, gr_fecs_arb_ctx_cmd_r()); + } + + if (retries == 0) { + nvgpu_err(g, "arbiter cmd timeout, fecs arb ctx cmd: 0x%08x", + gk20a_readl(g, gr_fecs_arb_ctx_cmd_r())); + } + + retries = FECS_ARB_CMD_TIMEOUT_MAX / FECS_ARB_CMD_TIMEOUT_DEFAULT; + while (((gk20a_readl(g, gr_fecs_ctxsw_status_1_r()) & + gr_fecs_ctxsw_status_1_arb_busy_m()) != 0U) && + (retries != 0)) { + nvgpu_udelay(FECS_ARB_CMD_TIMEOUT_DEFAULT); + retries--; + } + if (retries == 0) { + nvgpu_err(g, + "arbiter idle timeout, fecs ctxsw status: 0x%08x", + gk20a_readl(g, gr_fecs_ctxsw_status_1_r())); + } +} + +void gr_gk20a_load_falcon_bind_instblk(struct gk20a *g) +{ + struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; + int retries = FECS_ARB_CMD_TIMEOUT_MAX / FECS_ARB_CMD_TIMEOUT_DEFAULT; + u64 inst_ptr; + + while (((gk20a_readl(g, gr_fecs_ctxsw_status_1_r()) & + gr_fecs_ctxsw_status_1_arb_busy_m()) != 0U) && + (retries != 0)) { + nvgpu_udelay(FECS_ARB_CMD_TIMEOUT_DEFAULT); + retries--; + } + if (retries == 0) { + nvgpu_err(g, + "arbiter idle timeout, status: %08x", + gk20a_readl(g, gr_fecs_ctxsw_status_1_r())); + } + + gk20a_writel(g, gr_fecs_arb_ctx_adr_r(), 0x0); + + inst_ptr = nvgpu_inst_block_addr(g, &ucode_info->inst_blk_desc); + gk20a_writel(g, gr_fecs_new_ctx_r(), + gr_fecs_new_ctx_ptr_f(inst_ptr >> 12) | + nvgpu_aperture_mask(g, &ucode_info->inst_blk_desc, + gr_fecs_new_ctx_target_sys_mem_ncoh_f(), + gr_fecs_new_ctx_target_sys_mem_coh_f(), + gr_fecs_new_ctx_target_vid_mem_f()) | + gr_fecs_new_ctx_valid_m()); + + gk20a_writel(g, gr_fecs_arb_ctx_ptr_r(), + gr_fecs_arb_ctx_ptr_ptr_f(inst_ptr >> 12) | + nvgpu_aperture_mask(g, &ucode_info->inst_blk_desc, + gr_fecs_arb_ctx_ptr_target_sys_mem_ncoh_f(), + gr_fecs_arb_ctx_ptr_target_sys_mem_coh_f(), + gr_fecs_arb_ctx_ptr_target_vid_mem_f())); + + gk20a_writel(g, gr_fecs_arb_ctx_cmd_r(), 0x7); + + /* Wait for arbiter command to complete */ + gr_gk20a_wait_for_fecs_arb_idle(g); + + gk20a_writel(g, gr_fecs_current_ctx_r(), + gr_fecs_current_ctx_ptr_f(inst_ptr >> 12) | + gr_fecs_current_ctx_target_m() | + gr_fecs_current_ctx_valid_m()); + /* Send command to arbiter to flush */ + gk20a_writel(g, gr_fecs_arb_ctx_cmd_r(), gr_fecs_arb_ctx_cmd_cmd_s()); + + gr_gk20a_wait_for_fecs_arb_idle(g); + +} + +void gr_gk20a_load_ctxsw_ucode_header(struct gk20a *g, u64 addr_base, + struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset) +{ + u32 addr_code32; + u32 addr_data32; + + addr_code32 = u64_lo32((addr_base + segments->code.offset) >> 8); + addr_data32 = u64_lo32((addr_base + segments->data.offset) >> 8); + + /* + * Copy falcon bootloader header into dmem at offset 0. + * Configure dmem port 0 for auto-incrementing writes starting at dmem + * offset 0. + */ + gk20a_writel(g, reg_offset + gr_fecs_dmemc_r(0), + gr_fecs_dmemc_offs_f(0) | + gr_fecs_dmemc_blk_f(0) | + gr_fecs_dmemc_aincw_f(1)); + + /* Write out the actual data */ + switch (segments->boot_signature) { + case FALCON_UCODE_SIG_T18X_GPCCS_WITH_RESERVED: + case FALCON_UCODE_SIG_T21X_FECS_WITH_DMEM_SIZE: + case FALCON_UCODE_SIG_T21X_FECS_WITH_RESERVED: + case FALCON_UCODE_SIG_T21X_GPCCS_WITH_RESERVED: + case FALCON_UCODE_SIG_T12X_FECS_WITH_RESERVED: + case FALCON_UCODE_SIG_T12X_GPCCS_WITH_RESERVED: + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + /* fallthrough */ + case FALCON_UCODE_SIG_T12X_FECS_WITHOUT_RESERVED: + case FALCON_UCODE_SIG_T12X_GPCCS_WITHOUT_RESERVED: + case FALCON_UCODE_SIG_T21X_FECS_WITHOUT_RESERVED: + case FALCON_UCODE_SIG_T21X_FECS_WITHOUT_RESERVED2: + case FALCON_UCODE_SIG_T21X_GPCCS_WITHOUT_RESERVED: + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 4); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), + addr_code32); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), + segments->code.size); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), + addr_data32); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), + segments->data.size); + break; + case FALCON_UCODE_SIG_T12X_FECS_OLDER: + case FALCON_UCODE_SIG_T12X_GPCCS_OLDER: + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), + addr_code32); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), + segments->code.size); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), + addr_data32); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), + segments->data.size); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), + addr_code32); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); + break; + default: + nvgpu_err(g, + "unknown falcon ucode boot signature 0x%08x" + " with reg_offset 0x%08x", + segments->boot_signature, reg_offset); + BUG(); + } +} + +void gr_gk20a_load_ctxsw_ucode_boot(struct gk20a *g, u64 addr_base, + struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset) +{ + u32 addr_load32; + u32 blocks; + u32 b; + u32 dst; + + addr_load32 = u64_lo32((addr_base + segments->boot.offset) >> 8); + blocks = ((segments->boot.size + 0xFF) & ~0xFF) >> 8; + + /* + * Set the base FB address for the DMA transfer. Subtract off the 256 + * byte IMEM block offset such that the relative FB and IMEM offsets + * match, allowing the IMEM tags to be properly created. + */ + + dst = segments->boot_imem_offset; + gk20a_writel(g, reg_offset + gr_fecs_dmatrfbase_r(), + (addr_load32 - (dst >> 8))); + + for (b = 0; b < blocks; b++) { + /* Setup destination IMEM offset */ + gk20a_writel(g, reg_offset + gr_fecs_dmatrfmoffs_r(), + dst + (b << 8)); + + /* Setup source offset (relative to BASE) */ + gk20a_writel(g, reg_offset + gr_fecs_dmatrffboffs_r(), + dst + (b << 8)); + + gk20a_writel(g, reg_offset + gr_fecs_dmatrfcmd_r(), + gr_fecs_dmatrfcmd_imem_f(0x01) | + gr_fecs_dmatrfcmd_write_f(0x00) | + gr_fecs_dmatrfcmd_size_f(0x06) | + gr_fecs_dmatrfcmd_ctxdma_f(0)); + } + + /* Specify the falcon boot vector */ + gk20a_writel(g, reg_offset + gr_fecs_bootvec_r(), + gr_fecs_bootvec_vec_f(segments->boot_entry)); +} + +static void gr_gk20a_load_falcon_with_bootloader(struct gk20a *g) +{ + struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; + u64 addr_base = ucode_info->surface_desc.gpu_va; + + gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), 0x0); + + gr_gk20a_load_falcon_bind_instblk(g); + + g->ops.gr.falcon_load_ucode(g, addr_base, + &g->ctxsw_ucode_info.fecs, 0); + + g->ops.gr.falcon_load_ucode(g, addr_base, + &g->ctxsw_ucode_info.gpccs, + gr_gpcs_gpccs_falcon_hwcfg_r() - + gr_fecs_falcon_hwcfg_r()); +} + +int gr_gk20a_load_ctxsw_ucode(struct gk20a *g) +{ + int err; + + nvgpu_log_fn(g, " "); + + if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) { + gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(7), + gr_fecs_ctxsw_mailbox_value_f(0xc0de7777)); + gk20a_writel(g, gr_gpccs_ctxsw_mailbox_r(7), + gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777)); + } + + /* + * In case bootloader is not supported, revert to the old way of + * loading gr ucode, without the faster bootstrap routine. + */ + if (!nvgpu_is_enabled(g, NVGPU_GR_USE_DMA_FOR_FW_BOOTSTRAP)) { + gr_gk20a_load_falcon_dmem(g); + gr_gk20a_load_falcon_imem(g); + gr_gk20a_start_falcon_ucode(g); + } else { + if (!g->gr.skip_ucode_init) { + err = gr_gk20a_init_ctxsw_ucode(g); + + if (err != 0) { + return err; + } + } + gr_gk20a_load_falcon_with_bootloader(g); + g->gr.skip_ucode_init = true; + } + nvgpu_log_fn(g, "done"); + return 0; +} + +int gr_gk20a_set_fecs_watchdog_timeout(struct gk20a *g) +{ + gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), 0xffffffff); + gk20a_writel(g, gr_fecs_method_data_r(), 0x7fffffff); + gk20a_writel(g, gr_fecs_method_push_r(), + gr_fecs_method_push_adr_set_watchdog_timeout_f()); + + return 0; +} + +static int gr_gk20a_wait_ctxsw_ready(struct gk20a *g) +{ + u32 ret; + + nvgpu_log_fn(g, " "); + + ret = gr_gk20a_ctx_wait_ucode(g, 0, NULL, + GR_IS_UCODE_OP_EQUAL, + eUcodeHandshakeInitComplete, + GR_IS_UCODE_OP_SKIP, 0, false); + if (ret) { + nvgpu_err(g, "falcon ucode init timeout"); + return ret; + } + + if (nvgpu_is_enabled(g, NVGPU_GR_USE_DMA_FOR_FW_BOOTSTRAP) || + nvgpu_is_enabled(g, NVGPU_SEC_SECUREGPCCS)) { + gk20a_writel(g, gr_fecs_current_ctx_r(), + gr_fecs_current_ctx_valid_false_f()); + } + + ret = g->ops.gr.set_fecs_watchdog_timeout(g); + if (ret) { + nvgpu_err(g, "fail to set watchdog timeout"); + return ret; + } + + nvgpu_log_fn(g, "done"); + return 0; +} + +int gr_gk20a_init_ctx_state(struct gk20a *g) +{ + u32 ret; + struct fecs_method_op_gk20a op = { + .mailbox = { .id = 0, .data = 0, + .clr = ~0, .ok = 0, .fail = 0}, + .method.data = 0, + .cond.ok = GR_IS_UCODE_OP_NOT_EQUAL, + .cond.fail = GR_IS_UCODE_OP_SKIP, + }; + + nvgpu_log_fn(g, " "); + /* query ctxsw image sizes, if golden context is not created */ + if (!g->gr.ctx_vars.golden_image_initialized) { + op.method.addr = + gr_fecs_method_push_adr_discover_image_size_v(); + op.mailbox.ret = &g->gr.ctx_vars.golden_image_size; + ret = gr_gk20a_submit_fecs_method_op(g, op, false); + if (ret) { + nvgpu_err(g, + "query golden image size failed"); + return ret; + } + op.method.addr = + gr_fecs_method_push_adr_discover_zcull_image_size_v(); + op.mailbox.ret = &g->gr.ctx_vars.zcull_ctxsw_image_size; + ret = gr_gk20a_submit_fecs_method_op(g, op, false); + if (ret) { + nvgpu_err(g, + "query zcull ctx image size failed"); + return ret; + } + op.method.addr = + gr_fecs_method_push_adr_discover_pm_image_size_v(); + op.mailbox.ret = &g->gr.ctx_vars.pm_ctxsw_image_size; + ret = gr_gk20a_submit_fecs_method_op(g, op, false); + if (ret) { + nvgpu_err(g, + "query pm ctx image size failed"); + return ret; + } + g->gr.ctx_vars.priv_access_map_size = 512 * 1024; +#ifdef CONFIG_GK20A_CTXSW_TRACE + g->gr.ctx_vars.fecs_trace_buffer_size = + gk20a_fecs_trace_buffer_size(g); +#endif + } + + nvgpu_log_fn(g, "done"); + return 0; +} + +void gk20a_gr_destroy_ctx_buffer(struct gk20a *g, + struct gr_ctx_buffer_desc *desc) +{ + if (desc == NULL) { + return; + } + nvgpu_dma_free(g, &desc->mem); + desc->destroy = NULL; +} + +int gk20a_gr_alloc_ctx_buffer(struct gk20a *g, + struct gr_ctx_buffer_desc *desc, + size_t size) +{ + int err = 0; + + nvgpu_log_fn(g, " "); + + if (nvgpu_mem_is_valid(&desc->mem)) { + return 0; + } + + err = nvgpu_dma_alloc_sys(g, size, &desc->mem); + if (err != 0) { + return err; + } + + desc->destroy = gk20a_gr_destroy_ctx_buffer; + + return err; +} + +static void gr_gk20a_free_global_ctx_buffers(struct gk20a *g) +{ + struct gr_gk20a *gr = &g->gr; + u32 i; + + for (i = 0; i < NR_GLOBAL_CTX_BUF; i++) { + /* destroy exists iff buffer is allocated */ + if (gr->global_ctx_buffer[i].destroy) { + gr->global_ctx_buffer[i].destroy(g, + &gr->global_ctx_buffer[i]); + } + } + + nvgpu_log_fn(g, "done"); +} + +int gr_gk20a_alloc_global_ctx_buffers(struct gk20a *g) +{ + struct gr_gk20a *gr = &g->gr; + int attr_buffer_size, err; + + u32 cb_buffer_size = gr->bundle_cb_default_size * + gr_scc_bundle_cb_size_div_256b_byte_granularity_v(); + + u32 pagepool_buffer_size = g->ops.gr.pagepool_default_size(g) * + gr_scc_pagepool_total_pages_byte_granularity_v(); + + nvgpu_log_fn(g, " "); + + attr_buffer_size = g->ops.gr.calc_global_ctx_buffer_size(g); + + nvgpu_log_info(g, "cb_buffer_size : %d", cb_buffer_size); + + err = gk20a_gr_alloc_ctx_buffer(g, &gr->global_ctx_buffer[CIRCULAR], + cb_buffer_size); + if (err != 0) { + goto clean_up; + } + + if (g->ops.secure_alloc) { + err = g->ops.secure_alloc(g, + &gr->global_ctx_buffer[CIRCULAR_VPR], + cb_buffer_size); + if (err != 0) { + goto clean_up; + } + } + + nvgpu_log_info(g, "pagepool_buffer_size : %d", pagepool_buffer_size); + + err = gk20a_gr_alloc_ctx_buffer(g, &gr->global_ctx_buffer[PAGEPOOL], + pagepool_buffer_size); + if (err != 0) { + goto clean_up; + } + + if (g->ops.secure_alloc) { + err = g->ops.secure_alloc(g, + &gr->global_ctx_buffer[PAGEPOOL_VPR], + pagepool_buffer_size); + if (err != 0) { + goto clean_up; + } + } + + nvgpu_log_info(g, "attr_buffer_size : %d", attr_buffer_size); + + err = gk20a_gr_alloc_ctx_buffer(g, &gr->global_ctx_buffer[ATTRIBUTE], + attr_buffer_size); + if (err != 0) { + goto clean_up; + } + + if (g->ops.secure_alloc) { + err = g->ops.secure_alloc(g, + &gr->global_ctx_buffer[ATTRIBUTE_VPR], + attr_buffer_size); + if (err != 0) { + goto clean_up; + } + } + + nvgpu_log_info(g, "golden_image_size : %d", + gr->ctx_vars.golden_image_size); + + err = gk20a_gr_alloc_ctx_buffer(g, + &gr->global_ctx_buffer[GOLDEN_CTX], + gr->ctx_vars.golden_image_size); + if (err != 0) { + goto clean_up; + } + + nvgpu_log_info(g, "priv_access_map_size : %d", + gr->ctx_vars.priv_access_map_size); + + err = gk20a_gr_alloc_ctx_buffer(g, + &gr->global_ctx_buffer[PRIV_ACCESS_MAP], + gr->ctx_vars.priv_access_map_size); + + if (err != 0) { + goto clean_up; + } + +#ifdef CONFIG_GK20A_CTXSW_TRACE + nvgpu_log_info(g, "fecs_trace_buffer_size : %d", + gr->ctx_vars.fecs_trace_buffer_size); + + err = nvgpu_dma_alloc_sys(g, + gr->ctx_vars.fecs_trace_buffer_size, + &gr->global_ctx_buffer[FECS_TRACE_BUFFER].mem); + if (err != 0) { + goto clean_up; + } + + gr->global_ctx_buffer[FECS_TRACE_BUFFER].destroy = + gk20a_gr_destroy_ctx_buffer; +#endif + + nvgpu_log_fn(g, "done"); + return 0; + + clean_up: + nvgpu_err(g, "fail"); + gr_gk20a_free_global_ctx_buffers(g); + return -ENOMEM; +} + +static void gr_gk20a_unmap_global_ctx_buffers(struct gk20a *g, + struct vm_gk20a *vm, + struct nvgpu_gr_ctx *gr_ctx) +{ + u64 *g_bfr_va = gr_ctx->global_ctx_buffer_va; + u64 *g_bfr_size = gr_ctx->global_ctx_buffer_size; + int *g_bfr_index = gr_ctx->global_ctx_buffer_index; + u32 i; + + nvgpu_log_fn(g, " "); + + for (i = 0; i < NR_GLOBAL_CTX_BUF_VA; i++) { + if (g_bfr_index[i]) { + struct nvgpu_mem *mem; + + /* + * Translate from VA index to buffer index to determine + * the correct struct nvgpu_mem to use. Handles the VPR + * vs non-VPR difference in context images. + */ + mem = &g->gr.global_ctx_buffer[g_bfr_index[i]].mem; + + nvgpu_gmmu_unmap(vm, mem, g_bfr_va[i]); + } + } + + memset(g_bfr_va, 0, sizeof(gr_ctx->global_ctx_buffer_va)); + memset(g_bfr_size, 0, sizeof(gr_ctx->global_ctx_buffer_size)); + memset(g_bfr_index, 0, sizeof(gr_ctx->global_ctx_buffer_index)); + + gr_ctx->global_ctx_buffer_mapped = false; +} + +int gr_gk20a_map_global_ctx_buffers(struct gk20a *g, + struct channel_gk20a *c) +{ + struct tsg_gk20a *tsg; + struct vm_gk20a *ch_vm = c->vm; + u64 *g_bfr_va; + u64 *g_bfr_size; + int *g_bfr_index; + struct gr_gk20a *gr = &g->gr; + struct nvgpu_mem *mem; + u64 gpu_va; + + nvgpu_log_fn(g, " "); + + tsg = tsg_gk20a_from_ch(c); + if (tsg == NULL) { + return -EINVAL; + } + + g_bfr_va = tsg->gr_ctx.global_ctx_buffer_va; + g_bfr_size = tsg->gr_ctx.global_ctx_buffer_size; + g_bfr_index = tsg->gr_ctx.global_ctx_buffer_index; + + /* Circular Buffer */ + if (c->vpr && + nvgpu_mem_is_valid(&gr->global_ctx_buffer[CIRCULAR_VPR].mem)) { + mem = &gr->global_ctx_buffer[CIRCULAR_VPR].mem; + g_bfr_index[CIRCULAR_VA] = CIRCULAR_VPR; + } else { + mem = &gr->global_ctx_buffer[CIRCULAR].mem; + g_bfr_index[CIRCULAR_VA] = CIRCULAR; + } + + gpu_va = nvgpu_gmmu_map(ch_vm, mem, mem->size, + NVGPU_VM_MAP_CACHEABLE, + gk20a_mem_flag_none, true, mem->aperture); + if (gpu_va == 0ULL) { + goto clean_up; + } + g_bfr_va[CIRCULAR_VA] = gpu_va; + g_bfr_size[CIRCULAR_VA] = mem->size; + + /* Attribute Buffer */ + if (c->vpr && + nvgpu_mem_is_valid(&gr->global_ctx_buffer[ATTRIBUTE_VPR].mem)) { + mem = &gr->global_ctx_buffer[ATTRIBUTE_VPR].mem; + g_bfr_index[ATTRIBUTE_VA] = ATTRIBUTE_VPR; + } else { + mem = &gr->global_ctx_buffer[ATTRIBUTE].mem; + g_bfr_index[ATTRIBUTE_VA] = ATTRIBUTE; + } + + gpu_va = nvgpu_gmmu_map(ch_vm, mem, mem->size, + NVGPU_VM_MAP_CACHEABLE, + gk20a_mem_flag_none, false, mem->aperture); + if (gpu_va == 0ULL) { + goto clean_up; + } + g_bfr_va[ATTRIBUTE_VA] = gpu_va; + g_bfr_size[ATTRIBUTE_VA] = mem->size; + + /* Page Pool */ + if (c->vpr && + nvgpu_mem_is_valid(&gr->global_ctx_buffer[PAGEPOOL_VPR].mem)) { + mem = &gr->global_ctx_buffer[PAGEPOOL_VPR].mem; + g_bfr_index[PAGEPOOL_VA] = PAGEPOOL_VPR; + } else { + mem = &gr->global_ctx_buffer[PAGEPOOL].mem; + g_bfr_index[PAGEPOOL_VA] = PAGEPOOL; + } + + gpu_va = nvgpu_gmmu_map(ch_vm, mem, mem->size, + NVGPU_VM_MAP_CACHEABLE, + gk20a_mem_flag_none, true, mem->aperture); + if (gpu_va == 0ULL) { + goto clean_up; + } + g_bfr_va[PAGEPOOL_VA] = gpu_va; + g_bfr_size[PAGEPOOL_VA] = mem->size; + + /* Golden Image */ + mem = &gr->global_ctx_buffer[GOLDEN_CTX].mem; + gpu_va = nvgpu_gmmu_map(ch_vm, mem, mem->size, 0, + gk20a_mem_flag_none, true, mem->aperture); + if (gpu_va == 0ULL) { + goto clean_up; + } + g_bfr_va[GOLDEN_CTX_VA] = gpu_va; + g_bfr_size[GOLDEN_CTX_VA] = mem->size; + g_bfr_index[GOLDEN_CTX_VA] = GOLDEN_CTX; + + /* Priv register Access Map */ + mem = &gr->global_ctx_buffer[PRIV_ACCESS_MAP].mem; + gpu_va = nvgpu_gmmu_map(ch_vm, mem, mem->size, 0, + gk20a_mem_flag_none, true, mem->aperture); + if (gpu_va == 0ULL) { + goto clean_up; + } + g_bfr_va[PRIV_ACCESS_MAP_VA] = gpu_va; + g_bfr_size[PRIV_ACCESS_MAP_VA] = mem->size; + g_bfr_index[PRIV_ACCESS_MAP_VA] = PRIV_ACCESS_MAP; + + tsg->gr_ctx.global_ctx_buffer_mapped = true; + +#ifdef CONFIG_GK20A_CTXSW_TRACE + /* FECS trace buffer */ + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_VA)) { + mem = &gr->global_ctx_buffer[FECS_TRACE_BUFFER].mem; + gpu_va = nvgpu_gmmu_map(ch_vm, mem, mem->size, 0, + gk20a_mem_flag_none, true, mem->aperture); + if (!gpu_va) + goto clean_up; + g_bfr_va[FECS_TRACE_BUFFER_VA] = gpu_va; + g_bfr_size[FECS_TRACE_BUFFER_VA] = mem->size; + g_bfr_index[FECS_TRACE_BUFFER_VA] = FECS_TRACE_BUFFER; + } +#endif + + return 0; + +clean_up: + gr_gk20a_unmap_global_ctx_buffers(g, ch_vm, &tsg->gr_ctx); + + return -ENOMEM; +} + +int gr_gk20a_alloc_gr_ctx(struct gk20a *g, + struct nvgpu_gr_ctx *gr_ctx, struct vm_gk20a *vm, + u32 class, + u32 padding) +{ + struct gr_gk20a *gr = &g->gr; + int err = 0; + + nvgpu_log_fn(g, " "); + + if (gr->ctx_vars.buffer_size == 0) { + return 0; + } + + /* alloc channel gr ctx buffer */ + gr->ctx_vars.buffer_size = gr->ctx_vars.golden_image_size; + gr->ctx_vars.buffer_total_size = gr->ctx_vars.golden_image_size; + + err = nvgpu_dma_alloc(g, gr->ctx_vars.buffer_total_size, &gr_ctx->mem); + if (err != 0) { + return err; + } + + gr_ctx->mem.gpu_va = nvgpu_gmmu_map(vm, + &gr_ctx->mem, + gr_ctx->mem.size, + 0, /* not GPU-cacheable */ + gk20a_mem_flag_none, true, + gr_ctx->mem.aperture); + if (gr_ctx->mem.gpu_va == 0ULL) { + goto err_free_mem; + } + + return 0; + + err_free_mem: + nvgpu_dma_free(g, &gr_ctx->mem); + + return err; +} + +static int gr_gk20a_alloc_tsg_gr_ctx(struct gk20a *g, + struct tsg_gk20a *tsg, u32 class, u32 padding) +{ + struct nvgpu_gr_ctx *gr_ctx = &tsg->gr_ctx; + int err; + + if (tsg->vm == NULL) { + nvgpu_err(tsg->g, "No address space bound"); + return -ENOMEM; + } + + err = g->ops.gr.alloc_gr_ctx(g, gr_ctx, tsg->vm, class, padding); + if (err != 0) { + return err; + } + + gr_ctx->tsgid = tsg->tsgid; + + return 0; +} + +void gr_gk20a_free_gr_ctx(struct gk20a *g, + struct vm_gk20a *vm, struct nvgpu_gr_ctx *gr_ctx) +{ + nvgpu_log_fn(g, " "); + + if (gr_ctx->mem.gpu_va) { + gr_gk20a_unmap_global_ctx_buffers(g, vm, gr_ctx); + gr_gk20a_free_channel_patch_ctx(g, vm, gr_ctx); + gr_gk20a_free_channel_pm_ctx(g, vm, gr_ctx); + + if ((g->ops.gr.dump_ctxsw_stats != NULL) && + g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close) { + g->ops.gr.dump_ctxsw_stats(g, vm, gr_ctx); + } + + nvgpu_dma_unmap_free(vm, &gr_ctx->pagepool_ctxsw_buffer); + nvgpu_dma_unmap_free(vm, &gr_ctx->betacb_ctxsw_buffer); + nvgpu_dma_unmap_free(vm, &gr_ctx->spill_ctxsw_buffer); + nvgpu_dma_unmap_free(vm, &gr_ctx->preempt_ctxsw_buffer); + nvgpu_dma_unmap_free(vm, &gr_ctx->mem); + + memset(gr_ctx, 0, sizeof(*gr_ctx)); + } +} + +void gr_gk20a_free_tsg_gr_ctx(struct tsg_gk20a *tsg) +{ + struct gk20a *g = tsg->g; + + if (tsg->vm == NULL) { + nvgpu_err(g, "No address space bound"); + return; + } + tsg->g->ops.gr.free_gr_ctx(g, tsg->vm, &tsg->gr_ctx); +} + +u32 gr_gk20a_get_patch_slots(struct gk20a *g) +{ + return PATCH_CTX_SLOTS_PER_PAGE; +} + +static int gr_gk20a_alloc_channel_patch_ctx(struct gk20a *g, + struct channel_gk20a *c) +{ + struct tsg_gk20a *tsg; + struct patch_desc *patch_ctx; + struct vm_gk20a *ch_vm = c->vm; + u32 alloc_size; + int err = 0; + + nvgpu_log_fn(g, " "); + + tsg = tsg_gk20a_from_ch(c); + if (tsg == NULL) { + return -EINVAL; + } + + patch_ctx = &tsg->gr_ctx.patch_ctx; + alloc_size = g->ops.gr.get_patch_slots(g) * + PATCH_CTX_SLOTS_REQUIRED_PER_ENTRY; + + nvgpu_log(g, gpu_dbg_info, "patch buffer size in entries: %d", + alloc_size); + + err = nvgpu_dma_alloc_map_sys(ch_vm, + alloc_size * sizeof(u32), &patch_ctx->mem); + if (err != 0) { + return err; + } + + nvgpu_log_fn(g, "done"); + return 0; +} + +static void gr_gk20a_free_channel_patch_ctx(struct gk20a *g, + struct vm_gk20a *vm, + struct nvgpu_gr_ctx *gr_ctx) +{ + struct patch_desc *patch_ctx = &gr_ctx->patch_ctx; + + nvgpu_log_fn(g, " "); + + if (patch_ctx->mem.gpu_va) { + nvgpu_gmmu_unmap(vm, &patch_ctx->mem, + patch_ctx->mem.gpu_va); + } + + nvgpu_dma_free(g, &patch_ctx->mem); + patch_ctx->data_count = 0; +} + +static void gr_gk20a_free_channel_pm_ctx(struct gk20a *g, + struct vm_gk20a *vm, + struct nvgpu_gr_ctx *gr_ctx) +{ + struct pm_ctx_desc *pm_ctx = &gr_ctx->pm_ctx; + + nvgpu_log_fn(g, " "); + + if (pm_ctx->mem.gpu_va) { + nvgpu_gmmu_unmap(vm, &pm_ctx->mem, pm_ctx->mem.gpu_va); + + nvgpu_dma_free(g, &pm_ctx->mem); + } +} + +int gk20a_alloc_obj_ctx(struct channel_gk20a *c, u32 class_num, u32 flags) +{ + struct gk20a *g = c->g; + struct nvgpu_gr_ctx *gr_ctx; + struct tsg_gk20a *tsg = NULL; + int err = 0; + + nvgpu_log_fn(g, " "); + + /* an address space needs to have been bound at this point.*/ + if (!gk20a_channel_as_bound(c) && (c->vm == NULL)) { + nvgpu_err(g, + "not bound to address space at time" + " of grctx allocation"); + return -EINVAL; + } + + if (!g->ops.gr.is_valid_class(g, class_num)) { + nvgpu_err(g, + "invalid obj class 0x%x", class_num); + err = -EINVAL; + goto out; + } + c->obj_class = class_num; + + tsg = tsg_gk20a_from_ch(c); + if (tsg == NULL) { + return -EINVAL; + } + + gr_ctx = &tsg->gr_ctx; + + if (!nvgpu_mem_is_valid(&gr_ctx->mem)) { + tsg->vm = c->vm; + nvgpu_vm_get(tsg->vm); + err = gr_gk20a_alloc_tsg_gr_ctx(g, tsg, + class_num, + flags); + if (err != 0) { + nvgpu_err(g, + "fail to allocate TSG gr ctx buffer"); + nvgpu_vm_put(tsg->vm); + tsg->vm = NULL; + goto out; + } + + /* allocate patch buffer */ + if (!nvgpu_mem_is_valid(&gr_ctx->patch_ctx.mem)) { + gr_ctx->patch_ctx.data_count = 0; + err = gr_gk20a_alloc_channel_patch_ctx(g, c); + if (err != 0) { + nvgpu_err(g, + "fail to allocate patch buffer"); + goto out; + } + } + + /* map global buffer to channel gpu_va and commit */ + err = g->ops.gr.map_global_ctx_buffers(g, c); + if (err != 0) { + nvgpu_err(g, + "fail to map global ctx buffer"); + goto out; + } + g->ops.gr.commit_global_ctx_buffers(g, c, true); + + /* commit gr ctx buffer */ + err = g->ops.gr.commit_inst(c, gr_ctx->mem.gpu_va); + if (err != 0) { + nvgpu_err(g, + "fail to commit gr ctx buffer"); + goto out; + } + + /* init golden image */ + err = gr_gk20a_init_golden_ctx_image(g, c); + if (err != 0) { + nvgpu_err(g, + "fail to init golden ctx image"); + goto out; + } + + /* Re-enable ELPG now that golden image has been initialized. + * The PMU PG init code may already have tried to enable elpg, but + * would not have been able to complete this action since the golden + * image hadn't been initialized yet, so do this now. + */ + err = nvgpu_pmu_reenable_elpg(g); + if (err != 0) { + nvgpu_err(g, "fail to re-enable elpg"); + goto out; + } + + /* load golden image */ + gr_gk20a_load_golden_ctx_image(g, c); + if (err != 0) { + nvgpu_err(g, + "fail to load golden ctx image"); + goto out; + } +#ifdef CONFIG_GK20A_CTXSW_TRACE + if (g->ops.fecs_trace.bind_channel && !c->vpr) { + err = g->ops.fecs_trace.bind_channel(g, c); + if (err != 0) { + nvgpu_warn(g, + "fail to bind channel for ctxsw trace"); + } + } +#endif + + if (g->ops.gr.set_czf_bypass) { + g->ops.gr.set_czf_bypass(g, c); + } + + /* PM ctxt switch is off by default */ + gr_ctx->pm_ctx.pm_mode = ctxsw_prog_main_image_pm_mode_no_ctxsw_f(); + } else { + /* commit gr ctx buffer */ + err = g->ops.gr.commit_inst(c, gr_ctx->mem.gpu_va); + if (err != 0) { + nvgpu_err(g, + "fail to commit gr ctx buffer"); + goto out; + } +#ifdef CONFIG_GK20A_CTXSW_TRACE + if (g->ops.fecs_trace.bind_channel && !c->vpr) { + err = g->ops.fecs_trace.bind_channel(g, c); + if (err != 0) { + nvgpu_warn(g, + "fail to bind channel for ctxsw trace"); + } + } +#endif + } + + nvgpu_log_fn(g, "done"); + return 0; +out: + /* 1. gr_ctx, patch_ctx and global ctx buffer mapping + can be reused so no need to release them. + 2. golden image init and load is a one time thing so if + they pass, no need to undo. */ + nvgpu_err(g, "fail"); + return err; +} + +static void gk20a_remove_gr_support(struct gr_gk20a *gr) +{ + struct gk20a *g = gr->g; + + nvgpu_log_fn(g, " "); + + gr_gk20a_free_cyclestats_snapshot_data(g); + + gr_gk20a_free_global_ctx_buffers(g); + + nvgpu_dma_free(g, &gr->compbit_store.mem); + + memset(&gr->compbit_store, 0, sizeof(struct compbit_store_desc)); + + nvgpu_kfree(g, gr->gpc_tpc_count); + nvgpu_kfree(g, gr->gpc_zcb_count); + nvgpu_kfree(g, gr->gpc_ppc_count); + nvgpu_kfree(g, gr->pes_tpc_count[0]); + nvgpu_kfree(g, gr->pes_tpc_count[1]); + nvgpu_kfree(g, gr->pes_tpc_mask[0]); + nvgpu_kfree(g, gr->pes_tpc_mask[1]); + nvgpu_kfree(g, gr->sm_to_cluster); + nvgpu_kfree(g, gr->gpc_skip_mask); + nvgpu_kfree(g, gr->map_tiles); + nvgpu_kfree(g, gr->fbp_rop_l2_en_mask); + gr->gpc_tpc_count = NULL; + gr->gpc_zcb_count = NULL; + gr->gpc_ppc_count = NULL; + gr->pes_tpc_count[0] = NULL; + gr->pes_tpc_count[1] = NULL; + gr->pes_tpc_mask[0] = NULL; + gr->pes_tpc_mask[1] = NULL; + gr->gpc_skip_mask = NULL; + gr->map_tiles = NULL; + gr->fbp_rop_l2_en_mask = NULL; + + gr->ctx_vars.valid = false; + nvgpu_kfree(g, gr->ctx_vars.ucode.fecs.inst.l); + nvgpu_kfree(g, gr->ctx_vars.ucode.fecs.data.l); + nvgpu_kfree(g, gr->ctx_vars.ucode.gpccs.inst.l); + nvgpu_kfree(g, gr->ctx_vars.ucode.gpccs.data.l); + nvgpu_kfree(g, gr->ctx_vars.sw_bundle_init.l); + nvgpu_kfree(g, gr->ctx_vars.sw_veid_bundle_init.l); + nvgpu_kfree(g, gr->ctx_vars.sw_method_init.l); + nvgpu_kfree(g, gr->ctx_vars.sw_ctx_load.l); + nvgpu_kfree(g, gr->ctx_vars.sw_non_ctx_load.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.sys.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.gpc.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.tpc.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.zcull_gpc.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.ppc.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.pm_sys.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.pm_gpc.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.pm_tpc.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.pm_ppc.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.perf_sys.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.fbp.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.perf_gpc.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.fbp_router.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.gpc_router.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.pm_ltc.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.pm_fbpa.l); + nvgpu_kfree(g, gr->ctx_vars.sw_bundle64_init.l); + nvgpu_kfree(g, gr->ctx_vars.ctxsw_regs.pm_cau.l); + + nvgpu_vfree(g, gr->ctx_vars.local_golden_image); + gr->ctx_vars.local_golden_image = NULL; + + if (gr->ctx_vars.hwpm_ctxsw_buffer_offset_map) { + nvgpu_big_free(g, gr->ctx_vars.hwpm_ctxsw_buffer_offset_map); + } + gr->ctx_vars.hwpm_ctxsw_buffer_offset_map = NULL; + + gk20a_comptag_allocator_destroy(g, &gr->comp_tags); + + nvgpu_ecc_remove_support(g); +} + +static int gr_gk20a_init_gr_config(struct gk20a *g, struct gr_gk20a *gr) +{ + u32 gpc_index, pes_index; + u32 pes_tpc_mask; + u32 pes_tpc_count; + u32 pes_heavy_index; + u32 gpc_new_skip_mask; + u32 tmp; + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 sm_per_tpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_SM_PER_TPC); + + tmp = gk20a_readl(g, pri_ringmaster_enum_fbp_r()); + gr->num_fbps = pri_ringmaster_enum_fbp_count_v(tmp); + + tmp = gk20a_readl(g, top_num_gpcs_r()); + gr->max_gpc_count = top_num_gpcs_value_v(tmp); + + tmp = gk20a_readl(g, top_num_fbps_r()); + gr->max_fbps_count = top_num_fbps_value_v(tmp); + + gr->fbp_en_mask = g->ops.gr.get_fbp_en_mask(g); + + if (gr->fbp_rop_l2_en_mask == NULL) { + gr->fbp_rop_l2_en_mask = + nvgpu_kzalloc(g, gr->max_fbps_count * sizeof(u32)); + if (gr->fbp_rop_l2_en_mask == NULL) { + goto clean_up; + } + } else { + memset(gr->fbp_rop_l2_en_mask, 0, gr->max_fbps_count * + sizeof(u32)); + } + + tmp = gk20a_readl(g, top_tpc_per_gpc_r()); + gr->max_tpc_per_gpc_count = top_tpc_per_gpc_value_v(tmp); + + gr->max_tpc_count = gr->max_gpc_count * gr->max_tpc_per_gpc_count; + + tmp = gk20a_readl(g, top_num_fbps_r()); + gr->sys_count = top_num_fbps_value_v(tmp); + + tmp = gk20a_readl(g, pri_ringmaster_enum_gpc_r()); + gr->gpc_count = pri_ringmaster_enum_gpc_count_v(tmp); + + gr->pe_count_per_gpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_PES_PER_GPC); + if (WARN(gr->pe_count_per_gpc > GK20A_GR_MAX_PES_PER_GPC, + "too many pes per gpc\n")) { + goto clean_up; + } + + gr->max_zcull_per_gpc_count = nvgpu_get_litter_value(g, GPU_LIT_NUM_ZCULL_BANKS); + + if (gr->gpc_count == 0U) { + nvgpu_err(g, "gpc_count==0!"); + goto clean_up; + } + + if (gr->gpc_tpc_count == NULL) { + gr->gpc_tpc_count = nvgpu_kzalloc(g, gr->gpc_count * + sizeof(u32)); + } else { + memset(gr->gpc_tpc_count, 0, gr->gpc_count * + sizeof(u32)); + } + + if (gr->gpc_tpc_mask == NULL) { + gr->gpc_tpc_mask = nvgpu_kzalloc(g, gr->max_gpc_count * + sizeof(u32)); + } else { + memset(gr->gpc_tpc_mask, 0, gr->max_gpc_count * + sizeof(u32)); + } + + if (gr->gpc_zcb_count == NULL) { + gr->gpc_zcb_count = nvgpu_kzalloc(g, gr->gpc_count * + sizeof(u32)); + } else { + memset(gr->gpc_zcb_count, 0, gr->gpc_count * + sizeof(u32)); + } + + if (gr->gpc_ppc_count == NULL) { + gr->gpc_ppc_count = nvgpu_kzalloc(g, gr->gpc_count * + sizeof(u32)); + } else { + memset(gr->gpc_ppc_count, 0, gr->gpc_count * + sizeof(u32)); + } + + if (gr->gpc_skip_mask == NULL) { + gr->gpc_skip_mask = + nvgpu_kzalloc(g, gr_pd_dist_skip_table__size_1_v() * + 4 * sizeof(u32)); + } else { + memset(gr->gpc_skip_mask, 0, gr_pd_dist_skip_table__size_1_v() * + 4 * sizeof(u32)); + } + + if ((gr->gpc_tpc_count == NULL) || (gr->gpc_tpc_mask == NULL) || + (gr->gpc_zcb_count == NULL) || (gr->gpc_ppc_count == NULL) || + (gr->gpc_skip_mask == NULL)) { + goto clean_up; + } + + for (gpc_index = 0; gpc_index < gr->max_gpc_count; gpc_index++) { + if (g->ops.gr.get_gpc_tpc_mask) { + gr->gpc_tpc_mask[gpc_index] = + g->ops.gr.get_gpc_tpc_mask(g, gpc_index); + } + } + + gr->ppc_count = 0; + gr->tpc_count = 0; + gr->zcb_count = 0; + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + tmp = gk20a_readl(g, gr_gpc0_fs_gpc_r() + + gpc_stride * gpc_index); + + gr->gpc_tpc_count[gpc_index] = + gr_gpc0_fs_gpc_num_available_tpcs_v(tmp); + gr->tpc_count += gr->gpc_tpc_count[gpc_index]; + + gr->gpc_zcb_count[gpc_index] = + gr_gpc0_fs_gpc_num_available_zculls_v(tmp); + gr->zcb_count += gr->gpc_zcb_count[gpc_index]; + + for (pes_index = 0; pes_index < gr->pe_count_per_gpc; pes_index++) { + if (gr->pes_tpc_count[pes_index] == NULL) { + gr->pes_tpc_count[pes_index] = + nvgpu_kzalloc(g, gr->gpc_count * + sizeof(u32)); + gr->pes_tpc_mask[pes_index] = + nvgpu_kzalloc(g, gr->gpc_count * + sizeof(u32)); + if ((gr->pes_tpc_count[pes_index] == NULL) || + (gr->pes_tpc_mask[pes_index] == NULL)) { + goto clean_up; + } + } + + tmp = gk20a_readl(g, + gr_gpc0_gpm_pd_pes_tpc_id_mask_r(pes_index) + + gpc_index * gpc_stride); + + pes_tpc_mask = gr_gpc0_gpm_pd_pes_tpc_id_mask_mask_v(tmp); + pes_tpc_count = count_bits(pes_tpc_mask); + + /* detect PES presence by seeing if there are + * TPCs connected to it. + */ + if (pes_tpc_count != 0) { + gr->gpc_ppc_count[gpc_index]++; + } + + gr->pes_tpc_count[pes_index][gpc_index] = pes_tpc_count; + gr->pes_tpc_mask[pes_index][gpc_index] = pes_tpc_mask; + } + + gr->ppc_count += gr->gpc_ppc_count[gpc_index]; + + gpc_new_skip_mask = 0; + if (gr->pe_count_per_gpc > 1 && + gr->pes_tpc_count[0][gpc_index] + + gr->pes_tpc_count[1][gpc_index] == 5) { + pes_heavy_index = + gr->pes_tpc_count[0][gpc_index] > + gr->pes_tpc_count[1][gpc_index] ? 0 : 1; + + gpc_new_skip_mask = + gr->pes_tpc_mask[pes_heavy_index][gpc_index] ^ + (gr->pes_tpc_mask[pes_heavy_index][gpc_index] & + (gr->pes_tpc_mask[pes_heavy_index][gpc_index] - 1)); + + } else if (gr->pe_count_per_gpc > 1 && + (gr->pes_tpc_count[0][gpc_index] + + gr->pes_tpc_count[1][gpc_index] == 4) && + (gr->pes_tpc_count[0][gpc_index] != + gr->pes_tpc_count[1][gpc_index])) { + pes_heavy_index = + gr->pes_tpc_count[0][gpc_index] > + gr->pes_tpc_count[1][gpc_index] ? 0 : 1; + + gpc_new_skip_mask = + gr->pes_tpc_mask[pes_heavy_index][gpc_index] ^ + (gr->pes_tpc_mask[pes_heavy_index][gpc_index] & + (gr->pes_tpc_mask[pes_heavy_index][gpc_index] - 1)); + } + gr->gpc_skip_mask[gpc_index] = gpc_new_skip_mask; + } + + /* allocate for max tpc per gpc */ + if (gr->sm_to_cluster == NULL) { + gr->sm_to_cluster = nvgpu_kzalloc(g, gr->gpc_count * + gr->max_tpc_per_gpc_count * + sm_per_tpc * sizeof(struct sm_info)); + if (!gr->sm_to_cluster) + goto clean_up; + } else { + memset(gr->sm_to_cluster, 0, gr->gpc_count * + gr->max_tpc_per_gpc_count * + sm_per_tpc * sizeof(struct sm_info)); + } + gr->no_of_sm = 0; + + nvgpu_log_info(g, "fbps: %d", gr->num_fbps); + nvgpu_log_info(g, "max_gpc_count: %d", gr->max_gpc_count); + nvgpu_log_info(g, "max_fbps_count: %d", gr->max_fbps_count); + nvgpu_log_info(g, "max_tpc_per_gpc_count: %d", gr->max_tpc_per_gpc_count); + nvgpu_log_info(g, "max_zcull_per_gpc_count: %d", gr->max_zcull_per_gpc_count); + nvgpu_log_info(g, "max_tpc_count: %d", gr->max_tpc_count); + nvgpu_log_info(g, "sys_count: %d", gr->sys_count); + nvgpu_log_info(g, "gpc_count: %d", gr->gpc_count); + nvgpu_log_info(g, "pe_count_per_gpc: %d", gr->pe_count_per_gpc); + nvgpu_log_info(g, "tpc_count: %d", gr->tpc_count); + nvgpu_log_info(g, "ppc_count: %d", gr->ppc_count); + + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + nvgpu_log_info(g, "gpc_tpc_count[%d] : %d", + gpc_index, gr->gpc_tpc_count[gpc_index]); + } + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + nvgpu_log_info(g, "gpc_zcb_count[%d] : %d", + gpc_index, gr->gpc_zcb_count[gpc_index]); + } + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + nvgpu_log_info(g, "gpc_ppc_count[%d] : %d", + gpc_index, gr->gpc_ppc_count[gpc_index]); + } + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + nvgpu_log_info(g, "gpc_skip_mask[%d] : %d", + gpc_index, gr->gpc_skip_mask[gpc_index]); + } + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + for (pes_index = 0; + pes_index < gr->pe_count_per_gpc; + pes_index++) { + nvgpu_log_info(g, "pes_tpc_count[%d][%d] : %d", + pes_index, gpc_index, + gr->pes_tpc_count[pes_index][gpc_index]); + } + } + + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + for (pes_index = 0; + pes_index < gr->pe_count_per_gpc; + pes_index++) { + nvgpu_log_info(g, "pes_tpc_mask[%d][%d] : %d", + pes_index, gpc_index, + gr->pes_tpc_mask[pes_index][gpc_index]); + } + } + + g->ops.gr.bundle_cb_defaults(g); + g->ops.gr.cb_size_default(g); + g->ops.gr.calc_global_ctx_buffer_size(g); + gr->timeslice_mode = gr_gpcs_ppcs_cbm_cfg_timeslice_mode_enable_v(); + + nvgpu_log_info(g, "bundle_cb_default_size: %d", + gr->bundle_cb_default_size); + nvgpu_log_info(g, "min_gpm_fifo_depth: %d", gr->min_gpm_fifo_depth); + nvgpu_log_info(g, "bundle_cb_token_limit: %d", gr->bundle_cb_token_limit); + nvgpu_log_info(g, "attrib_cb_default_size: %d", + gr->attrib_cb_default_size); + nvgpu_log_info(g, "attrib_cb_size: %d", gr->attrib_cb_size); + nvgpu_log_info(g, "alpha_cb_default_size: %d", gr->alpha_cb_default_size); + nvgpu_log_info(g, "alpha_cb_size: %d", gr->alpha_cb_size); + nvgpu_log_info(g, "timeslice_mode: %d", gr->timeslice_mode); + + return 0; + +clean_up: + return -ENOMEM; +} + +static u32 prime_set[18] = { + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61 }; + +static int gr_gk20a_init_map_tiles(struct gk20a *g, struct gr_gk20a *gr) +{ + s32 comm_denom; + s32 mul_factor; + s32 *init_frac = NULL; + s32 *init_err = NULL; + s32 *run_err = NULL; + s32 *sorted_num_tpcs = NULL; + s32 *sorted_to_unsorted_gpc_map = NULL; + u32 gpc_index; + u32 gpc_mark = 0; + u32 num_tpc; + u32 max_tpc_count = 0; + u32 swap; + u32 tile_count; + u32 index; + bool delete_map = false; + bool gpc_sorted; + int ret = 0; + int num_gpcs = nvgpu_get_litter_value(g, GPU_LIT_NUM_GPCS); + int num_tpc_per_gpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_TPC_PER_GPC); + int map_tile_count = num_gpcs * num_tpc_per_gpc; + + init_frac = nvgpu_kzalloc(g, num_gpcs * sizeof(s32)); + init_err = nvgpu_kzalloc(g, num_gpcs * sizeof(s32)); + run_err = nvgpu_kzalloc(g, num_gpcs * sizeof(s32)); + sorted_num_tpcs = + nvgpu_kzalloc(g, num_gpcs * num_tpc_per_gpc * sizeof(s32)); + sorted_to_unsorted_gpc_map = + nvgpu_kzalloc(g, num_gpcs * sizeof(s32)); + + if (!((init_frac != NULL) && + (init_err != NULL) && + (run_err != NULL) && + (sorted_num_tpcs != NULL) && + (sorted_to_unsorted_gpc_map != NULL))) { + ret = -ENOMEM; + goto clean_up; + } + + gr->map_row_offset = INVALID_SCREEN_TILE_ROW_OFFSET; + + if (gr->tpc_count == 3) { + gr->map_row_offset = 2; + } else if (gr->tpc_count < 3) { + gr->map_row_offset = 1; + } else { + gr->map_row_offset = 3; + + for (index = 1; index < 18; index++) { + u32 prime = prime_set[index]; + if ((gr->tpc_count % prime) != 0) { + gr->map_row_offset = prime; + break; + } + } + } + + switch (gr->tpc_count) { + case 15: + gr->map_row_offset = 6; + break; + case 14: + gr->map_row_offset = 5; + break; + case 13: + gr->map_row_offset = 2; + break; + case 11: + gr->map_row_offset = 7; + break; + case 10: + gr->map_row_offset = 6; + break; + case 7: + case 5: + gr->map_row_offset = 1; + break; + default: + break; + } + + if (gr->map_tiles) { + if (gr->map_tile_count != gr->tpc_count) { + delete_map = true; + } + + for (tile_count = 0; tile_count < gr->map_tile_count; tile_count++) { + if (gr_gk20a_get_map_tile_count(gr, tile_count) + >= gr->tpc_count) { + delete_map = true; + } + } + + if (delete_map) { + nvgpu_kfree(g, gr->map_tiles); + gr->map_tiles = NULL; + gr->map_tile_count = 0; + } + } + + if (gr->map_tiles == NULL) { + gr->map_tiles = nvgpu_kzalloc(g, map_tile_count * sizeof(u8)); + if (gr->map_tiles == NULL) { + ret = -ENOMEM; + goto clean_up; + } + gr->map_tile_count = map_tile_count; + + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + sorted_num_tpcs[gpc_index] = gr->gpc_tpc_count[gpc_index]; + sorted_to_unsorted_gpc_map[gpc_index] = gpc_index; + } + + gpc_sorted = false; + while (!gpc_sorted) { + gpc_sorted = true; + for (gpc_index = 0; gpc_index < gr->gpc_count - 1; gpc_index++) { + if (sorted_num_tpcs[gpc_index + 1] > sorted_num_tpcs[gpc_index]) { + gpc_sorted = false; + swap = sorted_num_tpcs[gpc_index]; + sorted_num_tpcs[gpc_index] = sorted_num_tpcs[gpc_index + 1]; + sorted_num_tpcs[gpc_index + 1] = swap; + swap = sorted_to_unsorted_gpc_map[gpc_index]; + sorted_to_unsorted_gpc_map[gpc_index] = + sorted_to_unsorted_gpc_map[gpc_index + 1]; + sorted_to_unsorted_gpc_map[gpc_index + 1] = swap; + } + } + } + + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + if (gr->gpc_tpc_count[gpc_index] > max_tpc_count) { + max_tpc_count = gr->gpc_tpc_count[gpc_index]; + } + } + + mul_factor = gr->gpc_count * max_tpc_count; + if (mul_factor & 0x1) { + mul_factor = 2; + } else { + mul_factor = 1; + } + + comm_denom = gr->gpc_count * max_tpc_count * mul_factor; + + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + num_tpc = sorted_num_tpcs[gpc_index]; + + init_frac[gpc_index] = num_tpc * gr->gpc_count * mul_factor; + + if (num_tpc != 0) { + init_err[gpc_index] = gpc_index * max_tpc_count * mul_factor - comm_denom/2; + } else { + init_err[gpc_index] = 0; + } + + run_err[gpc_index] = init_frac[gpc_index] + init_err[gpc_index]; + } + + while (gpc_mark < gr->tpc_count) { + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + if ((run_err[gpc_index] * 2) >= comm_denom) { + gr->map_tiles[gpc_mark++] = (u8)sorted_to_unsorted_gpc_map[gpc_index]; + run_err[gpc_index] += init_frac[gpc_index] - comm_denom; + } else { + run_err[gpc_index] += init_frac[gpc_index]; + } + } + } + } + +clean_up: + nvgpu_kfree(g, init_frac); + nvgpu_kfree(g, init_err); + nvgpu_kfree(g, run_err); + nvgpu_kfree(g, sorted_num_tpcs); + nvgpu_kfree(g, sorted_to_unsorted_gpc_map); + + if (ret) { + nvgpu_err(g, "fail"); + } else { + nvgpu_log_fn(g, "done"); + } + + return ret; +} + +static int gr_gk20a_init_zcull(struct gk20a *g, struct gr_gk20a *gr) +{ + struct gr_zcull_gk20a *zcull = &gr->zcull; + + zcull->aliquot_width = gr->tpc_count * 16; + zcull->aliquot_height = 16; + + zcull->width_align_pixels = gr->tpc_count * 16; + zcull->height_align_pixels = 32; + + zcull->aliquot_size = + zcull->aliquot_width * zcull->aliquot_height; + + /* assume no floor sweeping since we only have 1 tpc in 1 gpc */ + zcull->pixel_squares_by_aliquots = + gr->zcb_count * 16 * 16 * gr->tpc_count / + (gr->gpc_count * gr->gpc_tpc_count[0]); + + zcull->total_aliquots = + gr_gpc0_zcull_total_ram_size_num_aliquots_f( + gk20a_readl(g, gr_gpc0_zcull_total_ram_size_r())); + + return 0; +} + +u32 gr_gk20a_get_ctxsw_zcull_size(struct gk20a *g, struct gr_gk20a *gr) +{ + /* assuming gr has already been initialized */ + return gr->ctx_vars.zcull_ctxsw_image_size; +} + +int gr_gk20a_bind_ctxsw_zcull(struct gk20a *g, struct gr_gk20a *gr, + struct channel_gk20a *c, u64 zcull_va, u32 mode) +{ + struct tsg_gk20a *tsg; + struct zcull_ctx_desc *zcull_ctx; + + tsg = tsg_gk20a_from_ch(c); + if (tsg == NULL) { + return -EINVAL; + } + + zcull_ctx = &tsg->gr_ctx.zcull_ctx; + zcull_ctx->ctx_sw_mode = mode; + zcull_ctx->gpu_va = zcull_va; + + /* TBD: don't disable channel in sw method processing */ + return gr_gk20a_ctx_zcull_setup(g, c); +} + +int gr_gk20a_get_zcull_info(struct gk20a *g, struct gr_gk20a *gr, + struct gr_zcull_info *zcull_params) +{ + struct gr_zcull_gk20a *zcull = &gr->zcull; + + zcull_params->width_align_pixels = zcull->width_align_pixels; + zcull_params->height_align_pixels = zcull->height_align_pixels; + zcull_params->pixel_squares_by_aliquots = + zcull->pixel_squares_by_aliquots; + zcull_params->aliquot_total = zcull->total_aliquots; + + zcull_params->region_byte_multiplier = + gr->gpc_count * gr_zcull_bytes_per_aliquot_per_gpu_v(); + zcull_params->region_header_size = + nvgpu_get_litter_value(g, GPU_LIT_NUM_GPCS) * + gr_zcull_save_restore_header_bytes_per_gpc_v(); + + zcull_params->subregion_header_size = + nvgpu_get_litter_value(g, GPU_LIT_NUM_GPCS) * + gr_zcull_save_restore_subregion_header_bytes_per_gpc_v(); + + zcull_params->subregion_width_align_pixels = + gr->tpc_count * gr_gpc0_zcull_zcsize_width_subregion__multiple_v(); + zcull_params->subregion_height_align_pixels = + gr_gpc0_zcull_zcsize_height_subregion__multiple_v(); + zcull_params->subregion_count = gr_zcull_subregion_qty_v(); + + return 0; +} + +int gr_gk20a_add_zbc_color(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *color_val, u32 index) +{ + u32 i; + + /* update l2 table */ + g->ops.ltc.set_zbc_color_entry(g, color_val, index); + + /* update ds table */ + gk20a_writel(g, gr_ds_zbc_color_r_r(), + gr_ds_zbc_color_r_val_f(color_val->color_ds[0])); + gk20a_writel(g, gr_ds_zbc_color_g_r(), + gr_ds_zbc_color_g_val_f(color_val->color_ds[1])); + gk20a_writel(g, gr_ds_zbc_color_b_r(), + gr_ds_zbc_color_b_val_f(color_val->color_ds[2])); + gk20a_writel(g, gr_ds_zbc_color_a_r(), + gr_ds_zbc_color_a_val_f(color_val->color_ds[3])); + + gk20a_writel(g, gr_ds_zbc_color_fmt_r(), + gr_ds_zbc_color_fmt_val_f(color_val->format)); + + gk20a_writel(g, gr_ds_zbc_tbl_index_r(), + gr_ds_zbc_tbl_index_val_f(index + GK20A_STARTOF_ZBC_TABLE)); + + /* trigger the write */ + gk20a_writel(g, gr_ds_zbc_tbl_ld_r(), + gr_ds_zbc_tbl_ld_select_c_f() | + gr_ds_zbc_tbl_ld_action_write_f() | + gr_ds_zbc_tbl_ld_trigger_active_f()); + + /* update local copy */ + for (i = 0; i < GK20A_ZBC_COLOR_VALUE_SIZE; i++) { + gr->zbc_col_tbl[index].color_l2[i] = color_val->color_l2[i]; + gr->zbc_col_tbl[index].color_ds[i] = color_val->color_ds[i]; + } + gr->zbc_col_tbl[index].format = color_val->format; + gr->zbc_col_tbl[index].ref_cnt++; + + return 0; +} + +int gr_gk20a_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *depth_val, u32 index) +{ + /* update l2 table */ + g->ops.ltc.set_zbc_depth_entry(g, depth_val, index); + + /* update ds table */ + gk20a_writel(g, gr_ds_zbc_z_r(), + gr_ds_zbc_z_val_f(depth_val->depth)); + + gk20a_writel(g, gr_ds_zbc_z_fmt_r(), + gr_ds_zbc_z_fmt_val_f(depth_val->format)); + + gk20a_writel(g, gr_ds_zbc_tbl_index_r(), + gr_ds_zbc_tbl_index_val_f(index + GK20A_STARTOF_ZBC_TABLE)); + + /* trigger the write */ + gk20a_writel(g, gr_ds_zbc_tbl_ld_r(), + gr_ds_zbc_tbl_ld_select_z_f() | + gr_ds_zbc_tbl_ld_action_write_f() | + gr_ds_zbc_tbl_ld_trigger_active_f()); + + /* update local copy */ + gr->zbc_dep_tbl[index].depth = depth_val->depth; + gr->zbc_dep_tbl[index].format = depth_val->format; + gr->zbc_dep_tbl[index].ref_cnt++; + + return 0; +} + +void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries) +{ + struct fifo_gk20a *f = &g->fifo; + struct fifo_engine_info_gk20a *gr_info = NULL; + u32 ret; + u32 engine_id; + + engine_id = gk20a_fifo_get_gr_engine_id(g); + gr_info = (f->engine_info + engine_id); + + ret = gk20a_fifo_disable_engine_activity(g, gr_info, true); + if (ret) { + nvgpu_err(g, + "failed to disable gr engine activity"); + return; + } + + ret = g->ops.gr.wait_empty(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + if (ret) { + nvgpu_err(g, + "failed to idle graphics"); + goto clean_up; + } + + /* update zbc */ + g->ops.gr.pmu_save_zbc(g, entries); + +clean_up: + ret = gk20a_fifo_enable_engine_activity(g, gr_info); + if (ret) { + nvgpu_err(g, + "failed to enable gr engine activity"); + } +} + +int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *zbc_val) +{ + struct zbc_color_table *c_tbl; + struct zbc_depth_table *d_tbl; + u32 i; + int ret = -ENOSPC; + bool added = false; + u32 entries; + + /* no endian swap ? */ + + nvgpu_mutex_acquire(&gr->zbc_lock); + nvgpu_speculation_barrier(); + switch (zbc_val->type) { + case GK20A_ZBC_TYPE_COLOR: + /* search existing tables */ + for (i = 0; i < gr->max_used_color_index; i++) { + + c_tbl = &gr->zbc_col_tbl[i]; + + if ((c_tbl->ref_cnt != 0U) && + (c_tbl->format == zbc_val->format) && + (memcmp(c_tbl->color_ds, zbc_val->color_ds, + sizeof(zbc_val->color_ds)) == 0) && + (memcmp(c_tbl->color_l2, zbc_val->color_l2, + sizeof(zbc_val->color_l2)) == 0)) { + + added = true; + c_tbl->ref_cnt++; + ret = 0; + break; + } + } + /* add new table */ + if (!added && + gr->max_used_color_index < GK20A_ZBC_TABLE_SIZE) { + + c_tbl = + &gr->zbc_col_tbl[gr->max_used_color_index]; + WARN_ON(c_tbl->ref_cnt != 0); + + ret = g->ops.gr.add_zbc_color(g, gr, + zbc_val, gr->max_used_color_index); + + if (ret == 0) { + gr->max_used_color_index++; + } + } + break; + case GK20A_ZBC_TYPE_DEPTH: + /* search existing tables */ + for (i = 0; i < gr->max_used_depth_index; i++) { + + d_tbl = &gr->zbc_dep_tbl[i]; + + if ((d_tbl->ref_cnt != 0U) && + (d_tbl->depth == zbc_val->depth) && + (d_tbl->format == zbc_val->format)) { + added = true; + d_tbl->ref_cnt++; + ret = 0; + break; + } + } + /* add new table */ + if (!added && + gr->max_used_depth_index < GK20A_ZBC_TABLE_SIZE) { + + d_tbl = + &gr->zbc_dep_tbl[gr->max_used_depth_index]; + WARN_ON(d_tbl->ref_cnt != 0); + + ret = g->ops.gr.add_zbc_depth(g, gr, + zbc_val, gr->max_used_depth_index); + + if (ret == 0) { + gr->max_used_depth_index++; + } + } + break; + case T19X_ZBC: + if (g->ops.gr.add_zbc_type_s) { + added = g->ops.gr.add_zbc_type_s(g, gr, zbc_val, &ret); + } else { + nvgpu_err(g, + "invalid zbc table type %d", zbc_val->type); + ret = -EINVAL; + goto err_mutex; + } + break; + default: + nvgpu_err(g, + "invalid zbc table type %d", zbc_val->type); + ret = -EINVAL; + goto err_mutex; + } + + if (!added && ret == 0) { + /* update zbc for elpg only when new entry is added */ + entries = max(gr->max_used_color_index, + gr->max_used_depth_index); + g->ops.gr.pmu_save_zbc(g, entries); + } + +err_mutex: + nvgpu_mutex_release(&gr->zbc_lock); + return ret; +} + +/* get a zbc table entry specified by index + * return table size when type is invalid */ +int gr_gk20a_query_zbc(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_query_params *query_params) +{ + u32 index = query_params->index_size; + u32 i; + + nvgpu_speculation_barrier(); + switch (query_params->type) { + case GK20A_ZBC_TYPE_INVALID: + query_params->index_size = GK20A_ZBC_TABLE_SIZE; + break; + case GK20A_ZBC_TYPE_COLOR: + if (index >= GK20A_ZBC_TABLE_SIZE) { + nvgpu_err(g, + "invalid zbc color table index"); + return -EINVAL; + } + + nvgpu_speculation_barrier(); + for (i = 0; i < GK20A_ZBC_COLOR_VALUE_SIZE; i++) { + query_params->color_l2[i] = + gr->zbc_col_tbl[index].color_l2[i]; + query_params->color_ds[i] = + gr->zbc_col_tbl[index].color_ds[i]; + } + query_params->format = gr->zbc_col_tbl[index].format; + query_params->ref_cnt = gr->zbc_col_tbl[index].ref_cnt; + break; + case GK20A_ZBC_TYPE_DEPTH: + if (index >= GK20A_ZBC_TABLE_SIZE) { + nvgpu_err(g, + "invalid zbc depth table index"); + return -EINVAL; + } + + nvgpu_speculation_barrier(); + query_params->depth = gr->zbc_dep_tbl[index].depth; + query_params->format = gr->zbc_dep_tbl[index].format; + query_params->ref_cnt = gr->zbc_dep_tbl[index].ref_cnt; + break; + case T19X_ZBC: + if (g->ops.gr.zbc_s_query_table) { + return g->ops.gr.zbc_s_query_table(g, gr, + query_params); + } else { + nvgpu_err(g, + "invalid zbc table type"); + return -EINVAL; + } + break; + default: + nvgpu_err(g, + "invalid zbc table type"); + return -EINVAL; + } + + return 0; +} + +static int gr_gk20a_load_zbc_table(struct gk20a *g, struct gr_gk20a *gr) +{ + unsigned int i; + int ret; + + for (i = 0; i < gr->max_used_color_index; i++) { + struct zbc_color_table *c_tbl = &gr->zbc_col_tbl[i]; + struct zbc_entry zbc_val; + + zbc_val.type = GK20A_ZBC_TYPE_COLOR; + memcpy(zbc_val.color_ds, + c_tbl->color_ds, sizeof(zbc_val.color_ds)); + memcpy(zbc_val.color_l2, + c_tbl->color_l2, sizeof(zbc_val.color_l2)); + zbc_val.format = c_tbl->format; + + ret = g->ops.gr.add_zbc_color(g, gr, &zbc_val, i); + + if (ret) { + return ret; + } + } + for (i = 0; i < gr->max_used_depth_index; i++) { + struct zbc_depth_table *d_tbl = &gr->zbc_dep_tbl[i]; + struct zbc_entry zbc_val; + + zbc_val.type = GK20A_ZBC_TYPE_DEPTH; + zbc_val.depth = d_tbl->depth; + zbc_val.format = d_tbl->format; + + ret = g->ops.gr.add_zbc_depth(g, gr, &zbc_val, i); + if (ret) { + return ret; + } + } + + if (g->ops.gr.load_zbc_s_tbl) { + ret = g->ops.gr.load_zbc_s_tbl(g, gr); + if (ret) { + return ret; + } + } + + return 0; +} + +int gr_gk20a_load_zbc_default_table(struct gk20a *g, struct gr_gk20a *gr) +{ + struct zbc_entry zbc_val; + u32 i = 0; + int err = 0; + + err = nvgpu_mutex_init(&gr->zbc_lock); + if (err != 0) { + nvgpu_err(g, "Error in zbc_lock mutex initialization"); + return err; + } + + /* load default color table */ + zbc_val.type = GK20A_ZBC_TYPE_COLOR; + + /* Opaque black (i.e. solid black, fmt 0x28 = A8B8G8R8) */ + zbc_val.format = gr_ds_zbc_color_fmt_val_a8_b8_g8_r8_v(); + for (i = 0; i < GK20A_ZBC_COLOR_VALUE_SIZE; i++) { + zbc_val.color_ds[i] = 0; + zbc_val.color_l2[i] = 0; + } + zbc_val.color_l2[0] = 0xff000000; + zbc_val.color_ds[3] = 0x3f800000; + err = gr_gk20a_add_zbc(g, gr, &zbc_val); + if (err != 0) { + goto color_fail; + } + + /* Transparent black = (fmt 1 = zero) */ + zbc_val.format = gr_ds_zbc_color_fmt_val_zero_v(); + for (i = 0; i < GK20A_ZBC_COLOR_VALUE_SIZE; i++) { + zbc_val.color_ds[i] = 0; + zbc_val.color_l2[i] = 0; + } + err = gr_gk20a_add_zbc(g, gr, &zbc_val); + if (err != 0) { + goto color_fail; + } + + /* Opaque white (i.e. solid white) = (fmt 2 = uniform 1) */ + zbc_val.format = gr_ds_zbc_color_fmt_val_unorm_one_v(); + for (i = 0; i < GK20A_ZBC_COLOR_VALUE_SIZE; i++) { + zbc_val.color_ds[i] = 0x3f800000; + zbc_val.color_l2[i] = 0xffffffff; + } + err = gr_gk20a_add_zbc(g, gr, &zbc_val); + if (err != 0) { + goto color_fail; + } + + gr->max_default_color_index = 3; + + /* load default depth table */ + zbc_val.type = GK20A_ZBC_TYPE_DEPTH; + + zbc_val.format = gr_ds_zbc_z_fmt_val_fp32_v(); + zbc_val.depth = 0x3f800000; + err = gr_gk20a_add_zbc(g, gr, &zbc_val); + if (err != 0) { + goto depth_fail; + } + + zbc_val.format = gr_ds_zbc_z_fmt_val_fp32_v(); + zbc_val.depth = 0; + err = gr_gk20a_add_zbc(g, gr, &zbc_val); + if (err != 0) { + goto depth_fail; + } + + gr->max_default_depth_index = 2; + + if (g->ops.gr.load_zbc_s_default_tbl) { + err = g->ops.gr.load_zbc_s_default_tbl(g, gr); + if (err != 0) { + return err; + } + } + + return 0; + +color_fail: + nvgpu_err(g, "fail to load default zbc color table"); + return err; +depth_fail: + nvgpu_err(g, "fail to load default zbc depth table"); + return err; +} + +int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *zbc_val) +{ + struct fifo_gk20a *f = &g->fifo; + struct fifo_engine_info_gk20a *gr_info = NULL; + int ret; + u32 engine_id; + + engine_id = gk20a_fifo_get_gr_engine_id(g); + gr_info = (f->engine_info + engine_id); + + ret = gk20a_fifo_disable_engine_activity(g, gr_info, true); + if (ret) { + nvgpu_err(g, + "failed to disable gr engine activity"); + return ret; + } + + ret = g->ops.gr.wait_empty(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + if (ret) { + nvgpu_err(g, + "failed to idle graphics"); + goto clean_up; + } + + ret = gr_gk20a_add_zbc(g, gr, zbc_val); + +clean_up: + if (gk20a_fifo_enable_engine_activity(g, gr_info)) { + nvgpu_err(g, + "failed to enable gr engine activity"); + } + + return ret; +} + +int gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *zbc_val) +{ + nvgpu_log_fn(g, " "); + + return gr_gk20a_elpg_protected_call(g, + gr_gk20a_add_zbc(g, gr, zbc_val)); +} + +void gr_gk20a_program_zcull_mapping(struct gk20a *g, u32 zcull_num_entries, + u32 *zcull_map_tiles) +{ + u32 val; + + nvgpu_log_fn(g, " "); + + if (zcull_num_entries >= 8) { + nvgpu_log_fn(g, "map0"); + val = + gr_gpcs_zcull_sm_in_gpc_number_map0_tile_0_f( + zcull_map_tiles[0]) | + gr_gpcs_zcull_sm_in_gpc_number_map0_tile_1_f( + zcull_map_tiles[1]) | + gr_gpcs_zcull_sm_in_gpc_number_map0_tile_2_f( + zcull_map_tiles[2]) | + gr_gpcs_zcull_sm_in_gpc_number_map0_tile_3_f( + zcull_map_tiles[3]) | + gr_gpcs_zcull_sm_in_gpc_number_map0_tile_4_f( + zcull_map_tiles[4]) | + gr_gpcs_zcull_sm_in_gpc_number_map0_tile_5_f( + zcull_map_tiles[5]) | + gr_gpcs_zcull_sm_in_gpc_number_map0_tile_6_f( + zcull_map_tiles[6]) | + gr_gpcs_zcull_sm_in_gpc_number_map0_tile_7_f( + zcull_map_tiles[7]); + + gk20a_writel(g, gr_gpcs_zcull_sm_in_gpc_number_map0_r(), val); + } + + if (zcull_num_entries >= 16) { + nvgpu_log_fn(g, "map1"); + val = + gr_gpcs_zcull_sm_in_gpc_number_map1_tile_8_f( + zcull_map_tiles[8]) | + gr_gpcs_zcull_sm_in_gpc_number_map1_tile_9_f( + zcull_map_tiles[9]) | + gr_gpcs_zcull_sm_in_gpc_number_map1_tile_10_f( + zcull_map_tiles[10]) | + gr_gpcs_zcull_sm_in_gpc_number_map1_tile_11_f( + zcull_map_tiles[11]) | + gr_gpcs_zcull_sm_in_gpc_number_map1_tile_12_f( + zcull_map_tiles[12]) | + gr_gpcs_zcull_sm_in_gpc_number_map1_tile_13_f( + zcull_map_tiles[13]) | + gr_gpcs_zcull_sm_in_gpc_number_map1_tile_14_f( + zcull_map_tiles[14]) | + gr_gpcs_zcull_sm_in_gpc_number_map1_tile_15_f( + zcull_map_tiles[15]); + + gk20a_writel(g, gr_gpcs_zcull_sm_in_gpc_number_map1_r(), val); + } + + if (zcull_num_entries >= 24) { + nvgpu_log_fn(g, "map2"); + val = + gr_gpcs_zcull_sm_in_gpc_number_map2_tile_16_f( + zcull_map_tiles[16]) | + gr_gpcs_zcull_sm_in_gpc_number_map2_tile_17_f( + zcull_map_tiles[17]) | + gr_gpcs_zcull_sm_in_gpc_number_map2_tile_18_f( + zcull_map_tiles[18]) | + gr_gpcs_zcull_sm_in_gpc_number_map2_tile_19_f( + zcull_map_tiles[19]) | + gr_gpcs_zcull_sm_in_gpc_number_map2_tile_20_f( + zcull_map_tiles[20]) | + gr_gpcs_zcull_sm_in_gpc_number_map2_tile_21_f( + zcull_map_tiles[21]) | + gr_gpcs_zcull_sm_in_gpc_number_map2_tile_22_f( + zcull_map_tiles[22]) | + gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_f( + zcull_map_tiles[23]); + + gk20a_writel(g, gr_gpcs_zcull_sm_in_gpc_number_map2_r(), val); + } + + if (zcull_num_entries >= 32) { + nvgpu_log_fn(g, "map3"); + val = + gr_gpcs_zcull_sm_in_gpc_number_map3_tile_24_f( + zcull_map_tiles[24]) | + gr_gpcs_zcull_sm_in_gpc_number_map3_tile_25_f( + zcull_map_tiles[25]) | + gr_gpcs_zcull_sm_in_gpc_number_map3_tile_26_f( + zcull_map_tiles[26]) | + gr_gpcs_zcull_sm_in_gpc_number_map3_tile_27_f( + zcull_map_tiles[27]) | + gr_gpcs_zcull_sm_in_gpc_number_map3_tile_28_f( + zcull_map_tiles[28]) | + gr_gpcs_zcull_sm_in_gpc_number_map3_tile_29_f( + zcull_map_tiles[29]) | + gr_gpcs_zcull_sm_in_gpc_number_map3_tile_30_f( + zcull_map_tiles[30]) | + gr_gpcs_zcull_sm_in_gpc_number_map3_tile_31_f( + zcull_map_tiles[31]); + + gk20a_writel(g, gr_gpcs_zcull_sm_in_gpc_number_map3_r(), val); + } + +} + +static int gr_gk20a_zcull_init_hw(struct gk20a *g, struct gr_gk20a *gr) +{ + u32 gpc_index, gpc_tpc_count, gpc_zcull_count; + u32 *zcull_map_tiles, *zcull_bank_counters; + u32 map_counter; + u32 rcp_conserv; + u32 offset; + bool floorsweep = false; + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 num_gpcs = nvgpu_get_litter_value(g, GPU_LIT_NUM_GPCS); + u32 num_tpc_per_gpc = nvgpu_get_litter_value(g, + GPU_LIT_NUM_TPC_PER_GPC); + u32 zcull_alloc_num = num_gpcs * num_tpc_per_gpc; + u32 map_tile_count; + + if (gr->map_tiles == NULL) { + return -1; + } + + if (zcull_alloc_num % 8 != 0) { + /* Total 8 fields per map reg i.e. tile_0 to tile_7*/ + zcull_alloc_num += (zcull_alloc_num % 8); + } + zcull_map_tiles = nvgpu_kzalloc(g, zcull_alloc_num * sizeof(u32)); + + if (zcull_map_tiles == NULL) { + nvgpu_err(g, + "failed to allocate zcull map titles"); + return -ENOMEM; + } + + zcull_bank_counters = nvgpu_kzalloc(g, zcull_alloc_num * sizeof(u32)); + + if (zcull_bank_counters == NULL) { + nvgpu_err(g, + "failed to allocate zcull bank counters"); + nvgpu_kfree(g, zcull_map_tiles); + return -ENOMEM; + } + + for (map_counter = 0; map_counter < gr->tpc_count; map_counter++) { + map_tile_count = gr_gk20a_get_map_tile_count(gr, map_counter); + zcull_map_tiles[map_counter] = + zcull_bank_counters[map_tile_count]; + zcull_bank_counters[map_tile_count]++; + } + + if (g->ops.gr.program_zcull_mapping != NULL) { + g->ops.gr.program_zcull_mapping(g, zcull_alloc_num, + zcull_map_tiles); + } + + nvgpu_kfree(g, zcull_map_tiles); + nvgpu_kfree(g, zcull_bank_counters); + + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + gpc_tpc_count = gr->gpc_tpc_count[gpc_index]; + gpc_zcull_count = gr->gpc_zcb_count[gpc_index]; + + if (gpc_zcull_count != gr->max_zcull_per_gpc_count && + gpc_zcull_count < gpc_tpc_count) { + nvgpu_err(g, + "zcull_banks (%d) less than tpcs (%d) for gpc (%d)", + gpc_zcull_count, gpc_tpc_count, gpc_index); + return -EINVAL; + } + if (gpc_zcull_count != gr->max_zcull_per_gpc_count && + gpc_zcull_count != 0) { + floorsweep = true; + } + } + + /* ceil(1.0f / SM_NUM * gr_gpc0_zcull_sm_num_rcp_conservative__max_v()) */ + rcp_conserv = DIV_ROUND_UP(gr_gpc0_zcull_sm_num_rcp_conservative__max_v(), + gr->gpc_tpc_count[0]); + + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + offset = gpc_index * gpc_stride; + + if (floorsweep) { + gk20a_writel(g, gr_gpc0_zcull_ram_addr_r() + offset, + gr_gpc0_zcull_ram_addr_row_offset_f(gr->map_row_offset) | + gr_gpc0_zcull_ram_addr_tiles_per_hypertile_row_per_gpc_f( + gr->max_zcull_per_gpc_count)); + } else { + gk20a_writel(g, gr_gpc0_zcull_ram_addr_r() + offset, + gr_gpc0_zcull_ram_addr_row_offset_f(gr->map_row_offset) | + gr_gpc0_zcull_ram_addr_tiles_per_hypertile_row_per_gpc_f( + gr->gpc_tpc_count[gpc_index])); + } + + gk20a_writel(g, gr_gpc0_zcull_fs_r() + offset, + gr_gpc0_zcull_fs_num_active_banks_f(gr->gpc_zcb_count[gpc_index]) | + gr_gpc0_zcull_fs_num_sms_f(gr->tpc_count)); + + gk20a_writel(g, gr_gpc0_zcull_sm_num_rcp_r() + offset, + gr_gpc0_zcull_sm_num_rcp_conservative_f(rcp_conserv)); + } + + gk20a_writel(g, gr_gpcs_ppcs_wwdx_sm_num_rcp_r(), + gr_gpcs_ppcs_wwdx_sm_num_rcp_conservative_f(rcp_conserv)); + + return 0; +} + +void gk20a_gr_enable_exceptions(struct gk20a *g) +{ + gk20a_writel(g, gr_exception_r(), 0xFFFFFFFF); + gk20a_writel(g, gr_exception_en_r(), 0xFFFFFFFF); + gk20a_writel(g, gr_exception1_r(), 0xFFFFFFFF); + gk20a_writel(g, gr_exception1_en_r(), 0xFFFFFFFF); + gk20a_writel(g, gr_exception2_r(), 0xFFFFFFFF); + gk20a_writel(g, gr_exception2_en_r(), 0xFFFFFFFF); +} + +void gk20a_gr_enable_gpc_exceptions(struct gk20a *g) +{ + struct gr_gk20a *gr = &g->gr; + u32 tpc_mask; + + gk20a_writel(g, gr_gpcs_tpcs_tpccs_tpc_exception_en_r(), + gr_gpcs_tpcs_tpccs_tpc_exception_en_tex_enabled_f() | + gr_gpcs_tpcs_tpccs_tpc_exception_en_sm_enabled_f()); + + tpc_mask = + gr_gpcs_gpccs_gpc_exception_en_tpc_f((1 << gr->max_tpc_per_gpc_count) - 1); + + gk20a_writel(g, gr_gpcs_gpccs_gpc_exception_en_r(), tpc_mask); +} + + +void gr_gk20a_enable_hww_exceptions(struct gk20a *g) +{ + /* enable exceptions */ + gk20a_writel(g, gr_fe_hww_esr_r(), + gr_fe_hww_esr_en_enable_f() | + gr_fe_hww_esr_reset_active_f()); + gk20a_writel(g, gr_memfmt_hww_esr_r(), + gr_memfmt_hww_esr_en_enable_f() | + gr_memfmt_hww_esr_reset_active_f()); +} + +void gr_gk20a_fecs_host_int_enable(struct gk20a *g) +{ + gk20a_writel(g, gr_fecs_host_int_enable_r(), + gr_fecs_host_int_enable_ctxsw_intr1_enable_f() | + gr_fecs_host_int_enable_fault_during_ctxsw_enable_f() | + gr_fecs_host_int_enable_umimp_firmware_method_enable_f() | + gr_fecs_host_int_enable_umimp_illegal_method_enable_f() | + gr_fecs_host_int_enable_watchdog_enable_f()); +} + +static int gk20a_init_gr_setup_hw(struct gk20a *g) +{ + struct gr_gk20a *gr = &g->gr; + struct aiv_list_gk20a *sw_ctx_load = &g->gr.ctx_vars.sw_ctx_load; + struct av_list_gk20a *sw_method_init = &g->gr.ctx_vars.sw_method_init; + u32 data; + u32 last_method_data = 0; + u32 i, err; + + nvgpu_log_fn(g, " "); + + if (g->ops.gr.init_gpc_mmu) { + g->ops.gr.init_gpc_mmu(g); + } + + /* load gr floorsweeping registers */ + data = gk20a_readl(g, gr_gpc0_ppc0_pes_vsc_strem_r()); + data = set_field(data, gr_gpc0_ppc0_pes_vsc_strem_master_pe_m(), + gr_gpc0_ppc0_pes_vsc_strem_master_pe_true_f()); + gk20a_writel(g, gr_gpc0_ppc0_pes_vsc_strem_r(), data); + + gr_gk20a_zcull_init_hw(g, gr); + + if (g->ops.priv_ring.set_ppriv_timeout_settings != NULL) { + g->ops.priv_ring.set_ppriv_timeout_settings(g); + } + + /* enable fifo access */ + gk20a_writel(g, gr_gpfifo_ctl_r(), + gr_gpfifo_ctl_access_enabled_f() | + gr_gpfifo_ctl_semaphore_access_enabled_f()); + + /* TBD: reload gr ucode when needed */ + + /* enable interrupts */ + gk20a_writel(g, gr_intr_r(), 0xFFFFFFFF); + gk20a_writel(g, gr_intr_en_r(), 0xFFFFFFFF); + + /* enable fecs error interrupts */ + g->ops.gr.fecs_host_int_enable(g); + + g->ops.gr.enable_hww_exceptions(g); + g->ops.gr.set_hww_esr_report_mask(g); + + /* enable TPC exceptions per GPC */ + if (g->ops.gr.enable_gpc_exceptions) { + g->ops.gr.enable_gpc_exceptions(g); + } + + /* enable ECC for L1/SM */ + if (g->ops.gr.ecc_init_scrub_reg) { + g->ops.gr.ecc_init_scrub_reg(g); + } + + /* TBD: enable per BE exceptions */ + + /* reset and enable exceptions */ + g->ops.gr.enable_exceptions(g); + + gr_gk20a_load_zbc_table(g, gr); + + if (g->ops.ltc.init_cbc) { + g->ops.ltc.init_cbc(g, gr); + } + + if (g->ops.fb.init_cbc) { + g->ops.fb.init_cbc(g, gr); + } + + if (g->ops.gr.disable_rd_coalesce) { + g->ops.gr.disable_rd_coalesce(g); + } + + /* load ctx init */ + for (i = 0; i < sw_ctx_load->count; i++) { + gk20a_writel(g, sw_ctx_load->l[i].addr, + sw_ctx_load->l[i].value); + } + + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + if (err != 0U) { + goto out; + } + + if (g->ops.gr.init_preemption_state) { + err = g->ops.gr.init_preemption_state(g); + if (err != 0U) { + goto out; + } + } + + /* disable fe_go_idle */ + gk20a_writel(g, gr_fe_go_idle_timeout_r(), + gr_fe_go_idle_timeout_count_disabled_f()); + + /* override a few ctx state registers */ + g->ops.gr.commit_global_timeslice(g, NULL); + + /* floorsweep anything left */ + err = g->ops.gr.init_fs_state(g); + if (err != 0U) { + goto out; + } + + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + if (err != 0U) { + goto restore_fe_go_idle; + } + +restore_fe_go_idle: + /* restore fe_go_idle */ + gk20a_writel(g, gr_fe_go_idle_timeout_r(), + gr_fe_go_idle_timeout_count_prod_f()); + + if ((err != 0U) || (gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT) != 0)) { + goto out; + } + + /* load method init */ + if (sw_method_init->count) { + gk20a_writel(g, gr_pri_mme_shadow_raw_data_r(), + sw_method_init->l[0].value); + gk20a_writel(g, gr_pri_mme_shadow_raw_index_r(), + gr_pri_mme_shadow_raw_index_write_trigger_f() | + sw_method_init->l[0].addr); + last_method_data = sw_method_init->l[0].value; + } + for (i = 1; i < sw_method_init->count; i++) { + if (sw_method_init->l[i].value != last_method_data) { + gk20a_writel(g, gr_pri_mme_shadow_raw_data_r(), + sw_method_init->l[i].value); + last_method_data = sw_method_init->l[i].value; + } + gk20a_writel(g, gr_pri_mme_shadow_raw_index_r(), + gr_pri_mme_shadow_raw_index_write_trigger_f() | + sw_method_init->l[i].addr); + } + + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); +out: + nvgpu_log_fn(g, "done"); + return err; +} + +static int gk20a_init_gr_prepare(struct gk20a *g) +{ + u32 err = 0; + + /* reset gr engine */ + g->ops.mc.reset(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_GRAPH) | + g->ops.mc.reset_mask(g, NVGPU_UNIT_BLG) | + g->ops.mc.reset_mask(g, NVGPU_UNIT_PERFMON)); + + nvgpu_cg_init_gr_load_gating_prod(g); + + /* Disable elcg until it gets enabled later in the init*/ + nvgpu_cg_elcg_disable_no_wait(g); + + /* enable fifo access */ + gk20a_writel(g, gr_gpfifo_ctl_r(), + gr_gpfifo_ctl_access_enabled_f() | + gr_gpfifo_ctl_semaphore_access_enabled_f()); + + if (!g->gr.ctx_vars.valid) { + err = gr_gk20a_init_ctx_vars(g, &g->gr); + if (err != 0U) { + nvgpu_err(g, + "fail to load gr init ctx"); + } + } + return err; +} + +static int gr_gk20a_wait_mem_scrubbing(struct gk20a *g) +{ + struct nvgpu_timeout timeout; + bool fecs_scrubbing; + bool gpccs_scrubbing; + + nvgpu_log_fn(g, " "); + + nvgpu_timeout_init(g, &timeout, + CTXSW_MEM_SCRUBBING_TIMEOUT_MAX / + CTXSW_MEM_SCRUBBING_TIMEOUT_DEFAULT, + NVGPU_TIMER_RETRY_TIMER); + do { + fecs_scrubbing = gk20a_readl(g, gr_fecs_dmactl_r()) & + (gr_fecs_dmactl_imem_scrubbing_m() | + gr_fecs_dmactl_dmem_scrubbing_m()); + + gpccs_scrubbing = gk20a_readl(g, gr_gpccs_dmactl_r()) & + (gr_gpccs_dmactl_imem_scrubbing_m() | + gr_gpccs_dmactl_imem_scrubbing_m()); + + if (!fecs_scrubbing && !gpccs_scrubbing) { + nvgpu_log_fn(g, "done"); + return 0; + } + + nvgpu_udelay(CTXSW_MEM_SCRUBBING_TIMEOUT_DEFAULT); + } while (nvgpu_timeout_expired(&timeout) == 0); + + nvgpu_err(g, "Falcon mem scrubbing timeout"); + return -ETIMEDOUT; +} + +static int gr_gk20a_init_ctxsw(struct gk20a *g) +{ + u32 err = 0; + + err = g->ops.gr.load_ctxsw_ucode(g); + if (err != 0U) { + goto out; + } + + err = gr_gk20a_wait_ctxsw_ready(g); + if (err != 0U) { + goto out; + } + +out: + if (err != 0U) { + nvgpu_err(g, "fail"); + } else { + nvgpu_log_fn(g, "done"); + } + + return err; +} + +static int gk20a_init_gr_reset_enable_hw(struct gk20a *g) +{ + struct av_list_gk20a *sw_non_ctx_load = &g->gr.ctx_vars.sw_non_ctx_load; + u32 i, err = 0; + + nvgpu_log_fn(g, " "); + + /* enable interrupts */ + gk20a_writel(g, gr_intr_r(), ~0); + gk20a_writel(g, gr_intr_en_r(), ~0); + + /* load non_ctx init */ + for (i = 0; i < sw_non_ctx_load->count; i++) { + gk20a_writel(g, sw_non_ctx_load->l[i].addr, + sw_non_ctx_load->l[i].value); + } + + err = gr_gk20a_wait_mem_scrubbing(g); + if (err != 0U) { + goto out; + } + + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + if (err != 0U) { + goto out; + } + +out: + if (err != 0U) { + nvgpu_err(g, "fail"); + } else { + nvgpu_log_fn(g, "done"); + } + + return 0; +} + +static int gr_gk20a_init_access_map(struct gk20a *g) +{ + struct gr_gk20a *gr = &g->gr; + struct nvgpu_mem *mem = &gr->global_ctx_buffer[PRIV_ACCESS_MAP].mem; + u32 nr_pages = + DIV_ROUND_UP(gr->ctx_vars.priv_access_map_size, + PAGE_SIZE); + u32 *whitelist = NULL; + int w, num_entries = 0; + + nvgpu_memset(g, mem, 0, 0, PAGE_SIZE * nr_pages); + + g->ops.gr.get_access_map(g, &whitelist, &num_entries); + + for (w = 0; w < num_entries; w++) { + u32 map_bit, map_byte, map_shift, x; + map_bit = whitelist[w] >> 2; + map_byte = map_bit >> 3; + map_shift = map_bit & 0x7; /* i.e. 0-7 */ + nvgpu_log_info(g, "access map addr:0x%x byte:0x%x bit:%d", + whitelist[w], map_byte, map_shift); + x = nvgpu_mem_rd32(g, mem, map_byte / sizeof(u32)); + x |= 1 << ( + (map_byte % sizeof(u32) * BITS_PER_BYTE) + + map_shift); + nvgpu_mem_wr32(g, mem, map_byte / sizeof(u32), x); + } + + return 0; +} + +static int gk20a_init_gr_setup_sw(struct gk20a *g) +{ + struct gr_gk20a *gr = &g->gr; + int err = 0; + + nvgpu_log_fn(g, " "); + + if (gr->sw_ready) { + nvgpu_log_fn(g, "skip init"); + return 0; + } + + gr->g = g; + +#if defined(CONFIG_GK20A_CYCLE_STATS) + err = nvgpu_mutex_init(&g->gr.cs_lock); + if (err != 0) { + nvgpu_err(g, "Error in gr.cs_lock mutex initialization"); + return err; + } +#endif + + err = gr_gk20a_init_gr_config(g, gr); + if (err != 0) { + goto clean_up; + } + + err = gr_gk20a_init_map_tiles(g, gr); + if (err != 0) { + goto clean_up; + } + + if (g->ops.ltc.init_comptags) { + err = g->ops.ltc.init_comptags(g, gr); + if (err != 0) { + goto clean_up; + } + } + + err = gr_gk20a_init_zcull(g, gr); + if (err != 0) { + goto clean_up; + } + + err = g->ops.gr.alloc_global_ctx_buffers(g); + if (err != 0) { + goto clean_up; + } + + err = gr_gk20a_init_access_map(g); + if (err != 0) { + goto clean_up; + } + + gr_gk20a_load_zbc_default_table(g, gr); + + if (g->ops.gr.init_czf_bypass) { + g->ops.gr.init_czf_bypass(g); + } + + if (g->ops.gr.init_gfxp_wfi_timeout_count) { + g->ops.gr.init_gfxp_wfi_timeout_count(g); + } + + err = nvgpu_mutex_init(&gr->ctx_mutex); + if (err != 0) { + nvgpu_err(g, "Error in gr.ctx_mutex initialization"); + goto clean_up; + } + + nvgpu_spinlock_init(&gr->ch_tlb_lock); + + gr->remove_support = gk20a_remove_gr_support; + gr->sw_ready = true; + + err = nvgpu_ecc_init_support(g); + if (err != 0) { + goto clean_up; + } + + nvgpu_log_fn(g, "done"); + return 0; + +clean_up: + nvgpu_err(g, "fail"); + gk20a_remove_gr_support(gr); + return err; +} + +static int gk20a_init_gr_bind_fecs_elpg(struct gk20a *g) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct mm_gk20a *mm = &g->mm; + struct vm_gk20a *vm = mm->pmu.vm; + int err = 0; + + u32 size; + + nvgpu_log_fn(g, " "); + + size = 0; + + err = gr_gk20a_fecs_get_reglist_img_size(g, &size); + if (err != 0) { + nvgpu_err(g, + "fail to query fecs pg buffer size"); + return err; + } + + if (pmu->pg_buf.cpu_va == NULL) { + err = nvgpu_dma_alloc_map_sys(vm, size, &pmu->pg_buf); + if (err != 0) { + nvgpu_err(g, "failed to allocate memory"); + return -ENOMEM; + } + } + + + err = gr_gk20a_fecs_set_reglist_bind_inst(g, &mm->pmu.inst_block); + if (err != 0) { + nvgpu_err(g, + "fail to bind pmu inst to gr"); + return err; + } + + err = gr_gk20a_fecs_set_reglist_virtual_addr(g, pmu->pg_buf.gpu_va); + if (err != 0) { + nvgpu_err(g, + "fail to set pg buffer pmu va"); + return err; + } + + return err; +} + +int gk20a_init_gr_support(struct gk20a *g) +{ + int err = 0; + + nvgpu_log_fn(g, " "); + + g->gr.initialized = false; + + /* this is required before gr_gk20a_init_ctx_state */ + err = nvgpu_mutex_init(&g->gr.fecs_mutex); + if (err != 0) { + nvgpu_err(g, "Error in gr.fecs_mutex initialization"); + return err; + } + + err = gr_gk20a_init_ctxsw(g); + if (err != 0) { + return err; + } + + /* this appears query for sw states but fecs actually init + ramchain, etc so this is hw init */ + err = g->ops.gr.init_ctx_state(g); + if (err != 0) { + return err; + } + + err = gk20a_init_gr_setup_sw(g); + if (err != 0) { + return err; + } + + err = gk20a_init_gr_setup_hw(g); + if (err != 0) { + return err; + } + + if (g->can_elpg) { + err = gk20a_init_gr_bind_fecs_elpg(g); + if (err != 0) { + return err; + } + } + + /* GR is inialized, signal possible waiters */ + g->gr.initialized = true; + nvgpu_cond_signal(&g->gr.init_wq); + + return 0; +} + +/* Wait until GR is initialized */ +void gk20a_gr_wait_initialized(struct gk20a *g) +{ + NVGPU_COND_WAIT(&g->gr.init_wq, g->gr.initialized, 0); +} + +#define NVA297_SET_ALPHA_CIRCULAR_BUFFER_SIZE 0x02dc +#define NVA297_SET_CIRCULAR_BUFFER_SIZE 0x1280 +#define NVA297_SET_SHADER_EXCEPTIONS 0x1528 +#define NVA0C0_SET_SHADER_EXCEPTIONS 0x1528 + +#define NVA297_SET_SHADER_EXCEPTIONS_ENABLE_FALSE 0 + +void gk20a_gr_set_shader_exceptions(struct gk20a *g, u32 data) +{ + nvgpu_log_fn(g, " "); + + if (data == NVA297_SET_SHADER_EXCEPTIONS_ENABLE_FALSE) { + gk20a_writel(g, + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_r(), 0); + gk20a_writel(g, + gr_gpcs_tpcs_sm_hww_global_esr_report_mask_r(), 0); + } else { + /* setup sm warp esr report masks */ + gk20a_writel(g, gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_r(), + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_stack_error_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_api_stack_error_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_ret_empty_stack_error_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_wrap_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_pc_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_overflow_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_immc_addr_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_reg_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_encoding_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_sph_instr_combo_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_reg_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_addr_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_addr_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_addr_space_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param2_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_ldc_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_geometry_sm_error_report_f() | + gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_divergent_report_f()); + + /* setup sm global esr report mask */ + gk20a_writel(g, gr_gpcs_tpcs_sm_hww_global_esr_report_mask_r(), + gr_gpcs_tpcs_sm_hww_global_esr_report_mask_sm_to_sm_fault_report_f() | + gr_gpcs_tpcs_sm_hww_global_esr_report_mask_l1_error_report_f() | + gr_gpcs_tpcs_sm_hww_global_esr_report_mask_multiple_warp_errors_report_f() | + gr_gpcs_tpcs_sm_hww_global_esr_report_mask_physical_stack_overflow_error_report_f() | + gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_int_report_f() | + gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_pause_report_f() | + gr_gpcs_tpcs_sm_hww_global_esr_report_mask_single_step_complete_report_f()); + } +} + +int gk20a_enable_gr_hw(struct gk20a *g) +{ + int err; + + nvgpu_log_fn(g, " "); + + err = gk20a_init_gr_prepare(g); + if (err != 0) { + return err; + } + + err = gk20a_init_gr_reset_enable_hw(g); + if (err != 0) { + return err; + } + + nvgpu_log_fn(g, "done"); + + return 0; +} + +int gk20a_gr_reset(struct gk20a *g) +{ + int err; + u32 size; + + g->gr.initialized = false; + + nvgpu_mutex_acquire(&g->gr.fecs_mutex); + + err = gk20a_enable_gr_hw(g); + if (err != 0) { + nvgpu_mutex_release(&g->gr.fecs_mutex); + return err; + } + + err = gk20a_init_gr_setup_hw(g); + if (err != 0) { + nvgpu_mutex_release(&g->gr.fecs_mutex); + return err; + } + + err = gr_gk20a_init_ctxsw(g); + if (err != 0) { + nvgpu_mutex_release(&g->gr.fecs_mutex); + return err; + } + + nvgpu_mutex_release(&g->gr.fecs_mutex); + + /* this appears query for sw states but fecs actually init + ramchain, etc so this is hw init */ + err = g->ops.gr.init_ctx_state(g); + if (err != 0) { + return err; + } + + size = 0; + err = gr_gk20a_fecs_get_reglist_img_size(g, &size); + if (err != 0) { + nvgpu_err(g, + "fail to query fecs pg buffer size"); + return err; + } + + err = gr_gk20a_fecs_set_reglist_bind_inst(g, &g->mm.pmu.inst_block); + if (err != 0) { + nvgpu_err(g, + "fail to bind pmu inst to gr"); + return err; + } + + err = gr_gk20a_fecs_set_reglist_virtual_addr(g, g->pmu.pg_buf.gpu_va); + if (err != 0) { + nvgpu_err(g, + "fail to set pg buffer pmu va"); + return err; + } + + nvgpu_cg_init_gr_load_gating_prod(g); + nvgpu_cg_elcg_enable_no_wait(g); + + /* GR is inialized, signal possible waiters */ + g->gr.initialized = true; + nvgpu_cond_signal(&g->gr.init_wq); + + return err; +} + +static void gk20a_gr_set_error_notifier(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data, u32 error_notifier) +{ + struct channel_gk20a *ch; + struct tsg_gk20a *tsg; + struct channel_gk20a *ch_tsg; + + ch = isr_data->ch; + + if (ch == NULL) { + return; + } + + tsg = tsg_gk20a_from_ch(ch); + if (tsg != NULL) { + nvgpu_rwsem_down_read(&tsg->ch_list_lock); + nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list, + channel_gk20a, ch_entry) { + if (gk20a_channel_get(ch_tsg)) { + g->ops.fifo.set_error_notifier(ch_tsg, + error_notifier); + gk20a_channel_put(ch_tsg); + } + + } + nvgpu_rwsem_up_read(&tsg->ch_list_lock); + } else { + nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); + } +} + +static int gk20a_gr_handle_semaphore_timeout_pending(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data) +{ + nvgpu_log_fn(g, " "); + gk20a_gr_set_error_notifier(g, isr_data, + NVGPU_ERR_NOTIFIER_GR_SEMAPHORE_TIMEOUT); + nvgpu_err(g, + "gr semaphore timeout"); + return -EINVAL; +} + +static int gk20a_gr_intr_illegal_notify_pending(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data) +{ + nvgpu_log_fn(g, " "); + gk20a_gr_set_error_notifier(g, isr_data, + NVGPU_ERR_NOTIFIER_GR_ILLEGAL_NOTIFY); + /* This is an unrecoverable error, reset is needed */ + nvgpu_err(g, + "gr semaphore timeout"); + return -EINVAL; +} + +static int gk20a_gr_handle_illegal_method(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data) +{ + int ret = g->ops.gr.handle_sw_method(g, isr_data->addr, + isr_data->class_num, isr_data->offset, + isr_data->data_lo); + if (ret) { + gk20a_gr_set_error_notifier(g, isr_data, + NVGPU_ERR_NOTIFIER_GR_ILLEGAL_NOTIFY); + nvgpu_err(g, "invalid method class 0x%08x" + ", offset 0x%08x address 0x%08x", + isr_data->class_num, isr_data->offset, isr_data->addr); + } + return ret; +} + +static int gk20a_gr_handle_illegal_class(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data) +{ + nvgpu_log_fn(g, " "); + gk20a_gr_set_error_notifier(g, isr_data, + NVGPU_ERR_NOTIFIER_GR_ERROR_SW_NOTIFY); + nvgpu_err(g, + "invalid class 0x%08x, offset 0x%08x", + isr_data->class_num, isr_data->offset); + return -EINVAL; +} + +int gk20a_gr_handle_fecs_error(struct gk20a *g, struct channel_gk20a *ch, + struct gr_gk20a_isr_data *isr_data) +{ + u32 gr_fecs_intr = gk20a_readl(g, gr_fecs_host_int_status_r()); + int ret = 0; + u32 chid = isr_data->ch != NULL ? + isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID; + + if (gr_fecs_intr == 0U) { + return 0; + } + + if (gr_fecs_intr & gr_fecs_host_int_status_umimp_firmware_method_f(1)) { + gk20a_gr_set_error_notifier(g, isr_data, + NVGPU_ERR_NOTIFIER_FECS_ERR_UNIMP_FIRMWARE_METHOD); + nvgpu_err(g, + "firmware method error 0x%08x for offset 0x%04x", + gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(6)), + isr_data->data_lo); + ret = -1; + } else if ((gr_fecs_intr & + gr_fecs_host_int_status_watchdog_active_f()) != 0U) { + /* currently, recovery is not initiated */ + nvgpu_err(g, "fecs watchdog triggered for channel %u, " + "cannot ctxsw anymore !!", chid); + gk20a_fecs_dump_falcon_stats(g); + } else if ((gr_fecs_intr & + gr_fecs_host_int_status_ctxsw_intr_f(CTXSW_INTR0)) != 0U) { + u32 mailbox_value = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(6)); + + if (mailbox_value == MAILBOX_VALUE_TIMESTAMP_BUFFER_FULL) { + nvgpu_info(g, "ctxsw intr0 set by ucode, " + "timestamp buffer full"); +#ifdef CONFIG_GK20A_CTXSW_TRACE + gk20a_fecs_trace_reset_buffer(g); +#else + ret = -1; +#endif + } else { + nvgpu_err(g, + "ctxsw intr0 set by ucode, error_code: 0x%08x", + mailbox_value); + ret = -1; + } + } else { + nvgpu_err(g, + "unhandled fecs error interrupt 0x%08x for channel %u", + gr_fecs_intr, ch->chid); + gk20a_fecs_dump_falcon_stats(g); + } + + gk20a_writel(g, gr_fecs_host_int_clear_r(), gr_fecs_intr); + return ret; +} + +static int gk20a_gr_handle_class_error(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data) +{ + u32 gr_class_error; + u32 chid = isr_data->ch != NULL ? + isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID; + + nvgpu_log_fn(g, " "); + + gr_class_error = + gr_class_error_code_v(gk20a_readl(g, gr_class_error_r())); + gk20a_gr_set_error_notifier(g, isr_data, + NVGPU_ERR_NOTIFIER_GR_ERROR_SW_NOTIFY); + nvgpu_err(g, "class error 0x%08x, offset 0x%08x," + "sub channel 0x%08x mme generated %d," + " mme pc 0x%08xdata high %d priv status %d" + " unhandled intr 0x%08x for channel %u", + isr_data->class_num, (isr_data->offset << 2), + gr_trapped_addr_subch_v(isr_data->addr), + gr_trapped_addr_mme_generated_v(isr_data->addr), + gr_trapped_data_mme_pc_v( + gk20a_readl(g, gr_trapped_data_mme_r())), + gr_trapped_addr_datahigh_v(isr_data->addr), + gr_trapped_addr_priv_v(isr_data->addr), + gr_class_error, chid); + + nvgpu_err(g, "trapped data low 0x%08x", + gk20a_readl(g, gr_trapped_data_lo_r())); + if (gr_trapped_addr_datahigh_v(isr_data->addr)) { + nvgpu_err(g, "trapped data high 0x%08x", + gk20a_readl(g, gr_trapped_data_hi_r())); + } + + return -EINVAL; +} + +static int gk20a_gr_handle_firmware_method(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data) +{ + u32 chid = isr_data->ch != NULL ? + isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID; + + nvgpu_log_fn(g, " "); + + gk20a_gr_set_error_notifier(g, isr_data, + NVGPU_ERR_NOTIFIER_GR_ERROR_SW_NOTIFY); + nvgpu_err(g, + "firmware method 0x%08x, offset 0x%08x for channel %u", + isr_data->class_num, isr_data->offset, + chid); + return -EINVAL; +} + +int gk20a_gr_handle_semaphore_pending(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data) +{ + struct channel_gk20a *ch = isr_data->ch; + struct tsg_gk20a *tsg; + + if (ch == NULL) { + return 0; + } + + tsg = tsg_gk20a_from_ch(ch); + if (tsg != NULL) { + g->ops.fifo.post_event_id(tsg, + NVGPU_EVENT_ID_GR_SEMAPHORE_WRITE_AWAKEN); + + nvgpu_cond_broadcast(&ch->semaphore_wq); + } else { + nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); + } + + return 0; +} + +#if defined(CONFIG_GK20A_CYCLE_STATS) +static inline bool is_valid_cyclestats_bar0_offset_gk20a(struct gk20a *g, + u32 offset) +{ + /* support only 24-bit 4-byte aligned offsets */ + bool valid = !(offset & 0xFF000003); + + if (g->allow_all) + return true; + + /* whitelist check */ + valid = valid && + is_bar0_global_offset_whitelisted_gk20a(g, offset); + /* resource size check in case there was a problem + * with allocating the assumed size of bar0 */ + valid = valid && gk20a_io_valid_reg(g, offset); + return valid; +} +#endif + +int gk20a_gr_handle_notify_pending(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data) +{ + struct channel_gk20a *ch = isr_data->ch; + +#if defined(CONFIG_GK20A_CYCLE_STATS) + void *virtual_address; + u32 buffer_size; + u32 offset; + bool exit; +#endif + if (ch == NULL || tsg_gk20a_from_ch(ch) == NULL) { + return 0; + } + +#if defined(CONFIG_GK20A_CYCLE_STATS) + /* GL will never use payload 0 for cycle state */ + if ((ch->cyclestate.cyclestate_buffer == NULL) || (isr_data->data_lo == 0)) + return 0; + + nvgpu_mutex_acquire(&ch->cyclestate.cyclestate_buffer_mutex); + + virtual_address = ch->cyclestate.cyclestate_buffer; + buffer_size = ch->cyclestate.cyclestate_buffer_size; + offset = isr_data->data_lo; + exit = false; + while (!exit) { + struct share_buffer_head *sh_hdr; + u32 min_element_size; + + /* validate offset */ + if (offset + sizeof(struct share_buffer_head) > buffer_size || + offset + sizeof(struct share_buffer_head) < offset) { + nvgpu_err(g, + "cyclestats buffer overrun at offset 0x%x", + offset); + break; + } + + sh_hdr = (struct share_buffer_head *) + ((char *)virtual_address + offset); + + min_element_size = + (sh_hdr->operation == OP_END ? + sizeof(struct share_buffer_head) : + sizeof(struct gk20a_cyclestate_buffer_elem)); + + /* validate sh_hdr->size */ + if (sh_hdr->size < min_element_size || + offset + sh_hdr->size > buffer_size || + offset + sh_hdr->size < offset) { + nvgpu_err(g, + "bad cyclestate buffer header size at offset 0x%x", + offset); + sh_hdr->failed = true; + break; + } + + switch (sh_hdr->operation) { + case OP_END: + exit = true; + break; + + case BAR0_READ32: + case BAR0_WRITE32: + { + struct gk20a_cyclestate_buffer_elem *op_elem = + (struct gk20a_cyclestate_buffer_elem *)sh_hdr; + bool valid = is_valid_cyclestats_bar0_offset_gk20a( + g, op_elem->offset_bar0); + u32 raw_reg; + u64 mask_orig; + u64 v; + + if (!valid) { + nvgpu_err(g, + "invalid cycletstats op offset: 0x%x", + op_elem->offset_bar0); + + sh_hdr->failed = exit = true; + break; + } + + + mask_orig = + ((1ULL << + (op_elem->last_bit + 1)) + -1)&~((1ULL << + op_elem->first_bit)-1); + + raw_reg = + gk20a_readl(g, + op_elem->offset_bar0); + + switch (sh_hdr->operation) { + case BAR0_READ32: + op_elem->data = + (raw_reg & mask_orig) + >> op_elem->first_bit; + break; + + case BAR0_WRITE32: + v = 0; + if ((unsigned int)mask_orig != + (unsigned int)~0) { + v = (unsigned int) + (raw_reg & ~mask_orig); + } + + v |= ((op_elem->data + << op_elem->first_bit) + & mask_orig); + + gk20a_writel(g, + op_elem->offset_bar0, + (unsigned int)v); + break; + default: + /* nop ok?*/ + break; + } + } + break; + + default: + /* no operation content case */ + exit = true; + break; + } + sh_hdr->completed = true; + offset += sh_hdr->size; + } + nvgpu_mutex_release(&ch->cyclestate.cyclestate_buffer_mutex); +#endif + nvgpu_log_fn(g, " "); + nvgpu_cond_broadcast_interruptible(&ch->notifier_wq); + return 0; +} + +/* Used by sw interrupt thread to translate current ctx to chid. + * Also used by regops to translate current ctx to chid and tsgid. + * For performance, we don't want to go through 128 channels every time. + * curr_ctx should be the value read from gr_fecs_current_ctx_r(). + * A small tlb is used here to cache translation. + * + * Returned channel must be freed with gk20a_channel_put() */ +static struct channel_gk20a *gk20a_gr_get_channel_from_ctx( + struct gk20a *g, u32 curr_ctx, u32 *curr_tsgid) +{ + struct fifo_gk20a *f = &g->fifo; + struct gr_gk20a *gr = &g->gr; + u32 chid = -1; + u32 tsgid = NVGPU_INVALID_TSG_ID; + u32 i; + struct channel_gk20a *ret = NULL; + + /* when contexts are unloaded from GR, the valid bit is reset + * but the instance pointer information remains intact. + * This might be called from gr_isr where contexts might be + * unloaded. No need to check ctx_valid bit + */ + + nvgpu_spinlock_acquire(&gr->ch_tlb_lock); + + /* check cache first */ + for (i = 0; i < GR_CHANNEL_MAP_TLB_SIZE; i++) { + if (gr->chid_tlb[i].curr_ctx == curr_ctx) { + chid = gr->chid_tlb[i].chid; + tsgid = gr->chid_tlb[i].tsgid; + ret = gk20a_channel_from_id(g, chid); + goto unlock; + } + } + + /* slow path */ + for (chid = 0; chid < f->num_channels; chid++) { + struct channel_gk20a *ch = gk20a_channel_from_id(g, chid); + + if (ch == NULL) { + continue; + } + + if ((u32)(nvgpu_inst_block_addr(g, &ch->inst_block) >> + ram_in_base_shift_v()) == + gr_fecs_current_ctx_ptr_v(curr_ctx)) { + tsgid = ch->tsgid; + /* found it */ + ret = ch; + break; + } + gk20a_channel_put(ch); + } + + if (ret == NULL) { + goto unlock; + } + + /* add to free tlb entry */ + for (i = 0; i < GR_CHANNEL_MAP_TLB_SIZE; i++) { + if (gr->chid_tlb[i].curr_ctx == 0) { + gr->chid_tlb[i].curr_ctx = curr_ctx; + gr->chid_tlb[i].chid = chid; + gr->chid_tlb[i].tsgid = tsgid; + goto unlock; + } + } + + /* no free entry, flush one */ + gr->chid_tlb[gr->channel_tlb_flush_index].curr_ctx = curr_ctx; + gr->chid_tlb[gr->channel_tlb_flush_index].chid = chid; + gr->chid_tlb[gr->channel_tlb_flush_index].tsgid = tsgid; + + gr->channel_tlb_flush_index = + (gr->channel_tlb_flush_index + 1) & + (GR_CHANNEL_MAP_TLB_SIZE - 1); + +unlock: + nvgpu_spinlock_release(&gr->ch_tlb_lock); + if (curr_tsgid) { + *curr_tsgid = tsgid; + } + return ret; +} + +int gk20a_gr_lock_down_sm(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm, u32 global_esr_mask, + bool check_errors) +{ + u32 offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc); + u32 dbgr_control0; + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "GPC%d TPC%d SM%d: assert stop trigger", gpc, tpc, sm); + + /* assert stop trigger */ + dbgr_control0 = + gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_control0_r() + offset); + dbgr_control0 |= gr_gpc0_tpc0_sm_dbgr_control0_stop_trigger_enable_f(); + gk20a_writel(g, + gr_gpc0_tpc0_sm_dbgr_control0_r() + offset, dbgr_control0); + + return g->ops.gr.wait_for_sm_lock_down(g, gpc, tpc, sm, global_esr_mask, + check_errors); +} + +bool gk20a_gr_sm_debugger_attached(struct gk20a *g) +{ + u32 dbgr_control0 = gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_control0_r()); + + /* check if an sm debugger is attached. + * assumption: all SMs will have debug mode enabled/disabled + * uniformly. */ + if (gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_v(dbgr_control0) == + gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_on_v()) { + return true; + } + + return false; +} + +int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, + bool *post_event, struct channel_gk20a *fault_ch, + u32 *hww_global_esr) +{ + int ret = 0; + bool do_warp_sync = false, early_exit = false, ignore_debugger = false; + bool disable_sm_exceptions = true; + u32 offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc); + bool sm_debugger_attached; + u32 global_esr, warp_esr, global_mask; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + sm_debugger_attached = g->ops.gr.sm_debugger_attached(g); + + global_esr = g->ops.gr.get_sm_hww_global_esr(g, gpc, tpc, sm); + *hww_global_esr = global_esr; + warp_esr = g->ops.gr.get_sm_hww_warp_esr(g, gpc, tpc, sm); + global_mask = g->ops.gr.get_sm_no_lock_down_hww_global_esr_mask(g); + + if (!sm_debugger_attached) { + nvgpu_err(g, "sm hww global 0x%08x warp 0x%08x", + global_esr, warp_esr); + return -EFAULT; + } + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "sm hww global 0x%08x warp 0x%08x", global_esr, warp_esr); + + gr_gk20a_elpg_protected_call(g, + g->ops.gr.record_sm_error_state(g, gpc, tpc, sm, fault_ch)); + + if (g->ops.gr.pre_process_sm_exception) { + ret = g->ops.gr.pre_process_sm_exception(g, gpc, tpc, sm, + global_esr, warp_esr, + sm_debugger_attached, + fault_ch, + &early_exit, + &ignore_debugger); + if (ret) { + nvgpu_err(g, "could not pre-process sm error!"); + return ret; + } + } + + if (early_exit) { + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "returning early"); + return ret; + } + + /* + * Disable forwarding of tpc exceptions, + * the debugger will reenable exceptions after servicing them. + * + * Do not disable exceptions if the only SM exception is BPT_INT + */ + if ((global_esr == gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f()) + && (warp_esr == 0)) { + disable_sm_exceptions = false; + } + + if (!ignore_debugger && disable_sm_exceptions) { + u32 tpc_exception_en = gk20a_readl(g, + gr_gpc0_tpc0_tpccs_tpc_exception_en_r() + + offset); + tpc_exception_en &= ~gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_enabled_f(); + gk20a_writel(g, + gr_gpc0_tpc0_tpccs_tpc_exception_en_r() + offset, + tpc_exception_en); + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, "SM Exceptions disabled"); + } + + /* if a debugger is present and an error has occurred, do a warp sync */ + if (!ignore_debugger && + ((warp_esr != 0) || ((global_esr & ~global_mask) != 0))) { + nvgpu_log(g, gpu_dbg_intr, "warp sync needed"); + do_warp_sync = true; + } + + if (do_warp_sync) { + ret = g->ops.gr.lock_down_sm(g, gpc, tpc, sm, + global_mask, true); + if (ret) { + nvgpu_err(g, "sm did not lock down!"); + return ret; + } + } + + if (ignore_debugger) { + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "ignore_debugger set, skipping event posting"); + } else { + *post_event = true; + } + + return ret; +} + +int gr_gk20a_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc, + bool *post_event) +{ + int ret = 0; + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); + u32 offset = gpc_stride * gpc + tpc_in_gpc_stride * tpc; + u32 esr; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + esr = gk20a_readl(g, + gr_gpc0_tpc0_tex_m_hww_esr_r() + offset); + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, "0x%08x", esr); + + gk20a_writel(g, + gr_gpc0_tpc0_tex_m_hww_esr_r() + offset, + esr); + + return ret; +} + +void gk20a_gr_get_esr_sm_sel(struct gk20a *g, u32 gpc, u32 tpc, + u32 *esr_sm_sel) +{ + *esr_sm_sel = 1; +} + +static int gk20a_gr_handle_tpc_exception(struct gk20a *g, u32 gpc, u32 tpc, + bool *post_event, struct channel_gk20a *fault_ch, + u32 *hww_global_esr) +{ + int ret = 0; + u32 offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc); + u32 tpc_exception = gk20a_readl(g, gr_gpc0_tpc0_tpccs_tpc_exception_r() + + offset); + u32 sm_per_tpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_SM_PER_TPC); + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "GPC%d TPC%d: pending exception 0x%x", + gpc, tpc, tpc_exception); + + /* check if an sm exeption is pending */ + if (gr_gpc0_tpc0_tpccs_tpc_exception_sm_v(tpc_exception) == + gr_gpc0_tpc0_tpccs_tpc_exception_sm_pending_v()) { + u32 esr_sm_sel, sm; + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "GPC%d TPC%d: SM exception pending", gpc, tpc); + + if (g->ops.gr.handle_tpc_sm_ecc_exception) { + g->ops.gr.handle_tpc_sm_ecc_exception(g, gpc, tpc, + post_event, fault_ch, hww_global_esr); + } + + g->ops.gr.get_esr_sm_sel(g, gpc, tpc, &esr_sm_sel); + + for (sm = 0; sm < sm_per_tpc; sm++) { + + if ((esr_sm_sel & BIT32(sm)) == 0U) { + continue; + } + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "GPC%d TPC%d: SM%d exception pending", + gpc, tpc, sm); + + ret |= g->ops.gr.handle_sm_exception(g, + gpc, tpc, sm, post_event, fault_ch, + hww_global_esr); + /* clear the hwws, also causes tpc and gpc + * exceptions to be cleared. Should be cleared + * only if SM is locked down or empty. + */ + g->ops.gr.clear_sm_hww(g, + gpc, tpc, sm, *hww_global_esr); + + } + + } + + /* check if a tex exeption is pending */ + if (gr_gpc0_tpc0_tpccs_tpc_exception_tex_v(tpc_exception) == + gr_gpc0_tpc0_tpccs_tpc_exception_tex_pending_v()) { + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "GPC%d TPC%d: TEX exception pending", gpc, tpc); + ret |= g->ops.gr.handle_tex_exception(g, gpc, tpc, post_event); + } + + if (g->ops.gr.handle_tpc_mpc_exception) { + ret |= g->ops.gr.handle_tpc_mpc_exception(g, + gpc, tpc, post_event); + } + + return ret; +} + +static int gk20a_gr_handle_gpc_exception(struct gk20a *g, bool *post_event, + struct channel_gk20a *fault_ch, u32 *hww_global_esr) +{ + int ret = 0; + u32 gpc_offset, gpc, tpc; + struct gr_gk20a *gr = &g->gr; + u32 exception1 = gk20a_readl(g, gr_exception1_r()); + u32 gpc_exception; + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, " "); + + for (gpc = 0; gpc < gr->gpc_count; gpc++) { + if ((exception1 & (1 << gpc)) == 0) { + continue; + } + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "GPC%d exception pending", gpc); + + gpc_offset = gk20a_gr_gpc_offset(g, gpc); + + gpc_exception = gk20a_readl(g, gr_gpc0_gpccs_gpc_exception_r() + + gpc_offset); + + /* check if any tpc has an exception */ + for (tpc = 0; tpc < gr->gpc_tpc_count[gpc]; tpc++) { + if ((gr_gpc0_gpccs_gpc_exception_tpc_v(gpc_exception) & + (1 << tpc)) == 0) { + continue; + } + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "GPC%d: TPC%d exception pending", gpc, tpc); + + ret |= gk20a_gr_handle_tpc_exception(g, gpc, tpc, + post_event, fault_ch, hww_global_esr); + + } + + /* Handle GCC exception */ + if ((gr_gpc0_gpccs_gpc_exception_gcc_v(gpc_exception) != 0U) && + (g->ops.gr.handle_gcc_exception != NULL)) { + int gcc_ret = 0; + gcc_ret = g->ops.gr.handle_gcc_exception(g, gpc, tpc, + post_event, fault_ch, hww_global_esr); + ret |= (ret != 0) ? ret : gcc_ret; + } + + /* Handle GPCCS exceptions */ + if (g->ops.gr.handle_gpc_gpccs_exception) { + int ret_ecc = 0; + ret_ecc = g->ops.gr.handle_gpc_gpccs_exception(g, gpc, + gpc_exception); + ret |= (ret != 0) ? ret : ret_ecc; + } + + /* Handle GPCMMU exceptions */ + if (g->ops.gr.handle_gpc_gpcmmu_exception) { + int ret_mmu = 0; + + ret_mmu = g->ops.gr.handle_gpc_gpcmmu_exception(g, gpc, + gpc_exception); + ret |= (ret != 0) ? ret : ret_mmu; + } + + } + + return ret; +} + +static int gk20a_gr_post_bpt_events(struct gk20a *g, struct tsg_gk20a *tsg, + u32 global_esr) +{ + if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f()) { + g->ops.fifo.post_event_id(tsg, NVGPU_EVENT_ID_BPT_INT); + } + + if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f()) { + g->ops.fifo.post_event_id(tsg, NVGPU_EVENT_ID_BPT_PAUSE); + } + + return 0; +} + +int gk20a_gr_isr(struct gk20a *g) +{ + struct gr_gk20a_isr_data isr_data; + u32 grfifo_ctl; + u32 obj_table; + bool need_reset = false; + u32 gr_intr = gk20a_readl(g, gr_intr_r()); + struct channel_gk20a *ch = NULL; + struct channel_gk20a *fault_ch = NULL; + u32 tsgid = NVGPU_INVALID_TSG_ID; + struct tsg_gk20a *tsg = NULL; + u32 gr_engine_id; + u32 global_esr = 0; + u32 chid; + + nvgpu_log_fn(g, " "); + nvgpu_log(g, gpu_dbg_intr, "pgraph intr 0x%08x", gr_intr); + + if (gr_intr == 0U) { + return 0; + } + + gr_engine_id = gk20a_fifo_get_gr_engine_id(g); + if (gr_engine_id != FIFO_INVAL_ENGINE_ID) { + gr_engine_id = BIT(gr_engine_id); + } + + grfifo_ctl = gk20a_readl(g, gr_gpfifo_ctl_r()); + grfifo_ctl &= ~gr_gpfifo_ctl_semaphore_access_f(1); + grfifo_ctl &= ~gr_gpfifo_ctl_access_f(1); + + gk20a_writel(g, gr_gpfifo_ctl_r(), + grfifo_ctl | gr_gpfifo_ctl_access_f(0) | + gr_gpfifo_ctl_semaphore_access_f(0)); + + isr_data.addr = gk20a_readl(g, gr_trapped_addr_r()); + isr_data.data_lo = gk20a_readl(g, gr_trapped_data_lo_r()); + isr_data.data_hi = gk20a_readl(g, gr_trapped_data_hi_r()); + isr_data.curr_ctx = gk20a_readl(g, gr_fecs_current_ctx_r()); + isr_data.offset = gr_trapped_addr_mthd_v(isr_data.addr); + isr_data.sub_chan = gr_trapped_addr_subch_v(isr_data.addr); + obj_table = (isr_data.sub_chan < 4) ? gk20a_readl(g, + gr_fe_object_table_r(isr_data.sub_chan)) : 0; + isr_data.class_num = gr_fe_object_table_nvclass_v(obj_table); + + ch = gk20a_gr_get_channel_from_ctx(g, isr_data.curr_ctx, &tsgid); + isr_data.ch = ch; + chid = ch != NULL ? ch->chid : FIFO_INVAL_CHANNEL_ID; + + if (ch == NULL) { + nvgpu_err(g, "pgraph intr: 0x%08x, chid: INVALID", gr_intr); + } else { + tsg = tsg_gk20a_from_ch(ch); + if (tsg == NULL) { + nvgpu_err(g, "pgraph intr: 0x%08x, chid: %d " + "not bound to tsg", gr_intr, chid); + } + } + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "channel %d: addr 0x%08x, " + "data 0x%08x 0x%08x," + "ctx 0x%08x, offset 0x%08x, " + "subchannel 0x%08x, class 0x%08x", + chid, isr_data.addr, + isr_data.data_hi, isr_data.data_lo, + isr_data.curr_ctx, isr_data.offset, + isr_data.sub_chan, isr_data.class_num); + + if (gr_intr & gr_intr_notify_pending_f()) { + g->ops.gr.handle_notify_pending(g, &isr_data); + gk20a_writel(g, gr_intr_r(), + gr_intr_notify_reset_f()); + gr_intr &= ~gr_intr_notify_pending_f(); + } + + if (gr_intr & gr_intr_semaphore_pending_f()) { + g->ops.gr.handle_semaphore_pending(g, &isr_data); + gk20a_writel(g, gr_intr_r(), + gr_intr_semaphore_reset_f()); + gr_intr &= ~gr_intr_semaphore_pending_f(); + } + + if (gr_intr & gr_intr_semaphore_timeout_pending_f()) { + if (gk20a_gr_handle_semaphore_timeout_pending(g, + &isr_data) != 0) { + need_reset = true; + } + gk20a_writel(g, gr_intr_r(), + gr_intr_semaphore_reset_f()); + gr_intr &= ~gr_intr_semaphore_pending_f(); + } + + if (gr_intr & gr_intr_illegal_notify_pending_f()) { + if (gk20a_gr_intr_illegal_notify_pending(g, + &isr_data) != 0) { + need_reset = true; + } + gk20a_writel(g, gr_intr_r(), + gr_intr_illegal_notify_reset_f()); + gr_intr &= ~gr_intr_illegal_notify_pending_f(); + } + + if (gr_intr & gr_intr_illegal_method_pending_f()) { + if (gk20a_gr_handle_illegal_method(g, &isr_data) != 0) { + need_reset = true; + } + gk20a_writel(g, gr_intr_r(), + gr_intr_illegal_method_reset_f()); + gr_intr &= ~gr_intr_illegal_method_pending_f(); + } + + if (gr_intr & gr_intr_illegal_class_pending_f()) { + if (gk20a_gr_handle_illegal_class(g, &isr_data) != 0) { + need_reset = true; + } + gk20a_writel(g, gr_intr_r(), + gr_intr_illegal_class_reset_f()); + gr_intr &= ~gr_intr_illegal_class_pending_f(); + } + + if (gr_intr & gr_intr_fecs_error_pending_f()) { + if (g->ops.gr.handle_fecs_error(g, ch, &isr_data) != 0) { + need_reset = true; + } + gk20a_writel(g, gr_intr_r(), + gr_intr_fecs_error_reset_f()); + gr_intr &= ~gr_intr_fecs_error_pending_f(); + } + + if (gr_intr & gr_intr_class_error_pending_f()) { + if (gk20a_gr_handle_class_error(g, &isr_data) != 0) { + need_reset = true; + } + gk20a_writel(g, gr_intr_r(), + gr_intr_class_error_reset_f()); + gr_intr &= ~gr_intr_class_error_pending_f(); + } + + /* this one happens if someone tries to hit a non-whitelisted + * register using set_falcon[4] */ + if (gr_intr & gr_intr_firmware_method_pending_f()) { + if (gk20a_gr_handle_firmware_method(g, &isr_data) != 0) { + need_reset = true; + } + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, "firmware method intr pending\n"); + gk20a_writel(g, gr_intr_r(), + gr_intr_firmware_method_reset_f()); + gr_intr &= ~gr_intr_firmware_method_pending_f(); + } + + if (gr_intr & gr_intr_exception_pending_f()) { + u32 exception = gk20a_readl(g, gr_exception_r()); + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, "exception %08x\n", exception); + + if (exception & gr_exception_fe_m()) { + u32 fe = gk20a_readl(g, gr_fe_hww_esr_r()); + u32 info = gk20a_readl(g, gr_fe_hww_esr_info_r()); + + nvgpu_err(g, "fe exception: esr 0x%08x, info 0x%08x", + fe, info); + gk20a_writel(g, gr_fe_hww_esr_r(), + gr_fe_hww_esr_reset_active_f()); + need_reset = true; + } + + if (exception & gr_exception_memfmt_m()) { + u32 memfmt = gk20a_readl(g, gr_memfmt_hww_esr_r()); + + nvgpu_err(g, "memfmt exception: esr %08x", memfmt); + gk20a_writel(g, gr_memfmt_hww_esr_r(), + gr_memfmt_hww_esr_reset_active_f()); + need_reset = true; + } + + if (exception & gr_exception_pd_m()) { + u32 pd = gk20a_readl(g, gr_pd_hww_esr_r()); + + nvgpu_err(g, "pd exception: esr 0x%08x", pd); + gk20a_writel(g, gr_pd_hww_esr_r(), + gr_pd_hww_esr_reset_active_f()); + need_reset = true; + } + + if (exception & gr_exception_scc_m()) { + u32 scc = gk20a_readl(g, gr_scc_hww_esr_r()); + + nvgpu_err(g, "scc exception: esr 0x%08x", scc); + gk20a_writel(g, gr_scc_hww_esr_r(), + gr_scc_hww_esr_reset_active_f()); + need_reset = true; + } + + if (exception & gr_exception_ds_m()) { + u32 ds = gk20a_readl(g, gr_ds_hww_esr_r()); + + nvgpu_err(g, "ds exception: esr: 0x%08x", ds); + gk20a_writel(g, gr_ds_hww_esr_r(), + gr_ds_hww_esr_reset_task_f()); + need_reset = true; + } + + if (exception & gr_exception_ssync_m()) { + if (g->ops.gr.handle_ssync_hww) { + if (g->ops.gr.handle_ssync_hww(g) != 0) { + need_reset = true; + } + } else { + nvgpu_err(g, "unhandled ssync exception"); + } + } + + if (exception & gr_exception_mme_m()) { + u32 mme = gk20a_readl(g, gr_mme_hww_esr_r()); + u32 info = gk20a_readl(g, gr_mme_hww_esr_info_r()); + + nvgpu_err(g, "mme exception: esr 0x%08x info:0x%08x", + mme, info); + gk20a_writel(g, gr_mme_hww_esr_r(), + gr_mme_hww_esr_reset_active_f()); + need_reset = true; + } + + if (exception & gr_exception_sked_m()) { + u32 sked = gk20a_readl(g, gr_sked_hww_esr_r()); + + nvgpu_err(g, "sked exception: esr 0x%08x", sked); + gk20a_writel(g, gr_sked_hww_esr_r(), + gr_sked_hww_esr_reset_active_f()); + need_reset = true; + } + + /* check if a gpc exception has occurred */ + if (((exception & gr_exception_gpc_m()) != 0U) && + !need_reset) { + bool post_event = false; + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "GPC exception pending"); + + if (tsg != NULL) { + fault_ch = isr_data.ch; + } + + /* fault_ch can be NULL */ + /* check if any gpc has an exception */ + if (gk20a_gr_handle_gpc_exception(g, &post_event, + fault_ch, &global_esr) != 0) { + need_reset = true; + } + + /* signal clients waiting on an event */ + if (g->ops.gr.sm_debugger_attached(g) && + post_event && (fault_ch != NULL)) { + g->ops.debugger.post_events(fault_ch); + } + } + + gk20a_writel(g, gr_intr_r(), gr_intr_exception_reset_f()); + gr_intr &= ~gr_intr_exception_pending_f(); + + if (need_reset) { + nvgpu_err(g, "set gr exception notifier"); + gk20a_gr_set_error_notifier(g, &isr_data, + NVGPU_ERR_NOTIFIER_GR_EXCEPTION); + } + } + + if (need_reset) { + if (tsg != NULL) { + gk20a_fifo_recover(g, gr_engine_id, + tsgid, true, true, true, + RC_TYPE_GR_FAULT); + } else { + if (ch != NULL) { + nvgpu_err(g, "chid: %d referenceable but not " + "bound to tsg", chid); + } + gk20a_fifo_recover(g, gr_engine_id, + 0, false, false, true, + RC_TYPE_GR_FAULT); + } + } + + if (gr_intr != 0U) { + /* clear unhandled interrupts */ + if (ch == NULL) { + /* + * This is probably an interrupt during + * gk20a_free_channel() + */ + nvgpu_err(g, "unhandled gr intr 0x%08x for " + "unreferenceable channel, clearing", + gr_intr); + } else { + nvgpu_err(g, "unhandled gr intr 0x%08x for chid: %d", + gr_intr, chid); + } + gk20a_writel(g, gr_intr_r(), gr_intr); + } + + gk20a_writel(g, gr_gpfifo_ctl_r(), + grfifo_ctl | gr_gpfifo_ctl_access_f(1) | + gr_gpfifo_ctl_semaphore_access_f(1)); + + + /* Posting of BPT events should be the last thing in this function */ + if ((global_esr != 0U) && (tsg != NULL)) { + gk20a_gr_post_bpt_events(g, tsg, global_esr); + } + + if (ch) { + gk20a_channel_put(ch); + } + + return 0; +} + +u32 gk20a_gr_nonstall_isr(struct gk20a *g) +{ + u32 ops = 0; + u32 gr_intr = gk20a_readl(g, gr_intr_nonstall_r()); + + nvgpu_log(g, gpu_dbg_intr, "pgraph nonstall intr %08x", gr_intr); + + if ((gr_intr & gr_intr_nonstall_trap_pending_f()) != 0U) { + /* Clear the interrupt */ + gk20a_writel(g, gr_intr_nonstall_r(), + gr_intr_nonstall_trap_pending_f()); + ops |= (GK20A_NONSTALL_OPS_WAKEUP_SEMAPHORE | + GK20A_NONSTALL_OPS_POST_EVENTS); + } + return ops; +} + +int gr_gk20a_fecs_get_reglist_img_size(struct gk20a *g, u32 *size) +{ + BUG_ON(size == NULL); + return gr_gk20a_submit_fecs_method_op(g, + (struct fecs_method_op_gk20a) { + .mailbox.id = 0, + .mailbox.data = 0, + .mailbox.clr = ~0, + .method.data = 1, + .method.addr = gr_fecs_method_push_adr_discover_reglist_image_size_v(), + .mailbox.ret = size, + .cond.ok = GR_IS_UCODE_OP_NOT_EQUAL, + .mailbox.ok = 0, + .cond.fail = GR_IS_UCODE_OP_SKIP, + .mailbox.fail = 0}, false); +} + +int gr_gk20a_fecs_set_reglist_bind_inst(struct gk20a *g, + struct nvgpu_mem *inst_block) +{ + u32 data = fecs_current_ctx_data(g, inst_block); + + return gr_gk20a_submit_fecs_method_op(g, + (struct fecs_method_op_gk20a){ + .mailbox.id = 4, + .mailbox.data = data, + .mailbox.clr = ~0, + .method.data = 1, + .method.addr = gr_fecs_method_push_adr_set_reglist_bind_instance_v(), + .mailbox.ret = NULL, + .cond.ok = GR_IS_UCODE_OP_EQUAL, + .mailbox.ok = 1, + .cond.fail = GR_IS_UCODE_OP_SKIP, + .mailbox.fail = 0}, false); +} + +int gr_gk20a_fecs_set_reglist_virtual_addr(struct gk20a *g, u64 pmu_va) +{ + return gr_gk20a_submit_fecs_method_op(g, + (struct fecs_method_op_gk20a) { + .mailbox.id = 4, + .mailbox.data = u64_lo32(pmu_va >> 8), + .mailbox.clr = ~0, + .method.data = 1, + .method.addr = gr_fecs_method_push_adr_set_reglist_virtual_address_v(), + .mailbox.ret = NULL, + .cond.ok = GR_IS_UCODE_OP_EQUAL, + .mailbox.ok = 1, + .cond.fail = GR_IS_UCODE_OP_SKIP, + .mailbox.fail = 0}, false); +} + +int gk20a_gr_suspend(struct gk20a *g) +{ + u32 ret = 0; + + nvgpu_log_fn(g, " "); + + ret = g->ops.gr.wait_empty(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); + if (ret) { + return ret; + } + + gk20a_writel(g, gr_gpfifo_ctl_r(), + gr_gpfifo_ctl_access_disabled_f()); + + /* disable gr intr */ + gk20a_writel(g, gr_intr_r(), 0); + gk20a_writel(g, gr_intr_en_r(), 0); + + /* disable all exceptions */ + gk20a_writel(g, gr_exception_r(), 0); + gk20a_writel(g, gr_exception_en_r(), 0); + gk20a_writel(g, gr_exception1_r(), 0); + gk20a_writel(g, gr_exception1_en_r(), 0); + gk20a_writel(g, gr_exception2_r(), 0); + gk20a_writel(g, gr_exception2_en_r(), 0); + + gk20a_gr_flush_channel_tlb(&g->gr); + + g->gr.initialized = false; + + nvgpu_log_fn(g, "done"); + return ret; +} + +static int gr_gk20a_find_priv_offset_in_buffer(struct gk20a *g, + u32 addr, + bool is_quad, u32 quad, + u32 *context_buffer, + u32 context_buffer_size, + u32 *priv_offset); + +static int gr_gk20a_find_priv_offset_in_pm_buffer(struct gk20a *g, + u32 addr, + u32 *priv_offset); + +/* This function will decode a priv address and return the partition type and numbers. */ +int gr_gk20a_decode_priv_addr(struct gk20a *g, u32 addr, + enum ctxsw_addr_type *addr_type, + u32 *gpc_num, u32 *tpc_num, u32 *ppc_num, u32 *be_num, + u32 *broadcast_flags) +{ + u32 gpc_addr; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "addr=0x%x", addr); + + /* setup defaults */ + *addr_type = CTXSW_ADDR_TYPE_SYS; + *broadcast_flags = PRI_BROADCAST_FLAGS_NONE; + *gpc_num = 0; + *tpc_num = 0; + *ppc_num = 0; + *be_num = 0; + + if (pri_is_gpc_addr(g, addr)) { + *addr_type = CTXSW_ADDR_TYPE_GPC; + gpc_addr = pri_gpccs_addr_mask(addr); + if (pri_is_gpc_addr_shared(g, addr)) { + *addr_type = CTXSW_ADDR_TYPE_GPC; + *broadcast_flags |= PRI_BROADCAST_FLAGS_GPC; + } else { + *gpc_num = pri_get_gpc_num(g, addr); + } + + if (pri_is_ppc_addr(g, gpc_addr)) { + *addr_type = CTXSW_ADDR_TYPE_PPC; + if (pri_is_ppc_addr_shared(g, gpc_addr)) { + *broadcast_flags |= PRI_BROADCAST_FLAGS_PPC; + return 0; + } + } + if (g->ops.gr.is_tpc_addr(g, gpc_addr)) { + *addr_type = CTXSW_ADDR_TYPE_TPC; + if (pri_is_tpc_addr_shared(g, gpc_addr)) { + *broadcast_flags |= PRI_BROADCAST_FLAGS_TPC; + return 0; + } + *tpc_num = g->ops.gr.get_tpc_num(g, gpc_addr); + } + return 0; + } else if (pri_is_be_addr(g, addr)) { + *addr_type = CTXSW_ADDR_TYPE_BE; + if (pri_is_be_addr_shared(g, addr)) { + *broadcast_flags |= PRI_BROADCAST_FLAGS_BE; + return 0; + } + *be_num = pri_get_be_num(g, addr); + return 0; + } else if (g->ops.ltc.pri_is_ltc_addr(g, addr)) { + *addr_type = CTXSW_ADDR_TYPE_LTCS; + if (g->ops.ltc.is_ltcs_ltss_addr(g, addr)) { + *broadcast_flags |= PRI_BROADCAST_FLAGS_LTCS; + } else if (g->ops.ltc.is_ltcn_ltss_addr(g, addr)) { + *broadcast_flags |= PRI_BROADCAST_FLAGS_LTSS; + } + return 0; + } else if (pri_is_fbpa_addr(g, addr)) { + *addr_type = CTXSW_ADDR_TYPE_FBPA; + if (pri_is_fbpa_addr_shared(g, addr)) { + *broadcast_flags |= PRI_BROADCAST_FLAGS_FBPA; + return 0; + } + return 0; + } else if ((g->ops.gr.is_egpc_addr != NULL) && + g->ops.gr.is_egpc_addr(g, addr)) { + return g->ops.gr.decode_egpc_addr(g, + addr, addr_type, gpc_num, + tpc_num, broadcast_flags); + } else { + *addr_type = CTXSW_ADDR_TYPE_SYS; + return 0; + } + /* PPC!?!?!?! */ + + /*NOTREACHED*/ + return -EINVAL; +} + +void gr_gk20a_split_fbpa_broadcast_addr(struct gk20a *g, u32 addr, + u32 num_fbpas, + u32 *priv_addr_table, u32 *t) +{ + u32 fbpa_id; + + for (fbpa_id = 0; fbpa_id < num_fbpas; fbpa_id++) { + priv_addr_table[(*t)++] = pri_fbpa_addr(g, + pri_fbpa_addr_mask(g, addr), fbpa_id); + } +} + +int gr_gk20a_split_ppc_broadcast_addr(struct gk20a *g, u32 addr, + u32 gpc_num, + u32 *priv_addr_table, u32 *t) +{ + u32 ppc_num; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "addr=0x%x", addr); + + for (ppc_num = 0; ppc_num < g->gr.gpc_ppc_count[gpc_num]; ppc_num++) { + priv_addr_table[(*t)++] = pri_ppc_addr(g, pri_ppccs_addr_mask(addr), + gpc_num, ppc_num); + } + + return 0; +} + +/* + * The context buffer is indexed using BE broadcast addresses and GPC/TPC + * unicast addresses. This function will convert a BE unicast address to a BE + * broadcast address and split a GPC/TPC broadcast address into a table of + * GPC/TPC addresses. The addresses generated by this function can be + * successfully processed by gr_gk20a_find_priv_offset_in_buffer + */ +int gr_gk20a_create_priv_addr_table(struct gk20a *g, + u32 addr, + u32 *priv_addr_table, + u32 *num_registers) +{ + enum ctxsw_addr_type addr_type; + u32 gpc_num, tpc_num, ppc_num, be_num; + u32 priv_addr, gpc_addr; + u32 broadcast_flags; + u32 t; + int err; + + t = 0; + *num_registers = 0; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "addr=0x%x", addr); + + err = g->ops.gr.decode_priv_addr(g, addr, &addr_type, + &gpc_num, &tpc_num, &ppc_num, &be_num, + &broadcast_flags); + nvgpu_log(g, gpu_dbg_gpu_dbg, "addr_type = %d", addr_type); + if (err != 0) { + return err; + } + + if ((addr_type == CTXSW_ADDR_TYPE_SYS) || + (addr_type == CTXSW_ADDR_TYPE_BE)) { + /* The BE broadcast registers are included in the compressed PRI + * table. Convert a BE unicast address to a broadcast address + * so that we can look up the offset. */ + if ((addr_type == CTXSW_ADDR_TYPE_BE) && + ((broadcast_flags & PRI_BROADCAST_FLAGS_BE) == 0U)) { + priv_addr_table[t++] = pri_be_shared_addr(g, addr); + } else { + priv_addr_table[t++] = addr; + } + + *num_registers = t; + return 0; + } + + /* The GPC/TPC unicast registers are included in the compressed PRI + * tables. Convert a GPC/TPC broadcast address to unicast addresses so + * that we can look up the offsets. */ + if (broadcast_flags & PRI_BROADCAST_FLAGS_GPC) { + for (gpc_num = 0; gpc_num < g->gr.gpc_count; gpc_num++) { + + if (broadcast_flags & PRI_BROADCAST_FLAGS_TPC) { + for (tpc_num = 0; + tpc_num < g->gr.gpc_tpc_count[gpc_num]; + tpc_num++) { + priv_addr_table[t++] = + pri_tpc_addr(g, pri_tpccs_addr_mask(addr), + gpc_num, tpc_num); + } + + } else if (broadcast_flags & PRI_BROADCAST_FLAGS_PPC) { + err = gr_gk20a_split_ppc_broadcast_addr(g, addr, gpc_num, + priv_addr_table, &t); + if (err != 0) { + return err; + } + } else { + priv_addr = pri_gpc_addr(g, + pri_gpccs_addr_mask(addr), + gpc_num); + + gpc_addr = pri_gpccs_addr_mask(priv_addr); + tpc_num = g->ops.gr.get_tpc_num(g, gpc_addr); + if (tpc_num >= g->gr.gpc_tpc_count[gpc_num]) { + continue; + } + + priv_addr_table[t++] = priv_addr; + } + } + } else if (((addr_type == CTXSW_ADDR_TYPE_EGPC) || + (addr_type == CTXSW_ADDR_TYPE_ETPC)) && + (g->ops.gr.egpc_etpc_priv_addr_table != NULL)) { + nvgpu_log(g, gpu_dbg_gpu_dbg, "addr_type : EGPC/ETPC"); + g->ops.gr.egpc_etpc_priv_addr_table(g, addr, gpc_num, tpc_num, + broadcast_flags, priv_addr_table, &t); + } else if (broadcast_flags & PRI_BROADCAST_FLAGS_LTSS) { + g->ops.ltc.split_lts_broadcast_addr(g, addr, + priv_addr_table, &t); + } else if (broadcast_flags & PRI_BROADCAST_FLAGS_LTCS) { + g->ops.ltc.split_ltc_broadcast_addr(g, addr, + priv_addr_table, &t); + } else if (broadcast_flags & PRI_BROADCAST_FLAGS_FBPA) { + g->ops.gr.split_fbpa_broadcast_addr(g, addr, + nvgpu_get_litter_value(g, GPU_LIT_NUM_FBPAS), + priv_addr_table, &t); + } else if ((broadcast_flags & PRI_BROADCAST_FLAGS_GPC) == 0U) { + if (broadcast_flags & PRI_BROADCAST_FLAGS_TPC) { + for (tpc_num = 0; + tpc_num < g->gr.gpc_tpc_count[gpc_num]; + tpc_num++) { + priv_addr_table[t++] = + pri_tpc_addr(g, pri_tpccs_addr_mask(addr), + gpc_num, tpc_num); + } + } else if (broadcast_flags & PRI_BROADCAST_FLAGS_PPC) { + err = gr_gk20a_split_ppc_broadcast_addr(g, + addr, gpc_num, priv_addr_table, &t); + } else { + priv_addr_table[t++] = addr; + } + } + + *num_registers = t; + return 0; +} + +int gr_gk20a_get_ctx_buffer_offsets(struct gk20a *g, + u32 addr, + u32 max_offsets, + u32 *offsets, u32 *offset_addrs, + u32 *num_offsets, + bool is_quad, u32 quad) +{ + u32 i; + u32 priv_offset = 0; + u32 *priv_registers; + u32 num_registers = 0; + int err = 0; + struct gr_gk20a *gr = &g->gr; + u32 sm_per_tpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_SM_PER_TPC); + u32 potential_offsets = gr->max_gpc_count * gr->max_tpc_per_gpc_count * + sm_per_tpc; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "addr=0x%x", addr); + + /* implementation is crossed-up if either of these happen */ + if (max_offsets > potential_offsets) { + nvgpu_log_fn(g, "max_offsets > potential_offsets"); + return -EINVAL; + } + + if (!g->gr.ctx_vars.golden_image_initialized) { + return -ENODEV; + } + + priv_registers = nvgpu_kzalloc(g, sizeof(u32) * potential_offsets); + if (priv_registers == NULL) { + nvgpu_log_fn(g, "failed alloc for potential_offsets=%d", potential_offsets); + err = PTR_ERR(priv_registers); + goto cleanup; + } + memset(offsets, 0, sizeof(u32) * max_offsets); + memset(offset_addrs, 0, sizeof(u32) * max_offsets); + *num_offsets = 0; + + g->ops.gr.create_priv_addr_table(g, addr, &priv_registers[0], + &num_registers); + + if ((max_offsets > 1) && (num_registers > max_offsets)) { + nvgpu_log_fn(g, "max_offsets = %d, num_registers = %d", + max_offsets, num_registers); + err = -EINVAL; + goto cleanup; + } + + if ((max_offsets == 1) && (num_registers > 1)) { + num_registers = 1; + } + + if (g->gr.ctx_vars.local_golden_image == NULL) { + nvgpu_log_fn(g, "no context switch header info to work with"); + err = -EINVAL; + goto cleanup; + } + + for (i = 0; i < num_registers; i++) { + err = gr_gk20a_find_priv_offset_in_buffer(g, + priv_registers[i], + is_quad, quad, + g->gr.ctx_vars.local_golden_image, + g->gr.ctx_vars.golden_image_size, + &priv_offset); + if (err != 0) { + nvgpu_log_fn(g, "Could not determine priv_offset for addr:0x%x", + addr); /*, grPriRegStr(addr)));*/ + goto cleanup; + } + + offsets[i] = priv_offset; + offset_addrs[i] = priv_registers[i]; + } + + *num_offsets = num_registers; +cleanup: + if (!IS_ERR_OR_NULL(priv_registers)) { + nvgpu_kfree(g, priv_registers); + } + + return err; +} + +int gr_gk20a_get_pm_ctx_buffer_offsets(struct gk20a *g, + u32 addr, + u32 max_offsets, + u32 *offsets, u32 *offset_addrs, + u32 *num_offsets) +{ + u32 i; + u32 priv_offset = 0; + u32 *priv_registers; + u32 num_registers = 0; + int err = 0; + struct gr_gk20a *gr = &g->gr; + u32 sm_per_tpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_SM_PER_TPC); + u32 potential_offsets = gr->max_gpc_count * gr->max_tpc_per_gpc_count * + sm_per_tpc; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "addr=0x%x", addr); + + /* implementation is crossed-up if either of these happen */ + if (max_offsets > potential_offsets) { + return -EINVAL; + } + + if (!g->gr.ctx_vars.golden_image_initialized) { + return -ENODEV; + } + + priv_registers = nvgpu_kzalloc(g, sizeof(u32) * potential_offsets); + if (priv_registers == NULL) { + nvgpu_log_fn(g, "failed alloc for potential_offsets=%d", potential_offsets); + return -ENOMEM; + } + memset(offsets, 0, sizeof(u32) * max_offsets); + memset(offset_addrs, 0, sizeof(u32) * max_offsets); + *num_offsets = 0; + + g->ops.gr.create_priv_addr_table(g, addr, priv_registers, + &num_registers); + + if ((max_offsets > 1) && (num_registers > max_offsets)) { + err = -EINVAL; + goto cleanup; + } + + if ((max_offsets == 1) && (num_registers > 1)) { + num_registers = 1; + } + + if (g->gr.ctx_vars.local_golden_image == NULL) { + nvgpu_log_fn(g, "no context switch header info to work with"); + err = -EINVAL; + goto cleanup; + } + + for (i = 0; i < num_registers; i++) { + err = gr_gk20a_find_priv_offset_in_pm_buffer(g, + priv_registers[i], + &priv_offset); + if (err != 0) { + nvgpu_log_fn(g, "Could not determine priv_offset for addr:0x%x", + addr); /*, grPriRegStr(addr)));*/ + goto cleanup; + } + + offsets[i] = priv_offset; + offset_addrs[i] = priv_registers[i]; + } + + *num_offsets = num_registers; +cleanup: + nvgpu_kfree(g, priv_registers); + + return err; +} + +/* Setup some register tables. This looks hacky; our + * register/offset functions are just that, functions. + * So they can't be used as initializers... TBD: fix to + * generate consts at least on an as-needed basis. + */ +static const u32 _num_ovr_perf_regs = 17; +static u32 _ovr_perf_regs[17] = { 0, }; +/* Following are the blocks of registers that the ucode + stores in the extended region.*/ + +void gk20a_gr_init_ovr_sm_dsm_perf(void) +{ + if (_ovr_perf_regs[0] != 0) { + return; + } + + _ovr_perf_regs[0] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel0_r(); + _ovr_perf_regs[1] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel1_r(); + _ovr_perf_regs[2] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control0_r(); + _ovr_perf_regs[3] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control5_r(); + _ovr_perf_regs[4] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter_status1_r(); + _ovr_perf_regs[5] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_control_r(); + _ovr_perf_regs[6] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_control_r(); + _ovr_perf_regs[7] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_control_r(); + _ovr_perf_regs[8] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_control_r(); + _ovr_perf_regs[9] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter4_control_r(); + _ovr_perf_regs[10] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter5_control_r(); + _ovr_perf_regs[11] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter6_control_r(); + _ovr_perf_regs[12] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter7_control_r(); + _ovr_perf_regs[13] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter4_r(); + _ovr_perf_regs[14] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter5_r(); + _ovr_perf_regs[15] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter6_r(); + _ovr_perf_regs[16] = gr_pri_gpc0_tpc0_sm_dsm_perf_counter7_r(); + +} + +/* TBD: would like to handle this elsewhere, at a higher level. + * these are currently constructed in a "test-then-write" style + * which makes it impossible to know externally whether a ctx + * write will actually occur. so later we should put a lazy, + * map-and-hold system in the patch write state */ +static int gr_gk20a_ctx_patch_smpc(struct gk20a *g, + struct channel_gk20a *ch, + u32 addr, u32 data, + struct nvgpu_mem *mem) +{ + u32 num_gpc = g->gr.gpc_count; + u32 num_tpc; + u32 tpc, gpc, reg; + u32 chk_addr; + u32 vaddr_lo; + u32 vaddr_hi; + u32 tmp; + u32 num_ovr_perf_regs = 0; + u32 *ovr_perf_regs = NULL; + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); + struct tsg_gk20a *tsg; + struct nvgpu_gr_ctx *gr_ctx; + struct nvgpu_mem *ctxheader = &ch->ctx_header; + + tsg = tsg_gk20a_from_ch(ch); + if (tsg == NULL) { + return -EINVAL; + } + + gr_ctx = &tsg->gr_ctx; + g->ops.gr.init_ovr_sm_dsm_perf(); + g->ops.gr.init_sm_dsm_reg_info(); + g->ops.gr.get_ovr_perf_regs(g, &num_ovr_perf_regs, &ovr_perf_regs); + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "addr=0x%x", addr); + + for (reg = 0; reg < num_ovr_perf_regs; reg++) { + for (gpc = 0; gpc < num_gpc; gpc++) { + num_tpc = g->gr.gpc_tpc_count[gpc]; + for (tpc = 0; tpc < num_tpc; tpc++) { + chk_addr = ((gpc_stride * gpc) + + (tpc_in_gpc_stride * tpc) + + ovr_perf_regs[reg]); + if (chk_addr != addr) { + continue; + } + /* reset the patch count from previous + runs,if ucode has already processed + it */ + tmp = nvgpu_mem_rd(g, mem, + ctxsw_prog_main_image_patch_count_o()); + + if (tmp == 0U) { + gr_ctx->patch_ctx.data_count = 0; + } + + gr_gk20a_ctx_patch_write(g, gr_ctx, + addr, data, true); + + vaddr_lo = u64_lo32(gr_ctx->patch_ctx.mem.gpu_va); + vaddr_hi = u64_hi32(gr_ctx->patch_ctx.mem.gpu_va); + + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_patch_count_o(), + gr_ctx->patch_ctx.data_count); + if (ctxheader->gpu_va) { + nvgpu_mem_wr(g, ctxheader, + ctxsw_prog_main_image_patch_adr_lo_o(), + vaddr_lo); + nvgpu_mem_wr(g, ctxheader, + ctxsw_prog_main_image_patch_adr_hi_o(), + vaddr_hi); + } else { + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_patch_adr_lo_o(), + vaddr_lo); + nvgpu_mem_wr(g, mem, + ctxsw_prog_main_image_patch_adr_hi_o(), + vaddr_hi); + } + + /* we're not caching these on cpu side, + but later watch for it */ + return 0; + } + } + } + + return 0; +} + +#define ILLEGAL_ID ((u32)~0) + +static inline bool check_main_image_header_magic(u8 *context) +{ + u32 magic = *(u32 *)(context + ctxsw_prog_main_image_magic_value_o()); + return magic == ctxsw_prog_main_image_magic_value_v_value_v(); +} +static inline bool check_local_header_magic(u8 *context) +{ + u32 magic = *(u32 *)(context + ctxsw_prog_local_magic_value_o()); + return magic == ctxsw_prog_local_magic_value_v_value_v(); + +} + +/* most likely dupe of ctxsw_gpccs_header__size_1_v() */ +static inline int ctxsw_prog_ucode_header_size_in_bytes(void) +{ + return 256; +} + +void gk20a_gr_get_ovr_perf_regs(struct gk20a *g, u32 *num_ovr_perf_regs, + u32 **ovr_perf_regs) +{ + *num_ovr_perf_regs = _num_ovr_perf_regs; + *ovr_perf_regs = _ovr_perf_regs; +} + +static int gr_gk20a_find_priv_offset_in_ext_buffer(struct gk20a *g, + u32 addr, + bool is_quad, u32 quad, + u32 *context_buffer, + u32 context_buffer_size, + u32 *priv_offset) +{ + u32 i, data32; + u32 gpc_num, tpc_num; + u32 num_gpcs, num_tpcs; + u32 chk_addr; + u32 ext_priv_offset, ext_priv_size; + u8 *context; + u32 offset_to_segment, offset_to_segment_end; + u32 sm_dsm_perf_reg_id = ILLEGAL_ID; + u32 sm_dsm_perf_ctrl_reg_id = ILLEGAL_ID; + u32 num_ext_gpccs_ext_buffer_segments; + u32 inter_seg_offset; + u32 max_tpc_count; + u32 *sm_dsm_perf_ctrl_regs = NULL; + u32 num_sm_dsm_perf_ctrl_regs = 0; + u32 *sm_dsm_perf_regs = NULL; + u32 num_sm_dsm_perf_regs = 0; + u32 buffer_segments_size = 0; + u32 marker_size = 0; + u32 control_register_stride = 0; + u32 perf_register_stride = 0; + struct gr_gk20a *gr = &g->gr; + u32 gpc_base = nvgpu_get_litter_value(g, GPU_LIT_GPC_BASE); + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 tpc_in_gpc_base = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_BASE); + u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); + u32 tpc_gpc_mask = (tpc_in_gpc_stride - 1); + + /* Only have TPC registers in extended region, so if not a TPC reg, + then return error so caller can look elsewhere. */ + if (pri_is_gpc_addr(g, addr)) { + u32 gpc_addr = 0; + gpc_num = pri_get_gpc_num(g, addr); + gpc_addr = pri_gpccs_addr_mask(addr); + if (g->ops.gr.is_tpc_addr(g, gpc_addr)) { + tpc_num = g->ops.gr.get_tpc_num(g, gpc_addr); + } else { + return -EINVAL; + } + + nvgpu_log_info(g, " gpc = %d tpc = %d", + gpc_num, tpc_num); + } else if ((g->ops.gr.is_etpc_addr != NULL) && + g->ops.gr.is_etpc_addr(g, addr)) { + g->ops.gr.get_egpc_etpc_num(g, addr, &gpc_num, &tpc_num); + gpc_base = g->ops.gr.get_egpc_base(g); + } else { + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, + "does not exist in extended region"); + return -EINVAL; + } + + buffer_segments_size = ctxsw_prog_extended_buffer_segments_size_in_bytes_v(); + /* note below is in words/num_registers */ + marker_size = ctxsw_prog_extended_marker_size_in_bytes_v() >> 2; + + context = (u8 *)context_buffer; + /* sanity check main header */ + if (!check_main_image_header_magic(context)) { + nvgpu_err(g, + "Invalid main header: magic value"); + return -EINVAL; + } + num_gpcs = *(u32 *)(context + ctxsw_prog_main_image_num_gpcs_o()); + if (gpc_num >= num_gpcs) { + nvgpu_err(g, + "GPC 0x%08x is greater than total count 0x%08x!", + gpc_num, num_gpcs); + return -EINVAL; + } + + data32 = *(u32 *)(context + ctxsw_prog_main_extended_buffer_ctl_o()); + ext_priv_size = ctxsw_prog_main_extended_buffer_ctl_size_v(data32); + if (0 == ext_priv_size) { + nvgpu_log_info(g, " No extended memory in context buffer"); + return -EINVAL; + } + ext_priv_offset = ctxsw_prog_main_extended_buffer_ctl_offset_v(data32); + + offset_to_segment = ext_priv_offset * ctxsw_prog_ucode_header_size_in_bytes(); + offset_to_segment_end = offset_to_segment + + (ext_priv_size * buffer_segments_size); + + /* check local header magic */ + context += ctxsw_prog_ucode_header_size_in_bytes(); + if (!check_local_header_magic(context)) { + nvgpu_err(g, + "Invalid local header: magic value"); + return -EINVAL; + } + + /* + * See if the incoming register address is in the first table of + * registers. We check this by decoding only the TPC addr portion. + * If we get a hit on the TPC bit, we then double check the address + * by computing it from the base gpc/tpc strides. Then make sure + * it is a real match. + */ + g->ops.gr.get_sm_dsm_perf_regs(g, &num_sm_dsm_perf_regs, + &sm_dsm_perf_regs, + &perf_register_stride); + + g->ops.gr.init_sm_dsm_reg_info(); + + for (i = 0; i < num_sm_dsm_perf_regs; i++) { + if ((addr & tpc_gpc_mask) == (sm_dsm_perf_regs[i] & tpc_gpc_mask)) { + sm_dsm_perf_reg_id = i; + + nvgpu_log_info(g, "register match: 0x%08x", + sm_dsm_perf_regs[i]); + + chk_addr = (gpc_base + gpc_stride * gpc_num) + + tpc_in_gpc_base + + (tpc_in_gpc_stride * tpc_num) + + (sm_dsm_perf_regs[sm_dsm_perf_reg_id] & tpc_gpc_mask); + + if (chk_addr != addr) { + nvgpu_err(g, + "Oops addr miss-match! : 0x%08x != 0x%08x", + addr, chk_addr); + return -EINVAL; + } + break; + } + } + + /* Didn't find reg in supported group 1. + * so try the second group now */ + g->ops.gr.get_sm_dsm_perf_ctrl_regs(g, &num_sm_dsm_perf_ctrl_regs, + &sm_dsm_perf_ctrl_regs, + &control_register_stride); + + if (ILLEGAL_ID == sm_dsm_perf_reg_id) { + for (i = 0; i < num_sm_dsm_perf_ctrl_regs; i++) { + if ((addr & tpc_gpc_mask) == + (sm_dsm_perf_ctrl_regs[i] & tpc_gpc_mask)) { + sm_dsm_perf_ctrl_reg_id = i; + + nvgpu_log_info(g, "register match: 0x%08x", + sm_dsm_perf_ctrl_regs[i]); + + chk_addr = (gpc_base + gpc_stride * gpc_num) + + tpc_in_gpc_base + + tpc_in_gpc_stride * tpc_num + + (sm_dsm_perf_ctrl_regs[sm_dsm_perf_ctrl_reg_id] & + tpc_gpc_mask); + + if (chk_addr != addr) { + nvgpu_err(g, + "Oops addr miss-match! : 0x%08x != 0x%08x", + addr, chk_addr); + return -EINVAL; + + } + + break; + } + } + } + + if ((ILLEGAL_ID == sm_dsm_perf_ctrl_reg_id) && + (ILLEGAL_ID == sm_dsm_perf_reg_id)) { + return -EINVAL; + } + + /* Skip the FECS extended header, nothing there for us now. */ + offset_to_segment += buffer_segments_size; + + /* skip through the GPCCS extended headers until we get to the data for + * our GPC. The size of each gpc extended segment is enough to hold the + * max tpc count for the gpcs,in 256b chunks. + */ + + max_tpc_count = gr->max_tpc_per_gpc_count; + + num_ext_gpccs_ext_buffer_segments = (u32)((max_tpc_count + 1) / 2); + + offset_to_segment += (num_ext_gpccs_ext_buffer_segments * + buffer_segments_size * gpc_num); + + num_tpcs = g->gr.gpc_tpc_count[gpc_num]; + + /* skip the head marker to start with */ + inter_seg_offset = marker_size; + + if (ILLEGAL_ID != sm_dsm_perf_ctrl_reg_id) { + /* skip over control regs of TPC's before the one we want. + * then skip to the register in this tpc */ + inter_seg_offset = inter_seg_offset + + (tpc_num * control_register_stride) + + sm_dsm_perf_ctrl_reg_id; + } else { + /* skip all the control registers */ + inter_seg_offset = inter_seg_offset + + (num_tpcs * control_register_stride); + + /* skip the marker between control and counter segments */ + inter_seg_offset += marker_size; + + /* skip over counter regs of TPCs before the one we want */ + inter_seg_offset = inter_seg_offset + + (tpc_num * perf_register_stride) * + ctxsw_prog_extended_num_smpc_quadrants_v(); + + /* skip over the register for the quadrants we do not want. + * then skip to the register in this tpc */ + inter_seg_offset = inter_seg_offset + + (perf_register_stride * quad) + + sm_dsm_perf_reg_id; + } + + /* set the offset to the segment offset plus the inter segment offset to + * our register */ + offset_to_segment += (inter_seg_offset * 4); + + /* last sanity check: did we somehow compute an offset outside the + * extended buffer? */ + if (offset_to_segment > offset_to_segment_end) { + nvgpu_err(g, + "Overflow ctxsw buffer! 0x%08x > 0x%08x", + offset_to_segment, offset_to_segment_end); + return -EINVAL; + } + + *priv_offset = offset_to_segment; + + return 0; +} + + +static int +gr_gk20a_process_context_buffer_priv_segment(struct gk20a *g, + enum ctxsw_addr_type addr_type, + u32 pri_addr, + u32 gpc_num, u32 num_tpcs, + u32 num_ppcs, u32 ppc_mask, + u32 *priv_offset) +{ + u32 i; + u32 address, base_address; + u32 sys_offset, gpc_offset, tpc_offset, ppc_offset; + u32 ppc_num, tpc_num, tpc_addr, gpc_addr, ppc_addr; + struct aiv_gk20a *reg; + u32 gpc_base = nvgpu_get_litter_value(g, GPU_LIT_GPC_BASE); + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 ppc_in_gpc_base = nvgpu_get_litter_value(g, GPU_LIT_PPC_IN_GPC_BASE); + u32 ppc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_PPC_IN_GPC_STRIDE); + u32 tpc_in_gpc_base = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_BASE); + u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "pri_addr=0x%x", pri_addr); + + if (!g->gr.ctx_vars.valid) { + return -EINVAL; + } + + /* Process the SYS/BE segment. */ + if ((addr_type == CTXSW_ADDR_TYPE_SYS) || + (addr_type == CTXSW_ADDR_TYPE_BE)) { + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.sys.count; i++) { + reg = &g->gr.ctx_vars.ctxsw_regs.sys.l[i]; + address = reg->addr; + sys_offset = reg->index; + + if (pri_addr == address) { + *priv_offset = sys_offset; + return 0; + } + } + } + + /* Process the TPC segment. */ + if (addr_type == CTXSW_ADDR_TYPE_TPC) { + for (tpc_num = 0; tpc_num < num_tpcs; tpc_num++) { + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.tpc.count; i++) { + reg = &g->gr.ctx_vars.ctxsw_regs.tpc.l[i]; + address = reg->addr; + tpc_addr = pri_tpccs_addr_mask(address); + base_address = gpc_base + + (gpc_num * gpc_stride) + + tpc_in_gpc_base + + (tpc_num * tpc_in_gpc_stride); + address = base_address + tpc_addr; + /* + * The data for the TPCs is interleaved in the context buffer. + * Example with num_tpcs = 2 + * 0 1 2 3 4 5 6 7 8 9 10 11 ... + * 0-0 1-0 0-1 1-1 0-2 1-2 0-3 1-3 0-4 1-4 0-5 1-5 ... + */ + tpc_offset = (reg->index * num_tpcs) + (tpc_num * 4); + + if (pri_addr == address) { + *priv_offset = tpc_offset; + return 0; + } + } + } + } else if ((addr_type == CTXSW_ADDR_TYPE_EGPC) || + (addr_type == CTXSW_ADDR_TYPE_ETPC)) { + if (g->ops.gr.get_egpc_base == NULL) { + return -EINVAL; + } + + for (tpc_num = 0; tpc_num < num_tpcs; tpc_num++) { + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.etpc.count; i++) { + reg = &g->gr.ctx_vars.ctxsw_regs.etpc.l[i]; + address = reg->addr; + tpc_addr = pri_tpccs_addr_mask(address); + base_address = g->ops.gr.get_egpc_base(g) + + (gpc_num * gpc_stride) + + tpc_in_gpc_base + + (tpc_num * tpc_in_gpc_stride); + address = base_address + tpc_addr; + /* + * The data for the TPCs is interleaved in the context buffer. + * Example with num_tpcs = 2 + * 0 1 2 3 4 5 6 7 8 9 10 11 ... + * 0-0 1-0 0-1 1-1 0-2 1-2 0-3 1-3 0-4 1-4 0-5 1-5 ... + */ + tpc_offset = (reg->index * num_tpcs) + (tpc_num * 4); + + if (pri_addr == address) { + *priv_offset = tpc_offset; + nvgpu_log(g, + gpu_dbg_fn | gpu_dbg_gpu_dbg, + "egpc/etpc priv_offset=0x%#08x", + *priv_offset); + return 0; + } + } + } + } + + + /* Process the PPC segment. */ + if (addr_type == CTXSW_ADDR_TYPE_PPC) { + for (ppc_num = 0; ppc_num < num_ppcs; ppc_num++) { + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.ppc.count; i++) { + reg = &g->gr.ctx_vars.ctxsw_regs.ppc.l[i]; + address = reg->addr; + ppc_addr = pri_ppccs_addr_mask(address); + base_address = gpc_base + + (gpc_num * gpc_stride) + + ppc_in_gpc_base + + (ppc_num * ppc_in_gpc_stride); + address = base_address + ppc_addr; + /* + * The data for the PPCs is interleaved in the context buffer. + * Example with numPpcs = 2 + * 0 1 2 3 4 5 6 7 8 9 10 11 ... + * 0-0 1-0 0-1 1-1 0-2 1-2 0-3 1-3 0-4 1-4 0-5 1-5 ... + */ + ppc_offset = (reg->index * num_ppcs) + (ppc_num * 4); + + if (pri_addr == address) { + *priv_offset = ppc_offset; + return 0; + } + } + } + } + + + /* Process the GPC segment. */ + if (addr_type == CTXSW_ADDR_TYPE_GPC) { + for (i = 0; i < g->gr.ctx_vars.ctxsw_regs.gpc.count; i++) { + reg = &g->gr.ctx_vars.ctxsw_regs.gpc.l[i]; + + address = reg->addr; + gpc_addr = pri_gpccs_addr_mask(address); + gpc_offset = reg->index; + + base_address = gpc_base + (gpc_num * gpc_stride); + address = base_address + gpc_addr; + + if (pri_addr == address) { + *priv_offset = gpc_offset; + return 0; + } + } + } + return -EINVAL; +} + +static int gr_gk20a_determine_ppc_configuration(struct gk20a *g, + u8 *context, + u32 *num_ppcs, u32 *ppc_mask, + u32 *reg_ppc_count) +{ + u32 data32; + u32 num_pes_per_gpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_PES_PER_GPC); + + /* + * if there is only 1 PES_PER_GPC, then we put the PES registers + * in the GPC reglist, so we can't error out if ppc.count == 0 + */ + if ((!g->gr.ctx_vars.valid) || + ((g->gr.ctx_vars.ctxsw_regs.ppc.count == 0) && + (num_pes_per_gpc > 1))) { + return -EINVAL; + } + + data32 = *(u32 *)(context + ctxsw_prog_local_image_ppc_info_o()); + + *num_ppcs = ctxsw_prog_local_image_ppc_info_num_ppcs_v(data32); + *ppc_mask = ctxsw_prog_local_image_ppc_info_ppc_mask_v(data32); + + *reg_ppc_count = g->gr.ctx_vars.ctxsw_regs.ppc.count; + + return 0; +} + +int gr_gk20a_get_offset_in_gpccs_segment(struct gk20a *g, + enum ctxsw_addr_type addr_type, + u32 num_tpcs, + u32 num_ppcs, + u32 reg_list_ppc_count, + u32 *__offset_in_segment) +{ + u32 offset_in_segment = 0; + struct gr_gk20a *gr = &g->gr; + + if (addr_type == CTXSW_ADDR_TYPE_TPC) { + /* + * reg = gr->ctx_vars.ctxsw_regs.tpc.l; + * offset_in_segment = 0; + */ + } else if ((addr_type == CTXSW_ADDR_TYPE_EGPC) || + (addr_type == CTXSW_ADDR_TYPE_ETPC)) { + offset_in_segment = + ((gr->ctx_vars.ctxsw_regs.tpc.count * + num_tpcs) << 2); + + nvgpu_log(g, gpu_dbg_info | gpu_dbg_gpu_dbg, + "egpc etpc offset_in_segment 0x%#08x", + offset_in_segment); + } else if (addr_type == CTXSW_ADDR_TYPE_PPC) { + /* + * The ucode stores TPC data before PPC data. + * Advance offset past TPC data to PPC data. + */ + offset_in_segment = + (((gr->ctx_vars.ctxsw_regs.tpc.count + + gr->ctx_vars.ctxsw_regs.etpc.count) * + num_tpcs) << 2); + } else if (addr_type == CTXSW_ADDR_TYPE_GPC) { + /* + * The ucode stores TPC/PPC data before GPC data. + * Advance offset past TPC/PPC data to GPC data. + * + * Note 1 PES_PER_GPC case + */ + u32 num_pes_per_gpc = nvgpu_get_litter_value(g, + GPU_LIT_NUM_PES_PER_GPC); + if (num_pes_per_gpc > 1) { + offset_in_segment = + ((((gr->ctx_vars.ctxsw_regs.tpc.count + + gr->ctx_vars.ctxsw_regs.etpc.count) * + num_tpcs) << 2) + + ((reg_list_ppc_count * num_ppcs) << 2)); + } else { + offset_in_segment = + (((gr->ctx_vars.ctxsw_regs.tpc.count + + gr->ctx_vars.ctxsw_regs.etpc.count) * + num_tpcs) << 2); + } + } else { + nvgpu_log_fn(g, "Unknown address type."); + return -EINVAL; + } + + *__offset_in_segment = offset_in_segment; + return 0; +} + +/* + * This function will return the 32 bit offset for a priv register if it is + * present in the context buffer. The context buffer is in CPU memory. + */ +static int gr_gk20a_find_priv_offset_in_buffer(struct gk20a *g, + u32 addr, + bool is_quad, u32 quad, + u32 *context_buffer, + u32 context_buffer_size, + u32 *priv_offset) +{ + u32 i, data32; + int err; + enum ctxsw_addr_type addr_type; + u32 broadcast_flags; + u32 gpc_num, tpc_num, ppc_num, be_num; + u32 num_gpcs, num_tpcs, num_ppcs; + u32 offset; + u32 sys_priv_offset, gpc_priv_offset; + u32 ppc_mask, reg_list_ppc_count; + u8 *context; + u32 offset_to_segment, offset_in_segment = 0; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "addr=0x%x", addr); + + err = g->ops.gr.decode_priv_addr(g, addr, &addr_type, + &gpc_num, &tpc_num, &ppc_num, &be_num, + &broadcast_flags); + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, + "addr_type = %d, broadcast_flags: %08x", + addr_type, broadcast_flags); + if (err != 0) { + return err; + } + + context = (u8 *)context_buffer; + if (!check_main_image_header_magic(context)) { + nvgpu_err(g, + "Invalid main header: magic value"); + return -EINVAL; + } + num_gpcs = *(u32 *)(context + ctxsw_prog_main_image_num_gpcs_o()); + + /* Parse the FECS local header. */ + context += ctxsw_prog_ucode_header_size_in_bytes(); + if (!check_local_header_magic(context)) { + nvgpu_err(g, + "Invalid FECS local header: magic value"); + return -EINVAL; + } + data32 = *(u32 *)(context + ctxsw_prog_local_priv_register_ctl_o()); + sys_priv_offset = ctxsw_prog_local_priv_register_ctl_offset_v(data32); + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "sys_priv_offset=0x%x", sys_priv_offset); + + /* If found in Ext buffer, ok. + * If it failed and we expected to find it there (quad offset) + * then return the error. Otherwise continue on. + */ + err = gr_gk20a_find_priv_offset_in_ext_buffer(g, + addr, is_quad, quad, context_buffer, + context_buffer_size, priv_offset); + if ((err == 0) || ((err != 0) && is_quad)) { + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, + "err = %d, is_quad = %s", + err, is_quad ? "true" : "false"); + return err; + } + + if ((addr_type == CTXSW_ADDR_TYPE_SYS) || + (addr_type == CTXSW_ADDR_TYPE_BE)) { + /* Find the offset in the FECS segment. */ + offset_to_segment = sys_priv_offset * + ctxsw_prog_ucode_header_size_in_bytes(); + + err = gr_gk20a_process_context_buffer_priv_segment(g, + addr_type, addr, + 0, 0, 0, 0, + &offset); + if (err != 0) { + return err; + } + + *priv_offset = (offset_to_segment + offset); + return 0; + } + + if ((gpc_num + 1) > num_gpcs) { + nvgpu_err(g, + "GPC %d not in this context buffer.", + gpc_num); + return -EINVAL; + } + + /* Parse the GPCCS local header(s).*/ + for (i = 0; i < num_gpcs; i++) { + context += ctxsw_prog_ucode_header_size_in_bytes(); + if (!check_local_header_magic(context)) { + nvgpu_err(g, + "Invalid GPCCS local header: magic value"); + return -EINVAL; + + } + data32 = *(u32 *)(context + ctxsw_prog_local_priv_register_ctl_o()); + gpc_priv_offset = ctxsw_prog_local_priv_register_ctl_offset_v(data32); + + err = gr_gk20a_determine_ppc_configuration(g, context, + &num_ppcs, &ppc_mask, + ®_list_ppc_count); + if (err != 0) { + nvgpu_err(g, "determine ppc configuration failed"); + return err; + } + + + num_tpcs = *(u32 *)(context + ctxsw_prog_local_image_num_tpcs_o()); + + if ((i == gpc_num) && ((tpc_num + 1) > num_tpcs)) { + nvgpu_err(g, + "GPC %d TPC %d not in this context buffer.", + gpc_num, tpc_num); + return -EINVAL; + } + + /* Find the offset in the GPCCS segment.*/ + if (i == gpc_num) { + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, + "gpc_priv_offset 0x%#08x", + gpc_priv_offset); + offset_to_segment = gpc_priv_offset * + ctxsw_prog_ucode_header_size_in_bytes(); + + err = g->ops.gr.get_offset_in_gpccs_segment(g, + addr_type, + num_tpcs, num_ppcs, reg_list_ppc_count, + &offset_in_segment); + if (err != 0) { + return -EINVAL; + } + + offset_to_segment += offset_in_segment; + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, + "offset_to_segment 0x%#08x", + offset_to_segment); + + err = gr_gk20a_process_context_buffer_priv_segment(g, + addr_type, addr, + i, num_tpcs, + num_ppcs, ppc_mask, + &offset); + if (err != 0) { + return -EINVAL; + } + + *priv_offset = offset_to_segment + offset; + return 0; + } + } + + return -EINVAL; +} + +static int map_cmp(const void *a, const void *b) +{ + struct ctxsw_buf_offset_map_entry *e1 = + (struct ctxsw_buf_offset_map_entry *)a; + struct ctxsw_buf_offset_map_entry *e2 = + (struct ctxsw_buf_offset_map_entry *)b; + + if (e1->addr < e2->addr) { + return -1; + } + + if (e1->addr > e2->addr) { + return 1; + } + return 0; +} + +static int add_ctxsw_buffer_map_entries_pmsys(struct ctxsw_buf_offset_map_entry *map, + struct aiv_list_gk20a *regs, + u32 *count, u32 *offset, + u32 max_cnt, u32 base, u32 mask) +{ + u32 idx; + u32 cnt = *count; + u32 off = *offset; + + if ((cnt + regs->count) > max_cnt) { + return -EINVAL; + } + + for (idx = 0; idx < regs->count; idx++) { + if ((base + (regs->l[idx].addr & mask)) < 0xFFF) { + map[cnt].addr = base + (regs->l[idx].addr & mask) + + NV_PCFG_BASE; + } else { + map[cnt].addr = base + (regs->l[idx].addr & mask); + } + map[cnt++].offset = off; + off += 4; + } + *count = cnt; + *offset = off; + return 0; +} + +static int add_ctxsw_buffer_map_entries_pmgpc(struct gk20a *g, + struct ctxsw_buf_offset_map_entry *map, + struct aiv_list_gk20a *regs, + u32 *count, u32 *offset, + u32 max_cnt, u32 base, u32 mask) +{ + u32 idx; + u32 cnt = *count; + u32 off = *offset; + + if ((cnt + regs->count) > max_cnt) { + return -EINVAL; + } + + /* NOTE: The PPC offsets get added to the pm_gpc list if numPpc <= 1 + * To handle the case of PPC registers getting added into GPC, the below + * code specifically checks for any PPC offsets and adds them using + * proper mask + */ + for (idx = 0; idx < regs->count; idx++) { + /* Check if the address is PPC address */ + if (pri_is_ppc_addr_shared(g, regs->l[idx].addr & mask)) { + u32 ppc_in_gpc_base = nvgpu_get_litter_value(g, + GPU_LIT_PPC_IN_GPC_BASE); + u32 ppc_in_gpc_stride = nvgpu_get_litter_value(g, + GPU_LIT_PPC_IN_GPC_STRIDE); + /* Use PPC mask instead of the GPC mask provided */ + u32 ppcmask = ppc_in_gpc_stride - 1; + + map[cnt].addr = base + ppc_in_gpc_base + + (regs->l[idx].addr & ppcmask); + } else { + map[cnt].addr = base + (regs->l[idx].addr & mask); + } + map[cnt++].offset = off; + off += 4; + } + *count = cnt; + *offset = off; + return 0; +} + +static int add_ctxsw_buffer_map_entries(struct ctxsw_buf_offset_map_entry *map, + struct aiv_list_gk20a *regs, + u32 *count, u32 *offset, + u32 max_cnt, u32 base, u32 mask) +{ + u32 idx; + u32 cnt = *count; + u32 off = *offset; + + if ((cnt + regs->count) > max_cnt) { + return -EINVAL; + } + + for (idx = 0; idx < regs->count; idx++) { + map[cnt].addr = base + (regs->l[idx].addr & mask); + map[cnt++].offset = off; + off += 4; + } + *count = cnt; + *offset = off; + return 0; +} + +/* Helper function to add register entries to the register map for all + * subunits + */ +static int add_ctxsw_buffer_map_entries_subunits( + struct ctxsw_buf_offset_map_entry *map, + struct aiv_list_gk20a *regs, + u32 *count, u32 *offset, + u32 max_cnt, u32 base, + u32 num_units, u32 stride, u32 mask) +{ + u32 unit; + u32 idx; + u32 cnt = *count; + u32 off = *offset; + + if ((cnt + (regs->count * num_units)) > max_cnt) { + return -EINVAL; + } + + /* Data is interleaved for units in ctxsw buffer */ + for (idx = 0; idx < regs->count; idx++) { + for (unit = 0; unit < num_units; unit++) { + map[cnt].addr = base + (regs->l[idx].addr & mask) + + (unit * stride); + map[cnt++].offset = off; + off += 4; + } + } + *count = cnt; + *offset = off; + return 0; +} + +int gr_gk20a_add_ctxsw_reg_pm_fbpa(struct gk20a *g, + struct ctxsw_buf_offset_map_entry *map, + struct aiv_list_gk20a *regs, + u32 *count, u32 *offset, + u32 max_cnt, u32 base, + u32 num_fbpas, u32 stride, u32 mask) +{ + return add_ctxsw_buffer_map_entries_subunits(map, regs, count, offset, + max_cnt, base, num_fbpas, stride, mask); +} + +static int add_ctxsw_buffer_map_entries_gpcs(struct gk20a *g, + struct ctxsw_buf_offset_map_entry *map, + u32 *count, u32 *offset, u32 max_cnt) +{ + u32 num_gpcs = g->gr.gpc_count; + u32 num_ppcs, num_tpcs, gpc_num, base; + u32 gpc_base = nvgpu_get_litter_value(g, GPU_LIT_GPC_BASE); + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 ppc_in_gpc_base = nvgpu_get_litter_value(g, GPU_LIT_PPC_IN_GPC_BASE); + u32 ppc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_PPC_IN_GPC_STRIDE); + u32 tpc_in_gpc_base = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_BASE); + u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); + + for (gpc_num = 0; gpc_num < num_gpcs; gpc_num++) { + num_tpcs = g->gr.gpc_tpc_count[gpc_num]; + base = gpc_base + (gpc_stride * gpc_num) + tpc_in_gpc_base; + if (add_ctxsw_buffer_map_entries_subunits(map, + &g->gr.ctx_vars.ctxsw_regs.pm_tpc, + count, offset, max_cnt, base, num_tpcs, + tpc_in_gpc_stride, + (tpc_in_gpc_stride - 1))) { + return -EINVAL; + } + + num_ppcs = g->gr.gpc_ppc_count[gpc_num]; + base = gpc_base + (gpc_stride * gpc_num) + ppc_in_gpc_base; + if (add_ctxsw_buffer_map_entries_subunits(map, + &g->gr.ctx_vars.ctxsw_regs.pm_ppc, + count, offset, max_cnt, base, num_ppcs, + ppc_in_gpc_stride, + (ppc_in_gpc_stride - 1))) { + return -EINVAL; + } + + base = gpc_base + (gpc_stride * gpc_num); + if (add_ctxsw_buffer_map_entries_pmgpc(g, map, + &g->gr.ctx_vars.ctxsw_regs.pm_gpc, + count, offset, max_cnt, base, + (gpc_stride - 1))) { + return -EINVAL; + } + + base = NV_XBAR_MXBAR_PRI_GPC_GNIC_STRIDE * gpc_num; + if (add_ctxsw_buffer_map_entries(map, + &g->gr.ctx_vars.ctxsw_regs.pm_ucgpc, + count, offset, max_cnt, base, ~0)) { + return -EINVAL; + } + + base = (g->ops.gr.get_pmm_per_chiplet_offset() * gpc_num); + if (add_ctxsw_buffer_map_entries(map, + &g->gr.ctx_vars.ctxsw_regs.perf_gpc, + count, offset, max_cnt, base, ~0)) { + return -EINVAL; + } + + base = (NV_PERF_PMMGPCROUTER_STRIDE * gpc_num); + if (add_ctxsw_buffer_map_entries(map, + &g->gr.ctx_vars.ctxsw_regs.gpc_router, + count, offset, max_cnt, base, ~0)) { + return -EINVAL; + } + + /* Counter Aggregation Unit, if available */ + if (g->gr.ctx_vars.ctxsw_regs.pm_cau.count) { + base = gpc_base + (gpc_stride * gpc_num) + + tpc_in_gpc_base; + if (add_ctxsw_buffer_map_entries_subunits(map, + &g->gr.ctx_vars.ctxsw_regs.pm_cau, + count, offset, max_cnt, base, num_tpcs, + tpc_in_gpc_stride, + (tpc_in_gpc_stride - 1))) { + return -EINVAL; + } + } + + *offset = ALIGN(*offset, 256); + } + return 0; +} + +int gr_gk20a_add_ctxsw_reg_perf_pma(struct ctxsw_buf_offset_map_entry *map, + struct aiv_list_gk20a *regs, + u32 *count, u32 *offset, + u32 max_cnt, u32 base, u32 mask) +{ + return add_ctxsw_buffer_map_entries(map, regs, + count, offset, max_cnt, base, mask); +} + +/* + * PM CTXSW BUFFER LAYOUT : + *|---------------------------------------------|0x00 <----PM CTXSW BUFFER BASE + *| | + *| LIST_compressed_pm_ctx_reg_SYS |Space allocated: numRegs words + *|---------------------------------------------| + *| | + *| LIST_compressed_nv_perf_ctx_reg_SYS |Space allocated: numRegs words + *|---------------------------------------------| + *| | + *| LIST_compressed_nv_perf_ctx_reg_sysrouter|Space allocated: numRegs words + *|---------------------------------------------| + *| | + *| LIST_compressed_nv_perf_ctx_reg_PMA |Space allocated: numRegs words + *|---------------------------------------------| + *| PADDING for 256 byte alignment | + *|---------------------------------------------|<----256 byte aligned + *| LIST_compressed_nv_perf_fbp_ctx_regs | + *| |Space allocated: numRegs * n words (for n FB units) + *|---------------------------------------------| + *| LIST_compressed_nv_perf_fbprouter_ctx_regs | + *| |Space allocated: numRegs * n words (for n FB units) + *|---------------------------------------------| + *| LIST_compressed_pm_fbpa_ctx_regs | + *| |Space allocated: numRegs * n words (for n FB units) + *|---------------------------------------------| + *| LIST_compressed_pm_rop_ctx_regs | + *|---------------------------------------------| + *| LIST_compressed_pm_ltc_ctx_regs | + *| LTC0 LTS0 | + *| LTC1 LTS0 |Space allocated: numRegs * n words (for n LTC units) + *| LTCn LTS0 | + *| LTC0 LTS1 | + *| LTC1 LTS1 | + *| LTCn LTS1 | + *| LTC0 LTSn | + *| LTC1 LTSn | + *| LTCn LTSn | + *|---------------------------------------------| + *| PADDING for 256 byte alignment | + *|---------------------------------------------|<----256 byte aligned + *| GPC0 REG0 TPC0 |Each GPC has space allocated to accommodate + *| REG0 TPC1 | all the GPC/TPC register lists + *| Lists in each GPC region: REG0 TPCn |Per GPC allocated space is always 256 byte aligned + *| LIST_pm_ctx_reg_TPC REG1 TPC0 | + *| * numTpcs REG1 TPC1 | + *| LIST_pm_ctx_reg_PPC REG1 TPCn | + *| * numPpcs REGn TPC0 | + *| LIST_pm_ctx_reg_GPC REGn TPC1 | + *| List_pm_ctx_reg_uc_GPC REGn TPCn | + *| LIST_nv_perf_ctx_reg_GPC | + *| LIST_nv_perf_gpcrouter_ctx_reg | + *| LIST_nv_perf_ctx_reg_CAU | + *| ---- |-- + *| GPC1 . | + *| . |<---- + *|---------------------------------------------| + *= = + *| GPCn | + *= = + *|---------------------------------------------| + */ + +static int gr_gk20a_create_hwpm_ctxsw_buffer_offset_map(struct gk20a *g) +{ + u32 hwpm_ctxsw_buffer_size = g->gr.ctx_vars.pm_ctxsw_image_size; + u32 hwpm_ctxsw_reg_count_max; + u32 map_size; + u32 i, count = 0; + u32 offset = 0; + struct ctxsw_buf_offset_map_entry *map; + u32 ltc_stride = nvgpu_get_litter_value(g, GPU_LIT_LTC_STRIDE); + u32 num_fbpas = nvgpu_get_litter_value(g, GPU_LIT_NUM_FBPAS); + u32 fbpa_stride = nvgpu_get_litter_value(g, GPU_LIT_FBPA_STRIDE); + u32 num_ltc = g->ops.gr.get_max_ltc_per_fbp(g) * g->gr.num_fbps; + + if (hwpm_ctxsw_buffer_size == 0) { + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, + "no PM Ctxsw buffer memory in context buffer"); + return -EINVAL; + } + + hwpm_ctxsw_reg_count_max = hwpm_ctxsw_buffer_size >> 2; + map_size = hwpm_ctxsw_reg_count_max * sizeof(*map); + + map = nvgpu_big_zalloc(g, map_size); + if (map == NULL) { + return -ENOMEM; + } + + /* Add entries from _LIST_pm_ctx_reg_SYS */ + if (add_ctxsw_buffer_map_entries_pmsys(map, &g->gr.ctx_vars.ctxsw_regs.pm_sys, + &count, &offset, hwpm_ctxsw_reg_count_max, 0, ~0)) { + goto cleanup; + } + + /* Add entries from _LIST_nv_perf_ctx_reg_SYS */ + if (add_ctxsw_buffer_map_entries(map, &g->gr.ctx_vars.ctxsw_regs.perf_sys, + &count, &offset, hwpm_ctxsw_reg_count_max, 0, ~0)) { + goto cleanup; + } + + /* Add entries from _LIST_nv_perf_sysrouter_ctx_reg*/ + if (add_ctxsw_buffer_map_entries(map, &g->gr.ctx_vars.ctxsw_regs.perf_sys_router, + &count, &offset, hwpm_ctxsw_reg_count_max, 0, ~0)) { + goto cleanup; + } + + /* Add entries from _LIST_nv_perf_pma_ctx_reg*/ + if (g->ops.gr.add_ctxsw_reg_perf_pma(map, &g->gr.ctx_vars.ctxsw_regs.perf_pma, + &count, &offset, hwpm_ctxsw_reg_count_max, 0, ~0)) { + goto cleanup; + } + + offset = ALIGN(offset, 256); + + /* Add entries from _LIST_nv_perf_fbp_ctx_regs */ + if (add_ctxsw_buffer_map_entries_subunits(map, + &g->gr.ctx_vars.ctxsw_regs.fbp, + &count, &offset, + hwpm_ctxsw_reg_count_max, 0, + g->gr.num_fbps, + g->ops.gr.get_pmm_per_chiplet_offset(), + ~0)) { + goto cleanup; + } + + /* Add entries from _LIST_nv_perf_fbprouter_ctx_regs */ + if (add_ctxsw_buffer_map_entries_subunits(map, + &g->gr.ctx_vars.ctxsw_regs.fbp_router, + &count, &offset, + hwpm_ctxsw_reg_count_max, 0, g->gr.num_fbps, + NV_PERF_PMM_FBP_ROUTER_STRIDE, ~0)) { + goto cleanup; + } + + /* Add entries from _LIST_nv_pm_fbpa_ctx_regs */ + if (g->ops.gr.add_ctxsw_reg_pm_fbpa(g, map, + &g->gr.ctx_vars.ctxsw_regs.pm_fbpa, + &count, &offset, + hwpm_ctxsw_reg_count_max, 0, + num_fbpas, fbpa_stride, ~0)) { + goto cleanup; + } + + /* Add entries from _LIST_nv_pm_rop_ctx_regs */ + if (add_ctxsw_buffer_map_entries(map, + &g->gr.ctx_vars.ctxsw_regs.pm_rop, + &count, &offset, + hwpm_ctxsw_reg_count_max, 0, ~0)) { + goto cleanup; + } + + /* Add entries from _LIST_compressed_nv_pm_ltc_ctx_regs */ + if (add_ctxsw_buffer_map_entries_subunits(map, + &g->gr.ctx_vars.ctxsw_regs.pm_ltc, + &count, &offset, + hwpm_ctxsw_reg_count_max, 0, + num_ltc, ltc_stride, ~0)) { + goto cleanup; + } + + offset = ALIGN(offset, 256); + + /* Add GPC entries */ + if (add_ctxsw_buffer_map_entries_gpcs(g, map, &count, &offset, + hwpm_ctxsw_reg_count_max)) { + goto cleanup; + } + + if (offset > hwpm_ctxsw_buffer_size) { + nvgpu_err(g, "offset > buffer size"); + goto cleanup; + } + + sort(map, count, sizeof(*map), map_cmp, NULL); + + g->gr.ctx_vars.hwpm_ctxsw_buffer_offset_map = map; + g->gr.ctx_vars.hwpm_ctxsw_buffer_offset_map_count = count; + + nvgpu_log_info(g, "Reg Addr => HWPM Ctxt switch buffer offset"); + + for (i = 0; i < count; i++) { + nvgpu_log_info(g, "%08x => %08x", map[i].addr, map[i].offset); + } + + return 0; +cleanup: + nvgpu_err(g, "Failed to create HWPM buffer offset map"); + nvgpu_big_free(g, map); + return -EINVAL; +} + +/* + * This function will return the 32 bit offset for a priv register if it is + * present in the PM context buffer. + */ +static int gr_gk20a_find_priv_offset_in_pm_buffer(struct gk20a *g, + u32 addr, + u32 *priv_offset) +{ + struct gr_gk20a *gr = &g->gr; + int err = 0; + u32 count; + struct ctxsw_buf_offset_map_entry *map, *result, map_key; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "addr=0x%x", addr); + + /* Create map of pri address and pm offset if necessary */ + if (gr->ctx_vars.hwpm_ctxsw_buffer_offset_map == NULL) { + err = gr_gk20a_create_hwpm_ctxsw_buffer_offset_map(g); + if (err != 0) { + return err; + } + } + + *priv_offset = 0; + + map = gr->ctx_vars.hwpm_ctxsw_buffer_offset_map; + count = gr->ctx_vars.hwpm_ctxsw_buffer_offset_map_count; + + map_key.addr = addr; + result = bsearch(&map_key, map, count, sizeof(*map), map_cmp); + + if (result) { + *priv_offset = result->offset; + } else { + nvgpu_err(g, "Lookup failed for address 0x%x", addr); + err = -EINVAL; + } + return err; +} + +bool gk20a_is_channel_ctx_resident(struct channel_gk20a *ch) +{ + int curr_gr_ctx; + u32 curr_gr_tsgid; + struct gk20a *g = ch->g; + struct channel_gk20a *curr_ch; + bool ret = false; + struct tsg_gk20a *tsg; + + curr_gr_ctx = gk20a_readl(g, gr_fecs_current_ctx_r()); + + /* when contexts are unloaded from GR, the valid bit is reset + * but the instance pointer information remains intact. So the + * valid bit must be checked to be absolutely certain that a + * valid context is currently resident. + */ + if (gr_fecs_current_ctx_valid_v(curr_gr_ctx) == 0U) { + return NULL; + } + + curr_ch = gk20a_gr_get_channel_from_ctx(g, curr_gr_ctx, + &curr_gr_tsgid); + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, + "curr_gr_chid=%d curr_tsgid=%d, ch->tsgid=%d" + " ch->chid=%d", + (curr_ch != NULL) ? curr_ch->chid : U32_MAX, + curr_gr_tsgid, + ch->tsgid, + ch->chid); + + if (curr_ch == NULL) { + return false; + } + + if (ch->chid == curr_ch->chid) { + ret = true; + } + + tsg = tsg_gk20a_from_ch(ch); + if ((tsg != NULL) && (tsg->tsgid == curr_gr_tsgid)) { + ret = true; + } + + gk20a_channel_put(curr_ch); + return ret; +} + +int __gr_gk20a_exec_ctx_ops(struct channel_gk20a *ch, + struct nvgpu_dbg_reg_op *ctx_ops, u32 num_ops, + u32 num_ctx_wr_ops, u32 num_ctx_rd_ops, + bool ch_is_curr_ctx) +{ + struct gk20a *g = ch->g; + struct tsg_gk20a *tsg; + struct nvgpu_gr_ctx *gr_ctx; + bool gr_ctx_ready = false; + bool pm_ctx_ready = false; + struct nvgpu_mem *current_mem = NULL; + u32 i, j, offset, v; + struct gr_gk20a *gr = &g->gr; + u32 sm_per_tpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_SM_PER_TPC); + u32 max_offsets = gr->max_gpc_count * gr->max_tpc_per_gpc_count * + sm_per_tpc; + u32 *offsets = NULL; + u32 *offset_addrs = NULL; + u32 ctx_op_nr, num_ctx_ops[2] = {num_ctx_wr_ops, num_ctx_rd_ops}; + int err = 0, pass; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "wr_ops=%d rd_ops=%d", + num_ctx_wr_ops, num_ctx_rd_ops); + + tsg = tsg_gk20a_from_ch(ch); + if (tsg == NULL) { + return -EINVAL; + } + + gr_ctx = &tsg->gr_ctx; + + if (ch_is_curr_ctx) { + for (pass = 0; pass < 2; pass++) { + ctx_op_nr = 0; + for (i = 0; (ctx_op_nr < num_ctx_ops[pass]) && (i < num_ops); ++i) { + /* only do ctx ops and only on the right pass */ + if ((ctx_ops[i].type == REGOP(TYPE_GLOBAL)) || + (((pass == 0) && reg_op_is_read(ctx_ops[i].op)) || + ((pass == 1) && !reg_op_is_read(ctx_ops[i].op)))) { + continue; + } + + /* if this is a quad access, setup for special access*/ + if ((ctx_ops[i].type == REGOP(TYPE_GR_CTX_QUAD)) + && (g->ops.gr.access_smpc_reg != NULL)) { + g->ops.gr.access_smpc_reg(g, + ctx_ops[i].quad, + ctx_ops[i].offset); + } + offset = ctx_ops[i].offset; + + if (pass == 0) { /* write pass */ + v = gk20a_readl(g, offset); + v &= ~ctx_ops[i].and_n_mask_lo; + v |= ctx_ops[i].value_lo; + gk20a_writel(g, offset, v); + + nvgpu_log(g, gpu_dbg_gpu_dbg, + "direct wr: offset=0x%x v=0x%x", + offset, v); + + if (ctx_ops[i].op == REGOP(WRITE_64)) { + v = gk20a_readl(g, offset + 4); + v &= ~ctx_ops[i].and_n_mask_hi; + v |= ctx_ops[i].value_hi; + gk20a_writel(g, offset + 4, v); + + nvgpu_log(g, gpu_dbg_gpu_dbg, + "direct wr: offset=0x%x v=0x%x", + offset + 4, v); + } + + } else { /* read pass */ + ctx_ops[i].value_lo = + gk20a_readl(g, offset); + + nvgpu_log(g, gpu_dbg_gpu_dbg, + "direct rd: offset=0x%x v=0x%x", + offset, ctx_ops[i].value_lo); + + if (ctx_ops[i].op == REGOP(READ_64)) { + ctx_ops[i].value_hi = + gk20a_readl(g, offset + 4); + + nvgpu_log(g, gpu_dbg_gpu_dbg, + "direct rd: offset=0x%x v=0x%x", + offset, ctx_ops[i].value_lo); + } else { + ctx_ops[i].value_hi = 0; + } + } + ctx_op_nr++; + } + } + goto cleanup; + } + + /* they're the same size, so just use one alloc for both */ + offsets = nvgpu_kzalloc(g, 2 * sizeof(u32) * max_offsets); + if (offsets == NULL) { + err = -ENOMEM; + goto cleanup; + } + offset_addrs = offsets + max_offsets; + + err = gr_gk20a_ctx_patch_write_begin(g, gr_ctx, false); + if (err != 0) { + goto cleanup; + } + + g->ops.mm.l2_flush(g, true); + + /* write to appropriate place in context image, + * first have to figure out where that really is */ + + /* first pass is writes, second reads */ + for (pass = 0; pass < 2; pass++) { + ctx_op_nr = 0; + for (i = 0; (ctx_op_nr < num_ctx_ops[pass]) && (i < num_ops); ++i) { + u32 num_offsets; + + /* only do ctx ops and only on the right pass */ + if ((ctx_ops[i].type == REGOP(TYPE_GLOBAL)) || + (((pass == 0) && reg_op_is_read(ctx_ops[i].op)) || + ((pass == 1) && !reg_op_is_read(ctx_ops[i].op)))) { + continue; + } + + err = gr_gk20a_get_ctx_buffer_offsets(g, + ctx_ops[i].offset, + max_offsets, + offsets, offset_addrs, + &num_offsets, + ctx_ops[i].type == REGOP(TYPE_GR_CTX_QUAD), + ctx_ops[i].quad); + if (err == 0) { + if (!gr_ctx_ready) { + gr_ctx_ready = true; + } + current_mem = &gr_ctx->mem; + } else { + err = gr_gk20a_get_pm_ctx_buffer_offsets(g, + ctx_ops[i].offset, + max_offsets, + offsets, offset_addrs, + &num_offsets); + if (err != 0) { + nvgpu_log(g, gpu_dbg_gpu_dbg, + "ctx op invalid offset: offset=0x%x", + ctx_ops[i].offset); + ctx_ops[i].status = + REGOP(STATUS_INVALID_OFFSET); + continue; + } + if (!pm_ctx_ready) { + /* Make sure ctx buffer was initialized */ + if (!nvgpu_mem_is_valid(&gr_ctx->pm_ctx.mem)) { + nvgpu_err(g, + "Invalid ctx buffer"); + err = -EINVAL; + goto cleanup; + } + pm_ctx_ready = true; + } + current_mem = &gr_ctx->pm_ctx.mem; + } + + /* if this is a quad access, setup for special access*/ + if ((ctx_ops[i].type == REGOP(TYPE_GR_CTX_QUAD)) && + (g->ops.gr.access_smpc_reg != NULL)) { + g->ops.gr.access_smpc_reg(g, ctx_ops[i].quad, + ctx_ops[i].offset); + } + + for (j = 0; j < num_offsets; j++) { + /* sanity check gr ctxt offsets, + * don't write outside, worst case + */ + if ((current_mem == &gr_ctx->mem) && + (offsets[j] >= g->gr.ctx_vars.golden_image_size)) { + continue; + } + if (pass == 0) { /* write pass */ + v = nvgpu_mem_rd(g, current_mem, offsets[j]); + v &= ~ctx_ops[i].and_n_mask_lo; + v |= ctx_ops[i].value_lo; + nvgpu_mem_wr(g, current_mem, offsets[j], v); + + nvgpu_log(g, gpu_dbg_gpu_dbg, + "context wr: offset=0x%x v=0x%x", + offsets[j], v); + + if (ctx_ops[i].op == REGOP(WRITE_64)) { + v = nvgpu_mem_rd(g, current_mem, offsets[j] + 4); + v &= ~ctx_ops[i].and_n_mask_hi; + v |= ctx_ops[i].value_hi; + nvgpu_mem_wr(g, current_mem, offsets[j] + 4, v); + + nvgpu_log(g, gpu_dbg_gpu_dbg, + "context wr: offset=0x%x v=0x%x", + offsets[j] + 4, v); + } + + /* check to see if we need to add a special WAR + for some of the SMPC perf regs */ + gr_gk20a_ctx_patch_smpc(g, ch, offset_addrs[j], + v, current_mem); + + } else { /* read pass */ + ctx_ops[i].value_lo = + nvgpu_mem_rd(g, current_mem, offsets[0]); + + nvgpu_log(g, gpu_dbg_gpu_dbg, "context rd: offset=0x%x v=0x%x", + offsets[0], ctx_ops[i].value_lo); + + if (ctx_ops[i].op == REGOP(READ_64)) { + ctx_ops[i].value_hi = + nvgpu_mem_rd(g, current_mem, offsets[0] + 4); + + nvgpu_log(g, gpu_dbg_gpu_dbg, + "context rd: offset=0x%x v=0x%x", + offsets[0] + 4, ctx_ops[i].value_hi); + } else { + ctx_ops[i].value_hi = 0; + } + } + } + ctx_op_nr++; + } + } + + cleanup: + if (offsets) { + nvgpu_kfree(g, offsets); + } + + if (gr_ctx->patch_ctx.mem.cpu_va) { + gr_gk20a_ctx_patch_write_end(g, gr_ctx, gr_ctx_ready); + } + + return err; +} + +int gr_gk20a_exec_ctx_ops(struct channel_gk20a *ch, + struct nvgpu_dbg_reg_op *ctx_ops, u32 num_ops, + u32 num_ctx_wr_ops, u32 num_ctx_rd_ops, + bool *is_curr_ctx) +{ + struct gk20a *g = ch->g; + int err, tmp_err; + bool ch_is_curr_ctx; + + /* disable channel switching. + * at that point the hardware state can be inspected to + * determine if the context we're interested in is current. + */ + err = gr_gk20a_disable_ctxsw(g); + if (err != 0) { + nvgpu_err(g, "unable to stop gr ctxsw"); + /* this should probably be ctx-fatal... */ + return err; + } + + ch_is_curr_ctx = gk20a_is_channel_ctx_resident(ch); + if (is_curr_ctx != NULL) { + *is_curr_ctx = ch_is_curr_ctx; + } + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "is curr ctx=%d", + ch_is_curr_ctx); + + err = __gr_gk20a_exec_ctx_ops(ch, ctx_ops, num_ops, num_ctx_wr_ops, + num_ctx_rd_ops, ch_is_curr_ctx); + + tmp_err = gr_gk20a_enable_ctxsw(g); + if (tmp_err) { + nvgpu_err(g, "unable to restart ctxsw!"); + err = tmp_err; + } + + return err; +} + +void gr_gk20a_commit_global_pagepool(struct gk20a *g, + struct nvgpu_gr_ctx *gr_ctx, + u64 addr, u32 size, bool patch) +{ + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_scc_pagepool_base_r(), + gr_scc_pagepool_base_addr_39_8_f(addr), patch); + + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_scc_pagepool_r(), + gr_scc_pagepool_total_pages_f(size) | + gr_scc_pagepool_valid_true_f(), patch); + + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_gpcs_gcc_pagepool_base_r(), + gr_gpcs_gcc_pagepool_base_addr_39_8_f(addr), patch); + + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_gpcs_gcc_pagepool_r(), + gr_gpcs_gcc_pagepool_total_pages_f(size), patch); + + gr_gk20a_ctx_patch_write(g, gr_ctx, gr_pd_pagepool_r(), + gr_pd_pagepool_total_pages_f(size) | + gr_pd_pagepool_valid_true_f(), patch); +} + +void gk20a_init_gr(struct gk20a *g) +{ + nvgpu_cond_init(&g->gr.init_wq); +} + +int gk20a_gr_wait_for_sm_lock_down(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, + u32 global_esr_mask, bool check_errors) +{ + bool locked_down; + bool no_error_pending; + u32 delay = GR_IDLE_CHECK_DEFAULT; + bool mmu_debug_mode_enabled = g->ops.fb.is_debug_mode_enabled(g); + u32 offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc); + u32 dbgr_status0 = 0, dbgr_control0 = 0; + u64 warps_valid = 0, warps_paused = 0, warps_trapped = 0; + struct nvgpu_timeout timeout; + u32 warp_esr; + + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "GPC%d TPC%d SM%d: locking down SM", gpc, tpc, sm); + + nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); + + /* wait for the sm to lock down */ + do { + u32 global_esr = g->ops.gr.get_sm_hww_global_esr(g, + gpc, tpc, sm); + dbgr_status0 = gk20a_readl(g, + gr_gpc0_tpc0_sm_dbgr_status0_r() + offset); + + warp_esr = g->ops.gr.get_sm_hww_warp_esr(g, gpc, tpc, sm); + + locked_down = + (gr_gpc0_tpc0_sm_dbgr_status0_locked_down_v(dbgr_status0) == + gr_gpc0_tpc0_sm_dbgr_status0_locked_down_true_v()); + no_error_pending = + check_errors && + (gr_gpc0_tpc0_sm_hww_warp_esr_error_v(warp_esr) == + gr_gpc0_tpc0_sm_hww_warp_esr_error_none_v()) && + ((global_esr & ~global_esr_mask) == 0); + + if (locked_down || no_error_pending) { + nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, + "GPC%d TPC%d SM%d: locked down SM", + gpc, tpc, sm); + return 0; + } + + /* if an mmu fault is pending and mmu debug mode is not + * enabled, the sm will never lock down. */ + if (!mmu_debug_mode_enabled && + (g->ops.mm.mmu_fault_pending(g))) { + nvgpu_err(g, + "GPC%d TPC%d: mmu fault pending," + " SM%d will never lock down!", gpc, tpc, sm); + return -EFAULT; + } + + nvgpu_usleep_range(delay, delay * 2); + delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); + } while (nvgpu_timeout_expired(&timeout) == 0); + + dbgr_control0 = gk20a_readl(g, + gr_gpc0_tpc0_sm_dbgr_control0_r() + offset); + + /* 64 bit read */ + warps_valid = (u64)gk20a_readl(g, gr_gpc0_tpc0_sm_warp_valid_mask_1_r() + offset) << 32; + warps_valid |= gk20a_readl(g, gr_gpc0_tpc0_sm_warp_valid_mask_r() + offset); + + /* 64 bit read */ + warps_paused = (u64)gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_1_r() + offset) << 32; + warps_paused |= gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_r() + offset); + + /* 64 bit read */ + warps_trapped = (u64)gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_1_r() + offset) << 32; + warps_trapped |= gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_r() + offset); + + nvgpu_err(g, + "GPC%d TPC%d: timed out while trying to lock down SM", gpc, tpc); + nvgpu_err(g, + "STATUS0(0x%x)=0x%x CONTROL0=0x%x VALID_MASK=0x%llx PAUSE_MASK=0x%llx TRAP_MASK=0x%llx", + gr_gpc0_tpc0_sm_dbgr_status0_r() + offset, dbgr_status0, dbgr_control0, + warps_valid, warps_paused, warps_trapped); + + return -ETIMEDOUT; +} + +void gk20a_gr_suspend_single_sm(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm, + u32 global_esr_mask, bool check_errors) +{ + int err; + u32 dbgr_control0; + u32 offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc); + + /* if an SM debugger isn't attached, skip suspend */ + if (!g->ops.gr.sm_debugger_attached(g)) { + nvgpu_err(g, + "SM debugger not attached, skipping suspend!"); + return; + } + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, + "suspending gpc:%d, tpc:%d, sm%d", gpc, tpc, sm); + + /* assert stop trigger. */ + dbgr_control0 = gk20a_readl(g, + gr_gpc0_tpc0_sm_dbgr_control0_r() + offset); + dbgr_control0 |= gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_enable_f(); + gk20a_writel(g, gr_gpc0_tpc0_sm_dbgr_control0_r() + offset, + dbgr_control0); + + err = g->ops.gr.wait_for_sm_lock_down(g, gpc, tpc, sm, + global_esr_mask, check_errors); + if (err != 0) { + nvgpu_err(g, + "SuspendSm failed"); + return; + } +} + +void gk20a_gr_suspend_all_sms(struct gk20a *g, + u32 global_esr_mask, bool check_errors) +{ + struct gr_gk20a *gr = &g->gr; + u32 gpc, tpc, sm; + int err; + u32 dbgr_control0; + u32 sm_per_tpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_SM_PER_TPC); + + /* if an SM debugger isn't attached, skip suspend */ + if (!g->ops.gr.sm_debugger_attached(g)) { + nvgpu_err(g, + "SM debugger not attached, skipping suspend!"); + return; + } + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "suspending all sms"); + /* assert stop trigger. uniformity assumption: all SMs will have + * the same state in dbg_control0. + */ + dbgr_control0 = + gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_control0_r()); + dbgr_control0 |= gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_enable_f(); + + /* broadcast write */ + gk20a_writel(g, + gr_gpcs_tpcs_sm_dbgr_control0_r(), dbgr_control0); + + for (gpc = 0; gpc < gr->gpc_count; gpc++) { + for (tpc = 0; tpc < gr_gk20a_get_tpc_count(gr, gpc); tpc++) { + for (sm = 0; sm < sm_per_tpc; sm++) { + err = g->ops.gr.wait_for_sm_lock_down(g, + gpc, tpc, sm, + global_esr_mask, check_errors); + if (err != 0) { + nvgpu_err(g, "SuspendAllSms failed"); + return; + } + } + } + } +} + +void gk20a_gr_resume_single_sm(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm) +{ + u32 dbgr_control0; + u32 offset; + /* + * The following requires some clarification. Despite the fact that both + * RUN_TRIGGER and STOP_TRIGGER have the word "TRIGGER" in their + * names, only one is actually a trigger, and that is the STOP_TRIGGER. + * Merely writing a 1(_TASK) to the RUN_TRIGGER is not sufficient to + * resume the gpu - the _STOP_TRIGGER must explicitly be set to 0 + * (_DISABLE) as well. + + * Advice from the arch group: Disable the stop trigger first, as a + * separate operation, in order to ensure that the trigger has taken + * effect, before enabling the run trigger. + */ + + offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc); + + /*De-assert stop trigger */ + dbgr_control0 = + gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_control0_r() + offset); + dbgr_control0 = set_field(dbgr_control0, + gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_m(), + gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_disable_f()); + gk20a_writel(g, + gr_gpc0_tpc0_sm_dbgr_control0_r() + offset, dbgr_control0); + + /* Run trigger */ + dbgr_control0 |= gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_task_f(); + gk20a_writel(g, + gr_gpc0_tpc0_sm_dbgr_control0_r() + offset, dbgr_control0); +} + +void gk20a_gr_resume_all_sms(struct gk20a *g) +{ + u32 dbgr_control0; + /* + * The following requires some clarification. Despite the fact that both + * RUN_TRIGGER and STOP_TRIGGER have the word "TRIGGER" in their + * names, only one is actually a trigger, and that is the STOP_TRIGGER. + * Merely writing a 1(_TASK) to the RUN_TRIGGER is not sufficient to + * resume the gpu - the _STOP_TRIGGER must explicitly be set to 0 + * (_DISABLE) as well. + + * Advice from the arch group: Disable the stop trigger first, as a + * separate operation, in order to ensure that the trigger has taken + * effect, before enabling the run trigger. + */ + + /*De-assert stop trigger */ + dbgr_control0 = + gk20a_readl(g, gr_gpcs_tpcs_sm_dbgr_control0_r()); + dbgr_control0 &= ~gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_enable_f(); + gk20a_writel(g, + gr_gpcs_tpcs_sm_dbgr_control0_r(), dbgr_control0); + + /* Run trigger */ + dbgr_control0 |= gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_task_f(); + gk20a_writel(g, + gr_gpcs_tpcs_sm_dbgr_control0_r(), dbgr_control0); +} + +int gr_gk20a_set_sm_debug_mode(struct gk20a *g, + struct channel_gk20a *ch, u64 sms, bool enable) +{ + struct nvgpu_dbg_reg_op *ops; + unsigned int i = 0, sm_id; + int err; + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); + + ops = nvgpu_kcalloc(g, g->gr.no_of_sm, sizeof(*ops)); + if (ops == NULL) { + return -ENOMEM; + } + for (sm_id = 0; sm_id < g->gr.no_of_sm; sm_id++) { + int gpc, tpc; + u32 tpc_offset, gpc_offset, reg_offset, reg_mask, reg_val; + + if ((sms & BIT64(sm_id)) == 0ULL) { + continue; + } + + gpc = g->gr.sm_to_cluster[sm_id].gpc_index; + tpc = g->gr.sm_to_cluster[sm_id].tpc_index; + + tpc_offset = tpc_in_gpc_stride * tpc; + gpc_offset = gpc_stride * gpc; + reg_offset = tpc_offset + gpc_offset; + + ops[i].op = REGOP(WRITE_32); + ops[i].type = REGOP(TYPE_GR_CTX); + ops[i].offset = gr_gpc0_tpc0_sm_dbgr_control0_r() + reg_offset; + + reg_mask = 0; + reg_val = 0; + if (enable) { + reg_mask |= gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_m(); + reg_val |= gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_on_f(); + reg_mask |= gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_m(); + reg_val |= gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_disable_f(); + reg_mask |= gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_m(); + reg_val |= gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_disable_f(); + } else { + reg_mask |= gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_m(); + reg_val |= gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_off_f(); + } + + ops[i].and_n_mask_lo = reg_mask; + ops[i].value_lo = reg_val; + i++; + } + + err = gr_gk20a_exec_ctx_ops(ch, ops, i, i, 0, NULL); + if (err != 0) { + nvgpu_err(g, "Failed to access register"); + } + nvgpu_kfree(g, ops); + return err; +} + +/* + * gr_gk20a_suspend_context() + * This API should be called with dbg_session lock held + * and ctxsw disabled + * Returns bool value indicating if context was resident + * or not + */ +bool gr_gk20a_suspend_context(struct channel_gk20a *ch) +{ + struct gk20a *g = ch->g; + bool ctx_resident = false; + + if (gk20a_is_channel_ctx_resident(ch)) { + g->ops.gr.suspend_all_sms(g, 0, false); + ctx_resident = true; + } else { + gk20a_disable_channel_tsg(g, ch); + } + + return ctx_resident; +} + +bool gr_gk20a_resume_context(struct channel_gk20a *ch) +{ + struct gk20a *g = ch->g; + bool ctx_resident = false; + + if (gk20a_is_channel_ctx_resident(ch)) { + g->ops.gr.resume_all_sms(g); + ctx_resident = true; + } else { + gk20a_enable_channel_tsg(g, ch); + } + + return ctx_resident; +} + +int gr_gk20a_suspend_contexts(struct gk20a *g, + struct dbg_session_gk20a *dbg_s, + int *ctx_resident_ch_fd) +{ + int local_ctx_resident_ch_fd = -1; + bool ctx_resident; + struct channel_gk20a *ch; + struct dbg_session_channel_data *ch_data; + int err = 0; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + err = gr_gk20a_disable_ctxsw(g); + if (err != 0) { + nvgpu_err(g, "unable to stop gr ctxsw"); + goto clean_up; + } + + nvgpu_mutex_acquire(&dbg_s->ch_list_lock); + + nvgpu_list_for_each_entry(ch_data, &dbg_s->ch_list, + dbg_session_channel_data, ch_entry) { + ch = g->fifo.channel + ch_data->chid; + + ctx_resident = gr_gk20a_suspend_context(ch); + if (ctx_resident) { + local_ctx_resident_ch_fd = ch_data->channel_fd; + } + } + + nvgpu_mutex_release(&dbg_s->ch_list_lock); + + err = gr_gk20a_enable_ctxsw(g); + if (err != 0) { + nvgpu_err(g, "unable to restart ctxsw!"); + } + + *ctx_resident_ch_fd = local_ctx_resident_ch_fd; + +clean_up: + nvgpu_mutex_release(&g->dbg_sessions_lock); + + return err; +} + +int gr_gk20a_resume_contexts(struct gk20a *g, + struct dbg_session_gk20a *dbg_s, + int *ctx_resident_ch_fd) +{ + int local_ctx_resident_ch_fd = -1; + bool ctx_resident; + struct channel_gk20a *ch; + int err = 0; + struct dbg_session_channel_data *ch_data; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + err = gr_gk20a_disable_ctxsw(g); + if (err != 0) { + nvgpu_err(g, "unable to stop gr ctxsw"); + goto clean_up; + } + + nvgpu_list_for_each_entry(ch_data, &dbg_s->ch_list, + dbg_session_channel_data, ch_entry) { + ch = g->fifo.channel + ch_data->chid; + + ctx_resident = gr_gk20a_resume_context(ch); + if (ctx_resident) { + local_ctx_resident_ch_fd = ch_data->channel_fd; + } + } + + err = gr_gk20a_enable_ctxsw(g); + if (err != 0) { + nvgpu_err(g, "unable to restart ctxsw!"); + } + + *ctx_resident_ch_fd = local_ctx_resident_ch_fd; + +clean_up: + nvgpu_mutex_release(&g->dbg_sessions_lock); + + return err; +} + +int gr_gk20a_trigger_suspend(struct gk20a *g) +{ + int err = 0; + u32 dbgr_control0; + + /* assert stop trigger. uniformity assumption: all SMs will have + * the same state in dbg_control0. */ + dbgr_control0 = + gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_control0_r()); + dbgr_control0 |= gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_enable_f(); + + /* broadcast write */ + gk20a_writel(g, + gr_gpcs_tpcs_sm_dbgr_control0_r(), dbgr_control0); + + return err; +} + +int gr_gk20a_wait_for_pause(struct gk20a *g, struct nvgpu_warpstate *w_state) +{ + int err = 0; + struct gr_gk20a *gr = &g->gr; + u32 gpc, tpc, sm, sm_id; + u32 global_mask; + + /* Wait for the SMs to reach full stop. This condition is: + * 1) All SMs with valid warps must be in the trap handler (SM_IN_TRAP_MODE) + * 2) All SMs in the trap handler must have equivalent VALID and PAUSED warp + * masks. + */ + global_mask = g->ops.gr.get_sm_no_lock_down_hww_global_esr_mask(g); + + /* Lock down all SMs */ + for (sm_id = 0; sm_id < gr->no_of_sm; sm_id++) { + + gpc = g->gr.sm_to_cluster[sm_id].gpc_index; + tpc = g->gr.sm_to_cluster[sm_id].tpc_index; + sm = g->gr.sm_to_cluster[sm_id].sm_index; + + err = g->ops.gr.lock_down_sm(g, gpc, tpc, sm, + global_mask, false); + if (err != 0) { + nvgpu_err(g, "sm did not lock down!"); + return err; + } + } + + /* Read the warp status */ + g->ops.gr.bpt_reg_info(g, w_state); + + return 0; +} + +int gr_gk20a_resume_from_pause(struct gk20a *g) +{ + int err = 0; + u32 reg_val; + + /* Clear the pause mask to tell the GPU we want to resume everyone */ + gk20a_writel(g, + gr_gpcs_tpcs_sm_dbgr_bpt_pause_mask_r(), 0); + + /* explicitly re-enable forwarding of SM interrupts upon any resume */ + reg_val = gk20a_readl(g, gr_gpc0_tpc0_tpccs_tpc_exception_en_r()); + reg_val |= gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_enabled_f(); + gk20a_writel(g, gr_gpcs_tpcs_tpccs_tpc_exception_en_r(), reg_val); + + /* Now resume all sms, write a 0 to the stop trigger + * then a 1 to the run trigger */ + g->ops.gr.resume_all_sms(g); + + return err; +} + +int gr_gk20a_clear_sm_errors(struct gk20a *g) +{ + int ret = 0; + u32 gpc, tpc, sm; + struct gr_gk20a *gr = &g->gr; + u32 global_esr; + u32 sm_per_tpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_SM_PER_TPC); + + for (gpc = 0; gpc < gr->gpc_count; gpc++) { + + /* check if any tpc has an exception */ + for (tpc = 0; tpc < gr->gpc_tpc_count[gpc]; tpc++) { + + for (sm = 0; sm < sm_per_tpc; sm++) { + global_esr = g->ops.gr.get_sm_hww_global_esr(g, + gpc, tpc, sm); + + /* clearing hwws, also causes tpc and gpc + * exceptions to be cleared + */ + g->ops.gr.clear_sm_hww(g, + gpc, tpc, sm, global_esr); + } + } + } + + return ret; +} + +u32 gr_gk20a_tpc_enabled_exceptions(struct gk20a *g) +{ + struct gr_gk20a *gr = &g->gr; + u32 sm_id, tpc_exception_en = 0; + u32 offset, regval, tpc_offset, gpc_offset; + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); + + for (sm_id = 0; sm_id < gr->no_of_sm; sm_id++) { + + tpc_offset = tpc_in_gpc_stride * g->gr.sm_to_cluster[sm_id].tpc_index; + gpc_offset = gpc_stride * g->gr.sm_to_cluster[sm_id].gpc_index; + offset = tpc_offset + gpc_offset; + + regval = gk20a_readl(g, gr_gpc0_tpc0_tpccs_tpc_exception_en_r() + + offset); + /* Each bit represents corresponding enablement state, bit 0 corrsponds to SM0 */ + tpc_exception_en |= gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_v(regval) << sm_id; + } + + return tpc_exception_en; +} + +u32 gk20a_gr_get_sm_hww_warp_esr(struct gk20a *g, u32 gpc, u32 tpc, u32 sm) +{ + u32 offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc); + u32 hww_warp_esr = gk20a_readl(g, + gr_gpc0_tpc0_sm_hww_warp_esr_r() + offset); + return hww_warp_esr; +} + +u32 gk20a_gr_get_sm_hww_global_esr(struct gk20a *g, u32 gpc, u32 tpc, u32 sm) +{ + u32 offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc); + + u32 hww_global_esr = gk20a_readl(g, + gr_gpc0_tpc0_sm_hww_global_esr_r() + offset); + + return hww_global_esr; +} + +u32 gk20a_gr_get_sm_no_lock_down_hww_global_esr_mask(struct gk20a *g) +{ + /* + * These three interrupts don't require locking down the SM. They can + * be handled by usermode clients as they aren't fatal. Additionally, + * usermode clients may wish to allow some warps to execute while others + * are at breakpoints, as opposed to fatal errors where all warps should + * halt. + */ + u32 global_esr_mask = + gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f() | + gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f() | + gr_gpc0_tpc0_sm_hww_global_esr_single_step_complete_pending_f(); + + return global_esr_mask; +} + +/* invalidate channel lookup tlb */ +void gk20a_gr_flush_channel_tlb(struct gr_gk20a *gr) +{ + nvgpu_spinlock_acquire(&gr->ch_tlb_lock); + memset(gr->chid_tlb, 0, + sizeof(struct gr_channel_map_tlb_entry) * + GR_CHANNEL_MAP_TLB_SIZE); + nvgpu_spinlock_release(&gr->ch_tlb_lock); +} diff --git a/include/gk20a/gr_gk20a.h b/include/gk20a/gr_gk20a.h new file mode 100644 index 0000000..08b81e8 --- /dev/null +++ b/include/gk20a/gr_gk20a.h @@ -0,0 +1,851 @@ +/* + * GK20A Graphics Engine + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef GR_GK20A_H +#define GR_GK20A_H + +#include + +#include "gr_ctx_gk20a.h" +#include "mm_gk20a.h" +#include + +#include +#include + +#define GR_IDLE_CHECK_DEFAULT 10 /* usec */ +#define GR_IDLE_CHECK_MAX 200 /* usec */ +#define GR_FECS_POLL_INTERVAL 5 /* usec */ + +#define INVALID_SCREEN_TILE_ROW_OFFSET 0xFFFFFFFF +#define INVALID_MAX_WAYS 0xFFFFFFFF + +#define GK20A_FECS_UCODE_IMAGE "fecs.bin" +#define GK20A_GPCCS_UCODE_IMAGE "gpccs.bin" + +#define GK20A_GR_MAX_PES_PER_GPC 3 + +#define GK20A_TIMEOUT_FPGA 100000 /* 100 sec */ + +/* Flags to be passed to g->ops.gr.alloc_obj_ctx() */ +#define NVGPU_OBJ_CTX_FLAGS_SUPPORT_GFXP (1 << 1) +#define NVGPU_OBJ_CTX_FLAGS_SUPPORT_CILP (1 << 2) + +/* + * allocate a minimum of 1 page (4KB) worth of patch space, this is 512 entries + * of address and data pairs + */ +#define PATCH_CTX_SLOTS_REQUIRED_PER_ENTRY 2 +#define PATCH_CTX_SLOTS_PER_PAGE \ + (PAGE_SIZE/(PATCH_CTX_SLOTS_REQUIRED_PER_ENTRY * sizeof(u32))) +#define PATCH_CTX_ENTRIES_FROM_SIZE(size) (size/sizeof(u32)) + +#define NVGPU_PREEMPTION_MODE_GRAPHICS_WFI (1 << 0) +#define NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP (1 << 1) + +#define NVGPU_PREEMPTION_MODE_COMPUTE_WFI (1 << 0) +#define NVGPU_PREEMPTION_MODE_COMPUTE_CTA (1 << 1) +#define NVGPU_PREEMPTION_MODE_COMPUTE_CILP (1 << 2) + +#define CTXSW_INTR0 BIT32(0) +#define CTXSW_INTR1 BIT32(1) + +#define MAILBOX_VALUE_TIMESTAMP_BUFFER_FULL 0x26 + +struct tsg_gk20a; +struct channel_gk20a; +struct nvgpu_warpstate; + +enum ctxsw_addr_type; + +enum /* global_ctx_buffer */ { + CIRCULAR = 0, + PAGEPOOL = 1, + ATTRIBUTE = 2, + CIRCULAR_VPR = 3, + PAGEPOOL_VPR = 4, + ATTRIBUTE_VPR = 5, + GOLDEN_CTX = 6, + PRIV_ACCESS_MAP = 7, + /* #8 is reserved */ + FECS_TRACE_BUFFER = 9, + NR_GLOBAL_CTX_BUF = 10 +}; + +/* either ATTRIBUTE or ATTRIBUTE_VPR maps to ATTRIBUTE_VA */ +enum /*global_ctx_buffer_va */ { + CIRCULAR_VA = 0, + PAGEPOOL_VA = 1, + ATTRIBUTE_VA = 2, + GOLDEN_CTX_VA = 3, + PRIV_ACCESS_MAP_VA = 4, + /* #5 is reserved */ + FECS_TRACE_BUFFER_VA = 6, + NR_GLOBAL_CTX_BUF_VA = 7 +}; + +enum { + WAIT_UCODE_LOOP, + WAIT_UCODE_TIMEOUT, + WAIT_UCODE_ERROR, + WAIT_UCODE_OK +}; + +enum { + GR_IS_UCODE_OP_EQUAL, + GR_IS_UCODE_OP_NOT_EQUAL, + GR_IS_UCODE_OP_AND, + GR_IS_UCODE_OP_LESSER, + GR_IS_UCODE_OP_LESSER_EQUAL, + GR_IS_UCODE_OP_SKIP +}; + +enum { + eUcodeHandshakeInitComplete = 1, + eUcodeHandshakeMethodFinished +}; + +enum { + ELCG_MODE = (1 << 0), + BLCG_MODE = (1 << 1), + INVALID_MODE = (1 << 2) +}; + +enum { + NVGPU_EVENT_ID_BPT_INT = 0, + NVGPU_EVENT_ID_BPT_PAUSE, + NVGPU_EVENT_ID_BLOCKING_SYNC, + NVGPU_EVENT_ID_CILP_PREEMPTION_STARTED, + NVGPU_EVENT_ID_CILP_PREEMPTION_COMPLETE, + NVGPU_EVENT_ID_GR_SEMAPHORE_WRITE_AWAKEN, + NVGPU_EVENT_ID_MAX, +}; + +#ifndef GR_GO_IDLE_BUNDLE +#define GR_GO_IDLE_BUNDLE 0x0000e100 /* --V-B */ +#endif + +struct gr_channel_map_tlb_entry { + u32 curr_ctx; + u32 chid; + u32 tsgid; +}; + +struct gr_zcull_gk20a { + u32 aliquot_width; + u32 aliquot_height; + u32 aliquot_size; + u32 total_aliquots; + + u32 width_align_pixels; + u32 height_align_pixels; + u32 pixel_squares_by_aliquots; +}; + +struct gr_zcull_info { + u32 width_align_pixels; + u32 height_align_pixels; + u32 pixel_squares_by_aliquots; + u32 aliquot_total; + u32 region_byte_multiplier; + u32 region_header_size; + u32 subregion_header_size; + u32 subregion_width_align_pixels; + u32 subregion_height_align_pixels; + u32 subregion_count; +}; + +#define GK20A_ZBC_COLOR_VALUE_SIZE 4 /* RGBA */ + +#define GK20A_STARTOF_ZBC_TABLE 1U /* index zero reserved to indicate "not ZBCd" */ +#define GK20A_SIZEOF_ZBC_TABLE 16 /* match ltcs_ltss_dstg_zbc_index_address width (4) */ +#define GK20A_ZBC_TABLE_SIZE (16 - 1) + +#define GK20A_ZBC_TYPE_INVALID 0 +#define GK20A_ZBC_TYPE_COLOR 1 +#define GK20A_ZBC_TYPE_DEPTH 2 +#define T19X_ZBC 3 + +struct zbc_color_table { + u32 color_ds[GK20A_ZBC_COLOR_VALUE_SIZE]; + u32 color_l2[GK20A_ZBC_COLOR_VALUE_SIZE]; + u32 format; + u32 ref_cnt; +}; + +struct zbc_depth_table { + u32 depth; + u32 format; + u32 ref_cnt; +}; + +struct zbc_s_table { + u32 stencil; + u32 format; + u32 ref_cnt; +}; + +struct zbc_entry { + u32 color_ds[GK20A_ZBC_COLOR_VALUE_SIZE]; + u32 color_l2[GK20A_ZBC_COLOR_VALUE_SIZE]; + u32 depth; + u32 type; /* color or depth */ + u32 format; +}; + +struct zbc_query_params { + u32 color_ds[GK20A_ZBC_COLOR_VALUE_SIZE]; + u32 color_l2[GK20A_ZBC_COLOR_VALUE_SIZE]; + u32 depth; + u32 ref_cnt; + u32 format; + u32 type; /* color or depth */ + u32 index_size; /* [out] size, [in] index */ +}; + +struct sm_info { + u32 gpc_index; + u32 tpc_index; + u32 sm_index; + u32 global_tpc_index; +}; + +#if defined(CONFIG_GK20A_CYCLE_STATS) +struct gk20a_cs_snapshot_client; +struct gk20a_cs_snapshot; +#endif + +struct gr_gk20a_isr_data { + u32 addr; + u32 data_lo; + u32 data_hi; + u32 curr_ctx; + struct channel_gk20a *ch; + u32 offset; + u32 sub_chan; + u32 class_num; +}; + +struct gr_ctx_buffer_desc { + void (*destroy)(struct gk20a *, struct gr_ctx_buffer_desc *); + struct nvgpu_mem mem; + void *priv; +}; + +struct nvgpu_preemption_modes_rec { + u32 graphics_preemption_mode_flags; /* supported preemption modes */ + u32 compute_preemption_mode_flags; /* supported preemption modes */ + + u32 default_graphics_preempt_mode; /* default mode */ + u32 default_compute_preempt_mode; /* default mode */ +}; + +struct gr_gk20a { + struct gk20a *g; + struct { + bool dynamic; + + u32 buffer_size; + u32 buffer_total_size; + + bool golden_image_initialized; + u32 golden_image_size; + u32 *local_golden_image; + + u32 hwpm_ctxsw_buffer_offset_map_count; + struct ctxsw_buf_offset_map_entry *hwpm_ctxsw_buffer_offset_map; + + u32 zcull_ctxsw_image_size; + + u32 pm_ctxsw_image_size; + + u32 buffer_header_size; + + u32 priv_access_map_size; + + u32 fecs_trace_buffer_size; + + struct gr_ucode_gk20a ucode; + + struct av_list_gk20a sw_bundle_init; + struct av_list_gk20a sw_method_init; + struct aiv_list_gk20a sw_ctx_load; + struct av_list_gk20a sw_non_ctx_load; + struct av_list_gk20a sw_veid_bundle_init; + struct av64_list_gk20a sw_bundle64_init; + struct { + struct aiv_list_gk20a sys; + struct aiv_list_gk20a gpc; + struct aiv_list_gk20a tpc; + struct aiv_list_gk20a zcull_gpc; + struct aiv_list_gk20a ppc; + struct aiv_list_gk20a pm_sys; + struct aiv_list_gk20a pm_gpc; + struct aiv_list_gk20a pm_tpc; + struct aiv_list_gk20a pm_ppc; + struct aiv_list_gk20a perf_sys; + struct aiv_list_gk20a perf_gpc; + struct aiv_list_gk20a fbp; + struct aiv_list_gk20a fbp_router; + struct aiv_list_gk20a gpc_router; + struct aiv_list_gk20a pm_ltc; + struct aiv_list_gk20a pm_fbpa; + struct aiv_list_gk20a perf_sys_router; + struct aiv_list_gk20a perf_pma; + struct aiv_list_gk20a pm_rop; + struct aiv_list_gk20a pm_ucgpc; + struct aiv_list_gk20a etpc; + struct aiv_list_gk20a pm_cau; + } ctxsw_regs; + u32 regs_base_index; + bool valid; + + u32 preempt_image_size; + bool force_preemption_gfxp; + bool force_preemption_cilp; + bool dump_ctxsw_stats_on_channel_close; + } ctx_vars; + + struct nvgpu_mutex ctx_mutex; /* protect golden ctx init */ + struct nvgpu_mutex fecs_mutex; /* protect fecs method */ + +#define GR_NETLIST_DYNAMIC -1 +#define GR_NETLIST_STATIC_A 'A' + int netlist; + + struct nvgpu_cond init_wq; + int initialized; + + u32 num_fbps; + + u32 max_comptag_lines; + u32 compbit_backing_size; + u32 comptags_per_cacheline; + u32 slices_per_ltc; + u32 cacheline_size; + u32 gobs_per_comptagline_per_slice; + + u32 max_gpc_count; + u32 max_fbps_count; + u32 max_tpc_per_gpc_count; + u32 max_zcull_per_gpc_count; + u32 max_tpc_count; + + u32 sys_count; + u32 gpc_count; + u32 pe_count_per_gpc; + u32 ppc_count; + u32 *gpc_ppc_count; + u32 tpc_count; + u32 *gpc_tpc_count; + u32 *gpc_tpc_mask; + u32 zcb_count; + u32 *gpc_zcb_count; + u32 *pes_tpc_count[GK20A_GR_MAX_PES_PER_GPC]; + u32 *pes_tpc_mask[GK20A_GR_MAX_PES_PER_GPC]; + u32 *gpc_skip_mask; + + u32 bundle_cb_default_size; + u32 min_gpm_fifo_depth; + u32 bundle_cb_token_limit; + u32 attrib_cb_default_size; + u32 attrib_cb_size; + u32 attrib_cb_gfxp_default_size; + u32 attrib_cb_gfxp_size; + u32 alpha_cb_default_size; + u32 alpha_cb_size; + u32 timeslice_mode; + u32 czf_bypass; + u32 pd_max_batches; + u32 gfxp_wfi_timeout_count; + u32 gfxp_wfi_timeout_unit; + + /* + * The deductible memory size for max_comptag_mem (in MBytes) + * Usually close to memory size that running system is taking + */ + u32 comptag_mem_deduct; + + struct gr_ctx_buffer_desc global_ctx_buffer[NR_GLOBAL_CTX_BUF]; + + u8 *map_tiles; + u32 map_tile_count; + u32 map_row_offset; + + u32 max_comptag_mem; /* max memory size (MB) for comptag */ + struct compbit_store_desc compbit_store; + struct gk20a_comptag_allocator comp_tags; + + struct gr_zcull_gk20a zcull; + + struct nvgpu_mutex zbc_lock; + struct zbc_color_table zbc_col_tbl[GK20A_ZBC_TABLE_SIZE]; + struct zbc_depth_table zbc_dep_tbl[GK20A_ZBC_TABLE_SIZE]; + struct zbc_s_table zbc_s_tbl[GK20A_ZBC_TABLE_SIZE]; + s32 max_default_color_index; + s32 max_default_depth_index; + s32 max_default_s_index; + + u32 max_used_color_index; + u32 max_used_depth_index; + u32 max_used_s_index; + +#define GR_CHANNEL_MAP_TLB_SIZE 2 /* must of power of 2 */ + struct gr_channel_map_tlb_entry chid_tlb[GR_CHANNEL_MAP_TLB_SIZE]; + u32 channel_tlb_flush_index; + struct nvgpu_spinlock ch_tlb_lock; + + void (*remove_support)(struct gr_gk20a *gr); + bool sw_ready; + bool skip_ucode_init; + + struct nvgpu_preemption_modes_rec preemption_mode_rec; + + u32 fecs_feature_override_ecc_val; + + int cilp_preempt_pending_chid; + + u32 fbp_en_mask; + u32 *fbp_rop_l2_en_mask; + u32 no_of_sm; + struct sm_info *sm_to_cluster; + +#if defined(CONFIG_GK20A_CYCLE_STATS) + struct nvgpu_mutex cs_lock; + struct gk20a_cs_snapshot *cs_data; +#endif + u32 max_css_buffer_size; +}; + +void gk20a_fecs_dump_falcon_stats(struct gk20a *g); + +/* contexts associated with a TSG */ +struct nvgpu_gr_ctx { + struct nvgpu_mem mem; + + u32 graphics_preempt_mode; + u32 compute_preempt_mode; + + struct nvgpu_mem preempt_ctxsw_buffer; + struct nvgpu_mem spill_ctxsw_buffer; + struct nvgpu_mem betacb_ctxsw_buffer; + struct nvgpu_mem pagepool_ctxsw_buffer; + u32 ctx_id; + bool ctx_id_valid; + bool cilp_preempt_pending; + bool boosted_ctx; + bool golden_img_loaded; + +#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION + u64 virt_ctx; +#endif + + struct patch_desc patch_ctx; + struct zcull_ctx_desc zcull_ctx; + struct pm_ctx_desc pm_ctx; + u64 global_ctx_buffer_va[NR_GLOBAL_CTX_BUF_VA]; + u64 global_ctx_buffer_size[NR_GLOBAL_CTX_BUF_VA]; + int global_ctx_buffer_index[NR_GLOBAL_CTX_BUF_VA]; + bool global_ctx_buffer_mapped; + + u32 tsgid; +}; + +struct gk20a_ctxsw_ucode_segment { + u32 offset; + u32 size; +}; + +struct gk20a_ctxsw_ucode_segments { + u32 boot_entry; + u32 boot_imem_offset; + u32 boot_signature; + struct gk20a_ctxsw_ucode_segment boot; + struct gk20a_ctxsw_ucode_segment code; + struct gk20a_ctxsw_ucode_segment data; +}; + +/* sums over the ucode files as sequences of u32, computed to the + * boot_signature field in the structure above */ + +/* T18X FECS remains same as T21X, + * so FALCON_UCODE_SIG_T21X_FECS_WITH_RESERVED used + * for T18X*/ +#define FALCON_UCODE_SIG_T18X_GPCCS_WITH_RESERVED 0x68edab34 +#define FALCON_UCODE_SIG_T21X_FECS_WITH_DMEM_SIZE 0x9121ab5c +#define FALCON_UCODE_SIG_T21X_FECS_WITH_RESERVED 0x9125ab5c +#define FALCON_UCODE_SIG_T12X_FECS_WITH_RESERVED 0x8a621f78 +#define FALCON_UCODE_SIG_T12X_FECS_WITHOUT_RESERVED 0x67e5344b +#define FALCON_UCODE_SIG_T12X_FECS_OLDER 0x56da09f + +#define FALCON_UCODE_SIG_T21X_GPCCS_WITH_RESERVED 0x3d3d65e2 +#define FALCON_UCODE_SIG_T12X_GPCCS_WITH_RESERVED 0x303465d5 +#define FALCON_UCODE_SIG_T12X_GPCCS_WITHOUT_RESERVED 0x3fdd33d3 +#define FALCON_UCODE_SIG_T12X_GPCCS_OLDER 0x53d7877 + +#define FALCON_UCODE_SIG_T21X_FECS_WITHOUT_RESERVED 0x93671b7d +#define FALCON_UCODE_SIG_T21X_FECS_WITHOUT_RESERVED2 0x4d6cbc10 + +#define FALCON_UCODE_SIG_T21X_GPCCS_WITHOUT_RESERVED 0x393161da + +struct gk20a_ctxsw_ucode_info { + u64 *p_va; + struct nvgpu_mem inst_blk_desc; + struct nvgpu_mem surface_desc; + struct gk20a_ctxsw_ucode_segments fecs; + struct gk20a_ctxsw_ucode_segments gpccs; +}; + +struct gk20a_ctxsw_bootloader_desc { + u32 start_offset; + u32 size; + u32 imem_offset; + u32 entry_point; +}; + +struct fecs_method_op_gk20a { + struct { + u32 addr; + u32 data; + } method; + + struct { + u32 id; + u32 data; + u32 clr; + u32 *ret; + u32 ok; + u32 fail; + } mailbox; + + struct { + u32 ok; + u32 fail; + } cond; + +}; + +struct nvgpu_warpstate { + u64 valid_warps[2]; + u64 trapped_warps[2]; + u64 paused_warps[2]; +}; + +struct gpu_ops; +int gr_gk20a_load_golden_ctx_image(struct gk20a *g, + struct channel_gk20a *c); +void gk20a_init_gr(struct gk20a *g); +int gk20a_init_gr_support(struct gk20a *g); +int gk20a_enable_gr_hw(struct gk20a *g); +int gk20a_gr_reset(struct gk20a *g); +void gk20a_gr_wait_initialized(struct gk20a *g); + +int gk20a_init_gr_channel(struct channel_gk20a *ch_gk20a); + +int gk20a_alloc_obj_ctx(struct channel_gk20a *c, u32 class_num, u32 flags); + +int gk20a_gr_isr(struct gk20a *g); +u32 gk20a_gr_nonstall_isr(struct gk20a *g); + +/* zcull */ +u32 gr_gk20a_get_ctxsw_zcull_size(struct gk20a *g, struct gr_gk20a *gr); +int gr_gk20a_bind_ctxsw_zcull(struct gk20a *g, struct gr_gk20a *gr, + struct channel_gk20a *c, u64 zcull_va, u32 mode); +int gr_gk20a_get_zcull_info(struct gk20a *g, struct gr_gk20a *gr, + struct gr_zcull_info *zcull_params); +void gr_gk20a_program_zcull_mapping(struct gk20a *g, u32 zcull_num_entries, + u32 *zcull_map_tiles); +/* zbc */ +int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *zbc_val); +int gr_gk20a_query_zbc(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_query_params *query_params); +int gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *zbc_val); +int gr_gk20a_load_zbc_default_table(struct gk20a *g, struct gr_gk20a *gr); + +/* pmu */ +int gr_gk20a_fecs_get_reglist_img_size(struct gk20a *g, u32 *size); +int gr_gk20a_fecs_set_reglist_bind_inst(struct gk20a *g, + struct nvgpu_mem *inst_block); +int gr_gk20a_fecs_set_reglist_virtual_addr(struct gk20a *g, u64 pmu_va); + +void gr_gk20a_init_cg_mode(struct gk20a *g, u32 cgmode, u32 mode_config); + +/* sm */ +bool gk20a_gr_sm_debugger_attached(struct gk20a *g); +u32 gk20a_gr_get_sm_no_lock_down_hww_global_esr_mask(struct gk20a *g); + +#define gr_gk20a_elpg_protected_call(g, func) \ + ({ \ + int err = 0; \ + if (g->support_pmu) {\ + err = nvgpu_pg_elpg_disable(g);\ + if (err != 0) {\ + err = nvgpu_pg_elpg_enable(g); \ + } \ + } \ + if (err == 0) { \ + err = func; \ + if (g->support_pmu) {\ + (void)nvgpu_pg_elpg_enable(g); \ + } \ + } \ + err; \ + }) + +int gk20a_gr_suspend(struct gk20a *g); + +struct nvgpu_dbg_reg_op; +int gr_gk20a_exec_ctx_ops(struct channel_gk20a *ch, + struct nvgpu_dbg_reg_op *ctx_ops, u32 num_ops, + u32 num_ctx_wr_ops, u32 num_ctx_rd_ops, + bool *is_curr_ctx); +int __gr_gk20a_exec_ctx_ops(struct channel_gk20a *ch, + struct nvgpu_dbg_reg_op *ctx_ops, u32 num_ops, + u32 num_ctx_wr_ops, u32 num_ctx_rd_ops, + bool ch_is_curr_ctx); +int gr_gk20a_get_ctx_buffer_offsets(struct gk20a *g, + u32 addr, + u32 max_offsets, + u32 *offsets, u32 *offset_addrs, + u32 *num_offsets, + bool is_quad, u32 quad); +int gr_gk20a_get_pm_ctx_buffer_offsets(struct gk20a *g, + u32 addr, + u32 max_offsets, + u32 *offsets, u32 *offset_addrs, + u32 *num_offsets); +int gr_gk20a_update_smpc_ctxsw_mode(struct gk20a *g, + struct channel_gk20a *c, + bool enable_smpc_ctxsw); +int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, + struct channel_gk20a *c, + u64 gpu_va, + u32 mode); + +struct nvgpu_gr_ctx; +void gr_gk20a_ctx_patch_write(struct gk20a *g, struct nvgpu_gr_ctx *ch_ctx, + u32 addr, u32 data, bool patch); +int gr_gk20a_ctx_patch_write_begin(struct gk20a *g, + struct nvgpu_gr_ctx *ch_ctx, + bool update_patch_count); +void gr_gk20a_ctx_patch_write_end(struct gk20a *g, + struct nvgpu_gr_ctx *ch_ctx, + bool update_patch_count); +void gr_gk20a_commit_global_pagepool(struct gk20a *g, + struct nvgpu_gr_ctx *ch_ctx, + u64 addr, u32 size, bool patch); +void gk20a_gr_set_shader_exceptions(struct gk20a *g, u32 data); +void gr_gk20a_enable_hww_exceptions(struct gk20a *g); +int gr_gk20a_init_fs_state(struct gk20a *g); +int gr_gk20a_setup_rop_mapping(struct gk20a *g, struct gr_gk20a *gr); +int gr_gk20a_init_ctxsw_ucode(struct gk20a *g); +int gr_gk20a_load_ctxsw_ucode(struct gk20a *g); +void gr_gk20a_load_falcon_bind_instblk(struct gk20a *g); +void gr_gk20a_load_ctxsw_ucode_header(struct gk20a *g, u64 addr_base, + struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset); +void gr_gk20a_load_ctxsw_ucode_boot(struct gk20a *g, u64 addr_base, + struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset); + + +void gr_gk20a_free_tsg_gr_ctx(struct tsg_gk20a *c); +int gr_gk20a_disable_ctxsw(struct gk20a *g); +int gr_gk20a_enable_ctxsw(struct gk20a *g); +void gk20a_gr_resume_single_sm(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm); +void gk20a_gr_resume_all_sms(struct gk20a *g); +void gk20a_gr_suspend_single_sm(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm, + u32 global_esr_mask, bool check_errors); +void gk20a_gr_suspend_all_sms(struct gk20a *g, + u32 global_esr_mask, bool check_errors); +u32 gr_gk20a_get_tpc_count(struct gr_gk20a *gr, u32 gpc_index); +int gr_gk20a_set_sm_debug_mode(struct gk20a *g, + struct channel_gk20a *ch, u64 sms, bool enable); +bool gk20a_is_channel_ctx_resident(struct channel_gk20a *ch); +int gr_gk20a_add_zbc_color(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *color_val, u32 index); +int gr_gk20a_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *depth_val, u32 index); +int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *zbc_val); +void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries); +int gr_gk20a_wait_idle(struct gk20a *g, unsigned long duration_ms, + u32 expect_delay); +int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, + bool *post_event, struct channel_gk20a *fault_ch, + u32 *hww_global_esr); +int gr_gk20a_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc, + bool *post_event); +int gr_gk20a_init_ctx_state(struct gk20a *g); +int gr_gk20a_submit_fecs_method_op(struct gk20a *g, + struct fecs_method_op_gk20a op, + bool sleepduringwait); +int gr_gk20a_submit_fecs_method_op_locked(struct gk20a *g, + struct fecs_method_op_gk20a op, + bool sleepduringwait); +int gr_gk20a_submit_fecs_sideband_method_op(struct gk20a *g, + struct fecs_method_op_gk20a op); +int gr_gk20a_alloc_gr_ctx(struct gk20a *g, + struct nvgpu_gr_ctx *gr_ctx, struct vm_gk20a *vm, + u32 class, u32 padding); +void gr_gk20a_free_gr_ctx(struct gk20a *g, + struct vm_gk20a *vm, struct nvgpu_gr_ctx *gr_ctx); +int gr_gk20a_halt_pipe(struct gk20a *g); + +#if defined(CONFIG_GK20A_CYCLE_STATS) +int gr_gk20a_css_attach(struct channel_gk20a *ch, /* in - main hw structure */ + u32 perfmon_id_count, /* in - number of perfmons*/ + u32 *perfmon_id_start, /* out- index of first pm */ + /* in/out - pointer to client data used in later */ + struct gk20a_cs_snapshot_client *css_client); + +int gr_gk20a_css_detach(struct channel_gk20a *ch, + struct gk20a_cs_snapshot_client *css_client); +int gr_gk20a_css_flush(struct channel_gk20a *ch, + struct gk20a_cs_snapshot_client *css_client); + +void gr_gk20a_free_cyclestats_snapshot_data(struct gk20a *g); + +#else +/* fake empty cleanup function if no cyclestats snapshots enabled */ +static inline void gr_gk20a_free_cyclestats_snapshot_data(struct gk20a *g) +{ + (void)g; +} +#endif + +void gr_gk20a_fecs_host_int_enable(struct gk20a *g); +int gk20a_gr_handle_fecs_error(struct gk20a *g, struct channel_gk20a *ch, + struct gr_gk20a_isr_data *isr_data); +int gk20a_gr_lock_down_sm(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm, u32 global_esr_mask, + bool check_errors); +int gk20a_gr_wait_for_sm_lock_down(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, + u32 global_esr_mask, bool check_errors); +int gr_gk20a_ctx_wait_ucode(struct gk20a *g, u32 mailbox_id, + u32 *mailbox_ret, u32 opc_success, + u32 mailbox_ok, u32 opc_fail, + u32 mailbox_fail, bool sleepduringwait); + +int gr_gk20a_get_ctx_id(struct gk20a *g, + struct channel_gk20a *c, + u32 *ctx_id); + +u32 gk20a_gr_get_sm_hww_warp_esr(struct gk20a *g, u32 gpc, u32 tpc, u32 sm); +u32 gk20a_gr_get_sm_hww_global_esr(struct gk20a *g, u32 gpc, u32 tpc, u32 sm); + +int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long duration_ms, + u32 expect_delay); + +struct dbg_session_gk20a; + +bool gr_gk20a_suspend_context(struct channel_gk20a *ch); +bool gr_gk20a_resume_context(struct channel_gk20a *ch); +int gr_gk20a_suspend_contexts(struct gk20a *g, + struct dbg_session_gk20a *dbg_s, + int *ctx_resident_ch_fd); +int gr_gk20a_resume_contexts(struct gk20a *g, + struct dbg_session_gk20a *dbg_s, + int *ctx_resident_ch_fd); +void gk20a_gr_enable_gpc_exceptions(struct gk20a *g); +void gk20a_gr_enable_exceptions(struct gk20a *g); +int gr_gk20a_trigger_suspend(struct gk20a *g); +int gr_gk20a_wait_for_pause(struct gk20a *g, struct nvgpu_warpstate *w_state); +int gr_gk20a_resume_from_pause(struct gk20a *g); +int gr_gk20a_clear_sm_errors(struct gk20a *g); +u32 gr_gk20a_tpc_enabled_exceptions(struct gk20a *g); + +int gr_gk20a_commit_global_timeslice(struct gk20a *g, struct channel_gk20a *c); + +int gr_gk20a_init_sm_id_table(struct gk20a *g); + +int gr_gk20a_commit_inst(struct channel_gk20a *c, u64 gpu_va); + +void gr_gk20a_write_zcull_ptr(struct gk20a *g, + struct nvgpu_mem *mem, u64 gpu_va); + +void gr_gk20a_write_pm_ptr(struct gk20a *g, + struct nvgpu_mem *mem, u64 gpu_va); + +u32 gk20a_gr_gpc_offset(struct gk20a *g, u32 gpc); +u32 gk20a_gr_tpc_offset(struct gk20a *g, u32 tpc); +void gk20a_gr_get_esr_sm_sel(struct gk20a *g, u32 gpc, u32 tpc, + u32 *esr_sm_sel); +void gk20a_gr_init_ovr_sm_dsm_perf(void); +void gk20a_gr_get_ovr_perf_regs(struct gk20a *g, u32 *num_ovr_perf_regs, + u32 **ovr_perf_regs); +void gk20a_gr_init_ctxsw_hdr_data(struct gk20a *g, + struct nvgpu_mem *mem); +u32 gr_gk20a_get_patch_slots(struct gk20a *g); +int gk20a_gr_handle_notify_pending(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data); + +int gr_gk20a_alloc_global_ctx_buffers(struct gk20a *g); +int gr_gk20a_map_global_ctx_buffers(struct gk20a *g, + struct channel_gk20a *c); +int gr_gk20a_commit_global_ctx_buffers(struct gk20a *g, + struct channel_gk20a *c, bool patch); + +int gr_gk20a_fecs_ctx_bind_channel(struct gk20a *g, + struct channel_gk20a *c); +u32 gk20a_init_sw_bundle(struct gk20a *g); +int gr_gk20a_fecs_ctx_image_save(struct channel_gk20a *c, u32 save_type); +int gk20a_gr_handle_semaphore_pending(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data); +int gr_gk20a_add_ctxsw_reg_pm_fbpa(struct gk20a *g, + struct ctxsw_buf_offset_map_entry *map, + struct aiv_list_gk20a *regs, + u32 *count, u32 *offset, + u32 max_cnt, u32 base, + u32 num_fbpas, u32 stride, u32 mask); +int gr_gk20a_add_ctxsw_reg_perf_pma(struct ctxsw_buf_offset_map_entry *map, + struct aiv_list_gk20a *regs, + u32 *count, u32 *offset, + u32 max_cnt, u32 base, u32 mask); +int gr_gk20a_decode_priv_addr(struct gk20a *g, u32 addr, + enum ctxsw_addr_type *addr_type, + u32 *gpc_num, u32 *tpc_num, u32 *ppc_num, u32 *be_num, + u32 *broadcast_flags); +int gr_gk20a_split_ppc_broadcast_addr(struct gk20a *g, u32 addr, + u32 gpc_num, + u32 *priv_addr_table, u32 *t); +int gr_gk20a_create_priv_addr_table(struct gk20a *g, + u32 addr, + u32 *priv_addr_table, + u32 *num_registers); +void gr_gk20a_split_fbpa_broadcast_addr(struct gk20a *g, u32 addr, + u32 num_fbpas, + u32 *priv_addr_table, u32 *t); +int gr_gk20a_get_offset_in_gpccs_segment(struct gk20a *g, + enum ctxsw_addr_type addr_type, u32 num_tpcs, u32 num_ppcs, + u32 reg_list_ppc_count, u32 *__offset_in_segment); + +void gk20a_gr_destroy_ctx_buffer(struct gk20a *g, + struct gr_ctx_buffer_desc *desc); +int gk20a_gr_alloc_ctx_buffer(struct gk20a *g, + struct gr_ctx_buffer_desc *desc, size_t size); +void gk20a_gr_flush_channel_tlb(struct gr_gk20a *gr); +int gr_gk20a_set_fecs_watchdog_timeout(struct gk20a *g); +#endif /*__GR_GK20A_H__*/ diff --git a/include/gk20a/gr_pri_gk20a.h b/include/gk20a/gr_pri_gk20a.h new file mode 100644 index 0000000..d832d90 --- /dev/null +++ b/include/gk20a/gr_pri_gk20a.h @@ -0,0 +1,261 @@ +/* + * GK20A Graphics Context Pri Register Addressing + * + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef GR_PRI_GK20A_H +#define GR_PRI_GK20A_H + +/* + * These convenience macros are generally for use in the management/modificaiton + * of the context state store for gr/compute contexts. + */ + +/* + * GPC pri addressing + */ +static inline u32 pri_gpccs_addr_width(void) +{ + return 15; /*from where?*/ +} +static inline u32 pri_gpccs_addr_mask(u32 addr) +{ + return addr & ((1 << pri_gpccs_addr_width()) - 1); +} +static inline u32 pri_gpc_addr(struct gk20a *g, u32 addr, u32 gpc) +{ + u32 gpc_base = nvgpu_get_litter_value(g, GPU_LIT_GPC_BASE); + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + return gpc_base + (gpc * gpc_stride) + addr; +} +static inline bool pri_is_gpc_addr_shared(struct gk20a *g, u32 addr) +{ + u32 gpc_shared_base = nvgpu_get_litter_value(g, GPU_LIT_GPC_SHARED_BASE); + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + return (addr >= gpc_shared_base) && + (addr < gpc_shared_base + gpc_stride); +} +static inline bool pri_is_gpc_addr(struct gk20a *g, u32 addr) +{ + u32 gpc_base = nvgpu_get_litter_value(g, GPU_LIT_GPC_BASE); + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 num_gpcs = nvgpu_get_litter_value(g, GPU_LIT_NUM_GPCS); + return ((addr >= gpc_base) && + (addr < gpc_base + num_gpcs * gpc_stride)) || + pri_is_gpc_addr_shared(g, addr); +} +static inline u32 pri_get_gpc_num(struct gk20a *g, u32 addr) +{ + u32 i, start; + u32 num_gpcs = nvgpu_get_litter_value(g, GPU_LIT_NUM_GPCS); + u32 gpc_base = nvgpu_get_litter_value(g, GPU_LIT_GPC_BASE); + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + for (i = 0; i < num_gpcs; i++) { + start = gpc_base + (i * gpc_stride); + if ((addr >= start) && (addr < (start + gpc_stride))) + return i; + } + return 0; +} + +/* + * PPC pri addressing + */ +static inline bool pri_is_ppc_addr_shared(struct gk20a *g, u32 addr) +{ + u32 ppc_in_gpc_shared_base = nvgpu_get_litter_value(g, + GPU_LIT_PPC_IN_GPC_SHARED_BASE); + u32 ppc_in_gpc_stride = nvgpu_get_litter_value(g, + GPU_LIT_PPC_IN_GPC_STRIDE); + + return ((addr >= ppc_in_gpc_shared_base) && + (addr < (ppc_in_gpc_shared_base + ppc_in_gpc_stride))); +} + +static inline bool pri_is_ppc_addr(struct gk20a *g, u32 addr) +{ + u32 ppc_in_gpc_base = nvgpu_get_litter_value(g, + GPU_LIT_PPC_IN_GPC_BASE); + u32 num_pes_per_gpc = nvgpu_get_litter_value(g, + GPU_LIT_NUM_PES_PER_GPC); + u32 ppc_in_gpc_stride = nvgpu_get_litter_value(g, + GPU_LIT_PPC_IN_GPC_STRIDE); + + return ((addr >= ppc_in_gpc_base) && + (addr < ppc_in_gpc_base + num_pes_per_gpc * ppc_in_gpc_stride)) + || pri_is_ppc_addr_shared(g, addr); +} + +/* + * TPC pri addressing + */ +static inline u32 pri_tpccs_addr_width(void) +{ + return 11; /* from where? */ +} +static inline u32 pri_tpccs_addr_mask(u32 addr) +{ + return addr & ((1 << pri_tpccs_addr_width()) - 1); +} +static inline u32 pri_fbpa_addr_mask(struct gk20a *g, u32 addr) +{ + return addr & (nvgpu_get_litter_value(g, GPU_LIT_FBPA_STRIDE) - 1); +} +static inline u32 pri_tpc_addr(struct gk20a *g, u32 addr, u32 gpc, u32 tpc) +{ + u32 gpc_base = nvgpu_get_litter_value(g, GPU_LIT_GPC_BASE); + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 tpc_in_gpc_base = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_BASE); + u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); + return gpc_base + (gpc * gpc_stride) + + tpc_in_gpc_base + (tpc * tpc_in_gpc_stride) + + addr; +} +static inline bool pri_is_tpc_addr_shared(struct gk20a *g, u32 addr) +{ + u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE); + u32 tpc_in_gpc_shared_base = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_SHARED_BASE); + return (addr >= tpc_in_gpc_shared_base) && + (addr < (tpc_in_gpc_shared_base + + tpc_in_gpc_stride)); +} +static inline u32 pri_fbpa_addr(struct gk20a *g, u32 addr, u32 fbpa) +{ + return (nvgpu_get_litter_value(g, GPU_LIT_FBPA_BASE) + addr + + (fbpa * nvgpu_get_litter_value(g, GPU_LIT_FBPA_STRIDE))); +} +static inline bool pri_is_fbpa_addr_shared(struct gk20a *g, u32 addr) +{ + u32 fbpa_shared_base = nvgpu_get_litter_value(g, GPU_LIT_FBPA_SHARED_BASE); + u32 fbpa_stride = nvgpu_get_litter_value(g, GPU_LIT_FBPA_STRIDE); + return ((addr >= fbpa_shared_base) && + (addr < (fbpa_shared_base + fbpa_stride))); +} +static inline bool pri_is_fbpa_addr(struct gk20a *g, u32 addr) +{ + u32 fbpa_base = nvgpu_get_litter_value(g, GPU_LIT_FBPA_BASE); + u32 fbpa_stride = nvgpu_get_litter_value(g, GPU_LIT_FBPA_STRIDE); + u32 num_fbpas = nvgpu_get_litter_value(g, GPU_LIT_NUM_FBPAS); + return (((addr >= fbpa_base) && + (addr < (fbpa_base + num_fbpas * fbpa_stride))) + || pri_is_fbpa_addr_shared(g, addr)); +} +/* + * BE pri addressing + */ +static inline u32 pri_becs_addr_width(void) +{ + return 10;/* from where? */ +} +static inline u32 pri_becs_addr_mask(u32 addr) +{ + return addr & ((1 << pri_becs_addr_width()) - 1); +} +static inline bool pri_is_be_addr_shared(struct gk20a *g, u32 addr) +{ + u32 rop_shared_base = nvgpu_get_litter_value(g, GPU_LIT_ROP_SHARED_BASE); + u32 rop_stride = nvgpu_get_litter_value(g, GPU_LIT_ROP_STRIDE); + return (addr >= rop_shared_base) && + (addr < rop_shared_base + rop_stride); +} +static inline u32 pri_be_shared_addr(struct gk20a *g, u32 addr) +{ + u32 rop_shared_base = nvgpu_get_litter_value(g, GPU_LIT_ROP_SHARED_BASE); + return rop_shared_base + pri_becs_addr_mask(addr); +} +static inline bool pri_is_be_addr(struct gk20a *g, u32 addr) +{ + u32 rop_base = nvgpu_get_litter_value(g, GPU_LIT_ROP_BASE); + u32 rop_stride = nvgpu_get_litter_value(g, GPU_LIT_ROP_STRIDE); + return ((addr >= rop_base) && + (addr < rop_base + g->ltc_count * rop_stride)) || + pri_is_be_addr_shared(g, addr); +} + +static inline u32 pri_get_be_num(struct gk20a *g, u32 addr) +{ + u32 i, start; + u32 num_fbps = nvgpu_get_litter_value(g, GPU_LIT_NUM_FBPS); + u32 rop_base = nvgpu_get_litter_value(g, GPU_LIT_ROP_BASE); + u32 rop_stride = nvgpu_get_litter_value(g, GPU_LIT_ROP_STRIDE); + for (i = 0; i < num_fbps; i++) { + start = rop_base + (i * rop_stride); + if ((addr >= start) && (addr < (start + rop_stride))) + return i; + } + return 0; +} + +/* + * PPC pri addressing + */ +static inline u32 pri_ppccs_addr_width(void) +{ + return 9; /* from where? */ +} +static inline u32 pri_ppccs_addr_mask(u32 addr) +{ + return addr & ((1 << pri_ppccs_addr_width()) - 1); +} +static inline u32 pri_ppc_addr(struct gk20a *g, u32 addr, u32 gpc, u32 ppc) +{ + u32 gpc_base = nvgpu_get_litter_value(g, GPU_LIT_GPC_BASE); + u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); + u32 ppc_in_gpc_base = nvgpu_get_litter_value(g, GPU_LIT_PPC_IN_GPC_BASE); + u32 ppc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_PPC_IN_GPC_STRIDE); + return gpc_base + (gpc * gpc_stride) + + ppc_in_gpc_base + (ppc * ppc_in_gpc_stride) + addr; +} + +enum ctxsw_addr_type { + CTXSW_ADDR_TYPE_SYS = 0, + CTXSW_ADDR_TYPE_GPC = 1, + CTXSW_ADDR_TYPE_TPC = 2, + CTXSW_ADDR_TYPE_BE = 3, + CTXSW_ADDR_TYPE_PPC = 4, + CTXSW_ADDR_TYPE_LTCS = 5, + CTXSW_ADDR_TYPE_FBPA = 6, + CTXSW_ADDR_TYPE_EGPC = 7, + CTXSW_ADDR_TYPE_ETPC = 8, + CTXSW_ADDR_TYPE_ROP = 9, + CTXSW_ADDR_TYPE_FBP = 10, +}; + +#define PRI_BROADCAST_FLAGS_NONE 0U +#define PRI_BROADCAST_FLAGS_GPC BIT32(0) +#define PRI_BROADCAST_FLAGS_TPC BIT32(1) +#define PRI_BROADCAST_FLAGS_BE BIT32(2) +#define PRI_BROADCAST_FLAGS_PPC BIT32(3) +#define PRI_BROADCAST_FLAGS_LTCS BIT32(4) +#define PRI_BROADCAST_FLAGS_LTSS BIT32(5) +#define PRI_BROADCAST_FLAGS_FBPA BIT32(6) +#define PRI_BROADCAST_FLAGS_EGPC BIT32(7) +#define PRI_BROADCAST_FLAGS_ETPC BIT32(8) +#define PRI_BROADCAST_FLAGS_PMMGPC BIT32(9) +#define PRI_BROADCAST_FLAGS_PMM_GPCS BIT32(10) +#define PRI_BROADCAST_FLAGS_PMM_GPCGS_GPCTPCA BIT32(11) +#define PRI_BROADCAST_FLAGS_PMM_GPCGS_GPCTPCB BIT32(12) +#define PRI_BROADCAST_FLAGS_PMMFBP BIT32(13) +#define PRI_BROADCAST_FLAGS_PMM_FBPS BIT32(14) +#define PRI_BROADCAST_FLAGS_PMM_FBPGS_LTC BIT32(15) +#define PRI_BROADCAST_FLAGS_PMM_FBPGS_ROP BIT32(16) + +#endif /* GR_PRI_GK20A_H */ diff --git a/include/gk20a/hw_bus_gk20a.h b/include/gk20a/hw_bus_gk20a.h new file mode 100644 index 0000000..d3bb9e9 --- /dev/null +++ b/include/gk20a/hw_bus_gk20a.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_bus_gk20a_h_ +#define _hw_bus_gk20a_h_ + +static inline u32 bus_bar0_window_r(void) +{ + return 0x00001700U; +} +static inline u32 bus_bar0_window_base_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 bus_bar0_window_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar0_window_target_sys_mem_coherent_f(void) +{ + return 0x2000000U; +} +static inline u32 bus_bar0_window_target_sys_mem_noncoherent_f(void) +{ + return 0x3000000U; +} +static inline u32 bus_bar0_window_target_bar0_window_base_shift_v(void) +{ + return 0x00000010U; +} +static inline u32 bus_bar1_block_r(void) +{ + return 0x00001704U; +} +static inline u32 bus_bar1_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar1_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar1_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar1_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar1_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar2_block_r(void) +{ + return 0x00001714U; +} +static inline u32 bus_bar2_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar2_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar2_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar2_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar2_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar1_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bar2_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_intr_0_r(void) +{ + return 0x00001100U; +} +static inline u32 bus_intr_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +static inline u32 bus_intr_en_0_r(void) +{ + return 0x00001140U; +} +static inline u32 bus_intr_en_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_en_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_en_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +#endif diff --git a/include/gk20a/hw_ccsr_gk20a.h b/include/gk20a/hw_ccsr_gk20a.h new file mode 100644 index 0000000..95151f6 --- /dev/null +++ b/include/gk20a/hw_ccsr_gk20a.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ccsr_gk20a_h_ +#define _hw_ccsr_gk20a_h_ + +static inline u32 ccsr_channel_inst_r(u32 i) +{ + return 0x00800000U + i*8U; +} +static inline u32 ccsr_channel_inst__size_1_v(void) +{ + return 0x00000080U; +} +static inline u32 ccsr_channel_inst_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 ccsr_channel_inst_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 ccsr_channel_inst_bind_false_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_bind_true_f(void) +{ + return 0x80000000U; +} +static inline u32 ccsr_channel_r(u32 i) +{ + return 0x00800004U + i*8U; +} +static inline u32 ccsr_channel__size_1_v(void) +{ + return 0x00000080U; +} +static inline u32 ccsr_channel_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ccsr_channel_enable_set_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ccsr_channel_enable_set_true_f(void) +{ + return 0x400U; +} +static inline u32 ccsr_channel_enable_clr_true_f(void) +{ + return 0x800U; +} +static inline u32 ccsr_channel_runlist_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 ccsr_channel_status_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ccsr_channel_status_pending_ctx_reload_v(void) +{ + return 0x00000002U; +} +static inline u32 ccsr_channel_status_pending_acq_ctx_reload_v(void) +{ + return 0x00000004U; +} +static inline u32 ccsr_channel_status_on_pbdma_ctx_reload_v(void) +{ + return 0x0000000aU; +} +static inline u32 ccsr_channel_status_on_pbdma_and_eng_ctx_reload_v(void) +{ + return 0x0000000bU; +} +static inline u32 ccsr_channel_status_on_eng_ctx_reload_v(void) +{ + return 0x0000000cU; +} +static inline u32 ccsr_channel_status_on_eng_pending_ctx_reload_v(void) +{ + return 0x0000000dU; +} +static inline u32 ccsr_channel_status_on_eng_pending_acq_ctx_reload_v(void) +{ + return 0x0000000eU; +} +static inline u32 ccsr_channel_next_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ccsr_channel_next_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ccsr_channel_busy_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +#endif diff --git a/include/gk20a/hw_ce2_gk20a.h b/include/gk20a/hw_ce2_gk20a.h new file mode 100644 index 0000000..87481cd --- /dev/null +++ b/include/gk20a/hw_ce2_gk20a.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ce2_gk20a_h_ +#define _hw_ce2_gk20a_h_ + +static inline u32 ce2_intr_status_r(void) +{ + return 0x00106908U; +} +static inline u32 ce2_intr_status_blockpipe_pending_f(void) +{ + return 0x1U; +} +static inline u32 ce2_intr_status_blockpipe_reset_f(void) +{ + return 0x1U; +} +static inline u32 ce2_intr_status_nonblockpipe_pending_f(void) +{ + return 0x2U; +} +static inline u32 ce2_intr_status_nonblockpipe_reset_f(void) +{ + return 0x2U; +} +static inline u32 ce2_intr_status_launcherr_pending_f(void) +{ + return 0x4U; +} +static inline u32 ce2_intr_status_launcherr_reset_f(void) +{ + return 0x4U; +} +#endif diff --git a/include/gk20a/hw_ctxsw_prog_gk20a.h b/include/gk20a/hw_ctxsw_prog_gk20a.h new file mode 100644 index 0000000..131fd12 --- /dev/null +++ b/include/gk20a/hw_ctxsw_prog_gk20a.h @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ctxsw_prog_gk20a_h_ +#define _hw_ctxsw_prog_gk20a_h_ + +static inline u32 ctxsw_prog_fecs_header_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_main_image_num_gpcs_o(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_main_image_patch_count_o(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_main_image_context_id_o(void) +{ + return 0x000000f0U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_lo_o(void) +{ + return 0x00000014U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_hi_o(void) +{ + return 0x00000018U; +} +static inline u32 ctxsw_prog_main_image_zcull_o(void) +{ + return 0x0000001cU; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_no_ctxsw_v(void) +{ + return 0x00000001U; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_separate_buffer_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_zcull_ptr_o(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_main_image_pm_o(void) +{ + return 0x00000028U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_m(void) +{ + return 0x7U << 0U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_ctxsw_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_m(void) +{ + return 0x7U << 3U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_ctxsw_f(void) +{ + return 0x8U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_ptr_o(void) +{ + return 0x0000002cU; +} +static inline u32 ctxsw_prog_main_image_num_save_ops_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_main_image_num_restore_ops_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_main_image_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_main_image_magic_value_v_value_v(void) +{ + return 0x600dc0deU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_local_image_ppc_info_num_ppcs_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_ppc_mask_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_num_tpcs_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_local_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_local_magic_value_v_value_v(void) +{ + return 0xad0becabU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_o(void) +{ + return 0x000000ecU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_size_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 ctxsw_prog_extended_buffer_segments_size_in_bytes_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_extended_marker_size_in_bytes_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_register_stride_v(void) +{ + return 0x00000005U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_control_register_stride_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_extended_num_smpc_quadrants_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_o(void) +{ + return 0x000000a0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_s(void) +{ + return 2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_m(void) +{ + return 0x3U << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_allow_all_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_use_map_f(void) +{ + return 0x2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_lo_o(void) +{ + return 0x000000a4U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_hi_o(void) +{ + return 0x000000a8U; +} +static inline u32 ctxsw_prog_main_image_misc_options_o(void) +{ + return 0x0000003cU; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_disabled_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_control_o(void) +{ + return 0x000000acU; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_control_num_records_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_o(void) +{ + return 0x000000b0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_v_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_sys_mem_coherent_f(void) +{ + return 0x20000000U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_sys_mem_noncoherent_f(void) +{ + return 0x30000000U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_o(void) +{ + return 0x000000b4U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_record_timestamp_record_size_in_bytes_v(void) +{ + return 0x00000080U; +} +static inline u32 ctxsw_prog_record_timestamp_record_size_in_words_v(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_lo_o(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_lo_v_value_v(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_hi_o(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_hi_v_value_v(void) +{ + return 0x600dbeefU; +} +static inline u32 ctxsw_prog_record_timestamp_context_id_o(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_record_timestamp_context_ptr_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_record_timestamp_new_context_id_o(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_record_timestamp_new_context_ptr_o(void) +{ + return 0x00000014U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_lo_o(void) +{ + return 0x00000018U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_o(void) +{ + return 0x0000001cU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_v_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_v_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_m(void) +{ + return 0xffU << 24U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_v(u32 r) +{ + return (r >> 24U) & 0xffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_ctxsw_req_by_host_v(void) +{ + return 0x00000001U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_ctxsw_req_by_host_f(void) +{ + return 0x1000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_f(void) +{ + return 0x2000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_wfi_v(void) +{ + return 0x0000000aU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_wfi_f(void) +{ + return 0xa000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_gfxp_v(void) +{ + return 0x0000000bU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_gfxp_f(void) +{ + return 0xb000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_ctap_v(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_ctap_f(void) +{ + return 0xc000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_cilp_v(void) +{ + return 0x0000000dU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_cilp_f(void) +{ + return 0xd000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_save_end_v(void) +{ + return 0x00000003U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_save_end_f(void) +{ + return 0x3000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_restore_start_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_restore_start_f(void) +{ + return 0x4000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_context_start_v(void) +{ + return 0x00000005U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_context_start_f(void) +{ + return 0x5000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_invalid_timestamp_v(void) +{ + return 0x000000ffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_invalid_timestamp_f(void) +{ + return 0xff000000U; +} +#endif diff --git a/include/gk20a/hw_falcon_gk20a.h b/include/gk20a/hw_falcon_gk20a.h new file mode 100644 index 0000000..7b4d87b --- /dev/null +++ b/include/gk20a/hw_falcon_gk20a.h @@ -0,0 +1,559 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_falcon_gk20a_h_ +#define _hw_falcon_gk20a_h_ + +static inline u32 falcon_falcon_irqsset_r(void) +{ + return 0x00000000U; +} +static inline u32 falcon_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqsclr_r(void) +{ + return 0x00000004U; +} +static inline u32 falcon_falcon_irqstat_r(void) +{ + return 0x00000008U; +} +static inline u32 falcon_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 falcon_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 falcon_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqmode_r(void) +{ + return 0x0000000cU; +} +static inline u32 falcon_falcon_irqmset_r(void) +{ + return 0x00000010U; +} +static inline u32 falcon_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_r(void) +{ + return 0x00000014U; +} +static inline u32 falcon_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqmask_r(void) +{ + return 0x00000018U; +} +static inline u32 falcon_falcon_irqdest_r(void) +{ + return 0x0000001cU; +} +static inline u32 falcon_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 falcon_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 falcon_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 falcon_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 falcon_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 falcon_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 falcon_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 falcon_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 falcon_falcon_curctx_r(void) +{ + return 0x00000050U; +} +static inline u32 falcon_falcon_nxtctx_r(void) +{ + return 0x00000054U; +} +static inline u32 falcon_falcon_mailbox0_r(void) +{ + return 0x00000040U; +} +static inline u32 falcon_falcon_mailbox1_r(void) +{ + return 0x00000044U; +} +static inline u32 falcon_falcon_itfen_r(void) +{ + return 0x00000048U; +} +static inline u32 falcon_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 falcon_falcon_idlestate_r(void) +{ + return 0x0000004cU; +} +static inline u32 falcon_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 falcon_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 falcon_falcon_os_r(void) +{ + return 0x00000080U; +} +static inline u32 falcon_falcon_engctl_r(void) +{ + return 0x000000a4U; +} +static inline u32 falcon_falcon_cpuctl_r(void) +{ + return 0x00000100U; +} +static inline u32 falcon_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_cpuctl_sreset_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_cpuctl_hreset_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_stopped_m(void) +{ + return 0x1U << 5U; +} +static inline u32 falcon_falcon_imemc_r(u32 i) +{ + return 0x00000180U + i*16U; +} +static inline u32 falcon_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_imemc_secure_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 falcon_falcon_imemd_r(u32 i) +{ + return 0x00000184U + i*16U; +} +static inline u32 falcon_falcon_imemt_r(u32 i) +{ + return 0x00000188U + i*16U; +} +static inline u32 falcon_falcon_bootvec_r(void) +{ + return 0x00000104U; +} +static inline u32 falcon_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 falcon_falcon_dmactl_r(void) +{ + return 0x0000010cU; +} +static inline u32 falcon_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 falcon_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 falcon_falcon_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_hwcfg_r(void) +{ + return 0x00000108U; +} +static inline u32 falcon_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 falcon_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 falcon_falcon_dmatrfbase_r(void) +{ + return 0x00000110U; +} +static inline u32 falcon_falcon_dmatrfmoffs_r(void) +{ + return 0x00000114U; +} +static inline u32 falcon_falcon_dmatrfcmd_r(void) +{ + return 0x00000118U; +} +static inline u32 falcon_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 falcon_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 falcon_falcon_dmatrffboffs_r(void) +{ + return 0x0000011cU; +} +static inline u32 falcon_falcon_imstat_r(void) +{ + return 0x00000144U; +} +static inline u32 falcon_falcon_traceidx_r(void) +{ + return 0x00000148U; +} +static inline u32 falcon_falcon_traceidx_maxidx_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 falcon_falcon_traceidx_idx_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 falcon_falcon_tracepc_r(void) +{ + return 0x0000014cU; +} +static inline u32 falcon_falcon_tracepc_pc_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 falcon_falcon_exterraddr_r(void) +{ + return 0x00000168U; +} +static inline u32 falcon_falcon_exterrstat_r(void) +{ + return 0x0000016cU; +} +static inline u32 falcon_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 falcon_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 falcon_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 falcon_falcon_icd_cmd_r(void) +{ + return 0x00000200U; +} +static inline u32 falcon_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 falcon_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 falcon_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 falcon_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 falcon_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 falcon_falcon_icd_rdata_r(void) +{ + return 0x0000020cU; +} +static inline u32 falcon_falcon_dmemc_r(u32 i) +{ + return 0x000001c0U + i*8U; +} +static inline u32 falcon_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 falcon_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 falcon_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 falcon_falcon_dmemd_r(u32 i) +{ + return 0x000001c4U + i*8U; +} +static inline u32 falcon_falcon_debug1_r(void) +{ + return 0x00000090U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_s(void) +{ + return 1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_m(void) +{ + return 0x1U << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_init_f(void) +{ + return 0x0U; +} +static inline u32 falcon_falcon_debuginfo_r(void) +{ + return 0x00000094U; +} +#endif diff --git a/include/gk20a/hw_fb_gk20a.h b/include/gk20a/hw_fb_gk20a.h new file mode 100644 index 0000000..42df4f5 --- /dev/null +++ b/include/gk20a/hw_fb_gk20a.h @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fb_gk20a_h_ +#define _hw_fb_gk20a_h_ + +static inline u32 fb_mmu_ctrl_r(void) +{ + return 0x00100c80U; +} +static inline u32 fb_mmu_ctrl_vm_pg_size_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fb_mmu_ctrl_vm_pg_size_128kb_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_vm_pg_size_64kb_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_space_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 fb_mmu_invalidate_pdb_r(void) +{ + return 0x00100cb8U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_sys_mem_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_pdb_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_invalidate_r(void) +{ + return 0x00100cbcU; +} +static inline u32 fb_mmu_invalidate_all_va_true_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_invalidate_all_pdb_true_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_trigger_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_trigger_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_trigger_true_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_debug_wr_r(void) +{ + return 0x00100cc8U; +} +static inline u32 fb_mmu_debug_wr_aperture_s(void) +{ + return 2U; +} +static inline u32 fb_mmu_debug_wr_aperture_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_m(void) +{ + return 0x3U << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fb_mmu_debug_wr_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_wr_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_vol_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_wr_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_debug_wr_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_wr_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_rd_r(void) +{ + return 0x00100cccU; +} +static inline u32 fb_mmu_debug_rd_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_rd_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_rd_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_ctrl_r(void) +{ + return 0x00100cc4U; +} +static inline u32 fb_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 fb_mmu_debug_ctrl_debug_m(void) +{ + return 0x1U << 16U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_vpr_info_r(void) +{ + return 0x00100cd0U; +} +static inline u32 fb_mmu_vpr_info_fetch_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 fb_mmu_vpr_info_fetch_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_vpr_info_fetch_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_niso_flush_sysmem_addr_r(void) +{ + return 0x00100c10U; +} +#endif diff --git a/include/gk20a/hw_fifo_gk20a.h b/include/gk20a/hw_fifo_gk20a.h new file mode 100644 index 0000000..e61e386 --- /dev/null +++ b/include/gk20a/hw_fifo_gk20a.h @@ -0,0 +1,619 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fifo_gk20a_h_ +#define _hw_fifo_gk20a_h_ + +static inline u32 fifo_bar1_base_r(void) +{ + return 0x00002254U; +} +static inline u32 fifo_bar1_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_bar1_base_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_bar1_base_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 fifo_bar1_base_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_runlist_base_r(void) +{ + return 0x00002270U; +} +static inline u32 fifo_runlist_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_runlist_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fifo_runlist_base_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_runlist_base_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 fifo_runlist_r(void) +{ + return 0x00002274U; +} +static inline u32 fifo_runlist_engine_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 fifo_eng_runlist_base_r(u32 i) +{ + return 0x00002280U + i*8U; +} +static inline u32 fifo_eng_runlist_base__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_eng_runlist_r(u32 i) +{ + return 0x00002284U + i*8U; +} +static inline u32 fifo_eng_runlist__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_eng_runlist_length_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fifo_eng_runlist_length_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 fifo_eng_runlist_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_runlist_timeslice_r(u32 i) +{ + return 0x00002310U + i*4U; +} +static inline u32 fifo_runlist_timeslice_timeout_128_f(void) +{ + return 0x80U; +} +static inline u32 fifo_runlist_timeslice_timescale_3_f(void) +{ + return 0x3000U; +} +static inline u32 fifo_runlist_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_eng_timeout_r(void) +{ + return 0x00002a0cU; +} +static inline u32 fifo_eng_timeout_period_max_f(void) +{ + return 0x7fffffffU; +} +static inline u32 fifo_eng_timeout_detection_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_eng_timeout_detection_disabled_f(void) +{ + return 0x0U; +} +static inline u32 fifo_pb_timeslice_r(u32 i) +{ + return 0x00002350U + i*4U; +} +static inline u32 fifo_pb_timeslice_timeout_16_f(void) +{ + return 0x10U; +} +static inline u32 fifo_pb_timeslice_timescale_0_f(void) +{ + return 0x0U; +} +static inline u32 fifo_pb_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_pbdma_map_r(u32 i) +{ + return 0x00002390U + i*4U; +} +static inline u32 fifo_intr_0_r(void) +{ + return 0x00002100U; +} +static inline u32 fifo_intr_0_bind_error_pending_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_bind_error_reset_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_pio_error_pending_f(void) +{ + return 0x10U; +} +static inline u32 fifo_intr_0_pio_error_reset_f(void) +{ + return 0x10U; +} +static inline u32 fifo_intr_0_sched_error_pending_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_sched_error_reset_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_chsw_error_pending_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_chsw_error_reset_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_fb_flush_timeout_pending_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_fb_flush_timeout_reset_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_lb_error_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_lb_error_reset_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_dropped_mmu_fault_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 fifo_intr_0_dropped_mmu_fault_reset_f(void) +{ + return 0x8000000U; +} +static inline u32 fifo_intr_0_mmu_fault_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_intr_0_pbdma_intr_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_intr_0_runlist_event_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 fifo_intr_0_channel_intr_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_intr_en_0_r(void) +{ + return 0x00002140U; +} +static inline u32 fifo_intr_en_0_sched_error_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_intr_en_0_sched_error_m(void) +{ + return 0x1U << 8U; +} +static inline u32 fifo_intr_en_0_mmu_fault_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 fifo_intr_en_0_mmu_fault_m(void) +{ + return 0x1U << 28U; +} +static inline u32 fifo_intr_en_1_r(void) +{ + return 0x00002528U; +} +static inline u32 fifo_intr_bind_error_r(void) +{ + return 0x0000252cU; +} +static inline u32 fifo_intr_sched_error_r(void) +{ + return 0x0000254cU; +} +static inline u32 fifo_intr_sched_error_code_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fifo_intr_sched_error_code_ctxsw_timeout_v(void) +{ + return 0x0000000aU; +} +static inline u32 fifo_intr_chsw_error_r(void) +{ + return 0x0000256cU; +} +static inline u32 fifo_intr_mmu_fault_id_r(void) +{ + return 0x0000259cU; +} +static inline u32 fifo_intr_mmu_fault_eng_id_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_intr_mmu_fault_eng_id_graphics_f(void) +{ + return 0x0U; +} +static inline u32 fifo_intr_mmu_fault_inst_r(u32 i) +{ + return 0x00002800U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_inst_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 fifo_intr_mmu_fault_inst_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_intr_mmu_fault_lo_r(u32 i) +{ + return 0x00002804U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_hi_r(u32 i) +{ + return 0x00002808U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_info_r(u32 i) +{ + return 0x0000280cU + i*16U; +} +static inline u32 fifo_intr_mmu_fault_info_type_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 fifo_intr_mmu_fault_info_write_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 fifo_intr_mmu_fault_info_engine_subid_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 fifo_intr_mmu_fault_info_engine_subid_gpc_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_intr_mmu_fault_info_engine_subid_hub_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_mmu_fault_info_client_v(u32 r) +{ + return (r >> 8U) & 0x1fU; +} +static inline u32 fifo_intr_pbdma_id_r(void) +{ + return 0x000025a0U; +} +static inline u32 fifo_intr_pbdma_id_status_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_intr_pbdma_id_status_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fifo_intr_pbdma_id_status__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_runlist_r(void) +{ + return 0x00002a00U; +} +static inline u32 fifo_fb_timeout_r(void) +{ + return 0x00002a04U; +} +static inline u32 fifo_fb_timeout_period_m(void) +{ + return 0x3fffffffU << 0U; +} +static inline u32 fifo_fb_timeout_period_max_f(void) +{ + return 0x3fffffffU; +} +static inline u32 fifo_pb_timeout_r(void) +{ + return 0x00002a08U; +} +static inline u32 fifo_pb_timeout_detection_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_error_sched_disable_r(void) +{ + return 0x0000262cU; +} +static inline u32 fifo_sched_disable_r(void) +{ + return 0x00002630U; +} +static inline u32 fifo_sched_disable_runlist_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_sched_disable_runlist_m(u32 i) +{ + return 0x1U << (0U + i*1U); +} +static inline u32 fifo_sched_disable_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_preempt_r(void) +{ + return 0x00002634U; +} +static inline u32 fifo_preempt_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_preempt_type_channel_f(void) +{ + return 0x0U; +} +static inline u32 fifo_preempt_type_tsg_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_preempt_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_preempt_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_trigger_mmu_fault_r(u32 i) +{ + return 0x00002a30U + i*4U; +} +static inline u32 fifo_trigger_mmu_fault_id_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 fifo_trigger_mmu_fault_enable_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_engine_status_r(u32 i) +{ + return 0x00002640U + i*8U; +} +static inline u32 fifo_engine_status__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fifo_engine_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_engine_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_engine_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_engine_status_ctx_status_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_ctx_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_engine_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_engine_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_engine_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_faulted_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fifo_engine_status_faulted_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_engine_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fifo_engine_status_engine_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_engine_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_f(void) +{ + return 0x8000U; +} +static inline u32 fifo_pbdma_status_r(u32 i) +{ + return 0x00003080U + i*4U; +} +static inline u32 fifo_pbdma_status__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_pbdma_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_pbdma_status_chan_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_pbdma_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_pbdma_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_chsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_pbdma_status_chsw_in_progress_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/gk20a/hw_flush_gk20a.h b/include/gk20a/hw_flush_gk20a.h new file mode 100644 index 0000000..d270b5f --- /dev/null +++ b/include/gk20a/hw_flush_gk20a.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_flush_gk20a_h_ +#define _hw_flush_gk20a_h_ + +static inline u32 flush_l2_system_invalidate_r(void) +{ + return 0x00070004U; +} +static inline u32 flush_l2_system_invalidate_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_r(void) +{ + return 0x00070010U; +} +static inline u32 flush_l2_flush_dirty_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_r(void) +{ + return 0x0007000cU; +} +static inline u32 flush_l2_clean_comptags_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_r(void) +{ + return 0x00070000U; +} +static inline u32 flush_fb_flush_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_fb_flush_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_fb_flush_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_fb_flush_outstanding_true_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/gk20a/hw_gmmu_gk20a.h b/include/gk20a/hw_gmmu_gk20a.h new file mode 100644 index 0000000..a788d1d --- /dev/null +++ b/include/gk20a/hw_gmmu_gk20a.h @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2012-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gmmu_gk20a_h_ +#define _hw_gmmu_gk20a_h_ + +static inline u32 gmmu_pde_aperture_big_w(void) +{ + return 0U; +} +static inline u32 gmmu_pde_aperture_big_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_aperture_big_video_memory_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pde_aperture_big_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_pde_aperture_big_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 gmmu_pde_size_w(void) +{ + return 0U; +} +static inline u32 gmmu_pde_size_full_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_address_big_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_pde_address_big_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_pde_aperture_small_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_aperture_small_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_aperture_small_video_memory_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pde_aperture_small_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_pde_aperture_small_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 gmmu_pde_vol_small_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_vol_small_true_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_pde_vol_small_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_vol_big_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_vol_big_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_pde_vol_big_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_address_small_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_pde_address_small_sys_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_pde__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_pte__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_pte_valid_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_valid_true_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pte_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_privilege_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_privilege_true_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_pte_privilege_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_address_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_pte_address_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_address_vid_f(u32 v) +{ + return (v & 0x1ffffffU) << 4U; +} +static inline u32 gmmu_pte_address_vid_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_vol_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_vol_true_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pte_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_aperture_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_aperture_video_memory_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_aperture_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_pte_aperture_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_pte_read_only_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_read_only_true_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_pte_write_disable_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_write_disable_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gmmu_pte_read_disable_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_read_disable_true_f(void) +{ + return 0x40000000U; +} +static inline u32 gmmu_pte_comptagline_s(void) +{ + return 17U; +} +static inline u32 gmmu_pte_comptagline_f(u32 v) +{ + return (v & 0x1ffffU) << 12U; +} +static inline u32 gmmu_pte_comptagline_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_pte_kind_f(u32 v) +{ + return (v & 0xffU) << 4U; +} +static inline u32 gmmu_pte_kind_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_kind_invalid_v(void) +{ + return 0x000000ffU; +} +static inline u32 gmmu_pte_kind_pitch_v(void) +{ + return 0x00000000U; +} +#endif diff --git a/include/gk20a/hw_gr_gk20a.h b/include/gk20a/hw_gr_gk20a.h new file mode 100644 index 0000000..826108f --- /dev/null +++ b/include/gk20a/hw_gr_gk20a.h @@ -0,0 +1,3807 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gr_gk20a_h_ +#define _hw_gr_gk20a_h_ + +static inline u32 gr_intr_r(void) +{ + return 0x00400100U; +} +static inline u32 gr_intr_notify_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_notify_reset_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_semaphore_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_semaphore_reset_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_semaphore_timeout_not_pending_f(void) +{ + return 0x0U; +} +static inline u32 gr_intr_semaphore_timeout_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_intr_semaphore_timeout_reset_f(void) +{ + return 0x4U; +} +static inline u32 gr_intr_illegal_method_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_method_reset_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_notify_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_illegal_notify_reset_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 gr_intr_firmware_method_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_firmware_method_reset_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_illegal_class_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_illegal_class_reset_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_fecs_error_pending_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_fecs_error_reset_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_class_error_pending_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_class_error_reset_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_exception_pending_f(void) +{ + return 0x200000U; +} +static inline u32 gr_intr_exception_reset_f(void) +{ + return 0x200000U; +} +static inline u32 gr_fecs_intr_r(void) +{ + return 0x00400144U; +} +static inline u32 gr_class_error_r(void) +{ + return 0x00400110U; +} +static inline u32 gr_class_error_code_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_intr_nonstall_r(void) +{ + return 0x00400120U; +} +static inline u32 gr_intr_nonstall_trap_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_en_r(void) +{ + return 0x0040013cU; +} +static inline u32 gr_exception_r(void) +{ + return 0x00400108U; +} +static inline u32 gr_exception_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception_gpc_m(void) +{ + return 0x1U << 24U; +} +static inline u32 gr_exception_memfmt_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_exception_ds_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_exception_sked_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_exception_pd_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_exception_scc_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_exception_ssync_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_exception_mme_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_exception1_r(void) +{ + return 0x00400118U; +} +static inline u32 gr_exception1_gpc_0_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_exception2_r(void) +{ + return 0x0040011cU; +} +static inline u32 gr_exception_en_r(void) +{ + return 0x00400138U; +} +static inline u32 gr_exception_en_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception1_en_r(void) +{ + return 0x00400130U; +} +static inline u32 gr_exception2_en_r(void) +{ + return 0x00400134U; +} +static inline u32 gr_gpfifo_ctl_r(void) +{ + return 0x00400500U; +} +static inline u32 gr_gpfifo_ctl_access_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpfifo_ctl_access_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpfifo_ctl_access_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpfifo_status_r(void) +{ + return 0x00400504U; +} +static inline u32 gr_trapped_addr_r(void) +{ + return 0x00400704U; +} +static inline u32 gr_trapped_addr_mthd_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 gr_trapped_addr_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 gr_trapped_addr_mme_generated_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 gr_trapped_addr_datahigh_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 gr_trapped_addr_priv_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 gr_trapped_addr_status_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_trapped_data_lo_r(void) +{ + return 0x00400708U; +} +static inline u32 gr_trapped_data_hi_r(void) +{ + return 0x0040070cU; +} +static inline u32 gr_trapped_data_mme_r(void) +{ + return 0x00400710U; +} +static inline u32 gr_trapped_data_mme_pc_v(u32 r) +{ + return (r >> 0U) & 0x7ffU; +} +static inline u32 gr_status_r(void) +{ + return 0x00400700U; +} +static inline u32 gr_status_fe_method_upper_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_status_fe_gi_v(u32 r) +{ + return (r >> 21U) & 0x1U; +} +static inline u32 gr_status_mask_r(void) +{ + return 0x00400610U; +} +static inline u32 gr_status_1_r(void) +{ + return 0x00400604U; +} +static inline u32 gr_status_2_r(void) +{ + return 0x00400608U; +} +static inline u32 gr_engine_status_r(void) +{ + return 0x0040060cU; +} +static inline u32 gr_engine_status_value_busy_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_be0_becs_be_exception_r(void) +{ + return 0x00410204U; +} +static inline u32 gr_pri_be0_becs_be_exception_en_r(void) +{ + return 0x00410208U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_en_r(void) +{ + return 0x00502c94U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_activity_0_r(void) +{ + return 0x00400380U; +} +static inline u32 gr_activity_1_r(void) +{ + return 0x00400384U; +} +static inline u32 gr_activity_2_r(void) +{ + return 0x00400388U; +} +static inline u32 gr_activity_4_r(void) +{ + return 0x00400390U; +} +static inline u32 gr_pri_gpc0_gcc_dbg_r(void) +{ + return 0x00501000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_r(void) +{ + return 0x00419000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_invalidate_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cache_control_r(void) +{ + return 0x005046a4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_r(void) +{ + return 0x00419ea4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_invalidate_cache_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_sked_activity_r(void) +{ + return 0x00407054U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity0_r(void) +{ + return 0x00502c80U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity1_r(void) +{ + return 0x00502c84U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity2_r(void) +{ + return 0x00502c88U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity3_r(void) +{ + return 0x00502c8cU; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x00504500U; +} +static inline u32 gr_pri_gpc0_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00501d00U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_0_r(void) +{ + return 0x0041ac80U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_1_r(void) +{ + return 0x0041ac84U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_2_r(void) +{ + return 0x0041ac88U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_3_r(void) +{ + return 0x0041ac8cU; +} +static inline u32 gr_pri_gpcs_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x0041c500U; +} +static inline u32 gr_pri_gpcs_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00419d00U; +} +static inline u32 gr_pri_be0_becs_be_activity0_r(void) +{ + return 0x00410200U; +} +static inline u32 gr_pri_bes_becs_be_activity0_r(void) +{ + return 0x00408a00U; +} +static inline u32 gr_pri_ds_mpipe_status_r(void) +{ + return 0x00405858U; +} +static inline u32 gr_pri_fe_go_idle_on_status_r(void) +{ + return 0x00404150U; +} +static inline u32 gr_pri_fe_go_idle_check_r(void) +{ + return 0x00404158U; +} +static inline u32 gr_pri_fe_go_idle_info_r(void) +{ + return 0x00404194U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_tex_subunits_status_r(void) +{ + return 0x00504238U; +} +static inline u32 gr_pri_be0_crop_status1_r(void) +{ + return 0x00410134U; +} +static inline u32 gr_pri_bes_crop_status1_r(void) +{ + return 0x00408934U; +} +static inline u32 gr_pri_be0_zrop_status_r(void) +{ + return 0x00410048U; +} +static inline u32 gr_pri_be0_zrop_status2_r(void) +{ + return 0x0041004cU; +} +static inline u32 gr_pri_bes_zrop_status_r(void) +{ + return 0x00408848U; +} +static inline u32 gr_pri_bes_zrop_status2_r(void) +{ + return 0x0040884cU; +} +static inline u32 gr_pipe_bundle_address_r(void) +{ + return 0x00400200U; +} +static inline u32 gr_pipe_bundle_address_value_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pipe_bundle_data_r(void) +{ + return 0x00400204U; +} +static inline u32 gr_pipe_bundle_config_r(void) +{ + return 0x00400208U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_r(void) +{ + return 0x00404000U; +} +static inline u32 gr_fe_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_fe_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_info_r(void) +{ + return 0x004041b0U; +} +static inline u32 gr_fe_go_idle_timeout_r(void) +{ + return 0x00404154U; +} +static inline u32 gr_fe_go_idle_timeout_count_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fe_go_idle_timeout_count_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_go_idle_timeout_count_prod_f(void) +{ + return 0x800U; +} +static inline u32 gr_fe_object_table_r(u32 i) +{ + return 0x00404200U + i*4U; +} +static inline u32 gr_fe_object_table_nvclass_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_mme_shadow_raw_index_r(void) +{ + return 0x00404488U; +} +static inline u32 gr_pri_mme_shadow_raw_index_write_trigger_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pri_mme_shadow_raw_data_r(void) +{ + return 0x0040448cU; +} +static inline u32 gr_mme_hww_esr_r(void) +{ + return 0x00404490U; +} +static inline u32 gr_mme_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_mme_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_mme_hww_esr_info_r(void) +{ + return 0x00404494U; +} +static inline u32 gr_memfmt_hww_esr_r(void) +{ + return 0x00404600U; +} +static inline u32 gr_memfmt_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_memfmt_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fecs_cpuctl_r(void) +{ + return 0x00409100U; +} +static inline u32 gr_fecs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_dmactl_r(void) +{ + return 0x0040910cU; +} +static inline u32 gr_fecs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_fecs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_fecs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_fecs_os_r(void) +{ + return 0x00409080U; +} +static inline u32 gr_fecs_idlestate_r(void) +{ + return 0x0040904cU; +} +static inline u32 gr_fecs_mailbox0_r(void) +{ + return 0x00409040U; +} +static inline u32 gr_fecs_mailbox1_r(void) +{ + return 0x00409044U; +} +static inline u32 gr_fecs_irqstat_r(void) +{ + return 0x00409008U; +} +static inline u32 gr_fecs_irqmode_r(void) +{ + return 0x0040900cU; +} +static inline u32 gr_fecs_irqmask_r(void) +{ + return 0x00409018U; +} +static inline u32 gr_fecs_irqdest_r(void) +{ + return 0x0040901cU; +} +static inline u32 gr_fecs_curctx_r(void) +{ + return 0x00409050U; +} +static inline u32 gr_fecs_nxtctx_r(void) +{ + return 0x00409054U; +} +static inline u32 gr_fecs_engctl_r(void) +{ + return 0x004090a4U; +} +static inline u32 gr_fecs_debug1_r(void) +{ + return 0x00409090U; +} +static inline u32 gr_fecs_debuginfo_r(void) +{ + return 0x00409094U; +} +static inline u32 gr_fecs_icd_cmd_r(void) +{ + return 0x00409200U; +} +static inline u32 gr_fecs_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 gr_fecs_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 gr_fecs_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 gr_fecs_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 gr_fecs_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 gr_fecs_icd_rdata_r(void) +{ + return 0x0040920cU; +} +static inline u32 gr_fecs_imemc_r(u32 i) +{ + return 0x00409180U + i*16U; +} +static inline u32 gr_fecs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_imemd_r(u32 i) +{ + return 0x00409184U + i*16U; +} +static inline u32 gr_fecs_imemt_r(u32 i) +{ + return 0x00409188U + i*16U; +} +static inline u32 gr_fecs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_dmemc_r(u32 i) +{ + return 0x004091c0U + i*8U; +} +static inline u32 gr_fecs_dmemc_offs_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 gr_fecs_dmemc_offs_v(u32 r) +{ + return (r >> 2U) & 0x3fU; +} +static inline u32 gr_fecs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_dmemd_r(u32 i) +{ + return 0x004091c4U + i*8U; +} +static inline u32 gr_fecs_dmatrfbase_r(void) +{ + return 0x00409110U; +} +static inline u32 gr_fecs_dmatrfmoffs_r(void) +{ + return 0x00409114U; +} +static inline u32 gr_fecs_dmatrffboffs_r(void) +{ + return 0x0040911cU; +} +static inline u32 gr_fecs_dmatrfcmd_r(void) +{ + return 0x00409118U; +} +static inline u32 gr_fecs_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_fecs_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_fecs_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_fecs_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_fecs_bootvec_r(void) +{ + return 0x00409104U; +} +static inline u32 gr_fecs_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_falcon_hwcfg_r(void) +{ + return 0x00409108U; +} +static inline u32 gr_gpcs_gpccs_falcon_hwcfg_r(void) +{ + return 0x0041a108U; +} +static inline u32 gr_fecs_falcon_rm_r(void) +{ + return 0x00409084U; +} +static inline u32 gr_fecs_current_ctx_r(void) +{ + return 0x00409b00U; +} +static inline u32 gr_fecs_current_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_current_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_current_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_current_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_current_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_current_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_current_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_current_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_current_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_current_ctx_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_method_data_r(void) +{ + return 0x00409500U; +} +static inline u32 gr_fecs_method_push_r(void) +{ + return 0x00409504U; +} +static inline u32 gr_fecs_method_push_adr_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_v(void) +{ + return 0x00000003U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_f(void) +{ + return 0x3U; +} +static inline u32 gr_fecs_method_push_adr_discover_image_size_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_method_push_adr_wfi_golden_save_v(void) +{ + return 0x00000009U; +} +static inline u32 gr_fecs_method_push_adr_restore_golden_v(void) +{ + return 0x00000015U; +} +static inline u32 gr_fecs_method_push_adr_discover_zcull_image_size_v(void) +{ + return 0x00000016U; +} +static inline u32 gr_fecs_method_push_adr_discover_pm_image_size_v(void) +{ + return 0x00000025U; +} +static inline u32 gr_fecs_method_push_adr_discover_reglist_image_size_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_bind_instance_v(void) +{ + return 0x00000031U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_virtual_address_v(void) +{ + return 0x00000032U; +} +static inline u32 gr_fecs_method_push_adr_stop_ctxsw_v(void) +{ + return 0x00000038U; +} +static inline u32 gr_fecs_method_push_adr_start_ctxsw_v(void) +{ + return 0x00000039U; +} +static inline u32 gr_fecs_method_push_adr_set_watchdog_timeout_f(void) +{ + return 0x21U; +} +static inline u32 gr_fecs_method_push_adr_halt_pipeline_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_fecs_host_int_status_r(void) +{ + return 0x00409c18U; +} +static inline u32 gr_fecs_host_int_status_fault_during_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_fecs_host_int_status_umimp_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 gr_fecs_host_int_status_umimp_illegal_method_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 gr_fecs_host_int_status_watchdog_active_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_host_int_status_ctxsw_intr_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_host_int_clear_r(void) +{ + return 0x00409c20U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_clear_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_r(void) +{ + return 0x00409c24U; +} +static inline u32 gr_fecs_host_int_enable_ctxsw_intr1_enable_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_fault_during_ctxsw_enable_f(void) +{ + return 0x10000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_firmware_method_enable_f(void) +{ + return 0x20000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_illegal_method_enable_f(void) +{ + return 0x40000U; +} +static inline u32 gr_fecs_host_int_enable_watchdog_enable_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_r(void) +{ + return 0x00409614U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_engine_reset_disabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_engine_reset_disabled_f(void) +{ + return 0x20U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_engine_reset_disabled_f(void) +{ + return 0x40U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_disabled_f(void) +{ + return 0x100U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_disabled_f(void) +{ + return 0x200U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_disabled_f(void) +{ + return 0x400U; +} +static inline u32 gr_fecs_ctx_state_store_major_rev_id_r(void) +{ + return 0x0040960cU; +} +static inline u32 gr_fecs_ctxsw_mailbox_r(u32 i) +{ + return 0x00409800U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_fail_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_r(u32 i) +{ + return 0x00409820U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_r(u32 i) +{ + return 0x00409840U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_fs_r(void) +{ + return 0x00409604U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_fs_num_available_fbps_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_fbps_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_m(void) +{ + return 0x1fU << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_fecs_cfg_r(void) +{ + return 0x00409620U; +} +static inline u32 gr_fecs_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_fecs_rc_lanes_r(void) +{ + return 0x00409880U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_fecs_ctxsw_status_1_r(void) +{ + return 0x00409400U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_m(void) +{ + return 0x1U << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_adr_r(void) +{ + return 0x00409a24U; +} +static inline u32 gr_fecs_new_ctx_r(void) +{ + return 0x00409b04U; +} +static inline u32 gr_fecs_new_ctx_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_new_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_new_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_new_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_new_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_new_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_new_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_new_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_new_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_new_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_new_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_ptr_r(void) +{ + return 0x00409a0cU; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_arb_ctx_cmd_r(void) +{ + return 0x00409a10U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_ctxsw_status_fe_0_r(void) +{ + return 0x00409c00U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_gpc_0_r(void) +{ + return 0x00502c04U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_1_r(void) +{ + return 0x00502400U; +} +static inline u32 gr_fecs_ctxsw_idlestate_r(void) +{ + return 0x00409420U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_idlestate_r(void) +{ + return 0x00502420U; +} +static inline u32 gr_rstr2d_gpc_map0_r(void) +{ + return 0x0040780cU; +} +static inline u32 gr_rstr2d_gpc_map1_r(void) +{ + return 0x00407810U; +} +static inline u32 gr_rstr2d_gpc_map2_r(void) +{ + return 0x00407814U; +} +static inline u32 gr_rstr2d_gpc_map3_r(void) +{ + return 0x00407818U; +} +static inline u32 gr_rstr2d_gpc_map4_r(void) +{ + return 0x0040781cU; +} +static inline u32 gr_rstr2d_gpc_map5_r(void) +{ + return 0x00407820U; +} +static inline u32 gr_rstr2d_map_table_cfg_r(void) +{ + return 0x004078bcU; +} +static inline u32 gr_rstr2d_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_rstr2d_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_hww_esr_r(void) +{ + return 0x00406018U; +} +static inline u32 gr_pd_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pd_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_num_tpc_per_gpc_r(u32 i) +{ + return 0x00406028U + i*4U; +} +static inline u32 gr_pd_num_tpc_per_gpc__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count1_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count2_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count3_f(u32 v) +{ + return (v & 0xfU) << 12U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count4_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count5_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count6_f(u32 v) +{ + return (v & 0xfU) << 24U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count7_f(u32 v) +{ + return (v & 0xfU) << 28U; +} +static inline u32 gr_pd_ab_dist_cfg0_r(void) +{ + return 0x004064c0U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_en_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_dis_f(void) +{ + return 0x0U; +} +static inline u32 gr_pd_ab_dist_cfg1_r(void) +{ + return 0x004064c4U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_batches_init_f(void) +{ + return 0xffffU; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_f(u32 v) +{ + return (v & 0x7ffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_granularity_v(void) +{ + return 0x00000080U; +} +static inline u32 gr_pd_ab_dist_cfg2_r(void) +{ + return 0x004064c8U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_init_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_f(u32 v) +{ + return (v & 0xfffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_scc_bundle_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_min_gpm_fifo_depths_v(void) +{ + return 0x00000062U; +} +static inline u32 gr_pd_pagepool_r(void) +{ + return 0x004064ccU; +} +static inline u32 gr_pd_pagepool_total_pages_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_pagepool_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_dist_skip_table_r(u32 i) +{ + return 0x004064d0U + i*4U; +} +static inline u32 gr_pd_dist_skip_table__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n0_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n1_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n2_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n3_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_pd_alpha_ratio_table_r(u32 i) +{ + return 0x00406800U + i*4U; +} +static inline u32 gr_pd_alpha_ratio_table__size_1_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_pd_alpha_ratio_table_gpc_4n0_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_alpha_ratio_table_gpc_4n1_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_alpha_ratio_table_gpc_4n2_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_pd_alpha_ratio_table_gpc_4n3_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_pd_beta_ratio_table_r(u32 i) +{ + return 0x00406c00U + i*4U; +} +static inline u32 gr_pd_beta_ratio_table__size_1_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_pd_beta_ratio_table_gpc_4n0_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_beta_ratio_table_gpc_4n1_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_beta_ratio_table_gpc_4n2_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_pd_beta_ratio_table_gpc_4n3_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_ds_debug_r(void) +{ + return 0x00405800U; +} +static inline u32 gr_ds_debug_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_debug_timeslice_mode_enable_f(void) +{ + return 0x8000000U; +} +static inline u32 gr_ds_zbc_color_r_r(void) +{ + return 0x00405804U; +} +static inline u32 gr_ds_zbc_color_r_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_g_r(void) +{ + return 0x00405808U; +} +static inline u32 gr_ds_zbc_color_g_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_b_r(void) +{ + return 0x0040580cU; +} +static inline u32 gr_ds_zbc_color_b_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_a_r(void) +{ + return 0x00405810U; +} +static inline u32 gr_ds_zbc_color_a_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_r(void) +{ + return 0x00405814U; +} +static inline u32 gr_ds_zbc_color_fmt_val_f(u32 v) +{ + return (v & 0x7fU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_zero_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_color_fmt_val_unorm_one_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_ds_zbc_color_fmt_val_rf32_gf32_bf32_af32_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_ds_zbc_color_fmt_val_a8_b8_g8_r8_v(void) +{ + return 0x00000028U; +} +static inline u32 gr_ds_zbc_z_r(void) +{ + return 0x00405818U; +} +static inline u32 gr_ds_zbc_z_val_s(void) +{ + return 32U; +} +static inline u32 gr_ds_zbc_z_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_z_val_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_ds_zbc_z_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_ds_zbc_z_val__init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_ds_zbc_z_val__init_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_r(void) +{ + return 0x0040581cU; +} +static inline u32 gr_ds_zbc_z_fmt_val_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_fp32_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_tbl_index_r(void) +{ + return 0x00405820U; +} +static inline u32 gr_ds_zbc_tbl_index_val_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_ds_zbc_tbl_ld_r(void) +{ + return 0x00405824U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_c_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_z_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_zbc_tbl_ld_action_write_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_trigger_active_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_tga_constraintlogic_r(void) +{ + return 0x00405830U; +} +static inline u32 gr_ds_tga_constraintlogic_beta_cbsize_f(u32 v) +{ + return (v & 0xfffU) << 16U; +} +static inline u32 gr_ds_tga_constraintlogic_alpha_cbsize_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_ds_hww_esr_r(void) +{ + return 0x00405840U; +} +static inline u32 gr_ds_hww_esr_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_report_mask_r(void) +{ + return 0x00405844U; +} +static inline u32 gr_ds_hww_report_mask_sph0_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_hww_report_mask_sph1_err_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_ds_hww_report_mask_sph2_err_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_hww_report_mask_sph3_err_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_ds_hww_report_mask_sph4_err_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_ds_hww_report_mask_sph5_err_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_ds_hww_report_mask_sph6_err_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_ds_hww_report_mask_sph7_err_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_ds_hww_report_mask_sph8_err_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_ds_hww_report_mask_sph9_err_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_ds_hww_report_mask_sph10_err_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_ds_hww_report_mask_sph11_err_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_ds_hww_report_mask_sph12_err_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_ds_hww_report_mask_sph13_err_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_ds_hww_report_mask_sph14_err_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_ds_hww_report_mask_sph15_err_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_ds_hww_report_mask_sph16_err_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_ds_hww_report_mask_sph17_err_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_ds_hww_report_mask_sph18_err_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_ds_hww_report_mask_sph19_err_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_ds_hww_report_mask_sph20_err_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_ds_hww_report_mask_sph21_err_report_f(void) +{ + return 0x200000U; +} +static inline u32 gr_ds_hww_report_mask_sph22_err_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_ds_hww_report_mask_sph23_err_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_ds_num_tpc_per_gpc_r(u32 i) +{ + return 0x00405870U + i*4U; +} +static inline u32 gr_scc_bundle_cb_base_r(void) +{ + return 0x00408004U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_bundle_cb_size_r(void) +{ + return 0x00408008U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b__prod_v(void) +{ + return 0x00000018U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_scc_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_pagepool_base_r(void) +{ + return 0x0040800cU; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_pagepool_r(void) +{ + return 0x00408010U; +} +static inline u32 gr_scc_pagepool_total_pages_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_value_v(void) +{ + return 0x00000080U; +} +static inline u32 gr_scc_pagepool_total_pages_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_s(void) +{ + return 8U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_m(void) +{ + return 0xffU << 8U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 gr_scc_pagepool_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_init_r(void) +{ + return 0x0040802cU; +} +static inline u32 gr_scc_init_ram_trigger_f(void) +{ + return 0x1U; +} +static inline u32 gr_scc_hww_esr_r(void) +{ + return 0x00408030U; +} +static inline u32 gr_scc_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_scc_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_sked_hww_esr_r(void) +{ + return 0x00407020U; +} +static inline u32 gr_sked_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_cwd_fs_r(void) +{ + return 0x00405b00U; +} +static inline u32 gr_cwd_fs_num_gpcs_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_fs_num_tpcs_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpc0_fs_gpc_r(void) +{ + return 0x00502608U; +} +static inline u32 gr_gpc0_fs_gpc_num_available_tpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_gpc0_fs_gpc_num_available_zculls_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_gpc0_cfg_r(void) +{ + return 0x00502620U; +} +static inline u32 gr_gpc0_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpccs_rc_lanes_r(void) +{ + return 0x00502880U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_rc_lane_size_r(u32 i) +{ + return 0x00502910U + i*0U; +} +static inline u32 gr_gpccs_rc_lane_size__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpccs_rc_lane_size_v_s(void) +{ + return 24U; +} +static inline u32 gr_gpccs_rc_lane_size_v_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_zcull_fs_r(void) +{ + return 0x00500910U; +} +static inline u32 gr_gpc0_zcull_fs_num_sms_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 gr_gpc0_zcull_fs_num_active_banks_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_gpc0_zcull_ram_addr_r(void) +{ + return 0x00500914U; +} +static inline u32 gr_gpc0_zcull_ram_addr_tiles_per_hypertile_row_per_gpc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_gpc0_zcull_ram_addr_row_offset_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_r(void) +{ + return 0x00500918U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative__max_v(void) +{ + return 0x00800000U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_r(void) +{ + return 0x00500920U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_num_aliquots_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_zcsize_r(u32 i) +{ + return 0x00500a04U + i*32U; +} +static inline u32 gr_gpc0_zcull_zcsize_height_subregion__multiple_v(void) +{ + return 0x00000040U; +} +static inline u32 gr_gpc0_zcull_zcsize_width_subregion__multiple_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpc0_gpm_pd_active_tpcs_r(void) +{ + return 0x00500c08U; +} +static inline u32 gr_gpc0_gpm_pd_active_tpcs_num_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_r(u32 i) +{ + return 0x00500c10U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_id_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_r(u32 i) +{ + return 0x00500c30U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_mask_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_gpm_sd_active_tpcs_r(void) +{ + return 0x00500c8cU; +} +static inline u32 gr_gpc0_gpm_sd_active_tpcs_num_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_r(void) +{ + return 0x00504088U; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_value_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_l1c_cfg_smid_r(void) +{ + return 0x005044e8U; +} +static inline u32 gr_gpc0_tpc0_l1c_cfg_smid_value_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_r(void) +{ + return 0x00504698U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_sm_id_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_sm_id_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_r(void) +{ + return 0x0050469cU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_warp_count_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_spa_version_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_spa_version_smkepler_lp_v(void) +{ + return 0x0000000cU; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_r(void) +{ + return 0x00503018U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_true_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_r(void) +{ + return 0x005030c0U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_start_offset_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_start_offset_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_start_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_size_f(u32 v) +{ + return (v & 0xfffU) << 16U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_size_m(void) +{ + return 0xfffU << 16U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_size_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_size_default_v(void) +{ + return 0x00000240U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_size_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_timeslice_mode_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_r(void) +{ + return 0x005030e4U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_start_offset_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_size_f(u32 v) +{ + return (v & 0xfffU) << 16U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_size_m(void) +{ + return 0xfffU << 16U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_size_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_size_default_v(void) +{ + return 0x00000648U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_size_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpccs_falcon_addr_r(void) +{ + return 0x0041a0acU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_msb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_v(u32 r) +{ + return (r >> 6U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_s(void) +{ + return 12U; +} +static inline u32 gr_gpccs_falcon_addr_ext_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_m(void) +{ + return 0xfffU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_gpccs_cpuctl_r(void) +{ + return 0x0041a100U; +} +static inline u32 gr_gpccs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_gpccs_dmactl_r(void) +{ + return 0x0041a10cU; +} +static inline u32 gr_gpccs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpccs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpccs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpccs_imemc_r(u32 i) +{ + return 0x0041a180U + i*16U; +} +static inline u32 gr_gpccs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_imemd_r(u32 i) +{ + return 0x0041a184U + i*16U; +} +static inline u32 gr_gpccs_imemt_r(u32 i) +{ + return 0x0041a188U + i*16U; +} +static inline u32 gr_gpccs_imemt__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_gpccs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpccs_dmemc_r(u32 i) +{ + return 0x0041a1c0U + i*8U; +} +static inline u32 gr_gpccs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_dmemd_r(u32 i) +{ + return 0x0041a1c4U + i*8U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_r(u32 i) +{ + return 0x0041a800U + i*4U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_r(void) +{ + return 0x00418808U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_s(void) +{ + return 32U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_r(void) +{ + return 0x0041880cU; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_s(void) +{ + return 11U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_m(void) +{ + return 0x7ffU << 0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_v(u32 r) +{ + return (r >> 0U) & 0x7ffU; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b__prod_v(void) +{ + return 0x00000018U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b__prod_f(void) +{ + return 0x18U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_s(void) +{ + return 1U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_r(void) +{ + return 0x00418810U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_align_bits_v(void) +{ + return 0x0000000cU; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_crstr_gpc_map0_r(void) +{ + return 0x00418b08U; +} +static inline u32 gr_crstr_gpc_map0_tile0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map0_tile1_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map0_tile2_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map0_tile3_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map0_tile4_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map0_tile5_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map1_r(void) +{ + return 0x00418b0cU; +} +static inline u32 gr_crstr_gpc_map1_tile6_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map1_tile7_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map1_tile8_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map1_tile9_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map1_tile10_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map1_tile11_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map2_r(void) +{ + return 0x00418b10U; +} +static inline u32 gr_crstr_gpc_map2_tile12_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map2_tile13_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map2_tile14_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map2_tile15_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map2_tile16_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map2_tile17_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map3_r(void) +{ + return 0x00418b14U; +} +static inline u32 gr_crstr_gpc_map3_tile18_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map3_tile19_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map3_tile20_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map3_tile21_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map3_tile22_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map3_tile23_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map4_r(void) +{ + return 0x00418b18U; +} +static inline u32 gr_crstr_gpc_map4_tile24_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map4_tile25_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map4_tile26_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map4_tile27_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map4_tile28_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map4_tile29_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map5_r(void) +{ + return 0x00418b1cU; +} +static inline u32 gr_crstr_gpc_map5_tile30_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map5_tile31_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map5_tile32_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map5_tile33_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map5_tile34_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map5_tile35_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_map_table_cfg_r(void) +{ + return 0x00418bb8U; +} +static inline u32 gr_crstr_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_crstr_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_r(void) +{ + return 0x00418980U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_1_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_2_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_3_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_4_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_5_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_6_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_7_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_r(void) +{ + return 0x00418984U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_8_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_9_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_10_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_11_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_12_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_13_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_14_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_15_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_r(void) +{ + return 0x00418988U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_16_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_17_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_18_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_19_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_20_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_21_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_22_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_s(void) +{ + return 3U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_m(void) +{ + return 0x7U << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_v(u32 r) +{ + return (r >> 28U) & 0x7U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_r(void) +{ + return 0x0041898cU; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_24_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_25_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_26_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_27_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_28_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_29_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_30_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_31_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_r(void) +{ + return 0x00418c6cU; +} +static inline u32 gr_gpcs_gpm_pd_cfg_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_timeslice_mode_enable_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_r(void) +{ + return 0x00419004U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_gcc_pagepool_r(void) +{ + return 0x00419008U; +} +static inline u32 gr_gpcs_gcc_pagepool_total_pages_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_r(void) +{ + return 0x0041980cU; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_fast_mode_switch_true_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_r(void) +{ + return 0x00419848U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_r(void) +{ + return 0x00419c00U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_enabled_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_r(void) +{ + return 0x00419e44U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_stack_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_api_stack_error_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_ret_empty_stack_error_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_wrap_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_pc_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_overflow_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_immc_addr_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_reg_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_encoding_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_sph_instr_combo_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_reg_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_addr_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_addr_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_addr_space_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param2_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_ldc_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_geometry_sm_error_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_divergent_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_r(void) +{ + return 0x00419e4cU; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_sm_to_sm_fault_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_l1_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_multiple_warp_errors_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_physical_stack_overflow_error_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_int_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_pause_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_single_step_complete_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_r(void) +{ + return 0x00419d0cU; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_tex_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_r(void) +{ + return 0x0041ac94U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_tpc_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gcc_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_0_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_r(void) +{ + return 0x00504610U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_on_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_off_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_off_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_single_step_mode_enable_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_single_step_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_stop_on_any_warp_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_stop_on_any_sm_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_warp_valid_mask_r(void) +{ + return 0x00504614U; +} +static inline u32 gr_gpc0_tpc0_sm_warp_valid_mask_1_r(void) +{ + return 0x00504618U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_r(void) +{ + return 0x00504624U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_1_r(void) +{ + return 0x00504628U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_r(void) +{ + return 0x00504634U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_1_r(void) +{ + return 0x00504638U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_bpt_pause_mask_r(void) +{ + return 0x00419e24U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_r(void) +{ + return 0x0050460cU; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_sm_in_trap_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_locked_down_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_locked_down_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_r(void) +{ + return 0x00419e50U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_sm_to_sm_fault_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_l1_error_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_multiple_warp_errors_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_physical_stack_overflow_error_pending_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_timeout_error_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_r(void) +{ + return 0x00504650U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_sm_to_sm_fault_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_l1_error_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_multiple_warp_errors_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_physical_stack_overflow_error_pending_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_timeout_error_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_r(void) +{ + return 0x00504224U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_intr_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_r(void) +{ + return 0x00504648U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_none_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_none_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_halfctl_ctrl_r(void) +{ + return 0x00504770U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_r(void) +{ + return 0x00419f70U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_gpc0_tpc0_sm_debug_sfe_control_r(void) +{ + return 0x0050477cU; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_r(void) +{ + return 0x00419f7cU; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_r(void) +{ + return 0x0041be08U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_fast_mode_switch_true_f(void) +{ + return 0x4U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map0_r(void) +{ + return 0x0041bf00U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map1_r(void) +{ + return 0x0041bf04U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map2_r(void) +{ + return 0x0041bf08U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map3_r(void) +{ + return 0x0041bf0cU; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map4_r(void) +{ + return 0x0041bf10U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map5_r(void) +{ + return 0x0041bf14U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_r(void) +{ + return 0x0041bfd0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_num_entries_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_shift_value_f(u32 v) +{ + return (v & 0x7U) << 21U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff5_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 24U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_r(void) +{ + return 0x0041bfd4U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_r(void) +{ + return 0x0041bfe4U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff6_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff7_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 5U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff8_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 10U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff9_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 15U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff10_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 20U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff11_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 25U; +} +static inline u32 gr_gpcs_ppcs_cbm_cfg_r(void) +{ + return 0x0041bec0U; +} +static inline u32 gr_gpcs_ppcs_cbm_cfg_timeslice_mode_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_bes_zrop_settings_r(void) +{ + return 0x00408850U; +} +static inline u32 gr_bes_zrop_settings_num_active_fbps_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_bes_crop_settings_r(void) +{ + return 0x00408958U; +} +static inline u32 gr_bes_crop_settings_num_active_fbps_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_zcull_bytes_per_aliquot_per_gpu_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_header_bytes_per_gpc_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_subregion_header_bytes_per_gpc_v(void) +{ + return 0x000000c0U; +} +static inline u32 gr_zcull_subregion_qty_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel0_r(void) +{ + return 0x00504604U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel1_r(void) +{ + return 0x00504608U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control0_r(void) +{ + return 0x0050465cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control1_r(void) +{ + return 0x00504660U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control2_r(void) +{ + return 0x00504664U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control3_r(void) +{ + return 0x00504668U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control4_r(void) +{ + return 0x0050466cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control5_r(void) +{ + return 0x00504658U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_status_r(void) +{ + return 0x00504670U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_status1_r(void) +{ + return 0x00504694U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_control_r(void) +{ + return 0x00504730U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_control_r(void) +{ + return 0x00504734U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_control_r(void) +{ + return 0x00504738U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_control_r(void) +{ + return 0x0050473cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter4_control_r(void) +{ + return 0x00504740U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter5_control_r(void) +{ + return 0x00504744U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter6_control_r(void) +{ + return 0x00504748U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter7_control_r(void) +{ + return 0x0050474cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_r(void) +{ + return 0x00504674U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_r(void) +{ + return 0x00504678U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_r(void) +{ + return 0x0050467cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_r(void) +{ + return 0x00504680U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter4_r(void) +{ + return 0x00504684U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter5_r(void) +{ + return 0x00504688U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter6_r(void) +{ + return 0x0050468cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter7_r(void) +{ + return 0x00504690U; +} +static inline u32 gr_fe_pwr_mode_r(void) +{ + return 0x00404170U; +} +static inline u32 gr_fe_pwr_mode_mode_auto_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_pwr_mode_mode_force_on_f(void) +{ + return 0x2U; +} +static inline u32 gr_fe_pwr_mode_req_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_fe_pwr_mode_req_send_f(void) +{ + return 0x10U; +} +static inline u32 gr_fe_pwr_mode_req_done_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_l1c_dbg_r(void) +{ + return 0x005044b0U; +} +static inline u32 gr_gpc0_tpc0_l1c_dbg_cya15_en_f(void) +{ + return 0x8000000U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_r(void) +{ + return 0x00419ec8U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_tile_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_tile_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_phase_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_phase_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_tex_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_tex_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_timeout_m(void) +{ + return 0xffU << 4U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_timeout_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_dot_t_unlock_m(void) +{ + return 0x1U << 16U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_dot_t_unlock_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_macro_sched_r(void) +{ + return 0x00419eacU; +} +static inline u32 gr_gpcs_tpcs_sm_sch_macro_sched_lockboost_size_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_macro_sched_lockboost_size_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_r(void) +{ + return 0x00419e10U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_debugger_mode_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_enable_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +#endif diff --git a/include/gk20a/hw_ltc_gk20a.h b/include/gk20a/hw_ltc_gk20a.h new file mode 100644 index 0000000..efe7f98 --- /dev/null +++ b/include/gk20a/hw_ltc_gk20a.h @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ltc_gk20a_h_ +#define _hw_ltc_gk20a_h_ + +static inline u32 ltc_pltcg_base_v(void) +{ + return 0x00140000U; +} +static inline u32 ltc_pltcg_extent_v(void) +{ + return 0x0017ffffU; +} +static inline u32 ltc_ltcs_lts0_cbc_ctrl1_r(void) +{ + return 0x001410c8U; +} +static inline u32 ltc_ltc0_lts0_dstg_cfg0_r(void) +{ + return 0x00141200U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_r(void) +{ + return 0x0017ea00U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_r(void) +{ + return 0x00141104U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_ways_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_v(u32 r) +{ + return (r >> 16U) & 0x3U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_all_v(void) +{ + return 0x00000000U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_half_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_quarter_v(void) +{ + return 0x00000002U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void) +{ + return 0x0017e8c8U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(void) +{ + return 0x2U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_f(void) +{ + return 0x4U; +} +static inline u32 ltc_ltc0_lts0_cbc_ctrl1_r(void) +{ + return 0x001410c8U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_r(void) +{ + return 0x0017e8ccU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_r(void) +{ + return 0x0017e8d0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_init_v(void) +{ + return 0x0001ffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_r(void) +{ + return 0x0017e8d4U; +} +static inline u32 ltc_ltcs_ltss_cbc_base_alignment_shift_v(void) +{ + return 0x0000000bU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_address_v(u32 r) +{ + return (r >> 0U) & 0x3ffffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_r(void) +{ + return 0x0017e8dcU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_comptags_per_cache_line_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_cache_line_size_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_slices_per_fbp_v(u32 r) +{ + return (r >> 28U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_r(void) +{ + return 0x0017e91cU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_max_ways_evict_last_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_r(void) +{ + return 0x0017ea44U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_address_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value_r(u32 i) +{ + return 0x0017ea48U + i*4U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_r(void) +{ + return 0x0017ea58U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_s(void) +{ + return 32U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_r(void) +{ + return 0x0017e924U; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_l2_bypass_mode_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_r(void) +{ + return 0x0017e828U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_r(void) +{ + return 0x00140828U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_intr_r(void) +{ + return 0x00140820U; +} +static inline u32 ltc_ltcs_ltss_intr_r(void) +{ + return 0x0017e820U; +} +static inline u32 ltc_ltcs_ltss_intr_en_evicted_cb_m(void) +{ + return 0x1U << 20U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_m(void) +{ + return 0x1U << 21U; +} +static inline u32 ltc_ltc0_lts0_intr_r(void) +{ + return 0x00141020U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_r(void) +{ + return 0x0017e910U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_r(void) +{ + return 0x0017e914U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_f(void) +{ + return 0x10000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_r(void) +{ + return 0x00140910U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_r(void) +{ + return 0x00140914U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +#endif diff --git a/include/gk20a/hw_mc_gk20a.h b/include/gk20a/hw_mc_gk20a.h new file mode 100644 index 0000000..3ca2a29 --- /dev/null +++ b/include/gk20a/hw_mc_gk20a.h @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_mc_gk20a_h_ +#define _hw_mc_gk20a_h_ + +static inline u32 mc_boot_0_r(void) +{ + return 0x00000000U; +} +static inline u32 mc_boot_0_architecture_v(u32 r) +{ + return (r >> 24U) & 0x1fU; +} +static inline u32 mc_boot_0_implementation_v(u32 r) +{ + return (r >> 20U) & 0xfU; +} +static inline u32 mc_boot_0_major_revision_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 mc_boot_0_minor_revision_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 mc_intr_0_r(void) +{ + return 0x00000100U; +} +static inline u32 mc_intr_0_pfifo_pending_f(void) +{ + return 0x100U; +} +static inline u32 mc_intr_0_pgraph_pending_f(void) +{ + return 0x1000U; +} +static inline u32 mc_intr_0_pmu_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_0_ltc_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 mc_intr_0_priv_ring_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 mc_intr_0_pbus_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_intr_1_r(void) +{ + return 0x00000104U; +} +static inline u32 mc_intr_mask_0_r(void) +{ + return 0x00000640U; +} +static inline u32 mc_intr_mask_0_pmu_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_en_0_r(void) +{ + return 0x00000140U; +} +static inline u32 mc_intr_en_0_inta_disabled_f(void) +{ + return 0x0U; +} +static inline u32 mc_intr_en_0_inta_hardware_f(void) +{ + return 0x1U; +} +static inline u32 mc_intr_mask_1_r(void) +{ + return 0x00000644U; +} +static inline u32 mc_intr_mask_1_pmu_s(void) +{ + return 1U; +} +static inline u32 mc_intr_mask_1_pmu_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 mc_intr_mask_1_pmu_m(void) +{ + return 0x1U << 24U; +} +static inline u32 mc_intr_mask_1_pmu_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 mc_intr_mask_1_pmu_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_en_1_r(void) +{ + return 0x00000144U; +} +static inline u32 mc_intr_en_1_inta_disabled_f(void) +{ + return 0x0U; +} +static inline u32 mc_intr_en_1_inta_hardware_f(void) +{ + return 0x1U; +} +static inline u32 mc_enable_r(void) +{ + return 0x00000200U; +} +static inline u32 mc_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_enable_l2_enabled_f(void) +{ + return 0x8U; +} +static inline u32 mc_enable_pmedia_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pmedia_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 mc_enable_pmedia_m(void) +{ + return 0x1U << 4U; +} +static inline u32 mc_enable_pmedia_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 mc_enable_priv_ring_enabled_f(void) +{ + return 0x20U; +} +static inline u32 mc_enable_ce0_m(void) +{ + return 0x1U << 6U; +} +static inline u32 mc_enable_pfifo_enabled_f(void) +{ + return 0x100U; +} +static inline u32 mc_enable_pgraph_enabled_f(void) +{ + return 0x1000U; +} +static inline u32 mc_enable_pwr_v(u32 r) +{ + return (r >> 13U) & 0x1U; +} +static inline u32 mc_enable_pwr_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 mc_enable_pwr_enabled_f(void) +{ + return 0x2000U; +} +static inline u32 mc_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_enable_ce2_m(void) +{ + return 0x1U << 21U; +} +static inline u32 mc_enable_ce2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 mc_enable_blg_enabled_f(void) +{ + return 0x8000000U; +} +static inline u32 mc_enable_perfmon_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +static inline u32 mc_enable_pb_r(void) +{ + return 0x00000204U; +} +static inline u32 mc_enable_pb_0_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pb_0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 mc_enable_pb_0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 mc_enable_pb_0_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 mc_enable_pb_0_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 mc_enable_pb_sel_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 mc_elpg_enable_r(void) +{ + return 0x0000020cU; +} +static inline u32 mc_elpg_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_elpg_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_elpg_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +#endif diff --git a/include/gk20a/hw_pbdma_gk20a.h b/include/gk20a/hw_pbdma_gk20a.h new file mode 100644 index 0000000..2c8f48d --- /dev/null +++ b/include/gk20a/hw_pbdma_gk20a.h @@ -0,0 +1,575 @@ +/* + * Copyright (c) 2012-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pbdma_gk20a_h_ +#define _hw_pbdma_gk20a_h_ + +static inline u32 pbdma_gp_entry1_r(void) +{ + return 0x10000004U; +} +static inline u32 pbdma_gp_entry1_get_hi_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pbdma_gp_entry1_length_f(u32 v) +{ + return (v & 0x1fffffU) << 10U; +} +static inline u32 pbdma_gp_entry1_length_v(u32 r) +{ + return (r >> 10U) & 0x1fffffU; +} +static inline u32 pbdma_gp_base_r(u32 i) +{ + return 0x00040048U + i*8192U; +} +static inline u32 pbdma_gp_base__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 pbdma_gp_base_offset_f(u32 v) +{ + return (v & 0x1fffffffU) << 3U; +} +static inline u32 pbdma_gp_base_rsvd_s(void) +{ + return 3U; +} +static inline u32 pbdma_gp_base_hi_r(u32 i) +{ + return 0x0004004cU + i*8192U; +} +static inline u32 pbdma_gp_base_hi_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_gp_base_hi_limit2_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 pbdma_gp_fetch_r(u32 i) +{ + return 0x00040050U + i*8192U; +} +static inline u32 pbdma_gp_get_r(u32 i) +{ + return 0x00040014U + i*8192U; +} +static inline u32 pbdma_gp_put_r(u32 i) +{ + return 0x00040000U + i*8192U; +} +static inline u32 pbdma_timeout_r(u32 i) +{ + return 0x0004012cU + i*8192U; +} +static inline u32 pbdma_timeout__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 pbdma_timeout_period_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 pbdma_timeout_period_max_f(void) +{ + return 0xffffffffU; +} +static inline u32 pbdma_pb_fetch_r(u32 i) +{ + return 0x00040054U + i*8192U; +} +static inline u32 pbdma_pb_fetch_hi_r(u32 i) +{ + return 0x00040058U + i*8192U; +} +static inline u32 pbdma_get_r(u32 i) +{ + return 0x00040018U + i*8192U; +} +static inline u32 pbdma_get_hi_r(u32 i) +{ + return 0x0004001cU + i*8192U; +} +static inline u32 pbdma_put_r(u32 i) +{ + return 0x0004005cU + i*8192U; +} +static inline u32 pbdma_put_hi_r(u32 i) +{ + return 0x00040060U + i*8192U; +} +static inline u32 pbdma_formats_r(u32 i) +{ + return 0x0004009cU + i*8192U; +} +static inline u32 pbdma_formats_gp_fermi0_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_formats_pb_fermi1_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_formats_mp_fermi0_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_r(u32 i) +{ + return 0x00040084U + i*8192U; +} +static inline u32 pbdma_pb_header_priv_user_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_method_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_subchannel_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_level_main_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_pb_header_type_inc_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_pb_header_type_non_inc_f(void) +{ + return 0x60000000U; +} +static inline u32 pbdma_hdr_shadow_r(u32 i) +{ + return 0x00040118U + i*8192U; +} +static inline u32 pbdma_gp_shadow_0_r(u32 i) +{ + return 0x00040110U + i*8192U; +} +static inline u32 pbdma_gp_shadow_1_r(u32 i) +{ + return 0x00040114U + i*8192U; +} +static inline u32 pbdma_subdevice_r(u32 i) +{ + return 0x00040094U + i*8192U; +} +static inline u32 pbdma_subdevice_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 pbdma_subdevice_status_active_f(void) +{ + return 0x10000000U; +} +static inline u32 pbdma_subdevice_channel_dma_enable_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_method0_r(u32 i) +{ + return 0x000400c0U + i*8192U; +} +static inline u32 pbdma_method0_addr_f(u32 v) +{ + return (v & 0xfffU) << 2U; +} +static inline u32 pbdma_method0_addr_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 pbdma_method0_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 pbdma_method0_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_method0_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_method1_r(u32 i) +{ + return 0x000400c8U + i*8192U; +} +static inline u32 pbdma_method2_r(u32 i) +{ + return 0x000400d0U + i*8192U; +} +static inline u32 pbdma_method3_r(u32 i) +{ + return 0x000400d8U + i*8192U; +} +static inline u32 pbdma_data0_r(u32 i) +{ + return 0x000400c4U + i*8192U; +} +static inline u32 pbdma_target_r(u32 i) +{ + return 0x000400acU + i*8192U; +} +static inline u32 pbdma_target_engine_sw_f(void) +{ + return 0x1fU; +} +static inline u32 pbdma_acquire_r(u32 i) +{ + return 0x00040030U + i*8192U; +} +static inline u32 pbdma_acquire_retry_man_2_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_acquire_retry_exp_2_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_acquire_timeout_exp_f(u32 v) +{ + return (v & 0xfU) << 11U; +} +static inline u32 pbdma_acquire_timeout_exp_max_v(void) +{ + return 0x0000000fU; +} +static inline u32 pbdma_acquire_timeout_exp_max_f(void) +{ + return 0x7800U; +} +static inline u32 pbdma_acquire_timeout_man_f(u32 v) +{ + return (v & 0xffffU) << 15U; +} +static inline u32 pbdma_acquire_timeout_man_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 pbdma_acquire_timeout_man_max_f(void) +{ + return 0x7fff8000U; +} +static inline u32 pbdma_acquire_timeout_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_acquire_timeout_en_disable_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_status_r(u32 i) +{ + return 0x00040100U + i*8192U; +} +static inline u32 pbdma_channel_r(u32 i) +{ + return 0x00040120U + i*8192U; +} +static inline u32 pbdma_signature_r(u32 i) +{ + return 0x00040010U + i*8192U; +} +static inline u32 pbdma_signature_hw_valid_f(void) +{ + return 0xfaceU; +} +static inline u32 pbdma_signature_sw_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_r(u32 i) +{ + return 0x00040008U + i*8192U; +} +static inline u32 pbdma_userd_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_userd_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 pbdma_userd_addr_f(u32 v) +{ + return (v & 0x7fffffU) << 9U; +} +static inline u32 pbdma_userd_hi_r(u32 i) +{ + return 0x0004000cU + i*8192U; +} +static inline u32 pbdma_userd_hi_addr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_hce_ctrl_r(u32 i) +{ + return 0x000400e4U + i*8192U; +} +static inline u32 pbdma_hce_ctrl_hce_priv_mode_yes_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_r(u32 i) +{ + return 0x00040108U + i*8192U; +} +static inline u32 pbdma_intr_0_memreq_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pbdma_intr_0_memreq_pending_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_intr_0_memack_timeout_pending_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_intr_0_memack_extra_pending_f(void) +{ + return 0x4U; +} +static inline u32 pbdma_intr_0_memdat_timeout_pending_f(void) +{ + return 0x8U; +} +static inline u32 pbdma_intr_0_memdat_extra_pending_f(void) +{ + return 0x10U; +} +static inline u32 pbdma_intr_0_memflush_pending_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_memop_pending_f(void) +{ + return 0x40U; +} +static inline u32 pbdma_intr_0_lbconnect_pending_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_intr_0_lbreq_pending_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_0_lback_timeout_pending_f(void) +{ + return 0x200U; +} +static inline u32 pbdma_intr_0_lback_extra_pending_f(void) +{ + return 0x400U; +} +static inline u32 pbdma_intr_0_lbdat_timeout_pending_f(void) +{ + return 0x800U; +} +static inline u32 pbdma_intr_0_lbdat_extra_pending_f(void) +{ + return 0x1000U; +} +static inline u32 pbdma_intr_0_gpfifo_pending_f(void) +{ + return 0x2000U; +} +static inline u32 pbdma_intr_0_gpptr_pending_f(void) +{ + return 0x4000U; +} +static inline u32 pbdma_intr_0_gpentry_pending_f(void) +{ + return 0x8000U; +} +static inline u32 pbdma_intr_0_gpcrc_pending_f(void) +{ + return 0x10000U; +} +static inline u32 pbdma_intr_0_pbptr_pending_f(void) +{ + return 0x20000U; +} +static inline u32 pbdma_intr_0_pbentry_pending_f(void) +{ + return 0x40000U; +} +static inline u32 pbdma_intr_0_pbcrc_pending_f(void) +{ + return 0x80000U; +} +static inline u32 pbdma_intr_0_xbarconnect_pending_f(void) +{ + return 0x100000U; +} +static inline u32 pbdma_intr_0_method_pending_f(void) +{ + return 0x200000U; +} +static inline u32 pbdma_intr_0_methodcrc_pending_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_intr_0_device_pending_f(void) +{ + return 0x800000U; +} +static inline u32 pbdma_intr_0_semaphore_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 pbdma_intr_0_acquire_pending_f(void) +{ + return 0x4000000U; +} +static inline u32 pbdma_intr_0_pri_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 pbdma_intr_0_no_ctxsw_seg_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_intr_0_pbseg_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 pbdma_intr_0_signature_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_intr_1_r(u32 i) +{ + return 0x00040148U + i*8192U; +} +static inline u32 pbdma_intr_en_0_r(u32 i) +{ + return 0x0004010cU + i*8192U; +} +static inline u32 pbdma_intr_en_0_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_en_1_r(u32 i) +{ + return 0x0004014cU + i*8192U; +} +static inline u32 pbdma_intr_stall_r(u32 i) +{ + return 0x0004013cU + i*8192U; +} +static inline u32 pbdma_intr_stall_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_stall_1_r(u32 i) +{ + return 0x00040140U + i*8192U; +} +static inline u32 pbdma_intr_stall_1_hce_illegal_op_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_udma_nop_r(void) +{ + return 0x00000008U; +} +static inline u32 pbdma_syncpointa_r(u32 i) +{ + return 0x000400a4U + i*8192U; +} +static inline u32 pbdma_syncpointa_payload_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pbdma_syncpointb_r(u32 i) +{ + return 0x000400a8U + i*8192U; +} +static inline u32 pbdma_syncpointb_op_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 pbdma_syncpointb_op_wait_v(void) +{ + return 0x00000000U; +} +static inline u32 pbdma_syncpointb_wait_switch_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pbdma_syncpointb_wait_switch_en_v(void) +{ + return 0x00000001U; +} +static inline u32 pbdma_syncpointb_syncpt_index_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +#endif diff --git a/include/gk20a/hw_perf_gk20a.h b/include/gk20a/hw_perf_gk20a.h new file mode 100644 index 0000000..a93560f --- /dev/null +++ b/include/gk20a/hw_perf_gk20a.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2015-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_perf_gk20a_h_ +#define _hw_perf_gk20a_h_ + +static inline u32 perf_pmasys_control_r(void) +{ + return 0x001b4000U; +} +static inline u32 perf_pmasys_control_membuf_status_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_f(void) +{ + return 0x10U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_f(void) +{ + return 0x20U; +} +static inline u32 perf_pmasys_mem_block_r(void) +{ + return 0x001b4070U; +} +static inline u32 perf_pmasys_mem_block_base_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 perf_pmasys_mem_block_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 perf_pmasys_mem_block_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 perf_pmasys_mem_block_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 perf_pmasys_mem_block_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 perf_pmasys_mem_block_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_mem_block_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_outbase_r(void) +{ + return 0x001b4074U; +} +static inline u32 perf_pmasys_outbase_ptr_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_outbaseupper_r(void) +{ + return 0x001b4078U; +} +static inline u32 perf_pmasys_outbaseupper_ptr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 perf_pmasys_outsize_r(void) +{ + return 0x001b407cU; +} +static inline u32 perf_pmasys_outsize_numbytes_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_mem_bytes_r(void) +{ + return 0x001b4084U; +} +static inline u32 perf_pmasys_mem_bytes_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_mem_bump_r(void) +{ + return 0x001b4088U; +} +static inline u32 perf_pmasys_mem_bump_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_enginestatus_r(void) +{ + return 0x001b40a4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_f(void) +{ + return 0x10U; +} +#endif diff --git a/include/gk20a/hw_pram_gk20a.h b/include/gk20a/hw_pram_gk20a.h new file mode 100644 index 0000000..10923e2 --- /dev/null +++ b/include/gk20a/hw_pram_gk20a.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pram_gk20a_h_ +#define _hw_pram_gk20a_h_ + +static inline u32 pram_data032_r(u32 i) +{ + return 0x00700000U + i*4U; +} +#endif diff --git a/include/gk20a/hw_pri_ringmaster_gk20a.h b/include/gk20a/hw_pri_ringmaster_gk20a.h new file mode 100644 index 0000000..ca2775e --- /dev/null +++ b/include/gk20a/hw_pri_ringmaster_gk20a.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringmaster_gk20a_h_ +#define _hw_pri_ringmaster_gk20a_h_ + +static inline u32 pri_ringmaster_command_r(void) +{ + return 0x0012004cU; +} +static inline u32 pri_ringmaster_command_cmd_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 pri_ringmaster_command_cmd_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 pri_ringmaster_command_cmd_no_cmd_v(void) +{ + return 0x00000000U; +} +static inline u32 pri_ringmaster_command_cmd_start_ring_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_command_cmd_ack_interrupt_f(void) +{ + return 0x2U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_f(void) +{ + return 0x3U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_bc_grp_all_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_command_data_r(void) +{ + return 0x00120048U; +} +static inline u32 pri_ringmaster_start_results_r(void) +{ + return 0x00120050U; +} +static inline u32 pri_ringmaster_start_results_connectivity_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_start_results_connectivity_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 pri_ringmaster_intr_status0_r(void) +{ + return 0x00120058U; +} +static inline u32 pri_ringmaster_intr_status0_ring_start_conn_fault_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_disconnect_fault_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_overflow_fault_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_gbl_write_error_sys_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status1_r(void) +{ + return 0x0012005cU; +} +static inline u32 pri_ringmaster_global_ctl_r(void) +{ + return 0x00120060U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_asserted_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_deasserted_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_enum_fbp_r(void) +{ + return 0x00120074U; +} +static inline u32 pri_ringmaster_enum_fbp_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_gpc_r(void) +{ + return 0x00120078U; +} +static inline u32 pri_ringmaster_enum_gpc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +#endif diff --git a/include/gk20a/hw_pri_ringstation_fbp_gk20a.h b/include/gk20a/hw_pri_ringstation_fbp_gk20a.h new file mode 100644 index 0000000..06e08bd --- /dev/null +++ b/include/gk20a/hw_pri_ringstation_fbp_gk20a.h @@ -0,0 +1,231 @@ +/* + * drivers/video/tegra/host/gk20a/hw_pri_ringstation_fbp_gk20a.h + * + * Copyright (c) 2012-2013, 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. + */ + + /* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ + +#ifndef __hw_pri_ringstation_fbp_gk20a_h__ +#define __hw_pri_ringstation_fbp_gk20a_h__ +/*This file is autogenerated. Do not edit. */ + +static inline u32 pri_ringstation_fbp_master_config_r(u32 i) +{ + return 0x00124300+((i)*4); +} +static inline u32 pri_ringstation_fbp_master_config__size_1_v(void) +{ + return 64; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_s(void) +{ + return 18; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_f(u32 v) +{ + return (v & 0x3ffff) << 0; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_m(void) +{ + return 0x3ffff << 0; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_v(u32 r) +{ + return (r >> 0) & 0x3ffff; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_i_v(void) +{ + return 0x00000064; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_i_f(void) +{ + return 0x64; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_s(void) +{ + return 1; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_f(u32 v) +{ + return (v & 0x1) << 30; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_m(void) +{ + return 0x1 << 30; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_v(u32 r) +{ + return (r >> 30) & 0x1; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_error_v(void) +{ + return 0x00000000; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_error_f(void) +{ + return 0x0; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_soldier_on_v(void) +{ + return 0x00000001; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_soldier_on_f(void) +{ + return 0x40000000; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_s(void) +{ + return 1; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_f(u32 v) +{ + return (v & 0x1) << 31; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_m(void) +{ + return 0x1 << 31; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_v(u32 r) +{ + return (r >> 31) & 0x1; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_error_v(void) +{ + return 0x00000000; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_error_f(void) +{ + return 0x0; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_soldier_on_v(void) +{ + return 0x00000001; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_soldier_on_f(void) +{ + return 0x80000000; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_s(void) +{ + return 3; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_f(u32 v) +{ + return (v & 0x7) << 20; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_m(void) +{ + return 0x7 << 20; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_v(u32 r) +{ + return (r >> 20) & 0x7; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_i_v(void) +{ + return 0x00000000; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_i_f(void) +{ + return 0x0; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_s(void) +{ + return 3; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_f(u32 v) +{ + return (v & 0x7) << 24; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_m(void) +{ + return 0x7 << 24; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_v(u32 r) +{ + return (r >> 24) & 0x7; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_i_v(void) +{ + return 0x00000000; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_i_f(void) +{ + return 0x0; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_s(void) +{ + return 3; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_f(u32 v) +{ + return (v & 0x7) << 27; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_m(void) +{ + return 0x7 << 27; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_v(u32 r) +{ + return (r >> 27) & 0x7; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_i_v(void) +{ + return 0x00000000; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_i_f(void) +{ + return 0x0; +} + +#endif /* __hw_pri_ringstation_fbp_gk20a_h__ */ diff --git a/include/gk20a/hw_pri_ringstation_gpc_gk20a.h b/include/gk20a/hw_pri_ringstation_gpc_gk20a.h new file mode 100644 index 0000000..6b57429 --- /dev/null +++ b/include/gk20a/hw_pri_ringstation_gpc_gk20a.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_gpc_gk20a_h_ +#define _hw_pri_ringstation_gpc_gk20a_h_ + +static inline u32 pri_ringstation_gpc_master_config_r(u32 i) +{ + return 0x00128300U + i*4U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_adr_r(void) +{ + return 0x00128120U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_wrdat_r(void) +{ + return 0x00128124U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_info_r(void) +{ + return 0x00128128U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_code_r(void) +{ + return 0x0012812cU; +} +#endif diff --git a/include/gk20a/hw_pri_ringstation_sys_gk20a.h b/include/gk20a/hw_pri_ringstation_sys_gk20a.h new file mode 100644 index 0000000..e4d5c3b --- /dev/null +++ b/include/gk20a/hw_pri_ringstation_sys_gk20a.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_sys_gk20a_h_ +#define _hw_pri_ringstation_sys_gk20a_h_ + +static inline u32 pri_ringstation_sys_master_config_r(u32 i) +{ + return 0x00122300U + i*4U; +} +static inline u32 pri_ringstation_sys_decode_config_r(void) +{ + return 0x00122204U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_m(void) +{ + return 0x7U << 0U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_drop_on_ring_not_started_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringstation_sys_priv_error_adr_r(void) +{ + return 0x00122120U; +} +static inline u32 pri_ringstation_sys_priv_error_wrdat_r(void) +{ + return 0x00122124U; +} +static inline u32 pri_ringstation_sys_priv_error_info_r(void) +{ + return 0x00122128U; +} +static inline u32 pri_ringstation_sys_priv_error_code_r(void) +{ + return 0x0012212cU; +} +#endif diff --git a/include/gk20a/hw_proj_gk20a.h b/include/gk20a/hw_proj_gk20a.h new file mode 100644 index 0000000..10509ca --- /dev/null +++ b/include/gk20a/hw_proj_gk20a.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2012-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_proj_gk20a_h_ +#define _hw_proj_gk20a_h_ + +static inline u32 proj_gpc_base_v(void) +{ + return 0x00500000U; +} +static inline u32 proj_gpc_shared_base_v(void) +{ + return 0x00418000U; +} +static inline u32 proj_gpc_stride_v(void) +{ + return 0x00008000U; +} +static inline u32 proj_gpc_priv_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_ltc_stride_v(void) +{ + return 0x00002000U; +} +static inline u32 proj_lts_stride_v(void) +{ + return 0x00000400U; +} +static inline u32 proj_fbpa_stride_v(void) +{ + return 0x00001000U; +} +static inline u32 proj_ppc_in_gpc_base_v(void) +{ + return 0x00003000U; +} +static inline u32 proj_ppc_in_gpc_shared_base_v(void) +{ + return 0x00003e00U; +} +static inline u32 proj_ppc_in_gpc_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_rop_base_v(void) +{ + return 0x00410000U; +} +static inline u32 proj_rop_shared_base_v(void) +{ + return 0x00408800U; +} +static inline u32 proj_rop_stride_v(void) +{ + return 0x00000400U; +} +static inline u32 proj_tpc_in_gpc_base_v(void) +{ + return 0x00004000U; +} +static inline u32 proj_tpc_in_gpc_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_tpc_in_gpc_shared_base_v(void) +{ + return 0x00001800U; +} +static inline u32 proj_host_num_engines_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_host_num_pbdma_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_tpc_per_gpc_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_fbps_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_fbpas_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_gpcs_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_pes_per_gpc_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_tpcs_per_pes_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_zcull_banks_v(void) +{ + return 0x00000004U; +} +static inline u32 proj_scal_max_gpcs_v(void) +{ + return 0x00000020U; +} +static inline u32 proj_scal_max_tpc_per_gpc_v(void) +{ + return 0x00000008U; +} +#endif diff --git a/include/gk20a/hw_pwr_gk20a.h b/include/gk20a/hw_pwr_gk20a.h new file mode 100644 index 0000000..2845763 --- /dev/null +++ b/include/gk20a/hw_pwr_gk20a.h @@ -0,0 +1,823 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pwr_gk20a_h_ +#define _hw_pwr_gk20a_h_ + +static inline u32 pwr_falcon_irqsset_r(void) +{ + return 0x0010a000U; +} +static inline u32 pwr_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqsclr_r(void) +{ + return 0x0010a004U; +} +static inline u32 pwr_falcon_irqstat_r(void) +{ + return 0x0010a008U; +} +static inline u32 pwr_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 pwr_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 pwr_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqmode_r(void) +{ + return 0x0010a00cU; +} +static inline u32 pwr_falcon_irqmset_r(void) +{ + return 0x0010a010U; +} +static inline u32 pwr_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_r(void) +{ + return 0x0010a014U; +} +static inline u32 pwr_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqmask_r(void) +{ + return 0x0010a018U; +} +static inline u32 pwr_falcon_irqdest_r(void) +{ + return 0x0010a01cU; +} +static inline u32 pwr_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 pwr_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 pwr_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 pwr_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 pwr_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 pwr_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 pwr_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 pwr_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 pwr_falcon_curctx_r(void) +{ + return 0x0010a050U; +} +static inline u32 pwr_falcon_nxtctx_r(void) +{ + return 0x0010a054U; +} +static inline u32 pwr_falcon_mailbox0_r(void) +{ + return 0x0010a040U; +} +static inline u32 pwr_falcon_mailbox1_r(void) +{ + return 0x0010a044U; +} +static inline u32 pwr_falcon_itfen_r(void) +{ + return 0x0010a048U; +} +static inline u32 pwr_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 pwr_falcon_idlestate_r(void) +{ + return 0x0010a04cU; +} +static inline u32 pwr_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 pwr_falcon_os_r(void) +{ + return 0x0010a080U; +} +static inline u32 pwr_falcon_engctl_r(void) +{ + return 0x0010a0a4U; +} +static inline u32 pwr_falcon_cpuctl_r(void) +{ + return 0x0010a100U; +} +static inline u32 pwr_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pwr_falcon_imemc_r(u32 i) +{ + return 0x0010a180U + i*16U; +} +static inline u32 pwr_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_imemd_r(u32 i) +{ + return 0x0010a184U + i*16U; +} +static inline u32 pwr_falcon_imemt_r(u32 i) +{ + return 0x0010a188U + i*16U; +} +static inline u32 pwr_falcon_bootvec_r(void) +{ + return 0x0010a104U; +} +static inline u32 pwr_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_falcon_dmactl_r(void) +{ + return 0x0010a10cU; +} +static inline u32 pwr_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 pwr_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_falcon_hwcfg_r(void) +{ + return 0x0010a108U; +} +static inline u32 pwr_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 pwr_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 pwr_falcon_dmatrfbase_r(void) +{ + return 0x0010a110U; +} +static inline u32 pwr_falcon_dmatrfmoffs_r(void) +{ + return 0x0010a114U; +} +static inline u32 pwr_falcon_dmatrfcmd_r(void) +{ + return 0x0010a118U; +} +static inline u32 pwr_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 pwr_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 pwr_falcon_dmatrffboffs_r(void) +{ + return 0x0010a11cU; +} +static inline u32 pwr_falcon_exterraddr_r(void) +{ + return 0x0010a168U; +} +static inline u32 pwr_falcon_exterrstat_r(void) +{ + return 0x0010a16cU; +} +static inline u32 pwr_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 pwr_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 pwr_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_r(void) +{ + return 0x0010a200U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 pwr_pmu_falcon_icd_rdata_r(void) +{ + return 0x0010a20cU; +} +static inline u32 pwr_falcon_dmemc_r(u32 i) +{ + return 0x0010a1c0U + i*8U; +} +static inline u32 pwr_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 pwr_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 pwr_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 pwr_falcon_dmemd_r(u32 i) +{ + return 0x0010a1c4U + i*8U; +} +static inline u32 pwr_pmu_new_instblk_r(void) +{ + return 0x0010a480U; +} +static inline u32 pwr_pmu_new_instblk_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 pwr_pmu_new_instblk_target_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 pwr_pmu_new_instblk_valid_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 pwr_pmu_mutex_id_r(void) +{ + return 0x0010a488U; +} +static inline u32 pwr_pmu_mutex_id_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_id_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_value_not_avail_v(void) +{ + return 0x000000ffU; +} +static inline u32 pwr_pmu_mutex_id_release_r(void) +{ + return 0x0010a48cU; +} +static inline u32 pwr_pmu_mutex_id_release_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_m(void) +{ + return 0xffU << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_mutex_r(u32 i) +{ + return 0x0010a580U + i*4U; +} +static inline u32 pwr_pmu_mutex__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 pwr_pmu_mutex_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_value_initial_lock_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_queue_head_r(u32 i) +{ + return 0x0010a4a0U + i*4U; +} +static inline u32 pwr_pmu_queue_head__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_queue_head_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_head_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_queue_tail_r(u32 i) +{ + return 0x0010a4b0U + i*4U; +} +static inline u32 pwr_pmu_queue_tail__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_queue_tail_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_tail_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_head_r(void) +{ + return 0x0010a4c8U; +} +static inline u32 pwr_pmu_msgq_head_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_head_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_tail_r(void) +{ + return 0x0010a4ccU; +} +static inline u32 pwr_pmu_msgq_tail_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_tail_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_idle_mask_r(u32 i) +{ + return 0x0010a504U + i*16U; +} +static inline u32 pwr_pmu_idle_mask_gr_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pwr_pmu_idle_mask_ce_2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 pwr_pmu_idle_count_r(u32 i) +{ + return 0x0010a508U + i*16U; +} +static inline u32 pwr_pmu_idle_count_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_count_value_v(u32 r) +{ + return (r >> 0U) & 0x7fffffffU; +} +static inline u32 pwr_pmu_idle_count_reset_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 pwr_pmu_idle_ctrl_r(u32 i) +{ + return 0x0010a50cU + i*16U; +} +static inline u32 pwr_pmu_idle_ctrl_value_m(void) +{ + return 0x3U << 0U; +} +static inline u32 pwr_pmu_idle_ctrl_value_busy_f(void) +{ + return 0x2U; +} +static inline u32 pwr_pmu_idle_ctrl_value_always_f(void) +{ + return 0x3U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_disabled_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_idle_threshold_r(u32 i) +{ + return 0x0010a8a0U + i*4U; +} +static inline u32 pwr_pmu_idle_threshold_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_intr_r(void) +{ + return 0x0010a9e8U; +} +static inline u32 pwr_pmu_idle_intr_en_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_en_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_idle_intr_en_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_r(void) +{ + return 0x0010a9ecU; +} +static inline u32 pwr_pmu_idle_intr_status_intr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_m(void) +{ + return U32(0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_pmu_idle_mask_supp_r(u32 i) +{ + return 0x0010a9f0U + i*8U; +} +static inline u32 pwr_pmu_idle_mask_1_supp_r(u32 i) +{ + return 0x0010a9f4U + i*8U; +} +static inline u32 pwr_pmu_idle_ctrl_supp_r(u32 i) +{ + return 0x0010aa30U + i*8U; +} +static inline u32 pwr_pmu_debug_r(u32 i) +{ + return 0x0010a5c0U + i*4U; +} +static inline u32 pwr_pmu_debug__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_mailbox_r(u32 i) +{ + return 0x0010a450U + i*4U; +} +static inline u32 pwr_pmu_mailbox__size_1_v(void) +{ + return 0x0000000cU; +} +static inline u32 pwr_pmu_bar0_addr_r(void) +{ + return 0x0010a7a0U; +} +static inline u32 pwr_pmu_bar0_data_r(void) +{ + return 0x0010a7a4U; +} +static inline u32 pwr_pmu_bar0_ctl_r(void) +{ + return 0x0010a7acU; +} +static inline u32 pwr_pmu_bar0_timeout_r(void) +{ + return 0x0010a7a8U; +} +static inline u32 pwr_pmu_bar0_fecs_error_r(void) +{ + return 0x0010a988U; +} +static inline u32 pwr_pmu_bar0_error_status_r(void) +{ + return 0x0010a7b0U; +} +static inline u32 pwr_pmu_pg_idlefilth_r(u32 i) +{ + return 0x0010a6c0U + i*4U; +} +static inline u32 pwr_pmu_pg_ppuidlefilth_r(u32 i) +{ + return 0x0010a6e8U + i*4U; +} +static inline u32 pwr_pmu_pg_idle_cnt_r(u32 i) +{ + return 0x0010a710U + i*4U; +} +static inline u32 pwr_pmu_pg_intren_r(u32 i) +{ + return 0x0010a760U + i*4U; +} +static inline u32 pwr_fbif_transcfg_r(u32 i) +{ + return 0x0010a600U + i*4U; +} +static inline u32 pwr_fbif_transcfg_target_local_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_target_coherent_sysmem_f(void) +{ + return 0x1U; +} +static inline u32 pwr_fbif_transcfg_target_noncoherent_sysmem_f(void) +{ + return 0x2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_s(void) +{ + return 1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_virtual_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_mem_type_physical_f(void) +{ + return 0x4U; +} +#endif diff --git a/include/gk20a/hw_ram_gk20a.h b/include/gk20a/hw_ram_gk20a.h new file mode 100644 index 0000000..ed385d9 --- /dev/null +++ b/include/gk20a/hw_ram_gk20a.h @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ram_gk20a_h_ +#define _hw_ram_gk20a_h_ + +static inline u32 ram_in_ramfc_s(void) +{ + return 4096U; +} +static inline u32 ram_in_ramfc_w(void) +{ + return 0U; +} +static inline u32 ram_in_page_dir_base_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ram_in_page_dir_base_target_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 ram_in_page_dir_base_vol_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_page_dir_base_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_page_dir_base_lo_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_page_dir_base_hi_w(void) +{ + return 129U; +} +static inline u32 ram_in_adr_limit_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_adr_limit_lo_w(void) +{ + return 130U; +} +static inline u32 ram_in_adr_limit_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_adr_limit_hi_w(void) +{ + return 131U; +} +static inline u32 ram_in_engine_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_cs_wfi_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_engine_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_engine_cs_fg_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_engine_cs_fg_f(void) +{ + return 0x8U; +} +static inline u32 ram_in_gr_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_gr_wfi_target_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_mode_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_mode_physical_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_gr_wfi_mode_physical_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_gr_wfi_mode_virtual_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_gr_wfi_mode_virtual_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_gr_wfi_ptr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_gr_wfi_ptr_lo_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_ptr_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_gr_wfi_ptr_hi_w(void) +{ + return 133U; +} +static inline u32 ram_in_base_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 ram_in_alloc_size_v(void) +{ + return 0x00001000U; +} +static inline u32 ram_fc_size_val_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_fc_gp_put_w(void) +{ + return 0U; +} +static inline u32 ram_fc_userd_w(void) +{ + return 2U; +} +static inline u32 ram_fc_userd_hi_w(void) +{ + return 3U; +} +static inline u32 ram_fc_signature_w(void) +{ + return 4U; +} +static inline u32 ram_fc_gp_get_w(void) +{ + return 5U; +} +static inline u32 ram_fc_pb_get_w(void) +{ + return 6U; +} +static inline u32 ram_fc_pb_get_hi_w(void) +{ + return 7U; +} +static inline u32 ram_fc_pb_top_level_get_w(void) +{ + return 8U; +} +static inline u32 ram_fc_pb_top_level_get_hi_w(void) +{ + return 9U; +} +static inline u32 ram_fc_acquire_w(void) +{ + return 12U; +} +static inline u32 ram_fc_semaphorea_w(void) +{ + return 14U; +} +static inline u32 ram_fc_semaphoreb_w(void) +{ + return 15U; +} +static inline u32 ram_fc_semaphorec_w(void) +{ + return 16U; +} +static inline u32 ram_fc_semaphored_w(void) +{ + return 17U; +} +static inline u32 ram_fc_gp_base_w(void) +{ + return 18U; +} +static inline u32 ram_fc_gp_base_hi_w(void) +{ + return 19U; +} +static inline u32 ram_fc_gp_fetch_w(void) +{ + return 20U; +} +static inline u32 ram_fc_pb_fetch_w(void) +{ + return 21U; +} +static inline u32 ram_fc_pb_fetch_hi_w(void) +{ + return 22U; +} +static inline u32 ram_fc_pb_put_w(void) +{ + return 23U; +} +static inline u32 ram_fc_pb_put_hi_w(void) +{ + return 24U; +} +static inline u32 ram_fc_pb_header_w(void) +{ + return 33U; +} +static inline u32 ram_fc_pb_count_w(void) +{ + return 34U; +} +static inline u32 ram_fc_subdevice_w(void) +{ + return 37U; +} +static inline u32 ram_fc_formats_w(void) +{ + return 39U; +} +static inline u32 ram_fc_syncpointa_w(void) +{ + return 41U; +} +static inline u32 ram_fc_syncpointb_w(void) +{ + return 42U; +} +static inline u32 ram_fc_target_w(void) +{ + return 43U; +} +static inline u32 ram_fc_hce_ctrl_w(void) +{ + return 57U; +} +static inline u32 ram_fc_chid_w(void) +{ + return 58U; +} +static inline u32 ram_fc_chid_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_fc_chid_id_w(void) +{ + return 0U; +} +static inline u32 ram_fc_runlist_timeslice_w(void) +{ + return 62U; +} +static inline u32 ram_fc_pb_timeslice_w(void) +{ + return 63U; +} +static inline u32 ram_userd_base_shift_v(void) +{ + return 0x00000009U; +} +static inline u32 ram_userd_chan_size_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_userd_put_w(void) +{ + return 16U; +} +static inline u32 ram_userd_get_w(void) +{ + return 17U; +} +static inline u32 ram_userd_ref_w(void) +{ + return 18U; +} +static inline u32 ram_userd_put_hi_w(void) +{ + return 19U; +} +static inline u32 ram_userd_ref_threshold_w(void) +{ + return 20U; +} +static inline u32 ram_userd_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_userd_get_hi_w(void) +{ + return 24U; +} +static inline u32 ram_userd_gp_get_w(void) +{ + return 34U; +} +static inline u32 ram_userd_gp_put_w(void) +{ + return 35U; +} +static inline u32 ram_userd_gp_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_gp_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_rl_entry_size_v(void) +{ + return 0x00000008U; +} +static inline u32 ram_rl_entry_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_type_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 ram_rl_entry_type_chid_f(void) +{ + return 0x0U; +} +static inline u32 ram_rl_entry_type_tsg_f(void) +{ + return 0x2000U; +} +static inline u32 ram_rl_entry_timeslice_scale_f(u32 v) +{ + return (v & 0xfU) << 14U; +} +static inline u32 ram_rl_entry_timeslice_scale_3_f(void) +{ + return 0xc000U; +} +static inline u32 ram_rl_entry_timeslice_timeout_f(u32 v) +{ + return (v & 0xffU) << 18U; +} +static inline u32 ram_rl_entry_timeslice_timeout_128_f(void) +{ + return 0x2000000U; +} +static inline u32 ram_rl_entry_tsg_length_f(u32 v) +{ + return (v & 0x3fU) << 26U; +} +#endif diff --git a/include/gk20a/hw_therm_gk20a.h b/include/gk20a/hw_therm_gk20a.h new file mode 100644 index 0000000..075c9bc --- /dev/null +++ b/include/gk20a/hw_therm_gk20a.h @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_therm_gk20a_h_ +#define _hw_therm_gk20a_h_ + +static inline u32 therm_use_a_r(void) +{ + return 0x00020798U; +} +static inline u32 therm_use_a_ext_therm_0_enable_f(void) +{ + return 0x1U; +} +static inline u32 therm_use_a_ext_therm_1_enable_f(void) +{ + return 0x2U; +} +static inline u32 therm_use_a_ext_therm_2_enable_f(void) +{ + return 0x4U; +} +static inline u32 therm_evt_ext_therm_0_r(void) +{ + return 0x00020700U; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_init_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_0_priority_f(u32 v) +{ + return (v & 0x1fU) << 24U; +} +static inline u32 therm_evt_ext_therm_1_r(void) +{ + return 0x00020704U; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_init_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_1_priority_f(u32 v) +{ + return (v & 0x1fU) << 24U; +} +static inline u32 therm_evt_ext_therm_2_r(void) +{ + return 0x00020708U; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_init_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_2_priority_f(u32 v) +{ + return (v & 0x1fU) << 24U; +} +static inline u32 therm_weight_1_r(void) +{ + return 0x00020024U; +} +static inline u32 therm_config1_r(void) +{ + return 0x00020050U; +} +static inline u32 therm_config2_r(void) +{ + return 0x00020130U; +} +static inline u32 therm_config2_slowdown_factor_extended_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 therm_config2_grad_enable_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 therm_gate_ctrl_r(u32 i) +{ + return 0x00020200U + i*4U; +} +static inline u32 therm_gate_ctrl_eng_clk_m(void) +{ + return 0x3U << 0U; +} +static inline u32 therm_gate_ctrl_eng_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_eng_clk_auto_f(void) +{ + return 0x1U; +} +static inline u32 therm_gate_ctrl_eng_clk_stop_f(void) +{ + return 0x2U; +} +static inline u32 therm_gate_ctrl_blk_clk_m(void) +{ + return 0x3U << 2U; +} +static inline u32 therm_gate_ctrl_blk_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_blk_clk_auto_f(void) +{ + return 0x4U; +} +static inline u32 therm_gate_ctrl_eng_pwr_m(void) +{ + return 0x3U << 4U; +} +static inline u32 therm_gate_ctrl_eng_pwr_auto_f(void) +{ + return 0x10U; +} +static inline u32 therm_gate_ctrl_eng_pwr_off_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_gate_ctrl_eng_pwr_off_f(void) +{ + return 0x20U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_m(void) +{ + return 0x1fU << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_f(u32 v) +{ + return (v & 0x7U) << 13U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_m(void) +{ + return 0x7U << 13U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_m(void) +{ + return 0xfU << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_m(void) +{ + return 0xfU << 20U; +} +static inline u32 therm_fecs_idle_filter_r(void) +{ + return 0x00020288U; +} +static inline u32 therm_fecs_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_hubmmu_idle_filter_r(void) +{ + return 0x0002028cU; +} +static inline u32 therm_hubmmu_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_clk_slowdown_r(u32 i) +{ + return 0x00020160U + i*4U; +} +static inline u32 therm_clk_slowdown_idle_factor_f(u32 v) +{ + return (v & 0x3fU) << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_m(void) +{ + return 0x3fU << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_v(u32 r) +{ + return (r >> 16U) & 0x3fU; +} +static inline u32 therm_clk_slowdown_idle_factor_disabled_f(void) +{ + return 0x0U; +} +static inline u32 therm_grad_stepping_table_r(u32 i) +{ + return 0x000202c8U + i*4U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by1p5_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by2_f(void) +{ + return 0x2U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by4_f(void) +{ + return 0x6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f(void) +{ + return 0xeU; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_f(u32 v) +{ + return (v & 0x3fU) << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_m(void) +{ + return 0x3fU << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_f(u32 v) +{ + return (v & 0x3fU) << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_m(void) +{ + return 0x3fU << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_m(void) +{ + return 0x3fU << 24U; +} +static inline u32 therm_grad_stepping0_r(void) +{ + return 0x000202c0U; +} +static inline u32 therm_grad_stepping0_feature_s(void) +{ + return 1U; +} +static inline u32 therm_grad_stepping0_feature_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 therm_grad_stepping0_feature_m(void) +{ + return 0x1U << 0U; +} +static inline u32 therm_grad_stepping0_feature_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 therm_grad_stepping0_feature_enable_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping1_r(void) +{ + return 0x000202c4U; +} +static inline u32 therm_grad_stepping1_pdiv_duration_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 therm_clk_timing_r(u32 i) +{ + return 0x000203c0U + i*4U; +} +static inline u32 therm_clk_timing_grad_slowdown_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_m(void) +{ + return 0x1U << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_enabled_f(void) +{ + return 0x10000U; +} +#endif diff --git a/include/gk20a/hw_timer_gk20a.h b/include/gk20a/hw_timer_gk20a.h new file mode 100644 index 0000000..972d68a --- /dev/null +++ b/include/gk20a/hw_timer_gk20a.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_timer_gk20a_h_ +#define _hw_timer_gk20a_h_ + +static inline u32 timer_pri_timeout_r(void) +{ + return 0x00009080U; +} +static inline u32 timer_pri_timeout_period_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 timer_pri_timeout_period_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 timer_pri_timeout_period_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 timer_pri_timeout_en_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 timer_pri_timeout_en_m(void) +{ + return 0x1U << 31U; +} +static inline u32 timer_pri_timeout_en_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_en_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 timer_pri_timeout_en_en_disabled_f(void) +{ + return 0x0U; +} +static inline u32 timer_pri_timeout_save_0_r(void) +{ + return 0x00009084U; +} +static inline u32 timer_pri_timeout_save_0_fecs_tgt_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_save_0_addr_v(u32 r) +{ + return (r >> 2U) & 0x3fffffU; +} +static inline u32 timer_pri_timeout_save_0_write_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 timer_pri_timeout_save_1_r(void) +{ + return 0x00009088U; +} +static inline u32 timer_pri_timeout_fecs_errcode_r(void) +{ + return 0x0000908cU; +} +static inline u32 timer_time_0_r(void) +{ + return 0x00009400U; +} +static inline u32 timer_time_1_r(void) +{ + return 0x00009410U; +} +#endif diff --git a/include/gk20a/hw_top_gk20a.h b/include/gk20a/hw_top_gk20a.h new file mode 100644 index 0000000..be7fa4a --- /dev/null +++ b/include/gk20a/hw_top_gk20a.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_top_gk20a_h_ +#define _hw_top_gk20a_h_ + +static inline u32 top_num_gpcs_r(void) +{ + return 0x00022430U; +} +static inline u32 top_num_gpcs_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_tpc_per_gpc_r(void) +{ + return 0x00022434U; +} +static inline u32 top_tpc_per_gpc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_fbps_r(void) +{ + return 0x00022438U; +} +static inline u32 top_num_fbps_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_device_info_r(u32 i) +{ + return 0x00022700U + i*4U; +} +static inline u32 top_device_info__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 top_device_info_chain_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 top_device_info_chain_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_engine_enum_v(u32 r) +{ + return (r >> 26U) & 0xfU; +} +static inline u32 top_device_info_runlist_enum_v(u32 r) +{ + return (r >> 21U) & 0xfU; +} +static inline u32 top_device_info_intr_enum_v(u32 r) +{ + return (r >> 15U) & 0x1fU; +} +static inline u32 top_device_info_reset_enum_v(u32 r) +{ + return (r >> 9U) & 0x1fU; +} +static inline u32 top_device_info_type_enum_v(u32 r) +{ + return (r >> 2U) & 0x1fffffffU; +} +static inline u32 top_device_info_type_enum_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_type_enum_graphics_f(void) +{ + return 0x0U; +} +static inline u32 top_device_info_type_enum_copy0_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_type_enum_copy0_f(void) +{ + return 0x4U; +} +static inline u32 top_device_info_type_enum_copy1_v(void) +{ + return 0x00000002U; +} +static inline u32 top_device_info_type_enum_copy1_f(void) +{ + return 0x8U; +} +static inline u32 top_device_info_type_enum_copy2_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_type_enum_copy2_f(void) +{ + return 0xcU; +} +static inline u32 top_device_info_engine_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 top_device_info_runlist_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 top_device_info_intr_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 top_device_info_reset_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_entry_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 top_device_info_entry_not_valid_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_entry_enum_v(void) +{ + return 0x00000002U; +} +static inline u32 top_device_info_entry_engine_type_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_entry_data_v(void) +{ + return 0x00000001U; +} +static inline u32 top_fs_status_fbp_r(void) +{ + return 0x00022548U; +} +static inline u32 top_fs_status_fbp_cluster_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 top_fs_status_fbp_cluster_enable_v(void) +{ + return 0x00000000U; +} +static inline u32 top_fs_status_fbp_cluster_enable_f(void) +{ + return 0x0U; +} +static inline u32 top_fs_status_fbp_cluster_disable_v(void) +{ + return 0x00000001U; +} +static inline u32 top_fs_status_fbp_cluster_disable_f(void) +{ + return 0x1U; +} +#endif diff --git a/include/gk20a/hw_trim_gk20a.h b/include/gk20a/hw_trim_gk20a.h new file mode 100644 index 0000000..f28c21f --- /dev/null +++ b/include/gk20a/hw_trim_gk20a.h @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_trim_gk20a_h_ +#define _hw_trim_gk20a_h_ + +static inline u32 trim_sys_gpcpll_cfg_r(void) +{ + return 0x00137000U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_m(void) +{ + return 0x1U << 0U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_no_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_yes_f(void) +{ + return 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_iddq_m(void) +{ + return 0x1U << 1U; +} +static inline u32 trim_sys_gpcpll_cfg_iddq_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_iddq_power_on_v(void) +{ + return 0x00000000U; +} +static inline u32 trim_sys_gpcpll_cfg_enb_lckdet_m(void) +{ + return 0x1U << 4U; +} +static inline u32 trim_sys_gpcpll_cfg_enb_lckdet_power_on_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpcpll_cfg_enb_lckdet_power_off_f(void) +{ + return 0x10U; +} +static inline u32 trim_sys_gpcpll_cfg_pll_lock_v(u32 r) +{ + return (r >> 17U) & 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_pll_lock_true_f(void) +{ + return 0x20000U; +} +static inline u32 trim_sys_gpcpll_coeff_r(void) +{ + return 0x00137004U; +} +static inline u32 trim_sys_gpcpll_coeff_mdiv_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 trim_sys_gpcpll_coeff_mdiv_m(void) +{ + return 0xffU << 0U; +} +static inline u32 trim_sys_gpcpll_coeff_mdiv_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 trim_sys_gpcpll_coeff_ndiv_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 trim_sys_gpcpll_coeff_ndiv_m(void) +{ + return 0xffU << 8U; +} +static inline u32 trim_sys_gpcpll_coeff_ndiv_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 trim_sys_gpcpll_coeff_pldiv_f(u32 v) +{ + return (v & 0x3fU) << 16U; +} +static inline u32 trim_sys_gpcpll_coeff_pldiv_m(void) +{ + return 0x3fU << 16U; +} +static inline u32 trim_sys_gpcpll_coeff_pldiv_v(u32 r) +{ + return (r >> 16U) & 0x3fU; +} +static inline u32 trim_sys_sel_vco_r(void) +{ + return 0x00137100U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_m(void) +{ + return 0x1U << 0U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_init_v(void) +{ + return 0x00000000U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_init_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_bypass_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_vco_f(void) +{ + return 0x1U; +} +static inline u32 trim_sys_gpc2clk_out_r(void) +{ + return 0x00137250U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_s(void) +{ + return 6U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_by31_f(void) +{ + return 0x3cU; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_s(void) +{ + return 6U; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_m(void) +{ + return 0x3fU << 8U; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_v(u32 r) +{ + return (r >> 8U) & 0x3fU; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_by1_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpc2clk_out_sdiv14_m(void) +{ + return 0x1U << 31U; +} +static inline u32 trim_sys_gpc2clk_out_sdiv14_indiv4_mode_f(void) +{ + return 0x80000000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_r(u32 i) +{ + return 0x00134124U + i*512U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_noofipclks_f(u32 v) +{ + return (v & 0x3fffU) << 0U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_write_en_asserted_f(void) +{ + return 0x10000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_enable_asserted_f(void) +{ + return 0x100000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_reset_asserted_f(void) +{ + return 0x1000000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cnt_r(u32 i) +{ + return 0x00134128U + i*512U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cnt_value_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 trim_sys_gpcpll_cfg2_r(void) +{ + return 0x0013700cU; +} +static inline u32 trim_sys_gpcpll_cfg2_pll_stepa_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 trim_sys_gpcpll_cfg2_pll_stepa_m(void) +{ + return 0xffU << 24U; +} +static inline u32 trim_sys_gpcpll_cfg3_r(void) +{ + return 0x00137018U; +} +static inline u32 trim_sys_gpcpll_cfg3_pll_stepb_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 trim_sys_gpcpll_cfg3_pll_stepb_m(void) +{ + return 0xffU << 16U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_r(void) +{ + return 0x0013701cU; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_m(void) +{ + return 0x1U << 22U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_yes_f(void) +{ + return 0x400000U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_no_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_en_dynramp_m(void) +{ + return 0x1U << 31U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_en_dynramp_yes_f(void) +{ + return 0x80000000U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_en_dynramp_no_f(void) +{ + return 0x0U; +} +static inline u32 trim_gpc_bcast_gpcpll_ndiv_slowdown_debug_r(void) +{ + return 0x001328a0U; +} +static inline u32 trim_gpc_bcast_gpcpll_ndiv_slowdown_debug_pll_dynramp_done_synced_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +#endif diff --git a/include/gk20a/mm_gk20a.c b/include/gk20a/mm_gk20a.c new file mode 100644 index 0000000..10ca84d --- /dev/null +++ b/include/gk20a/mm_gk20a.c @@ -0,0 +1,654 @@ +/* + * Copyright (c) 2011-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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a.h" +#include "mm_gk20a.h" +#include "fence_gk20a.h" + +#include +#include +#include +#include + +/* + * GPU mapping life cycle + * ====================== + * + * Kernel mappings + * --------------- + * + * Kernel mappings are created through vm.map(..., false): + * + * - Mappings to the same allocations are reused and refcounted. + * - This path does not support deferred unmapping (i.e. kernel must wait for + * all hw operations on the buffer to complete before unmapping). + * - References to dmabuf are owned and managed by the (kernel) clients of + * the gk20a_vm layer. + * + * + * User space mappings + * ------------------- + * + * User space mappings are created through as.map_buffer -> vm.map(..., true): + * + * - Mappings to the same allocations are reused and refcounted. + * - This path supports deferred unmapping (i.e. we delay the actual unmapping + * until all hw operations have completed). + * - References to dmabuf are owned and managed by the vm_gk20a + * layer itself. vm.map acquires these refs, and sets + * mapped_buffer->own_mem_ref to record that we must release the refs when we + * actually unmap. + * + */ + +/* make sure gk20a_init_mm_support is called before */ +int gk20a_init_mm_setup_hw(struct gk20a *g) +{ + struct mm_gk20a *mm = &g->mm; + int err; + + nvgpu_log_fn(g, " "); + + if (g->ops.fb.set_mmu_page_size) { + g->ops.fb.set_mmu_page_size(g); + } + + if (g->ops.fb.set_use_full_comp_tag_line) { + mm->use_full_comp_tag_line = + g->ops.fb.set_use_full_comp_tag_line(g); + } + + g->ops.fb.init_hw(g); + + if (g->ops.bus.bar1_bind) { + g->ops.bus.bar1_bind(g, &mm->bar1.inst_block); + } + + if (g->ops.bus.bar2_bind) { + err = g->ops.bus.bar2_bind(g, &mm->bar2.inst_block); + if (err) { + return err; + } + } + + if (gk20a_mm_fb_flush(g) || gk20a_mm_fb_flush(g)) { + return -EBUSY; + } + + nvgpu_log_fn(g, "done"); + return 0; +} + +/* for gk20a the "video memory" apertures here are misnomers. */ +static inline u32 big_valid_pde0_bits(struct gk20a *g, + struct nvgpu_gmmu_pd *pd, u64 addr) +{ + u32 pde0_bits = + nvgpu_aperture_mask(g, pd->mem, + gmmu_pde_aperture_big_sys_mem_ncoh_f(), + gmmu_pde_aperture_big_sys_mem_coh_f(), + gmmu_pde_aperture_big_video_memory_f()) | + gmmu_pde_address_big_sys_f( + (u32)(addr >> gmmu_pde_address_shift_v())); + + return pde0_bits; +} + +static inline u32 small_valid_pde1_bits(struct gk20a *g, + struct nvgpu_gmmu_pd *pd, u64 addr) +{ + u32 pde1_bits = + nvgpu_aperture_mask(g, pd->mem, + gmmu_pde_aperture_small_sys_mem_ncoh_f(), + gmmu_pde_aperture_small_sys_mem_coh_f(), + gmmu_pde_aperture_small_video_memory_f()) | + gmmu_pde_vol_small_true_f() | /* tbd: why? */ + gmmu_pde_address_small_sys_f( + (u32)(addr >> gmmu_pde_address_shift_v())); + + return pde1_bits; +} + +static void update_gmmu_pde_locked(struct vm_gk20a *vm, + const struct gk20a_mmu_level *l, + struct nvgpu_gmmu_pd *pd, + u32 pd_idx, + u64 virt_addr, + u64 phys_addr, + struct nvgpu_gmmu_attrs *attrs) +{ + struct gk20a *g = gk20a_from_vm(vm); + bool small_valid, big_valid; + u32 pd_offset = pd_offset_from_index(l, pd_idx); + u32 pde_v[2] = {0, 0}; + + small_valid = attrs->pgsz == GMMU_PAGE_SIZE_SMALL; + big_valid = attrs->pgsz == GMMU_PAGE_SIZE_BIG; + + pde_v[0] = gmmu_pde_size_full_f(); + pde_v[0] |= big_valid ? + big_valid_pde0_bits(g, pd, phys_addr) : + gmmu_pde_aperture_big_invalid_f(); + + pde_v[1] |= (small_valid ? small_valid_pde1_bits(g, pd, phys_addr) : + (gmmu_pde_aperture_small_invalid_f() | + gmmu_pde_vol_small_false_f())) + | + (big_valid ? (gmmu_pde_vol_big_true_f()) : + gmmu_pde_vol_big_false_f()); + + pte_dbg(g, attrs, + "PDE: i=%-4u size=%-2u offs=%-4u pgsz: %c%c | " + "GPU %#-12llx phys %#-12llx " + "[0x%08x, 0x%08x]", + pd_idx, l->entry_size, pd_offset, + small_valid ? 'S' : '-', + big_valid ? 'B' : '-', + virt_addr, phys_addr, + pde_v[1], pde_v[0]); + + pd_write(g, &vm->pdb, pd_offset + 0, pde_v[0]); + pd_write(g, &vm->pdb, pd_offset + 1, pde_v[1]); +} + +static void __update_pte_sparse(u32 *pte_w) +{ + pte_w[0] = gmmu_pte_valid_false_f(); + pte_w[1] |= gmmu_pte_vol_true_f(); +} + +static void __update_pte(struct vm_gk20a *vm, + u32 *pte_w, + u64 phys_addr, + struct nvgpu_gmmu_attrs *attrs) +{ + struct gk20a *g = gk20a_from_vm(vm); + u32 page_size = vm->gmmu_page_sizes[attrs->pgsz]; + u32 pte_valid = attrs->valid ? + gmmu_pte_valid_true_f() : + gmmu_pte_valid_false_f(); + u32 phys_shifted = phys_addr >> gmmu_pte_address_shift_v(); + u32 addr = attrs->aperture == APERTURE_SYSMEM ? + gmmu_pte_address_sys_f(phys_shifted) : + gmmu_pte_address_vid_f(phys_shifted); + int ctag_shift = ilog2(g->ops.fb.compression_page_size(g)); + + pte_w[0] = pte_valid | addr; + + if (attrs->priv) { + pte_w[0] |= gmmu_pte_privilege_true_f(); + } + + pte_w[1] = nvgpu_aperture_mask_raw(g, attrs->aperture, + gmmu_pte_aperture_sys_mem_ncoh_f(), + gmmu_pte_aperture_sys_mem_coh_f(), + gmmu_pte_aperture_video_memory_f()) | + gmmu_pte_kind_f(attrs->kind_v) | + gmmu_pte_comptagline_f((u32)(attrs->ctag >> ctag_shift)); + + if (attrs->ctag && vm->mm->use_full_comp_tag_line && + phys_addr & 0x10000) { + pte_w[1] |= gmmu_pte_comptagline_f( + 1 << (gmmu_pte_comptagline_s() - 1)); + } + + if (attrs->rw_flag == gk20a_mem_flag_read_only) { + pte_w[0] |= gmmu_pte_read_only_true_f(); + pte_w[1] |= gmmu_pte_write_disable_true_f(); + } else if (attrs->rw_flag == gk20a_mem_flag_write_only) { + pte_w[1] |= gmmu_pte_read_disable_true_f(); + } + + if (!attrs->cacheable) { + pte_w[1] |= gmmu_pte_vol_true_f(); + } + + if (attrs->ctag) { + attrs->ctag += page_size; + } +} + +static void update_gmmu_pte_locked(struct vm_gk20a *vm, + const struct gk20a_mmu_level *l, + struct nvgpu_gmmu_pd *pd, + u32 pd_idx, + u64 virt_addr, + u64 phys_addr, + struct nvgpu_gmmu_attrs *attrs) +{ + struct gk20a *g = gk20a_from_vm(vm); + u32 page_size = vm->gmmu_page_sizes[attrs->pgsz]; + u32 pd_offset = pd_offset_from_index(l, pd_idx); + u32 pte_w[2] = {0, 0}; + int ctag_shift = ilog2(g->ops.fb.compression_page_size(g)); + + if (phys_addr) { + __update_pte(vm, pte_w, phys_addr, attrs); + } else if (attrs->sparse) { + __update_pte_sparse(pte_w); + } + + pte_dbg(g, attrs, + "PTE: i=%-4u size=%-2u offs=%-4u | " + "GPU %#-12llx phys %#-12llx " + "pgsz: %3dkb perm=%-2s kind=%#02x APT=%-6s %c%c%c%c " + "ctag=0x%08x " + "[0x%08x, 0x%08x]", + pd_idx, l->entry_size, pd_offset, + virt_addr, phys_addr, + page_size >> 10, + nvgpu_gmmu_perm_str(attrs->rw_flag), + attrs->kind_v, + nvgpu_aperture_str(g, attrs->aperture), + attrs->cacheable ? 'C' : '-', + attrs->sparse ? 'S' : '-', + attrs->priv ? 'P' : '-', + attrs->valid ? 'V' : '-', + (u32)attrs->ctag >> ctag_shift, + pte_w[1], pte_w[0]); + + pd_write(g, pd, pd_offset + 0, pte_w[0]); + pd_write(g, pd, pd_offset + 1, pte_w[1]); +} + +u32 gk20a_get_pde_pgsz(struct gk20a *g, const struct gk20a_mmu_level *l, + struct nvgpu_gmmu_pd *pd, u32 pd_idx) +{ + /* + * big and small page sizes are the same + */ + return GMMU_PAGE_SIZE_SMALL; +} + +u32 gk20a_get_pte_pgsz(struct gk20a *g, const struct gk20a_mmu_level *l, + struct nvgpu_gmmu_pd *pd, u32 pd_idx) +{ + /* + * return invalid + */ + return GMMU_NR_PAGE_SIZES; +} + +const struct gk20a_mmu_level gk20a_mm_levels_64k[] = { + {.hi_bit = {NV_GMMU_VA_RANGE-1, NV_GMMU_VA_RANGE-1}, + .lo_bit = {26, 26}, + .update_entry = update_gmmu_pde_locked, + .entry_size = 8, + .get_pgsz = gk20a_get_pde_pgsz}, + {.hi_bit = {25, 25}, + .lo_bit = {12, 16}, + .update_entry = update_gmmu_pte_locked, + .entry_size = 8, + .get_pgsz = gk20a_get_pte_pgsz}, + {.update_entry = NULL} +}; + +const struct gk20a_mmu_level gk20a_mm_levels_128k[] = { + {.hi_bit = {NV_GMMU_VA_RANGE-1, NV_GMMU_VA_RANGE-1}, + .lo_bit = {27, 27}, + .update_entry = update_gmmu_pde_locked, + .entry_size = 8, + .get_pgsz = gk20a_get_pde_pgsz}, + {.hi_bit = {26, 26}, + .lo_bit = {12, 17}, + .update_entry = update_gmmu_pte_locked, + .entry_size = 8, + .get_pgsz = gk20a_get_pte_pgsz}, + {.update_entry = NULL} +}; + +int gk20a_vm_bind_channel(struct vm_gk20a *vm, struct channel_gk20a *ch) +{ + int err = 0; + + nvgpu_log_fn(ch->g, " "); + + nvgpu_vm_get(vm); + ch->vm = vm; + err = channel_gk20a_commit_va(ch); + if (err) { + ch->vm = NULL; + } + + nvgpu_log(gk20a_from_vm(vm), gpu_dbg_map, "Binding ch=%d -> VM:%s", + ch->chid, vm->name); + + return err; +} + +void gk20a_mm_init_pdb(struct gk20a *g, struct nvgpu_mem *inst_block, + struct vm_gk20a *vm) +{ + u64 pdb_addr = nvgpu_mem_get_addr(g, vm->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, vm->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_page_dir_base_lo_f(pdb_addr_lo)); + + nvgpu_mem_wr32(g, inst_block, ram_in_page_dir_base_hi_w(), + ram_in_page_dir_base_hi_f(pdb_addr_hi)); +} + +void gk20a_init_inst_block(struct nvgpu_mem *inst_block, struct vm_gk20a *vm, + u32 big_page_size) +{ + struct gk20a *g = gk20a_from_vm(vm); + + nvgpu_log_info(g, "inst block phys = 0x%llx, kv = 0x%p", + nvgpu_inst_block_addr(g, inst_block), inst_block->cpu_va); + + g->ops.mm.init_pdb(g, inst_block, vm); + + nvgpu_mem_wr32(g, inst_block, ram_in_adr_limit_lo_w(), + u64_lo32(vm->va_limit - 1) & ~0xfff); + + nvgpu_mem_wr32(g, inst_block, ram_in_adr_limit_hi_w(), + ram_in_adr_limit_hi_f(u64_hi32(vm->va_limit - 1))); + + if (big_page_size && g->ops.mm.set_big_page_size) { + g->ops.mm.set_big_page_size(g, inst_block, big_page_size); + } +} + +int gk20a_alloc_inst_block(struct gk20a *g, struct nvgpu_mem *inst_block) +{ + int err; + + nvgpu_log_fn(g, " "); + + err = nvgpu_dma_alloc(g, ram_in_alloc_size_v(), inst_block); + if (err) { + nvgpu_err(g, "%s: memory allocation failed", __func__); + return err; + } + + nvgpu_log_fn(g, "done"); + return 0; +} + +int gk20a_mm_fb_flush(struct gk20a *g) +{ + struct mm_gk20a *mm = &g->mm; + u32 data; + int ret = 0; + struct nvgpu_timeout timeout; + u32 retries; + + nvgpu_log_fn(g, " "); + + gk20a_busy_noresume(g); + if (!g->power_on) { + gk20a_idle_nosuspend(g); + return 0; + } + + retries = 100; + + if (g->ops.mm.get_flush_retries) { + retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_FB); + } + + nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); + + nvgpu_mutex_acquire(&mm->l2_op_lock); + + /* Make sure all previous writes are committed to the L2. There's no + guarantee that writes are to DRAM. This will be a sysmembar internal + to the L2. */ + + trace_gk20a_mm_fb_flush(g->name); + + gk20a_writel(g, flush_fb_flush_r(), + flush_fb_flush_pending_busy_f()); + + do { + data = gk20a_readl(g, flush_fb_flush_r()); + + if (flush_fb_flush_outstanding_v(data) == + flush_fb_flush_outstanding_true_v() || + flush_fb_flush_pending_v(data) == + flush_fb_flush_pending_busy_v()) { + nvgpu_log_info(g, "fb_flush 0x%x", data); + nvgpu_udelay(5); + } else { + break; + } + } while (!nvgpu_timeout_expired(&timeout)); + + if (nvgpu_timeout_peek_expired(&timeout)) { + if (g->ops.fb.dump_vpr_info) { + g->ops.fb.dump_vpr_info(g); + } + if (g->ops.fb.dump_wpr_info) { + g->ops.fb.dump_wpr_info(g); + } + ret = -EBUSY; + } + + trace_gk20a_mm_fb_flush_done(g->name); + + nvgpu_mutex_release(&mm->l2_op_lock); + + gk20a_idle_nosuspend(g); + + return ret; +} + +static void gk20a_mm_l2_invalidate_locked(struct gk20a *g) +{ + u32 data; + struct nvgpu_timeout timeout; + u32 retries = 200; + + trace_gk20a_mm_l2_invalidate(g->name); + + if (g->ops.mm.get_flush_retries) { + retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_L2_INV); + } + + nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); + + /* Invalidate any clean lines from the L2 so subsequent reads go to + DRAM. Dirty lines are not affected by this operation. */ + gk20a_writel(g, flush_l2_system_invalidate_r(), + flush_l2_system_invalidate_pending_busy_f()); + + do { + data = gk20a_readl(g, flush_l2_system_invalidate_r()); + + if (flush_l2_system_invalidate_outstanding_v(data) == + flush_l2_system_invalidate_outstanding_true_v() || + flush_l2_system_invalidate_pending_v(data) == + flush_l2_system_invalidate_pending_busy_v()) { + nvgpu_log_info(g, "l2_system_invalidate 0x%x", + data); + nvgpu_udelay(5); + } else { + break; + } + } while (!nvgpu_timeout_expired(&timeout)); + + if (nvgpu_timeout_peek_expired(&timeout)) { + nvgpu_warn(g, "l2_system_invalidate too many retries"); + } + + trace_gk20a_mm_l2_invalidate_done(g->name); +} + +void gk20a_mm_l2_invalidate(struct gk20a *g) +{ + struct mm_gk20a *mm = &g->mm; + gk20a_busy_noresume(g); + if (g->power_on) { + nvgpu_mutex_acquire(&mm->l2_op_lock); + gk20a_mm_l2_invalidate_locked(g); + nvgpu_mutex_release(&mm->l2_op_lock); + } + gk20a_idle_nosuspend(g); +} + +void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate) +{ + struct mm_gk20a *mm = &g->mm; + u32 data; + struct nvgpu_timeout timeout; + u32 retries = 2000; + + nvgpu_log_fn(g, " "); + + gk20a_busy_noresume(g); + if (!g->power_on) { + goto hw_was_off; + } + + if (g->ops.mm.get_flush_retries) { + retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_L2_FLUSH); + } + + nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); + + nvgpu_mutex_acquire(&mm->l2_op_lock); + + trace_gk20a_mm_l2_flush(g->name); + + /* Flush all dirty lines from the L2 to DRAM. Lines are left in the L2 + as clean, so subsequent reads might hit in the L2. */ + gk20a_writel(g, flush_l2_flush_dirty_r(), + flush_l2_flush_dirty_pending_busy_f()); + + do { + data = gk20a_readl(g, flush_l2_flush_dirty_r()); + + if (flush_l2_flush_dirty_outstanding_v(data) == + flush_l2_flush_dirty_outstanding_true_v() || + flush_l2_flush_dirty_pending_v(data) == + flush_l2_flush_dirty_pending_busy_v()) { + nvgpu_log_info(g, "l2_flush_dirty 0x%x", data); + nvgpu_udelay(5); + } else { + break; + } + } while (!nvgpu_timeout_expired_msg(&timeout, + "l2_flush_dirty too many retries")); + + trace_gk20a_mm_l2_flush_done(g->name); + + if (invalidate) { + gk20a_mm_l2_invalidate_locked(g); + } + + nvgpu_mutex_release(&mm->l2_op_lock); + +hw_was_off: + gk20a_idle_nosuspend(g); +} + +void gk20a_mm_cbc_clean(struct gk20a *g) +{ + struct mm_gk20a *mm = &g->mm; + u32 data; + struct nvgpu_timeout timeout; + u32 retries = 200; + + nvgpu_log_fn(g, " "); + + gk20a_busy_noresume(g); + if (!g->power_on) { + goto hw_was_off; + } + + if (g->ops.mm.get_flush_retries) { + retries = g->ops.mm.get_flush_retries(g, NVGPU_FLUSH_CBC_CLEAN); + } + + nvgpu_timeout_init(g, &timeout, retries, NVGPU_TIMER_RETRY_TIMER); + + nvgpu_mutex_acquire(&mm->l2_op_lock); + + /* Flush all dirty lines from the CBC to L2 */ + gk20a_writel(g, flush_l2_clean_comptags_r(), + flush_l2_clean_comptags_pending_busy_f()); + + do { + data = gk20a_readl(g, flush_l2_clean_comptags_r()); + + if (flush_l2_clean_comptags_outstanding_v(data) == + flush_l2_clean_comptags_outstanding_true_v() || + flush_l2_clean_comptags_pending_v(data) == + flush_l2_clean_comptags_pending_busy_v()) { + nvgpu_log_info(g, "l2_clean_comptags 0x%x", data); + nvgpu_udelay(5); + } else { + break; + } + } while (!nvgpu_timeout_expired_msg(&timeout, + "l2_clean_comptags too many retries")); + + nvgpu_mutex_release(&mm->l2_op_lock); + +hw_was_off: + gk20a_idle_nosuspend(g); +} + +u32 gk20a_mm_get_iommu_bit(struct gk20a *g) +{ + return 34; +} + +const struct gk20a_mmu_level *gk20a_mm_get_mmu_levels(struct gk20a *g, + u32 big_page_size) +{ + return (big_page_size == SZ_64K) ? + gk20a_mm_levels_64k : gk20a_mm_levels_128k; +} diff --git a/include/gk20a/mm_gk20a.h b/include/gk20a/mm_gk20a.h new file mode 100644 index 0000000..76a1621 --- /dev/null +++ b/include/gk20a/mm_gk20a.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef MM_GK20A_H +#define MM_GK20A_H + +#include +#include +#include +#include +#include +#include + +enum gk20a_mem_rw_flag; + +struct patch_desc { + struct nvgpu_mem mem; + u32 data_count; +}; + +struct zcull_ctx_desc { + u64 gpu_va; + u32 ctx_attr; + u32 ctx_sw_mode; +}; + +struct pm_ctx_desc { + struct nvgpu_mem mem; + u32 pm_mode; +}; + +struct compbit_store_desc { + struct nvgpu_mem mem; + + /* The value that is written to the hardware. This depends on + * on the number of ltcs and is not an address. */ + u64 base_hw; +}; + +struct gk20a_buffer_state { + struct nvgpu_list_node list; + + /* The valid compbits and the fence must be changed atomically. */ + struct nvgpu_mutex lock; + + /* Offset of the surface within the dma-buf whose state is + * described by this struct (one dma-buf can contain multiple + * surfaces with different states). */ + size_t offset; + + /* A bitmask of valid sets of compbits (0 = uncompressed). */ + u32 valid_compbits; + + /* The ZBC color used on this buffer. */ + u32 zbc_color; + + /* This struct reflects the state of the buffer when this + * fence signals. */ + struct gk20a_fence *fence; +}; + +static inline struct gk20a_buffer_state * +gk20a_buffer_state_from_list(struct nvgpu_list_node *node) +{ + return (struct gk20a_buffer_state *) + ((uintptr_t)node - offsetof(struct gk20a_buffer_state, list)); +}; + +struct gk20a; +struct channel_gk20a; + +int gk20a_mm_fb_flush(struct gk20a *g); +void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate); +void gk20a_mm_cbc_clean(struct gk20a *g); +void gk20a_mm_l2_invalidate(struct gk20a *g); + +#define dev_from_vm(vm) dev_from_gk20a(vm->mm->g) + +void gk20a_mm_ltc_isr(struct gk20a *g); + +bool gk20a_mm_mmu_debug_mode_enabled(struct gk20a *g); + +int gk20a_alloc_inst_block(struct gk20a *g, struct nvgpu_mem *inst_block); +void gk20a_init_inst_block(struct nvgpu_mem *inst_block, struct vm_gk20a *vm, + u32 big_page_size); +int gk20a_init_mm_setup_hw(struct gk20a *g); + +u64 gk20a_locked_gmmu_map(struct vm_gk20a *vm, + u64 map_offset, + struct nvgpu_sgt *sgt, + u64 buffer_offset, + u64 size, + u32 pgsz_idx, + u8 kind_v, + u32 ctag_offset, + u32 flags, + enum gk20a_mem_rw_flag rw_flag, + bool clear_ctags, + bool sparse, + bool priv, + struct vm_gk20a_mapping_batch *batch, + enum nvgpu_aperture aperture); + +void gk20a_locked_gmmu_unmap(struct vm_gk20a *vm, + u64 vaddr, + u64 size, + u32 pgsz_idx, + bool va_allocated, + enum gk20a_mem_rw_flag rw_flag, + bool sparse, + struct vm_gk20a_mapping_batch *batch); + +/* vm-as interface */ +struct nvgpu_as_alloc_space_args; +struct nvgpu_as_free_space_args; +int gk20a_vm_release_share(struct gk20a_as_share *as_share); +int gk20a_vm_bind_channel(struct vm_gk20a *vm, struct channel_gk20a *ch); + +void pde_range_from_vaddr_range(struct vm_gk20a *vm, + u64 addr_lo, u64 addr_hi, + u32 *pde_lo, u32 *pde_hi); +u32 gk20a_mm_get_iommu_bit(struct gk20a *g); + +const struct gk20a_mmu_level *gk20a_mm_get_mmu_levels(struct gk20a *g, + u32 big_page_size); +void gk20a_mm_init_pdb(struct gk20a *g, struct nvgpu_mem *mem, + struct vm_gk20a *vm); + +extern const struct gk20a_mmu_level gk20a_mm_levels_64k[]; +extern const struct gk20a_mmu_level gk20a_mm_levels_128k[]; + +u32 gk20a_get_pde_pgsz(struct gk20a *g, const struct gk20a_mmu_level *l, + struct nvgpu_gmmu_pd *pd, u32 pd_idx); +u32 gk20a_get_pte_pgsz(struct gk20a *g, const struct gk20a_mmu_level *l, + struct nvgpu_gmmu_pd *pd, u32 pd_idx); +#endif /* MM_GK20A_H */ diff --git a/include/gk20a/pmu_gk20a.c b/include/gk20a/pmu_gk20a.c new file mode 100644 index 0000000..63a32f0 --- /dev/null +++ b/include/gk20a/pmu_gk20a.c @@ -0,0 +1,879 @@ +/* + * GK20A PMU (aka. gPMU outside gk20a context) + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a.h" +#include "gr_gk20a.h" +#include "pmu_gk20a.h" + +#include +#include +#include + +#define gk20a_dbg_pmu(g, fmt, arg...) \ + nvgpu_log(g, gpu_dbg_pmu, fmt, ##arg) + +bool nvgpu_find_hex_in_string(char *strings, struct gk20a *g, u32 *hex_pos) +{ + u32 i = 0, j = strlen(strings); + + for (; i < j; i++) { + if (strings[i] == '%') { + if (strings[i + 1] == 'x' || strings[i + 1] == 'X') { + *hex_pos = i; + return true; + } + } + } + *hex_pos = -1; + return false; +} + +static void print_pmu_trace(struct nvgpu_pmu *pmu) +{ + struct gk20a *g = pmu->g; + u32 i = 0, j = 0, k, l, m, count; + char part_str[40], buf[0x40]; + void *tracebuffer; + char *trace; + u32 *trace1; + + /* allocate system memory to copy pmu trace buffer */ + tracebuffer = nvgpu_kzalloc(g, GK20A_PMU_TRACE_BUFSIZE); + if (tracebuffer == NULL) { + return; + } + + /* read pmu traces into system memory buffer */ + nvgpu_mem_rd_n(g, &pmu->trace_buf, 0, tracebuffer, + GK20A_PMU_TRACE_BUFSIZE); + + trace = (char *)tracebuffer; + trace1 = (u32 *)tracebuffer; + + nvgpu_err(g, "dump PMU trace buffer"); + for (i = 0; i < GK20A_PMU_TRACE_BUFSIZE; i += 0x40) { + for (j = 0; j < 0x40; j++) { + if (trace1[(i / 4) + j]) { + break; + } + } + if (j == 0x40) { + break; + } + count = scnprintf(buf, 0x40, "Index %x: ", trace1[(i / 4)]); + l = 0; + m = 0; + while (nvgpu_find_hex_in_string((trace+i+20+m), g, &k)) { + if (k >= 40) { + break; + } + strncpy(part_str, (trace+i+20+m), k); + part_str[k] = '\0'; + count += scnprintf((buf + count), 0x40, "%s0x%x", + part_str, trace1[(i / 4) + 1 + l]); + l++; + m += k + 2; + } + + scnprintf((buf + count), 0x40, "%s", (trace+i+20+m)); + nvgpu_err(g, "%s", buf); + } + + nvgpu_kfree(g, tracebuffer); +} + +u32 gk20a_pmu_get_irqdest(struct gk20a *g) +{ + u32 intr_dest; + + /* dest 0=falcon, 1=host; level 0=irq0, 1=irq1 */ + intr_dest = pwr_falcon_irqdest_host_gptmr_f(0) | + pwr_falcon_irqdest_host_wdtmr_f(1) | + pwr_falcon_irqdest_host_mthd_f(0) | + pwr_falcon_irqdest_host_ctxsw_f(0) | + pwr_falcon_irqdest_host_halt_f(1) | + pwr_falcon_irqdest_host_exterr_f(0) | + pwr_falcon_irqdest_host_swgen0_f(1) | + pwr_falcon_irqdest_host_swgen1_f(0) | + pwr_falcon_irqdest_host_ext_f(0xff) | + pwr_falcon_irqdest_target_gptmr_f(1) | + pwr_falcon_irqdest_target_wdtmr_f(0) | + pwr_falcon_irqdest_target_mthd_f(0) | + pwr_falcon_irqdest_target_ctxsw_f(0) | + pwr_falcon_irqdest_target_halt_f(0) | + pwr_falcon_irqdest_target_exterr_f(0) | + pwr_falcon_irqdest_target_swgen0_f(0) | + pwr_falcon_irqdest_target_swgen1_f(0) | + pwr_falcon_irqdest_target_ext_f(0xff); + + return intr_dest; +} + +void gk20a_pmu_enable_irq(struct nvgpu_pmu *pmu, bool enable) +{ + struct gk20a *g = gk20a_from_pmu(pmu); + u32 intr_mask; + u32 intr_dest; + + nvgpu_log_fn(g, " "); + + g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_DISABLE, true, + mc_intr_mask_0_pmu_enabled_f()); + g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_DISABLE, false, + mc_intr_mask_1_pmu_enabled_f()); + + nvgpu_flcn_set_irq(pmu->flcn, false, 0x0, 0x0); + + if (enable) { + intr_dest = g->ops.pmu.get_irqdest(g); + /* 0=disable, 1=enable */ + intr_mask = pwr_falcon_irqmset_gptmr_f(1) | + pwr_falcon_irqmset_wdtmr_f(1) | + pwr_falcon_irqmset_mthd_f(0) | + pwr_falcon_irqmset_ctxsw_f(0) | + pwr_falcon_irqmset_halt_f(1) | + pwr_falcon_irqmset_exterr_f(1) | + pwr_falcon_irqmset_swgen0_f(1) | + pwr_falcon_irqmset_swgen1_f(1); + + nvgpu_flcn_set_irq(pmu->flcn, true, intr_mask, intr_dest); + + g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_ENABLE, true, + mc_intr_mask_0_pmu_enabled_f()); + } + + nvgpu_log_fn(g, "done"); +} + + + +int pmu_bootstrap(struct nvgpu_pmu *pmu) +{ + struct gk20a *g = gk20a_from_pmu(pmu); + struct mm_gk20a *mm = &g->mm; + struct pmu_ucode_desc *desc = pmu->desc; + u64 addr_code, addr_data, addr_load; + u32 i, blocks, addr_args; + + nvgpu_log_fn(g, " "); + + gk20a_writel(g, pwr_falcon_itfen_r(), + gk20a_readl(g, pwr_falcon_itfen_r()) | + pwr_falcon_itfen_ctxen_enable_f()); + gk20a_writel(g, pwr_pmu_new_instblk_r(), + pwr_pmu_new_instblk_ptr_f( + nvgpu_inst_block_addr(g, &mm->pmu.inst_block) >> 12) | + pwr_pmu_new_instblk_valid_f(1) | + pwr_pmu_new_instblk_target_sys_coh_f()); + + /* TBD: load all other surfaces */ + g->ops.pmu_ver.set_pmu_cmdline_args_trace_size( + pmu, GK20A_PMU_TRACE_BUFSIZE); + g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_base(pmu); + g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_idx( + pmu, GK20A_PMU_DMAIDX_VIRT); + + g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu, + g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_PWRCLK)); + + addr_args = (pwr_falcon_hwcfg_dmem_size_v( + gk20a_readl(g, pwr_falcon_hwcfg_r())) + << GK20A_PMU_DMEM_BLKSIZE2) - + g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu); + + nvgpu_flcn_copy_to_dmem(pmu->flcn, addr_args, + (u8 *)(g->ops.pmu_ver.get_pmu_cmdline_args_ptr(pmu)), + g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu), 0); + + gk20a_writel(g, pwr_falcon_dmemc_r(0), + pwr_falcon_dmemc_offs_f(0) | + pwr_falcon_dmemc_blk_f(0) | + pwr_falcon_dmemc_aincw_f(1)); + + addr_code = u64_lo32((pmu->ucode.gpu_va + + desc->app_start_offset + + desc->app_resident_code_offset) >> 8) ; + addr_data = u64_lo32((pmu->ucode.gpu_va + + desc->app_start_offset + + desc->app_resident_data_offset) >> 8); + addr_load = u64_lo32((pmu->ucode.gpu_va + + desc->bootloader_start_offset) >> 8); + + gk20a_writel(g, pwr_falcon_dmemd_r(0), GK20A_PMU_DMAIDX_UCODE); + gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_code); + gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_size); + gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_resident_code_size); + gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_imem_entry); + gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_data); + gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_resident_data_size); + gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_code); + gk20a_writel(g, pwr_falcon_dmemd_r(0), 0x1); + gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_args); + + g->ops.pmu.write_dmatrfbase(g, + addr_load - (desc->bootloader_imem_offset >> 8)); + + blocks = ((desc->bootloader_size + 0xFF) & ~0xFF) >> 8; + + for (i = 0; i < blocks; i++) { + gk20a_writel(g, pwr_falcon_dmatrfmoffs_r(), + desc->bootloader_imem_offset + (i << 8)); + gk20a_writel(g, pwr_falcon_dmatrffboffs_r(), + desc->bootloader_imem_offset + (i << 8)); + gk20a_writel(g, pwr_falcon_dmatrfcmd_r(), + pwr_falcon_dmatrfcmd_imem_f(1) | + pwr_falcon_dmatrfcmd_write_f(0) | + pwr_falcon_dmatrfcmd_size_f(6) | + pwr_falcon_dmatrfcmd_ctxdma_f(GK20A_PMU_DMAIDX_UCODE)); + } + + nvgpu_flcn_bootstrap(g->pmu.flcn, desc->bootloader_entry_point); + + gk20a_writel(g, pwr_falcon_os_r(), desc->app_version); + + return 0; +} + +void gk20a_pmu_pg_idle_counter_config(struct gk20a *g, u32 pg_engine_id) +{ + gk20a_writel(g, pwr_pmu_pg_idlefilth_r(pg_engine_id), + PMU_PG_IDLE_THRESHOLD); + gk20a_writel(g, pwr_pmu_pg_ppuidlefilth_r(pg_engine_id), + PMU_PG_POST_POWERUP_IDLE_THRESHOLD); +} + +int gk20a_pmu_mutex_acquire(struct nvgpu_pmu *pmu, u32 id, u32 *token) +{ + struct gk20a *g = gk20a_from_pmu(pmu); + struct pmu_mutex *mutex; + u32 data, owner, max_retry; + + if (!pmu->initialized) { + return -EINVAL; + } + + BUG_ON(!token); + BUG_ON(!PMU_MUTEX_ID_IS_VALID(id)); + BUG_ON(id > pmu->mutex_cnt); + + mutex = &pmu->mutex[id]; + + owner = pwr_pmu_mutex_value_v( + gk20a_readl(g, pwr_pmu_mutex_r(mutex->index))); + + if (*token != PMU_INVALID_MUTEX_OWNER_ID && *token == owner) { + BUG_ON(mutex->ref_cnt == 0); + gk20a_dbg_pmu(g, "already acquired by owner : 0x%08x", *token); + mutex->ref_cnt++; + return 0; + } + + max_retry = 40; + do { + data = pwr_pmu_mutex_id_value_v( + gk20a_readl(g, pwr_pmu_mutex_id_r())); + if (data == pwr_pmu_mutex_id_value_init_v() || + data == pwr_pmu_mutex_id_value_not_avail_v()) { + nvgpu_warn(g, + "fail to generate mutex token: val 0x%08x", + owner); + nvgpu_usleep_range(20, 40); + continue; + } + + owner = data; + gk20a_writel(g, pwr_pmu_mutex_r(mutex->index), + pwr_pmu_mutex_value_f(owner)); + + data = pwr_pmu_mutex_value_v( + gk20a_readl(g, pwr_pmu_mutex_r(mutex->index))); + + if (owner == data) { + mutex->ref_cnt = 1; + gk20a_dbg_pmu(g, "mutex acquired: id=%d, token=0x%x", + mutex->index, *token); + *token = owner; + return 0; + } else { + nvgpu_log_info(g, "fail to acquire mutex idx=0x%08x", + mutex->index); + + data = gk20a_readl(g, pwr_pmu_mutex_id_release_r()); + data = set_field(data, + pwr_pmu_mutex_id_release_value_m(), + pwr_pmu_mutex_id_release_value_f(owner)); + gk20a_writel(g, pwr_pmu_mutex_id_release_r(), data); + + nvgpu_usleep_range(20, 40); + continue; + } + } while (max_retry-- > 0); + + return -EBUSY; +} + +int gk20a_pmu_mutex_release(struct nvgpu_pmu *pmu, u32 id, u32 *token) +{ + struct gk20a *g = gk20a_from_pmu(pmu); + struct pmu_mutex *mutex; + u32 owner, data; + + if (!pmu->initialized) { + return -EINVAL; + } + + BUG_ON(!token); + BUG_ON(!PMU_MUTEX_ID_IS_VALID(id)); + BUG_ON(id > pmu->mutex_cnt); + + mutex = &pmu->mutex[id]; + + owner = pwr_pmu_mutex_value_v( + gk20a_readl(g, pwr_pmu_mutex_r(mutex->index))); + + if (*token != owner) { + nvgpu_err(g, "requester 0x%08x NOT match owner 0x%08x", + *token, owner); + return -EINVAL; + } + + if (--mutex->ref_cnt > 0) { + return -EBUSY; + } + + gk20a_writel(g, pwr_pmu_mutex_r(mutex->index), + pwr_pmu_mutex_value_initial_lock_f()); + + data = gk20a_readl(g, pwr_pmu_mutex_id_release_r()); + data = set_field(data, pwr_pmu_mutex_id_release_value_m(), + pwr_pmu_mutex_id_release_value_f(owner)); + gk20a_writel(g, pwr_pmu_mutex_id_release_r(), data); + + gk20a_dbg_pmu(g, "mutex released: id=%d, token=0x%x", + mutex->index, *token); + + return 0; +} + +int gk20a_pmu_queue_head(struct gk20a *g, struct nvgpu_falcon_queue *queue, + u32 *head, bool set) +{ + u32 queue_head_size = 0; + + if (g->ops.pmu.pmu_get_queue_head_size) { + queue_head_size = g->ops.pmu.pmu_get_queue_head_size(); + } + + BUG_ON(!head || !queue_head_size); + + if (PMU_IS_COMMAND_QUEUE(queue->id)) { + + if (queue->index >= queue_head_size) { + return -EINVAL; + } + + if (!set) { + *head = pwr_pmu_queue_head_address_v( + gk20a_readl(g, + g->ops.pmu.pmu_get_queue_head(queue->index))); + } else { + gk20a_writel(g, + g->ops.pmu.pmu_get_queue_head(queue->index), + pwr_pmu_queue_head_address_f(*head)); + } + } else { + if (!set) { + *head = pwr_pmu_msgq_head_val_v( + gk20a_readl(g, pwr_pmu_msgq_head_r())); + } else { + gk20a_writel(g, + pwr_pmu_msgq_head_r(), + pwr_pmu_msgq_head_val_f(*head)); + } + } + + return 0; +} + +int gk20a_pmu_queue_tail(struct gk20a *g, struct nvgpu_falcon_queue *queue, + u32 *tail, bool set) +{ + u32 queue_tail_size = 0; + + if (g->ops.pmu.pmu_get_queue_tail_size) { + queue_tail_size = g->ops.pmu.pmu_get_queue_tail_size(); + } + + BUG_ON(!tail || !queue_tail_size); + + if (PMU_IS_COMMAND_QUEUE(queue->id)) { + + if (queue->index >= queue_tail_size) { + return -EINVAL; + } + + if (!set) { + *tail = pwr_pmu_queue_tail_address_v(gk20a_readl(g, + g->ops.pmu.pmu_get_queue_tail(queue->index))); + } else { + gk20a_writel(g, + g->ops.pmu.pmu_get_queue_tail(queue->index), + pwr_pmu_queue_tail_address_f(*tail)); + } + + } else { + if (!set) { + *tail = pwr_pmu_msgq_tail_val_v( + gk20a_readl(g, pwr_pmu_msgq_tail_r())); + } else { + gk20a_writel(g, + pwr_pmu_msgq_tail_r(), + pwr_pmu_msgq_tail_val_f(*tail)); + } + } + + return 0; +} + +void gk20a_pmu_msgq_tail(struct nvgpu_pmu *pmu, u32 *tail, bool set) +{ + struct gk20a *g = gk20a_from_pmu(pmu); + u32 queue_tail_size = 0; + + if (g->ops.pmu.pmu_get_queue_tail_size) { + queue_tail_size = g->ops.pmu.pmu_get_queue_tail_size(); + } + + BUG_ON(!tail || !queue_tail_size); + + if (!set) { + *tail = pwr_pmu_msgq_tail_val_v( + gk20a_readl(g, pwr_pmu_msgq_tail_r())); + } else { + gk20a_writel(g, + pwr_pmu_msgq_tail_r(), + pwr_pmu_msgq_tail_val_f(*tail)); + } +} + +void gk20a_write_dmatrfbase(struct gk20a *g, u32 addr) +{ + gk20a_writel(g, pwr_falcon_dmatrfbase_r(), addr); +} + +bool gk20a_pmu_is_engine_in_reset(struct gk20a *g) +{ + bool status = false; + + status = g->ops.mc.is_enabled(g, NVGPU_UNIT_PWR); + + return status; +} + +int gk20a_pmu_engine_reset(struct gk20a *g, bool do_reset) +{ + u32 reset_mask = g->ops.mc.reset_mask(g, NVGPU_UNIT_PWR); + + if (do_reset) { + g->ops.mc.enable(g, reset_mask); + } else { + g->ops.mc.disable(g, reset_mask); + } + + return 0; +} + +bool gk20a_is_pmu_supported(struct gk20a *g) +{ + return true; +} + +u32 gk20a_pmu_pg_engines_list(struct gk20a *g) +{ + return BIT(PMU_PG_ELPG_ENGINE_ID_GRAPHICS); +} + +u32 gk20a_pmu_pg_feature_list(struct gk20a *g, u32 pg_engine_id) +{ + if (pg_engine_id == PMU_PG_ELPG_ENGINE_ID_GRAPHICS) { + return NVGPU_PMU_GR_FEATURE_MASK_POWER_GATING; + } + + return 0; +} + +static void pmu_handle_zbc_msg(struct gk20a *g, struct pmu_msg *msg, + void *param, u32 handle, u32 status) +{ + struct nvgpu_pmu *pmu = param; + gk20a_dbg_pmu(g, "reply ZBC_TABLE_UPDATE"); + pmu->zbc_save_done = 1; +} + +void gk20a_pmu_save_zbc(struct gk20a *g, u32 entries) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct pmu_cmd cmd; + u32 seq; + + if (!pmu->pmu_ready || !entries || !pmu->zbc_ready) { + return; + } + + memset(&cmd, 0, sizeof(struct pmu_cmd)); + cmd.hdr.unit_id = PMU_UNIT_PG; + cmd.hdr.size = PMU_CMD_HDR_SIZE + sizeof(struct pmu_zbc_cmd); + cmd.cmd.zbc.cmd_type = g->pmu_ver_cmd_id_zbc_table_update; + cmd.cmd.zbc.entry_mask = ZBC_MASK(entries); + + pmu->zbc_save_done = 0; + + gk20a_dbg_pmu(g, "cmd post ZBC_TABLE_UPDATE"); + nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ, + pmu_handle_zbc_msg, pmu, &seq, ~0); + pmu_wait_message_cond(pmu, gk20a_get_gr_idle_timeout(g), + &pmu->zbc_save_done, 1); + if (!pmu->zbc_save_done) { + nvgpu_err(g, "ZBC save timeout"); + } +} + +int nvgpu_pmu_handle_therm_event(struct nvgpu_pmu *pmu, + struct nv_pmu_therm_msg *msg) +{ + struct gk20a *g = gk20a_from_pmu(pmu); + + nvgpu_log_fn(g, " "); + + switch (msg->msg_type) { + case NV_PMU_THERM_MSG_ID_EVENT_HW_SLOWDOWN_NOTIFICATION: + if (msg->hw_slct_msg.mask == BIT(NV_PMU_THERM_EVENT_THERMAL_1)) { + nvgpu_clk_arb_send_thermal_alarm(pmu->g); + } else { + gk20a_dbg_pmu(g, "Unwanted/Unregistered thermal event received %d", + msg->hw_slct_msg.mask); + } + break; + default: + gk20a_dbg_pmu(g, "unkown therm event received %d", msg->msg_type); + break; + } + + return 0; +} + +void gk20a_pmu_dump_elpg_stats(struct nvgpu_pmu *pmu) +{ + struct gk20a *g = gk20a_from_pmu(pmu); + + gk20a_dbg_pmu(g, "pwr_pmu_idle_mask_supp_r(3): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_mask_supp_r(3))); + gk20a_dbg_pmu(g, "pwr_pmu_idle_mask_1_supp_r(3): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_mask_1_supp_r(3))); + gk20a_dbg_pmu(g, "pwr_pmu_idle_ctrl_supp_r(3): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_ctrl_supp_r(3))); + gk20a_dbg_pmu(g, "pwr_pmu_pg_idle_cnt_r(0): 0x%08x", + gk20a_readl(g, pwr_pmu_pg_idle_cnt_r(0))); + gk20a_dbg_pmu(g, "pwr_pmu_pg_intren_r(0): 0x%08x", + gk20a_readl(g, pwr_pmu_pg_intren_r(0))); + + gk20a_dbg_pmu(g, "pwr_pmu_idle_count_r(3): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_count_r(3))); + gk20a_dbg_pmu(g, "pwr_pmu_idle_count_r(4): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_count_r(4))); + gk20a_dbg_pmu(g, "pwr_pmu_idle_count_r(7): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_count_r(7))); +} + +void gk20a_pmu_dump_falcon_stats(struct nvgpu_pmu *pmu) +{ + struct gk20a *g = gk20a_from_pmu(pmu); + unsigned int i; + + for (i = 0; i < pwr_pmu_mailbox__size_1_v(); i++) { + nvgpu_err(g, "pwr_pmu_mailbox_r(%d) : 0x%x", + i, gk20a_readl(g, pwr_pmu_mailbox_r(i))); + } + + for (i = 0; i < pwr_pmu_debug__size_1_v(); i++) { + nvgpu_err(g, "pwr_pmu_debug_r(%d) : 0x%x", + i, gk20a_readl(g, pwr_pmu_debug_r(i))); + } + + i = gk20a_readl(g, pwr_pmu_bar0_error_status_r()); + nvgpu_err(g, "pwr_pmu_bar0_error_status_r : 0x%x", i); + if (i != 0) { + nvgpu_err(g, "pwr_pmu_bar0_addr_r : 0x%x", + gk20a_readl(g, pwr_pmu_bar0_addr_r())); + nvgpu_err(g, "pwr_pmu_bar0_data_r : 0x%x", + gk20a_readl(g, pwr_pmu_bar0_data_r())); + nvgpu_err(g, "pwr_pmu_bar0_timeout_r : 0x%x", + gk20a_readl(g, pwr_pmu_bar0_timeout_r())); + nvgpu_err(g, "pwr_pmu_bar0_ctl_r : 0x%x", + gk20a_readl(g, pwr_pmu_bar0_ctl_r())); + } + + i = gk20a_readl(g, pwr_pmu_bar0_fecs_error_r()); + nvgpu_err(g, "pwr_pmu_bar0_fecs_error_r : 0x%x", i); + + i = gk20a_readl(g, pwr_falcon_exterrstat_r()); + nvgpu_err(g, "pwr_falcon_exterrstat_r : 0x%x", i); + if (pwr_falcon_exterrstat_valid_v(i) == + pwr_falcon_exterrstat_valid_true_v()) { + nvgpu_err(g, "pwr_falcon_exterraddr_r : 0x%x", + gk20a_readl(g, pwr_falcon_exterraddr_r())); + } + + /* Print PMU F/W debug prints */ + print_pmu_trace(pmu); +} + +bool gk20a_pmu_is_interrupted(struct nvgpu_pmu *pmu) +{ + struct gk20a *g = gk20a_from_pmu(pmu); + u32 servicedpmuint; + + servicedpmuint = pwr_falcon_irqstat_halt_true_f() | + pwr_falcon_irqstat_exterr_true_f() | + pwr_falcon_irqstat_swgen0_true_f(); + + if (gk20a_readl(g, pwr_falcon_irqstat_r()) & servicedpmuint) { + return true; + } + + return false; +} + +void gk20a_pmu_isr(struct gk20a *g) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct nvgpu_falcon_queue *queue; + u32 intr, mask; + bool recheck = false; + + nvgpu_log_fn(g, " "); + + nvgpu_mutex_acquire(&pmu->isr_mutex); + if (!pmu->isr_enabled) { + nvgpu_mutex_release(&pmu->isr_mutex); + return; + } + + mask = gk20a_readl(g, pwr_falcon_irqmask_r()) & + gk20a_readl(g, pwr_falcon_irqdest_r()); + + intr = gk20a_readl(g, pwr_falcon_irqstat_r()); + + gk20a_dbg_pmu(g, "received falcon interrupt: 0x%08x", intr); + + intr = gk20a_readl(g, pwr_falcon_irqstat_r()) & mask; + if (!intr || pmu->pmu_state == PMU_STATE_OFF) { + gk20a_writel(g, pwr_falcon_irqsclr_r(), intr); + nvgpu_mutex_release(&pmu->isr_mutex); + return; + } + + if (intr & pwr_falcon_irqstat_halt_true_f()) { + nvgpu_err(g, "pmu halt intr not implemented"); + nvgpu_pmu_dump_falcon_stats(pmu); + if (gk20a_readl(g, pwr_pmu_mailbox_r + (PMU_MODE_MISMATCH_STATUS_MAILBOX_R)) == + PMU_MODE_MISMATCH_STATUS_VAL) { + if (g->ops.pmu.dump_secure_fuses) { + g->ops.pmu.dump_secure_fuses(g); + } + } + } + if (intr & pwr_falcon_irqstat_exterr_true_f()) { + nvgpu_err(g, + "pmu exterr intr not implemented. Clearing interrupt."); + nvgpu_pmu_dump_falcon_stats(pmu); + + gk20a_writel(g, pwr_falcon_exterrstat_r(), + gk20a_readl(g, pwr_falcon_exterrstat_r()) & + ~pwr_falcon_exterrstat_valid_m()); + } + + if (g->ops.pmu.handle_ext_irq) { + g->ops.pmu.handle_ext_irq(g, intr); + } + + if (intr & pwr_falcon_irqstat_swgen0_true_f()) { + nvgpu_pmu_process_message(pmu); + recheck = true; + } + + gk20a_writel(g, pwr_falcon_irqsclr_r(), intr); + + if (recheck) { + queue = &pmu->queue[PMU_MESSAGE_QUEUE]; + if (!nvgpu_flcn_queue_is_empty(pmu->flcn, queue)) { + gk20a_writel(g, pwr_falcon_irqsset_r(), + pwr_falcon_irqsset_swgen0_set_f()); + } + } + + nvgpu_mutex_release(&pmu->isr_mutex); +} + +void gk20a_pmu_init_perfmon_counter(struct gk20a *g) +{ + u32 data; + + /* use counter #3 for GR && CE2 busy cycles */ + gk20a_writel(g, pwr_pmu_idle_mask_r(3), + pwr_pmu_idle_mask_gr_enabled_f() | + pwr_pmu_idle_mask_ce_2_enabled_f()); + + /* assign same mask setting from GR ELPG to counter #3 */ + data = gk20a_readl(g, pwr_pmu_idle_mask_1_supp_r(0)); + gk20a_writel(g, pwr_pmu_idle_mask_1_r(3), data); + + /* disable idle filtering for counters 3 and 6 */ + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(3)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_busy_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(3), data); + + /* use counter #6 for total cycles */ + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(6)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_always_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(6), data); + + /* + * We don't want to disturb counters #3 and #6, which are used by + * perfmon, so we add wiring also to counters #1 and #2 for + * exposing raw counter readings. + */ + gk20a_writel(g, pwr_pmu_idle_mask_r(1), + pwr_pmu_idle_mask_gr_enabled_f() | + pwr_pmu_idle_mask_ce_2_enabled_f()); + + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(1)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_busy_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(1), data); + + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(2)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_always_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(2), data); + + /* + * use counters 4 and 0 for perfmon to log busy cycles and total cycles + * counter #0 overflow sets pmu idle intr status bit + */ + gk20a_writel(g, pwr_pmu_idle_intr_r(), + pwr_pmu_idle_intr_en_f(0)); + + gk20a_writel(g, pwr_pmu_idle_threshold_r(0), + pwr_pmu_idle_threshold_value_f(0x7FFFFFFF)); + + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(0)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_always_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(0), data); + + gk20a_writel(g, pwr_pmu_idle_mask_r(4), + pwr_pmu_idle_mask_gr_enabled_f() | + pwr_pmu_idle_mask_ce_2_enabled_f()); + + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(4)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_busy_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(4), data); + + gk20a_writel(g, pwr_pmu_idle_count_r(0), pwr_pmu_idle_count_reset_f(1)); + gk20a_writel(g, pwr_pmu_idle_count_r(4), pwr_pmu_idle_count_reset_f(1)); + gk20a_writel(g, pwr_pmu_idle_intr_status_r(), + pwr_pmu_idle_intr_status_intr_f(1)); +} + +u32 gk20a_pmu_read_idle_counter(struct gk20a *g, u32 counter_id) +{ + return pwr_pmu_idle_count_value_v( + gk20a_readl(g, pwr_pmu_idle_count_r(counter_id))); +} + +void gk20a_pmu_reset_idle_counter(struct gk20a *g, u32 counter_id) +{ + gk20a_writel(g, pwr_pmu_idle_count_r(counter_id), + pwr_pmu_idle_count_reset_f(1)); +} + +u32 gk20a_pmu_read_idle_intr_status(struct gk20a *g) +{ + return pwr_pmu_idle_intr_status_intr_v( + gk20a_readl(g, pwr_pmu_idle_intr_status_r())); +} + +void gk20a_pmu_clear_idle_intr_status(struct gk20a *g) +{ + gk20a_writel(g, pwr_pmu_idle_intr_status_r(), + pwr_pmu_idle_intr_status_intr_f(1)); +} + +void gk20a_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 stats; + + nvgpu_flcn_copy_from_dmem(pmu->flcn, + pmu->stat_dmem_offset[pg_engine_id], + (u8 *)&stats, sizeof(struct pmu_pg_stats), 0); + + pg_stat_data->ingating_time = stats.pg_ingating_time_us; + pg_stat_data->ungating_time = stats.pg_ungating_time_us; + pg_stat_data->gating_cnt = stats.pg_gating_cnt; + pg_stat_data->avg_entry_latency_us = stats.pg_avg_entry_time_us; + pg_stat_data->avg_exit_latency_us = stats.pg_avg_exit_time_us; +} diff --git a/include/gk20a/pmu_gk20a.h b/include/gk20a/pmu_gk20a.h new file mode 100644 index 0000000..65ffd63 --- /dev/null +++ b/include/gk20a/pmu_gk20a.h @@ -0,0 +1,80 @@ +/* + * drivers/video/tegra/host/gk20a/pmu_gk20a.h + * + * GK20A PMU (aka. gPMU outside gk20a context) + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_GK20A_PMU_GK20A_H +#define NVGPU_GK20A_PMU_GK20A_H + +#include +#include +#include + +struct nvgpu_firmware; + +#define ZBC_MASK(i) (~(~(0) << ((i)+1)) & 0xfffe) + +bool gk20a_pmu_is_interrupted(struct nvgpu_pmu *pmu); +void gk20a_pmu_isr(struct gk20a *g); + +u32 gk20a_pmu_pg_engines_list(struct gk20a *g); +u32 gk20a_pmu_pg_feature_list(struct gk20a *g, u32 pg_engine_id); + +void gk20a_pmu_save_zbc(struct gk20a *g, u32 entries); + +void gk20a_pmu_init_perfmon_counter(struct gk20a *g); + +void gk20a_pmu_pg_idle_counter_config(struct gk20a *g, u32 pg_engine_id); + +int gk20a_pmu_mutex_acquire(struct nvgpu_pmu *pmu, u32 id, u32 *token); +int gk20a_pmu_mutex_release(struct nvgpu_pmu *pmu, u32 id, u32 *token); + +int gk20a_pmu_queue_head(struct gk20a *g, struct nvgpu_falcon_queue *queue, + u32 *head, bool set); +int gk20a_pmu_queue_tail(struct gk20a *g, struct nvgpu_falcon_queue *queue, + u32 *tail, bool set); +void gk20a_pmu_msgq_tail(struct nvgpu_pmu *pmu, u32 *tail, bool set); + +u32 gk20a_pmu_read_idle_counter(struct gk20a *g, u32 counter_id); +void gk20a_pmu_reset_idle_counter(struct gk20a *g, u32 counter_id); + +u32 gk20a_pmu_read_idle_intr_status(struct gk20a *g); +void gk20a_pmu_clear_idle_intr_status(struct gk20a *g); + +void gk20a_write_dmatrfbase(struct gk20a *g, u32 addr); +bool gk20a_is_pmu_supported(struct gk20a *g); + +int pmu_bootstrap(struct nvgpu_pmu *pmu); + +void gk20a_pmu_dump_elpg_stats(struct nvgpu_pmu *pmu); +void gk20a_pmu_dump_falcon_stats(struct nvgpu_pmu *pmu); + +void gk20a_pmu_enable_irq(struct nvgpu_pmu *pmu, bool enable); +void pmu_handle_fecs_boot_acr_msg(struct gk20a *g, struct pmu_msg *msg, + void *param, u32 handle, u32 status); +void gk20a_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id, + struct pmu_pg_stats_data *pg_stat_data); +bool gk20a_pmu_is_engine_in_reset(struct gk20a *g); +int gk20a_pmu_engine_reset(struct gk20a *g, bool do_reset); +u32 gk20a_pmu_get_irqdest(struct gk20a *g); +#endif /*NVGPU_GK20A_PMU_GK20A_H*/ diff --git a/include/gk20a/regops_gk20a.c b/include/gk20a/regops_gk20a.c new file mode 100644 index 0000000..0aec4f8 --- /dev/null +++ b/include/gk20a/regops_gk20a.c @@ -0,0 +1,472 @@ +/* + * Tegra GK20A GPU Debugger Driver Register Ops + * + * Copyright (c) 2013-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "gk20a.h" +#include "gr_gk20a.h" +#include "dbg_gpu_gk20a.h" +#include "regops_gk20a.h" + +#include +#include +#include +#include + +static int regop_bsearch_range_cmp(const void *pkey, const void *pelem) +{ + u32 key = *(u32 *)pkey; + struct regop_offset_range *prange = (struct regop_offset_range *)pelem; + if (key < prange->base) { + return -1; + } else if (prange->base <= key && key < (prange->base + + (prange->count * 4U))) { + return 0; + } + return 1; +} + +static inline bool linear_search(u32 offset, const u32 *list, int size) +{ + int i; + for (i = 0; i < size; i++) { + if (list[i] == offset) { + return true; + } + } + return false; +} + +/* + * In order to perform a context relative op the context has + * to be created already... which would imply that the + * context switch mechanism has already been put in place. + * So by the time we perform such an opertation it should always + * be possible to query for the appropriate context offsets, etc. + * + * But note: while the dbg_gpu bind requires the a channel fd, + * it doesn't require an allocated gr/compute obj at that point... + */ +static bool gr_context_info_available(struct gr_gk20a *gr) +{ + int err; + + nvgpu_mutex_acquire(&gr->ctx_mutex); + err = !gr->ctx_vars.golden_image_initialized; + nvgpu_mutex_release(&gr->ctx_mutex); + if (err) { + return false; + } + + return true; + +} + +static bool validate_reg_ops(struct dbg_session_gk20a *dbg_s, + u32 *ctx_rd_count, u32 *ctx_wr_count, + struct nvgpu_dbg_reg_op *ops, + u32 op_count); + + +int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_reg_op *ops, + u64 num_ops, + bool *is_current_ctx) +{ + int err = 0; + unsigned int i; + struct channel_gk20a *ch = NULL; + struct gk20a *g = dbg_s->g; + /*struct gr_gk20a *gr = &g->gr;*/ + u32 data32_lo = 0, data32_hi = 0; + u32 ctx_rd_count = 0, ctx_wr_count = 0; + bool skip_read_lo, skip_read_hi; + bool ok; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + + /* For vgpu, the regops routines need to be handled in the + * context of the server and support for that does not exist. + * + * The two users of the regops interface are the compute driver + * and tools. The compute driver will work without a functional + * regops implementation, so we return -ENOSYS. This will allow + * compute apps to run with vgpu. Tools will not work in this + * configuration and are not required to work at this time. */ + if (g->is_virtual) { + return -ENOSYS; + } + + ok = validate_reg_ops(dbg_s, + &ctx_rd_count, &ctx_wr_count, + ops, num_ops); + if (!ok) { + nvgpu_err(g, "invalid op(s)"); + err = -EINVAL; + /* each op has its own err/status */ + goto clean_up; + } + + /* be sure that ctx info is in place if there are ctx ops */ + if (ctx_wr_count | ctx_rd_count) { + if (!gr_context_info_available(&g->gr)) { + nvgpu_err(g, "gr context data not available"); + return -ENODEV; + } + } + + for (i = 0; i < num_ops; i++) { + /* if it isn't global then it is done in the ctx ops... */ + if (ops[i].type != REGOP(TYPE_GLOBAL)) { + continue; + } + + switch (ops[i].op) { + + case REGOP(READ_32): + ops[i].value_hi = 0; + ops[i].value_lo = gk20a_readl(g, ops[i].offset); + nvgpu_log(g, gpu_dbg_gpu_dbg, "read_32 0x%08x from 0x%08x", + ops[i].value_lo, ops[i].offset); + + break; + + case REGOP(READ_64): + ops[i].value_lo = gk20a_readl(g, ops[i].offset); + ops[i].value_hi = + gk20a_readl(g, ops[i].offset + 4); + + nvgpu_log(g, gpu_dbg_gpu_dbg, "read_64 0x%08x:%08x from 0x%08x", + ops[i].value_hi, ops[i].value_lo, + ops[i].offset); + break; + + case REGOP(WRITE_32): + case REGOP(WRITE_64): + /* some of this appears wonky/unnecessary but + we've kept it for compat with existing + debugger code. just in case... */ + skip_read_lo = skip_read_hi = false; + if (ops[i].and_n_mask_lo == ~(u32)0) { + data32_lo = ops[i].value_lo; + skip_read_lo = true; + } + + if ((ops[i].op == REGOP(WRITE_64)) && + (ops[i].and_n_mask_hi == ~(u32)0)) { + data32_hi = ops[i].value_hi; + skip_read_hi = true; + } + + /* read first 32bits */ + if (skip_read_lo == false) { + data32_lo = gk20a_readl(g, ops[i].offset); + data32_lo &= ~ops[i].and_n_mask_lo; + data32_lo |= ops[i].value_lo; + } + + /* if desired, read second 32bits */ + if ((ops[i].op == REGOP(WRITE_64)) && + !skip_read_hi) { + data32_hi = gk20a_readl(g, ops[i].offset + 4); + data32_hi &= ~ops[i].and_n_mask_hi; + data32_hi |= ops[i].value_hi; + } + + /* now update first 32bits */ + gk20a_writel(g, ops[i].offset, data32_lo); + nvgpu_log(g, gpu_dbg_gpu_dbg, "Wrote 0x%08x to 0x%08x ", + data32_lo, ops[i].offset); + /* if desired, update second 32bits */ + if (ops[i].op == REGOP(WRITE_64)) { + gk20a_writel(g, ops[i].offset + 4, data32_hi); + nvgpu_log(g, gpu_dbg_gpu_dbg, "Wrote 0x%08x to 0x%08x ", + data32_hi, ops[i].offset + 4); + + } + + + break; + + /* shouldn't happen as we've already screened */ + default: + BUG(); + err = -EINVAL; + goto clean_up; + break; + } + } + + if (ctx_wr_count | ctx_rd_count) { + err = gr_gk20a_exec_ctx_ops(ch, ops, num_ops, + ctx_wr_count, ctx_rd_count, + is_current_ctx); + if (err) { + nvgpu_warn(g, "failed to perform ctx ops\n"); + goto clean_up; + } + } + + clean_up: + nvgpu_log(g, gpu_dbg_gpu_dbg, "ret=%d", err); + return err; + +} + + +static int validate_reg_op_info(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_reg_op *op) +{ + int err = 0; + + op->status = REGOP(STATUS_SUCCESS); + + switch (op->op) { + case REGOP(READ_32): + case REGOP(READ_64): + case REGOP(WRITE_32): + case REGOP(WRITE_64): + break; + default: + op->status |= REGOP(STATUS_UNSUPPORTED_OP); + err = -EINVAL; + break; + } + + switch (op->type) { + case REGOP(TYPE_GLOBAL): + case REGOP(TYPE_GR_CTX): + case REGOP(TYPE_GR_CTX_TPC): + case REGOP(TYPE_GR_CTX_SM): + case REGOP(TYPE_GR_CTX_CROP): + case REGOP(TYPE_GR_CTX_ZROP): + case REGOP(TYPE_GR_CTX_QUAD): + break; + /* + case NVGPU_DBG_GPU_REG_OP_TYPE_FB: + */ + default: + op->status |= REGOP(STATUS_INVALID_TYPE); + err = -EINVAL; + break; + } + + return err; +} + +static bool check_whitelists(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_reg_op *op, u32 offset) +{ + struct gk20a *g = dbg_s->g; + bool valid = false; + struct channel_gk20a *ch; + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + + if (op->type == REGOP(TYPE_GLOBAL)) { + /* search global list */ + valid = g->ops.regops.get_global_whitelist_ranges && + !!bsearch(&offset, + g->ops.regops.get_global_whitelist_ranges(), + g->ops.regops.get_global_whitelist_ranges_count(), + sizeof(*g->ops.regops.get_global_whitelist_ranges()), + regop_bsearch_range_cmp); + + /* if debug session and channel is bound search context list */ + if ((!valid) && (!dbg_s->is_profiler && ch)) { + /* binary search context list */ + valid = g->ops.regops.get_context_whitelist_ranges && + !!bsearch(&offset, + g->ops.regops.get_context_whitelist_ranges(), + g->ops.regops.get_context_whitelist_ranges_count(), + sizeof(*g->ops.regops.get_context_whitelist_ranges()), + regop_bsearch_range_cmp); + } + + /* if debug session and channel is bound search runcontrol list */ + if ((!valid) && (!dbg_s->is_profiler && ch)) { + valid = g->ops.regops.get_runcontrol_whitelist && + linear_search(offset, + g->ops.regops.get_runcontrol_whitelist(), + g->ops.regops.get_runcontrol_whitelist_count()); + } + } else if (op->type == REGOP(TYPE_GR_CTX)) { + /* it's a context-relative op */ + if (!ch) { + nvgpu_err(dbg_s->g, "can't perform ctx regop unless bound"); + op->status = REGOP(STATUS_UNSUPPORTED_OP); + return valid; + } + + /* binary search context list */ + valid = g->ops.regops.get_context_whitelist_ranges && + !!bsearch(&offset, + g->ops.regops.get_context_whitelist_ranges(), + g->ops.regops.get_context_whitelist_ranges_count(), + sizeof(*g->ops.regops.get_context_whitelist_ranges()), + regop_bsearch_range_cmp); + + /* if debug session and channel is bound search runcontrol list */ + if ((!valid) && (!dbg_s->is_profiler && ch)) { + valid = g->ops.regops.get_runcontrol_whitelist && + linear_search(offset, + g->ops.regops.get_runcontrol_whitelist(), + g->ops.regops.get_runcontrol_whitelist_count()); + } + + } else if (op->type == REGOP(TYPE_GR_CTX_QUAD)) { + valid = g->ops.regops.get_qctl_whitelist && + linear_search(offset, + g->ops.regops.get_qctl_whitelist(), + g->ops.regops.get_qctl_whitelist_count()); + } + + return valid; +} + +/* note: the op here has already been through validate_reg_op_info */ +static int validate_reg_op_offset(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_reg_op *op) +{ + int err; + u32 buf_offset_lo, buf_offset_addr, num_offsets, offset; + bool valid = false; + + op->status = 0; + offset = op->offset; + + /* support only 24-bit 4-byte aligned offsets */ + if (offset & 0xFF000003) { + nvgpu_err(dbg_s->g, "invalid regop offset: 0x%x", offset); + op->status |= REGOP(STATUS_INVALID_OFFSET); + return -EINVAL; + } + + valid = check_whitelists(dbg_s, op, offset); + if ((op->op == REGOP(READ_64) || op->op == REGOP(WRITE_64)) && valid) { + valid = check_whitelists(dbg_s, op, offset + 4); + } + + if (valid && (op->type != REGOP(TYPE_GLOBAL))) { + err = gr_gk20a_get_ctx_buffer_offsets(dbg_s->g, + op->offset, + 1, + &buf_offset_lo, + &buf_offset_addr, + &num_offsets, + op->type == REGOP(TYPE_GR_CTX_QUAD), + op->quad); + if (err) { + err = gr_gk20a_get_pm_ctx_buffer_offsets(dbg_s->g, + op->offset, + 1, + &buf_offset_lo, + &buf_offset_addr, + &num_offsets); + + if (err) { + op->status |= REGOP(STATUS_INVALID_OFFSET); + return -EINVAL; + } + } + if (!num_offsets) { + op->status |= REGOP(STATUS_INVALID_OFFSET); + return -EINVAL; + } + } + + if (!valid) { + nvgpu_err(dbg_s->g, "invalid regop offset: 0x%x", offset); + op->status |= REGOP(STATUS_INVALID_OFFSET); + return -EINVAL; + } + + return 0; +} + +static bool validate_reg_ops(struct dbg_session_gk20a *dbg_s, + u32 *ctx_rd_count, u32 *ctx_wr_count, + struct nvgpu_dbg_reg_op *ops, + u32 op_count) +{ + u32 i; + bool ok = true; + struct gk20a *g = dbg_s->g; + + /* keep going until the end so every op can get + * a separate error code if needed */ + for (i = 0; i < op_count; i++) { + + if (validate_reg_op_info(dbg_s, &ops[i]) != 0) { + ok = false; + } + + if (reg_op_is_gr_ctx(ops[i].type)) { + if (reg_op_is_read(ops[i].op)) { + (*ctx_rd_count)++; + } else { + (*ctx_wr_count)++; + } + } + + /* if "allow_all" flag enabled, dont validate offset */ + if (!g->allow_all) { + if (validate_reg_op_offset(dbg_s, &ops[i]) != 0) { + ok = false; + } + } + } + + nvgpu_log(g, gpu_dbg_gpu_dbg, "ctx_wrs:%d ctx_rds:%d", + *ctx_wr_count, *ctx_rd_count); + + return ok; +} + +/* exported for tools like cyclestats, etc */ +bool is_bar0_global_offset_whitelisted_gk20a(struct gk20a *g, u32 offset) +{ + bool valid = !!bsearch(&offset, + g->ops.regops.get_global_whitelist_ranges(), + g->ops.regops.get_global_whitelist_ranges_count(), + sizeof(*g->ops.regops.get_global_whitelist_ranges()), + regop_bsearch_range_cmp); + return valid; +} + +bool reg_op_is_gr_ctx(u8 type) +{ + return type == REGOP(TYPE_GR_CTX) || + type == REGOP(TYPE_GR_CTX_TPC) || + type == REGOP(TYPE_GR_CTX_SM) || + type == REGOP(TYPE_GR_CTX_CROP) || + type == REGOP(TYPE_GR_CTX_ZROP) || + type == REGOP(TYPE_GR_CTX_QUAD); +} + +bool reg_op_is_read(u8 op) +{ + return op == REGOP(READ_32) || + op == REGOP(READ_64); +} diff --git a/include/gk20a/regops_gk20a.h b/include/gk20a/regops_gk20a.h new file mode 100644 index 0000000..9670587 --- /dev/null +++ b/include/gk20a/regops_gk20a.h @@ -0,0 +1,90 @@ +/* + * Tegra GK20A GPU Debugger Driver Register Ops + * + * Copyright (c) 2013-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef REGOPS_GK20A_H +#define REGOPS_GK20A_H + +/* + * Register operations + * All operations are targeted towards first channel + * attached to debug session + */ +/* valid op values */ +#define NVGPU_DBG_REG_OP_READ_32 (0x00000000) +#define NVGPU_DBG_REG_OP_WRITE_32 (0x00000001) +#define NVGPU_DBG_REG_OP_READ_64 (0x00000002) +#define NVGPU_DBG_REG_OP_WRITE_64 (0x00000003) +/* note: 8b ops are unsupported */ +#define NVGPU_DBG_REG_OP_READ_08 (0x00000004) +#define NVGPU_DBG_REG_OP_WRITE_08 (0x00000005) + +/* valid type values */ +#define NVGPU_DBG_REG_OP_TYPE_GLOBAL (0x00000000) +#define NVGPU_DBG_REG_OP_TYPE_GR_CTX (0x00000001) +#define NVGPU_DBG_REG_OP_TYPE_GR_CTX_TPC (0x00000002) +#define NVGPU_DBG_REG_OP_TYPE_GR_CTX_SM (0x00000004) +#define NVGPU_DBG_REG_OP_TYPE_GR_CTX_CROP (0x00000008) +#define NVGPU_DBG_REG_OP_TYPE_GR_CTX_ZROP (0x00000010) +/*#define NVGPU_DBG_REG_OP_TYPE_FB (0x00000020)*/ +#define NVGPU_DBG_REG_OP_TYPE_GR_CTX_QUAD (0x00000040) + +/* valid status values */ +#define NVGPU_DBG_REG_OP_STATUS_SUCCESS (0x00000000) +#define NVGPU_DBG_REG_OP_STATUS_INVALID_OP (0x00000001) +#define NVGPU_DBG_REG_OP_STATUS_INVALID_TYPE (0x00000002) +#define NVGPU_DBG_REG_OP_STATUS_INVALID_OFFSET (0x00000004) +#define NVGPU_DBG_REG_OP_STATUS_UNSUPPORTED_OP (0x00000008) +#define NVGPU_DBG_REG_OP_STATUS_INVALID_MASK (0x00000010) + +struct nvgpu_dbg_reg_op { + u8 op; + u8 type; + u8 status; + u8 quad; + u32 group_mask; + u32 sub_group_mask; + u32 offset; + u32 value_lo; + u32 value_hi; + u32 and_n_mask_lo; + u32 and_n_mask_hi; +}; + +struct regop_offset_range { + u32 base:24; + u32 count:8; +}; + +int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_reg_op *ops, + u64 num_ops, + bool *is_current_ctx); + +/* turn seriously unwieldy names -> something shorter */ +#define REGOP(x) NVGPU_DBG_REG_OP_##x + +bool reg_op_is_gr_ctx(u8 type); +bool reg_op_is_read(u8 op); +bool is_bar0_global_offset_whitelisted_gk20a(struct gk20a *g, u32 offset); + +#endif /* REGOPS_GK20A_H */ diff --git a/include/lpwr/lpwr.c b/include/lpwr/lpwr.c new file mode 100644 index 0000000..c8cfb84 --- /dev/null +++ b/include/lpwr/lpwr.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "gp106/bios_gp106.h" +#include "pstate/pstate.h" +#include "pmu_perf/pmu_perf.h" +#include "lpwr.h" + +static int get_lpwr_idx_table(struct gk20a *g) +{ + u32 *lpwr_idx_table_ptr; + u8 *entry_addr; + u32 idx; + struct nvgpu_lpwr_bios_idx_data *pidx_data = + &g->perf_pmu.lpwr.lwpr_bios_data.idx; + struct nvgpu_bios_lpwr_idx_table_1x_header header = { 0 }; + struct nvgpu_bios_lpwr_idx_table_1x_entry entry = { 0 }; + + lpwr_idx_table_ptr = (u32 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, LOWPOWER_TABLE); + if (lpwr_idx_table_ptr == NULL) { + return -EINVAL; + } + + memcpy(&header, lpwr_idx_table_ptr, + sizeof(struct nvgpu_bios_lpwr_idx_table_1x_header)); + + if (header.entry_count >= LPWR_VBIOS_IDX_ENTRY_COUNT_MAX) { + return -EINVAL; + } + + pidx_data->base_sampling_period = (u16)header.base_sampling_period; + + /* Parse the LPWR Index Table entries.*/ + for (idx = 0; idx < header.entry_count; idx++) { + entry_addr = (u8 *)lpwr_idx_table_ptr + header.header_size + + (idx * header.entry_size); + + memcpy(&entry, entry_addr, + sizeof(struct nvgpu_bios_lpwr_idx_table_1x_entry)); + + pidx_data->entry[idx].pcie_idx = entry.pcie_idx; + pidx_data->entry[idx].gr_idx = entry.gr_idx; + pidx_data->entry[idx].ms_idx = entry.ms_idx; + pidx_data->entry[idx].di_idx = entry.di_idx; + pidx_data->entry[idx].gc6_idx = entry.gc6_idx; + + } + + return 0; +} + +static int get_lpwr_gr_table(struct gk20a *g) +{ + u32 *lpwr_gr_table_ptr; + u8 *entry_addr; + u32 idx; + struct nvgpu_lpwr_bios_gr_data *pgr_data = + &g->perf_pmu.lpwr.lwpr_bios_data.gr; + struct nvgpu_bios_lpwr_gr_table_1x_header header = { 0 }; + struct nvgpu_bios_lpwr_gr_table_1x_entry entry = { 0 }; + + lpwr_gr_table_ptr = (u32 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, LOWPOWER_GR_TABLE); + if (lpwr_gr_table_ptr == NULL) { + return -EINVAL; + } + + memcpy(&header, lpwr_gr_table_ptr, + sizeof(struct nvgpu_bios_lpwr_gr_table_1x_header)); + + /* Parse the LPWR Index Table entries.*/ + for (idx = 0; idx < header.entry_count; idx++) { + entry_addr = (u8 *)lpwr_gr_table_ptr + header.header_size + + (idx * header.entry_size); + + memcpy(&entry, entry_addr, + sizeof(struct nvgpu_bios_lpwr_gr_table_1x_entry)); + + if (BIOS_GET_FIELD(entry.feautre_mask, + NV_VBIOS_LPWR_MS_FEATURE_MASK_MS)) { + pgr_data->entry[idx].gr_enabled = true; + + pgr_data->entry[idx].feature_mask = + NVGPU_PMU_GR_FEATURE_MASK_ALL; + + if (!BIOS_GET_FIELD(entry.feautre_mask, + NV_VBIOS_LPWR_GR_FEATURE_MASK_GR_RPPG)) { + pgr_data->entry[idx].feature_mask &= + ~NVGPU_PMU_GR_FEATURE_MASK_RPPG; + } + } + + } + + return 0; +} + +static int get_lpwr_ms_table(struct gk20a *g) +{ + u32 *lpwr_ms_table_ptr; + u8 *entry_addr; + u32 idx; + struct nvgpu_lpwr_bios_ms_data *pms_data = + &g->perf_pmu.lpwr.lwpr_bios_data.ms; + struct nvgpu_bios_lpwr_ms_table_1x_header header = { 0 }; + struct nvgpu_bios_lpwr_ms_table_1x_entry entry = { 0 }; + + lpwr_ms_table_ptr = (u32 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, LOWPOWER_MS_TABLE); + if (lpwr_ms_table_ptr == NULL) { + return -EINVAL; + } + + memcpy(&header, lpwr_ms_table_ptr, + sizeof(struct nvgpu_bios_lpwr_ms_table_1x_header)); + + if (header.entry_count >= LPWR_VBIOS_MS_ENTRY_COUNT_MAX) { + return -EINVAL; + } + + pms_data->default_entry_idx = (u8)header.default_entry_idx; + + pms_data->idle_threshold_us = (u32)(header.idle_threshold_us * 10); + + /* Parse the LPWR MS Table entries.*/ + for (idx = 0; idx < header.entry_count; idx++) { + entry_addr = (u8 *)lpwr_ms_table_ptr + header.header_size + + (idx * header.entry_size); + + memcpy(&entry, entry_addr, + sizeof(struct nvgpu_bios_lpwr_ms_table_1x_entry)); + + if (BIOS_GET_FIELD(entry.feautre_mask, + NV_VBIOS_LPWR_MS_FEATURE_MASK_MS)) { + pms_data->entry[idx].ms_enabled = true; + + pms_data->entry[idx].feature_mask = + NVGPU_PMU_MS_FEATURE_MASK_ALL; + + if (!BIOS_GET_FIELD(entry.feautre_mask, + NV_VBIOS_LPWR_MS_FEATURE_MASK_MS_CLOCK_GATING)) { + pms_data->entry[idx].feature_mask &= + ~NVGPU_PMU_MS_FEATURE_MASK_CLOCK_GATING; + } + + if (!BIOS_GET_FIELD(entry.feautre_mask, + NV_VBIOS_LPWR_MS_FEATURE_MASK_MS_SWASR)) { + pms_data->entry[idx].feature_mask &= + ~NVGPU_PMU_MS_FEATURE_MASK_SW_ASR; + } + + if (!BIOS_GET_FIELD(entry.feautre_mask, + NV_VBIOS_LPWR_MS_FEATURE_MASK_MS_RPPG)) { + pms_data->entry[idx].feature_mask &= + ~NVGPU_PMU_MS_FEATURE_MASK_RPPG; + } + } + + pms_data->entry[idx].dynamic_current_logic = + entry.dynamic_current_logic; + + pms_data->entry[idx].dynamic_current_sram = + entry.dynamic_current_sram; + } + + return 0; +} + +u32 nvgpu_lpwr_pg_setup(struct gk20a *g) +{ + u32 err = 0; + + nvgpu_log_fn(g, " "); + + err = get_lpwr_gr_table(g); + if (err) { + return err; + } + + err = get_lpwr_ms_table(g); + if (err) { + return err; + } + + err = get_lpwr_idx_table(g); + + return err; +} + +static void nvgpu_pmu_handle_param_lpwr_msg(struct gk20a *g, + struct pmu_msg *msg, void *param, + u32 handle, u32 status) +{ + u32 *ack_status = param; + + nvgpu_log_fn(g, " "); + + if (status != 0) { + nvgpu_err(g, "LWPR PARAM cmd aborted"); + return; + } + + *ack_status = 1; + + nvgpu_pmu_dbg(g, "lpwr-param is acknowledged from PMU %x", + msg->msg.pg.msg_type); +} + +int nvgpu_lwpr_mclk_change(struct gk20a *g, u32 pstate) +{ + struct pmu_cmd cmd; + u32 seq, status = 0; + u32 payload = NV_PMU_PG_PARAM_MCLK_CHANGE_MS_SWASR_ENABLED; + struct clk_set_info *pstate_info; + u32 ack_status = 0; + + nvgpu_log_fn(g, " "); + + pstate_info = pstate_get_clk_set_info(g, pstate, + clkwhich_mclk); + if (!pstate_info) { + return -EINVAL; + } + + if (pstate_info->max_mhz > + MAX_SWASR_MCLK_FREQ_WITHOUT_WR_TRAINING_MAXWELL_MHZ) { + payload |= + NV_PMU_PG_PARAM_MCLK_CHANGE_GDDR5_WR_TRAINING_ENABLED; + } + + if (payload != g->perf_pmu.lpwr.mclk_change_cache) { + g->perf_pmu.lpwr.mclk_change_cache = payload; + + cmd.hdr.unit_id = PMU_UNIT_PG; + cmd.hdr.size = PMU_CMD_HDR_SIZE + + sizeof(struct pmu_pg_cmd_mclk_change); + cmd.cmd.pg.mclk_change.cmd_type = + PMU_PG_CMD_ID_PG_PARAM; + cmd.cmd.pg.mclk_change.cmd_id = + PMU_PG_PARAM_CMD_MCLK_CHANGE; + cmd.cmd.pg.mclk_change.data = payload; + + nvgpu_pmu_dbg(g, "cmd post MS PMU_PG_PARAM_CMD_MCLK_CHANGE"); + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, + PMU_COMMAND_QUEUE_HPQ, + nvgpu_pmu_handle_param_lpwr_msg, &ack_status, &seq, ~0); + + pmu_wait_message_cond(&g->pmu, gk20a_get_gr_idle_timeout(g), + &ack_status, 1); + if (ack_status == 0) { + status = -EINVAL; + nvgpu_err(g, "MCLK-CHANGE ACK failed"); + } + } + + return status; +} + +u32 nvgpu_lpwr_post_init(struct gk20a *g) +{ + struct pmu_cmd cmd; + u32 seq; + u32 status = 0; + u32 ack_status = 0; + + memset(&cmd, 0, sizeof(struct pmu_cmd)); + cmd.hdr.unit_id = PMU_UNIT_PG; + cmd.hdr.size = PMU_CMD_HDR_SIZE + + sizeof(struct pmu_pg_cmd_post_init_param); + + cmd.cmd.pg.post_init.cmd_type = + PMU_PG_CMD_ID_PG_PARAM; + cmd.cmd.pg.post_init.cmd_id = + PMU_PG_PARAM_CMD_POST_INIT; + + nvgpu_pmu_dbg(g, "cmd post post-init PMU_PG_PARAM_CMD_POST_INIT"); + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, + PMU_COMMAND_QUEUE_LPQ, + nvgpu_pmu_handle_param_lpwr_msg, &ack_status, &seq, ~0); + + pmu_wait_message_cond(&g->pmu, gk20a_get_gr_idle_timeout(g), + &ack_status, 1); + if (ack_status == 0) { + status = -EINVAL; + nvgpu_err(g, "post-init ack failed"); + } + + return status; +} + +u32 nvgpu_lpwr_is_mscg_supported(struct gk20a *g, u32 pstate_num) +{ + struct nvgpu_lpwr_bios_ms_data *pms_data = + &g->perf_pmu.lpwr.lwpr_bios_data.ms; + struct nvgpu_lpwr_bios_idx_data *pidx_data = + &g->perf_pmu.lpwr.lwpr_bios_data.idx; + struct pstate *pstate = pstate_find(g, pstate_num); + u32 ms_idx; + + nvgpu_log_fn(g, " "); + + if (!pstate) { + return 0; + } + + ms_idx = pidx_data->entry[pstate->lpwr_entry_idx].ms_idx; + if (pms_data->entry[ms_idx].ms_enabled) { + return 1; + } else { + return 0; + } +} + +u32 nvgpu_lpwr_is_rppg_supported(struct gk20a *g, u32 pstate_num) +{ + struct nvgpu_lpwr_bios_gr_data *pgr_data = + &g->perf_pmu.lpwr.lwpr_bios_data.gr; + struct nvgpu_lpwr_bios_idx_data *pidx_data = + &g->perf_pmu.lpwr.lwpr_bios_data.idx; + struct pstate *pstate = pstate_find(g, pstate_num); + u32 idx; + + nvgpu_log_fn(g, " "); + + if (!pstate) { + return 0; + } + + idx = pidx_data->entry[pstate->lpwr_entry_idx].gr_idx; + if (pgr_data->entry[idx].gr_enabled) { + return 1; + } else { + return 0; + } +} + + +int nvgpu_lpwr_enable_pg(struct gk20a *g, bool pstate_lock) +{ + struct nvgpu_pmu *pmu = &g->pmu; + u32 status = 0; + u32 is_mscg_supported = 0; + u32 is_rppg_supported = 0; + u32 present_pstate = 0; + + nvgpu_log_fn(g, " "); + + if (pstate_lock) { + nvgpu_clk_arb_pstate_change_lock(g, true); + } + nvgpu_mutex_acquire(&pmu->pg_mutex); + + present_pstate = nvgpu_clk_arb_get_current_pstate(g); + + is_mscg_supported = nvgpu_lpwr_is_mscg_supported(g, + present_pstate); + if (is_mscg_supported && g->mscg_enabled) { + if (!pmu->mscg_stat) { + pmu->mscg_stat = PMU_MSCG_ENABLED; + } + } + + is_rppg_supported = nvgpu_lpwr_is_rppg_supported(g, + present_pstate); + if (is_rppg_supported) { + if (g->support_pmu && g->can_elpg) { + status = nvgpu_pmu_enable_elpg(g); + } + } + + nvgpu_mutex_release(&pmu->pg_mutex); + if (pstate_lock) { + nvgpu_clk_arb_pstate_change_lock(g, false); + } + + return status; +} + +int nvgpu_lpwr_disable_pg(struct gk20a *g, bool pstate_lock) +{ + struct nvgpu_pmu *pmu = &g->pmu; + int status = 0; + u32 is_mscg_supported = 0; + u32 is_rppg_supported = 0; + u32 present_pstate = 0; + + nvgpu_log_fn(g, " "); + + if (pstate_lock) { + nvgpu_clk_arb_pstate_change_lock(g, true); + } + nvgpu_mutex_acquire(&pmu->pg_mutex); + + present_pstate = nvgpu_clk_arb_get_current_pstate(g); + + is_rppg_supported = nvgpu_lpwr_is_rppg_supported(g, + present_pstate); + if (is_rppg_supported) { + if (g->support_pmu && g->elpg_enabled) { + status = nvgpu_pmu_disable_elpg(g); + if (status) { + goto exit_unlock; + } + } + } + + is_mscg_supported = nvgpu_lpwr_is_mscg_supported(g, + present_pstate); + if (is_mscg_supported && g->mscg_enabled) { + if (pmu->mscg_stat) { + pmu->mscg_stat = PMU_MSCG_DISABLED; + } + } + +exit_unlock: + nvgpu_mutex_release(&pmu->pg_mutex); + if (pstate_lock) { + nvgpu_clk_arb_pstate_change_lock(g, false); + } + + nvgpu_log_fn(g, "done"); + return status; +} diff --git a/include/lpwr/lpwr.h b/include/lpwr/lpwr.h new file mode 100644 index 0000000..c38ba62 --- /dev/null +++ b/include/lpwr/lpwr.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_LPWR_H +#define NVGPU_LPWR_H + +#define MAX_SWASR_MCLK_FREQ_WITHOUT_WR_TRAINING_MAXWELL_MHZ 540 + +#define NV_PMU_PG_PARAM_MCLK_CHANGE_MS_SWASR_ENABLED BIT(0x1) +#define NV_PMU_PG_PARAM_MCLK_CHANGE_GDDR5_WR_TRAINING_ENABLED BIT(0x3) + +#define LPWR_ENTRY_COUNT_MAX 0x06 + +#define LPWR_VBIOS_IDX_ENTRY_COUNT_MAX (LPWR_ENTRY_COUNT_MAX) + +#define LPWR_VBIOS_IDX_ENTRY_RSVD \ + (LPWR_VBIOS_IDX_ENTRY_COUNT_MAX - 1) + +#define LPWR_VBIOS_BASE_SAMPLING_PERIOD_DEFAULT (500) + +struct nvgpu_lpwr_bios_idx_entry { + u8 pcie_idx; + u8 gr_idx; + u8 ms_idx; + u8 di_idx; + u8 gc6_idx; +}; + +struct nvgpu_lpwr_bios_idx_data { + u16 base_sampling_period; + struct nvgpu_lpwr_bios_idx_entry entry[LPWR_VBIOS_IDX_ENTRY_COUNT_MAX]; +}; + +#define LPWR_VBIOS_MS_ENTRY_COUNT_MAX (LPWR_ENTRY_COUNT_MAX) + +struct nvgpu_lpwr_bios_ms_entry { + bool ms_enabled; + u32 feature_mask; + u32 asr_efficiency_thresholdl; + u16 dynamic_current_logic; + u16 dynamic_current_sram; +}; + +struct nvgpu_lpwr_bios_ms_data { + u8 default_entry_idx; + u32 idle_threshold_us; + struct nvgpu_lpwr_bios_ms_entry entry[LPWR_VBIOS_MS_ENTRY_COUNT_MAX]; +}; + +#define LPWR_VBIOS_GR_ENTRY_COUNT_MAX (LPWR_ENTRY_COUNT_MAX) + +struct nvgpu_lpwr_bios_gr_entry { + bool gr_enabled; + u32 feature_mask; +}; + +struct nvgpu_lpwr_bios_gr_data { + u8 default_entry_idx; + u32 idle_threshold_us; + u8 adaptive_gr_multiplier; + struct nvgpu_lpwr_bios_gr_entry entry[LPWR_VBIOS_GR_ENTRY_COUNT_MAX]; +}; + +struct nvgpu_lpwr_bios_data { + struct nvgpu_lpwr_bios_idx_data idx; + struct nvgpu_lpwr_bios_ms_data ms; + struct nvgpu_lpwr_bios_gr_data gr; +}; + +struct obj_lwpr { + struct nvgpu_lpwr_bios_data lwpr_bios_data; + u32 mclk_change_cache; +}; + +u32 nvgpu_lpwr_pg_setup(struct gk20a *g); +int nvgpu_lwpr_mclk_change(struct gk20a *g, u32 pstate); +int nvgpu_lpwr_enable_pg(struct gk20a *g, bool pstate_lock); +int nvgpu_lpwr_disable_pg(struct gk20a *g, bool pstate_lock); +u32 nvgpu_lpwr_is_mscg_supported(struct gk20a *g, u32 pstate_num); +u32 nvgpu_lpwr_is_rppg_supported(struct gk20a *g, u32 pstate_num); +u32 nvgpu_lpwr_post_init(struct gk20a *g); + +#endif /* NVGPU_LPWR_H */ diff --git a/include/lpwr/rppg.c b/include/lpwr/rppg.c new file mode 100644 index 0000000..13e8126 --- /dev/null +++ b/include/lpwr/rppg.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "gp106/bios_gp106.h" +#include "pstate/pstate.h" +#include "lpwr/rppg.h" + +static void pmu_handle_rppg_init_msg(struct gk20a *g, struct pmu_msg *msg, + void *param, u32 handle, u32 status) +{ + u32 *success = param; + + if (status == 0) { + switch (msg->msg.pg.rppg_msg.cmn.msg_id) { + case NV_PMU_RPPG_MSG_ID_INIT_CTRL_ACK: + *success = 1; + nvgpu_pmu_dbg(g, "RPPG is acknowledged from PMU %x", + msg->msg.pg.msg_type); + break; + } + } + + nvgpu_pmu_dbg(g, "RPPG is acknowledged from PMU %x", + msg->msg.pg.msg_type); +} + +static u32 rppg_send_cmd(struct gk20a *g, struct nv_pmu_rppg_cmd *prppg_cmd) +{ + struct pmu_cmd cmd; + u32 seq; + u32 status = 0; + u32 success = 0; + + memset(&cmd, 0, sizeof(struct pmu_cmd)); + cmd.hdr.unit_id = PMU_UNIT_PG; + cmd.hdr.size = PMU_CMD_HDR_SIZE + + sizeof(struct nv_pmu_rppg_cmd); + + cmd.cmd.pg.rppg_cmd.cmn.cmd_type = PMU_PMU_PG_CMD_ID_RPPG; + cmd.cmd.pg.rppg_cmd.cmn.cmd_id = prppg_cmd->cmn.cmd_id; + + switch (prppg_cmd->cmn.cmd_id) { + case NV_PMU_RPPG_CMD_ID_INIT: + break; + case NV_PMU_RPPG_CMD_ID_INIT_CTRL: + cmd.cmd.pg.rppg_cmd.init_ctrl.ctrl_id = + prppg_cmd->init_ctrl.ctrl_id; + cmd.cmd.pg.rppg_cmd.init_ctrl.domain_id = + prppg_cmd->init_ctrl.domain_id; + break; + case NV_PMU_RPPG_CMD_ID_STATS_RESET: + cmd.cmd.pg.rppg_cmd.stats_reset.ctrl_id = + prppg_cmd->stats_reset.ctrl_id; + break; + default: + nvgpu_err(g, "Inivalid RPPG command %d", + prppg_cmd->cmn.cmd_id); + return -1; + } + + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ, + pmu_handle_rppg_init_msg, &success, &seq, ~0); + if (status) { + nvgpu_err(g, "Unable to submit parameter command %d", + prppg_cmd->cmn.cmd_id); + goto exit; + } + + if (prppg_cmd->cmn.cmd_id == NV_PMU_RPPG_CMD_ID_INIT_CTRL) { + pmu_wait_message_cond(&g->pmu, gk20a_get_gr_idle_timeout(g), + &success, 1); + if (success == 0) { + status = -EINVAL; + nvgpu_err(g, "Ack for the parameter command %x", + prppg_cmd->cmn.cmd_id); + } + } + +exit: + return status; +} + +static u32 rppg_init(struct gk20a *g) +{ + struct nv_pmu_rppg_cmd rppg_cmd; + + rppg_cmd.init.cmd_id = NV_PMU_RPPG_CMD_ID_INIT; + + return rppg_send_cmd(g, &rppg_cmd); +} + +static u32 rppg_ctrl_init(struct gk20a *g, u8 ctrl_id) +{ + struct nv_pmu_rppg_cmd rppg_cmd; + + rppg_cmd.init_ctrl.cmd_id = NV_PMU_RPPG_CMD_ID_INIT_CTRL; + rppg_cmd.init_ctrl.ctrl_id = ctrl_id; + + switch (ctrl_id) { + case NV_PMU_RPPG_CTRL_ID_GR: + case NV_PMU_RPPG_CTRL_ID_MS: + rppg_cmd.init_ctrl.domain_id = NV_PMU_RPPG_DOMAIN_ID_GFX; + break; + } + + return rppg_send_cmd(g, &rppg_cmd); +} + +u32 init_rppg(struct gk20a *g) +{ + u32 status; + + status = rppg_init(g); + if (status != 0) { + nvgpu_err(g, + "Failed to initialize RPPG in PMU: 0x%08x", status); + return status; + } + + + status = rppg_ctrl_init(g, NV_PMU_RPPG_CTRL_ID_GR); + if (status != 0) { + nvgpu_err(g, + "Failed to initialize RPPG_CTRL: GR in PMU: 0x%08x", + status); + return status; + } + + status = rppg_ctrl_init(g, NV_PMU_RPPG_CTRL_ID_MS); + if (status != 0) { + nvgpu_err(g, + "Failed to initialize RPPG_CTRL: MS in PMU: 0x%08x", + status); + return status; + } + + return status; +} diff --git a/include/lpwr/rppg.h b/include/lpwr/rppg.h new file mode 100644 index 0000000..d66600a --- /dev/null +++ b/include/lpwr/rppg.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_LPWR_RPPG_H +#define NVGPU_LPWR_RPPG_H + +u32 init_rppg(struct gk20a *g); +#endif /* NVGPU_LPWR_RPPG_H */ diff --git a/include/nvgpu/acr/acr_flcnbl.h b/include/nvgpu/acr/acr_flcnbl.h new file mode 100644 index 0000000..ad697b2 --- /dev/null +++ b/include/nvgpu/acr/acr_flcnbl.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_ACR_FLCNBL_H +#define NVGPU_ACR_FLCNBL_H + +#include + +#ifndef NVGPU_ACR_H +#warning "acr_flcnbl.h not included from nvgpu_acr.h!" \ + "Include nvgpu_acr.h instead of acr_xxx.h to get access to ACR interfaces" +#endif + +/* + * Structure used by the boot-loader to load the rest of the code. This has + * to be filled by NVGPU and copied into DMEM at offset provided in the + * hsflcn_bl_desc.bl_desc_dmem_load_off. + */ +struct flcn_bl_dmem_desc { + u32 reserved[4]; /*Should be the first element..*/ + u32 signature[4]; /*Should be the first element..*/ + u32 ctx_dma; + u32 code_dma_base; + u32 non_sec_code_off; + u32 non_sec_code_size; + u32 sec_code_off; + u32 sec_code_size; + u32 code_entry_point; + u32 data_dma_base; + u32 data_size; + u32 code_dma_base1; + u32 data_dma_base1; +}; + +struct flcn_bl_dmem_desc_v1 { + u32 reserved[4]; /*Should be the first element..*/ + u32 signature[4]; /*Should be the first element..*/ + u32 ctx_dma; + struct falc_u64 code_dma_base; + u32 non_sec_code_off; + u32 non_sec_code_size; + u32 sec_code_off; + u32 sec_code_size; + u32 code_entry_point; + struct falc_u64 data_dma_base; + u32 data_size; + u32 argc; + u32 argv; +}; + +/* + * The header used by NVGPU to figure out code and data sections of bootloader + * + * bl_code_off - Offset of code section in the image + * bl_code_size - Size of code section in the image + * bl_data_off - Offset of data section in the image + * bl_data_size - Size of data section in the image + */ +struct flcn_bl_img_hdr { + u32 bl_code_off; + u32 bl_code_size; + u32 bl_data_off; + u32 bl_data_size; +}; + +/* + * The descriptor used by NVGPU to figure out the requirements of bootloader + * + * bl_start_tag - Starting tag of bootloader + * bl_desc_dmem_load_off - Dmem offset where _def_rm_flcn_bl_dmem_desc + * to be loaded + * bl_img_hdr - Description of the image + */ +struct hsflcn_bl_desc { + u32 bl_start_tag; + u32 bl_desc_dmem_load_off; + struct flcn_bl_img_hdr bl_img_hdr; +}; + +/* + * Legacy structure used by the current PMU/DPU bootloader. + */ +struct loader_config { + u32 dma_idx; + u32 code_dma_base; /* upper 32-bits of 40-bit dma address */ + u32 code_size_total; + u32 code_size_to_load; + u32 code_entry_point; + u32 data_dma_base; /* upper 32-bits of 40-bit dma address */ + u32 data_size; /* initialized data of the application */ + u32 overlay_dma_base; /* upper 32-bits of the 40-bit dma address */ + u32 argc; + u32 argv; + u16 code_dma_base1; /* upper 7 bits of 47-bit dma address */ + u16 data_dma_base1; /* upper 7 bits of 47-bit dma address */ + u16 overlay_dma_base1; /* upper 7 bits of the 47-bit dma address */ +}; + +struct loader_config_v1 { + u32 reserved; + u32 dma_idx; + struct falc_u64 code_dma_base; + u32 code_size_total; + u32 code_size_to_load; + u32 code_entry_point; + struct falc_u64 data_dma_base; + u32 data_size; + struct falc_u64 overlay_dma_base; + u32 argc; + u32 argv; +}; + +/* + * Union of all supported structures used by bootloaders. + */ +union flcn_bl_generic_desc { + struct flcn_bl_dmem_desc bl_dmem_desc; + struct loader_config loader_cfg; +}; + +union flcn_bl_generic_desc_v1 { + struct flcn_bl_dmem_desc_v1 bl_dmem_desc_v1; + struct loader_config_v1 loader_cfg_v1; +}; + +#endif /* NVGPU_ACR_FLCNBL_H */ diff --git a/include/nvgpu/acr/acr_lsfm.h b/include/nvgpu/acr/acr_lsfm.h new file mode 100644 index 0000000..ed58552 --- /dev/null +++ b/include/nvgpu/acr/acr_lsfm.h @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_ACR_LSFM_H +#define NVGPU_ACR_LSFM_H + +#ifndef NVGPU_ACR_H +#warning "acr_lsfm.h not included from nvgpu_acr.h!" \ + "Include nvgpu_acr.h instead of acr_xxx.h to get access to ACR interfaces" +#endif + +/* + * READ/WRITE masks for WPR region + */ +/* Readable only from level 2 and 3 client */ +#define LSF_WPR_REGION_RMASK (0xC) +/* Writable only from level 2 and 3 client */ +#define LSF_WPR_REGION_WMASK (0xC) +/* Readable only from level 3 client */ +#define LSF_WPR_REGION_RMASK_SUB_WPR_ENABLED (0x8) +/* Writable only from level 3 client */ +#define LSF_WPR_REGION_WMASK_SUB_WPR_ENABLED (0x8) +/* Disallow read mis-match for all clients */ +#define LSF_WPR_REGION_ALLOW_READ_MISMATCH_NO (0x0) +/* Disallow write mis-match for all clients */ +#define LSF_WPR_REGION_ALLOW_WRITE_MISMATCH_NO (0x0) + +/* + * Falcon Id Defines + * Defines a common Light Secure Falcon identifier. + */ +#define LSF_FALCON_ID_PMU (0) +#define LSF_FALCON_ID_GSPLITE (1) +#define LSF_FALCON_ID_FECS (2) +#define LSF_FALCON_ID_GPCCS (3) +#define LSF_FALCON_ID_SEC2 (7) +#define LSF_FALCON_ID_END (11) +#define LSF_FALCON_ID_INVALID (0xFFFFFFFF) + +/* + * Light Secure Falcon Ucode Description Defines + * This structure is prelim and may change as the ucode signing flow evolves. + */ +struct lsf_ucode_desc { + u8 prd_keys[2][16]; + u8 dbg_keys[2][16]; + u32 b_prd_present; + u32 b_dbg_present; + u32 falcon_id; +}; + +struct lsf_ucode_desc_v1 { + u8 prd_keys[2][16]; + u8 dbg_keys[2][16]; + u32 b_prd_present; + u32 b_dbg_present; + u32 falcon_id; + u32 bsupports_versioning; + u32 version; + u32 dep_map_count; + u8 dep_map[LSF_FALCON_ID_END * 2 * 4]; + u8 kdf[16]; +}; + +/* + * Light Secure WPR Header + * Defines state allowing Light Secure Falcon bootstrapping. + */ +struct lsf_wpr_header { + u32 falcon_id; + u32 lsb_offset; + u32 bootstrap_owner; + u32 lazy_bootstrap; + u32 status; +}; + +struct lsf_wpr_header_v1 { + u32 falcon_id; + u32 lsb_offset; + u32 bootstrap_owner; + u32 lazy_bootstrap; + u32 bin_version; + u32 status; +}; + + +/* + * LSF shared SubWpr Header + * + * use_case_id - Shared SubWpr use case ID (updated by nvgpu) + * start_addr - start address of subWpr (updated by nvgpu) + * size_4K - size of subWpr in 4K (updated by nvgpu) + */ +struct lsf_shared_sub_wpr_header { + u32 use_case_id; + u32 start_addr; + u32 size_4K; +}; + +/* shared sub_wpr use case IDs */ +enum { + LSF_SHARED_DATA_SUB_WPR_USE_CASE_ID_FRTS_VBIOS_TABLES = 1, + LSF_SHARED_DATA_SUB_WPR_USE_CASE_ID_PLAYREADY_SHARED_DATA = 2 +}; + +#define LSF_SHARED_DATA_SUB_WPR_USE_CASE_ID_MAX \ + LSF_SHARED_DATA_SUB_WPR_USE_CASE_ID_PLAYREADY_SHARED_DATA + +#define LSF_SHARED_DATA_SUB_WPR_USE_CASE_ID_INVALID (0xFFFFFFFF) + +#define MAX_SUPPORTED_SHARED_SUB_WPR_USE_CASES \ + LSF_SHARED_DATA_SUB_WPR_USE_CASE_ID_MAX + +/* Static sizes of shared subWPRs */ +/* Minimum granularity supported is 4K */ +/* 1MB in 4K */ +#define LSF_SHARED_DATA_SUB_WPR_FRTS_VBIOS_TABLES_SIZE_IN_4K (0x100) +/* 4K */ +#define LSF_SHARED_DATA_SUB_WPR_PLAYREADY_SHARED_DATA_SIZE_IN_4K (0x1) + +/* + * Bootstrap Owner Defines + */ +#define LSF_BOOTSTRAP_OWNER_DEFAULT (LSF_FALCON_ID_PMU) + +/* + * Image Status Defines + */ +#define LSF_IMAGE_STATUS_NONE (0) +#define LSF_IMAGE_STATUS_COPY (1) +#define LSF_IMAGE_STATUS_VALIDATION_CODE_FAILED (2) +#define LSF_IMAGE_STATUS_VALIDATION_DATA_FAILED (3) +#define LSF_IMAGE_STATUS_VALIDATION_DONE (4) +#define LSF_IMAGE_STATUS_VALIDATION_SKIPPED (5) +#define LSF_IMAGE_STATUS_BOOTSTRAP_READY (6) + +/*Light Secure Bootstrap header related defines*/ +#define NV_FLCN_ACR_LSF_FLAG_LOAD_CODE_AT_0_FALSE 0 +#define NV_FLCN_ACR_LSF_FLAG_LOAD_CODE_AT_0_TRUE 1 +#define NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_FALSE 0 +#define NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_TRUE 4 +#define NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_TRUE 8 +#define NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_FALSE 0 + +/* + * Light Secure Bootstrap Header + * Defines state allowing Light Secure Falcon bootstrapping. + */ +struct lsf_lsb_header { + struct lsf_ucode_desc signature; + u32 ucode_off; + u32 ucode_size; + u32 data_size; + u32 bl_code_size; + u32 bl_imem_off; + u32 bl_data_off; + u32 bl_data_size; + u32 app_code_off; + u32 app_code_size; + u32 app_data_off; + u32 app_data_size; + u32 flags; +}; + +struct lsf_lsb_header_v1 { + struct lsf_ucode_desc_v1 signature; + u32 ucode_off; + u32 ucode_size; + u32 data_size; + u32 bl_code_size; + u32 bl_imem_off; + u32 bl_data_off; + u32 bl_data_size; + u32 app_code_off; + u32 app_code_size; + u32 app_data_off; + u32 app_data_size; + u32 flags; +}; + +/* + * Light Secure WPR Content Alignments + */ +#define LSF_WPR_HEADER_ALIGNMENT (256U) +#define LSF_SUB_WPR_HEADER_ALIGNMENT (256U) +#define LSF_LSB_HEADER_ALIGNMENT (256U) +#define LSF_BL_DATA_ALIGNMENT (256U) +#define LSF_BL_DATA_SIZE_ALIGNMENT (256U) +#define LSF_BL_CODE_SIZE_ALIGNMENT (256U) +#define LSF_DATA_SIZE_ALIGNMENT (256U) +#define LSF_CODE_SIZE_ALIGNMENT (256U) + +/* MMU excepts sub_wpr sizes in units of 4K */ +#define SUB_WPR_SIZE_ALIGNMENT (4096U) + +/* + * Maximum WPR Header size + */ +#define LSF_WPR_HEADERS_TOTAL_SIZE_MAX \ + (ALIGN_UP((sizeof(struct lsf_wpr_header_v1) * LSF_FALCON_ID_END), \ + LSF_WPR_HEADER_ALIGNMENT)) +#define LSF_LSB_HEADER_TOTAL_SIZE_MAX (\ + ALIGN_UP(sizeof(struct lsf_lsb_header_v1), LSF_LSB_HEADER_ALIGNMENT)) + +/* Maximum SUB WPR header size */ +#define LSF_SUB_WPR_HEADERS_TOTAL_SIZE_MAX (ALIGN_UP( \ + (sizeof(struct lsf_shared_sub_wpr_header) * \ + LSF_SHARED_DATA_SUB_WPR_USE_CASE_ID_MAX), \ + LSF_SUB_WPR_HEADER_ALIGNMENT)) + + +#define LSF_UCODE_DATA_ALIGNMENT 4096 + +/* Defined for 1MB alignment */ +#define SHIFT_1MB (20) +#define SHIFT_4KB (12) + +/* + * Supporting maximum of 2 regions. + * This is needed to pre-allocate space in DMEM + */ +#define NVGPU_FLCN_ACR_MAX_REGIONS (2) +#define LSF_BOOTSTRAP_OWNER_RESERVED_DMEM_SIZE (0x200) + +/* + * start_addr - Starting address of region + * end_addr - Ending address of region + * region_id - Region ID + * read_mask - Read Mask + * write_mask - WriteMask + * client_mask - Bit map of all clients currently using this region + */ +struct flcn_acr_region_prop { + u32 start_addr; + u32 end_addr; + u32 region_id; + u32 read_mask; + u32 write_mask; + u32 client_mask; +}; + +struct flcn_acr_region_prop_v1 { + u32 start_addr; + u32 end_addr; + u32 region_id; + u32 read_mask; + u32 write_mask; + u32 client_mask; + u32 shadowmMem_startaddress; +}; + +/* + * no_regions - Number of regions used. + * region_props - Region properties + */ +struct flcn_acr_regions { + u32 no_regions; + struct flcn_acr_region_prop region_props[NVGPU_FLCN_ACR_MAX_REGIONS]; +}; + +struct flcn_acr_regions_v1 { + u32 no_regions; + struct flcn_acr_region_prop_v1 region_props[NVGPU_FLCN_ACR_MAX_REGIONS]; +}; +/* + * reserved_dmem-When the bootstrap owner has done bootstrapping other falcons, + * and need to switch into LS mode, it needs to have its own + * actual DMEM image copied into DMEM as part of LS setup. If + * ACR desc is at location 0, it will definitely get overwritten + * causing data corruption. Hence we are reserving 0x200 bytes + * to give room for any loading data. NOTE: This has to be the + * first member always + * signature - Signature of ACR ucode. + * wpr_region_id - Region ID holding the WPR header and its details + * wpr_offset - Offset from the WPR region holding the wpr header + * regions - Region descriptors + * nonwpr_ucode_blob_start -stores non-WPR start where kernel stores ucode blob + * nonwpr_ucode_blob_end -stores non-WPR end where kernel stores ucode blob + */ +struct flcn_acr_desc { + union { + u32 reserved_dmem[(LSF_BOOTSTRAP_OWNER_RESERVED_DMEM_SIZE/4)]; + u32 signatures[4]; + } ucode_reserved_space; + /*Always 1st*/ + u32 wpr_region_id; + u32 wpr_offset; + u32 mmu_mem_range; + struct flcn_acr_regions regions; + u32 nonwpr_ucode_blob_size; + u64 nonwpr_ucode_blob_start; +}; + +struct flcn_acr_desc_v1 { + union { + u32 reserved_dmem[(LSF_BOOTSTRAP_OWNER_RESERVED_DMEM_SIZE/4)]; + } ucode_reserved_space; + u32 signatures[4]; + /*Always 1st*/ + u32 wpr_region_id; + u32 wpr_offset; + u32 mmu_mem_range; + struct flcn_acr_regions_v1 regions; + u32 nonwpr_ucode_blob_size; + u64 nonwpr_ucode_blob_start; + u32 dummy[4]; /* ACR_BSI_VPR_DESC */ +}; + + +#endif /* NVGPU_ACR_LSFM_H */ diff --git a/include/nvgpu/acr/acr_objflcn.h b/include/nvgpu/acr/acr_objflcn.h new file mode 100644 index 0000000..57b43c8 --- /dev/null +++ b/include/nvgpu/acr/acr_objflcn.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_ACR_OBJFLCN_H +#define NVGPU_ACR_OBJFLCN_H + +#ifndef NVGPU_ACR_H +#warning "acr_objflcn.h not included from nvgpu_acr.h!" \ + "Include nvgpu_acr.h instead of acr_xxx.h to get access to ACR interfaces" +#endif + +struct flcn_ucode_img { + u32 *header; /* only some falcons have header */ + u32 *data; + struct pmu_ucode_desc *desc; /* only some falcons have descriptor */ + u32 data_size; + void *fw_ver; /* CTRL_GPU_GET_FIRMWARE_VERSION_PARAMS struct */ + u8 load_entire_os_data; /* load the whole osData section at boot time.*/ + /* NULL if not a light secure falcon.*/ + struct lsf_ucode_desc *lsf_desc; + /* True if there a resources to freed by the client. */ + u8 free_res_allocs; + u32 flcn_inst; +}; + +struct flcn_ucode_img_v1 { + u32 *header; + u32 *data; + struct pmu_ucode_desc_v1 *desc; + u32 data_size; + void *fw_ver; + u8 load_entire_os_data; + struct lsf_ucode_desc_v1 *lsf_desc; + u8 free_res_allocs; + u32 flcn_inst; +}; + +/* + * Falcon UCODE header index. + */ +#define FLCN_NL_UCODE_HDR_OS_CODE_OFF_IND (0) +#define FLCN_NL_UCODE_HDR_OS_CODE_SIZE_IND (1) +#define FLCN_NL_UCODE_HDR_OS_DATA_OFF_IND (2) +#define FLCN_NL_UCODE_HDR_OS_DATA_SIZE_IND (3) +#define FLCN_NL_UCODE_HDR_NUM_APPS_IND (4) + +/* + * There are total N number of Apps with code and offset defined in UCODE header + * This macro provides the CODE and DATA offset and size of Ath application. + */ +#define FLCN_NL_UCODE_HDR_APP_CODE_START_IND (5) +#define FLCN_NL_UCODE_HDR_APP_CODE_OFF_IND(N, A) \ + (FLCN_NL_UCODE_HDR_APP_CODE_START_IND + (A*2)) +#define FLCN_NL_UCODE_HDR_APP_CODE_SIZE_IND(N, A) \ + (FLCN_NL_UCODE_HDR_APP_CODE_START_IND + (A*2) + 1) +#define FLCN_NL_UCODE_HDR_APP_CODE_END_IND(N) \ + (FLCN_NL_UCODE_HDR_APP_CODE_START_IND + (N*2) - 1) + +#define FLCN_NL_UCODE_HDR_APP_DATA_START_IND(N) \ + (FLCN_NL_UCODE_HDR_APP_CODE_END_IND(N) + 1) +#define FLCN_NL_UCODE_HDR_APP_DATA_OFF_IND(N, A) \ + (FLCN_NL_UCODE_HDR_APP_DATA_START_IND(N) + (A*2)) +#define FLCN_NL_UCODE_HDR_APP_DATA_SIZE_IND(N, A) \ + (FLCN_NL_UCODE_HDR_APP_DATA_START_IND(N) + (A*2) + 1) +#define FLCN_NL_UCODE_HDR_APP_DATA_END_IND(N) \ + (FLCN_NL_UCODE_HDR_APP_DATA_START_IND(N) + (N*2) - 1) + +#define FLCN_NL_UCODE_HDR_OS_OVL_OFF_IND(N) \ + (FLCN_NL_UCODE_HDR_APP_DATA_END_IND(N) + 1) +#define FLCN_NL_UCODE_HDR_OS_OVL_SIZE_IND(N) \ + (FLCN_NL_UCODE_HDR_APP_DATA_END_IND(N) + 2) + +#endif /* NVGPU_ACR_OBJFLCN_H */ diff --git a/include/nvgpu/acr/acr_objlsfm.h b/include/nvgpu/acr/acr_objlsfm.h new file mode 100644 index 0000000..e3769bb --- /dev/null +++ b/include/nvgpu/acr/acr_objlsfm.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_ACR_OBJLSFM_H +#define NVGPU_ACR_OBJLSFM_H + +#ifndef NVGPU_ACR_H +#warning "acr_objlsfm.h not included from nvgpu_acr.h!" \ + "Include nvgpu_acr.h instead of acr_xxx.h to get access to ACR interfaces" +#endif + +#include "acr_flcnbl.h" +#include "acr_objflcn.h" + +/* + * LSFM Managed Ucode Image + * next : Next image the list, NULL if last. + * wpr_header : WPR header for this ucode image + * lsb_header : LSB header for this ucode image + * bl_gen_desc : Bootloader generic desc structure for this ucode image + * bl_gen_desc_size : Sizeof bootloader desc structure for this ucode image + * full_ucode_size : Surface size required for final ucode image + * ucode_img : Ucode image info + */ +struct lsfm_managed_ucode_img { + struct lsfm_managed_ucode_img *next; + struct lsf_wpr_header wpr_header; + struct lsf_lsb_header lsb_header; + union flcn_bl_generic_desc bl_gen_desc; + u32 bl_gen_desc_size; + u32 full_ucode_size; + struct flcn_ucode_img ucode_img; +}; + +struct lsfm_managed_ucode_img_v2 { + struct lsfm_managed_ucode_img_v2 *next; + struct lsf_wpr_header_v1 wpr_header; + struct lsf_lsb_header_v1 lsb_header; + union flcn_bl_generic_desc_v1 bl_gen_desc; + u32 bl_gen_desc_size; + u32 full_ucode_size; + struct flcn_ucode_img_v1 ucode_img; +}; + +/* + * Defines the structure used to contain all generic information related to + * the LSFM. + * Contains the Light Secure Falcon Manager (LSFM) feature related data. + */ +struct ls_flcn_mgr { + u16 managed_flcn_cnt; + u32 wpr_size; + u32 disable_mask; + struct lsfm_managed_ucode_img *ucode_img_list; + void *wpr_client_req_state;/*PACR_CLIENT_REQUEST_STATE originally*/ +}; + +/* + * LSFM SUB WPRs struct + * pnext : Next entry in the list, NULL if last + * sub_wpr_header : SubWpr Header struct + */ +struct lsfm_sub_wpr { + struct lsfm_sub_wpr *pnext; + struct lsf_shared_sub_wpr_header sub_wpr_header; +}; + +struct ls_flcn_mgr_v1 { + u16 managed_flcn_cnt; + u32 wpr_size; + u32 disable_mask; + struct lsfm_managed_ucode_img_v2 *ucode_img_list; + void *wpr_client_req_state;/*PACR_CLIENT_REQUEST_STATE originally*/ + u16 managed_sub_wpr_count; + struct lsfm_sub_wpr *psub_wpr_list; +}; + + +#endif /* NVGPU_ACR_OBJLSFM_H */ diff --git a/include/nvgpu/acr/nvgpu_acr.h b/include/nvgpu/acr/nvgpu_acr.h new file mode 100644 index 0000000..7a0143e --- /dev/null +++ b/include/nvgpu/acr/nvgpu_acr.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_ACR_H +#define NVGPU_ACR_H + +#include + +#include "gk20a/mm_gk20a.h" + +#include "acr_lsfm.h" +#include "acr_flcnbl.h" +#include "acr_objlsfm.h" +#include "acr_objflcn.h" + +struct nvgpu_firmware; +struct gk20a; +struct hs_acr_ops; +struct hs_acr; +struct nvgpu_acr; + +#define HSBIN_ACR_BL_UCODE_IMAGE "pmu_bl.bin" +#define HSBIN_ACR_UCODE_IMAGE "acr_ucode.bin" +#define HSBIN_ACR_AHESASC_PROD_UCODE "acr_ahesasc_prod_ucode.bin" +#define HSBIN_ACR_ASB_PROD_UCODE "acr_asb_prod_ucode.bin" +#define HSBIN_ACR_AHESASC_DBG_UCODE "acr_ahesasc_dbg_ucode.bin" +#define HSBIN_ACR_ASB_DBG_UCODE "acr_asb_dbg_ucode.bin" + +#define LSF_SEC2_UCODE_IMAGE_BIN "sec2_ucode_image.bin" +#define LSF_SEC2_UCODE_DESC_BIN "sec2_ucode_desc.bin" +#define LSF_SEC2_UCODE_SIG_BIN "sec2_sig.bin" + +#define MAX_SUPPORTED_LSFM 3 /*PMU, FECS, GPCCS*/ + +#define ACR_COMPLETION_TIMEOUT_MS 10000 /*in msec */ + +#define PMU_SECURE_MODE (0x1) +#define PMU_LSFM_MANAGED (0x2) + +struct bin_hdr { + /* 0x10de */ + u32 bin_magic; + /* versioning of bin format */ + u32 bin_ver; + /* Entire image size including this header */ + u32 bin_size; + /* + * Header offset of executable binary metadata, + * start @ offset- 0x100 * + */ + u32 header_offset; + /* + * Start of executable binary data, start @ + * offset- 0x200 + */ + u32 data_offset; + /* Size of executable binary */ + u32 data_size; +}; + +struct acr_fw_header { + u32 sig_dbg_offset; + u32 sig_dbg_size; + u32 sig_prod_offset; + u32 sig_prod_size; + u32 patch_loc; + u32 patch_sig; + u32 hdr_offset; /* This header points to acr_ucode_header_t210_load */ + u32 hdr_size; /* Size of above header */ +}; + +struct wpr_carveout_info { + u64 wpr_base; + u64 nonwpr_base; + u64 size; +}; + +/* ACR interfaces */ + +struct hs_flcn_bl { + char *bl_fw_name; + struct nvgpu_firmware *hs_bl_fw; + struct hsflcn_bl_desc *hs_bl_desc; + struct bin_hdr *hs_bl_bin_hdr; + struct nvgpu_mem hs_bl_ucode; +}; + +struct hs_acr { + u32 acr_type; + + /* HS bootloader to validate & load ACR ucode */ + struct hs_flcn_bl acr_hs_bl; + + /* ACR ucode */ + char *acr_fw_name; + struct nvgpu_firmware *acr_fw; + struct nvgpu_mem acr_ucode; + + union { + struct flcn_bl_dmem_desc bl_dmem_desc; + struct flcn_bl_dmem_desc_v1 bl_dmem_desc_v1; + }; + + void *ptr_bl_dmem_desc; + u32 bl_dmem_desc_size; + + union{ + struct flcn_acr_desc *acr_dmem_desc; + struct flcn_acr_desc_v1 *acr_dmem_desc_v1; + }; + + /* Falcon used to execute ACR ucode */ + struct nvgpu_falcon *acr_flcn; + + int (*acr_flcn_setup_hw_and_bl_bootstrap)(struct gk20a *g, + struct hs_acr *acr_desc, + struct nvgpu_falcon_bl_info *bl_info); +}; + +#define ACR_DEFAULT 0U +#define ACR_AHESASC 1U +#define ACR_ASB 2U + +struct nvgpu_acr { + struct gk20a *g; + + u32 bootstrap_owner; + u32 max_supported_lsfm; + u32 capabilities; + + /* + * non-wpr space to hold LSF ucodes, + * ACR does copy ucode from non-wpr to wpr + */ + struct nvgpu_mem ucode_blob; + /* + * Even though this mem_desc wouldn't be used, + * the wpr region needs to be reserved in the + * allocator in dGPU case. + */ + struct nvgpu_mem wpr_dummy; + + /* ACR member for different types of ucode */ + /* For older dgpu/tegra ACR cuode */ + struct hs_acr acr; + /* ACR load split feature support */ + struct hs_acr acr_ahesasc; + struct hs_acr acr_asb; + + u32 pmu_args; + struct nvgpu_firmware *pmu_fw; + struct nvgpu_firmware *pmu_desc; + + int (*prepare_ucode_blob)(struct gk20a *g, struct nvgpu_acr *acr); + void (*get_wpr_info)(struct gk20a *g, struct wpr_carveout_info *inf); + int (*alloc_blob_space)(struct gk20a *g, size_t size, + struct nvgpu_mem *mem); + int (*patch_wpr_info_to_ucode)(struct gk20a *g, struct nvgpu_acr *acr, + struct hs_acr *acr_desc, bool is_recovery); + int (*acr_fill_bl_dmem_desc)(struct gk20a *g, + struct nvgpu_acr *acr, struct hs_acr *acr_desc, + u32 *acr_ucode_header); + int (*bootstrap_hs_acr)(struct gk20a *g, struct nvgpu_acr *acr, + struct hs_acr *acr_desc); + + void (*remove_support)(struct nvgpu_acr *acr); +}; +#endif /* NVGPU_ACR_H */ + diff --git a/include/nvgpu/allocator.h b/include/nvgpu/allocator.h new file mode 100644 index 0000000..c444543 --- /dev/null +++ b/include/nvgpu/allocator.h @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_ALLOCATOR_H +#define NVGPU_ALLOCATOR_H + +#ifdef __KERNEL__ +/* + * The Linux kernel has this notion of seq_files for printing info to userspace. + * One of the allocator function pointers takes advantage of this and allows the + * debug output to be directed either to nvgpu_log() or a seq_file. + */ +#include +#endif + +#include +#include +#include +#include + +/* #define ALLOCATOR_DEBUG_FINE */ + +struct nvgpu_allocator; +struct nvgpu_alloc_carveout; +struct vm_gk20a; +struct gk20a; + +/* + * Operations for an allocator to implement. + */ +struct nvgpu_allocator_ops { + u64 (*alloc)(struct nvgpu_allocator *allocator, u64 len); + u64 (*alloc_pte)(struct nvgpu_allocator *allocator, u64 len, + u32 page_size); + void (*free)(struct nvgpu_allocator *allocator, u64 addr); + + /* + * Special interface to allocate a memory region with a specific + * starting address. Yikes. Note: if free() works for freeing both + * regular and fixed allocations then free_fixed() does not need to + * be implemented. This behavior exists for legacy reasons and should + * not be propagated to new allocators. + * + * For allocators where the @page_size field is not applicable it can + * be left as 0. Otherwise a valid page size should be passed (4k or + * what the large page size is). + */ + u64 (*alloc_fixed)(struct nvgpu_allocator *allocator, + u64 base, u64 len, u32 page_size); + void (*free_fixed)(struct nvgpu_allocator *allocator, + u64 base, u64 len); + + /* + * Allow allocators to reserve space for carveouts. + */ + int (*reserve_carveout)(struct nvgpu_allocator *allocator, + struct nvgpu_alloc_carveout *co); + void (*release_carveout)(struct nvgpu_allocator *allocator, + struct nvgpu_alloc_carveout *co); + + /* + * Returns info about the allocator. + */ + u64 (*base)(struct nvgpu_allocator *allocator); + u64 (*length)(struct nvgpu_allocator *allocator); + u64 (*end)(struct nvgpu_allocator *allocator); + bool (*inited)(struct nvgpu_allocator *allocator); + u64 (*space)(struct nvgpu_allocator *allocator); + + /* Destructor. */ + void (*fini)(struct nvgpu_allocator *allocator); + +#ifdef __KERNEL__ + /* Debugging. */ + void (*print_stats)(struct nvgpu_allocator *allocator, + struct seq_file *s, int lock); +#endif +}; + +struct nvgpu_allocator { + struct gk20a *g; + + char name[32]; + struct nvgpu_mutex lock; + + void *priv; + const struct nvgpu_allocator_ops *ops; + + struct dentry *debugfs_entry; + bool debug; /* Control for debug msgs. */ +}; + +struct nvgpu_alloc_carveout { + const char *name; + u64 base; + u64 length; + + struct nvgpu_allocator *allocator; + + /* + * For usage by the allocator implementation. + */ + struct nvgpu_list_node co_entry; +}; + +static inline struct nvgpu_alloc_carveout * +nvgpu_alloc_carveout_from_co_entry(struct nvgpu_list_node *node) +{ + return (struct nvgpu_alloc_carveout *) + ((uintptr_t)node - offsetof(struct nvgpu_alloc_carveout, co_entry)); +}; + +#define NVGPU_CARVEOUT(local_name, local_base, local_length) \ + { \ + .name = (local_name), \ + .base = (local_base), \ + .length = (local_length) \ + } + +/* + * These are the available allocator flags. + * + * GPU_ALLOC_GVA_SPACE + * + * This flag makes sense for the buddy allocator only. It specifies that the + * allocator will be used for managing a GVA space. When managing GVA spaces + * special care has to be taken to ensure that allocations of similar PTE + * sizes are placed in the same PDE block. This allows the higher level + * code to skip defining both small and large PTE tables for every PDE. That + * can save considerable memory for address spaces that have a lot of + * allocations. + * + * GPU_ALLOC_NO_ALLOC_PAGE + * + * For any allocator that needs to manage a resource in a latency critical + * path this flag specifies that the allocator should not use any kmalloc() + * or similar functions during normal operation. Initialization routines + * may still use kmalloc(). This prevents the possibility of long waits for + * pages when using alloc_page(). Currently only the bitmap allocator + * implements this functionality. + * + * Also note that if you accept this flag then you must also define the + * free_fixed() function. Since no meta-data is allocated to help free + * allocations you need to keep track of the meta-data yourself (in this + * case the base and length of the allocation as opposed to just the base + * of the allocation). + * + * GPU_ALLOC_4K_VIDMEM_PAGES + * + * We manage vidmem pages at a large page granularity for performance + * reasons; however, this can lead to wasting memory. For page allocators + * setting this flag will tell the allocator to manage pools of 4K pages + * inside internally allocated large pages. + * + * Currently this flag is ignored since the only usage of the page allocator + * uses a 4K block size already. However, this flag has been reserved since + * it will be necessary in the future. + * + * GPU_ALLOC_FORCE_CONTIG + * + * Force allocations to be contiguous. Currently only relevant for page + * allocators since all other allocators are naturally contiguous. + * + * GPU_ALLOC_NO_SCATTER_GATHER + * + * The page allocator normally returns a scatter gather data structure for + * allocations (to handle discontiguous pages). However, at times that can + * be annoying so this flag forces the page allocator to return a u64 + * pointing to the allocation base (requires GPU_ALLOC_FORCE_CONTIG to be + * set as well). + */ +#define GPU_ALLOC_GVA_SPACE BIT64(0) +#define GPU_ALLOC_NO_ALLOC_PAGE BIT64(1) +#define GPU_ALLOC_4K_VIDMEM_PAGES BIT64(2) +#define GPU_ALLOC_FORCE_CONTIG BIT64(3) +#define GPU_ALLOC_NO_SCATTER_GATHER BIT64(4) + +static inline void alloc_lock(struct nvgpu_allocator *a) +{ + nvgpu_mutex_acquire(&a->lock); +} + +static inline void alloc_unlock(struct nvgpu_allocator *a) +{ + nvgpu_mutex_release(&a->lock); +} + +/* + * Buddy allocator specific initializers. + */ +int nvgpu_buddy_allocator_init(struct gk20a *g, struct nvgpu_allocator *na, + struct vm_gk20a *vm, const char *name, + u64 base, u64 size, u64 blk_size, + u64 max_order, u64 flags); + +/* + * Bitmap initializers. + */ +int nvgpu_bitmap_allocator_init(struct gk20a *g, struct nvgpu_allocator *na, + const char *name, u64 base, u64 length, + u64 blk_size, u64 flags); + +/* + * Page allocator initializers. + */ +int nvgpu_page_allocator_init(struct gk20a *g, struct nvgpu_allocator *na, + const char *name, u64 base, u64 length, + u64 blk_size, u64 flags); + +/* + * Lockless allocatior initializers. + * Note: This allocator can only allocate fixed-size structures of a + * pre-defined size. + */ +int nvgpu_lockless_allocator_init(struct gk20a *g, struct nvgpu_allocator *na, + const char *name, u64 base, u64 length, + u64 struct_size, u64 flags); + +#define GPU_BALLOC_MAX_ORDER 31U + +/* + * Allocator APIs. + */ +u64 nvgpu_alloc(struct nvgpu_allocator *allocator, u64 len); +u64 nvgpu_alloc_pte(struct nvgpu_allocator *a, u64 len, u32 page_size); +void nvgpu_free(struct nvgpu_allocator *allocator, u64 addr); + +u64 nvgpu_alloc_fixed(struct nvgpu_allocator *allocator, u64 base, u64 len, + u32 page_size); +void nvgpu_free_fixed(struct nvgpu_allocator *allocator, u64 base, u64 len); + +int nvgpu_alloc_reserve_carveout(struct nvgpu_allocator *a, + struct nvgpu_alloc_carveout *co); +void nvgpu_alloc_release_carveout(struct nvgpu_allocator *a, + struct nvgpu_alloc_carveout *co); + +u64 nvgpu_alloc_base(struct nvgpu_allocator *a); +u64 nvgpu_alloc_length(struct nvgpu_allocator *a); +u64 nvgpu_alloc_end(struct nvgpu_allocator *a); +bool nvgpu_alloc_initialized(struct nvgpu_allocator *a); +u64 nvgpu_alloc_space(struct nvgpu_allocator *a); + +void nvgpu_alloc_destroy(struct nvgpu_allocator *allocator); + +#ifdef __KERNEL__ +void nvgpu_alloc_print_stats(struct nvgpu_allocator *a, + struct seq_file *s, int lock); +#endif + +static inline struct gk20a *nvgpu_alloc_to_gpu(struct nvgpu_allocator *a) +{ + return a->g; +} + +#ifdef CONFIG_DEBUG_FS +/* + * Common functionality for the internals of the allocators. + */ +void nvgpu_init_alloc_debug(struct gk20a *g, struct nvgpu_allocator *a); +void nvgpu_fini_alloc_debug(struct nvgpu_allocator *a); +#endif + +int nvgpu_alloc_common_init(struct nvgpu_allocator *a, struct gk20a *g, + const char *name, void *priv, bool dbg, + const struct nvgpu_allocator_ops *ops); + +static inline void nvgpu_alloc_enable_dbg(struct nvgpu_allocator *a) +{ + a->debug = true; +} + +static inline void nvgpu_alloc_disable_dbg(struct nvgpu_allocator *a) +{ + a->debug = false; +} + +/* + * Debug stuff. + */ +#ifdef __KERNEL__ +#define __alloc_pstat(seq, allocator, fmt, arg...) \ + do { \ + if (seq) \ + seq_printf(seq, fmt "\n", ##arg); \ + else \ + alloc_dbg(allocator, fmt, ##arg); \ + } while (0) +#endif + +#define do_alloc_dbg(a, fmt, arg...) \ + nvgpu_log((a)->g, gpu_dbg_alloc, "%25s " fmt, (a)->name, ##arg) + +/* + * This gives finer control over debugging messages. By defining the + * ALLOCATOR_DEBUG_FINE macro prints for an allocator will only get made if + * that allocator's debug flag is set. + * + * Otherwise debugging is as normal: debug statements for all allocators + * if the GPU debugging mask bit is set. Note: even when ALLOCATOR_DEBUG_FINE + * is set gpu_dbg_alloc must still also be set to true. + */ +#if defined(ALLOCATOR_DEBUG_FINE) +#define alloc_dbg(a, fmt, arg...) \ + do { \ + if ((a)->debug) \ + do_alloc_dbg((a), fmt, ##arg); \ + } while (0) +#else +#define alloc_dbg(a, fmt, arg...) do_alloc_dbg(a, fmt, ##arg) +#endif + +#endif /* NVGPU_ALLOCATOR_H */ diff --git a/include/nvgpu/as.h b/include/nvgpu/as.h new file mode 100644 index 0000000..f2249f9 --- /dev/null +++ b/include/nvgpu/as.h @@ -0,0 +1,54 @@ +/* + * GK20A Address Spaces + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_AS_H +#define NVGPU_AS_H + +#include + +struct vm_gk20a; +struct gk20a; + +struct gk20a_as { + int last_share_id; /* dummy allocator for now */ +}; + +struct gk20a_as_share { + struct gk20a_as *as; + struct vm_gk20a *vm; + int id; +}; + +/* + * AS allocation flags. + */ +#define NVGPU_AS_ALLOC_USERSPACE_MANAGED (1 << 0) + +int gk20a_as_release_share(struct gk20a_as_share *as_share); + +/* if big_page_size == 0, the default big page size is used */ +int gk20a_as_alloc_share(struct gk20a *g, u32 big_page_size, + u32 flags, struct gk20a_as_share **out); + +struct gk20a *gk20a_from_as(struct gk20a_as *as); +#endif /* NVGPU_AS_H */ diff --git a/include/nvgpu/atomic.h b/include/nvgpu/atomic.h new file mode 100644 index 0000000..3edc1fc --- /dev/null +++ b/include/nvgpu/atomic.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_ATOMIC_H +#define NVGPU_ATOMIC_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +#define NVGPU_ATOMIC_INIT(i) __nvgpu_atomic_init(i) +#define NVGPU_ATOMIC64_INIT(i) __nvgpu_atomic64_init(i) + +static inline void nvgpu_atomic_set(nvgpu_atomic_t *v, int i) +{ + __nvgpu_atomic_set(v, i); +} +static inline int nvgpu_atomic_read(nvgpu_atomic_t *v) +{ + return __nvgpu_atomic_read(v); +} +static inline void nvgpu_atomic_inc(nvgpu_atomic_t *v) +{ + __nvgpu_atomic_inc(v); +} +static inline int nvgpu_atomic_inc_return(nvgpu_atomic_t *v) +{ + return __nvgpu_atomic_inc_return(v); +} +static inline void nvgpu_atomic_dec(nvgpu_atomic_t *v) +{ + __nvgpu_atomic_dec(v); +} +static inline int nvgpu_atomic_dec_return(nvgpu_atomic_t *v) +{ + return __nvgpu_atomic_dec_return(v); +} +static inline int nvgpu_atomic_cmpxchg(nvgpu_atomic_t *v, int old, int new) +{ + return __nvgpu_atomic_cmpxchg(v, old, new); +} +static inline int nvgpu_atomic_xchg(nvgpu_atomic_t *v, int new) +{ + return __nvgpu_atomic_xchg(v, new); +} +static inline bool nvgpu_atomic_inc_and_test(nvgpu_atomic_t *v) +{ + return __nvgpu_atomic_inc_and_test(v); +} +static inline bool nvgpu_atomic_dec_and_test(nvgpu_atomic_t *v) +{ + return __nvgpu_atomic_dec_and_test(v); +} +static inline bool nvgpu_atomic_sub_and_test(int i, nvgpu_atomic_t *v) +{ + return __nvgpu_atomic_sub_and_test(i, v); +} +static inline int nvgpu_atomic_add_return(int i, nvgpu_atomic_t *v) +{ + return __nvgpu_atomic_add_return(i, v); +} +static inline int nvgpu_atomic_add_unless(nvgpu_atomic_t *v, int a, int u) +{ + return __nvgpu_atomic_add_unless(v, a, u); +} +static inline void nvgpu_atomic64_set(nvgpu_atomic64_t *v, long i) +{ + return __nvgpu_atomic64_set(v, i); +} +static inline long nvgpu_atomic64_read(nvgpu_atomic64_t *v) +{ + return __nvgpu_atomic64_read(v); +} +static inline void nvgpu_atomic64_add(long x, nvgpu_atomic64_t *v) +{ + __nvgpu_atomic64_add(x, v); +} +static inline void nvgpu_atomic64_inc(nvgpu_atomic64_t *v) +{ + __nvgpu_atomic64_inc(v); +} +static inline long nvgpu_atomic64_inc_return(nvgpu_atomic64_t *v) +{ + return __nvgpu_atomic64_inc_return(v); +} +static inline void nvgpu_atomic64_dec(nvgpu_atomic64_t *v) +{ + __nvgpu_atomic64_dec(v); +} +static inline void nvgpu_atomic64_dec_return(nvgpu_atomic64_t *v) +{ + __nvgpu_atomic64_dec_return(v); +} +static inline long nvgpu_atomic64_cmpxchg(nvgpu_atomic64_t *v, long old, + long new) +{ + return __nvgpu_atomic64_cmpxchg(v, old, new); +} +static inline void nvgpu_atomic64_sub(long x, nvgpu_atomic64_t *v) +{ + __nvgpu_atomic64_sub(x, v); +} +static inline long nvgpu_atomic64_sub_return(long x, nvgpu_atomic64_t *v) +{ + return __nvgpu_atomic64_sub_return(x, v); +} + +#endif /* NVGPU_ATOMIC_H */ diff --git a/include/nvgpu/barrier.h b/include/nvgpu/barrier.h new file mode 100644 index 0000000..f0b6b2b --- /dev/null +++ b/include/nvgpu/barrier.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* This file contains NVGPU_* high-level abstractions for various + * memor-barrier operations available in linux/kernel. Every OS + * should provide their own OS specific calls under this common API + */ + +#ifndef NVGPU_BARRIER_H +#define NVGPU_BARRIER_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +#define nvgpu_mb() __nvgpu_mb() +#define nvgpu_rmb() __nvgpu_rmb() +#define nvgpu_wmb() __nvgpu_wmb() + +#define nvgpu_smp_mb() __nvgpu_smp_mb() +#define nvgpu_smp_rmb() __nvgpu_smp_rmb() +#define nvgpu_smp_wmb() __nvgpu_smp_wmb() + +#define nvgpu_read_barrier_depends() __nvgpu_read_barrier_depends() +#define nvgpu_smp_read_barrier_depends() __nvgpu_smp_read_barrier_depends() + +#define NV_ACCESS_ONCE(x) __NV_ACCESS_ONCE(x) + +/* + * Sometimes we want to prevent speculation. + */ +#ifdef __NVGPU_PREVENT_UNTRUSTED_SPECULATION +#define nvgpu_speculation_barrier() __nvgpu_speculation_barrier() +#else +#define nvgpu_speculation_barrier() +#endif + +#endif /* NVGPU_BARRIER_H */ diff --git a/include/nvgpu/bios.h b/include/nvgpu/bios.h new file mode 100644 index 0000000..7d729b6 --- /dev/null +++ b/include/nvgpu/bios.h @@ -0,0 +1,1123 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_BIOS_H +#define NVGPU_BIOS_H + +#include + +struct gk20a; + +#define PERF_PTRS_WIDTH 0x4 +#define PERF_PTRS_WIDTH_16 0x2 + +enum { + CLOCKS_TABLE = 2, + CLOCK_PROGRAMMING_TABLE, + FLL_TABLE, + VIN_TABLE, + FREQUENCY_CONTROLLER_TABLE +}; + +enum { + PERFORMANCE_TABLE = 0, + MEMORY_CLOCK_TABLE, + MEMORY_TWEAK_TABLE, + POWER_CONTROL_TABLE, + THERMAL_CONTROL_TABLE, + THERMAL_DEVICE_TABLE, + THERMAL_COOLERS_TABLE, + PERFORMANCE_SETTINGS_SCRIPT, + CONTINUOUS_VIRTUAL_BINNING_TABLE, + POWER_SENSORS_TABLE = 0xA, + POWER_CAPPING_TABLE = 0xB, + POWER_TOPOLOGY_TABLE = 0xF, + THERMAL_CHANNEL_TABLE = 0x12, + VOLTAGE_RAIL_TABLE = 26, + VOLTAGE_DEVICE_TABLE, + VOLTAGE_POLICY_TABLE, + LOWPOWER_TABLE, + LOWPOWER_GR_TABLE = 32, + LOWPOWER_MS_TABLE = 33, +}; + +enum { + VP_FIELD_TABLE = 0, + VP_FIELD_REGISTER, + VP_TRANSLATION_TABLE, +}; + +struct bit_token { + u8 token_id; + u8 data_version; + u16 data_size; + u16 data_ptr; +} __packed; + +#define BIOS_GET_FIELD(value, name) ((value & name##_MASK) >> name##_SHIFT) + +struct fll_descriptor_header { + u8 version; + u8 size; +} __packed; + +#define FLL_DESCRIPTOR_HEADER_10_SIZE_4 4U +#define FLL_DESCRIPTOR_HEADER_10_SIZE_6 6U + +struct fll_descriptor_header_10 { + u8 version; + u8 header_size; + u8 entry_size; + u8 entry_count; + u16 max_min_freq_mhz; +} __packed; + +#define FLL_DESCRIPTOR_ENTRY_10_SIZE 15U + +struct fll_descriptor_entry_10 { + u8 fll_device_type; + u8 clk_domain; + u8 fll_device_id; + u16 lut_params; + u8 vin_idx_logic; + u8 vin_idx_sram; + u16 fll_params; + u8 min_freq_vfe_idx; + u8 freq_ctrl_idx; + u16 ref_freq_mhz; + u16 ffr_cutoff_freq_mhz; +} __packed; + +#define NV_FLL_DESC_FLL_PARAMS_MDIV_MASK 0x1F +#define NV_FLL_DESC_FLL_PARAMS_MDIV_SHIFT 0 + +#define NV_FLL_DESC_FLL_PARAMS_SKIP_PLDIV_BELOW_DVCO_MIN_MASK 0x20 +#define NV_FLL_DESC_FLL_PARAMS_SKIP_PLDIV_BELOW_DVCO_MIN_SHIFT 5 + +#define NV_FLL_DESC_LUT_PARAMS_VSELECT_MASK 0x3 +#define NV_FLL_DESC_LUT_PARAMS_VSELECT_SHIFT 0 + +#define NV_FLL_DESC_LUT_PARAMS_HYSTERISIS_THRESHOLD_MASK 0x3C +#define NV_FLL_DESC_LUT_PARAMS_HYSTERISIS_THRESHOLD_SHIFT 2 + +struct vin_descriptor_header_10 { + u8 version; + u8 header_sizee; + u8 entry_size; + u8 entry_count; + u8 flags0; + u32 vin_cal; +} __packed; + +struct vin_descriptor_entry_10 { + u8 vin_device_type; + u8 volt_domain_vbios; + u8 vin_device_id; +} __packed; + +#define NV_VIN_DESC_FLAGS0_VIN_CAL_REVISION_MASK 0x7 +#define NV_VIN_DESC_FLAGS0_VIN_CAL_REVISION_SHIFT 0 + +#define NV_VIN_DESC_FLAGS0_VIN_CAL_TYPE_MASK 0xF0 +#define NV_VIN_DESC_FLAGS0_VIN_CAL_TYPE_SHIFT 4 + +#define NV_VIN_DESC_FLAGS0_DISABLE_CONTROL_MASK 0x8 +#define NV_VIN_DESC_FLAGS0_DISABLE_CONTROL_SHIFT 3 + +#define NV_VIN_DESC_VIN_CAL_SLOPE_FRACTION_MASK 0x1FF +#define NV_VIN_DESC_VIN_CAL_SLOPE_FRACTION_SHIFT 0 + +#define NV_VIN_DESC_VIN_CAL_SLOPE_INTEGER_MASK 0x3C00 +#define NV_VIN_DESC_VIN_CAL_SLOPE_INTEGER_SHIFT 10 + +#define NV_VIN_DESC_VIN_CAL_INTERCEPT_FRACTION_MASK 0x3C000 +#define NV_VIN_DESC_VIN_CAL_INTERCEPT_FRACTION_SHIFT 14 + +#define NV_VIN_DESC_VIN_CAL_INTERCEPT_INTEGER_MASK 0xFFC0000 +#define NV_VIN_DESC_VIN_CAL_INTERCEPT_INTEGER_SHIFT 18 + +#define NV_VIN_DESC_VIN_CAL_OFFSET_MASK 0x7F +#define NV_VIN_DESC_VIN_CAL_OFFSET_SHIFT 0 + +#define NV_VIN_DESC_VIN_CAL_GAIN_MASK 0xF80 +#define NV_VIN_DESC_VIN_CAL_GAIN_SHIFT 7 + +#define VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07 0x07U +struct vbios_clocks_table_1x_header { + u8 version; + u8 header_size; + u8 entry_size; + u8 entry_count; + u8 clocks_hal; + u16 cntr_sampling_periodms; +} __packed; + +#define VBIOS_CLOCKS_TABLE_35_HEADER_SIZE_09 0x09U +struct vbios_clocks_table_35_header { + u8 version; + u8 header_size; + u8 entry_size; + u8 entry_count; + u8 clocks_hal; + u16 cntr_sampling_periodms; + u16 reference_window; +} __packed; + +#define VBIOS_CLOCKS_TABLE_1X_ENTRY_SIZE_09 0x09U +struct vbios_clocks_table_1x_entry { + u8 flags0; + u16 param0; + u32 param1; + u16 param2; +} __packed; + +#define VBIOS_CLOCKS_TABLE_35_ENTRY_SIZE_11 0x0BU +struct vbios_clocks_table_35_entry { + u8 flags0; + u16 param0; + u32 param1; + u16 param2; + u16 param3; +} __packed; + +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_MASK 0x1F +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_SHIFT 0 +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_FIXED 0x00 +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_MASTER 0x01 +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_SLAVE 0x02 + +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_FIRST_MASK 0xFF +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_FIRST_SHIFT 0 +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_LAST_MASK 0xFF00 +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_LAST_SHIFT 0x08 + +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_FIXED_FREQUENCY_MHZ_MASK 0xFFFF +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_FIXED_FREQUENCY_MHZ_SHIFT 0 +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MIN_MHZ_MASK 0xFFFF +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MIN_MHZ_SHIFT 0 + +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MAX_MHZ_MASK 0xFFFF0000 +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MAX_MHZ_SHIFT 0 + +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_SLAVE_MASTER_DOMAIN_MASK 0xF +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_SLAVE_MASTER_DOMAIN_SHIFT 0 + +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_UNAWARE_ORDERING_IDX_MASK 0xF +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_UNAWARE_ORDERING_IDX_SHIFT 0 + +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_AWARE_ORDERING_IDX_MASK 0xF0 +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_AWARE_ORDERING_IDX_SHIFT 4 + +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING_MASK 0x100 +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING_SHIFT 8 +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING_FALSE 0x00 +#define NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING_TRUE 0x01 + +#define NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_PRE_VOLT_ORDERING_IDX_MASK 0xF +#define NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_PRE_VOLT_ORDERING_IDX_SHIFT 0 + +#define NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_POST_VOLT_ORDERING_IDX_MASK 0xF0 +#define NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_POST_VOLT_ORDERING_IDX_SHIFT 4 + +#define NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM3_CLK_MONITOR_THRESHOLD_MIN_MASK 0xFF +#define NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM3_CLK_MONITOR_THRESHOLD_MIN_SHIFT 0 +#define NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM3_CLK_MONITOR_THRESHOLD_MAX_MASK 0xFF00 +#define NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM3_CLK_MONITOR_THRESHOLD_MAX_SHIFT 0x08 + +#define VBIOS_CLOCK_PROGRAMMING_TABLE_1X_HEADER_SIZE_08 0x08U +struct vbios_clock_programming_table_1x_header { + u8 version; + u8 header_size; + u8 entry_size; + u8 entry_count; + u8 slave_entry_size; + u8 slave_entry_count; + u8 vf_entry_size; + u8 vf_entry_count; +} __packed; + +#define VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_SIZE_05 0x05U +#define VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_SIZE_0D 0x0DU +struct vbios_clock_programming_table_1x_entry { + u8 flags0; + u16 freq_max_mhz; + u8 param0; + u8 param1; + u32 rsvd; + u32 rsvd1; +} __packed; + +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASK 0xF +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_SHIFT 0 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO 0x00 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_TABLE 0x01 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_SLAVE 0x02 + +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_MASK 0x70 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_SHIFT 4 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_PLL 0x00 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_ONE_SOURCE 0x01 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_FLL 0x02 + +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_MASK 0x80 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_SHIFT 7 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_FALSE 0x00 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_TRUE 0x01 + +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM0_PLL_PLL_INDEX_MASK 0xFF +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM0_PLL_PLL_INDEX_SHIFT 0 + +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM1_PLL_FREQ_STEP_SIZE_MASK 0xFF +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM1_PLL_FREQ_STEP_SIZE_SHIFT 0 + +#define VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_SIZE_03 0x03U +struct vbios_clock_programming_table_1x_slave_entry { + u8 clk_dom_idx; + u16 param0; +} __packed; + +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_RATIO_RATIO_MASK 0xFF +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_RATIO_RATIO_SHIFT 0 + +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_TABLE_FREQ_MASK 0x3FFF +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_TABLE_FREQ_SHIFT 0 + +#define VBIOS_CLOCK_PROGRAMMING_TABLE_1X_VF_ENTRY_SIZE_02 0x02U +struct vbios_clock_programming_table_1x_vf_entry { + u8 vfe_idx; + u8 param0; +} __packed; + +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_VF_ENTRY_PARAM0_FLL_GAIN_VFE_IDX_MASK 0xFF +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_VF_ENTRY_PARAM0_FLL_GAIN_VFE_IDX_SHIFT 0 + +struct vbios_vfe_3x_header_struct { + u8 version; + u8 header_size; + u8 vfe_var_entry_size; + u8 vfe_var_entry_count; + u8 vfe_equ_entry_size; + u8 vfe_equ_entry_count; + u8 polling_periodms; +} __packed; + +#define VBIOS_VFE_3X_VAR_ENTRY_SIZE_11 0x11U +#define VBIOS_VFE_3X_VAR_ENTRY_SIZE_19 0x19U +struct vbios_vfe_3x_var_entry_struct { + u8 type; + u32 out_range_min; + u32 out_range_max; + u32 param0; + u32 param1; + u32 param2; + u32 param3; +} __packed; + +#define VBIOS_VFE_3X_VAR_ENTRY_TYPE_DISABLED 0x00U +#define VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_FREQUENCY 0x01U +#define VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_VOLTAGE 0x02U +#define VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_SENSED_TEMP 0x03U +#define VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_SENSED_FUSE 0x04U +#define VBIOS_VFE_3X_VAR_ENTRY_TYPE_DERIVED_PRODUCT 0x05U +#define VBIOS_VFE_3X_VAR_ENTRY_TYPE_DERIVED_SUM 0x06U + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_TH_CH_IDX_MASK 0xFF +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_TH_CH_IDX_SHIFT 0 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_HYS_POS_MASK 0xFF00 +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_HYS_POS_SHIFT 8 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_HYS_NEG_MASK 0xFF0000 +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_HYS_NEG_SHIFT 16 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VFIELD_ID_MASK 0xFF +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VFIELD_ID_SHIFT 0 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VFIELD_ID_VER_MASK 0xFF00 +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VFIELD_ID_VER_SHIFT 8 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_EXPECTED_VER_MASK 0xFF0000 +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_EXPECTED_VER_SHIFT 16 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_USE_DEFAULT_ON_VER_CHECK_FAIL_MASK 0x1000000 +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_USE_DEFAULT_ON_VER_CHECK_FAIL_SHIFT 24 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VALUE_SIGNED_INTEGER_MASK 0x2000000 +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VALUE_SIGNED_INTEGER_SHIFT 25 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_USE_DEFAULT_ON_VER_CHECK_FAIL_YES 0x00000001 +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_USE_DEFAULT_ON_VER_CHECK_FAIL_NO 0x00000000 +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_DPROD_VFE_VAR_IDX_0_MASK 0xFF +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_DPROD_VFE_VAR_IDX_0_SHIFT 0 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_DPROD_VFE_VAR_IDX_1_MASK 0xFF00 +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_DPROD_VFE_VAR_IDX_1_SHIFT 8 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_DSUM_VFE_VAR_IDX_0_MASK 0xFF +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_DSUM_VFE_VAR_IDX_0_SHIFT 0 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_DSUM_VFE_VAR_IDX_1_MASK 0xFF00 +#define VBIOS_VFE_3X_VAR_ENTRY_PAR0_DSUM_VFE_VAR_IDX_1_SHIFT 8 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR1_SSFUSE_DEFAULT_VAL_MASK 0xFFFFFFFF +#define VBIOS_VFE_3X_VAR_ENTRY_PAR1_SSFUSE_DEFAULT_VAL_SHIFT 0 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR1_SSFUSE_HW_CORRECTION_SCALE_MASK 0xFFFFFFFF +#define VBIOS_VFE_3X_VAR_ENTRY_PAR1_SSFUSE_HW_CORRECTION_SCALE_SHIFT 0 + +#define VBIOS_VFE_3X_VAR_ENTRY_PAR1_SSFUSE_HW_CORRECTION_OFFSET_MASK 0xFFFFFFFF +#define VBIOS_VFE_3X_VAR_ENTRY_PAR1_SSFUSE_HW_CORRECTION_OFFSET_SHIFT 0 + +#define VBIOS_VFE_3X_EQU_ENTRY_SIZE_17 0x17U +#define VBIOS_VFE_3X_EQU_ENTRY_SIZE_18 0x18U + +struct vbios_vfe_3x_equ_entry_struct { + u8 type; + u8 var_idx; + u8 equ_idx_next; + u32 out_range_min; + u32 out_range_max; + u32 param0; + u32 param1; + u32 param2; + u8 param3; +} __packed; + + +#define VBIOS_VFE_3X_EQU_ENTRY_TYPE_DISABLED 0x00U +#define VBIOS_VFE_3X_EQU_ENTRY_TYPE_QUADRATIC 0x01U +#define VBIOS_VFE_3X_EQU_ENTRY_TYPE_MINMAX 0x02U +#define VBIOS_VFE_3X_EQU_ENTRY_TYPE_COMPARE 0x03U +#define VBIOS_VFE_3X_EQU_ENTRY_TYPE_QUADRATIC_FXP 0x04U +#define VBIOS_VFE_3X_EQU_ENTRY_TYPE_MINMAX_FXP 0x05U + +#define VBIOS_VFE_3X_EQU_ENTRY_IDX_INVALID 0xFFU + +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_QUADRATIC_C0_MASK 0xFFFFFFFF +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_QUADRATIC_C0_SHIFT 0 + +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_VFE_EQU_IDX_0_MASK 0xFF +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_VFE_EQU_IDX_0_SHIFT 0 + +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_VFE_EQU_IDX_1_MASK 0xFF00 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_VFE_EQU_IDX_1_SHIFT 8 + +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_CRIT_MASK 0x10000 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_CRIT_SHIFT 16 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_CRIT_MIN 0x00000000 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_CRIT_MAX 0x00000001 + +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_COMPARE_CRIT_MASK 0xFFFFFFFF +#define VBIOS_VFE_3X_EQU_ENTRY_PAR0_COMPARE_CRIT_SHIFT 0 + +#define VBIOS_VFE_3X_EQU_ENTRY_PAR1_QUADRATIC_C1_MASK 0xFFFFFFFF +#define VBIOS_VFE_3X_EQU_ENTRY_PAR1_QUADRATIC_C1_SHIFT 0 + +#define VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_VFE_EQU_IDX_TRUE_MASK 0xFF +#define VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_VFE_EQU_IDX_TRUE_SHIFT 0 + +#define VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_VFE_EQU_IDX_FALSE_MASK 0xFF00 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_VFE_EQU_IDX_FALSE_SHIFT 8 + +#define VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_MASK 0x70000 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_SHIFT 16 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_EQUAL 0x00000000 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_GREATER_EQ 0x00000001 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_GREATER 0x00000002 + +#define VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_MASK 0xF +#define VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_SHIFT 0 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_UNITLESS 0x0 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_FREQ_MHZ 0x1 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VOLT_UV 0x2 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VF_GAIN 0x3 +#define VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VOLT_DELTA_UV 0x4 + +#define NV_VFIELD_DESC_SIZE_BYTE 0x00000000U +#define NV_VFIELD_DESC_SIZE_WORD 0x00000001U +#define NV_VFIELD_DESC_SIZE_DWORD 0x00000002U +#define VFIELD_SIZE(pvregentry) ((pvregentry->strap_reg_desc & 0x18U) >> 3U) + +#define NV_PMU_BIOS_VFIELD_DESC_CODE_INVALID 0x00000000U +#define NV_PMU_BIOS_VFIELD_DESC_CODE_REG 0x00000001U +#define NV_PMU_BIOS_VFIELD_DESC_CODE_INDEX_REG 0x00000002U + +#define NV_VFIELD_DESC_CODE_INVALID NV_PMU_BIOS_VFIELD_DESC_CODE_INVALID +#define NV_VFIELD_DESC_CODE_REG NV_PMU_BIOS_VFIELD_DESC_CODE_REG +#define NV_VFIELD_DESC_CODE_INDEX_REG NV_PMU_BIOS_VFIELD_DESC_CODE_INDEX_REG + +#define VFIELD_CODE(pvregentry) ((pvregentry->strap_reg_desc & 0xE0U) >> 5U) + +#define VFIELD_ID_STRAP_IDDQ 0x09U +#define VFIELD_ID_STRAP_IDDQ_1 0x0BU + +#define VFIELD_REG_HEADER_SIZE 3U +struct vfield_reg_header { + u8 version; + u8 entry_size; + u8 count; +} __packed; + +#define VBIOS_VFIELD_REG_TABLE_VERSION_1_0 0x10U + + +#define VFIELD_REG_ENTRY_SIZE 13U +struct vfield_reg_entry { + u8 strap_reg_desc; + u32 reg; + u32 reg_index; + u32 index; +} __packed; + +#define VFIELD_HEADER_SIZE 3U + +struct vfield_header { + u8 version; + u8 entry_size; + u8 count; +} __packed; + +#define VBIOS_VFIELD_TABLE_VERSION_1_0 0x10U + +#define VFIELD_BIT_START(ventry) (ventry.strap_desc & 0x1FU) +#define VFIELD_BIT_STOP(ventry) ((ventry.strap_desc & 0x3E0U) >> 5U) +#define VFIELD_BIT_REG(ventry) ((ventry.strap_desc & 0x3C00U) >> 10U) + +#define VFIELD_ENTRY_SIZE 3U + +struct vfield_entry { + u8 strap_id; + u16 strap_desc; +} __packed; + +#define PERF_CLK_DOMAINS_IDX_MAX (32U) +#define PERF_CLK_DOMAINS_IDX_INVALID PERF_CLK_DOMAINS_IDX_MAX + +#define VBIOS_PSTATE_TABLE_VERSION_5X 0x50U +#define VBIOS_PSTATE_HEADER_5X_SIZE_10 (10U) + +struct vbios_pstate_header_5x { + u8 version; + u8 header_size; + u8 base_entry_size; + u8 base_entry_count; + u8 clock_entry_size; + u8 clock_entry_count; + u8 flags0; + u8 initial_pstate; + u8 cpi_support_level; +u8 cpi_features; +} __packed; + +#define VBIOS_PSTATE_CLOCK_ENTRY_5X_SIZE_6 6U + +#define VBIOS_PSTATE_BASE_ENTRY_5X_SIZE_2 0x2U +#define VBIOS_PSTATE_BASE_ENTRY_5X_SIZE_3 0x3U + +struct vbios_pstate_entry_clock_5x { + u16 param0; + u32 param1; +} __packed; + +struct vbios_pstate_entry_5x { + u8 pstate_level; + u8 flags0; + u8 lpwr_entry_idx; + struct vbios_pstate_entry_clock_5x clockEntry[PERF_CLK_DOMAINS_IDX_MAX]; +} __packed; + +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM0_NOM_FREQ_MHZ_SHIFT 0 +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM0_NOM_FREQ_MHZ_MASK 0x00003FFF + +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MIN_FREQ_MHZ_SHIFT 0 +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MIN_FREQ_MHZ_MASK 0x00003FFF + +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MAX_FREQ_MHZ_SHIFT 14 +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MAX_FREQ_MHZ_MASK 0x0FFFC000 + +#define VBIOS_PERFLEVEL_SKIP_ENTRY 0xFFU + +#define VBIOS_MEMORY_CLOCK_HEADER_11_VERSION 0x11U + +#define VBIOS_MEMORY_CLOCK_HEADER_11_0_SIZE 16U +#define VBIOS_MEMORY_CLOCK_HEADER_11_1_SIZE 21U +#define VBIOS_MEMORY_CLOCK_HEADER_11_2_SIZE 26U + +struct vbios_memory_clock_header_1x { + u8 version; + u8 header_size; + u8 base_entry_size; + u8 strap_entry_size; + u8 strap_entry_count; + u8 entry_count; + u8 flags; + u8 fbvdd_settle_time; + u32 cfg_pwrd_val; + u16 fbvddq_high; + u16 fbvddq_low; + u32 script_list_ptr; + u8 script_list_count; + u32 cmd_script_list_ptr; + u8 cmd_script_list_count; +} __packed; + +#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_2_SIZE 20U + +struct vbios_memory_clock_base_entry_11 { + u16 minimum; + u16 maximum; + u32 script_pointer; + u8 flags0; + u32 fbpa_config; + u32 fbpa_config1; + u8 flags1; + u8 ref_mpllssf_freq_delta; + u8 flags2; +} __packed; + +/* Script Pointer Index */ +/* #define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_FLAGS1_SCRIPT_INDEX 3:2*/ +#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_FLAGS1_SCRIPT_INDEX_MASK \ + ((u8)0xc) +#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_FLAGS1_SCRIPT_INDEX_SHIFT 2 +/* #define VBIOS_MEMORY_CLOCK_BASE_ENTRY_12_FLAGS2_CMD_SCRIPT_INDEX 1:0*/ +#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_12_FLAGS2_CMD_SCRIPT_INDEX_MASK \ + ((u8)0x3) +#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_12_FLAGS2_CMD_SCRIPT_INDEX_SHIFT 0 + +#define VBIOS_POWER_SENSORS_VERSION_2X 0x20U +#define VBIOS_POWER_SENSORS_2X_HEADER_SIZE_08 0x00000008U + +struct pwr_sensors_2x_header { + u8 version; + u8 header_size; + u8 table_entry_size; + u8 num_table_entries; + u32 ba_script_pointer; +} __packed; + +#define VBIOS_POWER_SENSORS_2X_ENTRY_SIZE_15 0x00000015U + +struct pwr_sensors_2x_entry { + u8 flags0; + u32 class_param0; + u32 sensor_param0; + u32 sensor_param1; + u32 sensor_param2; + u32 sensor_param3; +} __packed; + +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_FLAGS0_CLASS_MASK 0xF +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_FLAGS0_CLASS_SHIFT 0 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_FLAGS0_CLASS_I2C 0x00000001U + +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_CLASS_PARAM0_I2C_INDEX_MASK 0xFF +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_CLASS_PARAM0_I2C_INDEX_SHIFT 0 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_CLASS_PARAM0_I2C_USE_FXP8_8_MASK 0x100 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_CLASS_PARAM0_I2C_USE_FXP8_8_SHIFT 8 + +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM0_INA3221_RSHUNT0_MOHM_MASK 0xFFFF +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM0_INA3221_RSHUNT0_MOHM_SHIFT 0 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM0_INA3221_RSHUNT1_MOHM_MASK 0xFFFF0000 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM0_INA3221_RSHUNT1_MOHM_SHIFT 16 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM1_INA3221_RSHUNT2_MOHM_MASK 0xFFFF +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM1_INA3221_RSHUNT2_MOHM_SHIFT 0 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM1_INA3221_CONFIGURATION_MASK 0xFFFF0000 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM1_INA3221_CONFIGURATION_SHIFT 16 + +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM2_INA3221_MASKENABLE_MASK 0xFFFF +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM2_INA3221_MASKENABLE_SHIFT 0 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM2_INA3221_GPIOFUNCTION_MASK 0xFF0000 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM2_INA3221_GPIOFUNCTION_SHIFT 16 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM3_INA3221_CURR_CORRECT_M_MASK 0xFFFF +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM3_INA3221_CURR_CORRECT_M_SHIFT 0 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM3_INA3221_CURR_CORRECT_B_MASK 0xFFFF0000 +#define NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM3_INA3221_CURR_CORRECT_B_SHIFT 16 + +#define VBIOS_POWER_TOPOLOGY_VERSION_2X 0x20U +#define VBIOS_POWER_TOPOLOGY_2X_HEADER_SIZE_06 0x00000006U + +struct pwr_topology_2x_header { + u8 version; + u8 header_size; + u8 table_entry_size; + u8 num_table_entries; + u8 rel_entry_size; + u8 num_rel_entries; +} __packed; + +#define VBIOS_POWER_TOPOLOGY_2X_ENTRY_SIZE_16 0x00000016U + +struct pwr_topology_2x_entry { + u8 flags0; + u8 pwr_rail; + u32 param0; + u32 curr_corr_slope; + u32 curr_corr_offset; + u32 param1; + u32 param2; +} __packed; + +#define NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_FLAGS0_CLASS_MASK 0xF +#define NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_FLAGS0_CLASS_SHIFT 0 +#define NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_FLAGS0_CLASS_SENSOR U8(0x00000001) + +#define NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_PARAM1_SENSOR_INDEX_MASK 0xFF +#define NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_PARAM1_SENSOR_INDEX_SHIFT 0 +#define NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_PARAM1_SENSOR_PROVIDER_INDEX_MASK 0xFF00 +#define NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_PARAM1_SENSOR_PROVIDER_INDEX_SHIFT 8 + +#define VBIOS_POWER_POLICY_VERSION_3X 0x30U +#define VBIOS_POWER_POLICY_3X_HEADER_SIZE_25 0x00000025U + +struct pwr_policy_3x_header_struct { + u8 version; + u8 header_size; + u8 table_entry_size; + u8 num_table_entries; + u16 base_sample_period; + u16 min_client_sample_period; + u8 table_rel_entry_size; + u8 num_table_rel_entries; + u8 tgp_policy_idx; + u8 rtp_policy_idx; + u8 mxm_policy_idx; + u8 dnotifier_policy_idx; + u32 d2_limit; + u32 d3_limit; + u32 d4_limit; + u32 d5_limit; + u8 low_sampling_mult; + u8 pwr_tgt_policy_idx; + u8 pwr_tgt_floor_policy_idx; + u8 sm_bus_policy_idx; + u8 table_viol_entry_size; + u8 num_table_viol_entries; +} __packed; + +#define VBIOS_POWER_POLICY_3X_ENTRY_SIZE_2E 0x0000002EU + +struct pwr_policy_3x_entry_struct { + u8 flags0; + u8 ch_idx; + u32 limit_min; + u32 limit_rated; + u32 limit_max; + u32 param0; + u32 param1; + u32 param2; + u32 param3; + u32 limit_batt; + u8 flags1; + u8 past_length; + u8 next_length; + u16 ratio_min; + u16 ratio_max; + u8 sample_mult; + u32 filter_param; +} __packed; + +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS_MASK 0xF +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS_SHIFT 0 +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS_HW_THRESHOLD 0x00000005U +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_LIMIT_UNIT_MASK 0x10 +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_LIMIT_UNIT_SHIFT 4 + +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_FULL_DEFLECTION_LIMIT_MASK 0x1 +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_FULL_DEFLECTION_LIMIT_SHIFT 0 +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_INTEGRAL_CONTROL_MASK 0x2 +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_INTEGRAL_CONTROL_SHIFT 1 +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_FILTER_TYPE_MASK 0x3C +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_FILTER_TYPE_SHIFT 2 + +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_THRES_IDX_MASK 0xFF +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_THRES_IDX_SHIFT 0 +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_LOW_THRESHOLD_IDX_MASK 0xFF00 +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_LOW_THRESHOLD_IDX_SHIFT 8 +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_LOW_THRESHOLD_USE_MASK 0x10000 +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_LOW_THRESHOLD_USE_SHIFT 16 + +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM1_HW_THRESHOLD_LOW_THRESHOLD_VAL_MASK 0xFFFF +#define NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM1_HW_THRESHOLD_LOW_THRESHOLD_VAL_SHIFT 0 + +/* Voltage Rail Table */ +struct vbios_voltage_rail_table_1x_header { + u8 version; + u8 header_size; + u8 table_entry_size; + u8 num_table_entries; + u8 volt_domain_hal; +} __packed; + +#define NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_07 0X00000007U +#define NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_08 0X00000008U +#define NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_09 0X00000009U +#define NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0A 0X0000000AU +#define NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0B 0X0000000BU +#define NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0C 0X0000000CU + +struct vbios_voltage_rail_table_1x_entry { + u32 boot_voltage_uv; + u8 rel_limit_vfe_equ_idx; + u8 alt_rel_limit_vfe_equidx; + u8 ov_limit_vfe_equ_idx; + u8 pwr_equ_idx; + u8 boot_volt_vfe_equ_idx; + u8 vmin_limit_vfe_equ_idx; + u8 volt_margin_limit_vfe_equ_idx; + u8 volt_scale_exp_pwr_equ_idx; +} __packed; + +/* Voltage Device Table */ +struct vbios_voltage_device_table_1x_header { + u8 version; + u8 header_size; + u8 table_entry_size; + u8 num_table_entries; +} __packed; + +struct vbios_voltage_device_table_1x_entry { + u8 type; + u8 volt_domain; + u16 settle_time_us; + u32 param0; + u32 param1; + u32 param2; + u32 param3; + u32 param4; +} __packed; + +#define NV_VBIOS_VOLTAGE_DEVICE_1X_ENTRY_TYPE_INVALID 0x00U +#define NV_VBIOS_VOLTAGE_DEVICE_1X_ENTRY_TYPE_PSV 0x02U + +#define NV_VBIOS_VDT_1X_ENTRY_PARAM0_PSV_INPUT_FREQUENCY_MASK \ + GENMASK(23, 0) +#define NV_VBIOS_VDT_1X_ENTRY_PARAM0_PSV_INPUT_FREQUENCY_SHIFT 0 +#define NV_VBIOS_VDT_1X_ENTRY_PARAM0_PSV_EXT_DEVICE_INDEX_MASK \ + GENMASK(31, 24) +#define NV_VBIOS_VDT_1X_ENTRY_PARAM0_PSV_EXT_DEVICE_INDEX_SHIFT 24 + +#define NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_VOLTAGE_MINIMUM_MASK \ + GENMASK(23, 0) +#define NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_VOLTAGE_MINIMUM_SHIFT 0 +#define NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_OPERATION_TYPE_MASK \ + GENMASK(31, 24) +#define NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_OPERATION_TYPE_SHIFT 24 +#define NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_OPERATION_TYPE_DEFAULT 0x00 +#define NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_OPERATION_TYPE_LPWR_STEADY_STATE \ + 0x01 +#define NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_OPERATION_TYPE_LPWR_SLEEP_STATE \ + 0x02 +#define NV_VBIOS_VDT_1X_ENTRY_PARAM2_PSV_VOLTAGE_MAXIMUM_MASK \ + GENMASK(23, 0) +#define NV_VBIOS_VDT_1X_ENTRY_PARAM2_PSV_VOLTAGE_MAXIMUM_SHIFT 0 +#define NV_VBIOS_VDT_1X_ENTRY_PARAM2_PSV_RSVD_MASK \ + GENMASK(31, 24) +#define NV_VBIOS_VDT_1X_ENTRY_PARAM2_PSV_RSVD_SHIFT 24 + +#define NV_VBIOS_VDT_1X_ENTRY_PARAM3_PSV_VOLTAGE_BASE_MASK \ + GENMASK(23, 0) +#define NV_VBIOS_VDT_1X_ENTRY_PARAM3_PSV_VOLTAGE_BASE_SHIFT 0 +#define NV_VBIOS_VDT_1X_ENTRY_PARAM3_PSV_VOLTAGE_STEPS_MASK \ + GENMASK(31, 24) +#define NV_VBIOS_VDT_1X_ENTRY_PARAM3_PSV_VOLTAGE_STEPS_SHIFT 24 + +#define NV_VBIOS_VDT_1X_ENTRY_PARAM4_PSV_OFFSET_SCALE_MASK \ + GENMASK(23, 0) +#define NV_VBIOS_VDT_1X_ENTRY_PARAM4_PSV_OFFSET_SCALE_SHIFT 0 +#define NV_VBIOS_VDT_1X_ENTRY_PARAM4_PSV_RSVD_MASK \ + GENMASK(31, 24) +#define NV_VBIOS_VDT_1X_ENTRY_PARAM4_PSV_RSVD_SHIFT 24 + +/* Voltage Policy Table */ +struct vbios_voltage_policy_table_1x_header { + u8 version; + u8 header_size; + u8 table_entry_size; + u8 num_table_entries; + u8 perf_core_vf_seq_policy_idx; +} __packed; + +struct vbios_voltage_policy_table_1x_entry { + u8 type; + u32 param0; + u32 param1; + u32 param2; + u32 param3; +} __packed; + +#define NV_VBIOS_VOLTAGE_POLICY_1X_ENTRY_TYPE_INVALID 0x00U +#define NV_VBIOS_VOLTAGE_POLICY_1X_ENTRY_TYPE_SINGLE_RAIL 0x01U +#define NV_VBIOS_VOLTAGE_POLICY_1X_ENTRY_TYPE_SR_MULTI_STEP 0x02U +#define NV_VBIOS_VOLTAGE_POLICY_1X_ENTRY_TYPE_SR_SINGLE_STEP 0x03U +#define NV_VBIOS_VOLTAGE_POLICY_1X_ENTRY_TYPE_SINGLE_RAIL_MULTI_STEP 0x04U + +#define NV_VBIOS_VPT_ENTRY_PARAM0_SINGLE_RAIL_VOLT_DOMAIN_MASK \ + GENMASK(7, 0) +#define NV_VBIOS_VPT_ENTRY_PARAM0_SINGLE_RAIL_VOLT_DOMAIN_SHIFT 0 +#define NV_VBIOS_VPT_ENTRY_PARAM0_RSVD_MASK GENMASK(8, 31) +#define NV_VBIOS_VPT_ENTRY_PARAM0_RSVD_SHIFT 8 + +#define NV_VBIOS_VPT_ENTRY_PARAM0_SR_VD_MASTER_MASK \ + GENMASK(7, 0) +#define NV_VBIOS_VPT_ENTRY_PARAM0_SR_VD_MASTER_SHIFT 0 +#define NV_VBIOS_VPT_ENTRY_PARAM0_SR_VD_SLAVE_MASK \ + GENMASK(15, 8) +#define NV_VBIOS_VPT_ENTRY_PARAM0_SR_VD_SLAVE_SHIFT 8 +#define NV_VBIOS_VPT_ENTRY_PARAM0_SR_DELTA_SM_MIN_MASK \ + GENMASK(23, 16) +#define NV_VBIOS_VPT_ENTRY_PARAM0_SR_DELTA_SM_MIN_SHIFT 16 +#define NV_VBIOS_VPT_ENTRY_PARAM0_SR_DELTA_SM_MAX_MASK \ + GENMASK(31, 24) +#define NV_VBIOS_VPT_ENTRY_PARAM0_SR_DELTA_SM_MAX_SHIFT 24 + +#define NV_VBIOS_VPT_ENTRY_PARAM1_SR_SETTLE_TIME_INTERMEDIATE_MASK \ + GENMASK(15, 0) +#define NV_VBIOS_VPT_ENTRY_PARAM1_SR_SETTLE_TIME_INTERMEDIATE_SHIFT 0 +#define NV_VBIOS_VPT_ENTRY_PARAM2_SR_RAMP_UP_STEP_SIZE_UV_MASK \ + GENMASK(31, 0) +#define NV_VBIOS_VPT_ENTRY_PARAM2_SR_RAMP_UP_STEP_SIZE_UV_SHIFT 0 +#define NV_VBIOS_VPT_ENTRY_PARAM3_SR_RAMP_DOWN_STEP_SIZE_UV_MASK \ + GENMASK(31, 0) +#define NV_VBIOS_VPT_ENTRY_PARAM3_SR_RAMP_DOWN_STEP_SIZE_UV_SHIFT 0 + +/* Type-Specific Parameter DWORD 0 - Type = _SR_MULTI_STEP */ +#define NV_VBIOS_VPT_ENTRY_PARAM1_SR_SETTLE_TIME_INTERMEDIATE_MASK \ + GENMASK(15, 0) +#define NV_VBIOS_VPT_ENTRY_PARAM1_SR_SETTLE_TIME_INTERMEDIATE_SHIFT \ + 0 + +#define VBIOS_THERM_DEVICE_VERSION_1X 0x10U + +#define VBIOS_THERM_DEVICE_1X_HEADER_SIZE_04 0x00000004U + +struct therm_device_1x_header { + u8 version; + u8 header_size; + u8 table_entry_size; + u8 num_table_entries; +} ; + +struct therm_device_1x_entry { + u8 class_id; + u8 param0; + u8 flags; +} ; + +#define NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_INVALID 0x00U +#define NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_GPU 0x01U +#define NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_GPU_GPC_TSOSC 0x02U +#define NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_GPU_GPC_SCI 0x03U +#define NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_HBM2_SITE 0x70U +#define NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_HBM2_COMBINED 0x71U + +#define NV_VBIOS_THERM_DEVICE_1X_ENTRY_PARAM0_I2C_DEVICE_INDEX_MASK 0xFF +#define NV_VBIOS_THERM_DEVICE_1X_ENTRY_PARAM0_I2C_DEVICE_INDEX_SHIFT 0 + +#define VBIOS_THERM_CHANNEL_VERSION_1X 0x10U + +#define VBIOS_THERM_CHANNEL_1X_HEADER_SIZE_09 0x00000009U + +struct therm_channel_1x_header { + u8 version; + u8 header_size; + u8 table_entry_size; + u8 num_table_entries; + u8 gpu_avg_pri_ch_idx; + u8 gpu_max_pri_ch_idx; + u8 board_pri_ch_idx; + u8 mem_pri_ch_idx; + u8 pwr_supply_pri_ch_idx; +} __packed; + +struct therm_channel_1x_entry { + u8 class_id; + u8 param0; + u8 param1; + u8 param2; + u8 flags; +} __packed; + +#define NV_VBIOS_THERM_CHANNEL_1X_ENTRY_CLASS_DEVICE 0x01U + +#define NV_VBIOS_THERM_CHANNEL_1X_ENTRY_PARAM0_DEVICE_INDEX_MASK 0xFF +#define NV_VBIOS_THERM_CHANNEL_1X_ENTRY_PARAM0_DEVICE_INDEX_SHIFT 0 + +#define NV_VBIOS_THERM_CHANNEL_1X_ENTRY_PARAM1_DEVICE_PROVIDER_INDEX_MASK 0xFF +#define NV_VBIOS_THERM_CHANNEL_1X_ENTRY_PARAM1_DEVICE_PROVIDER_INDEX_SHIFT 0 + +/* Frequency Controller Table */ +struct vbios_fct_1x_header { + u8 version; + u8 header_size; + u8 entry_size; + u8 entry_count; + u16 sampling_period_ms; +} __packed; + +struct vbios_fct_1x_entry { + u8 flags0; + u8 clk_domain_idx; + u16 param0; + u16 param1; + u32 param2; + u32 param3; + u32 param4; + u32 param5; + u32 param6; + u32 param7; + u32 param8; +} __packed; + +#define NV_VBIOS_FCT_1X_ENTRY_FLAGS0_TYPE_MASK GENMASK(3, 0) +#define NV_VBIOS_FCT_1X_ENTRY_FLAGS0_TYPE_SHIFT 0 +#define NV_VBIOS_FCT_1X_ENTRY_FLAGS0_TYPE_DISABLED 0x0 +#define NV_VBIOS_FCT_1X_ENTRY_FLAGS0_TYPE_PI 0x1 + +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_MASK GENMASK(7, 0) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_SHIFT 0 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_SYS 0x00 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_LTC 0x01 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_XBAR 0x02 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_GPC0 0x03 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_GPC1 0x04 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_GPC2 0x05 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_GPC3 0x06 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_GPC4 0x07 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_GPC5 0x08 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_ID_GPCS 0x09 + +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_FREQ_MODE_MASK GENMASK(9, 8) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_FREQ_MODE_SHIFT 8 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_FREQ_MODE_BCAST 0x0 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_FREQ_MODE_MIN 0x1 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_FREQ_MODE_MAX 0x2 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM0_FREQ_MODE_AVG 0x3 + +#define NV_VBIOS_FCT_1X_ENTRY_PARAM1_SLOWDOWN_PCT_MIN_MASK GENMASK(7, 0) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM1_SLOWDOWN_PCT_MIN_SHIFT 0 + +#define NV_VBIOS_FCT_1X_ENTRY_PARAM1_POISON_MASK GENMASK(8, 8) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM1_POISON_SHIFT 8 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM1_POISON_NO 0x0 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM1_POISON_YES 0x1 + +#define NV_VBIOS_FCT_1X_ENTRY_PARAM2_PROP_GAIN_MASK GENMASK(31, 0) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM2_PROP_GAIN_SHIFT 0 + +#define NV_VBIOS_FCT_1X_ENTRY_PARAM3_INTEG_GAIN_MASK GENMASK(31, 0) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM3_INTEG_GAIN_SHIFT 0 + + +#define NV_VBIOS_FCT_1X_ENTRY_PARAM4_INTEG_DECAY_MASK GENMASK(31, 0) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM4_INTEG_DECAY_SHIFT 0 + +#define NV_VBIOS_FCT_1X_ENTRY_PARAM5_VOLT_DELTA_MIN_MASK GENMASK(31, 0) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM5_VOLT_DELTA_MIN_SHIFT 0 + + +#define NV_VBIOS_FCT_1X_ENTRY_PARAM6_VOLT_DELTA_MAX_MASK GENMASK(31, 0) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM6_VOLT_DELTA_MAX_SHIFT 0 + +#define NV_VBIOS_FCT_1X_ENTRY_PARAM7_FREQ_CAP_VF_MASK GENMASK(15, 0) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM7_FREQ_CAP_VF_SHIFT 0 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM7_FREQ_CAP_VMIN_MASK GENMASK(31, 16) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM7_FREQ_CAP_VMIN_SHIFT 16 + +#define NV_VBIOS_FCT_1X_ENTRY_PARAM8_FREQ_HYST_POS_MASK GENMASK(15, 0) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM8_FREQ_HYST_POS_SHIFT 0 +#define NV_VBIOS_FCT_1X_ENTRY_PARAM8_FREQ_HYST_NEG_MASK GENMASK(31, 16) +#define NV_VBIOS_FCT_1X_ENTRY_PARAM8_FREQ_HYST_NEG_SHIFT 16 + +/* LPWR Index Table */ +struct nvgpu_bios_lpwr_idx_table_1x_header { + u8 version; + u8 header_size; + u8 entry_size; + u8 entry_count; + u16 base_sampling_period; +} __packed; + +struct nvgpu_bios_lpwr_idx_table_1x_entry { + u8 pcie_idx; + u8 gr_idx; + u8 ms_idx; + u8 di_idx; + u8 gc6_idx; +} __packed; + +/* LPWR MS Table*/ +struct nvgpu_bios_lpwr_ms_table_1x_header { + u8 version; + u8 header_size; + u8 entry_size; + u8 entry_count; + u8 default_entry_idx; + u16 idle_threshold_us; +} __packed; + +struct nvgpu_bios_lpwr_ms_table_1x_entry { + u32 feautre_mask; + u16 dynamic_current_logic; + u16 dynamic_current_sram; +} __packed; + +#define NV_VBIOS_LPWR_MS_FEATURE_MASK_MS_MASK GENMASK(0, 0) +#define NV_VBIOS_LPWR_MS_FEATURE_MASK_MS_SHIFT 0 +#define NV_VBIOS_LPWR_MS_FEATURE_MASK_MS_SWASR_MASK GENMASK(2, 2) +#define NV_VBIOS_LPWR_MS_FEATURE_MASK_MS_SWASR_SHIFT 2 +#define NV_VBIOS_LPWR_MS_FEATURE_MASK_MS_CLOCK_GATING_MASK \ + GENMASK(3, 3) +#define NV_VBIOS_LPWR_MS_FEATURE_MASK_MS_CLOCK_GATING_SHIFT 3 +#define NV_VBIOS_LPWR_MS_FEATURE_MASK_MS_RPPG_MASK GENMASK(5, 5) +#define NV_VBIOS_LPWR_MS_FEATURE_MASK_MS_RPPG_SHIFT 5 + +/* LPWR GR Table */ +struct nvgpu_bios_lpwr_gr_table_1x_header { + u8 version; + u8 header_size; + u8 entry_size; + u8 entry_count; + u8 default_entry_idx; + u16 idle_threshold_us; + u8 adaptive_gr_multiplier; +} __packed; + +struct nvgpu_bios_lpwr_gr_table_1x_entry { + u32 feautre_mask; +} __packed; + +#define NV_VBIOS_LPWR_GR_FEATURE_MASK_GR_MASK GENMASK(0, 0) +#define NV_VBIOS_LPWR_GR_FEATURE_MASK_GR_SHIFT 0 + +#define NV_VBIOS_LPWR_GR_FEATURE_MASK_GR_RPPG_MASK GENMASK(4, 4) +#define NV_VBIOS_LPWR_GR_FEATURE_MASK_GR_RPPG_SHIFT 4 +int nvgpu_bios_parse_rom(struct gk20a *g); +u8 nvgpu_bios_read_u8(struct gk20a *g, u32 offset); +s8 nvgpu_bios_read_s8(struct gk20a *g, u32 offset); +u16 nvgpu_bios_read_u16(struct gk20a *g, u32 offset); +u32 nvgpu_bios_read_u32(struct gk20a *g, u32 offset); +void *nvgpu_bios_get_perf_table_ptrs(struct gk20a *g, + struct bit_token *ptoken, u8 table_id); +int nvgpu_bios_execute_script(struct gk20a *g, u32 offset); +u32 nvgpu_bios_get_nvlink_config_data(struct gk20a *g); +#endif diff --git a/include/nvgpu/bitops.h b/include/nvgpu/bitops.h new file mode 100644 index 0000000..00336d0 --- /dev/null +++ b/include/nvgpu/bitops.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_BITOPS_H +#define NVGPU_BITOPS_H + +#include + +/* + * Explicit sizes for bit definitions. Please use these instead of BIT(). + */ +#define BIT8(i) (U8(1) << (i)) +#define BIT16(i) (U16(1) << (i)) +#define BIT32(i) (U32(1) << (i)) +#define BIT64(i) (U64(1) << (i)) + +#ifdef __KERNEL__ +#include +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +#endif /* NVGPU_BITOPS_H */ diff --git a/include/nvgpu/bsearch.h b/include/nvgpu/bsearch.h new file mode 100644 index 0000000..46a2d04 --- /dev/null +++ b/include/nvgpu/bsearch.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_BSEARCH_H +#define NVGPU_BSEARCH_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#endif + +#endif /*NVGPU_BSEARCH_H*/ diff --git a/include/nvgpu/bug.h b/include/nvgpu/bug.h new file mode 100644 index 0000000..3d139b7 --- /dev/null +++ b/include/nvgpu/bug.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_BUG_H +#define NVGPU_BUG_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +#endif /* NVGPU_BUG_H */ diff --git a/include/nvgpu/channel.h b/include/nvgpu/channel.h new file mode 100644 index 0000000..764d047 --- /dev/null +++ b/include/nvgpu/channel.h @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2018-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_CHANNEL_H +#define NVGPU_CHANNEL_H + +#include +#include +#include +#include +#include +#include +#include + +struct gk20a; +struct dbg_session_gk20a; +struct gk20a_fence; +struct fifo_profile_gk20a; +struct nvgpu_channel_sync; +struct nvgpu_gpfifo_userdata; + +/* Flags to be passed to nvgpu_channel_setup_bind() */ +#define NVGPU_SETUP_BIND_FLAGS_SUPPORT_VPR (1U << 0U) +#define NVGPU_SETUP_BIND_FLAGS_SUPPORT_DETERMINISTIC (1U << 1U) +#define NVGPU_SETUP_BIND_FLAGS_REPLAYABLE_FAULTS_ENABLE (1U << 2U) +#define NVGPU_SETUP_BIND_FLAGS_USERMODE_SUPPORT (1U << 3U) + +/* Flags to be passed to nvgpu_submit_channel_gpfifo() */ +#define NVGPU_SUBMIT_FLAGS_FENCE_WAIT (1U << 0U) +#define NVGPU_SUBMIT_FLAGS_FENCE_GET (1U << 1U) +#define NVGPU_SUBMIT_FLAGS_HW_FORMAT (1U << 2U) +#define NVGPU_SUBMIT_FLAGS_SYNC_FENCE (1U << 3U) +#define NVGPU_SUBMIT_FLAGS_SUPPRESS_WFI (1U << 4U) +#define NVGPU_SUBMIT_FLAGS_SKIP_BUFFER_REFCOUNTING (1U << 5U) + +/* + * The binary format of 'struct nvgpu_channel_fence' introduced here + * should match that of 'struct nvgpu_fence' defined in uapi header, since + * this struct is intended to be a mirror copy of the uapi struct. This is + * not a hard requirement though because of nvgpu_get_fence_args conversion + * function. + */ +struct nvgpu_channel_fence { + u32 id; + u32 value; +}; + +/* + * The binary format of 'struct nvgpu_gpfifo_entry' introduced here + * should match that of 'struct nvgpu_gpfifo' defined in uapi header, since + * this struct is intended to be a mirror copy of the uapi struct. This is + * a rigid requirement because there's no conversion function and there are + * memcpy's present between the user gpfifo (of type nvgpu_gpfifo) and the + * kern gpfifo (of type nvgpu_gpfifo_entry). + */ +struct nvgpu_gpfifo_entry { + u32 entry0; + u32 entry1; +}; + +struct gpfifo_desc { + struct nvgpu_mem mem; + u32 entry_num; + + u32 get; + u32 put; + + bool wrap; + + /* if gpfifo lives in vidmem or is forced to go via PRAMIN, first copy + * from userspace to pipe and then from pipe to gpu buffer */ + void *pipe; +}; + +struct nvgpu_setup_bind_args { + u32 num_gpfifo_entries; + u32 num_inflight_jobs; + u32 userd_dmabuf_fd; + u64 userd_dmabuf_offset; + u32 gpfifo_dmabuf_fd; + u64 gpfifo_dmabuf_offset; + u32 work_submit_token; + u32 flags; +}; + +struct notification { + struct { + u32 nanoseconds[2]; + } timestamp; + u32 info32; + u16 info16; + u16 status; +}; + +struct priv_cmd_queue { + struct nvgpu_mem mem; + u32 size; /* num of entries in words */ + u32 put; /* put for priv cmd queue */ + u32 get; /* get for priv cmd queue */ +}; + +struct priv_cmd_entry { + bool valid; + struct nvgpu_mem *mem; + u32 off; /* offset in mem, in u32 entries */ + u64 gva; + u32 get; /* start of entry in queue */ + u32 size; /* in words */ +}; + +struct channel_gk20a_job { + struct nvgpu_mapped_buf **mapped_buffers; + int num_mapped_buffers; + struct gk20a_fence *post_fence; + struct priv_cmd_entry *wait_cmd; + struct priv_cmd_entry *incr_cmd; + struct nvgpu_list_node list; +}; + +static inline struct channel_gk20a_job * +channel_gk20a_job_from_list(struct nvgpu_list_node *node) +{ + return (struct channel_gk20a_job *) + ((uintptr_t)node - offsetof(struct channel_gk20a_job, list)); +}; + +struct channel_gk20a_joblist { + struct { + bool enabled; + unsigned int length; + unsigned int put; + unsigned int get; + struct channel_gk20a_job *jobs; + struct nvgpu_mutex read_lock; + } pre_alloc; + + struct { + struct nvgpu_list_node jobs; + struct nvgpu_spinlock lock; + } dynamic; + + /* + * Synchronize abort cleanup (when closing a channel) and job cleanup + * (asynchronously from worker) - protect from concurrent access when + * job resources are being freed. + */ + struct nvgpu_mutex cleanup_lock; +}; + +struct channel_gk20a_timeout { + /* lock protects the running timer state */ + struct nvgpu_spinlock lock; + struct nvgpu_timeout timer; + bool running; + u32 gp_get; + u64 pb_get; + + /* lock not needed */ + u32 limit_ms; + bool enabled; + bool debug_dump; +}; + +/* + * Track refcount actions, saving their stack traces. This number specifies how + * many most recent actions are stored in a buffer. Set to 0 to disable. 128 + * should be enough to track moderately hard problems from the start. + */ +#define GK20A_CHANNEL_REFCOUNT_TRACKING 0 +/* Stack depth for the saved actions. */ +#define GK20A_CHANNEL_REFCOUNT_TRACKING_STACKLEN 8 + +/* + * Because the puts and gets are not linked together explicitly (although they + * should always come in pairs), it's not possible to tell which ref holder to + * delete from the list when doing a put. So, just store some number of most + * recent gets and puts in a ring buffer, to obtain a history. + * + * These are zeroed when a channel is closed, so a new one starts fresh. + */ + +enum channel_gk20a_ref_action_type { + channel_gk20a_ref_action_get, + channel_gk20a_ref_action_put +}; + +#if GK20A_CHANNEL_REFCOUNT_TRACKING + +#include + +struct channel_gk20a_ref_action { + enum channel_gk20a_ref_action_type type; + s64 timestamp_ms; + /* + * Many of these traces will be similar. Simpler to just capture + * duplicates than to have a separate database for the entries. + */ + struct stack_trace trace; + unsigned long trace_entries[GK20A_CHANNEL_REFCOUNT_TRACKING_STACKLEN]; +}; +#endif + +/* this is the priv element of struct nvhost_channel */ +struct channel_gk20a { + struct gk20a *g; /* set only when channel is active */ + + struct nvgpu_list_node free_chs; + + struct nvgpu_spinlock ref_obtain_lock; + nvgpu_atomic_t ref_count; + struct nvgpu_cond ref_count_dec_wq; +#if GK20A_CHANNEL_REFCOUNT_TRACKING + /* + * Ring buffer for most recent refcount gets and puts. Protected by + * ref_actions_lock when getting or putting refs (i.e., adding + * entries), and when reading entries. + */ + struct channel_gk20a_ref_action ref_actions[ + GK20A_CHANNEL_REFCOUNT_TRACKING]; + size_t ref_actions_put; /* index of next write */ + struct nvgpu_spinlock ref_actions_lock; +#endif + + struct nvgpu_semaphore_int *hw_sema; + + nvgpu_atomic_t bound; + + u32 chid; + u32 tsgid; + pid_t pid; + pid_t tgid; + struct nvgpu_mutex ioctl_lock; + + struct nvgpu_list_node ch_entry; /* channel's entry in TSG */ + + struct channel_gk20a_joblist joblist; + struct nvgpu_allocator fence_allocator; + + struct vm_gk20a *vm; + + struct gpfifo_desc gpfifo; + + struct nvgpu_mem usermode_userd; /* Used for Usermode Submission */ + struct nvgpu_mem usermode_gpfifo; + struct nvgpu_mem inst_block; + + u64 userd_iova; + u64 userd_gpu_va; + + struct priv_cmd_queue priv_cmd_q; + + struct nvgpu_cond notifier_wq; + struct nvgpu_cond semaphore_wq; + + /* kernel watchdog to kill stuck jobs */ + struct channel_gk20a_timeout timeout; + + /* for job cleanup handling in the background worker */ + struct nvgpu_list_node worker_item; + +#if defined(CONFIG_GK20A_CYCLE_STATS) + struct { + void *cyclestate_buffer; + u32 cyclestate_buffer_size; + struct nvgpu_mutex cyclestate_buffer_mutex; + } cyclestate; + + struct nvgpu_mutex cs_client_mutex; + struct gk20a_cs_snapshot_client *cs_client; +#endif + struct nvgpu_mutex dbg_s_lock; + struct nvgpu_list_node dbg_s_list; + + struct nvgpu_mutex sync_lock; + struct nvgpu_channel_sync *sync; + struct nvgpu_channel_sync *user_sync; + +#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION + u64 virt_ctx; +#endif + + struct nvgpu_mem ctx_header; + + struct nvgpu_spinlock ch_timedout_lock; + bool ch_timedout; + /* Any operating system specific data. */ + void *os_priv; + + u32 obj_class; /* we support only one obj per channel */ + + u32 timeout_accumulated_ms; + u32 timeout_gpfifo_get; + + u32 subctx_id; + u32 runqueue_sel; + + u32 timeout_ms_max; + u32 runlist_id; + + bool mmu_nack_handled; + bool referenceable; + bool vpr; + bool deterministic; + /* deterministic, but explicitly idle and submits disallowed */ + bool deterministic_railgate_allowed; + bool cde; + bool usermode_submit_enabled; + bool timeout_debug_dump; + bool has_os_fence_framework_support; + + bool is_privileged_channel; + + /** + * MMU Debugger Mode is enabled for this channel if refcnt > 0 + */ + u32 mmu_debug_mode_refcnt; +}; + +static inline struct channel_gk20a * +channel_gk20a_from_free_chs(struct nvgpu_list_node *node) +{ + return (struct channel_gk20a *) + ((uintptr_t)node - offsetof(struct channel_gk20a, free_chs)); +}; + +static inline struct channel_gk20a * +channel_gk20a_from_ch_entry(struct nvgpu_list_node *node) +{ + return (struct channel_gk20a *) + ((uintptr_t)node - offsetof(struct channel_gk20a, ch_entry)); +}; + +static inline struct channel_gk20a * +channel_gk20a_from_worker_item(struct nvgpu_list_node *node) +{ + return (struct channel_gk20a *) + ((uintptr_t)node - offsetof(struct channel_gk20a, worker_item)); +}; + +static inline bool gk20a_channel_as_bound(struct channel_gk20a *ch) +{ + return !!ch->vm; +} +int channel_gk20a_commit_va(struct channel_gk20a *c); +int gk20a_init_channel_support(struct gk20a *, u32 chid); + +/* must be inside gk20a_busy()..gk20a_idle() */ +void gk20a_channel_close(struct channel_gk20a *ch); +void __gk20a_channel_kill(struct channel_gk20a *ch); + +bool gk20a_channel_update_and_check_timeout(struct channel_gk20a *ch, + u32 timeout_delta_ms, bool *progress); +void gk20a_disable_channel(struct channel_gk20a *ch); +void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt); +void gk20a_channel_abort_clean_up(struct channel_gk20a *ch); +void gk20a_channel_semaphore_wakeup(struct gk20a *g, bool post_events); +int gk20a_channel_alloc_priv_cmdbuf(struct channel_gk20a *c, u32 size, + struct priv_cmd_entry *entry); +int gk20a_free_priv_cmdbuf(struct channel_gk20a *c, struct priv_cmd_entry *e); + +int gk20a_enable_channel_tsg(struct gk20a *g, struct channel_gk20a *ch); +int gk20a_disable_channel_tsg(struct gk20a *g, struct channel_gk20a *ch); + +int gk20a_channel_suspend(struct gk20a *g); +int gk20a_channel_resume(struct gk20a *g); + +void gk20a_channel_deterministic_idle(struct gk20a *g); +void gk20a_channel_deterministic_unidle(struct gk20a *g); + +int nvgpu_channel_worker_init(struct gk20a *g); +void nvgpu_channel_worker_deinit(struct gk20a *g); + +struct channel_gk20a *gk20a_get_channel_from_file(int fd); +void gk20a_channel_update(struct channel_gk20a *c); + +/* returns ch if reference was obtained */ +struct channel_gk20a *__must_check _gk20a_channel_get(struct channel_gk20a *ch, + const char *caller); +#define gk20a_channel_get(ch) _gk20a_channel_get(ch, __func__) + + +void _gk20a_channel_put(struct channel_gk20a *ch, const char *caller); +#define gk20a_channel_put(ch) _gk20a_channel_put(ch, __func__) + +/* returns NULL if could not take a ref to the channel */ +struct channel_gk20a *__must_check _gk20a_channel_from_id(struct gk20a *g, + u32 chid, const char *caller); +#define gk20a_channel_from_id(g, chid) _gk20a_channel_from_id(g, chid, __func__) + +int gk20a_wait_channel_idle(struct channel_gk20a *ch); + +/* runlist_id -1 is synonym for ENGINE_GR_GK20A runlist id */ +struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g, + s32 runlist_id, + bool is_privileged_channel, + pid_t pid, pid_t tid); + +int nvgpu_channel_setup_bind(struct channel_gk20a *c, + struct nvgpu_setup_bind_args *args); + +void gk20a_channel_timeout_restart_all_channels(struct gk20a *g); + +bool channel_gk20a_is_prealloc_enabled(struct channel_gk20a *c); +void channel_gk20a_joblist_lock(struct channel_gk20a *c); +void channel_gk20a_joblist_unlock(struct channel_gk20a *c); +bool channel_gk20a_joblist_is_empty(struct channel_gk20a *c); + +int channel_gk20a_update_runlist(struct channel_gk20a *c, bool add); +int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g, + unsigned int timeslice_period, + unsigned int *__timeslice_timeout, unsigned int *__timeslice_scale); + +void gk20a_wait_until_counter_is_N( + struct channel_gk20a *ch, nvgpu_atomic_t *counter, int wait_value, + struct nvgpu_cond *c, const char *caller, const char *counter_name); +int channel_gk20a_alloc_job(struct channel_gk20a *c, + struct channel_gk20a_job **job_out); +void channel_gk20a_free_job(struct channel_gk20a *c, + struct channel_gk20a_job *job); +u32 nvgpu_get_gp_free_count(struct channel_gk20a *c); +u32 nvgpu_gp_free_count(struct channel_gk20a *c); +int gk20a_channel_add_job(struct channel_gk20a *c, + struct channel_gk20a_job *job, + bool skip_buffer_refcounting); +void free_priv_cmdbuf(struct channel_gk20a *c, + struct priv_cmd_entry *e); +void gk20a_channel_clean_up_jobs(struct channel_gk20a *c, + bool clean_all); + +void gk20a_channel_free_usermode_buffers(struct channel_gk20a *c); +u32 nvgpu_get_gpfifo_entry_size(void); + +int nvgpu_submit_channel_gpfifo_user(struct channel_gk20a *c, + struct nvgpu_gpfifo_userdata userdata, + u32 num_entries, + u32 flags, + struct nvgpu_channel_fence *fence, + struct gk20a_fence **fence_out, + struct fifo_profile_gk20a *profile); + +int nvgpu_submit_channel_gpfifo_kernel(struct channel_gk20a *c, + struct nvgpu_gpfifo_entry *gpfifo, + u32 num_entries, + u32 flags, + struct nvgpu_channel_fence *fence, + struct gk20a_fence **fence_out); + +#ifdef CONFIG_DEBUG_FS +void trace_write_pushbuffers(struct channel_gk20a *c, u32 count); +#else +static inline void trace_write_pushbuffers(struct channel_gk20a *c, u32 count) +{ +} +#endif + +void gk20a_channel_set_timedout(struct channel_gk20a *ch); +bool gk20a_channel_check_timedout(struct channel_gk20a *ch); + +#endif diff --git a/include/nvgpu/channel_sync.h b/include/nvgpu/channel_sync.h new file mode 100644 index 0000000..f0b2b86 --- /dev/null +++ b/include/nvgpu/channel_sync.h @@ -0,0 +1,113 @@ +/* + * + * Nvgpu Channel Synchronization Abstraction + * + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_CHANNEL_SYNC_H +#define NVGPU_CHANNEL_SYNC_H + +#include + +struct nvgpu_channel_sync; +struct priv_cmd_entry; +struct channel_gk20a; +struct gk20a_fence; +struct gk20a; +struct nvgpu_semaphore; + +struct nvgpu_channel_sync { + nvgpu_atomic_t refcount; + + /* Generate a gpu wait cmdbuf from syncpoint. + * Returns a gpu cmdbuf that performs the wait when executed + */ + int (*wait_syncpt)(struct nvgpu_channel_sync *s, u32 id, u32 thresh, + struct priv_cmd_entry *entry); + + /* Generate a gpu wait cmdbuf from sync fd. + * Returns a gpu cmdbuf that performs the wait when executed + */ + int (*wait_fd)(struct nvgpu_channel_sync *s, int fd, + struct priv_cmd_entry *entry, int max_wait_cmds); + + /* Increment syncpoint/semaphore. + * Returns + * - a gpu cmdbuf that performs the increment when executed, + * - a fence that can be passed to wait_cpu() and is_expired(). + */ + int (*incr)(struct nvgpu_channel_sync *s, + struct priv_cmd_entry *entry, + struct gk20a_fence *fence, + bool need_sync_fence, + bool register_irq); + + /* Increment syncpoint/semaphore, so that the returned fence represents + * work completion (may need wfi) and can be returned to user space. + * Returns + * - a gpu cmdbuf that performs the increment when executed, + * - a fence that can be passed to wait_cpu() and is_expired(), + * - a gk20a_fence that signals when the incr has happened. + */ + int (*incr_user)(struct nvgpu_channel_sync *s, + int wait_fence_fd, + struct priv_cmd_entry *entry, + struct gk20a_fence *fence, + bool wfi, + bool need_sync_fence, + bool register_irq); + + /* Reset the channel syncpoint/semaphore. */ + void (*set_min_eq_max)(struct nvgpu_channel_sync *s); + + /* + * Set the channel syncpoint/semaphore to safe state + * This should be used to reset User managed syncpoint since we don't + * track threshold values for those syncpoints + */ + void (*set_safe_state)(struct nvgpu_channel_sync *s); + + /* Returns the sync point id or negative number if no syncpt*/ + int (*syncpt_id)(struct nvgpu_channel_sync *s); + + /* Returns the sync point address of sync point or 0 if not supported */ + u64 (*syncpt_address)(struct nvgpu_channel_sync *s); + + /* Free the resources allocated by nvgpu_channel_sync_create. */ + void (*destroy)(struct nvgpu_channel_sync *s); +}; + +void channel_sync_semaphore_gen_wait_cmd(struct channel_gk20a *c, + struct nvgpu_semaphore *sema, struct priv_cmd_entry *wait_cmd, + u32 wait_cmd_size, u32 pos); + +int channel_sync_syncpt_gen_wait_cmd(struct channel_gk20a *c, + u32 id, u32 thresh, struct priv_cmd_entry *wait_cmd, + u32 wait_cmd_size, u32 pos, bool preallocated); + +void nvgpu_channel_sync_destroy(struct nvgpu_channel_sync *sync, + bool set_safe_state); +struct nvgpu_channel_sync *nvgpu_channel_sync_create(struct channel_gk20a *c, + bool user_managed); +bool nvgpu_channel_sync_needs_os_fence_framework(struct gk20a *g); + +#endif /* NVGPU_CHANNEL_SYNC_H */ diff --git a/include/nvgpu/circ_buf.h b/include/nvgpu/circ_buf.h new file mode 100644 index 0000000..76998ca --- /dev/null +++ b/include/nvgpu/circ_buf.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_CIRC_BUF_H +#define NVGPU_CIRC_BUF_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#endif + +#endif /* NVGPU_CIRC_BUF_H */ diff --git a/include/nvgpu/clk.h b/include/nvgpu/clk.h new file mode 100644 index 0000000..62bb0f9 --- /dev/null +++ b/include/nvgpu/clk.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_CLK_H__ +#define __NVGPU_CLK_H__ + +#define CLK_NAME_MAX 24 + +struct namemap_cfg { + u32 namemap; + u32 is_enable; /* Namemap enabled */ + u32 is_counter; /* Using cntr */ + struct gk20a *g; + struct { + u32 reg_ctrl_addr; + u32 reg_ctrl_idx; + u32 reg_cntr_addr; + } cntr; + u32 scale; + char name[CLK_NAME_MAX]; +}; + +#endif diff --git a/include/nvgpu/clk_arb.h b/include/nvgpu/clk_arb.h new file mode 100644 index 0000000..43af631 --- /dev/null +++ b/include/nvgpu/clk_arb.h @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_CLK_ARB_H +#define NVGPU_CLK_ARB_H + +struct gk20a; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk/clk.h" +#include "pstate/pstate.h" +#include "lpwr/lpwr.h" +#include "volt/volt.h" + +#define MAX_F_POINTS 256 +#define DEFAULT_EVENT_NUMBER 32 + +struct nvgpu_clk_dev; +struct nvgpu_clk_arb_target; +struct nvgpu_clk_notification_queue; +struct nvgpu_clk_session; + +#define VF_POINT_INVALID_PSTATE ~0U +#define VF_POINT_SET_PSTATE_SUPPORTED(a, b) ((a)->pstates |= (1UL << (b))) +#define VF_POINT_GET_PSTATE(a) (((a)->pstates) ?\ + __fls((a)->pstates) :\ + VF_POINT_INVALID_PSTATE) +#define VF_POINT_COMMON_PSTATE(a, b) (((a)->pstates & (b)->pstates) ?\ + __fls((a)->pstates & (b)->pstates) :\ + VF_POINT_INVALID_PSTATE) + +/* + * These events, defined in common code are the counterparts of the uapi + * events. There should be a conversion function to take care to convert + * these to the uapi events. + */ +/* Event associated to a VF update */ +#define NVGPU_EVENT_VF_UPDATE 0 + +/* Recoverable alarms (POLLPRI) */ +/* Alarm when target frequency on any session is not possible */ +#define NVGPU_EVENT_ALARM_TARGET_VF_NOT_POSSIBLE 1 +/* Alarm when target frequency on current session is not possible */ +#define NVGPU_EVENT_ALARM_LOCAL_TARGET_VF_NOT_POSSIBLE 2 +/* Alarm when Clock Arbiter failed */ +#define NVGPU_EVENT_ALARM_CLOCK_ARBITER_FAILED 3 +/* Alarm when VF table update failed */ +#define NVGPU_EVENT_ALARM_VF_TABLE_UPDATE_FAILED 4 +/* Alarm on thermal condition */ +#define NVGPU_EVENT_ALARM_THERMAL_ABOVE_THRESHOLD 5 +/* Alarm on power condition */ +#define NVGPU_EVENT_ALARM_POWER_ABOVE_THRESHOLD 6 + +/* Non recoverable alarm (POLLHUP) */ +/* Alarm on GPU shutdown/fall from bus */ +#define NVGPU_EVENT_ALARM_GPU_LOST 7 + +#define NVGPU_EVENT_LAST NVGPU_EVENT_ALARM_GPU_LOST + +/* Local Alarms */ +#define EVENT(alarm) (0x1UL << NVGPU_EVENT_##alarm) + +#define LOCAL_ALARM_MASK (EVENT(ALARM_LOCAL_TARGET_VF_NOT_POSSIBLE) | \ + EVENT(VF_UPDATE)) + +#define _WRAPGTEQ(a, b) ((a-b) > 0) + +/* + * NVGPU_POLL* defines equivalent to the POLL* linux defines + */ +#define NVGPU_POLLIN (1 << 0) +#define NVGPU_POLLPRI (1 << 1) +#define NVGPU_POLLOUT (1 << 2) +#define NVGPU_POLLRDNORM (1 << 3) +#define NVGPU_POLLHUP (1 << 4) + +/* NVGPU_CLK_DOMAIN_* defines equivalent to NVGPU_GPU_CLK_DOMAIN_* + * defines in uapi header + */ +/* Memory clock */ +#define NVGPU_CLK_DOMAIN_MCLK (0) +/* Main graphics core clock */ +#define NVGPU_CLK_DOMAIN_GPCCLK (1) + +#define NVGPU_CLK_DOMAIN_MAX (NVGPU_CLK_DOMAIN_GPCCLK) + +#define clk_arb_dbg(g, fmt, args...) \ + do { \ + nvgpu_log(g, gpu_dbg_clk_arb, \ + fmt, ##args); \ + } while (0) + +struct nvgpu_clk_notification { + u32 notification; + u64 timestamp; +}; + +struct nvgpu_clk_notification_queue { + u32 size; + nvgpu_atomic_t head; + nvgpu_atomic_t tail; + struct nvgpu_clk_notification *notifications; +}; + +struct nvgpu_clk_vf_point { + u16 pstates; + union { + struct { + u16 gpc_mhz; + u16 sys_mhz; + u16 xbar_mhz; + }; + u16 mem_mhz; + }; + u32 uvolt; + u32 uvolt_sram; +}; + +struct nvgpu_clk_vf_table { + u32 mclk_num_points; + struct nvgpu_clk_vf_point *mclk_points; + u32 gpc2clk_num_points; + struct nvgpu_clk_vf_point *gpc2clk_points; +}; +#ifdef CONFIG_DEBUG_FS +struct nvgpu_clk_arb_debug { + s64 switch_max; + s64 switch_min; + u64 switch_num; + s64 switch_avg; + s64 switch_std; +}; +#endif + +struct nvgpu_clk_arb_target { + u16 mclk; + u16 gpc2clk; + u32 pstate; +}; + +enum clk_arb_work_item_type { + CLK_ARB_WORK_UPDATE_VF_TABLE, + CLK_ARB_WORK_UPDATE_ARB +}; + +struct nvgpu_clk_arb_work_item { + enum clk_arb_work_item_type item_type; + struct nvgpu_clk_arb *arb; + struct nvgpu_list_node worker_item; +}; + +struct nvgpu_clk_arb { + struct nvgpu_spinlock sessions_lock; + struct nvgpu_spinlock users_lock; + struct nvgpu_spinlock requests_lock; + + struct nvgpu_mutex pstate_lock; + struct nvgpu_list_node users; + struct nvgpu_list_node sessions; + struct nvgpu_list_node requests; + + struct gk20a *g; + int status; + + struct nvgpu_clk_arb_target actual_pool[2]; + struct nvgpu_clk_arb_target *actual; + + u16 gpc2clk_default_mhz; + u16 mclk_default_mhz; + u32 voltuv_actual; + + u16 gpc2clk_min, gpc2clk_max; + u16 mclk_min, mclk_max; + + struct nvgpu_clk_arb_work_item update_vf_table_work_item; + struct nvgpu_clk_arb_work_item update_arb_work_item; + + struct nvgpu_cond request_wq; + + struct nvgpu_clk_vf_table *current_vf_table; + struct nvgpu_clk_vf_table vf_table_pool[2]; + u32 vf_table_index; + + u16 *mclk_f_points; + nvgpu_atomic_t req_nr; + + u32 mclk_f_numpoints; + u16 *gpc2clk_f_points; + u32 gpc2clk_f_numpoints; + + bool clk_arb_events_supported; + + nvgpu_atomic64_t alarm_mask; + struct nvgpu_clk_notification_queue notification_queue; + +#ifdef CONFIG_DEBUG_FS + struct nvgpu_clk_arb_debug debug_pool[2]; + struct nvgpu_clk_arb_debug *debug; + bool debugfs_set; +#endif +}; + +struct nvgpu_clk_dev { + struct nvgpu_clk_session *session; + union { + struct nvgpu_list_node link; + struct nvgpu_list_node node; + }; + struct nvgpu_cond readout_wq; + nvgpu_atomic_t poll_mask; + u16 gpc2clk_target_mhz; + u16 mclk_target_mhz; + u32 alarms_reported; + nvgpu_atomic_t enabled_mask; + struct nvgpu_clk_notification_queue queue; + u32 arb_queue_head; + struct nvgpu_ref refcount; +}; + +struct nvgpu_clk_session { + bool zombie; + struct gk20a *g; + struct nvgpu_ref refcount; + struct nvgpu_list_node link; + struct nvgpu_list_node targets; + + struct nvgpu_spinlock session_lock; + struct nvgpu_clk_arb_target target_pool[2]; + struct nvgpu_clk_arb_target *target; +}; + +static inline struct nvgpu_clk_session * +nvgpu_clk_session_from_link(struct nvgpu_list_node *node) +{ + return (struct nvgpu_clk_session *) + ((uintptr_t)node - offsetof(struct nvgpu_clk_session, link)); +}; + +static inline struct nvgpu_clk_dev * +nvgpu_clk_dev_from_node(struct nvgpu_list_node *node) +{ + return (struct nvgpu_clk_dev *) + ((uintptr_t)node - offsetof(struct nvgpu_clk_dev, node)); +}; + +static inline struct nvgpu_clk_dev * +nvgpu_clk_dev_from_link(struct nvgpu_list_node *node) +{ + return (struct nvgpu_clk_dev *) + ((uintptr_t)node - offsetof(struct nvgpu_clk_dev, link)); +}; + +static inline struct nvgpu_clk_arb_work_item * +nvgpu_clk_arb_work_item_from_worker_item(struct nvgpu_list_node *node) +{ + return (struct nvgpu_clk_arb_work_item *) + ((uintptr_t)node - offsetof(struct nvgpu_clk_arb_work_item, worker_item)); +}; + +void nvgpu_clk_arb_worker_enqueue(struct gk20a *g, + struct nvgpu_clk_arb_work_item *work_item); + +int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb); + +int nvgpu_clk_arb_worker_init(struct gk20a *g); + +int nvgpu_clk_arb_init_arbiter(struct gk20a *g); + +bool nvgpu_clk_arb_has_active_req(struct gk20a *g); + +int nvgpu_clk_arb_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, + u16 *min_mhz, u16 *max_mhz); + +int nvgpu_clk_arb_get_arbiter_actual_mhz(struct gk20a *g, + u32 api_domain, u16 *actual_mhz); + +int nvgpu_clk_arb_get_arbiter_effective_mhz(struct gk20a *g, + u32 api_domain, u16 *effective_mhz); + +int nvgpu_clk_arb_get_arbiter_clk_f_points(struct gk20a *g, + u32 api_domain, u32 *max_points, u16 *fpoints); + +u32 nvgpu_clk_arb_get_arbiter_clk_domains(struct gk20a *g); +bool nvgpu_clk_arb_is_valid_domain(struct gk20a *g, u32 api_domain); + +void nvgpu_clk_arb_cleanup_arbiter(struct gk20a *g); + +int nvgpu_clk_arb_install_session_fd(struct gk20a *g, + struct nvgpu_clk_session *session); + +int nvgpu_clk_arb_init_session(struct gk20a *g, + struct nvgpu_clk_session **_session); + +void nvgpu_clk_arb_release_session(struct gk20a *g, + struct nvgpu_clk_session *session); + +int nvgpu_clk_arb_commit_request_fd(struct gk20a *g, + struct nvgpu_clk_session *session, int request_fd); + +int nvgpu_clk_arb_set_session_target_mhz(struct nvgpu_clk_session *session, + int fd, u32 api_domain, u16 target_mhz); + +int nvgpu_clk_arb_get_session_target_mhz(struct nvgpu_clk_session *session, + u32 api_domain, u16 *target_mhz); + +int nvgpu_clk_arb_install_event_fd(struct gk20a *g, + struct nvgpu_clk_session *session, int *event_fd, u32 alarm_mask); + +int nvgpu_clk_arb_install_request_fd(struct gk20a *g, + struct nvgpu_clk_session *session, int *event_fd); + +void nvgpu_clk_arb_schedule_vf_table_update(struct gk20a *g); + +int nvgpu_clk_arb_get_current_pstate(struct gk20a *g); + +void nvgpu_clk_arb_pstate_change_lock(struct gk20a *g, bool lock); + +void nvgpu_clk_arb_send_thermal_alarm(struct gk20a *g); + +void nvgpu_clk_arb_set_global_alarm(struct gk20a *g, u32 alarm); + +void nvgpu_clk_arb_schedule_alarm(struct gk20a *g, u32 alarm); + +void nvgpu_clk_arb_clear_global_alarm(struct gk20a *g, u32 alarm); + +void nvgpu_clk_arb_free_session(struct nvgpu_ref *refcount); + +void nvgpu_clk_arb_free_fd(struct nvgpu_ref *refcount); + +u32 nvgpu_clk_arb_notify(struct nvgpu_clk_dev *dev, + struct nvgpu_clk_arb_target *target, + u32 alarm); + +int nvgpu_clk_notification_queue_alloc(struct gk20a *g, + struct nvgpu_clk_notification_queue *queue, + size_t events_number); + +void nvgpu_clk_notification_queue_free(struct gk20a *g, + struct nvgpu_clk_notification_queue *queue); + +void nvgpu_clk_arb_event_post_event(struct nvgpu_clk_dev *dev); + +unsigned long nvgpu_clk_measure_freq(struct gk20a *g, u32 api_domain); + +#ifdef CONFIG_DEBUG_FS +int nvgpu_clk_arb_debugfs_init(struct gk20a *g); +#endif +#endif /* NVGPU_CLK_ARB_H */ + diff --git a/include/nvgpu/comptags.h b/include/nvgpu/comptags.h new file mode 100644 index 0000000..3df1b6f --- /dev/null +++ b/include/nvgpu/comptags.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_COMPTAGS_H +#define NVGPU_COMPTAGS_H + +#include +#include + +struct gk20a; +struct nvgpu_os_buffer; + +struct gk20a_comptags { + u32 offset; + u32 lines; + + /* + * This signals whether allocation has been attempted. Observe 'lines' + * to see whether the comptags were actually allocated. We try alloc + * only once per buffer in order not to break multiple compressible-kind + * mappings. + */ + bool allocated; + + /* + * Do comptags need to be cleared before mapping? + */ + bool needs_clear; +}; + +struct gk20a_comptag_allocator { + struct gk20a *g; + + struct nvgpu_mutex lock; + + /* This bitmap starts at ctag 1. 0th cannot be taken. */ + unsigned long *bitmap; + + /* Size of bitmap, not max ctags, so one less. */ + unsigned long size; +}; + +/* real size here, but first (ctag 0) isn't used */ +int gk20a_comptag_allocator_init(struct gk20a *g, + struct gk20a_comptag_allocator *allocator, + unsigned long size); +void gk20a_comptag_allocator_destroy(struct gk20a *g, + struct gk20a_comptag_allocator *allocator); + +int gk20a_comptaglines_alloc(struct gk20a_comptag_allocator *allocator, + u32 *offset, u32 len); +void gk20a_comptaglines_free(struct gk20a_comptag_allocator *allocator, + u32 offset, u32 len); + +/* + * Defined by OS specific code since comptags are stored in a highly OS specific + * way. + */ +int gk20a_alloc_or_get_comptags(struct gk20a *g, + struct nvgpu_os_buffer *buf, + struct gk20a_comptag_allocator *allocator, + struct gk20a_comptags *comptags); +void gk20a_get_comptags(struct nvgpu_os_buffer *buf, + struct gk20a_comptags *comptags); + +/* + * These functions must be used to synchronize comptags clear. The usage: + * + * if (gk20a_comptags_start_clear(os_buf)) { + * // we now hold the buffer lock for clearing + * + * bool successful = hw_clear_comptags(); + * + * // mark the buf cleared (or not) and release the buffer lock + * gk20a_comptags_finish_clear(os_buf, successful); + * } + * + * If gk20a_start_comptags_clear() returns false, another caller has + * already cleared the comptags. + */ +bool gk20a_comptags_start_clear(struct nvgpu_os_buffer *buf); +void gk20a_comptags_finish_clear(struct nvgpu_os_buffer *buf, + bool clear_successful); + +#endif /* NVGPU_COMPTAGS_H */ diff --git a/include/nvgpu/cond.h b/include/nvgpu/cond.h new file mode 100644 index 0000000..49e9d1f --- /dev/null +++ b/include/nvgpu/cond.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_COND_H +#define NVGPU_COND_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +/* + * struct nvgpu_cond + * + * Should be implemented per-OS in a separate library + */ +struct nvgpu_cond; + +/** + * nvgpu_cond_init - Initialize a condition variable + * + * @cond - The condition variable to initialize + * + * Initialize a condition variable before using it. + */ +int nvgpu_cond_init(struct nvgpu_cond *cond); + +/** + * nvgpu_cond_signal - Signal a condition variable + * + * @cond - The condition variable to signal + * + * Wake up a waiter for a condition variable to check if its condition has been + * satisfied. + * + * The waiter is using an uninterruptible wait. + */ +int nvgpu_cond_signal(struct nvgpu_cond *cond); + +/** + * nvgpu_cond_signal_interruptible - Signal a condition variable + * + * @cond - The condition variable to signal + * + * Wake up a waiter for a condition variable to check if its condition has been + * satisfied. + * + * The waiter is using an interruptible wait. + */ +int nvgpu_cond_signal_interruptible(struct nvgpu_cond *cond); + +/** + * nvgpu_cond_broadcast - Signal all waiters of a condition variable + * + * @cond - The condition variable to signal + * + * Wake up all waiters for a condition variable to check if their conditions + * have been satisfied. + * + * The waiters are using an uninterruptible wait. + */ +int nvgpu_cond_broadcast(struct nvgpu_cond *cond); + +/** + * nvgpu_cond_broadcast_interruptible - Signal all waiters of a condition + * variable + * + * @cond - The condition variable to signal + * + * Wake up all waiters for a condition variable to check if their conditions + * have been satisfied. + * + * The waiters are using an interruptible wait. + */ +int nvgpu_cond_broadcast_interruptible(struct nvgpu_cond *cond); + +/** + * nvgpu_cond_destroy - Destroy a condition variable + * + * @cond - The condition variable to destroy + */ +void nvgpu_cond_destroy(struct nvgpu_cond *cond); + +#endif /* NVGPU_COND_H */ diff --git a/include/nvgpu/ctxsw_trace.h b/include/nvgpu/ctxsw_trace.h new file mode 100644 index 0000000..033e020 --- /dev/null +++ b/include/nvgpu/ctxsw_trace.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2017-2019, 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_TRACE_H +#define NVGPU_CTXSW_TRACE_H + +#include + +struct gk20a; +struct tsg_gk20a; +struct channel_gk20a; + +#define NVGPU_GPU_CTXSW_TAG_SOF 0x00 +#define NVGPU_GPU_CTXSW_TAG_CTXSW_REQ_BY_HOST 0x01 +#define NVGPU_GPU_CTXSW_TAG_FE_ACK 0x02 +#define NVGPU_GPU_CTXSW_TAG_FE_ACK_WFI 0x0a +#define NVGPU_GPU_CTXSW_TAG_FE_ACK_GFXP 0x0b +#define NVGPU_GPU_CTXSW_TAG_FE_ACK_CTAP 0x0c +#define NVGPU_GPU_CTXSW_TAG_FE_ACK_CILP 0x0d +#define NVGPU_GPU_CTXSW_TAG_SAVE_END 0x03 +#define NVGPU_GPU_CTXSW_TAG_RESTORE_START 0x04 +#define NVGPU_GPU_CTXSW_TAG_CONTEXT_START 0x05 +#define NVGPU_GPU_CTXSW_TAG_ENGINE_RESET 0xfe +#define NVGPU_GPU_CTXSW_TAG_INVALID_TIMESTAMP 0xff +#define NVGPU_GPU_CTXSW_TAG_LAST \ + NVGPU_GPU_CTXSW_TAG_INVALID_TIMESTAMP + +#define NVGPU_GPU_CTXSW_FILTER_ISSET(n, p) \ + ((p)->tag_bits[(n) / 64] & (1 << ((n) & 63))) + +#define NVGPU_GPU_CTXSW_FILTER_SIZE (NVGPU_GPU_CTXSW_TAG_LAST + 1) +#define NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT 31 + +struct nvgpu_gpu_ctxsw_trace_filter { + u64 tag_bits[(NVGPU_GPU_CTXSW_FILTER_SIZE + 63) / 64]; +}; + +/* + * The binary format of 'struct nvgpu_gpu_ctxsw_trace_entry' introduced here + * should match that of 'struct nvgpu_ctxsw_trace_entry' defined in uapi + * header, since this struct is intended to be a mirror copy of the uapi + * struct. + */ +struct nvgpu_gpu_ctxsw_trace_entry { + u8 tag; + u8 vmid; + u16 seqno; /* sequence number to detect drops */ + u32 context_id; /* context_id as allocated by FECS */ + u64 pid; /* 64-bit is max bits of different OS pid */ + u64 timestamp; /* 64-bit time */ +}; + +int gk20a_ctxsw_trace_init(struct gk20a *g); + +void gk20a_ctxsw_trace_channel_reset(struct gk20a *g, struct channel_gk20a *ch); +void gk20a_ctxsw_trace_tsg_reset(struct gk20a *g, struct tsg_gk20a *tsg); + +void gk20a_ctxsw_trace_cleanup(struct gk20a *g); +int gk20a_ctxsw_trace_write(struct gk20a *g, + struct nvgpu_gpu_ctxsw_trace_entry *entry); +void gk20a_ctxsw_trace_wake_up(struct gk20a *g, int vmid); + +#ifdef CONFIG_GK20A_CTXSW_TRACE +struct file; +struct vm_area_struct; + +int gk20a_ctxsw_dev_mmap(struct file *filp, struct vm_area_struct *vma); +int gk20a_ctxsw_dev_ring_alloc(struct gk20a *g, void **buf, size_t *size); +int gk20a_ctxsw_dev_ring_free(struct gk20a *g); +int gk20a_ctxsw_dev_mmap_buffer(struct gk20a *g, struct vm_area_struct *vma); +#endif + +u8 nvgpu_gpu_ctxsw_tags_to_common_tags(u8 tags); + +#endif /*NVGPU_CTXSW_TRACE_H */ diff --git a/include/nvgpu/debug.h b/include/nvgpu/debug.h new file mode 100644 index 0000000..33bf621 --- /dev/null +++ b/include/nvgpu/debug.h @@ -0,0 +1,63 @@ +/* + * GK20A Debug functionality + * + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_DEBUG_H +#define NVGPU_DEBUG_H + +#include + +struct gk20a; +struct gpu_ops; + +struct gk20a_debug_output { + void (*fn)(void *ctx, const char *str, size_t len); + void *ctx; + char buf[256]; +}; + +#ifdef CONFIG_DEBUG_FS +extern unsigned int gk20a_debug_trace_cmdbuf; + +void gk20a_debug_output(struct gk20a_debug_output *o, + const char *fmt, ...); + +void gk20a_debug_dump(struct gk20a *g); +void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o); +int gk20a_gr_debug_dump(struct gk20a *g); +void gk20a_init_debug_ops(struct gpu_ops *gops); + +void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink); +void gk20a_debug_deinit(struct gk20a *g); +#else +static inline void gk20a_debug_output(struct gk20a_debug_output *o, + const char *fmt, ...) {} + +static inline void gk20a_debug_dump(struct gk20a *g) {} +static inline void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o) {} +static inline int gk20a_gr_debug_dump(struct gk20a *g) { return 0;} +static inline void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink) {} +static inline void gk20a_debug_deinit(struct gk20a *g) {} +#endif + +#endif /* NVGPU_DEBUG_H */ diff --git a/include/nvgpu/defaults.h b/include/nvgpu/defaults.h new file mode 100644 index 0000000..cae380a --- /dev/null +++ b/include/nvgpu/defaults.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_DEFAULTS_H__ +#define __NVGPU_DEFAULTS_H__ + +/* + * Default timeout used for channel watchdog and ctxsw timeout. + */ +#define NVGPU_DEFAULT_GR_IDLE_TIMEOUT 3000 + +#define NVGPU_DEFAULT_RAILGATE_IDLE_TIMEOUT 500 + +#endif diff --git a/include/nvgpu/dma.h b/include/nvgpu/dma.h new file mode 100644 index 0000000..cbb829b --- /dev/null +++ b/include/nvgpu/dma.h @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_DMA_H +#define NVGPU_DMA_H + +#include + +struct gk20a; +struct vm_gk20a; +struct nvgpu_mem; + +/* + * Flags for the below nvgpu_dma_{alloc,alloc_map}_flags* + */ + +/* + * Don't create a virtual kernel mapping for the buffer but only allocate it; + * this may save some resources. The buffer can be mapped later explicitly. + */ +#define NVGPU_DMA_NO_KERNEL_MAPPING BIT32(0) + +/* + * Don't allow building the buffer from individual pages but require a + * physically contiguous block. + */ +#define NVGPU_DMA_FORCE_CONTIGUOUS BIT32(1) + +/* + * Make the mapping read-only. + */ +#define NVGPU_DMA_READ_ONLY BIT32(2) + +/** + * nvgpu_iommuable - Check if GPU is behind IOMMU + * + * @g - The GPU. + * + * Returns true if the passed GPU is behind an IOMMU; false otherwise. If the + * GPU is iommuable then the DMA address in nvgpu_mem_sgl is valid. + * + * Note that even if a GPU is behind an IOMMU that does not necessarily mean the + * GPU _must_ use DMA addresses. GPUs may still use physical addresses if it + * makes sense. + */ +bool nvgpu_iommuable(struct gk20a *g); + +/** + * nvgpu_dma_alloc - Allocate DMA memory + * + * @g - The GPU. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA. Store the allocation info in @mem. + * Returns 0 on success and a suitable error code when there's an error. This + * memory can be either placed in VIDMEM or SYSMEM, which ever is more + * convenient for the driver. + */ +int nvgpu_dma_alloc(struct gk20a *g, size_t size, struct nvgpu_mem *mem); + +/** + * nvgpu_dma_alloc_flags - Allocate DMA memory + * + * @g - The GPU. + * @flags - Flags modifying the operation of the DMA allocation. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA. Store the allocation info in @mem. + * Returns 0 on success and a suitable error code when there's an error. This + * memory can be either placed in VIDMEM or SYSMEM, which ever is more + * convenient for the driver. + * + * The following flags are accepted: + * + * %NVGPU_DMA_NO_KERNEL_MAPPING + * %NVGPU_DMA_FORCE_CONTIGUOUS + * %NVGPU_DMA_READ_ONLY + */ +int nvgpu_dma_alloc_flags(struct gk20a *g, unsigned long flags, size_t size, + struct nvgpu_mem *mem); + +/** + * nvgpu_dma_alloc_sys - Allocate DMA memory + * + * @g - The GPU. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA. Store the allocation info in @mem. + * Returns 0 on success and a suitable error code when there's an error. This + * allocates memory specifically in SYSMEM. + */ +int nvgpu_dma_alloc_sys(struct gk20a *g, size_t size, struct nvgpu_mem *mem); + +/** + * nvgpu_dma_alloc_flags_sys - Allocate DMA memory + * + * @g - The GPU. + * @flags - Flags modifying the operation of the DMA allocation. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA. Store the allocation info in @mem. + * Returns 0 on success and a suitable error code when there's an error. This + * allocates memory specifically in SYSMEM. + * + * The following flags are accepted: + * + * %NVGPU_DMA_NO_KERNEL_MAPPING + * %NVGPU_DMA_FORCE_CONTIGUOUS + * %NVGPU_DMA_READ_ONLY + */ +int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem); + +/** + * nvgpu_dma_alloc_vid - Allocate DMA memory + * + * @g - The GPU. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA. Store the allocation info in @mem. + * Returns 0 on success and a suitable error code when there's an error. This + * allocates memory specifically in VIDMEM. + */ +int nvgpu_dma_alloc_vid(struct gk20a *g, size_t size, struct nvgpu_mem *mem); + +/** + * nvgpu_dma_alloc_flags_vid - Allocate DMA memory + * + * @g - The GPU. + * @flags - Flags modifying the operation of the DMA allocation. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA. Store the allocation info in @mem. + * Returns 0 on success and a suitable error code when there's an error. This + * allocates memory specifically in VIDMEM. + * + * Only the following flags are accepted: + * + * %NVGPU_DMA_NO_KERNEL_MAPPING + * + */ +int nvgpu_dma_alloc_flags_vid(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem); + + +/** + * nvgpu_dma_alloc_flags_vid_at - Allocate DMA memory + * + * @g - The GPU. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * @at - A specific location to attempt to allocate memory from or 0 if the + * caller does not care what the address is. + * + * Allocate memory suitable for doing DMA. Store the allocation info in @mem. + * Returns 0 on success and a suitable error code when there's an error. This + * allocates memory specifically in VIDMEM. + * + */ +int nvgpu_dma_alloc_vid_at(struct gk20a *g, + size_t size, struct nvgpu_mem *mem, u64 at); + +/** + * nvgpu_dma_alloc_flags_vid_at - Allocate DMA memory + * + * @g - The GPU. + * @flags - Flags modifying the operation of the DMA allocation. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * @at - A specific location to attempt to allocate memory from or 0 if the + * caller does not care what the address is. + * + * Allocate memory suitable for doing DMA. Store the allocation info in @mem. + * Returns 0 on success and a suitable error code when there's an error. This + * allocates memory specifically in VIDMEM. + * + * Only the following flags are accepted: + * + * %NVGPU_DMA_NO_KERNEL_MAPPING + */ +int nvgpu_dma_alloc_flags_vid_at(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem, u64 at); + +/** + * nvgpu_dma_free - Free a DMA allocation + * + * @g - The GPU. + * @mem - An allocation to free. + * + * Free memory created with any of: + * + * nvgpu_dma_alloc() + * nvgpu_dma_alloc_flags() + * nvgpu_dma_alloc_sys() + * nvgpu_dma_alloc_flags_sys() + * nvgpu_dma_alloc_vid() + * nvgpu_dma_alloc_flags_vid() + * nvgpu_dma_alloc_flags_vid_at() + */ +void nvgpu_dma_free(struct gk20a *g, struct nvgpu_mem *mem); + +/** + * nvgpu_dma_alloc_map - Allocate DMA memory and map into GMMU. + * + * @vm - VM context for GMMU mapping. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA and map that memory into the GMMU. + * Note this is different than mapping it into the CPU. This memory can be + * either placed in VIDMEM or SYSMEM, which ever is more convenient for the + * driver. + * + * Note: currently a bug exists in the nvgpu_dma_alloc_map*() routines: you + * cannot use nvgpu_gmmu_map() on said buffer - it will overwrite the necessary + * information for the DMA unmap routines to actually unmap the buffer. You + * will either leak mappings or see GMMU faults. + */ +int nvgpu_dma_alloc_map(struct vm_gk20a *vm, size_t size, + struct nvgpu_mem *mem); + +/** + * nvgpu_dma_alloc_map_flags - Allocate DMA memory and map into GMMU. + * + * @vm - VM context for GMMU mapping. + * @flags - Flags modifying the operation of the DMA allocation. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA and map that memory into the GMMU. + * Note this is different than mapping it into the CPU. This memory can be + * either placed in VIDMEM or SYSMEM, which ever is more convenient for the + * driver. + * + * This version passes @flags on to the underlying DMA allocation. The accepted + * flags are: + * + * %NVGPU_DMA_NO_KERNEL_MAPPING + * %NVGPU_DMA_FORCE_CONTIGUOUS + * %NVGPU_DMA_READ_ONLY + */ +int nvgpu_dma_alloc_map_flags(struct vm_gk20a *vm, unsigned long flags, + size_t size, struct nvgpu_mem *mem); + +/** + * nvgpu_dma_alloc_map_sys - Allocate DMA memory and map into GMMU. + * + * @vm - VM context for GMMU mapping. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA and map that memory into the GMMU. + * This memory will be placed in SYSMEM. + */ +int nvgpu_dma_alloc_map_sys(struct vm_gk20a *vm, size_t size, + struct nvgpu_mem *mem); + +/** + * nvgpu_dma_alloc_map_flags_sys - Allocate DMA memory and map into GMMU. + * + * @vm - VM context for GMMU mapping. + * @flags - Flags modifying the operation of the DMA allocation. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA and map that memory into the GMMU. + * This memory will be placed in SYSMEM. + * + * This version passes @flags on to the underlying DMA allocation. The accepted + * flags are: + * + * %NVGPU_DMA_NO_KERNEL_MAPPING + * %NVGPU_DMA_FORCE_CONTIGUOUS + * %NVGPU_DMA_READ_ONLY + */ +int nvgpu_dma_alloc_map_flags_sys(struct vm_gk20a *vm, unsigned long flags, + size_t size, struct nvgpu_mem *mem); + +/** + * nvgpu_dma_alloc_map_vid - Allocate DMA memory and map into GMMU. + * + * @vm - VM context for GMMU mapping. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA and map that memory into the GMMU. + * This memory will be placed in VIDMEM. + */ +int nvgpu_dma_alloc_map_vid(struct vm_gk20a *vm, size_t size, + struct nvgpu_mem *mem); + +/** + * nvgpu_dma_alloc_map_flags_vid - Allocate DMA memory and map into GMMU. + * + * @vm - VM context for GMMU mapping. + * @flags - Flags modifying the operation of the DMA allocation. + * @size - Size of the allocation in bytes. + * @mem - Struct for storing the allocation information. + * + * Allocate memory suitable for doing DMA and map that memory into the GMMU. + * This memory will be placed in VIDMEM. + * + * This version passes @flags on to the underlying DMA allocation. The accepted + * flags are: + * + * %NVGPU_DMA_NO_KERNEL_MAPPING + * %NVGPU_DMA_FORCE_CONTIGUOUS + * %NVGPU_DMA_READ_ONLY + */ +int nvgpu_dma_alloc_map_flags_vid(struct vm_gk20a *vm, unsigned long flags, + size_t size, struct nvgpu_mem *mem); + +/** + * nvgpu_dma_unmap_free - Free a DMA allocation + * + * @g - The GPU. + * @mem - An allocation to free. + * + * Free memory created with any of: + * + * nvgpu_dma_alloc_map() + * nvgpu_dma_alloc_map_flags() + * nvgpu_dma_alloc_map_sys() + * nvgpu_dma_alloc_map_flags_sys() + * nvgpu_dma_alloc_map_vid() + * nvgpu_dma_alloc_map_flags_vid() + */ +void nvgpu_dma_unmap_free(struct vm_gk20a *vm, struct nvgpu_mem *mem); + +/* + * Don't use these directly. Instead use nvgpu_dma_free(). + */ +void nvgpu_dma_free_sys(struct gk20a *g, struct nvgpu_mem *mem); +void nvgpu_dma_free_vid(struct gk20a *g, struct nvgpu_mem *mem); + +#endif /* NVGPU_DMA_H */ diff --git a/include/nvgpu/dt.h b/include/nvgpu/dt.h new file mode 100644 index 0000000..b5fdbfc --- /dev/null +++ b/include/nvgpu/dt.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +struct gk20a; + +int nvgpu_dt_read_u32_index(struct gk20a *g, const char *name, + u32 index, u32 *value); diff --git a/include/nvgpu/ecc.h b/include/nvgpu/ecc.h new file mode 100644 index 0000000..9b211ef --- /dev/null +++ b/include/nvgpu/ecc.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_ECC_H +#define NVGPU_ECC_H + +#include +#include + +#define NVGPU_ECC_STAT_NAME_MAX_SIZE 100 + +struct gk20a; + +struct nvgpu_ecc_stat { + char name[NVGPU_ECC_STAT_NAME_MAX_SIZE]; + u32 counter; + struct nvgpu_list_node node; +}; + +static inline struct nvgpu_ecc_stat *nvgpu_ecc_stat_from_node( + struct nvgpu_list_node *node) +{ + return (struct nvgpu_ecc_stat *)( + (uintptr_t)node - offsetof(struct nvgpu_ecc_stat, node) + ); +} + +struct nvgpu_ecc { + struct { + /* stats per tpc */ + + struct nvgpu_ecc_stat **sm_lrf_ecc_single_err_count; + struct nvgpu_ecc_stat **sm_lrf_ecc_double_err_count; + + struct nvgpu_ecc_stat **sm_shm_ecc_sec_count; + struct nvgpu_ecc_stat **sm_shm_ecc_sed_count; + struct nvgpu_ecc_stat **sm_shm_ecc_ded_count; + + struct nvgpu_ecc_stat **tex_ecc_total_sec_pipe0_count; + struct nvgpu_ecc_stat **tex_ecc_total_ded_pipe0_count; + struct nvgpu_ecc_stat **tex_unique_ecc_sec_pipe0_count; + struct nvgpu_ecc_stat **tex_unique_ecc_ded_pipe0_count; + struct nvgpu_ecc_stat **tex_ecc_total_sec_pipe1_count; + struct nvgpu_ecc_stat **tex_ecc_total_ded_pipe1_count; + struct nvgpu_ecc_stat **tex_unique_ecc_sec_pipe1_count; + struct nvgpu_ecc_stat **tex_unique_ecc_ded_pipe1_count; + + struct nvgpu_ecc_stat **sm_l1_tag_ecc_corrected_err_count; + struct nvgpu_ecc_stat **sm_l1_tag_ecc_uncorrected_err_count; + struct nvgpu_ecc_stat **sm_cbu_ecc_corrected_err_count; + struct nvgpu_ecc_stat **sm_cbu_ecc_uncorrected_err_count; + struct nvgpu_ecc_stat **sm_l1_data_ecc_corrected_err_count; + struct nvgpu_ecc_stat **sm_l1_data_ecc_uncorrected_err_count; + struct nvgpu_ecc_stat **sm_icache_ecc_corrected_err_count; + struct nvgpu_ecc_stat **sm_icache_ecc_uncorrected_err_count; + + /* stats per gpc */ + + struct nvgpu_ecc_stat *gcc_l15_ecc_corrected_err_count; + struct nvgpu_ecc_stat *gcc_l15_ecc_uncorrected_err_count; + + struct nvgpu_ecc_stat *gpccs_ecc_corrected_err_count; + struct nvgpu_ecc_stat *gpccs_ecc_uncorrected_err_count; + struct nvgpu_ecc_stat *mmu_l1tlb_ecc_corrected_err_count; + struct nvgpu_ecc_stat *mmu_l1tlb_ecc_uncorrected_err_count; + + /* stats per device */ + struct nvgpu_ecc_stat *fecs_ecc_corrected_err_count; + struct nvgpu_ecc_stat *fecs_ecc_uncorrected_err_count; + } gr; + + struct { + /* stats per lts */ + struct nvgpu_ecc_stat **ecc_sec_count; + struct nvgpu_ecc_stat **ecc_ded_count; + } ltc; + + struct { + /* stats per device */ + struct nvgpu_ecc_stat *mmu_l2tlb_ecc_corrected_err_count; + struct nvgpu_ecc_stat *mmu_l2tlb_ecc_uncorrected_err_count; + struct nvgpu_ecc_stat *mmu_hubtlb_ecc_corrected_err_count; + struct nvgpu_ecc_stat *mmu_hubtlb_ecc_uncorrected_err_count; + struct nvgpu_ecc_stat *mmu_fillunit_ecc_corrected_err_count; + struct nvgpu_ecc_stat *mmu_fillunit_ecc_uncorrected_err_count; + } fb; + + struct { + /* stats per device */ + struct nvgpu_ecc_stat *pmu_ecc_corrected_err_count; + struct nvgpu_ecc_stat *pmu_ecc_uncorrected_err_count; + } pmu; + + struct { + /* stats per fbpa */ + struct nvgpu_ecc_stat *fbpa_ecc_sec_err_count; + struct nvgpu_ecc_stat *fbpa_ecc_ded_err_count; + } fbpa; + + struct nvgpu_list_node stats_list; + int stats_count; +}; + +int nvgpu_ecc_counter_init_per_tpc(struct gk20a *g, + struct nvgpu_ecc_stat ***stat, const char *name); +#define NVGPU_ECC_COUNTER_INIT_PER_TPC(stat) \ + nvgpu_ecc_counter_init_per_tpc(g, &g->ecc.gr.stat, #stat) + +int nvgpu_ecc_counter_init_per_gpc(struct gk20a *g, + struct nvgpu_ecc_stat **stat, const char *name); +#define NVGPU_ECC_COUNTER_INIT_PER_GPC(stat) \ + nvgpu_ecc_counter_init_per_gpc(g, &g->ecc.gr.stat, #stat) + +int nvgpu_ecc_counter_init(struct gk20a *g, + struct nvgpu_ecc_stat **stat, const char *name); +#define NVGPU_ECC_COUNTER_INIT_GR(stat) \ + nvgpu_ecc_counter_init(g, &g->ecc.gr.stat, #stat) +#define NVGPU_ECC_COUNTER_INIT_FB(stat) \ + nvgpu_ecc_counter_init(g, &g->ecc.fb.stat, #stat) +#define NVGPU_ECC_COUNTER_INIT_PMU(stat) \ + nvgpu_ecc_counter_init(g, &g->ecc.pmu.stat, #stat) + +int nvgpu_ecc_counter_init_per_lts(struct gk20a *g, + struct nvgpu_ecc_stat ***stat, const char *name); +#define NVGPU_ECC_COUNTER_INIT_PER_LTS(stat) \ + nvgpu_ecc_counter_init_per_lts(g, &g->ecc.ltc.stat, #stat) + +int nvgpu_ecc_counter_init_per_fbpa(struct gk20a *g, + struct nvgpu_ecc_stat **stat, const char *name); +#define NVGPU_ECC_COUNTER_INIT_PER_FBPA(stat) \ + nvgpu_ecc_counter_init_per_fbpa(g, &g->ecc.fbpa.stat, #stat) + +void nvgpu_ecc_free(struct gk20a *g); + +int nvgpu_ecc_init_support(struct gk20a *g); +void nvgpu_ecc_remove_support(struct gk20a *g); + +/* OSes to implement */ + +int nvgpu_ecc_sysfs_init(struct gk20a *g); +void nvgpu_ecc_sysfs_remove(struct gk20a *g); + +#endif diff --git a/include/nvgpu/enabled.h b/include/nvgpu/enabled.h new file mode 100644 index 0000000..ef55dad --- /dev/null +++ b/include/nvgpu/enabled.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2017-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_ENABLED_H +#define NVGPU_ENABLED_H + +struct gk20a; + +#include + +/* + * Available flags that describe what's enabled and what's not in the GPU. Each + * flag here is defined by it's offset in a bitmap. + */ +#define NVGPU_IS_FMODEL 1 +#define NVGPU_DRIVER_IS_DYING 2 +#define NVGPU_GR_USE_DMA_FOR_FW_BOOTSTRAP 3 +#define NVGPU_FECS_TRACE_VA 4 +#define NVGPU_CAN_RAILGATE 5 +#define NVGPU_KERNEL_IS_DYING 6 +#define NVGPU_FECS_TRACE_FEATURE_CONTROL 7 + +/* + * ECC flags + */ +/* SM LRF ECC is enabled */ +#define NVGPU_ECC_ENABLED_SM_LRF 8 +/* SM SHM ECC is enabled */ +#define NVGPU_ECC_ENABLED_SM_SHM 9 +/* TEX ECC is enabled */ +#define NVGPU_ECC_ENABLED_TEX 10 +/* L2 ECC is enabled */ +#define NVGPU_ECC_ENABLED_LTC 11 +/* SM L1 DATA ECC is enabled */ +#define NVGPU_ECC_ENABLED_SM_L1_DATA 12 +/* SM L1 TAG ECC is enabled */ +#define NVGPU_ECC_ENABLED_SM_L1_TAG 13 +/* SM CBU ECC is enabled */ +#define NVGPU_ECC_ENABLED_SM_CBU 14 +/* SM ICAHE ECC is enabled */ +#define NVGPU_ECC_ENABLED_SM_ICACHE 15 + +/* + * MM flags. + */ +#define NVGPU_MM_UNIFY_ADDRESS_SPACES 16 +/* false if vidmem aperture actually points to sysmem */ +#define NVGPU_MM_HONORS_APERTURE 17 +/* unified or split memory with separate vidmem? */ +#define NVGPU_MM_UNIFIED_MEMORY 18 +/* User-space managed address spaces support */ +#define NVGPU_SUPPORT_USERSPACE_MANAGED_AS 20 +/* IO coherence support is available */ +#define NVGPU_SUPPORT_IO_COHERENCE 21 +/* MAP_BUFFER_EX with partial mappings */ +#define NVGPU_SUPPORT_PARTIAL_MAPPINGS 22 +/* MAP_BUFFER_EX with sparse allocations */ +#define NVGPU_SUPPORT_SPARSE_ALLOCS 23 +/* Direct PTE kind control is supported (map_buffer_ex) */ +#define NVGPU_SUPPORT_MAP_DIRECT_KIND_CTRL 24 +/* Support batch mapping */ +#define NVGPU_SUPPORT_MAP_BUFFER_BATCH 25 +/* Use coherent aperture for sysmem. */ +#define NVGPU_USE_COHERENT_SYSMEM 26 +/* Use physical scatter tables instead of IOMMU */ +#define NVGPU_MM_USE_PHYSICAL_SG 27 +/* WAR for gm20b chips. */ +#define NVGPU_MM_FORCE_128K_PMU_VM 28 + +/* + * Host flags + */ +#define NVGPU_HAS_SYNCPOINTS 30 +/* sync fence FDs are available in, e.g., submit_gpfifo */ +#define NVGPU_SUPPORT_SYNC_FENCE_FDS 31 +/* NVGPU_DBG_GPU_IOCTL_CYCLE_STATS is available */ +#define NVGPU_SUPPORT_CYCLE_STATS 32 +/* NVGPU_DBG_GPU_IOCTL_CYCLE_STATS_SNAPSHOT is available */ +#define NVGPU_SUPPORT_CYCLE_STATS_SNAPSHOT 33 +/* Both gpu driver and device support TSG */ +#define NVGPU_SUPPORT_TSG 34 +/* Fast deterministic submits with no job tracking are supported */ +#define NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_NO_JOBTRACKING 35 +/* Deterministic submits are supported even with job tracking */ +#define NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_FULL 36 +/* NVGPU_IOCTL_CHANNEL_RESCHEDULE_RUNLIST is available */ +#define NVGPU_SUPPORT_RESCHEDULE_RUNLIST 37 + +/* NVGPU_GPU_IOCTL_GET_EVENT_FD is available */ +#define NVGPU_SUPPORT_DEVICE_EVENTS 38 +/* FECS context switch tracing is available */ +#define NVGPU_SUPPORT_FECS_CTXSW_TRACE 39 + +/* NVGPU_GPU_IOCTL_SET_DETERMINISTIC_OPTS is available */ +#define NVGPU_SUPPORT_DETERMINISTIC_OPTS 40 + +/* + * Security flags + */ + +#define NVGPU_SEC_SECUREGPCCS 41 +#define NVGPU_SEC_PRIVSECURITY 42 +/* VPR is supported */ +#define NVGPU_SUPPORT_VPR 43 + +/* + * Nvlink flags + */ + +#define NVGPU_SUPPORT_NVLINK 45 +/* + * PMU flags. + */ +/* perfmon enabled or disabled for PMU */ +#define NVGPU_PMU_PERFMON 48 +#define NVGPU_PMU_PSTATE 49 +#define NVGPU_PMU_ZBC_SAVE 50 +#define NVGPU_PMU_FECS_BOOTSTRAP_DONE 51 +#define NVGPU_GPU_CAN_BLCG 52 +#define NVGPU_GPU_CAN_SLCG 53 +#define NVGPU_GPU_CAN_ELCG 54 +/* Clock control support */ +#define NVGPU_SUPPORT_CLOCK_CONTROLS 55 +/* NVGPU_GPU_IOCTL_GET_VOLTAGE is available */ +#define NVGPU_SUPPORT_GET_VOLTAGE 56 +/* NVGPU_GPU_IOCTL_GET_CURRENT is available */ +#define NVGPU_SUPPORT_GET_CURRENT 57 +/* NVGPU_GPU_IOCTL_GET_POWER is available */ +#define NVGPU_SUPPORT_GET_POWER 58 +/* NVGPU_GPU_IOCTL_GET_TEMPERATURE is available */ +#define NVGPU_SUPPORT_GET_TEMPERATURE 59 +/* NVGPU_GPU_IOCTL_SET_THERM_ALERT_LIMIT is available */ +#define NVGPU_SUPPORT_SET_THERM_ALERT_LIMIT 60 + +/* whether to run PREOS binary on dGPUs */ +#define NVGPU_PMU_RUN_PREOS 61 + +/* set if ASPM is enabled; only makes sense for PCI */ +#define NVGPU_SUPPORT_ASPM 62 +/* subcontexts are available */ +#define NVGPU_SUPPORT_TSG_SUBCONTEXTS 63 +/* Simultaneous Compute and Graphics (SCG) is available */ +#define NVGPU_SUPPORT_SCG 64 + +/* GPU_VA address of a syncpoint is supported */ +#define NVGPU_SUPPORT_SYNCPOINT_ADDRESS 65 +/* Allocating per-channel syncpoint in user space is supported */ +#define NVGPU_SUPPORT_USER_SYNCPOINT 66 + +/* USERMODE enable bit */ +#define NVGPU_SUPPORT_USERMODE_SUBMIT 67 + +/* Multiple WPR support */ +#define NVGPU_SUPPORT_MULTIPLE_WPR 68 + +/* SEC2 RTOS support*/ +#define NVGPU_SUPPORT_SEC2_RTOS 69 + +/* NVGPU_GPU_IOCTL_GET_GPU_LOAD is available */ +#define NVGPU_SUPPORT_GET_GPU_LOAD 70 + +/* PLATFORM_ATOMIC support */ +#define NVGPU_SUPPORT_PLATFORM_ATOMIC 71 + +/* NVGPU_GPU_IOCTL_SET_MMU_DEBUG_MODE is available */ +#define NVGPU_SUPPORT_SET_CTX_MMU_DEBUG_MODE 72 + +/* + * Must be greater than the largest bit offset in the above list. + */ +#define NVGPU_MAX_ENABLED_BITS 73U + +/** + * nvgpu_is_enabled - Check if the passed flag is enabled. + * + * @g - The GPU. + * @flag - Which flag to check. + * + * Returns true if the passed @flag is true; false otherwise. + */ +bool nvgpu_is_enabled(struct gk20a *g, int flag); + +/** + * __nvgpu_set_enabled - Set the state of a flag. + * + * @g - The GPU. + * @flag - Which flag to modify. + * @state - The state to set the flag to. + * + * Set the state of the passed @flag to @state. + */ +void __nvgpu_set_enabled(struct gk20a *g, int flag, bool state); + +int nvgpu_init_enabled_flags(struct gk20a *g); +void nvgpu_free_enabled_flags(struct gk20a *g); + +#endif /* NVGPU_ENABLED_H */ diff --git a/include/nvgpu/errno.h b/include/nvgpu/errno.h new file mode 100644 index 0000000..7e8b110 --- /dev/null +++ b/include/nvgpu/errno.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_ERRNO_H +#define NVGPU_ERRNO_H + +/* + * Explicit include to get all the -E* error messages. Useful for header files + * with static inlines that return error messages. In actual C code normally + * enough Linux/QNX headers bleed in to get the error messages but header files + * with sparse includes do not have this luxury. + */ + +#ifdef __KERNEL__ +#include +#endif + +/* + * TODO: add else path above for QNX. + */ + +#endif /* NVGPU_ERRNO_H */ diff --git a/include/nvgpu/error_notifier.h b/include/nvgpu/error_notifier.h new file mode 100644 index 0000000..7ba01e9 --- /dev/null +++ b/include/nvgpu/error_notifier.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_ERROR_NOTIFIER_H +#define NVGPU_ERROR_NOTIFIER_H + +#include + +struct channel_gk20a; + +enum { + NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT = 0, + NVGPU_ERR_NOTIFIER_GR_ERROR_SW_METHOD, + NVGPU_ERR_NOTIFIER_GR_ERROR_SW_NOTIFY, + NVGPU_ERR_NOTIFIER_GR_EXCEPTION, + NVGPU_ERR_NOTIFIER_GR_SEMAPHORE_TIMEOUT, + NVGPU_ERR_NOTIFIER_GR_ILLEGAL_NOTIFY, + NVGPU_ERR_NOTIFIER_FIFO_ERROR_MMU_ERR_FLT, + NVGPU_ERR_NOTIFIER_PBDMA_ERROR, + NVGPU_ERR_NOTIFIER_FECS_ERR_UNIMP_FIRMWARE_METHOD, + NVGPU_ERR_NOTIFIER_RESETCHANNEL_VERIF_ERROR, + NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH, +}; + +void nvgpu_set_error_notifier_locked(struct channel_gk20a *ch, u32 error); +void nvgpu_set_error_notifier(struct channel_gk20a *ch, u32 error); +void nvgpu_set_error_notifier_if_empty(struct channel_gk20a *ch, u32 error); +bool nvgpu_is_error_notifier_set(struct channel_gk20a *ch, u32 error_notifier); + +#endif /* NVGPU_ERROR_NOTIFIER_H */ diff --git a/include/nvgpu/falcon.h b/include/nvgpu/falcon.h new file mode 100644 index 0000000..4fc97ee --- /dev/null +++ b/include/nvgpu/falcon.h @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_FALCON_H +#define NVGPU_FALCON_H + +#include +#include + +/* + * Falcon Id Defines + */ +#define FALCON_ID_PMU (0U) +#define FALCON_ID_GSPLITE (1U) +#define FALCON_ID_FECS (2U) +#define FALCON_ID_GPCCS (3U) +#define FALCON_ID_NVDEC (4U) +#define FALCON_ID_SEC2 (7U) +#define FALCON_ID_MINION (10U) + +/* + * Falcon Base address Defines + */ +#define FALCON_NVDEC_BASE 0x00084000 +#define FALCON_PWR_BASE 0x0010a000 +#define FALCON_SEC_BASE 0x00087000 +#define FALCON_FECS_BASE 0x00409000 +#define FALCON_GPCCS_BASE 0x0041a000 + +/* Falcon Register index */ +#define FALCON_REG_R0 (0) +#define FALCON_REG_R1 (1) +#define FALCON_REG_R2 (2) +#define FALCON_REG_R3 (3) +#define FALCON_REG_R4 (4) +#define FALCON_REG_R5 (5) +#define FALCON_REG_R6 (6) +#define FALCON_REG_R7 (7) +#define FALCON_REG_R8 (8) +#define FALCON_REG_R9 (9) +#define FALCON_REG_R10 (10) +#define FALCON_REG_R11 (11) +#define FALCON_REG_R12 (12) +#define FALCON_REG_R13 (13) +#define FALCON_REG_R14 (14) +#define FALCON_REG_R15 (15) +#define FALCON_REG_IV0 (16) +#define FALCON_REG_IV1 (17) +#define FALCON_REG_UNDEFINED (18) +#define FALCON_REG_EV (19) +#define FALCON_REG_SP (20) +#define FALCON_REG_PC (21) +#define FALCON_REG_IMB (22) +#define FALCON_REG_DMB (23) +#define FALCON_REG_CSW (24) +#define FALCON_REG_CCR (25) +#define FALCON_REG_SEC (26) +#define FALCON_REG_CTX (27) +#define FALCON_REG_EXCI (28) +#define FALCON_REG_RSVD0 (29) +#define FALCON_REG_RSVD1 (30) +#define FALCON_REG_RSVD2 (31) +#define FALCON_REG_SIZE (32) + +#define FALCON_MAILBOX_0 0x0 +#define FALCON_MAILBOX_1 0x1 +#define FALCON_MAILBOX_COUNT 0x02 +#define FALCON_BLOCK_SIZE 0x100U + +#define GET_IMEM_TAG(IMEM_ADDR) (IMEM_ADDR >> 8) + +#define GET_NEXT_BLOCK(ADDR) \ + ((((ADDR + (FALCON_BLOCK_SIZE - 1)) & ~(FALCON_BLOCK_SIZE-1)) \ + / FALCON_BLOCK_SIZE) << 8) + +/* + * Falcon HWCFG request read types defines + */ +enum flcn_hwcfg_read { + FALCON_IMEM_SIZE = 0, + FALCON_DMEM_SIZE, + FALCON_CORE_REV, + FALCON_SECURITY_MODEL, + FLACON_MAILBOX_COUNT +}; + +/* + * Falcon HWCFG request write types defines + */ +enum flcn_hwcfg_write { + FALCON_STARTCPU = 0, + FALCON_STARTCPU_SECURE, + FALCON_BOOTVEC, + FALCON_ITF_EN +}; + +#define FALCON_MEM_SCRUBBING_TIMEOUT_MAX 1000 +#define FALCON_MEM_SCRUBBING_TIMEOUT_DEFAULT 10 + +enum flcn_dma_dir { + DMA_TO_FB = 0, + DMA_FROM_FB +}; + +enum flcn_mem_type { + MEM_DMEM = 0, + MEM_IMEM +}; + +/* Falcon ucode header format + * OS Code Offset + * OS Code Size + * OS Data Offset + * OS Data Size + * NumApps (N) + * App 0 Code Offset + * App 0 Code Size + * . . . . + * App N - 1 Code Offset + * App N - 1 Code Size + * App 0 Data Offset + * App 0 Data Size + * . . . . + * App N - 1 Data Offset + * App N - 1 Data Size + * OS Ovl Offset + * OS Ovl Size +*/ +#define OS_CODE_OFFSET 0x0 +#define OS_CODE_SIZE 0x1 +#define OS_DATA_OFFSET 0x2 +#define OS_DATA_SIZE 0x3 +#define NUM_APPS 0x4 +#define APP_0_CODE_OFFSET 0x5 +#define APP_0_CODE_SIZE 0x6 + +struct nvgpu_falcon_dma_info { + u32 fb_base; + u32 fb_off; + u32 flcn_mem_off; + u32 size_in_bytes; + enum flcn_dma_dir dir; + u32 ctx_dma; + enum flcn_mem_type flcn_mem; + u32 is_wait_complete; +}; + +struct gk20a; +struct nvgpu_falcon; +struct nvgpu_falcon_bl_info; + +/* Queue Type */ +#define QUEUE_TYPE_DMEM 0x0U +#define QUEUE_TYPE_EMEM 0x1U + +struct nvgpu_falcon_queue { + + /* Queue Type (queue_type) */ + u8 queue_type; + + /* used by nvgpu, for command LPQ/HPQ */ + struct nvgpu_mutex mutex; + + /* current write position */ + u32 position; + /* physical dmem offset where this queue begins */ + u32 offset; + /* logical queue identifier */ + u32 id; + /* physical queue index */ + u32 index; + /* in bytes */ + u32 size; + /* open-flag */ + u32 oflag; + + /* queue type(DMEM-Q/FB-Q) specific ops */ + int (*rewind)(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue); + int (*pop)(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue, void *data, u32 size, + u32 *bytes_read); + int (*push)(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue, void *data, u32 size); + bool (*has_room)(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue, u32 size, + bool *need_rewind); + int (*tail)(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue, u32 *tail, bool set); + int (*head)(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue, u32 *head, bool set); +}; + +struct nvgpu_falcon_version_ops { + void (*start_cpu_secure)(struct nvgpu_falcon *flcn); + void (*write_dmatrfbase)(struct nvgpu_falcon *flcn, u32 addr); +}; + +/* ops which are falcon engine specific */ +struct nvgpu_falcon_engine_dependency_ops { + int (*reset_eng)(struct gk20a *g); + int (*queue_head)(struct gk20a *g, struct nvgpu_falcon_queue *queue, + u32 *head, bool set); + int (*queue_tail)(struct gk20a *g, struct nvgpu_falcon_queue *queue, + u32 *tail, bool set); + void (*msgq_tail)(struct gk20a *g, u32 *tail, bool set); + int (*copy_from_emem)(struct nvgpu_falcon *flcn, u32 src, u8 *dst, + u32 size, u8 port); + int (*copy_to_emem)(struct nvgpu_falcon *flcn, u32 dst, u8 *src, + u32 size, u8 port); +}; + +struct nvgpu_falcon_ops { + int (*reset)(struct nvgpu_falcon *flcn); + void (*set_irq)(struct nvgpu_falcon *flcn, bool enable); + bool (*clear_halt_interrupt_status)(struct nvgpu_falcon *flcn); + bool (*is_falcon_cpu_halted)(struct nvgpu_falcon *flcn); + bool (*is_falcon_idle)(struct nvgpu_falcon *flcn); + bool (*is_falcon_scrubbing_done)(struct nvgpu_falcon *flcn); + int (*copy_from_dmem)(struct nvgpu_falcon *flcn, u32 src, u8 *dst, + u32 size, u8 port); + int (*copy_to_dmem)(struct nvgpu_falcon *flcn, u32 dst, u8 *src, + u32 size, u8 port); + int (*copy_from_imem)(struct nvgpu_falcon *flcn, u32 src, u8 *dst, + u32 size, u8 port); + int (*copy_to_imem)(struct nvgpu_falcon *flcn, u32 dst, u8 *src, + u32 size, u8 port, bool sec, u32 tag); + int (*dma_copy)(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_dma_info *dma_info); + u32 (*mailbox_read)(struct nvgpu_falcon *flcn, u32 mailbox_index); + void (*mailbox_write)(struct nvgpu_falcon *flcn, u32 mailbox_index, + u32 data); + int (*bootstrap)(struct nvgpu_falcon *flcn, u32 boot_vector); + void (*dump_falcon_stats)(struct nvgpu_falcon *flcn); + int (*bl_bootstrap)(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_bl_info *bl_info); +}; + +struct nvgpu_falcon_bl_info { + void *bl_src; + u8 *bl_desc; + u32 bl_desc_size; + u32 bl_size; + u32 bl_start_tag; +}; + +struct nvgpu_falcon { + struct gk20a *g; + u32 flcn_id; + u32 flcn_base; + u32 flcn_core_rev; + bool is_falcon_supported; + bool is_interrupt_enabled; + u32 intr_mask; + u32 intr_dest; + bool isr_enabled; + struct nvgpu_mutex isr_mutex; + struct nvgpu_mutex copy_lock; + struct nvgpu_falcon_ops flcn_ops; + struct nvgpu_falcon_version_ops flcn_vops; + struct nvgpu_falcon_engine_dependency_ops flcn_engine_dep_ops; +}; + +int nvgpu_flcn_wait_idle(struct nvgpu_falcon *flcn); +int nvgpu_flcn_wait_for_halt(struct nvgpu_falcon *flcn, unsigned int timeout); +int nvgpu_flcn_clear_halt_intr_status(struct nvgpu_falcon *flcn, + unsigned int timeout); +int nvgpu_flcn_reset(struct nvgpu_falcon *flcn); +void nvgpu_flcn_set_irq(struct nvgpu_falcon *flcn, bool enable, + u32 intr_mask, u32 intr_dest); +bool nvgpu_flcn_get_mem_scrubbing_status(struct nvgpu_falcon *flcn); +int nvgpu_flcn_mem_scrub_wait(struct nvgpu_falcon *flcn); +bool nvgpu_flcn_get_cpu_halted_status(struct nvgpu_falcon *flcn); +bool nvgpu_flcn_get_idle_status(struct nvgpu_falcon *flcn); +int nvgpu_flcn_copy_from_emem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port); +int nvgpu_flcn_copy_to_emem(struct nvgpu_falcon *flcn, + u32 dst, u8 *src, u32 size, u8 port); +int nvgpu_flcn_copy_from_dmem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port); +int nvgpu_flcn_copy_to_dmem(struct nvgpu_falcon *flcn, + u32 dst, u8 *src, u32 size, u8 port); +int nvgpu_flcn_copy_to_imem(struct nvgpu_falcon *flcn, + u32 dst, u8 *src, u32 size, u8 port, bool sec, u32 tag); +int nvgpu_flcn_copy_from_imem(struct nvgpu_falcon *flcn, + u32 src, u8 *dst, u32 size, u8 port); +int nvgpu_flcn_dma_copy(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_dma_info *dma_info); +u32 nvgpu_flcn_mailbox_read(struct nvgpu_falcon *flcn, u32 mailbox_index); +void nvgpu_flcn_mailbox_write(struct nvgpu_falcon *flcn, u32 mailbox_index, + u32 data); +int nvgpu_flcn_bootstrap(struct nvgpu_falcon *flcn, u32 boot_vector); +void nvgpu_flcn_print_dmem(struct nvgpu_falcon *flcn, u32 src, u32 size); +void nvgpu_flcn_print_imem(struct nvgpu_falcon *flcn, u32 src, u32 size); +void nvgpu_flcn_dump_stats(struct nvgpu_falcon *flcn); +int nvgpu_flcn_bl_bootstrap(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_bl_info *bl_info); + +/* queue public functions */ +int nvgpu_flcn_queue_init(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue); +bool nvgpu_flcn_queue_is_empty(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue); +int nvgpu_flcn_queue_rewind(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue); +int nvgpu_flcn_queue_pop(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue, void *data, u32 size, + u32 *bytes_read); +int nvgpu_flcn_queue_push(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue, void *data, u32 size); +void nvgpu_flcn_queue_free(struct nvgpu_falcon *flcn, + struct nvgpu_falcon_queue *queue); + +int nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id); + +#endif /* NVGPU_FALCON_H */ diff --git a/include/nvgpu/fecs_trace.h b/include/nvgpu/fecs_trace.h new file mode 100644 index 0000000..5dc3530 --- /dev/null +++ b/include/nvgpu/fecs_trace.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_FECS_TRACE_H +#define NVGPU_FECS_TRACE_H + +struct gk20a; + +/* + * If HW circular buffer is getting too many "buffer full" conditions, + * increasing this constant should help (it drives Linux' internal buffer size). + */ +#define GK20A_FECS_TRACE_NUM_RECORDS (1 << 10) +#define GK20A_FECS_TRACE_HASH_BITS 8 /* 2^8 */ +#define GK20A_FECS_TRACE_FRAME_PERIOD_US (1000000ULL/60ULL) +#define GK20A_FECS_TRACE_PTIMER_SHIFT 5 + +struct gk20a_fecs_trace_record { + u32 magic_lo; + u32 magic_hi; + u32 context_id; + u32 context_ptr; + u32 new_context_id; + u32 new_context_ptr; + u64 ts[]; +}; + +#ifdef CONFIG_GK20A_CTXSW_TRACE +u32 gk20a_fecs_trace_record_ts_tag_invalid_ts_v(void); +u32 gk20a_fecs_trace_record_ts_tag_v(u64 ts); +u64 gk20a_fecs_trace_record_ts_timestamp_v(u64 ts); +int gk20a_fecs_trace_num_ts(void); +struct gk20a_fecs_trace_record *gk20a_fecs_trace_get_record(struct gk20a *g, + int idx); +bool gk20a_fecs_trace_is_valid_record(struct gk20a_fecs_trace_record *r); +int gk20a_fecs_trace_get_read_index(struct gk20a *g); +int gk20a_fecs_trace_get_write_index(struct gk20a *g); + +#endif /* CONFIG_GK20A_CTXSW_TRACE */ + +#endif diff --git a/include/nvgpu/firmware.h b/include/nvgpu/firmware.h new file mode 100644 index 0000000..54d6795 --- /dev/null +++ b/include/nvgpu/firmware.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_FIRMWARE_H +#define NVGPU_FIRMWARE_H + +#include + +struct gk20a; + +#define NVGPU_REQUEST_FIRMWARE_NO_WARN (1UL << 0) +#define NVGPU_REQUEST_FIRMWARE_NO_SOC (1UL << 1) + +struct nvgpu_firmware { + u8 *data; + size_t size; +}; + +/** + * nvgpu_request_firmware - load a firmware blob from filesystem. + * + * @g The GPU driver struct for device to load firmware for + * @fw_name The base name of the firmware file. + * @flags Flags for loading; + * + * NVGPU_REQUEST_FIRMWARE_NO_WARN: Do not display warning on + * failed load. + * + * NVGPU_REQUEST_FIRMWARE_NO_SOC: Do not attempt loading from + * path . + * + * nvgpu_request_firmware() will load firmware from: + * + * // + * + * If that fails and NO_SOC is not enabled, it'll try next from: + * + * // + * + * It'll allocate a nvgpu_firmware structure and initializes it and returns + * it to caller. + */ +struct nvgpu_firmware *nvgpu_request_firmware(struct gk20a *g, + const char *fw_name, + int flags); + +/** + * nvgpu_release_firmware - free firmware and associated nvgpu_firmware blob + * + * @g The GPU driver struct for device to free firmware for + * @fw The firmware to free. fw blob will also be freed. + */ +void nvgpu_release_firmware(struct gk20a *g, struct nvgpu_firmware *fw); + +#endif /* NVGPU_FIRMWARE_H */ diff --git a/include/nvgpu/flcnif_cmn.h b/include/nvgpu/flcnif_cmn.h new file mode 100644 index 0000000..273da1e --- /dev/null +++ b/include/nvgpu/flcnif_cmn.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_FLCNIF_CMN_H +#define NVGPU_FLCNIF_CMN_H + +#define PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED 0 + +struct falc_u64 { + u32 lo; + u32 hi; +}; + +struct falc_dma_addr { + u32 dma_base; + /* + * dma_base1 is 9-bit MSB for FB Base + * address for the transfer in FB after + * address using 49b FB address + */ + u16 dma_base1; + u8 dma_offset; +}; + +struct pmu_mem_v1 { + u32 dma_base; + u8 dma_offset; + u8 dma_idx; + u16 fb_size; +}; + +struct pmu_mem_desc_v0 { + struct falc_u64 dma_addr; + u16 dma_sizemax; + u8 dma_idx; +}; + +struct pmu_dmem { + u16 size; + u32 offset; +}; + +struct flcn_mem_desc_v0 { + struct falc_u64 address; + u32 params; +}; + +#define nv_flcn_mem_desc flcn_mem_desc_v0 + +struct pmu_allocation_v1 { + struct { + struct pmu_dmem dmem; + struct pmu_mem_v1 fb; + } alloc; +}; + +struct pmu_allocation_v2 { + struct { + struct pmu_dmem dmem; + struct pmu_mem_desc_v0 fb; + } alloc; +}; + +struct pmu_allocation_v3 { + struct { + struct pmu_dmem dmem; + struct flcn_mem_desc_v0 fb; + } alloc; +}; + +#define nv_pmu_allocation pmu_allocation_v3 + +struct pmu_hdr { + u8 unit_id; + u8 size; + u8 ctrl_flags; + u8 seq_id; +}; + +#define NV_FLCN_UNIT_ID_REWIND (0x00U) + +#define PMU_MSG_HDR_SIZE sizeof(struct pmu_hdr) +#define PMU_CMD_HDR_SIZE sizeof(struct pmu_hdr) + +#define nv_pmu_hdr pmu_hdr +typedef u8 flcn_status; + +#define PMU_DMEM_ALLOC_ALIGNMENT (32) +#define PMU_DMEM_ALIGNMENT (4) + +#define PMU_CMD_FLAGS_PMU_MASK (0xF0) + +#define PMU_CMD_FLAGS_STATUS BIT(0) +#define PMU_CMD_FLAGS_INTR BIT(1) +#define PMU_CMD_FLAGS_EVENT BIT(2) +#define PMU_CMD_FLAGS_WATERMARK BIT(3) + +#define ALIGN_UP(v, gran) (((v) + ((gran) - 1)) & ~((gran)-1)) + +#define NV_UNSIGNED_ROUNDED_DIV(a, b) (((a) + ((b) / 2)) / (b)) + +#endif /* NVGPU_FLCNIF_CMN_H */ diff --git a/include/nvgpu/fuse.h b/include/nvgpu/fuse.h new file mode 100644 index 0000000..1d459a9 --- /dev/null +++ b/include/nvgpu/fuse.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_FUSE_H +#define NVGPU_FUSE_H + +struct gk20a; + +#include + +int nvgpu_tegra_get_gpu_speedo_id(struct gk20a *g); + +void nvgpu_tegra_fuse_write_bypass(struct gk20a *g, u32 val); +void nvgpu_tegra_fuse_write_access_sw(struct gk20a *g, u32 val); +void nvgpu_tegra_fuse_write_opt_gpu_tpc0_disable(struct gk20a *g, u32 val); +void nvgpu_tegra_fuse_write_opt_gpu_tpc1_disable(struct gk20a *g, u32 val); +int nvgpu_tegra_fuse_read_gcplex_config_fuse(struct gk20a *g, u32 *val); +int nvgpu_tegra_fuse_read_reserved_calib(struct gk20a *g, u32 *val); + +#endif /* NVGPU_FUSE_H */ diff --git a/include/nvgpu/gk20a.h b/include/nvgpu/gk20a.h new file mode 100644 index 0000000..aa95969 --- /dev/null +++ b/include/nvgpu/gk20a.h @@ -0,0 +1,1803 @@ +/* + * Copyright (c) 2011-2020, NVIDIA CORPORATION. All rights reserved. + * + * GK20A Graphics + * + * 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 GK20A_H +#define GK20A_H + +struct gk20a; +struct fifo_gk20a; +struct channel_gk20a; +struct gr_gk20a; +struct sim_nvgpu; +struct gk20a_ctxsw_ucode_segments; +struct gk20a_fecs_trace; +struct gk20a_ctxsw_trace; +struct acr_desc; +struct nvgpu_mem_alloc_tracker; +struct dbg_profiler_object_data; +struct gk20a_debug_output; +struct nvgpu_clk_pll_debug_data; +struct nvgpu_nvhost_dev; +struct nvgpu_cpu_time_correlation_sample; +struct nvgpu_mem_sgt; +struct nvgpu_warpstate; +struct nvgpu_clk_session; +struct nvgpu_clk_arb; +#ifdef CONFIG_GK20A_CTXSW_TRACE +struct nvgpu_gpu_ctxsw_trace_filter; +#endif +struct priv_cmd_entry; +struct nvgpu_setup_bind_args; + +#ifdef __KERNEL__ +#include +#endif +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a/clk_gk20a.h" +#include "gk20a/ce2_gk20a.h" +#include "gk20a/fifo_gk20a.h" +#include "clk/clk.h" +#include "pmu_perf/pmu_perf.h" +#include "pmgr/pmgr.h" +#include "therm/thrm.h" + +#ifdef CONFIG_DEBUG_FS +struct railgate_stats { + unsigned long last_rail_gate_start; + unsigned long last_rail_gate_complete; + unsigned long last_rail_ungate_start; + unsigned long last_rail_ungate_complete; + unsigned long total_rail_gate_time_ms; + unsigned long total_rail_ungate_time_ms; + unsigned long railgating_cycle_count; +}; +#endif + +enum gk20a_cbc_op { + gk20a_cbc_op_clear, + gk20a_cbc_op_clean, + gk20a_cbc_op_invalidate, +}; + +#define MC_INTR_UNIT_DISABLE false +#define MC_INTR_UNIT_ENABLE true + +#define GPU_LIT_NUM_GPCS 0 +#define GPU_LIT_NUM_PES_PER_GPC 1 +#define GPU_LIT_NUM_ZCULL_BANKS 2 +#define GPU_LIT_NUM_TPC_PER_GPC 3 +#define GPU_LIT_NUM_SM_PER_TPC 4 +#define GPU_LIT_NUM_FBPS 5 +#define GPU_LIT_GPC_BASE 6 +#define GPU_LIT_GPC_STRIDE 7 +#define GPU_LIT_GPC_SHARED_BASE 8 +#define GPU_LIT_TPC_IN_GPC_BASE 9 +#define GPU_LIT_TPC_IN_GPC_STRIDE 10 +#define GPU_LIT_TPC_IN_GPC_SHARED_BASE 11 +#define GPU_LIT_PPC_IN_GPC_BASE 12 +#define GPU_LIT_PPC_IN_GPC_STRIDE 13 +#define GPU_LIT_PPC_IN_GPC_SHARED_BASE 14 +#define GPU_LIT_ROP_BASE 15 +#define GPU_LIT_ROP_STRIDE 16 +#define GPU_LIT_ROP_SHARED_BASE 17 +#define GPU_LIT_HOST_NUM_ENGINES 18 +#define GPU_LIT_HOST_NUM_PBDMA 19 +#define GPU_LIT_LTC_STRIDE 20 +#define GPU_LIT_LTS_STRIDE 21 +#define GPU_LIT_NUM_FBPAS 22 +#define GPU_LIT_FBPA_STRIDE 23 +#define GPU_LIT_FBPA_BASE 24 +#define GPU_LIT_FBPA_SHARED_BASE 25 +#define GPU_LIT_SM_PRI_STRIDE 26 +#define GPU_LIT_SMPC_PRI_BASE 27 +#define GPU_LIT_SMPC_PRI_SHARED_BASE 28 +#define GPU_LIT_SMPC_PRI_UNIQUE_BASE 29 +#define GPU_LIT_SMPC_PRI_STRIDE 30 +#define GPU_LIT_TWOD_CLASS 31 +#define GPU_LIT_THREED_CLASS 32 +#define GPU_LIT_COMPUTE_CLASS 33 +#define GPU_LIT_GPFIFO_CLASS 34 +#define GPU_LIT_I2M_CLASS 35 +#define GPU_LIT_DMA_COPY_CLASS 36 +#define GPU_LIT_GPC_PRIV_STRIDE 37 +#define GPU_LIT_PERFMON_PMMGPCTPCA_DOMAIN_START 38 +#define GPU_LIT_PERFMON_PMMGPCTPCB_DOMAIN_START 39 +#define GPU_LIT_PERFMON_PMMGPCTPC_DOMAIN_COUNT 40 +#define GPU_LIT_PERFMON_PMMFBP_LTC_DOMAIN_START 41 +#define GPU_LIT_PERFMON_PMMFBP_LTC_DOMAIN_COUNT 42 +#define GPU_LIT_PERFMON_PMMFBP_ROP_DOMAIN_START 43 +#define GPU_LIT_PERFMON_PMMFBP_ROP_DOMAIN_COUNT 44 + +#define nvgpu_get_litter_value(g, v) (g)->ops.get_litter_value((g), v) + +#define MAX_TPC_PG_CONFIGS 9 + +enum nvgpu_unit; + +enum nvgpu_flush_op; +enum gk20a_mem_rw_flag; + +struct _resmgr_context; +struct nvgpu_gpfifo_entry; + +struct nvgpu_gpfifo_userdata { + struct nvgpu_gpfifo_entry __user *entries; + struct _resmgr_context *context; +}; + +/* + * gpu_ops should only contain function pointers! Non-function pointer members + * should go in struct gk20a or be implemented with the boolean flag API defined + * in nvgpu/enabled.h + */ + +/* index for FB fault buffer functions */ +#define NVGPU_FB_MMU_FAULT_NONREPLAY_REG_INDEX 0U +#define NVGPU_FB_MMU_FAULT_REPLAY_REG_INDEX 1U +#define NVGPU_FB_MMU_FAULT_BUF_DISABLED 0U +#define NVGPU_FB_MMU_FAULT_BUF_ENABLED 1U + +/* Parameters for init_elcg_mode/init_blcg_mode */ +enum { + ELCG_RUN, /* clk always run, i.e. disable elcg */ + ELCG_STOP, /* clk is stopped */ + ELCG_AUTO /* clk will run when non-idle, standard elcg mode */ +}; + +enum { + BLCG_RUN, /* clk always run, i.e. disable blcg */ + BLCG_AUTO /* clk will run when non-idle, standard blcg mode */ +}; + +struct gpu_ops { + struct { + int (*determine_L2_size_bytes)(struct gk20a *gk20a); + u64 (*get_cbc_base_divisor)(struct gk20a *g); + int (*init_comptags)(struct gk20a *g, struct gr_gk20a *gr); + int (*cbc_ctrl)(struct gk20a *g, enum gk20a_cbc_op op, + u32 min, u32 max); + void (*set_zbc_color_entry)(struct gk20a *g, + struct zbc_entry *color_val, + u32 index); + void (*set_zbc_depth_entry)(struct gk20a *g, + struct zbc_entry *depth_val, + u32 index); + void (*set_zbc_s_entry)(struct gk20a *g, + struct zbc_entry *s_val, + u32 index); + void (*init_cbc)(struct gk20a *g, struct gr_gk20a *gr); + void (*set_enabled)(struct gk20a *g, bool enabled); + void (*init_fs_state)(struct gk20a *g); + void (*isr)(struct gk20a *g); + u32 (*cbc_fix_config)(struct gk20a *g, int base); + void (*flush)(struct gk20a *g); + void (*intr_en_illegal_compstat)(struct gk20a *g, bool enable); + bool (*pri_is_ltc_addr)(struct gk20a *g, u32 addr); + bool (*is_ltcs_ltss_addr)(struct gk20a *g, u32 addr); + bool (*is_ltcn_ltss_addr)(struct gk20a *g, u32 addr); + void (*split_lts_broadcast_addr)(struct gk20a *g, u32 addr, + u32 *priv_addr_table, + u32 *priv_addr_table_index); + void (*split_ltc_broadcast_addr)(struct gk20a *g, u32 addr, + u32 *priv_addr_table, + u32 *priv_addr_table_index); + } ltc; + struct { + void (*isr_stall)(struct gk20a *g, u32 inst_id, u32 pri_base); + u32 (*isr_nonstall)(struct gk20a *g, u32 inst_id, u32 pri_base); + u32 (*get_num_pce)(struct gk20a *g); + void (*init_prod_values)(struct gk20a *g); + } ce2; + struct { + u32 (*get_patch_slots)(struct gk20a *g); + int (*init_fs_state)(struct gk20a *g); + int (*init_preemption_state)(struct gk20a *g); + void (*access_smpc_reg)(struct gk20a *g, u32 quad, u32 offset); + void (*bundle_cb_defaults)(struct gk20a *g); + void (*cb_size_default)(struct gk20a *g); + int (*calc_global_ctx_buffer_size)(struct gk20a *g); + void (*commit_global_attrib_cb)(struct gk20a *g, + struct nvgpu_gr_ctx *ch_ctx, + u64 addr, bool patch); + void (*commit_global_bundle_cb)(struct gk20a *g, + struct nvgpu_gr_ctx *ch_ctx, + u64 addr, u64 size, bool patch); + int (*commit_global_cb_manager)(struct gk20a *g, + struct channel_gk20a *ch, + bool patch); + void (*commit_global_pagepool)(struct gk20a *g, + struct nvgpu_gr_ctx *ch_ctx, + u64 addr, u32 size, bool patch); + void (*init_gpc_mmu)(struct gk20a *g); + int (*handle_sw_method)(struct gk20a *g, u32 addr, + u32 class_num, u32 offset, u32 data); + void (*set_alpha_circular_buffer_size)(struct gk20a *g, + u32 data); + void (*set_circular_buffer_size)(struct gk20a *g, u32 data); + void (*set_bes_crop_debug3)(struct gk20a *g, u32 data); + void (*set_bes_crop_debug4)(struct gk20a *g, u32 data); + void (*enable_hww_exceptions)(struct gk20a *g); + bool (*is_valid_class)(struct gk20a *g, u32 class_num); + bool (*is_valid_gfx_class)(struct gk20a *g, u32 class_num); + bool (*is_valid_compute_class)(struct gk20a *g, u32 class_num); + void (*get_sm_dsm_perf_regs)(struct gk20a *g, + u32 *num_sm_dsm_perf_regs, + u32 **sm_dsm_perf_regs, + u32 *perf_register_stride); + void (*get_sm_dsm_perf_ctrl_regs)(struct gk20a *g, + u32 *num_sm_dsm_perf_regs, + u32 **sm_dsm_perf_regs, + u32 *perf_register_stride); + void (*get_ovr_perf_regs)(struct gk20a *g, + u32 *num_ovr_perf_regs, + u32 **ovr_perf_regsr); + void (*set_hww_esr_report_mask)(struct gk20a *g); + int (*setup_alpha_beta_tables)(struct gk20a *g, + struct gr_gk20a *gr); + int (*falcon_load_ucode)(struct gk20a *g, + u64 addr_base, + struct gk20a_ctxsw_ucode_segments *segments, + u32 reg_offset); + int (*load_ctxsw_ucode)(struct gk20a *g); + u32 (*get_gpc_mask)(struct gk20a *g); + u32 (*get_gpc_tpc_mask)(struct gk20a *g, u32 gpc_index); + void (*set_gpc_tpc_mask)(struct gk20a *g, u32 gpc_index); + int (*alloc_obj_ctx)(struct channel_gk20a *c, + u32 class_num, u32 flags); + int (*bind_ctxsw_zcull)(struct gk20a *g, struct gr_gk20a *gr, + struct channel_gk20a *c, u64 zcull_va, + u32 mode); + int (*get_zcull_info)(struct gk20a *g, struct gr_gk20a *gr, + struct gr_zcull_info *zcull_params); + int (*decode_egpc_addr)(struct gk20a *g, + u32 addr, enum ctxsw_addr_type *addr_type, + u32 *gpc_num, u32 *tpc_num, u32 *broadcast_flags); + void (*egpc_etpc_priv_addr_table)(struct gk20a *g, u32 addr, + u32 gpc, u32 tpc, u32 broadcast_flags, + u32 *priv_addr_table, + u32 *priv_addr_table_index); + bool (*is_tpc_addr)(struct gk20a *g, u32 addr); + bool (*is_egpc_addr)(struct gk20a *g, u32 addr); + bool (*is_etpc_addr)(struct gk20a *g, u32 addr); + void (*get_egpc_etpc_num)(struct gk20a *g, u32 addr, + u32 *gpc_num, u32 *tpc_num); + u32 (*get_tpc_num)(struct gk20a *g, u32 addr); + u32 (*get_egpc_base)(struct gk20a *g); + void (*detect_sm_arch)(struct gk20a *g); + int (*add_zbc_color)(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *color_val, u32 index); + int (*add_zbc_depth)(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *depth_val, u32 index); + int (*add_zbc_s)(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *s_val, u32 index); + int (*zbc_set_table)(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *zbc_val); + int (*zbc_query_table)(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_query_params *query_params); + int (*zbc_s_query_table)(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_query_params *query_params); + int (*load_zbc_s_default_tbl)(struct gk20a *g, + struct gr_gk20a *gr); + int (*load_zbc_s_tbl)(struct gk20a *g, + struct gr_gk20a *gr); + void (*pmu_save_zbc)(struct gk20a *g, u32 entries); + int (*add_zbc)(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *zbc_val); + bool (*add_zbc_type_s)(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *zbc_val, int *ret_val); + u32 (*pagepool_default_size)(struct gk20a *g); + int (*init_ctx_state)(struct gk20a *g); + int (*alloc_gr_ctx)(struct gk20a *g, + struct nvgpu_gr_ctx *gr_ctx, struct vm_gk20a *vm, + u32 class, u32 padding); + void (*free_gr_ctx)(struct gk20a *g, + struct vm_gk20a *vm, struct nvgpu_gr_ctx *gr_ctx); + void (*powergate_tpc)(struct gk20a *g); + void (*update_ctxsw_preemption_mode)(struct gk20a *g, + struct channel_gk20a *c, + struct nvgpu_mem *mem); + int (*update_smpc_ctxsw_mode)(struct gk20a *g, + struct channel_gk20a *c, + bool enable); + u32 (*get_hw_accessor_stream_out_mode)(void); + int (*update_hwpm_ctxsw_mode)(struct gk20a *g, + struct channel_gk20a *c, + u64 gpu_va, + u32 mode); + void (*init_hwpm_pmm_register)(struct gk20a *g); + void (*get_num_hwpm_perfmon)(struct gk20a *g, u32 *num_sys_perfmon, + u32 *num_fbp_perfmon, u32 *num_gpc_perfmon); + void (*set_pmm_register)(struct gk20a *g, u32 offset, u32 val, + u32 num_chiplets, u32 num_perfmons); + int (*dump_gr_regs)(struct gk20a *g, + struct gk20a_debug_output *o); + int (*update_pc_sampling)(struct channel_gk20a *ch, + bool enable); + u32 (*get_max_fbps_count)(struct gk20a *g); + u32 (*get_fbp_en_mask)(struct gk20a *g); + u32 (*get_max_ltc_per_fbp)(struct gk20a *g); + u32 (*get_max_lts_per_ltc)(struct gk20a *g); + u32* (*get_rop_l2_en_mask)(struct gk20a *g); + void (*init_sm_dsm_reg_info)(void); + void (*init_ovr_sm_dsm_perf)(void); + int (*wait_empty)(struct gk20a *g, unsigned long duration_ms, + u32 expect_delay); + void (*init_cyclestats)(struct gk20a *g); + void (*enable_cde_in_fecs)(struct gk20a *g, + struct nvgpu_mem *mem); + int (*set_sm_debug_mode)(struct gk20a *g, struct channel_gk20a *ch, + u64 sms, bool enable); + void (*bpt_reg_info)(struct gk20a *g, + struct nvgpu_warpstate *w_state); + void (*get_access_map)(struct gk20a *g, + u32 **whitelist, int *num_entries); + int (*handle_fecs_error)(struct gk20a *g, + struct channel_gk20a *ch, + struct gr_gk20a_isr_data *isr_data); + int (*pre_process_sm_exception)(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm, u32 global_esr, u32 warp_esr, + bool sm_debugger_attached, + struct channel_gk20a *fault_ch, + bool *early_exit, bool *ignore_debugger); + u32 (*get_sm_hww_warp_esr)(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm); + u32 (*get_sm_hww_global_esr)(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm); + u32 (*get_sm_no_lock_down_hww_global_esr_mask)(struct gk20a *g); + int (*lock_down_sm)(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, + u32 global_esr_mask, bool check_errors); + int (*wait_for_sm_lock_down)(struct gk20a *g, u32 gpc, u32 tpc, + u32 sm, u32 global_esr_mask, bool check_errors); + void (*clear_sm_hww)(struct gk20a *g, u32 gpc, u32 tpc, u32 sm, + u32 global_esr); + void (*get_esr_sm_sel)(struct gk20a *g, u32 gpc, u32 tpc, + u32 *esr_sm_sel); + int (*handle_tpc_sm_ecc_exception)(struct gk20a *g, + u32 gpc, u32 tpc, + bool *post_event, struct channel_gk20a *fault_ch, + u32 *hww_global_esr); + int (*handle_sm_exception)(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm, + bool *post_event, struct channel_gk20a *fault_ch, + u32 *hww_global_esr); + int (*handle_gcc_exception)(struct gk20a *g, u32 gpc, u32 tpc, + bool *post_event, struct channel_gk20a *fault_ch, + u32 *hww_global_esr); + int (*handle_tex_exception)(struct gk20a *g, u32 gpc, u32 tpc, + bool *post_event); + int (*handle_tpc_mpc_exception)(struct gk20a *g, + u32 gpc, u32 tpc, bool *post_event); + int (*handle_gpc_gpccs_exception)(struct gk20a *g, u32 gpc, + u32 gpc_exception); + int (*handle_gpc_gpcmmu_exception)(struct gk20a *g, u32 gpc, + u32 gpc_exception); + void (*enable_gpc_exceptions)(struct gk20a *g); + void (*enable_exceptions)(struct gk20a *g); + int (*init_ecc)(struct gk20a *g); + u32 (*get_lrf_tex_ltc_dram_override)(struct gk20a *g); + int (*record_sm_error_state)(struct gk20a *g, u32 gpc, u32 tpc, + u32 sm, struct channel_gk20a *fault_ch); + int (*clear_sm_error_state)(struct gk20a *g, + struct channel_gk20a *ch, u32 sm_id); + int (*suspend_contexts)(struct gk20a *g, + struct dbg_session_gk20a *dbg_s, + int *ctx_resident_ch_fd); + int (*resume_contexts)(struct gk20a *g, + struct dbg_session_gk20a *dbg_s, + int *ctx_resident_ch_fd); + int (*set_preemption_mode)(struct channel_gk20a *ch, + u32 graphics_preempt_mode, + u32 compute_preempt_mode); + int (*get_preemption_mode_flags)(struct gk20a *g, + struct nvgpu_preemption_modes_rec *preemption_modes_rec); + int (*set_ctxsw_preemption_mode)(struct gk20a *g, + struct nvgpu_gr_ctx *gr_ctx, + struct vm_gk20a *vm, u32 class, + u32 graphics_preempt_mode, + u32 compute_preempt_mode); + int (*set_boosted_ctx)(struct channel_gk20a *ch, bool boost); + void (*update_boosted_ctx)(struct gk20a *g, + struct nvgpu_mem *mem, + struct nvgpu_gr_ctx *gr_ctx); + int (*init_sm_id_table)(struct gk20a *g); + int (*load_smid_config)(struct gk20a *g); + void (*program_sm_id_numbering)(struct gk20a *g, + u32 gpc, u32 tpc, u32 smid); + void (*program_active_tpc_counts)(struct gk20a *g, u32 gpc); + int (*setup_rop_mapping)(struct gk20a *g, struct gr_gk20a *gr); + int (*init_sw_veid_bundle)(struct gk20a *g); + void (*program_zcull_mapping)(struct gk20a *g, + u32 zcull_alloc_num, u32 *zcull_map_tiles); + int (*commit_global_timeslice)(struct gk20a *g, + struct channel_gk20a *c); + int (*commit_inst)(struct channel_gk20a *c, u64 gpu_va); + void (*write_zcull_ptr)(struct gk20a *g, + struct nvgpu_mem *mem, u64 gpu_va); + void (*write_pm_ptr)(struct gk20a *g, + struct nvgpu_mem *mem, u64 gpu_va); + void (*set_preemption_buffer_va)(struct gk20a *g, + struct nvgpu_mem *mem, u64 gpu_va); + void (*load_tpc_mask)(struct gk20a *g); + int (*trigger_suspend)(struct gk20a *g); + int (*wait_for_pause)(struct gk20a *g, struct nvgpu_warpstate *w_state); + int (*resume_from_pause)(struct gk20a *g); + int (*clear_sm_errors)(struct gk20a *g); + u32 (*tpc_enabled_exceptions)(struct gk20a *g); + int (*set_czf_bypass)(struct gk20a *g, + struct channel_gk20a *ch); + void (*init_czf_bypass)(struct gk20a *g); + bool (*sm_debugger_attached)(struct gk20a *g); + void (*suspend_single_sm)(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm, + u32 global_esr_mask, bool check_errors); + void (*suspend_all_sms)(struct gk20a *g, + u32 global_esr_mask, bool check_errors); + void (*resume_single_sm)(struct gk20a *g, + u32 gpc, u32 tpc, u32 sm); + void (*resume_all_sms)(struct gk20a *g); + void (*disable_rd_coalesce)(struct gk20a *g); + void (*init_ctxsw_hdr_data)(struct gk20a *g, + struct nvgpu_mem *mem); + void (*init_gfxp_wfi_timeout_count)(struct gk20a *g); + unsigned long (*get_max_gfxp_wfi_timeout_count) + (struct gk20a *g); + void (*ecc_init_scrub_reg)(struct gk20a *g); + u32 (*get_gpcs_swdx_dss_zbc_c_format_reg)(struct gk20a *g); + u32 (*get_gpcs_swdx_dss_zbc_z_format_reg)(struct gk20a *g); + void (*dump_ctxsw_stats)(struct gk20a *g, struct vm_gk20a *vm, + struct nvgpu_gr_ctx *gr_ctx); + void (*fecs_host_int_enable)(struct gk20a *g); + int (*handle_ssync_hww)(struct gk20a *g); + int (*handle_notify_pending)(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data); + int (*handle_semaphore_pending)(struct gk20a *g, + struct gr_gk20a_isr_data *isr_data); + int (*add_ctxsw_reg_pm_fbpa)(struct gk20a *g, + struct ctxsw_buf_offset_map_entry *map, + struct aiv_list_gk20a *regs, + u32 *count, u32 *offset, + u32 max_cnt, u32 base, + u32 num_fbpas, u32 stride, u32 mask); + int (*add_ctxsw_reg_perf_pma)(struct ctxsw_buf_offset_map_entry *map, + struct aiv_list_gk20a *regs, + u32 *count, u32 *offset, + u32 max_cnt, u32 base, u32 mask); + int (*decode_priv_addr)(struct gk20a *g, u32 addr, + enum ctxsw_addr_type *addr_type, + u32 *gpc_num, u32 *tpc_num, + u32 *ppc_num, u32 *be_num, + u32 *broadcast_flags); + int (*create_priv_addr_table)(struct gk20a *g, + u32 addr, + u32 *priv_addr_table, + u32 *num_registers); + u32 (*get_pmm_per_chiplet_offset)(void); + void (*split_fbpa_broadcast_addr)(struct gk20a *g, u32 addr, + u32 num_fbpas, + u32 *priv_addr_table, + u32 *priv_addr_table_index); + u32 (*fecs_ctxsw_mailbox_size)(void); + int (*init_sw_bundle64)(struct gk20a *g); + int (*alloc_global_ctx_buffers)(struct gk20a *g); + int (*map_global_ctx_buffers)(struct gk20a *g, + struct channel_gk20a *c); + int (*commit_global_ctx_buffers)(struct gk20a *g, + struct channel_gk20a *c, bool patch); + u32 (*get_nonpes_aware_tpc)(struct gk20a *g, u32 gpc, u32 tpc); + int (*get_offset_in_gpccs_segment)(struct gk20a *g, + enum ctxsw_addr_type addr_type, u32 num_tpcs, + u32 num_ppcs, u32 reg_list_ppc_count, + u32 *__offset_in_segment); + void (*set_debug_mode)(struct gk20a *g, bool enable); + int (*set_mmu_debug_mode)(struct gk20a *g, + struct channel_gk20a *ch, bool enable); + int (*set_fecs_watchdog_timeout)(struct gk20a *g); + } gr; + struct { + void (*init_hw)(struct gk20a *g); + void (*init_cbc)(struct gk20a *g, struct gr_gk20a *gr); + void (*init_fs_state)(struct gk20a *g); + void (*init_uncompressed_kind_map)(struct gk20a *g); + void (*init_kind_attr)(struct gk20a *g); + void (*set_mmu_page_size)(struct gk20a *g); + bool (*set_use_full_comp_tag_line)(struct gk20a *g); + u32 (*mmu_ctrl)(struct gk20a *g); + u32 (*mmu_debug_ctrl)(struct gk20a *g); + u32 (*mmu_debug_wr)(struct gk20a *g); + u32 (*mmu_debug_rd)(struct gk20a *g); + + /* + * Compression tag line coverage. When mapping a compressible + * buffer, ctagline is increased when the virtual address + * crosses over the compression page boundary. + */ + unsigned int (*compression_page_size)(struct gk20a *g); + + /* + * Minimum page size that can be used for compressible kinds. + */ + unsigned int (*compressible_page_size)(struct gk20a *g); + + /* + * Compressible kind mappings: Mask for the virtual and physical + * address bits that must match. + */ + u32 (*compression_align_mask)(struct gk20a *g); + + void (*dump_vpr_info)(struct gk20a *g); + void (*dump_wpr_info)(struct gk20a *g); + int (*vpr_info_fetch)(struct gk20a *g); + void (*read_wpr_info)(struct gk20a *g, + struct wpr_carveout_info *inf); + bool (*is_debug_mode_enabled)(struct gk20a *g); + void (*set_debug_mode)(struct gk20a *g, bool enable); + void (*set_mmu_debug_mode)(struct gk20a *g, bool enable); + int (*tlb_invalidate)(struct gk20a *g, struct nvgpu_mem *pdb); + void (*hub_isr)(struct gk20a *g); + void (*handle_replayable_fault)(struct gk20a *g); + int (*mem_unlock)(struct gk20a *g); + int (*init_nvlink)(struct gk20a *g); + int (*enable_nvlink)(struct gk20a *g); + void (*enable_hub_intr)(struct gk20a *g); + void (*disable_hub_intr)(struct gk20a *g); + int (*init_fbpa)(struct gk20a *g); + void (*handle_fbpa_intr)(struct gk20a *g, u32 fbpa_id); + void (*write_mmu_fault_buffer_lo_hi)(struct gk20a *g, u32 index, + u32 addr_lo, u32 addr_hi); + void (*write_mmu_fault_buffer_get)(struct gk20a *g, u32 index, + u32 reg_val); + void (*write_mmu_fault_buffer_size)(struct gk20a *g, u32 index, + u32 reg_val); + void (*write_mmu_fault_status)(struct gk20a *g, u32 reg_val); + u32 (*read_mmu_fault_buffer_get)(struct gk20a *g, u32 index); + u32 (*read_mmu_fault_buffer_put)(struct gk20a *g, u32 index); + u32 (*read_mmu_fault_buffer_size)(struct gk20a *g, u32 index); + void (*read_mmu_fault_addr_lo_hi)(struct gk20a *g, + u32 *addr_lo, u32 *addr_hi); + void (*read_mmu_fault_inst_lo_hi)(struct gk20a *g, + u32 *inst_lo, u32 *inst_hi); + u32 (*read_mmu_fault_info)(struct gk20a *g); + u32 (*read_mmu_fault_status)(struct gk20a *g); + int (*mmu_invalidate_replay)(struct gk20a *g, + u32 invalidate_replay_val); + bool (*mmu_fault_pending)(struct gk20a *g); + bool (*is_fault_buf_enabled)(struct gk20a *g, u32 index); + void (*fault_buf_set_state_hw)(struct gk20a *g, + u32 index, u32 state); + void (*fault_buf_configure_hw)(struct gk20a *g, u32 index); + size_t (*get_vidmem_size)(struct gk20a *g); + int (*apply_pdb_cache_war)(struct gk20a *g); + } fb; + struct { + void (*slcg_bus_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_ce2_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_chiplet_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_ctxsw_firmware_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_fb_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_fifo_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_gr_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_ltc_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_perf_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_priring_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_pmu_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_therm_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_xbar_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_hshub_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_acb_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_bus_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_ce_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_ctxsw_firmware_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_fb_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_fifo_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_gr_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_ltc_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_pwr_csb_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_pmu_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_xbar_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_hshub_load_gating_prod)(struct gk20a *g, bool prod); + void (*pg_gr_load_gating_prod)(struct gk20a *g, bool prod); + } clock_gating; + struct { + void (*post_events)(struct channel_gk20a *ch); + } debugger; + struct { + int (*setup_sw)(struct gk20a *g); + int (*init_fifo_setup_hw)(struct gk20a *g); + void (*bind_channel)(struct channel_gk20a *ch_gk20a); + void (*unbind_channel)(struct channel_gk20a *ch_gk20a); + void (*disable_channel)(struct channel_gk20a *ch); + void (*enable_channel)(struct channel_gk20a *ch); + int (*alloc_inst)(struct gk20a *g, struct channel_gk20a *ch); + void (*free_inst)(struct gk20a *g, struct channel_gk20a *ch); + int (*setup_ramfc)(struct channel_gk20a *c, u64 gpfifo_base, + u32 gpfifo_entries, + unsigned long acquire_timeout, + u32 flags); + int (*resetup_ramfc)(struct channel_gk20a *c); + int (*preempt_channel)(struct gk20a *g, struct channel_gk20a *ch); + int (*preempt_tsg)(struct gk20a *g, struct tsg_gk20a *tsg); + int (*enable_tsg)(struct tsg_gk20a *tsg); + int (*disable_tsg)(struct tsg_gk20a *tsg); + int (*tsg_verify_channel_status)(struct channel_gk20a *ch); + void (*tsg_verify_status_ctx_reload)(struct channel_gk20a *ch); + void (*tsg_verify_status_faulted)(struct channel_gk20a *ch); + int (*reschedule_runlist)(struct channel_gk20a *ch, + bool preempt_next); + int (*update_runlist)(struct gk20a *g, u32 runlist_id, + u32 chid, bool add, + bool wait_for_finish); + void (*trigger_mmu_fault)(struct gk20a *g, + unsigned long engine_ids); + void (*get_mmu_fault_info)(struct gk20a *g, u32 mmu_fault_id, + struct mmu_fault_info *mmfault); + void (*get_mmu_fault_desc)(struct mmu_fault_info *mmfault); + void (*get_mmu_fault_client_desc)( + struct mmu_fault_info *mmfault); + void (*get_mmu_fault_gpc_desc)(struct mmu_fault_info *mmfault); + void (*apply_pb_timeout)(struct gk20a *g); + void (*apply_ctxsw_timeout_intr)(struct gk20a *g); + int (*wait_engine_idle)(struct gk20a *g); + u32 (*get_num_fifos)(struct gk20a *g); + u32 (*get_pbdma_signature)(struct gk20a *g); + int (*set_runlist_interleave)(struct gk20a *g, u32 id, + u32 runlist_id, + u32 new_level); + int (*tsg_set_timeslice)(struct tsg_gk20a *tsg, u32 timeslice); + u32 (*default_timeslice_us)(struct gk20a *); + int (*force_reset_ch)(struct channel_gk20a *ch, + u32 err_code, bool verbose); + int (*engine_enum_from_type)(struct gk20a *g, u32 engine_type, + u32 *inst_id); + void (*device_info_data_parse)(struct gk20a *g, + u32 table_entry, u32 *inst_id, + u32 *pri_base, u32 *fault_id); + u32 (*device_info_fault_id)(u32 table_entry); + int (*tsg_bind_channel)(struct tsg_gk20a *tsg, + struct channel_gk20a *ch); + int (*tsg_unbind_channel)(struct channel_gk20a *ch); + int (*tsg_open)(struct tsg_gk20a *tsg); + void (*tsg_release)(struct tsg_gk20a *tsg); + u32 (*eng_runlist_base_size)(void); + int (*init_engine_info)(struct fifo_gk20a *f); + u32 (*runlist_entry_size)(void); + void (*get_tsg_runlist_entry)(struct tsg_gk20a *tsg, + u32 *runlist); + void (*get_ch_runlist_entry)(struct channel_gk20a *ch, + u32 *runlist); + u32 (*userd_gp_get)(struct gk20a *g, struct channel_gk20a *ch); + void (*userd_gp_put)(struct gk20a *g, struct channel_gk20a *ch); + u64 (*userd_pb_get)(struct gk20a *g, struct channel_gk20a *ch); + void (*free_channel_ctx_header)(struct channel_gk20a *ch); + bool (*is_fault_engine_subid_gpc)(struct gk20a *g, + u32 engine_subid); + void (*dump_pbdma_status)(struct gk20a *g, + struct gk20a_debug_output *o); + void (*dump_eng_status)(struct gk20a *g, + struct gk20a_debug_output *o); + void (*dump_channel_status_ramfc)(struct gk20a *g, + struct gk20a_debug_output *o, u32 chid, + struct ch_state *ch_state); + u32 (*intr_0_error_mask)(struct gk20a *g); + int (*is_preempt_pending)(struct gk20a *g, u32 id, + unsigned int id_type); + void (*init_pbdma_intr_descs)(struct fifo_gk20a *f); + int (*reset_enable_hw)(struct gk20a *g); + int (*setup_userd)(struct channel_gk20a *c); + u32 (*pbdma_acquire_val)(u64 timeout); + void (*teardown_ch_tsg)(struct gk20a *g, u32 act_eng_bitmask, + u32 id, unsigned int id_type, unsigned int rc_type, + struct mmu_fault_info *mmfault); + void (*teardown_mask_intr)(struct gk20a *g); + void (*teardown_unmask_intr)(struct gk20a *g); + bool (*handle_sched_error)(struct gk20a *g); + bool (*handle_ctxsw_timeout)(struct gk20a *g, u32 fifo_intr); + unsigned int (*handle_pbdma_intr_0)(struct gk20a *g, + u32 pbdma_id, u32 pbdma_intr_0, + u32 *handled, u32 *error_notifier); + unsigned int (*handle_pbdma_intr_1)(struct gk20a *g, + u32 pbdma_id, u32 pbdma_intr_1, + u32 *handled, u32 *error_notifier); + void (*init_eng_method_buffers)(struct gk20a *g, + struct tsg_gk20a *tsg); + void (*deinit_eng_method_buffers)(struct gk20a *g, + struct tsg_gk20a *tsg); + u32 (*get_preempt_timeout)(struct gk20a *g); + void (*post_event_id)(struct tsg_gk20a *tsg, int event_id); + void (*ch_abort_clean_up)(struct channel_gk20a *ch); + bool (*check_tsg_ctxsw_timeout)(struct tsg_gk20a *tsg, + bool *verbose, u32 *ms); + bool (*check_ch_ctxsw_timeout)(struct channel_gk20a *ch, + bool *verbose, u32 *ms); + int (*channel_suspend)(struct gk20a *g); + int (*channel_resume)(struct gk20a *g); + void (*set_error_notifier)(struct channel_gk20a *ch, u32 error); +#ifdef CONFIG_TEGRA_GK20A_NVHOST + int (*alloc_syncpt_buf)(struct channel_gk20a *c, + u32 syncpt_id, struct nvgpu_mem *syncpt_buf); + void (*free_syncpt_buf)(struct channel_gk20a *c, + struct nvgpu_mem *syncpt_buf); + void (*add_syncpt_wait_cmd)(struct gk20a *g, + struct priv_cmd_entry *cmd, u32 off, + u32 id, u32 thresh, u64 gpu_va); + u32 (*get_syncpt_wait_cmd_size)(void); + void (*add_syncpt_incr_cmd)(struct gk20a *g, + bool wfi_cmd, struct priv_cmd_entry *cmd, + u32 id, u64 gpu_va); + u32 (*get_syncpt_incr_cmd_size)(bool wfi_cmd); + int (*get_sync_ro_map)(struct vm_gk20a *vm, + u64 *base_gpuva, u32 *sync_size); + u32 (*get_syncpt_incr_per_release)(void); +#endif + void (*runlist_hw_submit)(struct gk20a *g, u32 runlist_id, + u32 count, u32 buffer_index); + int (*runlist_wait_pending)(struct gk20a *g, u32 runlist_id); + void (*ring_channel_doorbell)(struct channel_gk20a *c); + u64 (*usermode_base)(struct gk20a *g); + u32 (*get_sema_wait_cmd_size)(void); + u32 (*get_sema_incr_cmd_size)(void); + void (*add_sema_cmd)(struct gk20a *g, + struct nvgpu_semaphore *s, u64 sema_va, + struct priv_cmd_entry *cmd, + u32 off, bool acquire, bool wfi); + int (*init_pdb_cache_war)(struct gk20a *g); + void (*deinit_pdb_cache_war)(struct gk20a *g); + } fifo; + struct pmu_v { + u32 (*get_pmu_cmdline_args_size)(struct nvgpu_pmu *pmu); + void (*set_pmu_cmdline_args_cpu_freq)(struct nvgpu_pmu *pmu, + u32 freq); + void (*set_pmu_cmdline_args_trace_size)(struct nvgpu_pmu *pmu, + u32 size); + void (*set_pmu_cmdline_args_trace_dma_base)( + struct nvgpu_pmu *pmu); + void (*config_pmu_cmdline_args_super_surface)( + struct nvgpu_pmu *pmu); + void (*set_pmu_cmdline_args_trace_dma_idx)( + struct nvgpu_pmu *pmu, u32 idx); + void * (*get_pmu_cmdline_args_ptr)(struct nvgpu_pmu *pmu); + u32 (*get_pmu_allocation_struct_size)(struct nvgpu_pmu *pmu); + void (*set_pmu_allocation_ptr)(struct nvgpu_pmu *pmu, + void **pmu_alloc_ptr, void *assign_ptr); + void (*pmu_allocation_set_dmem_size)(struct nvgpu_pmu *pmu, + void *pmu_alloc_ptr, u16 size); + u16 (*pmu_allocation_get_dmem_size)(struct nvgpu_pmu *pmu, + void *pmu_alloc_ptr); + u32 (*pmu_allocation_get_dmem_offset)(struct nvgpu_pmu *pmu, + void *pmu_alloc_ptr); + u32 * (*pmu_allocation_get_dmem_offset_addr)( + struct nvgpu_pmu *pmu, void *pmu_alloc_ptr); + void (*pmu_allocation_set_dmem_offset)(struct nvgpu_pmu *pmu, + void *pmu_alloc_ptr, u32 offset); + void * (*pmu_allocation_get_fb_addr)( + struct nvgpu_pmu *pmu, void *pmu_alloc_ptr); + u32 (*pmu_allocation_get_fb_size)( + struct nvgpu_pmu *pmu, void *pmu_alloc_ptr); + void (*get_pmu_init_msg_pmu_queue_params)( + struct nvgpu_falcon_queue *queue, u32 id, + void *pmu_init_msg); + void *(*get_pmu_msg_pmu_init_msg_ptr)( + struct pmu_init_msg *init); + u16 (*get_pmu_init_msg_pmu_sw_mg_off)( + union pmu_init_msg_pmu *init_msg); + u16 (*get_pmu_init_msg_pmu_sw_mg_size)( + union pmu_init_msg_pmu *init_msg); + u32 (*get_pmu_perfmon_cmd_start_size)(void); + int (*get_perfmon_cmd_start_offsetofvar)( + enum pmu_perfmon_cmd_start_fields field); + void (*perfmon_start_set_cmd_type)(struct pmu_perfmon_cmd *pc, + u8 value); + void (*perfmon_start_set_group_id)(struct pmu_perfmon_cmd *pc, + u8 value); + void (*perfmon_start_set_state_id)(struct pmu_perfmon_cmd *pc, + u8 value); + void (*perfmon_start_set_flags)(struct pmu_perfmon_cmd *pc, + u8 value); + u8 (*perfmon_start_get_flags)(struct pmu_perfmon_cmd *pc); + u32 (*get_pmu_perfmon_cmd_init_size)(void); + int (*get_perfmon_cmd_init_offsetofvar)( + enum pmu_perfmon_cmd_start_fields field); + void (*perfmon_cmd_init_set_sample_buffer)( + struct pmu_perfmon_cmd *pc, u16 value); + void (*perfmon_cmd_init_set_dec_cnt)( + struct pmu_perfmon_cmd *pc, u8 value); + void (*perfmon_cmd_init_set_base_cnt_id)( + struct pmu_perfmon_cmd *pc, u8 value); + void (*perfmon_cmd_init_set_samp_period_us)( + struct pmu_perfmon_cmd *pc, u32 value); + void (*perfmon_cmd_init_set_num_cnt)(struct pmu_perfmon_cmd *pc, + u8 value); + void (*perfmon_cmd_init_set_mov_avg)(struct pmu_perfmon_cmd *pc, + u8 value); + void *(*get_pmu_seq_in_a_ptr)( + struct pmu_sequence *seq); + void *(*get_pmu_seq_out_a_ptr)( + struct pmu_sequence *seq); + void (*set_pmu_cmdline_args_secure_mode)(struct nvgpu_pmu *pmu, + u32 val); + u32 (*get_perfmon_cntr_sz)(struct nvgpu_pmu *pmu); + void * (*get_perfmon_cntr_ptr)(struct nvgpu_pmu *pmu); + void (*set_perfmon_cntr_ut)(struct nvgpu_pmu *pmu, u16 ut); + void (*set_perfmon_cntr_lt)(struct nvgpu_pmu *pmu, u16 lt); + void (*set_perfmon_cntr_valid)(struct nvgpu_pmu *pmu, u8 val); + void (*set_perfmon_cntr_index)(struct nvgpu_pmu *pmu, u8 val); + void (*set_perfmon_cntr_group_id)(struct nvgpu_pmu *pmu, + u8 gid); + + u8 (*pg_cmd_eng_buf_load_size)(struct pmu_pg_cmd *pg); + void (*pg_cmd_eng_buf_load_set_cmd_type)(struct pmu_pg_cmd *pg, + u8 value); + void (*pg_cmd_eng_buf_load_set_engine_id)(struct pmu_pg_cmd *pg, + u8 value); + void (*pg_cmd_eng_buf_load_set_buf_idx)(struct pmu_pg_cmd *pg, + u8 value); + void (*pg_cmd_eng_buf_load_set_pad)(struct pmu_pg_cmd *pg, + u8 value); + void (*pg_cmd_eng_buf_load_set_buf_size)(struct pmu_pg_cmd *pg, + u16 value); + void (*pg_cmd_eng_buf_load_set_dma_base)(struct pmu_pg_cmd *pg, + u32 value); + void (*pg_cmd_eng_buf_load_set_dma_offset)(struct pmu_pg_cmd *pg, + u8 value); + void (*pg_cmd_eng_buf_load_set_dma_idx)(struct pmu_pg_cmd *pg, + u8 value); + struct { + int (*boardobjgrp_pmucmd_construct_impl) + (struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid, + u16 hdrsize, u16 entrysize, u16 fbsize, u32 ss_offset, + u8 rpc_func_id); + int (*boardobjgrp_pmuset_impl)(struct gk20a *g, + struct boardobjgrp *pboardobjgrp); + int (*boardobjgrp_pmugetstatus_impl)(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrpmask *mask); + int (*is_boardobjgrp_pmucmd_id_valid)(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd); + } boardobj; + struct { + u32 (*volt_set_voltage)(struct gk20a *g, + u32 logic_voltage_uv, u32 sram_voltage_uv); + u32 (*volt_get_voltage)(struct gk20a *g, + u8 volt_domain, u32 *pvoltage_uv); + u32 (*volt_send_load_cmd_to_pmu)(struct gk20a *g); + } volt; + struct { + u32 (*get_vbios_clk_domain)(u32 vbios_domain); + u32 (*clk_avfs_get_vin_cal_data)(struct gk20a *g, + struct avfsvinobjs *pvinobjs, + struct vin_device_v20 *pvindev); + u32 (*clk_vf_change_inject_data_fill)(struct gk20a *g, + struct nv_pmu_clk_rpc *rpccall, + struct set_fll_clk *setfllclk); + u32 (*clk_set_boot_clk)(struct gk20a *g); + }clk; + } pmu_ver; + struct { + int (*get_netlist_name)(struct gk20a *g, int index, char *name); + bool (*is_fw_defined)(void); + } gr_ctx; +#ifdef CONFIG_GK20A_CTXSW_TRACE + /* + * Currently only supported on Linux due to the extremely tight + * integration with Linux device driver structure (in particular + * mmap). + */ + struct { + int (*init)(struct gk20a *g); + int (*max_entries)(struct gk20a *, + struct nvgpu_gpu_ctxsw_trace_filter *filter); + int (*flush)(struct gk20a *g); + int (*poll)(struct gk20a *g); + int (*enable)(struct gk20a *g); + int (*disable)(struct gk20a *g); + bool (*is_enabled)(struct gk20a *g); + int (*reset)(struct gk20a *g); + int (*bind_channel)(struct gk20a *g, struct channel_gk20a *ch); + int (*unbind_channel)(struct gk20a *g, + struct channel_gk20a *ch); + int (*deinit)(struct gk20a *g); + int (*alloc_user_buffer)(struct gk20a *g, + void **buf, size_t *size); + int (*free_user_buffer)(struct gk20a *g); + int (*mmap_user_buffer)(struct gk20a *g, + struct vm_area_struct *vma); + int (*set_filter)(struct gk20a *g, + struct nvgpu_gpu_ctxsw_trace_filter *filter); + } fecs_trace; +#endif + struct { + bool (*support_sparse)(struct gk20a *g); + u64 (*gmmu_map)(struct vm_gk20a *vm, + u64 map_offset, + struct nvgpu_sgt *sgt, + u64 buffer_offset, + u64 size, + u32 pgsz_idx, + u8 kind_v, + u32 ctag_offset, + u32 flags, + enum gk20a_mem_rw_flag rw_flag, + bool clear_ctags, + bool sparse, + bool priv, + struct vm_gk20a_mapping_batch *batch, + enum nvgpu_aperture aperture); + void (*gmmu_unmap)(struct vm_gk20a *vm, + u64 vaddr, + u64 size, + u32 pgsz_idx, + bool va_allocated, + enum gk20a_mem_rw_flag rw_flag, + bool sparse, + struct vm_gk20a_mapping_batch *batch); + int (*vm_bind_channel)(struct vm_gk20a *vm, + struct channel_gk20a *ch); + int (*fb_flush)(struct gk20a *g); + void (*l2_invalidate)(struct gk20a *g); + void (*l2_flush)(struct gk20a *g, bool invalidate); + void (*cbc_clean)(struct gk20a *g); + void (*set_big_page_size)(struct gk20a *g, + struct nvgpu_mem *mem, int size); + u32 (*get_big_page_sizes)(void); + u32 (*get_default_big_page_size)(void); + u32 (*get_iommu_bit)(struct gk20a *g); + int (*init_mm_setup_hw)(struct gk20a *g); + bool (*is_bar1_supported)(struct gk20a *g); + int (*init_bar2_vm)(struct gk20a *g); + void (*remove_bar2_vm)(struct gk20a *g); + const struct gk20a_mmu_level * + (*get_mmu_levels)(struct gk20a *g, u32 big_page_size); + void (*init_pdb)(struct gk20a *g, struct nvgpu_mem *inst_block, + struct vm_gk20a *vm); + u64 (*gpu_phys_addr)(struct gk20a *g, + struct nvgpu_gmmu_attrs *attrs, u64 phys); + int (*alloc_inst_block)(struct gk20a *g, + struct nvgpu_mem *inst_block); + void (*init_inst_block)(struct nvgpu_mem *inst_block, + struct vm_gk20a *vm, u32 big_page_size); + bool (*mmu_fault_pending)(struct gk20a *g); + void (*fault_info_mem_destroy)(struct gk20a *g); + void (*mmu_fault_disable_hw)(struct gk20a *g); + u32 (*get_kind_invalid)(void); + u32 (*get_kind_pitch)(void); + u32 (*get_flush_retries)(struct gk20a *g, + enum nvgpu_flush_op op); + } mm; + /* + * This function is called to allocate secure memory (memory + * that the CPU cannot see). The function should fill the + * context buffer descriptor (especially fields destroy, sgt, + * size). + */ + int (*secure_alloc)(struct gk20a *g, + struct gr_ctx_buffer_desc *desc, + size_t size); + struct { + void (*exit)(struct gk20a *g, struct nvgpu_mem *mem, + struct nvgpu_sgl *sgl); + u32 (*data032_r)(u32 i); + } pramin; + struct { + int (*init_therm_setup_hw)(struct gk20a *g); + void (*init_elcg_mode)(struct gk20a *g, u32 mode, u32 engine); + void (*init_blcg_mode)(struct gk20a *g, u32 mode, u32 engine); + int (*elcg_init_idle_filters)(struct gk20a *g); +#ifdef CONFIG_DEBUG_FS + void (*therm_debugfs_init)(struct gk20a *g); +#endif + int (*get_internal_sensor_curr_temp)(struct gk20a *g, u32 *temp_f24_8); + void (*get_internal_sensor_limits)(s32 *max_24_8, + s32 *min_24_8); + u32 (*configure_therm_alert)(struct gk20a *g, s32 curr_warn_temp); + } therm; + struct { + bool (*is_pmu_supported)(struct gk20a *g); + int (*prepare_ucode)(struct gk20a *g); + int (*pmu_setup_hw_and_bootstrap)(struct gk20a *g); + int (*pmu_nsbootstrap)(struct nvgpu_pmu *pmu); + int (*pmu_init_perfmon)(struct nvgpu_pmu *pmu); + int (*pmu_perfmon_start_sampling)(struct nvgpu_pmu *pmu); + int (*pmu_perfmon_stop_sampling)(struct nvgpu_pmu *pmu); + int (*pmu_perfmon_get_samples_rpc)(struct nvgpu_pmu *pmu); + int (*pmu_setup_elpg)(struct gk20a *g); + u32 (*pmu_get_queue_head)(u32 i); + u32 (*pmu_get_queue_head_size)(void); + u32 (*pmu_get_queue_tail_size)(void); + u32 (*pmu_get_queue_tail)(u32 i); + int (*pmu_queue_head)(struct gk20a *g, + struct nvgpu_falcon_queue *queue, u32 *head, bool set); + int (*pmu_queue_tail)(struct gk20a *g, + struct nvgpu_falcon_queue *queue, u32 *tail, bool set); + void (*pmu_msgq_tail)(struct nvgpu_pmu *pmu, + u32 *tail, bool set); + u32 (*pmu_mutex_size)(void); + int (*pmu_mutex_acquire)(struct nvgpu_pmu *pmu, + u32 id, u32 *token); + int (*pmu_mutex_release)(struct nvgpu_pmu *pmu, + u32 id, u32 *token); + bool (*pmu_is_interrupted)(struct nvgpu_pmu *pmu); + void (*pmu_isr)(struct gk20a *g); + void (*pmu_init_perfmon_counter)(struct gk20a *g); + void (*pmu_pg_idle_counter_config)(struct gk20a *g, u32 pg_engine_id); + u32 (*pmu_read_idle_counter)(struct gk20a *g, u32 counter_id); + u32 (*pmu_read_idle_intr_status)(struct gk20a *g); + void (*pmu_clear_idle_intr_status)(struct gk20a *g); + void (*pmu_reset_idle_counter)(struct gk20a *g, u32 counter_id); + void (*pmu_dump_elpg_stats)(struct nvgpu_pmu *pmu); + void (*pmu_dump_falcon_stats)(struct nvgpu_pmu *pmu); + void (*pmu_enable_irq)(struct nvgpu_pmu *pmu, bool enable); + int (*init_wpr_region)(struct gk20a *g); + int (*load_lsfalcon_ucode)(struct gk20a *g, u32 falconidmask); + void (*write_dmatrfbase)(struct gk20a *g, u32 addr); + void (*pmu_elpg_statistics)(struct gk20a *g, u32 pg_engine_id, + struct pmu_pg_stats_data *pg_stat_data); + int (*pmu_pg_init_param)(struct gk20a *g, u32 pg_engine_id); + int (*pmu_pg_set_sub_feature_mask)(struct gk20a *g, + u32 pg_engine_id); + u32 (*pmu_pg_supported_engines_list)(struct gk20a *g); + u32 (*pmu_pg_engines_feature_list)(struct gk20a *g, + u32 pg_engine_id); + bool (*pmu_is_lpwr_feature_supported)(struct gk20a *g, + u32 feature_id); + int (*pmu_lpwr_enable_pg)(struct gk20a *g, bool pstate_lock); + int (*pmu_lpwr_disable_pg)(struct gk20a *g, bool pstate_lock); + u32 (*pmu_pg_param_post_init)(struct gk20a *g); + void (*dump_secure_fuses)(struct gk20a *g); + int (*reset_engine)(struct gk20a *g, bool do_reset); + bool (*is_engine_in_reset)(struct gk20a *g); + bool (*is_lazy_bootstrap)(u32 falcon_id); + bool (*is_priv_load)(u32 falcon_id); + int (*pmu_populate_loader_cfg)(struct gk20a *g, + void *lsfm, u32 *p_bl_gen_desc_size); + int (*flcn_populate_bl_dmem_desc)(struct gk20a *g, + void *lsfm, u32 *p_bl_gen_desc_size, u32 falconid); + void (*handle_ext_irq)(struct gk20a *g, u32 intr); + void (*set_irqmask)(struct gk20a *g); + void (*update_lspmu_cmdline_args)(struct gk20a *g); + void (*setup_apertures)(struct gk20a *g); + u32 (*get_irqdest)(struct gk20a *g); + int (*alloc_super_surface)(struct gk20a *g, + struct nvgpu_mem *super_surface, u32 size); + bool (*is_debug_mode_enabled)(struct gk20a *g); + void (*secured_pmu_start)(struct gk20a *g); + } pmu; + struct { + int (*init_debugfs)(struct gk20a *g); + void (*disable_slowboot)(struct gk20a *g); + int (*init_clk_support)(struct gk20a *g); + int (*suspend_clk_support)(struct gk20a *g); + u32 (*get_crystal_clk_hz)(struct gk20a *g); + int (*clk_domain_get_f_points)(struct gk20a *g, + u32 clkapidomain, u32 *pfpointscount, + u16 *pfreqpointsinmhz); + int (*clk_get_round_rate)(struct gk20a *g, u32 api_domain, + unsigned long rate_target, unsigned long *rounded_rate); + int (*get_clk_range)(struct gk20a *g, u32 api_domain, + u16 *min_mhz, u16 *max_mhz); + unsigned long (*measure_freq)(struct gk20a *g, u32 api_domain); + u32 (*get_rate_cntr)(struct gk20a *g, struct namemap_cfg *c); + unsigned long (*get_rate)(struct gk20a *g, u32 api_domain); + int (*set_rate)(struct gk20a *g, u32 api_domain, unsigned long rate); + unsigned long (*get_fmax_at_vmin_safe)(struct gk20a *g); + u32 (*get_ref_clock_rate)(struct gk20a *g); + int (*predict_mv_at_hz_cur_tfloor)(struct clk_gk20a *clk, + unsigned long rate); + unsigned long (*get_maxrate)(struct gk20a *g, u32 api_domain); + int (*prepare_enable)(struct clk_gk20a *clk); + void (*disable_unprepare)(struct clk_gk20a *clk); + int (*get_voltage)(struct clk_gk20a *clk, u64 *val); + int (*get_gpcclk_clock_counter)(struct clk_gk20a *clk, u64 *val); + int (*pll_reg_write)(struct gk20a *g, u32 reg, u32 val); + int (*get_pll_debug_data)(struct gk20a *g, + struct nvgpu_clk_pll_debug_data *d); + int (*mclk_init)(struct gk20a *g); + void (*mclk_deinit)(struct gk20a *g); + int (*mclk_change)(struct gk20a *g, u16 val); + bool split_rail_support; + bool support_clk_freq_controller; + bool support_pmgr_domain; + bool support_lpwr_pg; + u32 (*perf_pmu_vfe_load)(struct gk20a *g); + u32 lut_num_entries; + } clk; + struct { + int (*arbiter_clk_init)(struct gk20a *g); + u32 (*get_arbiter_clk_domains)(struct gk20a *g); + int (*get_arbiter_f_points)(struct gk20a *g,u32 api_domain, + u32 *num_points, u16 *freqs_in_mhz); + int (*get_arbiter_clk_range)(struct gk20a *g, u32 api_domain, + u16 *min_mhz, u16 *max_mhz); + int (*get_arbiter_clk_default)(struct gk20a *g, u32 api_domain, + u16 *default_mhz); + void (*clk_arb_run_arbiter_cb)(struct nvgpu_clk_arb *arb); + /* This function is inherently unsafe to call while + * arbiter is running arbiter must be blocked + * before calling this function */ + int (*get_current_pstate)(struct gk20a *g); + void (*clk_arb_cleanup)(struct nvgpu_clk_arb *arb); + } clk_arb; + struct { + int (*handle_pmu_perf_event)(struct gk20a *g, void *pmu_msg); + } pmu_perf; + struct { + int (*exec_regops)(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_reg_op *ops, + u64 num_ops, + bool *is_current_ctx); + const struct regop_offset_range* ( + *get_global_whitelist_ranges)(void); + u64 (*get_global_whitelist_ranges_count)(void); + const struct regop_offset_range* ( + *get_context_whitelist_ranges)(void); + u64 (*get_context_whitelist_ranges_count)(void); + const u32* (*get_runcontrol_whitelist)(void); + u64 (*get_runcontrol_whitelist_count)(void); + const u32* (*get_qctl_whitelist)(void); + u64 (*get_qctl_whitelist_count)(void); + } regops; + struct { + void (*intr_mask)(struct gk20a *g); + void (*intr_enable)(struct gk20a *g); + void (*intr_unit_config)(struct gk20a *g, + bool enable, bool is_stalling, u32 mask); + void (*isr_stall)(struct gk20a *g); + bool (*is_intr_hub_pending)(struct gk20a *g, u32 mc_intr); + bool (*is_intr_nvlink_pending)(struct gk20a *g, u32 mc_intr); + bool (*is_stall_and_eng_intr_pending)(struct gk20a *g, + u32 act_eng_id, u32 *eng_intr_pending); + u32 (*intr_stall)(struct gk20a *g); + void (*intr_stall_pause)(struct gk20a *g); + void (*intr_stall_resume)(struct gk20a *g); + u32 (*intr_nonstall)(struct gk20a *g); + void (*intr_nonstall_pause)(struct gk20a *g); + void (*intr_nonstall_resume)(struct gk20a *g); + u32 (*isr_nonstall)(struct gk20a *g); + void (*enable)(struct gk20a *g, u32 units); + void (*disable)(struct gk20a *g, u32 units); + void (*reset)(struct gk20a *g, u32 units); + bool (*is_enabled)(struct gk20a *g, enum nvgpu_unit unit); + bool (*is_intr1_pending)(struct gk20a *g, enum nvgpu_unit unit, u32 mc_intr_1); + void (*log_pending_intrs)(struct gk20a *g); + void (*fbpa_isr)(struct gk20a *g); + u32 (*reset_mask)(struct gk20a *g, enum nvgpu_unit unit); + void (*fb_reset)(struct gk20a *g); + } mc; + struct { + void (*show_dump)(struct gk20a *g, + struct gk20a_debug_output *o); + } debug; + struct { + int (*dbg_set_powergate)(struct dbg_session_gk20a *dbg_s, + bool disable_powergate); + bool (*check_and_set_global_reservation)( + struct dbg_session_gk20a *dbg_s, + struct dbg_profiler_object_data *prof_obj); + bool (*check_and_set_context_reservation)( + struct dbg_session_gk20a *dbg_s, + struct dbg_profiler_object_data *prof_obj); + void (*release_profiler_reservation)( + struct dbg_session_gk20a *dbg_s, + struct dbg_profiler_object_data *prof_obj); + int (*perfbuffer_enable)(struct gk20a *g, u64 offset, u32 size); + int (*perfbuffer_disable)(struct gk20a *g); + } dbg_session_ops; + + u32 (*get_litter_value)(struct gk20a *g, int value); + int (*chip_init_gpu_characteristics)(struct gk20a *g); + + struct { + void (*init_hw)(struct gk20a *g); + void (*isr)(struct gk20a *g); + int (*bar1_bind)(struct gk20a *g, struct nvgpu_mem *bar1_inst); + int (*bar2_bind)(struct gk20a *g, struct nvgpu_mem *bar1_inst); + u32 (*set_bar0_window)(struct gk20a *g, struct nvgpu_mem *mem, + struct nvgpu_sgt *sgt, struct nvgpu_sgl *sgl, + u32 w); + u32 (*read_sw_scratch)(struct gk20a *g, u32 index); + void (*write_sw_scratch)(struct gk20a *g, u32 index, u32 val); + } bus; + + struct { + void (*isr)(struct gk20a *g); + int (*read_ptimer)(struct gk20a *g, u64 *value); + int (*get_timestamps_zipper)(struct gk20a *g, + u32 source_id, u32 count, + struct nvgpu_cpu_time_correlation_sample *); + } ptimer; + + struct { + int (*init)(struct gk20a *g); + int (*preos_wait_for_halt)(struct gk20a *g); + void (*preos_reload_check)(struct gk20a *g); + int (*devinit)(struct gk20a *g); + int (*preos)(struct gk20a *g); + int (*verify_devinit)(struct gk20a *g); + } bios; + +#if defined(CONFIG_GK20A_CYCLE_STATS) + struct { + int (*enable_snapshot)(struct channel_gk20a *ch, + struct gk20a_cs_snapshot_client *client); + void (*disable_snapshot)(struct gr_gk20a *gr); + int (*check_data_available)(struct channel_gk20a *ch, + u32 *pending, + bool *hw_overflow); + void (*set_handled_snapshots)(struct gk20a *g, u32 num); + u32 (*allocate_perfmon_ids)(struct gk20a_cs_snapshot *data, + u32 count); + u32 (*release_perfmon_ids)(struct gk20a_cs_snapshot *data, + u32 start, + u32 count); + int (*detach_snapshot)(struct channel_gk20a *ch, + struct gk20a_cs_snapshot_client *client); + bool (*get_overflow_status)(struct gk20a *g); + u32 (*get_pending_snapshots)(struct gk20a *g); + } css; +#endif + struct { + int (*get_speed)(struct gk20a *g, u32 *xve_link_speed); + int (*set_speed)(struct gk20a *g, u32 xve_link_speed); + void (*available_speeds)(struct gk20a *g, u32 *speed_mask); + u32 (*xve_readl)(struct gk20a *g, u32 reg); + void (*xve_writel)(struct gk20a *g, u32 reg, u32 val); + void (*disable_aspm)(struct gk20a *g); + void (*reset_gpu)(struct gk20a *g); +#if defined(CONFIG_PCI_MSI) + void (*rearm_msi)(struct gk20a *g); +#endif + void (*enable_shadow_rom)(struct gk20a *g); + void (*disable_shadow_rom)(struct gk20a *g); + u32 (*get_link_control_status)(struct gk20a *g); + } xve; + struct { + int (*falcon_hal_sw_init)(struct nvgpu_falcon *flcn); + } falcon; + struct { + void (*enable_priv_ring)(struct gk20a *g); + void (*isr)(struct gk20a *g); + void (*decode_error_code)(struct gk20a *g, u32 error_code); + void (*set_ppriv_timeout_settings)(struct gk20a *g); + u32 (*enum_ltc)(struct gk20a *g); + } priv_ring; + struct { + int (*check_priv_security)(struct gk20a *g); + bool (*is_opt_ecc_enable)(struct gk20a *g); + bool (*is_opt_feature_override_disable)(struct gk20a *g); + u32 (*fuse_status_opt_fbio)(struct gk20a *g); + u32 (*fuse_status_opt_fbp)(struct gk20a *g); + u32 (*fuse_status_opt_rop_l2_fbp)(struct gk20a *g, u32 fbp); + u32 (*fuse_status_opt_gpc)(struct gk20a *g); + u32 (*fuse_status_opt_tpc_gpc)(struct gk20a *g, u32 gpc); + void (*fuse_ctrl_opt_tpc_gpc)(struct gk20a *g, u32 gpc, u32 val); + u32 (*fuse_opt_sec_debug_en)(struct gk20a *g); + u32 (*fuse_opt_priv_sec_en)(struct gk20a *g); + u32 (*read_vin_cal_fuse_rev)(struct gk20a *g); + u32 (*read_vin_cal_slope_intercept_fuse)(struct gk20a *g, + u32 vin_id, u32 *slope, + u32 *intercept); + u32 (*read_vin_cal_gain_offset_fuse)(struct gk20a *g, + u32 vin_id, s8 *gain, + s8 *offset); + } fuse; + struct { + int (*init)(struct gk20a *g); + int (*discover_ioctrl)(struct gk20a *g); + int (*discover_link)(struct gk20a *g); + int (*isr)(struct gk20a *g); + int (*rxdet)(struct gk20a *g, u32 link_id); + int (*setup_pll)(struct gk20a *g, unsigned long link_mask); + int (*minion_data_ready_en)(struct gk20a *g, + unsigned long link_mask, bool sync); + void (*get_connected_link_mask)(u32 *link_mask); + void (*set_sw_war)(struct gk20a *g, u32 link_id); + /* API */ + int (*link_early_init)(struct gk20a *g, unsigned long mask); + u32 (*link_get_mode)(struct gk20a *g, u32 link_id); + u32 (*link_get_state)(struct gk20a *g, u32 link_id); + int (*link_set_mode)(struct gk20a *g, u32 link_id, u32 mode); + u32 (*get_sublink_mode)(struct gk20a *g, u32 link_id, + bool is_rx_sublink); + u32 (*get_rx_sublink_state)(struct gk20a *g, u32 link_id); + u32 (*get_tx_sublink_state)(struct gk20a *g, u32 link_id); + int (*set_sublink_mode)(struct gk20a *g, u32 link_id, + bool is_rx_sublink, u32 mode); + int (*interface_init)(struct gk20a *g); + int (*interface_disable)(struct gk20a *g); + int (*reg_init)(struct gk20a *g); + int (*shutdown)(struct gk20a *g); + int (*early_init)(struct gk20a *g); + } nvlink; + struct { + u32 (*get_nvhsclk_ctrl_e_clk_nvl)(struct gk20a *g); + void (*set_nvhsclk_ctrl_e_clk_nvl)(struct gk20a *g, u32 val); + u32 (*get_nvhsclk_ctrl_swap_clk_nvl)(struct gk20a *g); + void (*set_nvhsclk_ctrl_swap_clk_nvl)(struct gk20a *g, u32 val); + } top; + struct { + void (*acr_sw_init)(struct gk20a *g, struct nvgpu_acr *acr); + } acr; + struct { + int (*tpc_powergate)(struct gk20a *g, u32 fuse_status); + } tpc; + void (*semaphore_wakeup)(struct gk20a *g, bool post_events); +}; + +struct nvgpu_bios_ucode { + u8 *bootloader; + u32 bootloader_phys_base; + u32 bootloader_size; + u8 *ucode; + u32 phys_base; + u32 size; + u8 *dmem; + u32 dmem_phys_base; + u32 dmem_size; + u32 code_entry_point; +}; + +struct nvgpu_bios { + u32 vbios_version; + u8 vbios_oem_version; + + u8 *data; + size_t size; + + struct nvgpu_bios_ucode devinit; + struct nvgpu_bios_ucode preos; + + u8 *devinit_tables; + u32 devinit_tables_size; + u8 *bootscripts; + u32 bootscripts_size; + + u8 mem_strap_data_count; + u16 mem_strap_xlat_tbl_ptr; + + u32 condition_table_ptr; + + u32 devinit_tables_phys_base; + u32 devinit_script_phys_base; + + struct bit_token *perf_token; + struct bit_token *clock_token; + struct bit_token *virt_token; + u32 expansion_rom_offset; + + u32 nvlink_config_data_offset; +}; + +struct nvgpu_gpu_params { + /* GPU architecture ID */ + u32 gpu_arch; + /* GPU implementation ID */ + u32 gpu_impl; + /* GPU revision ID */ + u32 gpu_rev; + /* sm version */ + u32 sm_arch_sm_version; + /* sm instruction set */ + u32 sm_arch_spa_version; + u32 sm_arch_warp_count; +}; + +struct gk20a { + void (*free)(struct gk20a *g); + struct nvgpu_nvhost_dev *nvhost_dev; + + /* + * Used by . Do not access directly! + */ + unsigned long *enabled_flags; + +#ifdef __KERNEL__ + struct notifier_block nvgpu_reboot_nb; +#endif + + nvgpu_atomic_t usage_count; + + struct nvgpu_mutex ctxsw_disable_lock; + int ctxsw_disable_count; + + struct nvgpu_ref refcount; + + const char *name; + + bool gpu_reset_done; + bool power_on; + bool suspended; + bool sw_ready; + + u64 log_mask; + u32 log_trace; + + struct nvgpu_mutex tpc_pg_lock; + + struct nvgpu_gpu_params params; + + /* + * Guards access to hardware when usual gk20a_{busy,idle} are skipped + * for submits and held for channel lifetime but dropped for an ongoing + * gk20a_do_idle(). + */ + struct nvgpu_rwsem deterministic_busy; + + struct nvgpu_falcon pmu_flcn; + struct nvgpu_falcon sec2_flcn; + struct nvgpu_falcon fecs_flcn; + struct nvgpu_falcon gpccs_flcn; + struct nvgpu_falcon nvdec_flcn; + struct nvgpu_falcon minion_flcn; + struct nvgpu_falcon gsp_flcn; + struct clk_gk20a clk; + struct fifo_gk20a fifo; + struct nvgpu_nvlink_dev nvlink; + struct gr_gk20a gr; + struct sim_nvgpu *sim; + struct mm_gk20a mm; + struct nvgpu_pmu pmu; + struct nvgpu_acr acr; + struct nvgpu_ecc ecc; + struct clk_pmupstate clk_pmu; + struct perf_pmupstate perf_pmu; + struct pmgr_pmupstate pmgr_pmu; + struct therm_pmupstate therm_pmu; + struct nvgpu_sec2 sec2; + struct nvgpu_sched_ctrl sched_ctrl; + +#ifdef CONFIG_DEBUG_FS + struct railgate_stats pstats; +#endif + u32 gr_idle_timeout_default; + bool timeouts_disabled_by_user; + unsigned int ch_wdt_timeout_ms; + u32 fifo_eng_timeout_us; + + struct nvgpu_mutex power_lock; + + /* Channel priorities */ + u32 timeslice_low_priority_us; + u32 timeslice_medium_priority_us; + u32 timeslice_high_priority_us; + u32 min_timeslice_us; + u32 max_timeslice_us; + bool runlist_interleave; + + struct nvgpu_mutex cg_pg_lock; + bool slcg_enabled; + bool blcg_enabled; + bool elcg_enabled; + bool elpg_enabled; + bool aelpg_enabled; + bool can_elpg; + bool mscg_enabled; + bool forced_idle; + bool forced_reset; + bool allow_all; + + u32 ptimer_src_freq; + + int railgate_delay; + u8 ldiv_slowdown_factor; + unsigned int aggressive_sync_destroy_thresh; + bool aggressive_sync_destroy; + + /* Debugfs knob for forcing syncpt support off in runtime. */ + u32 disable_syncpoints; + + bool support_pmu; + + bool is_virtual; + + bool has_cde; + + u32 emc3d_ratio; + + struct nvgpu_spinlock ltc_enabled_lock; + + struct gk20a_ctxsw_ucode_info ctxsw_ucode_info; + + /* + * A group of semaphore pools. One for each channel. + */ + struct nvgpu_semaphore_sea *sema_sea; + + /* held while manipulating # of debug/profiler sessions present */ + /* also prevents debug sessions from attaching until released */ + struct nvgpu_mutex dbg_sessions_lock; + int dbg_powergating_disabled_refcount; /*refcount for pg disable */ + /*refcount for timeout disable */ + nvgpu_atomic_t timeouts_disabled_refcount; + + /* must have dbg_sessions_lock before use */ + struct nvgpu_dbg_reg_op *dbg_regops_tmp_buf; + u32 dbg_regops_tmp_buf_ops; + + /* For perfbuf mapping */ + struct { + struct dbg_session_gk20a *owner; + u64 offset; + } perfbuf; + + /* For profiler reservations */ + struct nvgpu_list_node profiler_objects; + bool global_profiler_reservation_held; + int profiler_reservation_count; + + void (*remove_support)(struct gk20a *); + + u64 pg_ingating_time_us; + u64 pg_ungating_time_us; + u32 pg_gating_cnt; + + struct nvgpu_spinlock mc_enable_lock; + + struct gk20a_as as; + + struct nvgpu_mutex client_lock; + int client_refcount; /* open channels and ctrl nodes */ + + struct gpu_ops ops; + u32 mc_intr_mask_restore[4]; + /*used for change of enum zbc update cmd id from ver 0 to ver1*/ + u32 pmu_ver_cmd_id_zbc_table_update; + u32 pmu_lsf_pmu_wpr_init_done; + u32 pmu_lsf_loaded_falcon_id; + + int irqs_enabled; + int irq_stall; /* can be same as irq_nonstall in case of PCI */ + int irq_nonstall; + u32 max_ltc_count; + u32 ltc_count; + u32 ltc_streamid; + + struct gk20a_worker { + struct nvgpu_thread poll_task; + nvgpu_atomic_t put; + struct nvgpu_cond wq; + struct nvgpu_list_node items; + struct nvgpu_spinlock items_lock; + struct nvgpu_mutex start_lock; + } channel_worker, clk_arb_worker; + + struct { + void (*open)(struct channel_gk20a *ch); + void (*close)(struct channel_gk20a *ch); + void (*work_completion_signal)(struct channel_gk20a *ch); + void (*work_completion_cancel_sync)(struct channel_gk20a *ch); + bool (*os_fence_framework_inst_exists)(struct channel_gk20a *ch); + int (*init_os_fence_framework)( + struct channel_gk20a *ch, const char *fmt, ...); + void (*signal_os_fence_framework)(struct channel_gk20a *ch); + void (*destroy_os_fence_framework)(struct channel_gk20a *ch); + int (*copy_user_gpfifo)(struct nvgpu_gpfifo_entry *dest, + struct nvgpu_gpfifo_userdata userdata, + u32 start, u32 length); + int (*alloc_usermode_buffers)(struct channel_gk20a *c, + struct nvgpu_setup_bind_args *args); + void (*free_usermode_buffers)(struct channel_gk20a *c); + } os_channel; + + struct gk20a_scale_profile *scale_profile; + unsigned long last_freq; + + struct gk20a_ctxsw_trace *ctxsw_trace; + struct gk20a_fecs_trace *fecs_trace; + + bool mmu_debug_ctrl; + u32 mmu_debug_mode_refcnt; + + u32 tpc_fs_mask_user; + + u32 tpc_pg_mask; + u32 tpc_count; + bool can_tpc_powergate; + + u32 valid_tpc_mask[MAX_TPC_PG_CONFIGS]; + + struct nvgpu_bios bios; + bool bios_is_init; + + struct nvgpu_clk_arb *clk_arb; + + struct nvgpu_mutex clk_arb_enable_lock; + + nvgpu_atomic_t clk_arb_global_nr; + + struct gk20a_ce_app ce_app; + + bool ltc_intr_en_illegal_compstat; + + /* PCI device identifier */ + u16 pci_vendor_id, pci_device_id; + u16 pci_subsystem_vendor_id, pci_subsystem_device_id; + u16 pci_class; + u8 pci_revision; + + /* + * PCI power management: i2c device index, port and address for + * INA3221. + */ + u32 ina3221_dcb_index; + u32 ina3221_i2c_address; + u32 ina3221_i2c_port; + bool hardcode_sw_threshold; + + /* PCIe power states. */ + bool xve_l0s; + bool xve_l1; + + /* Current warning temp in sfxp24.8 */ + s32 curr_warn_temp; + +#if defined(CONFIG_PCI_MSI) + /* Check if msi is enabled */ + bool msi_enabled; +#endif +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE + struct nvgpu_mem_alloc_tracker *vmallocs; + struct nvgpu_mem_alloc_tracker *kmallocs; +#endif + + /* The minimum VBIOS version supported */ + u32 vbios_min_version; + + /* memory training sequence and mclk switch scripts */ + u32 mem_config_idx; + + u64 dma_memory_used; + +#if defined(CONFIG_TEGRA_GK20A_NVHOST) + u64 syncpt_unit_base; + size_t syncpt_unit_size; + u32 syncpt_size; +#endif + struct nvgpu_mem syncpt_mem; + + struct nvgpu_list_node boardobj_head; + struct nvgpu_list_node boardobjgrp_head; + + struct nvgpu_mem pdb_cache_war_mem; +}; + +static inline bool nvgpu_is_timeouts_enabled(struct gk20a *g) +{ + return nvgpu_atomic_read(&g->timeouts_disabled_refcount) == 0; +} + +static inline u32 gk20a_get_gr_idle_timeout(struct gk20a *g) +{ + return nvgpu_is_timeouts_enabled(g) ? + g->gr_idle_timeout_default : UINT_MAX; +} + +#define MULTICHAR_TAG(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) +enum BAR0_DEBUG_OPERATION { + BARO_ZERO_NOP = 0, + OP_END = MULTICHAR_TAG('D', 'O', 'N', 'E'), + BAR0_READ32 = MULTICHAR_TAG('0', 'R', '3', '2'), + BAR0_WRITE32 = MULTICHAR_TAG('0', 'W', '3', '2'), +}; + +struct share_buffer_head { + enum BAR0_DEBUG_OPERATION operation; +/* size of the operation item */ + u32 size; + u32 completed; + u32 failed; + u64 context; + u64 completion_callback; +}; + +struct gk20a_cyclestate_buffer_elem { + struct share_buffer_head head; +/* in */ + u64 p_data; + u64 p_done; + u32 offset_bar0; + u16 first_bit; + u16 last_bit; +/* out */ +/* keep 64 bits to be consistent */ + u64 data; +}; + +/* operations that will need to be executed on non stall workqueue */ +#define GK20A_NONSTALL_OPS_WAKEUP_SEMAPHORE BIT32(0) +#define GK20A_NONSTALL_OPS_POST_EVENTS BIT32(1) + +/* register accessors */ +void __nvgpu_check_gpu_state(struct gk20a *g); +void __gk20a_warn_on_no_regs(void); + +/* classes that the device supports */ +/* TBD: get these from an open-sourced SDK? */ +enum { + FERMI_TWOD_A = 0x902D, + KEPLER_INLINE_TO_MEMORY_A = 0xA040, + KEPLER_DMA_COPY_A = 0xA0B5, +}; + +#define GK20A_BAR0_IORESOURCE_MEM 0 +#define GK20A_BAR1_IORESOURCE_MEM 1 +#define GK20A_SIM_IORESOURCE_MEM 2 + +void gk20a_busy_noresume(struct gk20a *g); +void gk20a_idle_nosuspend(struct gk20a *g); +int __must_check gk20a_busy(struct gk20a *g); +void gk20a_idle(struct gk20a *g); +int __gk20a_do_idle(struct gk20a *g, bool force_reset); +int __gk20a_do_unidle(struct gk20a *g); + +int gk20a_wait_for_idle(struct gk20a *g); + +#define NVGPU_GPU_ARCHITECTURE_SHIFT 4 + +/* constructs unique and compact GPUID from nvgpu_gpu_characteristics + * arch/impl fields */ +#define GK20A_GPUID(arch, impl) ((u32) ((arch) | (impl))) + +#define GK20A_GPUID_GK20A 0x000000EA +#define GK20A_GPUID_GM20B 0x0000012B +#define GK20A_GPUID_GM20B_B 0x0000012E +#define NVGPU_GPUID_GP10B 0x0000013B +#define NVGPU_GPUID_GP104 0x00000134 +#define NVGPU_GPUID_GP106 0x00000136 +#define NVGPU_GPUID_GV11B 0x0000015B +#define NVGPU_GPUID_GV100 0x00000140 + +int gk20a_init_gpu_characteristics(struct gk20a *g); + +bool gk20a_check_poweron(struct gk20a *g); +int gk20a_prepare_poweroff(struct gk20a *g); +int gk20a_finalize_poweron(struct gk20a *g); + +void nvgpu_wait_for_deferred_interrupts(struct gk20a *g); + +struct gk20a * __must_check gk20a_get(struct gk20a *g); +void gk20a_put(struct gk20a *g); + +bool nvgpu_has_syncpoints(struct gk20a *g); + +#endif /* GK20A_H */ diff --git a/include/nvgpu/gmmu.h b/include/nvgpu/gmmu.h new file mode 100644 index 0000000..2fc0d44 --- /dev/null +++ b/include/nvgpu/gmmu.h @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2017-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_GMMU_H +#define NVGPU_GMMU_H + +#include +#include +#include +#include +#include +#include +#include + +/* + * This is the GMMU API visible to blocks outside of the GMMU. Basically this + * API supports all the different types of mappings that might be done in the + * GMMU. + */ + +struct vm_gk20a; +struct nvgpu_mem; + +#define GMMU_PAGE_SIZE_SMALL 0U +#define GMMU_PAGE_SIZE_BIG 1U +#define GMMU_PAGE_SIZE_KERNEL 2U +#define GMMU_NR_PAGE_SIZES 3U + +enum gk20a_mem_rw_flag { + gk20a_mem_flag_none = 0, /* RW */ + gk20a_mem_flag_read_only = 1, /* RO */ + gk20a_mem_flag_write_only = 2, /* WO */ +}; + +/* + * Minimum size of a cache. The number of different caches in the nvgpu_pd_cache + * structure is of course depending on this. The MIN_SHIFT define is the right + * number of bits to shift to determine which list to use in the array of lists. + * + * For Linux, limit the use of the cache to entries less than the page size, to + * avoid potential problems with running out of CMA memory when allocating large, + * contiguous slabs, as would be required for non-iommmuable chips. + */ +#define NVGPU_PD_CACHE_MIN 256U +#define NVGPU_PD_CACHE_MIN_SHIFT 9U + +#ifdef __KERNEL__ + +#if PAGE_SIZE == 4096 +#define NVGPU_PD_CACHE_COUNT 4U +#elif PAGE_SIZE == 65536 +#define NVGPU_PD_CACHE_COUNT 8U +#else +#error "Unsupported page size." +#endif + +#else +#define NVGPU_PD_CACHE_COUNT 8U +#endif + +#define NVGPU_PD_CACHE_SIZE (NVGPU_PD_CACHE_MIN * (1U << NVGPU_PD_CACHE_COUNT)) + +struct nvgpu_pd_mem_entry { + struct nvgpu_mem mem; + + /* + * Size of the page directories (not the mem). alloc_map is a bitmap + * showing which PDs have been allocated. + * + * The size of mem will be NVGPU_PD_CACHE_SIZE + * and pd_size will always be a power of 2. + * + */ + u32 pd_size; + DECLARE_BITMAP(alloc_map, NVGPU_PD_CACHE_SIZE / NVGPU_PD_CACHE_MIN); + + /* Total number of allocations in this PD. */ + u32 allocs; + + struct nvgpu_list_node list_entry; + struct nvgpu_rbtree_node tree_entry; +}; + +static inline struct nvgpu_pd_mem_entry * +nvgpu_pd_mem_entry_from_list_entry(struct nvgpu_list_node *node) +{ + return (struct nvgpu_pd_mem_entry *) + ((uintptr_t)node - + offsetof(struct nvgpu_pd_mem_entry, list_entry)); +}; + +static inline struct nvgpu_pd_mem_entry * +nvgpu_pd_mem_entry_from_tree_entry(struct nvgpu_rbtree_node *node) +{ + return (struct nvgpu_pd_mem_entry *) + ((uintptr_t)node - + offsetof(struct nvgpu_pd_mem_entry, tree_entry)); +}; + +/* + * A cache for allocating PD memory from. This enables smaller PDs to be packed + * into single pages. + * + * This is fairly complex so see the documentation in pd_cache.c for a full + * description of how this is organized. + */ +struct nvgpu_pd_cache { + /* + * Array of lists of full nvgpu_pd_mem_entries and partially full (or + * empty) nvgpu_pd_mem_entries. + */ + struct nvgpu_list_node full[NVGPU_PD_CACHE_COUNT]; + struct nvgpu_list_node partial[NVGPU_PD_CACHE_COUNT]; + + /* + * Tree of all allocated struct nvgpu_mem's for fast look up. + */ + struct nvgpu_rbtree_node *mem_tree; + + /* + * All access to the cache much be locked. This protects the lists and + * the rb tree. + */ + struct nvgpu_mutex lock; +}; + +/* + * GMMU page directory. This is the kernel's tracking of a list of PDEs or PTEs + * in the GMMU. + */ +struct nvgpu_gmmu_pd { + /* + * DMA memory describing the PTEs or PDEs. @mem_offs describes the + * offset of the PDE table in @mem. @cached specifies if this PD is + * using pd_cache memory. + */ + struct nvgpu_mem *mem; + u32 mem_offs; + bool cached; + + /* + * List of pointers to the next level of page tables. Does not + * need to be populated when this PD is pointing to PTEs. + */ + struct nvgpu_gmmu_pd *entries; + int num_entries; +}; + +/* + * Reduce the number of arguments getting passed through the various levels of + * GMMU mapping functions. + * + * The following fields are set statically and do not change throughout the + * mapping call: + * + * pgsz: Index into the page size table. + * kind_v: Kind attributes for mapping. + * cacheable: Cacheability of the mapping. + * rw_flag: Flag from enum gk20a_mem_rw_flag + * sparse: Set if the mapping should be sparse. + * priv: Privilidged mapping. + * coherent: Set if the mapping should be IO coherent. + * valid: Set if the PTE should be marked valid. + * aperture: VIDMEM or SYSMEM. + * debug: When set print debugging info. + * platform_atomic: True if platform_atomic flag is valid. + * + * These fields are dynamically updated as necessary during the map: + * + * ctag: Comptag line in the comptag cache; + * updated every time we write a PTE. + */ +struct nvgpu_gmmu_attrs { + u32 pgsz; + u32 kind_v; + u64 ctag; + bool cacheable; + enum gk20a_mem_rw_flag rw_flag; + bool sparse; + bool priv; + bool valid; + enum nvgpu_aperture aperture; + bool debug; + bool l3_alloc; + bool platform_atomic; +}; + +struct gk20a_mmu_level { + int hi_bit[2]; + int lo_bit[2]; + + /* + * Build map from virt_addr -> phys_addr. + */ + void (*update_entry)(struct vm_gk20a *vm, + const struct gk20a_mmu_level *l, + struct nvgpu_gmmu_pd *pd, + u32 pd_idx, + u64 phys_addr, + u64 virt_addr, + struct nvgpu_gmmu_attrs *attrs); + u32 entry_size; + /* + * Get pde page size + */ + u32 (*get_pgsz)(struct gk20a *g, const struct gk20a_mmu_level *l, + struct nvgpu_gmmu_pd *pd, u32 pd_idx); +}; + +static inline const char *nvgpu_gmmu_perm_str(enum gk20a_mem_rw_flag p) +{ + switch (p) { + case gk20a_mem_flag_none: + return "RW"; + case gk20a_mem_flag_write_only: + return "WO"; + case gk20a_mem_flag_read_only: + return "RO"; + default: + return "??"; + } +} + +int nvgpu_gmmu_init_page_table(struct vm_gk20a *vm); + +/** + * nvgpu_gmmu_map - Map memory into the GMMU. + * + * Kernel space. + */ +u64 nvgpu_gmmu_map(struct vm_gk20a *vm, + struct nvgpu_mem *mem, + u64 size, + u32 flags, + enum gk20a_mem_rw_flag rw_flag, + bool priv, + enum nvgpu_aperture aperture); + +/** + * nvgpu_gmmu_map_fixed - Map memory into the GMMU. + * + * Kernel space. + */ +u64 nvgpu_gmmu_map_fixed(struct vm_gk20a *vm, + struct nvgpu_mem *mem, + u64 addr, + u64 size, + u32 flags, + enum gk20a_mem_rw_flag rw_flag, + bool priv, + enum nvgpu_aperture aperture); + +/** + * nvgpu_gmmu_unmap - Unmap a buffer. + * + * Kernel space. + */ +void nvgpu_gmmu_unmap(struct vm_gk20a *vm, + struct nvgpu_mem *mem, + u64 gpu_va); + +int nvgpu_pd_alloc(struct vm_gk20a *vm, + struct nvgpu_gmmu_pd *pd, + u32 bytes); + +void nvgpu_pd_free(struct vm_gk20a *vm, struct nvgpu_gmmu_pd *pd); +int nvgpu_pd_cache_alloc_direct(struct gk20a *g, + struct nvgpu_gmmu_pd *pd, u32 bytes); +void nvgpu_pd_cache_free_direct(struct gk20a *g, struct nvgpu_gmmu_pd *pd); +int nvgpu_pd_cache_init(struct gk20a *g); +void nvgpu_pd_cache_fini(struct gk20a *g); + +/* + * Some useful routines that are shared across chips. + */ +static inline u32 pd_offset_from_index(const struct gk20a_mmu_level *l, + u32 pd_idx) +{ + return (pd_idx * l->entry_size) / sizeof(u32); +} + +static inline void pd_write(struct gk20a *g, struct nvgpu_gmmu_pd *pd, + size_t w, size_t data) +{ + nvgpu_mem_wr32(g, pd->mem, (pd->mem_offs / sizeof(u32)) + w, data); +} + +/** + * __nvgpu_pte_words - Compute number of words in a PTE. + * + * @g - The GPU. + * + * This computes and returns the size of a PTE for the passed chip. + */ +u32 __nvgpu_pte_words(struct gk20a *g); + +/** + * __nvgpu_get_pte - Get the contents of a PTE by virtual address + * + * @g - The GPU. + * @vm - VM to look in. + * @vaddr - GPU virtual address. + * @pte - [out] Set to the contents of the PTE. + * + * Find a PTE in the passed VM based on the passed GPU virtual address. This + * will @pte with a copy of the contents of the PTE. @pte must be an array of + * u32s large enough to contain the PTE. This can be computed using + * __nvgpu_pte_words(). + * + * If you wish to write to this PTE then you may modify @pte and then use the + * __nvgpu_set_pte(). + * + * This function returns 0 if the PTE is found and -EINVAL otherwise. + */ +int __nvgpu_get_pte(struct gk20a *g, struct vm_gk20a *vm, u64 vaddr, u32 *pte); + +/** + * __nvgpu_set_pte - Set a PTE based on virtual address + * + * @g - The GPU. + * @vm - VM to look in. + * @vaddr - GPU virtual address. + * @pte - The contents of the PTE to write. + * + * Find a PTE and overwrite the contents of that PTE with the passed in data + * located in @pte. If the PTE does not exist then no writing will happen. That + * is this function will not fill out the page tables for you. The expectation + * is that the passed @vaddr has already been mapped and this is just modifying + * the mapping (for instance changing invalid to valid). + * + * @pte must contain at least the required words for the PTE. See + * __nvgpu_pte_words(). + * + * This function returns 0 on success and -EINVAL otherwise. + */ +int __nvgpu_set_pte(struct gk20a *g, struct vm_gk20a *vm, u64 vaddr, u32 *pte); + + +/* + * Internal debugging routines. Probably not something you want to use. + */ +#define pte_dbg(g, attrs, fmt, args...) \ + do { \ + if ((attrs != NULL) && (attrs->debug)) \ + nvgpu_info(g, fmt, ##args); \ + else \ + nvgpu_log(g, gpu_dbg_pte, fmt, ##args); \ + } while (0) + +#endif /* NVGPU_GMMU_H */ diff --git a/include/nvgpu/hal_init.h b/include/nvgpu/hal_init.h new file mode 100644 index 0000000..06e58e7 --- /dev/null +++ b/include/nvgpu/hal_init.h @@ -0,0 +1,33 @@ +/* + * NVIDIA GPU Hardware Abstraction Layer functions definitions. + * + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_HAL_INIT_H +#define NVGPU_HAL_INIT_H + +struct gk20a; + +int nvgpu_init_hal(struct gk20a *g); +int nvgpu_detect_chip(struct gk20a *g); + +#endif /* NVGPU_HAL_INIT_H */ diff --git a/include/nvgpu/hashtable.h b/include/nvgpu/hashtable.h new file mode 100644 index 0000000..5ce56f0 --- /dev/null +++ b/include/nvgpu/hashtable.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017, 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_SORT_H__ +#define __NVGPU_SORT_H__ + +#ifdef __KERNEL__ +#include +#endif + +#endif diff --git a/include/nvgpu/hw/gk20a/hw_bus_gk20a.h b/include/nvgpu/hw/gk20a/hw_bus_gk20a.h new file mode 100644 index 0000000..d3bb9e9 --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_bus_gk20a.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_bus_gk20a_h_ +#define _hw_bus_gk20a_h_ + +static inline u32 bus_bar0_window_r(void) +{ + return 0x00001700U; +} +static inline u32 bus_bar0_window_base_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 bus_bar0_window_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar0_window_target_sys_mem_coherent_f(void) +{ + return 0x2000000U; +} +static inline u32 bus_bar0_window_target_sys_mem_noncoherent_f(void) +{ + return 0x3000000U; +} +static inline u32 bus_bar0_window_target_bar0_window_base_shift_v(void) +{ + return 0x00000010U; +} +static inline u32 bus_bar1_block_r(void) +{ + return 0x00001704U; +} +static inline u32 bus_bar1_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar1_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar1_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar1_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar1_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar2_block_r(void) +{ + return 0x00001714U; +} +static inline u32 bus_bar2_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar2_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar2_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar2_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar2_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar1_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bar2_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_intr_0_r(void) +{ + return 0x00001100U; +} +static inline u32 bus_intr_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +static inline u32 bus_intr_en_0_r(void) +{ + return 0x00001140U; +} +static inline u32 bus_intr_en_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_en_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_en_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_ccsr_gk20a.h b/include/nvgpu/hw/gk20a/hw_ccsr_gk20a.h new file mode 100644 index 0000000..95151f6 --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_ccsr_gk20a.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ccsr_gk20a_h_ +#define _hw_ccsr_gk20a_h_ + +static inline u32 ccsr_channel_inst_r(u32 i) +{ + return 0x00800000U + i*8U; +} +static inline u32 ccsr_channel_inst__size_1_v(void) +{ + return 0x00000080U; +} +static inline u32 ccsr_channel_inst_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 ccsr_channel_inst_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 ccsr_channel_inst_bind_false_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_bind_true_f(void) +{ + return 0x80000000U; +} +static inline u32 ccsr_channel_r(u32 i) +{ + return 0x00800004U + i*8U; +} +static inline u32 ccsr_channel__size_1_v(void) +{ + return 0x00000080U; +} +static inline u32 ccsr_channel_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ccsr_channel_enable_set_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ccsr_channel_enable_set_true_f(void) +{ + return 0x400U; +} +static inline u32 ccsr_channel_enable_clr_true_f(void) +{ + return 0x800U; +} +static inline u32 ccsr_channel_runlist_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 ccsr_channel_status_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ccsr_channel_status_pending_ctx_reload_v(void) +{ + return 0x00000002U; +} +static inline u32 ccsr_channel_status_pending_acq_ctx_reload_v(void) +{ + return 0x00000004U; +} +static inline u32 ccsr_channel_status_on_pbdma_ctx_reload_v(void) +{ + return 0x0000000aU; +} +static inline u32 ccsr_channel_status_on_pbdma_and_eng_ctx_reload_v(void) +{ + return 0x0000000bU; +} +static inline u32 ccsr_channel_status_on_eng_ctx_reload_v(void) +{ + return 0x0000000cU; +} +static inline u32 ccsr_channel_status_on_eng_pending_ctx_reload_v(void) +{ + return 0x0000000dU; +} +static inline u32 ccsr_channel_status_on_eng_pending_acq_ctx_reload_v(void) +{ + return 0x0000000eU; +} +static inline u32 ccsr_channel_next_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ccsr_channel_next_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ccsr_channel_busy_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_ce2_gk20a.h b/include/nvgpu/hw/gk20a/hw_ce2_gk20a.h new file mode 100644 index 0000000..87481cd --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_ce2_gk20a.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ce2_gk20a_h_ +#define _hw_ce2_gk20a_h_ + +static inline u32 ce2_intr_status_r(void) +{ + return 0x00106908U; +} +static inline u32 ce2_intr_status_blockpipe_pending_f(void) +{ + return 0x1U; +} +static inline u32 ce2_intr_status_blockpipe_reset_f(void) +{ + return 0x1U; +} +static inline u32 ce2_intr_status_nonblockpipe_pending_f(void) +{ + return 0x2U; +} +static inline u32 ce2_intr_status_nonblockpipe_reset_f(void) +{ + return 0x2U; +} +static inline u32 ce2_intr_status_launcherr_pending_f(void) +{ + return 0x4U; +} +static inline u32 ce2_intr_status_launcherr_reset_f(void) +{ + return 0x4U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_ctxsw_prog_gk20a.h b/include/nvgpu/hw/gk20a/hw_ctxsw_prog_gk20a.h new file mode 100644 index 0000000..131fd12 --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_ctxsw_prog_gk20a.h @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ctxsw_prog_gk20a_h_ +#define _hw_ctxsw_prog_gk20a_h_ + +static inline u32 ctxsw_prog_fecs_header_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_main_image_num_gpcs_o(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_main_image_patch_count_o(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_main_image_context_id_o(void) +{ + return 0x000000f0U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_lo_o(void) +{ + return 0x00000014U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_hi_o(void) +{ + return 0x00000018U; +} +static inline u32 ctxsw_prog_main_image_zcull_o(void) +{ + return 0x0000001cU; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_no_ctxsw_v(void) +{ + return 0x00000001U; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_separate_buffer_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_zcull_ptr_o(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_main_image_pm_o(void) +{ + return 0x00000028U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_m(void) +{ + return 0x7U << 0U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_ctxsw_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_m(void) +{ + return 0x7U << 3U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_ctxsw_f(void) +{ + return 0x8U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_ptr_o(void) +{ + return 0x0000002cU; +} +static inline u32 ctxsw_prog_main_image_num_save_ops_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_main_image_num_restore_ops_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_main_image_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_main_image_magic_value_v_value_v(void) +{ + return 0x600dc0deU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_local_image_ppc_info_num_ppcs_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_ppc_mask_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_num_tpcs_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_local_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_local_magic_value_v_value_v(void) +{ + return 0xad0becabU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_o(void) +{ + return 0x000000ecU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_size_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 ctxsw_prog_extended_buffer_segments_size_in_bytes_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_extended_marker_size_in_bytes_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_register_stride_v(void) +{ + return 0x00000005U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_control_register_stride_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_extended_num_smpc_quadrants_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_o(void) +{ + return 0x000000a0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_s(void) +{ + return 2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_m(void) +{ + return 0x3U << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_allow_all_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_use_map_f(void) +{ + return 0x2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_lo_o(void) +{ + return 0x000000a4U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_hi_o(void) +{ + return 0x000000a8U; +} +static inline u32 ctxsw_prog_main_image_misc_options_o(void) +{ + return 0x0000003cU; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_disabled_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_control_o(void) +{ + return 0x000000acU; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_control_num_records_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_o(void) +{ + return 0x000000b0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_v_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_sys_mem_coherent_f(void) +{ + return 0x20000000U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_sys_mem_noncoherent_f(void) +{ + return 0x30000000U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_o(void) +{ + return 0x000000b4U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_record_timestamp_record_size_in_bytes_v(void) +{ + return 0x00000080U; +} +static inline u32 ctxsw_prog_record_timestamp_record_size_in_words_v(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_lo_o(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_lo_v_value_v(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_hi_o(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_hi_v_value_v(void) +{ + return 0x600dbeefU; +} +static inline u32 ctxsw_prog_record_timestamp_context_id_o(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_record_timestamp_context_ptr_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_record_timestamp_new_context_id_o(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_record_timestamp_new_context_ptr_o(void) +{ + return 0x00000014U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_lo_o(void) +{ + return 0x00000018U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_o(void) +{ + return 0x0000001cU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_v_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_v_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_m(void) +{ + return 0xffU << 24U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_v(u32 r) +{ + return (r >> 24U) & 0xffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_ctxsw_req_by_host_v(void) +{ + return 0x00000001U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_ctxsw_req_by_host_f(void) +{ + return 0x1000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_f(void) +{ + return 0x2000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_wfi_v(void) +{ + return 0x0000000aU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_wfi_f(void) +{ + return 0xa000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_gfxp_v(void) +{ + return 0x0000000bU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_gfxp_f(void) +{ + return 0xb000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_ctap_v(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_ctap_f(void) +{ + return 0xc000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_cilp_v(void) +{ + return 0x0000000dU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_cilp_f(void) +{ + return 0xd000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_save_end_v(void) +{ + return 0x00000003U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_save_end_f(void) +{ + return 0x3000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_restore_start_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_restore_start_f(void) +{ + return 0x4000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_context_start_v(void) +{ + return 0x00000005U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_context_start_f(void) +{ + return 0x5000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_invalid_timestamp_v(void) +{ + return 0x000000ffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_invalid_timestamp_f(void) +{ + return 0xff000000U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_falcon_gk20a.h b/include/nvgpu/hw/gk20a/hw_falcon_gk20a.h new file mode 100644 index 0000000..7b4d87b --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_falcon_gk20a.h @@ -0,0 +1,559 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_falcon_gk20a_h_ +#define _hw_falcon_gk20a_h_ + +static inline u32 falcon_falcon_irqsset_r(void) +{ + return 0x00000000U; +} +static inline u32 falcon_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqsclr_r(void) +{ + return 0x00000004U; +} +static inline u32 falcon_falcon_irqstat_r(void) +{ + return 0x00000008U; +} +static inline u32 falcon_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 falcon_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 falcon_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqmode_r(void) +{ + return 0x0000000cU; +} +static inline u32 falcon_falcon_irqmset_r(void) +{ + return 0x00000010U; +} +static inline u32 falcon_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_r(void) +{ + return 0x00000014U; +} +static inline u32 falcon_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqmask_r(void) +{ + return 0x00000018U; +} +static inline u32 falcon_falcon_irqdest_r(void) +{ + return 0x0000001cU; +} +static inline u32 falcon_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 falcon_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 falcon_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 falcon_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 falcon_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 falcon_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 falcon_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 falcon_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 falcon_falcon_curctx_r(void) +{ + return 0x00000050U; +} +static inline u32 falcon_falcon_nxtctx_r(void) +{ + return 0x00000054U; +} +static inline u32 falcon_falcon_mailbox0_r(void) +{ + return 0x00000040U; +} +static inline u32 falcon_falcon_mailbox1_r(void) +{ + return 0x00000044U; +} +static inline u32 falcon_falcon_itfen_r(void) +{ + return 0x00000048U; +} +static inline u32 falcon_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 falcon_falcon_idlestate_r(void) +{ + return 0x0000004cU; +} +static inline u32 falcon_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 falcon_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 falcon_falcon_os_r(void) +{ + return 0x00000080U; +} +static inline u32 falcon_falcon_engctl_r(void) +{ + return 0x000000a4U; +} +static inline u32 falcon_falcon_cpuctl_r(void) +{ + return 0x00000100U; +} +static inline u32 falcon_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_cpuctl_sreset_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_cpuctl_hreset_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_stopped_m(void) +{ + return 0x1U << 5U; +} +static inline u32 falcon_falcon_imemc_r(u32 i) +{ + return 0x00000180U + i*16U; +} +static inline u32 falcon_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_imemc_secure_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 falcon_falcon_imemd_r(u32 i) +{ + return 0x00000184U + i*16U; +} +static inline u32 falcon_falcon_imemt_r(u32 i) +{ + return 0x00000188U + i*16U; +} +static inline u32 falcon_falcon_bootvec_r(void) +{ + return 0x00000104U; +} +static inline u32 falcon_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 falcon_falcon_dmactl_r(void) +{ + return 0x0000010cU; +} +static inline u32 falcon_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 falcon_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 falcon_falcon_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_hwcfg_r(void) +{ + return 0x00000108U; +} +static inline u32 falcon_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 falcon_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 falcon_falcon_dmatrfbase_r(void) +{ + return 0x00000110U; +} +static inline u32 falcon_falcon_dmatrfmoffs_r(void) +{ + return 0x00000114U; +} +static inline u32 falcon_falcon_dmatrfcmd_r(void) +{ + return 0x00000118U; +} +static inline u32 falcon_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 falcon_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 falcon_falcon_dmatrffboffs_r(void) +{ + return 0x0000011cU; +} +static inline u32 falcon_falcon_imstat_r(void) +{ + return 0x00000144U; +} +static inline u32 falcon_falcon_traceidx_r(void) +{ + return 0x00000148U; +} +static inline u32 falcon_falcon_traceidx_maxidx_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 falcon_falcon_traceidx_idx_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 falcon_falcon_tracepc_r(void) +{ + return 0x0000014cU; +} +static inline u32 falcon_falcon_tracepc_pc_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 falcon_falcon_exterraddr_r(void) +{ + return 0x00000168U; +} +static inline u32 falcon_falcon_exterrstat_r(void) +{ + return 0x0000016cU; +} +static inline u32 falcon_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 falcon_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 falcon_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 falcon_falcon_icd_cmd_r(void) +{ + return 0x00000200U; +} +static inline u32 falcon_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 falcon_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 falcon_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 falcon_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 falcon_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 falcon_falcon_icd_rdata_r(void) +{ + return 0x0000020cU; +} +static inline u32 falcon_falcon_dmemc_r(u32 i) +{ + return 0x000001c0U + i*8U; +} +static inline u32 falcon_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 falcon_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 falcon_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 falcon_falcon_dmemd_r(u32 i) +{ + return 0x000001c4U + i*8U; +} +static inline u32 falcon_falcon_debug1_r(void) +{ + return 0x00000090U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_s(void) +{ + return 1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_m(void) +{ + return 0x1U << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_init_f(void) +{ + return 0x0U; +} +static inline u32 falcon_falcon_debuginfo_r(void) +{ + return 0x00000094U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_fb_gk20a.h b/include/nvgpu/hw/gk20a/hw_fb_gk20a.h new file mode 100644 index 0000000..42df4f5 --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_fb_gk20a.h @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fb_gk20a_h_ +#define _hw_fb_gk20a_h_ + +static inline u32 fb_mmu_ctrl_r(void) +{ + return 0x00100c80U; +} +static inline u32 fb_mmu_ctrl_vm_pg_size_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fb_mmu_ctrl_vm_pg_size_128kb_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_vm_pg_size_64kb_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_space_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 fb_mmu_invalidate_pdb_r(void) +{ + return 0x00100cb8U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_sys_mem_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_pdb_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_invalidate_r(void) +{ + return 0x00100cbcU; +} +static inline u32 fb_mmu_invalidate_all_va_true_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_invalidate_all_pdb_true_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_trigger_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_trigger_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_trigger_true_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_debug_wr_r(void) +{ + return 0x00100cc8U; +} +static inline u32 fb_mmu_debug_wr_aperture_s(void) +{ + return 2U; +} +static inline u32 fb_mmu_debug_wr_aperture_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_m(void) +{ + return 0x3U << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fb_mmu_debug_wr_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_wr_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_vol_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_wr_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_debug_wr_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_wr_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_rd_r(void) +{ + return 0x00100cccU; +} +static inline u32 fb_mmu_debug_rd_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_rd_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_rd_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_ctrl_r(void) +{ + return 0x00100cc4U; +} +static inline u32 fb_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 fb_mmu_debug_ctrl_debug_m(void) +{ + return 0x1U << 16U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_vpr_info_r(void) +{ + return 0x00100cd0U; +} +static inline u32 fb_mmu_vpr_info_fetch_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 fb_mmu_vpr_info_fetch_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_vpr_info_fetch_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_niso_flush_sysmem_addr_r(void) +{ + return 0x00100c10U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_fifo_gk20a.h b/include/nvgpu/hw/gk20a/hw_fifo_gk20a.h new file mode 100644 index 0000000..e61e386 --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_fifo_gk20a.h @@ -0,0 +1,619 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fifo_gk20a_h_ +#define _hw_fifo_gk20a_h_ + +static inline u32 fifo_bar1_base_r(void) +{ + return 0x00002254U; +} +static inline u32 fifo_bar1_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_bar1_base_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_bar1_base_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 fifo_bar1_base_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_runlist_base_r(void) +{ + return 0x00002270U; +} +static inline u32 fifo_runlist_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_runlist_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fifo_runlist_base_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_runlist_base_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 fifo_runlist_r(void) +{ + return 0x00002274U; +} +static inline u32 fifo_runlist_engine_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 fifo_eng_runlist_base_r(u32 i) +{ + return 0x00002280U + i*8U; +} +static inline u32 fifo_eng_runlist_base__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_eng_runlist_r(u32 i) +{ + return 0x00002284U + i*8U; +} +static inline u32 fifo_eng_runlist__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_eng_runlist_length_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fifo_eng_runlist_length_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 fifo_eng_runlist_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_runlist_timeslice_r(u32 i) +{ + return 0x00002310U + i*4U; +} +static inline u32 fifo_runlist_timeslice_timeout_128_f(void) +{ + return 0x80U; +} +static inline u32 fifo_runlist_timeslice_timescale_3_f(void) +{ + return 0x3000U; +} +static inline u32 fifo_runlist_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_eng_timeout_r(void) +{ + return 0x00002a0cU; +} +static inline u32 fifo_eng_timeout_period_max_f(void) +{ + return 0x7fffffffU; +} +static inline u32 fifo_eng_timeout_detection_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_eng_timeout_detection_disabled_f(void) +{ + return 0x0U; +} +static inline u32 fifo_pb_timeslice_r(u32 i) +{ + return 0x00002350U + i*4U; +} +static inline u32 fifo_pb_timeslice_timeout_16_f(void) +{ + return 0x10U; +} +static inline u32 fifo_pb_timeslice_timescale_0_f(void) +{ + return 0x0U; +} +static inline u32 fifo_pb_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_pbdma_map_r(u32 i) +{ + return 0x00002390U + i*4U; +} +static inline u32 fifo_intr_0_r(void) +{ + return 0x00002100U; +} +static inline u32 fifo_intr_0_bind_error_pending_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_bind_error_reset_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_pio_error_pending_f(void) +{ + return 0x10U; +} +static inline u32 fifo_intr_0_pio_error_reset_f(void) +{ + return 0x10U; +} +static inline u32 fifo_intr_0_sched_error_pending_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_sched_error_reset_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_chsw_error_pending_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_chsw_error_reset_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_fb_flush_timeout_pending_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_fb_flush_timeout_reset_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_lb_error_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_lb_error_reset_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_dropped_mmu_fault_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 fifo_intr_0_dropped_mmu_fault_reset_f(void) +{ + return 0x8000000U; +} +static inline u32 fifo_intr_0_mmu_fault_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_intr_0_pbdma_intr_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_intr_0_runlist_event_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 fifo_intr_0_channel_intr_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_intr_en_0_r(void) +{ + return 0x00002140U; +} +static inline u32 fifo_intr_en_0_sched_error_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_intr_en_0_sched_error_m(void) +{ + return 0x1U << 8U; +} +static inline u32 fifo_intr_en_0_mmu_fault_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 fifo_intr_en_0_mmu_fault_m(void) +{ + return 0x1U << 28U; +} +static inline u32 fifo_intr_en_1_r(void) +{ + return 0x00002528U; +} +static inline u32 fifo_intr_bind_error_r(void) +{ + return 0x0000252cU; +} +static inline u32 fifo_intr_sched_error_r(void) +{ + return 0x0000254cU; +} +static inline u32 fifo_intr_sched_error_code_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fifo_intr_sched_error_code_ctxsw_timeout_v(void) +{ + return 0x0000000aU; +} +static inline u32 fifo_intr_chsw_error_r(void) +{ + return 0x0000256cU; +} +static inline u32 fifo_intr_mmu_fault_id_r(void) +{ + return 0x0000259cU; +} +static inline u32 fifo_intr_mmu_fault_eng_id_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_intr_mmu_fault_eng_id_graphics_f(void) +{ + return 0x0U; +} +static inline u32 fifo_intr_mmu_fault_inst_r(u32 i) +{ + return 0x00002800U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_inst_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 fifo_intr_mmu_fault_inst_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_intr_mmu_fault_lo_r(u32 i) +{ + return 0x00002804U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_hi_r(u32 i) +{ + return 0x00002808U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_info_r(u32 i) +{ + return 0x0000280cU + i*16U; +} +static inline u32 fifo_intr_mmu_fault_info_type_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 fifo_intr_mmu_fault_info_write_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 fifo_intr_mmu_fault_info_engine_subid_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 fifo_intr_mmu_fault_info_engine_subid_gpc_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_intr_mmu_fault_info_engine_subid_hub_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_mmu_fault_info_client_v(u32 r) +{ + return (r >> 8U) & 0x1fU; +} +static inline u32 fifo_intr_pbdma_id_r(void) +{ + return 0x000025a0U; +} +static inline u32 fifo_intr_pbdma_id_status_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_intr_pbdma_id_status_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fifo_intr_pbdma_id_status__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_runlist_r(void) +{ + return 0x00002a00U; +} +static inline u32 fifo_fb_timeout_r(void) +{ + return 0x00002a04U; +} +static inline u32 fifo_fb_timeout_period_m(void) +{ + return 0x3fffffffU << 0U; +} +static inline u32 fifo_fb_timeout_period_max_f(void) +{ + return 0x3fffffffU; +} +static inline u32 fifo_pb_timeout_r(void) +{ + return 0x00002a08U; +} +static inline u32 fifo_pb_timeout_detection_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_error_sched_disable_r(void) +{ + return 0x0000262cU; +} +static inline u32 fifo_sched_disable_r(void) +{ + return 0x00002630U; +} +static inline u32 fifo_sched_disable_runlist_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_sched_disable_runlist_m(u32 i) +{ + return 0x1U << (0U + i*1U); +} +static inline u32 fifo_sched_disable_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_preempt_r(void) +{ + return 0x00002634U; +} +static inline u32 fifo_preempt_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_preempt_type_channel_f(void) +{ + return 0x0U; +} +static inline u32 fifo_preempt_type_tsg_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_preempt_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_preempt_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_trigger_mmu_fault_r(u32 i) +{ + return 0x00002a30U + i*4U; +} +static inline u32 fifo_trigger_mmu_fault_id_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 fifo_trigger_mmu_fault_enable_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_engine_status_r(u32 i) +{ + return 0x00002640U + i*8U; +} +static inline u32 fifo_engine_status__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fifo_engine_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_engine_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_engine_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_engine_status_ctx_status_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_ctx_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_engine_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_engine_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_engine_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_faulted_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fifo_engine_status_faulted_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_engine_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fifo_engine_status_engine_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_engine_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_f(void) +{ + return 0x8000U; +} +static inline u32 fifo_pbdma_status_r(u32 i) +{ + return 0x00003080U + i*4U; +} +static inline u32 fifo_pbdma_status__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_pbdma_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_pbdma_status_chan_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_pbdma_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_pbdma_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_chsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_pbdma_status_chsw_in_progress_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_flush_gk20a.h b/include/nvgpu/hw/gk20a/hw_flush_gk20a.h new file mode 100644 index 0000000..d270b5f --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_flush_gk20a.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_flush_gk20a_h_ +#define _hw_flush_gk20a_h_ + +static inline u32 flush_l2_system_invalidate_r(void) +{ + return 0x00070004U; +} +static inline u32 flush_l2_system_invalidate_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_r(void) +{ + return 0x00070010U; +} +static inline u32 flush_l2_flush_dirty_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_r(void) +{ + return 0x0007000cU; +} +static inline u32 flush_l2_clean_comptags_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_r(void) +{ + return 0x00070000U; +} +static inline u32 flush_fb_flush_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_fb_flush_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_fb_flush_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_fb_flush_outstanding_true_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_gmmu_gk20a.h b/include/nvgpu/hw/gk20a/hw_gmmu_gk20a.h new file mode 100644 index 0000000..a788d1d --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_gmmu_gk20a.h @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2012-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gmmu_gk20a_h_ +#define _hw_gmmu_gk20a_h_ + +static inline u32 gmmu_pde_aperture_big_w(void) +{ + return 0U; +} +static inline u32 gmmu_pde_aperture_big_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_aperture_big_video_memory_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pde_aperture_big_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_pde_aperture_big_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 gmmu_pde_size_w(void) +{ + return 0U; +} +static inline u32 gmmu_pde_size_full_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_address_big_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_pde_address_big_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_pde_aperture_small_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_aperture_small_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_aperture_small_video_memory_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pde_aperture_small_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_pde_aperture_small_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 gmmu_pde_vol_small_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_vol_small_true_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_pde_vol_small_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_vol_big_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_vol_big_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_pde_vol_big_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_address_small_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_pde_address_small_sys_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_pde__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_pte__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_pte_valid_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_valid_true_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pte_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_privilege_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_privilege_true_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_pte_privilege_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_address_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_pte_address_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_address_vid_f(u32 v) +{ + return (v & 0x1ffffffU) << 4U; +} +static inline u32 gmmu_pte_address_vid_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_vol_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_vol_true_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pte_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_aperture_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_aperture_video_memory_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_aperture_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_pte_aperture_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_pte_read_only_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_read_only_true_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_pte_write_disable_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_write_disable_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gmmu_pte_read_disable_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_read_disable_true_f(void) +{ + return 0x40000000U; +} +static inline u32 gmmu_pte_comptagline_s(void) +{ + return 17U; +} +static inline u32 gmmu_pte_comptagline_f(u32 v) +{ + return (v & 0x1ffffU) << 12U; +} +static inline u32 gmmu_pte_comptagline_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_pte_kind_f(u32 v) +{ + return (v & 0xffU) << 4U; +} +static inline u32 gmmu_pte_kind_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_kind_invalid_v(void) +{ + return 0x000000ffU; +} +static inline u32 gmmu_pte_kind_pitch_v(void) +{ + return 0x00000000U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_gr_gk20a.h b/include/nvgpu/hw/gk20a/hw_gr_gk20a.h new file mode 100644 index 0000000..826108f --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_gr_gk20a.h @@ -0,0 +1,3807 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gr_gk20a_h_ +#define _hw_gr_gk20a_h_ + +static inline u32 gr_intr_r(void) +{ + return 0x00400100U; +} +static inline u32 gr_intr_notify_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_notify_reset_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_semaphore_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_semaphore_reset_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_semaphore_timeout_not_pending_f(void) +{ + return 0x0U; +} +static inline u32 gr_intr_semaphore_timeout_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_intr_semaphore_timeout_reset_f(void) +{ + return 0x4U; +} +static inline u32 gr_intr_illegal_method_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_method_reset_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_notify_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_illegal_notify_reset_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 gr_intr_firmware_method_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_firmware_method_reset_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_illegal_class_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_illegal_class_reset_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_fecs_error_pending_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_fecs_error_reset_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_class_error_pending_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_class_error_reset_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_exception_pending_f(void) +{ + return 0x200000U; +} +static inline u32 gr_intr_exception_reset_f(void) +{ + return 0x200000U; +} +static inline u32 gr_fecs_intr_r(void) +{ + return 0x00400144U; +} +static inline u32 gr_class_error_r(void) +{ + return 0x00400110U; +} +static inline u32 gr_class_error_code_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_intr_nonstall_r(void) +{ + return 0x00400120U; +} +static inline u32 gr_intr_nonstall_trap_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_en_r(void) +{ + return 0x0040013cU; +} +static inline u32 gr_exception_r(void) +{ + return 0x00400108U; +} +static inline u32 gr_exception_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception_gpc_m(void) +{ + return 0x1U << 24U; +} +static inline u32 gr_exception_memfmt_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_exception_ds_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_exception_sked_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_exception_pd_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_exception_scc_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_exception_ssync_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_exception_mme_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_exception1_r(void) +{ + return 0x00400118U; +} +static inline u32 gr_exception1_gpc_0_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_exception2_r(void) +{ + return 0x0040011cU; +} +static inline u32 gr_exception_en_r(void) +{ + return 0x00400138U; +} +static inline u32 gr_exception_en_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception1_en_r(void) +{ + return 0x00400130U; +} +static inline u32 gr_exception2_en_r(void) +{ + return 0x00400134U; +} +static inline u32 gr_gpfifo_ctl_r(void) +{ + return 0x00400500U; +} +static inline u32 gr_gpfifo_ctl_access_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpfifo_ctl_access_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpfifo_ctl_access_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpfifo_status_r(void) +{ + return 0x00400504U; +} +static inline u32 gr_trapped_addr_r(void) +{ + return 0x00400704U; +} +static inline u32 gr_trapped_addr_mthd_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 gr_trapped_addr_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 gr_trapped_addr_mme_generated_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 gr_trapped_addr_datahigh_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 gr_trapped_addr_priv_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 gr_trapped_addr_status_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_trapped_data_lo_r(void) +{ + return 0x00400708U; +} +static inline u32 gr_trapped_data_hi_r(void) +{ + return 0x0040070cU; +} +static inline u32 gr_trapped_data_mme_r(void) +{ + return 0x00400710U; +} +static inline u32 gr_trapped_data_mme_pc_v(u32 r) +{ + return (r >> 0U) & 0x7ffU; +} +static inline u32 gr_status_r(void) +{ + return 0x00400700U; +} +static inline u32 gr_status_fe_method_upper_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_status_fe_gi_v(u32 r) +{ + return (r >> 21U) & 0x1U; +} +static inline u32 gr_status_mask_r(void) +{ + return 0x00400610U; +} +static inline u32 gr_status_1_r(void) +{ + return 0x00400604U; +} +static inline u32 gr_status_2_r(void) +{ + return 0x00400608U; +} +static inline u32 gr_engine_status_r(void) +{ + return 0x0040060cU; +} +static inline u32 gr_engine_status_value_busy_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_be0_becs_be_exception_r(void) +{ + return 0x00410204U; +} +static inline u32 gr_pri_be0_becs_be_exception_en_r(void) +{ + return 0x00410208U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_en_r(void) +{ + return 0x00502c94U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_activity_0_r(void) +{ + return 0x00400380U; +} +static inline u32 gr_activity_1_r(void) +{ + return 0x00400384U; +} +static inline u32 gr_activity_2_r(void) +{ + return 0x00400388U; +} +static inline u32 gr_activity_4_r(void) +{ + return 0x00400390U; +} +static inline u32 gr_pri_gpc0_gcc_dbg_r(void) +{ + return 0x00501000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_r(void) +{ + return 0x00419000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_invalidate_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cache_control_r(void) +{ + return 0x005046a4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_r(void) +{ + return 0x00419ea4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_invalidate_cache_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_sked_activity_r(void) +{ + return 0x00407054U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity0_r(void) +{ + return 0x00502c80U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity1_r(void) +{ + return 0x00502c84U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity2_r(void) +{ + return 0x00502c88U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity3_r(void) +{ + return 0x00502c8cU; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x00504500U; +} +static inline u32 gr_pri_gpc0_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00501d00U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_0_r(void) +{ + return 0x0041ac80U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_1_r(void) +{ + return 0x0041ac84U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_2_r(void) +{ + return 0x0041ac88U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_3_r(void) +{ + return 0x0041ac8cU; +} +static inline u32 gr_pri_gpcs_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x0041c500U; +} +static inline u32 gr_pri_gpcs_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00419d00U; +} +static inline u32 gr_pri_be0_becs_be_activity0_r(void) +{ + return 0x00410200U; +} +static inline u32 gr_pri_bes_becs_be_activity0_r(void) +{ + return 0x00408a00U; +} +static inline u32 gr_pri_ds_mpipe_status_r(void) +{ + return 0x00405858U; +} +static inline u32 gr_pri_fe_go_idle_on_status_r(void) +{ + return 0x00404150U; +} +static inline u32 gr_pri_fe_go_idle_check_r(void) +{ + return 0x00404158U; +} +static inline u32 gr_pri_fe_go_idle_info_r(void) +{ + return 0x00404194U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_tex_subunits_status_r(void) +{ + return 0x00504238U; +} +static inline u32 gr_pri_be0_crop_status1_r(void) +{ + return 0x00410134U; +} +static inline u32 gr_pri_bes_crop_status1_r(void) +{ + return 0x00408934U; +} +static inline u32 gr_pri_be0_zrop_status_r(void) +{ + return 0x00410048U; +} +static inline u32 gr_pri_be0_zrop_status2_r(void) +{ + return 0x0041004cU; +} +static inline u32 gr_pri_bes_zrop_status_r(void) +{ + return 0x00408848U; +} +static inline u32 gr_pri_bes_zrop_status2_r(void) +{ + return 0x0040884cU; +} +static inline u32 gr_pipe_bundle_address_r(void) +{ + return 0x00400200U; +} +static inline u32 gr_pipe_bundle_address_value_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pipe_bundle_data_r(void) +{ + return 0x00400204U; +} +static inline u32 gr_pipe_bundle_config_r(void) +{ + return 0x00400208U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_r(void) +{ + return 0x00404000U; +} +static inline u32 gr_fe_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_fe_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_info_r(void) +{ + return 0x004041b0U; +} +static inline u32 gr_fe_go_idle_timeout_r(void) +{ + return 0x00404154U; +} +static inline u32 gr_fe_go_idle_timeout_count_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fe_go_idle_timeout_count_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_go_idle_timeout_count_prod_f(void) +{ + return 0x800U; +} +static inline u32 gr_fe_object_table_r(u32 i) +{ + return 0x00404200U + i*4U; +} +static inline u32 gr_fe_object_table_nvclass_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_mme_shadow_raw_index_r(void) +{ + return 0x00404488U; +} +static inline u32 gr_pri_mme_shadow_raw_index_write_trigger_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pri_mme_shadow_raw_data_r(void) +{ + return 0x0040448cU; +} +static inline u32 gr_mme_hww_esr_r(void) +{ + return 0x00404490U; +} +static inline u32 gr_mme_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_mme_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_mme_hww_esr_info_r(void) +{ + return 0x00404494U; +} +static inline u32 gr_memfmt_hww_esr_r(void) +{ + return 0x00404600U; +} +static inline u32 gr_memfmt_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_memfmt_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fecs_cpuctl_r(void) +{ + return 0x00409100U; +} +static inline u32 gr_fecs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_dmactl_r(void) +{ + return 0x0040910cU; +} +static inline u32 gr_fecs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_fecs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_fecs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_fecs_os_r(void) +{ + return 0x00409080U; +} +static inline u32 gr_fecs_idlestate_r(void) +{ + return 0x0040904cU; +} +static inline u32 gr_fecs_mailbox0_r(void) +{ + return 0x00409040U; +} +static inline u32 gr_fecs_mailbox1_r(void) +{ + return 0x00409044U; +} +static inline u32 gr_fecs_irqstat_r(void) +{ + return 0x00409008U; +} +static inline u32 gr_fecs_irqmode_r(void) +{ + return 0x0040900cU; +} +static inline u32 gr_fecs_irqmask_r(void) +{ + return 0x00409018U; +} +static inline u32 gr_fecs_irqdest_r(void) +{ + return 0x0040901cU; +} +static inline u32 gr_fecs_curctx_r(void) +{ + return 0x00409050U; +} +static inline u32 gr_fecs_nxtctx_r(void) +{ + return 0x00409054U; +} +static inline u32 gr_fecs_engctl_r(void) +{ + return 0x004090a4U; +} +static inline u32 gr_fecs_debug1_r(void) +{ + return 0x00409090U; +} +static inline u32 gr_fecs_debuginfo_r(void) +{ + return 0x00409094U; +} +static inline u32 gr_fecs_icd_cmd_r(void) +{ + return 0x00409200U; +} +static inline u32 gr_fecs_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 gr_fecs_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 gr_fecs_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 gr_fecs_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 gr_fecs_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 gr_fecs_icd_rdata_r(void) +{ + return 0x0040920cU; +} +static inline u32 gr_fecs_imemc_r(u32 i) +{ + return 0x00409180U + i*16U; +} +static inline u32 gr_fecs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_imemd_r(u32 i) +{ + return 0x00409184U + i*16U; +} +static inline u32 gr_fecs_imemt_r(u32 i) +{ + return 0x00409188U + i*16U; +} +static inline u32 gr_fecs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_dmemc_r(u32 i) +{ + return 0x004091c0U + i*8U; +} +static inline u32 gr_fecs_dmemc_offs_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 gr_fecs_dmemc_offs_v(u32 r) +{ + return (r >> 2U) & 0x3fU; +} +static inline u32 gr_fecs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_dmemd_r(u32 i) +{ + return 0x004091c4U + i*8U; +} +static inline u32 gr_fecs_dmatrfbase_r(void) +{ + return 0x00409110U; +} +static inline u32 gr_fecs_dmatrfmoffs_r(void) +{ + return 0x00409114U; +} +static inline u32 gr_fecs_dmatrffboffs_r(void) +{ + return 0x0040911cU; +} +static inline u32 gr_fecs_dmatrfcmd_r(void) +{ + return 0x00409118U; +} +static inline u32 gr_fecs_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_fecs_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_fecs_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_fecs_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_fecs_bootvec_r(void) +{ + return 0x00409104U; +} +static inline u32 gr_fecs_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_falcon_hwcfg_r(void) +{ + return 0x00409108U; +} +static inline u32 gr_gpcs_gpccs_falcon_hwcfg_r(void) +{ + return 0x0041a108U; +} +static inline u32 gr_fecs_falcon_rm_r(void) +{ + return 0x00409084U; +} +static inline u32 gr_fecs_current_ctx_r(void) +{ + return 0x00409b00U; +} +static inline u32 gr_fecs_current_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_current_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_current_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_current_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_current_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_current_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_current_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_current_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_current_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_current_ctx_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_method_data_r(void) +{ + return 0x00409500U; +} +static inline u32 gr_fecs_method_push_r(void) +{ + return 0x00409504U; +} +static inline u32 gr_fecs_method_push_adr_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_v(void) +{ + return 0x00000003U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_f(void) +{ + return 0x3U; +} +static inline u32 gr_fecs_method_push_adr_discover_image_size_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_method_push_adr_wfi_golden_save_v(void) +{ + return 0x00000009U; +} +static inline u32 gr_fecs_method_push_adr_restore_golden_v(void) +{ + return 0x00000015U; +} +static inline u32 gr_fecs_method_push_adr_discover_zcull_image_size_v(void) +{ + return 0x00000016U; +} +static inline u32 gr_fecs_method_push_adr_discover_pm_image_size_v(void) +{ + return 0x00000025U; +} +static inline u32 gr_fecs_method_push_adr_discover_reglist_image_size_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_bind_instance_v(void) +{ + return 0x00000031U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_virtual_address_v(void) +{ + return 0x00000032U; +} +static inline u32 gr_fecs_method_push_adr_stop_ctxsw_v(void) +{ + return 0x00000038U; +} +static inline u32 gr_fecs_method_push_adr_start_ctxsw_v(void) +{ + return 0x00000039U; +} +static inline u32 gr_fecs_method_push_adr_set_watchdog_timeout_f(void) +{ + return 0x21U; +} +static inline u32 gr_fecs_method_push_adr_halt_pipeline_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_fecs_host_int_status_r(void) +{ + return 0x00409c18U; +} +static inline u32 gr_fecs_host_int_status_fault_during_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_fecs_host_int_status_umimp_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 gr_fecs_host_int_status_umimp_illegal_method_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 gr_fecs_host_int_status_watchdog_active_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_host_int_status_ctxsw_intr_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_host_int_clear_r(void) +{ + return 0x00409c20U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_clear_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_r(void) +{ + return 0x00409c24U; +} +static inline u32 gr_fecs_host_int_enable_ctxsw_intr1_enable_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_fault_during_ctxsw_enable_f(void) +{ + return 0x10000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_firmware_method_enable_f(void) +{ + return 0x20000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_illegal_method_enable_f(void) +{ + return 0x40000U; +} +static inline u32 gr_fecs_host_int_enable_watchdog_enable_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_r(void) +{ + return 0x00409614U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_engine_reset_disabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_engine_reset_disabled_f(void) +{ + return 0x20U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_engine_reset_disabled_f(void) +{ + return 0x40U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_disabled_f(void) +{ + return 0x100U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_disabled_f(void) +{ + return 0x200U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_disabled_f(void) +{ + return 0x400U; +} +static inline u32 gr_fecs_ctx_state_store_major_rev_id_r(void) +{ + return 0x0040960cU; +} +static inline u32 gr_fecs_ctxsw_mailbox_r(u32 i) +{ + return 0x00409800U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_fail_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_r(u32 i) +{ + return 0x00409820U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_r(u32 i) +{ + return 0x00409840U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_fs_r(void) +{ + return 0x00409604U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_fs_num_available_fbps_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_fbps_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_m(void) +{ + return 0x1fU << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_fecs_cfg_r(void) +{ + return 0x00409620U; +} +static inline u32 gr_fecs_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_fecs_rc_lanes_r(void) +{ + return 0x00409880U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_fecs_ctxsw_status_1_r(void) +{ + return 0x00409400U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_m(void) +{ + return 0x1U << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_adr_r(void) +{ + return 0x00409a24U; +} +static inline u32 gr_fecs_new_ctx_r(void) +{ + return 0x00409b04U; +} +static inline u32 gr_fecs_new_ctx_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_new_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_new_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_new_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_new_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_new_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_new_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_new_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_new_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_new_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_new_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_ptr_r(void) +{ + return 0x00409a0cU; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_arb_ctx_cmd_r(void) +{ + return 0x00409a10U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_ctxsw_status_fe_0_r(void) +{ + return 0x00409c00U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_gpc_0_r(void) +{ + return 0x00502c04U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_1_r(void) +{ + return 0x00502400U; +} +static inline u32 gr_fecs_ctxsw_idlestate_r(void) +{ + return 0x00409420U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_idlestate_r(void) +{ + return 0x00502420U; +} +static inline u32 gr_rstr2d_gpc_map0_r(void) +{ + return 0x0040780cU; +} +static inline u32 gr_rstr2d_gpc_map1_r(void) +{ + return 0x00407810U; +} +static inline u32 gr_rstr2d_gpc_map2_r(void) +{ + return 0x00407814U; +} +static inline u32 gr_rstr2d_gpc_map3_r(void) +{ + return 0x00407818U; +} +static inline u32 gr_rstr2d_gpc_map4_r(void) +{ + return 0x0040781cU; +} +static inline u32 gr_rstr2d_gpc_map5_r(void) +{ + return 0x00407820U; +} +static inline u32 gr_rstr2d_map_table_cfg_r(void) +{ + return 0x004078bcU; +} +static inline u32 gr_rstr2d_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_rstr2d_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_hww_esr_r(void) +{ + return 0x00406018U; +} +static inline u32 gr_pd_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pd_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_num_tpc_per_gpc_r(u32 i) +{ + return 0x00406028U + i*4U; +} +static inline u32 gr_pd_num_tpc_per_gpc__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count1_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count2_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count3_f(u32 v) +{ + return (v & 0xfU) << 12U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count4_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count5_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count6_f(u32 v) +{ + return (v & 0xfU) << 24U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count7_f(u32 v) +{ + return (v & 0xfU) << 28U; +} +static inline u32 gr_pd_ab_dist_cfg0_r(void) +{ + return 0x004064c0U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_en_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_dis_f(void) +{ + return 0x0U; +} +static inline u32 gr_pd_ab_dist_cfg1_r(void) +{ + return 0x004064c4U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_batches_init_f(void) +{ + return 0xffffU; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_f(u32 v) +{ + return (v & 0x7ffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_granularity_v(void) +{ + return 0x00000080U; +} +static inline u32 gr_pd_ab_dist_cfg2_r(void) +{ + return 0x004064c8U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_init_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_f(u32 v) +{ + return (v & 0xfffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_scc_bundle_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_min_gpm_fifo_depths_v(void) +{ + return 0x00000062U; +} +static inline u32 gr_pd_pagepool_r(void) +{ + return 0x004064ccU; +} +static inline u32 gr_pd_pagepool_total_pages_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_pagepool_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_dist_skip_table_r(u32 i) +{ + return 0x004064d0U + i*4U; +} +static inline u32 gr_pd_dist_skip_table__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n0_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n1_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n2_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n3_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_pd_alpha_ratio_table_r(u32 i) +{ + return 0x00406800U + i*4U; +} +static inline u32 gr_pd_alpha_ratio_table__size_1_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_pd_alpha_ratio_table_gpc_4n0_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_alpha_ratio_table_gpc_4n1_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_alpha_ratio_table_gpc_4n2_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_pd_alpha_ratio_table_gpc_4n3_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_pd_beta_ratio_table_r(u32 i) +{ + return 0x00406c00U + i*4U; +} +static inline u32 gr_pd_beta_ratio_table__size_1_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_pd_beta_ratio_table_gpc_4n0_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_beta_ratio_table_gpc_4n1_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_beta_ratio_table_gpc_4n2_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_pd_beta_ratio_table_gpc_4n3_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_ds_debug_r(void) +{ + return 0x00405800U; +} +static inline u32 gr_ds_debug_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_debug_timeslice_mode_enable_f(void) +{ + return 0x8000000U; +} +static inline u32 gr_ds_zbc_color_r_r(void) +{ + return 0x00405804U; +} +static inline u32 gr_ds_zbc_color_r_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_g_r(void) +{ + return 0x00405808U; +} +static inline u32 gr_ds_zbc_color_g_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_b_r(void) +{ + return 0x0040580cU; +} +static inline u32 gr_ds_zbc_color_b_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_a_r(void) +{ + return 0x00405810U; +} +static inline u32 gr_ds_zbc_color_a_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_r(void) +{ + return 0x00405814U; +} +static inline u32 gr_ds_zbc_color_fmt_val_f(u32 v) +{ + return (v & 0x7fU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_zero_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_color_fmt_val_unorm_one_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_ds_zbc_color_fmt_val_rf32_gf32_bf32_af32_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_ds_zbc_color_fmt_val_a8_b8_g8_r8_v(void) +{ + return 0x00000028U; +} +static inline u32 gr_ds_zbc_z_r(void) +{ + return 0x00405818U; +} +static inline u32 gr_ds_zbc_z_val_s(void) +{ + return 32U; +} +static inline u32 gr_ds_zbc_z_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_z_val_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_ds_zbc_z_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_ds_zbc_z_val__init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_ds_zbc_z_val__init_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_r(void) +{ + return 0x0040581cU; +} +static inline u32 gr_ds_zbc_z_fmt_val_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_fp32_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_tbl_index_r(void) +{ + return 0x00405820U; +} +static inline u32 gr_ds_zbc_tbl_index_val_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_ds_zbc_tbl_ld_r(void) +{ + return 0x00405824U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_c_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_z_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_zbc_tbl_ld_action_write_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_trigger_active_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_tga_constraintlogic_r(void) +{ + return 0x00405830U; +} +static inline u32 gr_ds_tga_constraintlogic_beta_cbsize_f(u32 v) +{ + return (v & 0xfffU) << 16U; +} +static inline u32 gr_ds_tga_constraintlogic_alpha_cbsize_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_ds_hww_esr_r(void) +{ + return 0x00405840U; +} +static inline u32 gr_ds_hww_esr_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_report_mask_r(void) +{ + return 0x00405844U; +} +static inline u32 gr_ds_hww_report_mask_sph0_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_hww_report_mask_sph1_err_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_ds_hww_report_mask_sph2_err_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_hww_report_mask_sph3_err_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_ds_hww_report_mask_sph4_err_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_ds_hww_report_mask_sph5_err_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_ds_hww_report_mask_sph6_err_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_ds_hww_report_mask_sph7_err_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_ds_hww_report_mask_sph8_err_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_ds_hww_report_mask_sph9_err_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_ds_hww_report_mask_sph10_err_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_ds_hww_report_mask_sph11_err_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_ds_hww_report_mask_sph12_err_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_ds_hww_report_mask_sph13_err_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_ds_hww_report_mask_sph14_err_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_ds_hww_report_mask_sph15_err_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_ds_hww_report_mask_sph16_err_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_ds_hww_report_mask_sph17_err_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_ds_hww_report_mask_sph18_err_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_ds_hww_report_mask_sph19_err_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_ds_hww_report_mask_sph20_err_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_ds_hww_report_mask_sph21_err_report_f(void) +{ + return 0x200000U; +} +static inline u32 gr_ds_hww_report_mask_sph22_err_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_ds_hww_report_mask_sph23_err_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_ds_num_tpc_per_gpc_r(u32 i) +{ + return 0x00405870U + i*4U; +} +static inline u32 gr_scc_bundle_cb_base_r(void) +{ + return 0x00408004U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_bundle_cb_size_r(void) +{ + return 0x00408008U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b__prod_v(void) +{ + return 0x00000018U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_scc_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_pagepool_base_r(void) +{ + return 0x0040800cU; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_pagepool_r(void) +{ + return 0x00408010U; +} +static inline u32 gr_scc_pagepool_total_pages_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_value_v(void) +{ + return 0x00000080U; +} +static inline u32 gr_scc_pagepool_total_pages_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_s(void) +{ + return 8U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_m(void) +{ + return 0xffU << 8U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 gr_scc_pagepool_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_init_r(void) +{ + return 0x0040802cU; +} +static inline u32 gr_scc_init_ram_trigger_f(void) +{ + return 0x1U; +} +static inline u32 gr_scc_hww_esr_r(void) +{ + return 0x00408030U; +} +static inline u32 gr_scc_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_scc_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_sked_hww_esr_r(void) +{ + return 0x00407020U; +} +static inline u32 gr_sked_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_cwd_fs_r(void) +{ + return 0x00405b00U; +} +static inline u32 gr_cwd_fs_num_gpcs_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_fs_num_tpcs_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpc0_fs_gpc_r(void) +{ + return 0x00502608U; +} +static inline u32 gr_gpc0_fs_gpc_num_available_tpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_gpc0_fs_gpc_num_available_zculls_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_gpc0_cfg_r(void) +{ + return 0x00502620U; +} +static inline u32 gr_gpc0_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpccs_rc_lanes_r(void) +{ + return 0x00502880U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_rc_lane_size_r(u32 i) +{ + return 0x00502910U + i*0U; +} +static inline u32 gr_gpccs_rc_lane_size__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpccs_rc_lane_size_v_s(void) +{ + return 24U; +} +static inline u32 gr_gpccs_rc_lane_size_v_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_zcull_fs_r(void) +{ + return 0x00500910U; +} +static inline u32 gr_gpc0_zcull_fs_num_sms_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 gr_gpc0_zcull_fs_num_active_banks_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_gpc0_zcull_ram_addr_r(void) +{ + return 0x00500914U; +} +static inline u32 gr_gpc0_zcull_ram_addr_tiles_per_hypertile_row_per_gpc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_gpc0_zcull_ram_addr_row_offset_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_r(void) +{ + return 0x00500918U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative__max_v(void) +{ + return 0x00800000U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_r(void) +{ + return 0x00500920U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_num_aliquots_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_zcsize_r(u32 i) +{ + return 0x00500a04U + i*32U; +} +static inline u32 gr_gpc0_zcull_zcsize_height_subregion__multiple_v(void) +{ + return 0x00000040U; +} +static inline u32 gr_gpc0_zcull_zcsize_width_subregion__multiple_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpc0_gpm_pd_active_tpcs_r(void) +{ + return 0x00500c08U; +} +static inline u32 gr_gpc0_gpm_pd_active_tpcs_num_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_r(u32 i) +{ + return 0x00500c10U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_id_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_r(u32 i) +{ + return 0x00500c30U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_mask_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_gpm_sd_active_tpcs_r(void) +{ + return 0x00500c8cU; +} +static inline u32 gr_gpc0_gpm_sd_active_tpcs_num_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_r(void) +{ + return 0x00504088U; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_value_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_l1c_cfg_smid_r(void) +{ + return 0x005044e8U; +} +static inline u32 gr_gpc0_tpc0_l1c_cfg_smid_value_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_r(void) +{ + return 0x00504698U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_sm_id_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_sm_id_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_r(void) +{ + return 0x0050469cU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_warp_count_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_spa_version_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_spa_version_smkepler_lp_v(void) +{ + return 0x0000000cU; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_r(void) +{ + return 0x00503018U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_true_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_r(void) +{ + return 0x005030c0U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_start_offset_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_start_offset_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_start_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_size_f(u32 v) +{ + return (v & 0xfffU) << 16U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_size_m(void) +{ + return 0xfffU << 16U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_size_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_size_default_v(void) +{ + return 0x00000240U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_size_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg_timeslice_mode_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_r(void) +{ + return 0x005030e4U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_start_offset_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_size_f(u32 v) +{ + return (v & 0xfffU) << 16U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_size_m(void) +{ + return 0xfffU << 16U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_size_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_size_default_v(void) +{ + return 0x00000648U; +} +static inline u32 gr_gpc0_ppc0_cbm_cfg2_size_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpccs_falcon_addr_r(void) +{ + return 0x0041a0acU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_msb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_v(u32 r) +{ + return (r >> 6U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_s(void) +{ + return 12U; +} +static inline u32 gr_gpccs_falcon_addr_ext_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_m(void) +{ + return 0xfffU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_gpccs_cpuctl_r(void) +{ + return 0x0041a100U; +} +static inline u32 gr_gpccs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_gpccs_dmactl_r(void) +{ + return 0x0041a10cU; +} +static inline u32 gr_gpccs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpccs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpccs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpccs_imemc_r(u32 i) +{ + return 0x0041a180U + i*16U; +} +static inline u32 gr_gpccs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_imemd_r(u32 i) +{ + return 0x0041a184U + i*16U; +} +static inline u32 gr_gpccs_imemt_r(u32 i) +{ + return 0x0041a188U + i*16U; +} +static inline u32 gr_gpccs_imemt__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_gpccs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpccs_dmemc_r(u32 i) +{ + return 0x0041a1c0U + i*8U; +} +static inline u32 gr_gpccs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_dmemd_r(u32 i) +{ + return 0x0041a1c4U + i*8U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_r(u32 i) +{ + return 0x0041a800U + i*4U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_r(void) +{ + return 0x00418808U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_s(void) +{ + return 32U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_setup_bundle_cb_base_addr_39_8_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_r(void) +{ + return 0x0041880cU; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_s(void) +{ + return 11U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_m(void) +{ + return 0x7ffU << 0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_v(u32 r) +{ + return (r >> 0U) & 0x7ffU; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b__prod_v(void) +{ + return 0x00000018U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_div_256b__prod_f(void) +{ + return 0x18U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_s(void) +{ + return 1U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_setup_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_r(void) +{ + return 0x00418810U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_align_bits_v(void) +{ + return 0x0000000cU; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_crstr_gpc_map0_r(void) +{ + return 0x00418b08U; +} +static inline u32 gr_crstr_gpc_map0_tile0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map0_tile1_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map0_tile2_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map0_tile3_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map0_tile4_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map0_tile5_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map1_r(void) +{ + return 0x00418b0cU; +} +static inline u32 gr_crstr_gpc_map1_tile6_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map1_tile7_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map1_tile8_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map1_tile9_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map1_tile10_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map1_tile11_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map2_r(void) +{ + return 0x00418b10U; +} +static inline u32 gr_crstr_gpc_map2_tile12_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map2_tile13_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map2_tile14_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map2_tile15_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map2_tile16_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map2_tile17_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map3_r(void) +{ + return 0x00418b14U; +} +static inline u32 gr_crstr_gpc_map3_tile18_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map3_tile19_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map3_tile20_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map3_tile21_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map3_tile22_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map3_tile23_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map4_r(void) +{ + return 0x00418b18U; +} +static inline u32 gr_crstr_gpc_map4_tile24_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map4_tile25_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map4_tile26_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map4_tile27_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map4_tile28_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map4_tile29_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map5_r(void) +{ + return 0x00418b1cU; +} +static inline u32 gr_crstr_gpc_map5_tile30_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map5_tile31_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map5_tile32_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map5_tile33_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map5_tile34_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map5_tile35_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_map_table_cfg_r(void) +{ + return 0x00418bb8U; +} +static inline u32 gr_crstr_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_crstr_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_r(void) +{ + return 0x00418980U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_1_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_2_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_3_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_4_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_5_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_6_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_7_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_r(void) +{ + return 0x00418984U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_8_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_9_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_10_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_11_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_12_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_13_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_14_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_15_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_r(void) +{ + return 0x00418988U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_16_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_17_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_18_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_19_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_20_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_21_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_22_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_s(void) +{ + return 3U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_m(void) +{ + return 0x7U << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_v(u32 r) +{ + return (r >> 28U) & 0x7U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_r(void) +{ + return 0x0041898cU; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_24_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_25_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_26_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_27_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_28_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_29_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_30_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_31_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_r(void) +{ + return 0x00418c6cU; +} +static inline u32 gr_gpcs_gpm_pd_cfg_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_timeslice_mode_enable_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_r(void) +{ + return 0x00419004U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_gcc_pagepool_r(void) +{ + return 0x00419008U; +} +static inline u32 gr_gpcs_gcc_pagepool_total_pages_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_r(void) +{ + return 0x0041980cU; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_fast_mode_switch_true_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_r(void) +{ + return 0x00419848U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_r(void) +{ + return 0x00419c00U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_enabled_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_r(void) +{ + return 0x00419e44U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_stack_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_api_stack_error_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_ret_empty_stack_error_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_wrap_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_pc_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_overflow_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_immc_addr_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_reg_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_encoding_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_sph_instr_combo_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_reg_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_addr_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_addr_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_addr_space_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param2_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_ldc_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_geometry_sm_error_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_divergent_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_r(void) +{ + return 0x00419e4cU; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_sm_to_sm_fault_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_l1_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_multiple_warp_errors_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_physical_stack_overflow_error_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_int_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_pause_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_single_step_complete_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_r(void) +{ + return 0x00419d0cU; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_tex_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_r(void) +{ + return 0x0041ac94U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_tpc_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gcc_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_0_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_r(void) +{ + return 0x00504610U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_on_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_off_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_off_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_single_step_mode_enable_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_single_step_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_stop_on_any_warp_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_stop_on_any_sm_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_warp_valid_mask_r(void) +{ + return 0x00504614U; +} +static inline u32 gr_gpc0_tpc0_sm_warp_valid_mask_1_r(void) +{ + return 0x00504618U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_r(void) +{ + return 0x00504624U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_1_r(void) +{ + return 0x00504628U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_r(void) +{ + return 0x00504634U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_1_r(void) +{ + return 0x00504638U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_bpt_pause_mask_r(void) +{ + return 0x00419e24U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_r(void) +{ + return 0x0050460cU; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_sm_in_trap_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_locked_down_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_locked_down_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_r(void) +{ + return 0x00419e50U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_sm_to_sm_fault_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_l1_error_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_multiple_warp_errors_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_physical_stack_overflow_error_pending_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_timeout_error_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_r(void) +{ + return 0x00504650U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_sm_to_sm_fault_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_l1_error_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_multiple_warp_errors_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_physical_stack_overflow_error_pending_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_timeout_error_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_r(void) +{ + return 0x00504224U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_intr_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_r(void) +{ + return 0x00504648U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_none_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_none_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_halfctl_ctrl_r(void) +{ + return 0x00504770U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_r(void) +{ + return 0x00419f70U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_gpc0_tpc0_sm_debug_sfe_control_r(void) +{ + return 0x0050477cU; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_r(void) +{ + return 0x00419f7cU; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_r(void) +{ + return 0x0041be08U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_fast_mode_switch_true_f(void) +{ + return 0x4U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map0_r(void) +{ + return 0x0041bf00U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map1_r(void) +{ + return 0x0041bf04U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map2_r(void) +{ + return 0x0041bf08U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map3_r(void) +{ + return 0x0041bf0cU; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map4_r(void) +{ + return 0x0041bf10U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map5_r(void) +{ + return 0x0041bf14U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_r(void) +{ + return 0x0041bfd0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_num_entries_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_shift_value_f(u32 v) +{ + return (v & 0x7U) << 21U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff5_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 24U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_r(void) +{ + return 0x0041bfd4U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_r(void) +{ + return 0x0041bfe4U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff6_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff7_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 5U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff8_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 10U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff9_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 15U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff10_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 20U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff11_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 25U; +} +static inline u32 gr_gpcs_ppcs_cbm_cfg_r(void) +{ + return 0x0041bec0U; +} +static inline u32 gr_gpcs_ppcs_cbm_cfg_timeslice_mode_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_bes_zrop_settings_r(void) +{ + return 0x00408850U; +} +static inline u32 gr_bes_zrop_settings_num_active_fbps_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_bes_crop_settings_r(void) +{ + return 0x00408958U; +} +static inline u32 gr_bes_crop_settings_num_active_fbps_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_zcull_bytes_per_aliquot_per_gpu_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_header_bytes_per_gpc_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_subregion_header_bytes_per_gpc_v(void) +{ + return 0x000000c0U; +} +static inline u32 gr_zcull_subregion_qty_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel0_r(void) +{ + return 0x00504604U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel1_r(void) +{ + return 0x00504608U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control0_r(void) +{ + return 0x0050465cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control1_r(void) +{ + return 0x00504660U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control2_r(void) +{ + return 0x00504664U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control3_r(void) +{ + return 0x00504668U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control4_r(void) +{ + return 0x0050466cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control5_r(void) +{ + return 0x00504658U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_status_r(void) +{ + return 0x00504670U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_status1_r(void) +{ + return 0x00504694U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_control_r(void) +{ + return 0x00504730U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_control_r(void) +{ + return 0x00504734U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_control_r(void) +{ + return 0x00504738U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_control_r(void) +{ + return 0x0050473cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter4_control_r(void) +{ + return 0x00504740U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter5_control_r(void) +{ + return 0x00504744U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter6_control_r(void) +{ + return 0x00504748U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter7_control_r(void) +{ + return 0x0050474cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_r(void) +{ + return 0x00504674U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_r(void) +{ + return 0x00504678U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_r(void) +{ + return 0x0050467cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_r(void) +{ + return 0x00504680U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter4_r(void) +{ + return 0x00504684U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter5_r(void) +{ + return 0x00504688U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter6_r(void) +{ + return 0x0050468cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter7_r(void) +{ + return 0x00504690U; +} +static inline u32 gr_fe_pwr_mode_r(void) +{ + return 0x00404170U; +} +static inline u32 gr_fe_pwr_mode_mode_auto_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_pwr_mode_mode_force_on_f(void) +{ + return 0x2U; +} +static inline u32 gr_fe_pwr_mode_req_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_fe_pwr_mode_req_send_f(void) +{ + return 0x10U; +} +static inline u32 gr_fe_pwr_mode_req_done_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_l1c_dbg_r(void) +{ + return 0x005044b0U; +} +static inline u32 gr_gpc0_tpc0_l1c_dbg_cya15_en_f(void) +{ + return 0x8000000U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_r(void) +{ + return 0x00419ec8U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_tile_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_tile_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_phase_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_phase_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_tex_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_tex_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_timeout_m(void) +{ + return 0xffU << 4U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_tex_hash_timeout_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_dot_t_unlock_m(void) +{ + return 0x1U << 16U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_texlock_dot_t_unlock_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_macro_sched_r(void) +{ + return 0x00419eacU; +} +static inline u32 gr_gpcs_tpcs_sm_sch_macro_sched_lockboost_size_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_gpcs_tpcs_sm_sch_macro_sched_lockboost_size_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_r(void) +{ + return 0x00419e10U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_debugger_mode_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_enable_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_ltc_gk20a.h b/include/nvgpu/hw/gk20a/hw_ltc_gk20a.h new file mode 100644 index 0000000..efe7f98 --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_ltc_gk20a.h @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ltc_gk20a_h_ +#define _hw_ltc_gk20a_h_ + +static inline u32 ltc_pltcg_base_v(void) +{ + return 0x00140000U; +} +static inline u32 ltc_pltcg_extent_v(void) +{ + return 0x0017ffffU; +} +static inline u32 ltc_ltcs_lts0_cbc_ctrl1_r(void) +{ + return 0x001410c8U; +} +static inline u32 ltc_ltc0_lts0_dstg_cfg0_r(void) +{ + return 0x00141200U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_r(void) +{ + return 0x0017ea00U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_r(void) +{ + return 0x00141104U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_ways_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_v(u32 r) +{ + return (r >> 16U) & 0x3U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_all_v(void) +{ + return 0x00000000U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_half_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_quarter_v(void) +{ + return 0x00000002U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void) +{ + return 0x0017e8c8U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(void) +{ + return 0x2U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_f(void) +{ + return 0x4U; +} +static inline u32 ltc_ltc0_lts0_cbc_ctrl1_r(void) +{ + return 0x001410c8U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_r(void) +{ + return 0x0017e8ccU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_r(void) +{ + return 0x0017e8d0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_init_v(void) +{ + return 0x0001ffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_r(void) +{ + return 0x0017e8d4U; +} +static inline u32 ltc_ltcs_ltss_cbc_base_alignment_shift_v(void) +{ + return 0x0000000bU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_address_v(u32 r) +{ + return (r >> 0U) & 0x3ffffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_r(void) +{ + return 0x0017e8dcU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_comptags_per_cache_line_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_cache_line_size_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_slices_per_fbp_v(u32 r) +{ + return (r >> 28U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_r(void) +{ + return 0x0017e91cU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_max_ways_evict_last_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_r(void) +{ + return 0x0017ea44U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_address_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value_r(u32 i) +{ + return 0x0017ea48U + i*4U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_r(void) +{ + return 0x0017ea58U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_s(void) +{ + return 32U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_r(void) +{ + return 0x0017e924U; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_l2_bypass_mode_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_r(void) +{ + return 0x0017e828U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_r(void) +{ + return 0x00140828U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_intr_r(void) +{ + return 0x00140820U; +} +static inline u32 ltc_ltcs_ltss_intr_r(void) +{ + return 0x0017e820U; +} +static inline u32 ltc_ltcs_ltss_intr_en_evicted_cb_m(void) +{ + return 0x1U << 20U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_m(void) +{ + return 0x1U << 21U; +} +static inline u32 ltc_ltc0_lts0_intr_r(void) +{ + return 0x00141020U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_r(void) +{ + return 0x0017e910U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_r(void) +{ + return 0x0017e914U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_f(void) +{ + return 0x10000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_r(void) +{ + return 0x00140910U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_r(void) +{ + return 0x00140914U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_mc_gk20a.h b/include/nvgpu/hw/gk20a/hw_mc_gk20a.h new file mode 100644 index 0000000..3ca2a29 --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_mc_gk20a.h @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_mc_gk20a_h_ +#define _hw_mc_gk20a_h_ + +static inline u32 mc_boot_0_r(void) +{ + return 0x00000000U; +} +static inline u32 mc_boot_0_architecture_v(u32 r) +{ + return (r >> 24U) & 0x1fU; +} +static inline u32 mc_boot_0_implementation_v(u32 r) +{ + return (r >> 20U) & 0xfU; +} +static inline u32 mc_boot_0_major_revision_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 mc_boot_0_minor_revision_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 mc_intr_0_r(void) +{ + return 0x00000100U; +} +static inline u32 mc_intr_0_pfifo_pending_f(void) +{ + return 0x100U; +} +static inline u32 mc_intr_0_pgraph_pending_f(void) +{ + return 0x1000U; +} +static inline u32 mc_intr_0_pmu_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_0_ltc_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 mc_intr_0_priv_ring_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 mc_intr_0_pbus_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_intr_1_r(void) +{ + return 0x00000104U; +} +static inline u32 mc_intr_mask_0_r(void) +{ + return 0x00000640U; +} +static inline u32 mc_intr_mask_0_pmu_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_en_0_r(void) +{ + return 0x00000140U; +} +static inline u32 mc_intr_en_0_inta_disabled_f(void) +{ + return 0x0U; +} +static inline u32 mc_intr_en_0_inta_hardware_f(void) +{ + return 0x1U; +} +static inline u32 mc_intr_mask_1_r(void) +{ + return 0x00000644U; +} +static inline u32 mc_intr_mask_1_pmu_s(void) +{ + return 1U; +} +static inline u32 mc_intr_mask_1_pmu_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 mc_intr_mask_1_pmu_m(void) +{ + return 0x1U << 24U; +} +static inline u32 mc_intr_mask_1_pmu_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 mc_intr_mask_1_pmu_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_en_1_r(void) +{ + return 0x00000144U; +} +static inline u32 mc_intr_en_1_inta_disabled_f(void) +{ + return 0x0U; +} +static inline u32 mc_intr_en_1_inta_hardware_f(void) +{ + return 0x1U; +} +static inline u32 mc_enable_r(void) +{ + return 0x00000200U; +} +static inline u32 mc_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_enable_l2_enabled_f(void) +{ + return 0x8U; +} +static inline u32 mc_enable_pmedia_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pmedia_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 mc_enable_pmedia_m(void) +{ + return 0x1U << 4U; +} +static inline u32 mc_enable_pmedia_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 mc_enable_priv_ring_enabled_f(void) +{ + return 0x20U; +} +static inline u32 mc_enable_ce0_m(void) +{ + return 0x1U << 6U; +} +static inline u32 mc_enable_pfifo_enabled_f(void) +{ + return 0x100U; +} +static inline u32 mc_enable_pgraph_enabled_f(void) +{ + return 0x1000U; +} +static inline u32 mc_enable_pwr_v(u32 r) +{ + return (r >> 13U) & 0x1U; +} +static inline u32 mc_enable_pwr_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 mc_enable_pwr_enabled_f(void) +{ + return 0x2000U; +} +static inline u32 mc_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_enable_ce2_m(void) +{ + return 0x1U << 21U; +} +static inline u32 mc_enable_ce2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 mc_enable_blg_enabled_f(void) +{ + return 0x8000000U; +} +static inline u32 mc_enable_perfmon_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +static inline u32 mc_enable_pb_r(void) +{ + return 0x00000204U; +} +static inline u32 mc_enable_pb_0_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pb_0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 mc_enable_pb_0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 mc_enable_pb_0_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 mc_enable_pb_0_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 mc_enable_pb_sel_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 mc_elpg_enable_r(void) +{ + return 0x0000020cU; +} +static inline u32 mc_elpg_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_elpg_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_elpg_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_pbdma_gk20a.h b/include/nvgpu/hw/gk20a/hw_pbdma_gk20a.h new file mode 100644 index 0000000..2c8f48d --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_pbdma_gk20a.h @@ -0,0 +1,575 @@ +/* + * Copyright (c) 2012-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pbdma_gk20a_h_ +#define _hw_pbdma_gk20a_h_ + +static inline u32 pbdma_gp_entry1_r(void) +{ + return 0x10000004U; +} +static inline u32 pbdma_gp_entry1_get_hi_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pbdma_gp_entry1_length_f(u32 v) +{ + return (v & 0x1fffffU) << 10U; +} +static inline u32 pbdma_gp_entry1_length_v(u32 r) +{ + return (r >> 10U) & 0x1fffffU; +} +static inline u32 pbdma_gp_base_r(u32 i) +{ + return 0x00040048U + i*8192U; +} +static inline u32 pbdma_gp_base__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 pbdma_gp_base_offset_f(u32 v) +{ + return (v & 0x1fffffffU) << 3U; +} +static inline u32 pbdma_gp_base_rsvd_s(void) +{ + return 3U; +} +static inline u32 pbdma_gp_base_hi_r(u32 i) +{ + return 0x0004004cU + i*8192U; +} +static inline u32 pbdma_gp_base_hi_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_gp_base_hi_limit2_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 pbdma_gp_fetch_r(u32 i) +{ + return 0x00040050U + i*8192U; +} +static inline u32 pbdma_gp_get_r(u32 i) +{ + return 0x00040014U + i*8192U; +} +static inline u32 pbdma_gp_put_r(u32 i) +{ + return 0x00040000U + i*8192U; +} +static inline u32 pbdma_timeout_r(u32 i) +{ + return 0x0004012cU + i*8192U; +} +static inline u32 pbdma_timeout__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 pbdma_timeout_period_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 pbdma_timeout_period_max_f(void) +{ + return 0xffffffffU; +} +static inline u32 pbdma_pb_fetch_r(u32 i) +{ + return 0x00040054U + i*8192U; +} +static inline u32 pbdma_pb_fetch_hi_r(u32 i) +{ + return 0x00040058U + i*8192U; +} +static inline u32 pbdma_get_r(u32 i) +{ + return 0x00040018U + i*8192U; +} +static inline u32 pbdma_get_hi_r(u32 i) +{ + return 0x0004001cU + i*8192U; +} +static inline u32 pbdma_put_r(u32 i) +{ + return 0x0004005cU + i*8192U; +} +static inline u32 pbdma_put_hi_r(u32 i) +{ + return 0x00040060U + i*8192U; +} +static inline u32 pbdma_formats_r(u32 i) +{ + return 0x0004009cU + i*8192U; +} +static inline u32 pbdma_formats_gp_fermi0_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_formats_pb_fermi1_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_formats_mp_fermi0_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_r(u32 i) +{ + return 0x00040084U + i*8192U; +} +static inline u32 pbdma_pb_header_priv_user_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_method_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_subchannel_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_level_main_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_pb_header_type_inc_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_pb_header_type_non_inc_f(void) +{ + return 0x60000000U; +} +static inline u32 pbdma_hdr_shadow_r(u32 i) +{ + return 0x00040118U + i*8192U; +} +static inline u32 pbdma_gp_shadow_0_r(u32 i) +{ + return 0x00040110U + i*8192U; +} +static inline u32 pbdma_gp_shadow_1_r(u32 i) +{ + return 0x00040114U + i*8192U; +} +static inline u32 pbdma_subdevice_r(u32 i) +{ + return 0x00040094U + i*8192U; +} +static inline u32 pbdma_subdevice_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 pbdma_subdevice_status_active_f(void) +{ + return 0x10000000U; +} +static inline u32 pbdma_subdevice_channel_dma_enable_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_method0_r(u32 i) +{ + return 0x000400c0U + i*8192U; +} +static inline u32 pbdma_method0_addr_f(u32 v) +{ + return (v & 0xfffU) << 2U; +} +static inline u32 pbdma_method0_addr_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 pbdma_method0_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 pbdma_method0_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_method0_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_method1_r(u32 i) +{ + return 0x000400c8U + i*8192U; +} +static inline u32 pbdma_method2_r(u32 i) +{ + return 0x000400d0U + i*8192U; +} +static inline u32 pbdma_method3_r(u32 i) +{ + return 0x000400d8U + i*8192U; +} +static inline u32 pbdma_data0_r(u32 i) +{ + return 0x000400c4U + i*8192U; +} +static inline u32 pbdma_target_r(u32 i) +{ + return 0x000400acU + i*8192U; +} +static inline u32 pbdma_target_engine_sw_f(void) +{ + return 0x1fU; +} +static inline u32 pbdma_acquire_r(u32 i) +{ + return 0x00040030U + i*8192U; +} +static inline u32 pbdma_acquire_retry_man_2_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_acquire_retry_exp_2_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_acquire_timeout_exp_f(u32 v) +{ + return (v & 0xfU) << 11U; +} +static inline u32 pbdma_acquire_timeout_exp_max_v(void) +{ + return 0x0000000fU; +} +static inline u32 pbdma_acquire_timeout_exp_max_f(void) +{ + return 0x7800U; +} +static inline u32 pbdma_acquire_timeout_man_f(u32 v) +{ + return (v & 0xffffU) << 15U; +} +static inline u32 pbdma_acquire_timeout_man_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 pbdma_acquire_timeout_man_max_f(void) +{ + return 0x7fff8000U; +} +static inline u32 pbdma_acquire_timeout_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_acquire_timeout_en_disable_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_status_r(u32 i) +{ + return 0x00040100U + i*8192U; +} +static inline u32 pbdma_channel_r(u32 i) +{ + return 0x00040120U + i*8192U; +} +static inline u32 pbdma_signature_r(u32 i) +{ + return 0x00040010U + i*8192U; +} +static inline u32 pbdma_signature_hw_valid_f(void) +{ + return 0xfaceU; +} +static inline u32 pbdma_signature_sw_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_r(u32 i) +{ + return 0x00040008U + i*8192U; +} +static inline u32 pbdma_userd_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_userd_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 pbdma_userd_addr_f(u32 v) +{ + return (v & 0x7fffffU) << 9U; +} +static inline u32 pbdma_userd_hi_r(u32 i) +{ + return 0x0004000cU + i*8192U; +} +static inline u32 pbdma_userd_hi_addr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_hce_ctrl_r(u32 i) +{ + return 0x000400e4U + i*8192U; +} +static inline u32 pbdma_hce_ctrl_hce_priv_mode_yes_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_r(u32 i) +{ + return 0x00040108U + i*8192U; +} +static inline u32 pbdma_intr_0_memreq_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pbdma_intr_0_memreq_pending_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_intr_0_memack_timeout_pending_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_intr_0_memack_extra_pending_f(void) +{ + return 0x4U; +} +static inline u32 pbdma_intr_0_memdat_timeout_pending_f(void) +{ + return 0x8U; +} +static inline u32 pbdma_intr_0_memdat_extra_pending_f(void) +{ + return 0x10U; +} +static inline u32 pbdma_intr_0_memflush_pending_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_memop_pending_f(void) +{ + return 0x40U; +} +static inline u32 pbdma_intr_0_lbconnect_pending_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_intr_0_lbreq_pending_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_0_lback_timeout_pending_f(void) +{ + return 0x200U; +} +static inline u32 pbdma_intr_0_lback_extra_pending_f(void) +{ + return 0x400U; +} +static inline u32 pbdma_intr_0_lbdat_timeout_pending_f(void) +{ + return 0x800U; +} +static inline u32 pbdma_intr_0_lbdat_extra_pending_f(void) +{ + return 0x1000U; +} +static inline u32 pbdma_intr_0_gpfifo_pending_f(void) +{ + return 0x2000U; +} +static inline u32 pbdma_intr_0_gpptr_pending_f(void) +{ + return 0x4000U; +} +static inline u32 pbdma_intr_0_gpentry_pending_f(void) +{ + return 0x8000U; +} +static inline u32 pbdma_intr_0_gpcrc_pending_f(void) +{ + return 0x10000U; +} +static inline u32 pbdma_intr_0_pbptr_pending_f(void) +{ + return 0x20000U; +} +static inline u32 pbdma_intr_0_pbentry_pending_f(void) +{ + return 0x40000U; +} +static inline u32 pbdma_intr_0_pbcrc_pending_f(void) +{ + return 0x80000U; +} +static inline u32 pbdma_intr_0_xbarconnect_pending_f(void) +{ + return 0x100000U; +} +static inline u32 pbdma_intr_0_method_pending_f(void) +{ + return 0x200000U; +} +static inline u32 pbdma_intr_0_methodcrc_pending_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_intr_0_device_pending_f(void) +{ + return 0x800000U; +} +static inline u32 pbdma_intr_0_semaphore_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 pbdma_intr_0_acquire_pending_f(void) +{ + return 0x4000000U; +} +static inline u32 pbdma_intr_0_pri_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 pbdma_intr_0_no_ctxsw_seg_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_intr_0_pbseg_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 pbdma_intr_0_signature_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_intr_1_r(u32 i) +{ + return 0x00040148U + i*8192U; +} +static inline u32 pbdma_intr_en_0_r(u32 i) +{ + return 0x0004010cU + i*8192U; +} +static inline u32 pbdma_intr_en_0_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_en_1_r(u32 i) +{ + return 0x0004014cU + i*8192U; +} +static inline u32 pbdma_intr_stall_r(u32 i) +{ + return 0x0004013cU + i*8192U; +} +static inline u32 pbdma_intr_stall_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_stall_1_r(u32 i) +{ + return 0x00040140U + i*8192U; +} +static inline u32 pbdma_intr_stall_1_hce_illegal_op_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_udma_nop_r(void) +{ + return 0x00000008U; +} +static inline u32 pbdma_syncpointa_r(u32 i) +{ + return 0x000400a4U + i*8192U; +} +static inline u32 pbdma_syncpointa_payload_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pbdma_syncpointb_r(u32 i) +{ + return 0x000400a8U + i*8192U; +} +static inline u32 pbdma_syncpointb_op_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 pbdma_syncpointb_op_wait_v(void) +{ + return 0x00000000U; +} +static inline u32 pbdma_syncpointb_wait_switch_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pbdma_syncpointb_wait_switch_en_v(void) +{ + return 0x00000001U; +} +static inline u32 pbdma_syncpointb_syncpt_index_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_perf_gk20a.h b/include/nvgpu/hw/gk20a/hw_perf_gk20a.h new file mode 100644 index 0000000..a93560f --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_perf_gk20a.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2015-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_perf_gk20a_h_ +#define _hw_perf_gk20a_h_ + +static inline u32 perf_pmasys_control_r(void) +{ + return 0x001b4000U; +} +static inline u32 perf_pmasys_control_membuf_status_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_f(void) +{ + return 0x10U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_f(void) +{ + return 0x20U; +} +static inline u32 perf_pmasys_mem_block_r(void) +{ + return 0x001b4070U; +} +static inline u32 perf_pmasys_mem_block_base_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 perf_pmasys_mem_block_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 perf_pmasys_mem_block_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 perf_pmasys_mem_block_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 perf_pmasys_mem_block_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 perf_pmasys_mem_block_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_mem_block_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_outbase_r(void) +{ + return 0x001b4074U; +} +static inline u32 perf_pmasys_outbase_ptr_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_outbaseupper_r(void) +{ + return 0x001b4078U; +} +static inline u32 perf_pmasys_outbaseupper_ptr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 perf_pmasys_outsize_r(void) +{ + return 0x001b407cU; +} +static inline u32 perf_pmasys_outsize_numbytes_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_mem_bytes_r(void) +{ + return 0x001b4084U; +} +static inline u32 perf_pmasys_mem_bytes_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_mem_bump_r(void) +{ + return 0x001b4088U; +} +static inline u32 perf_pmasys_mem_bump_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_enginestatus_r(void) +{ + return 0x001b40a4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_f(void) +{ + return 0x10U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_pram_gk20a.h b/include/nvgpu/hw/gk20a/hw_pram_gk20a.h new file mode 100644 index 0000000..10923e2 --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_pram_gk20a.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pram_gk20a_h_ +#define _hw_pram_gk20a_h_ + +static inline u32 pram_data032_r(u32 i) +{ + return 0x00700000U + i*4U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_pri_ringmaster_gk20a.h b/include/nvgpu/hw/gk20a/hw_pri_ringmaster_gk20a.h new file mode 100644 index 0000000..ca2775e --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_pri_ringmaster_gk20a.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringmaster_gk20a_h_ +#define _hw_pri_ringmaster_gk20a_h_ + +static inline u32 pri_ringmaster_command_r(void) +{ + return 0x0012004cU; +} +static inline u32 pri_ringmaster_command_cmd_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 pri_ringmaster_command_cmd_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 pri_ringmaster_command_cmd_no_cmd_v(void) +{ + return 0x00000000U; +} +static inline u32 pri_ringmaster_command_cmd_start_ring_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_command_cmd_ack_interrupt_f(void) +{ + return 0x2U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_f(void) +{ + return 0x3U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_bc_grp_all_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_command_data_r(void) +{ + return 0x00120048U; +} +static inline u32 pri_ringmaster_start_results_r(void) +{ + return 0x00120050U; +} +static inline u32 pri_ringmaster_start_results_connectivity_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_start_results_connectivity_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 pri_ringmaster_intr_status0_r(void) +{ + return 0x00120058U; +} +static inline u32 pri_ringmaster_intr_status0_ring_start_conn_fault_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_disconnect_fault_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_overflow_fault_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_gbl_write_error_sys_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status1_r(void) +{ + return 0x0012005cU; +} +static inline u32 pri_ringmaster_global_ctl_r(void) +{ + return 0x00120060U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_asserted_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_deasserted_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_enum_fbp_r(void) +{ + return 0x00120074U; +} +static inline u32 pri_ringmaster_enum_fbp_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_gpc_r(void) +{ + return 0x00120078U; +} +static inline u32 pri_ringmaster_enum_gpc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_pri_ringstation_fbp_gk20a.h b/include/nvgpu/hw/gk20a/hw_pri_ringstation_fbp_gk20a.h new file mode 100644 index 0000000..06e08bd --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_pri_ringstation_fbp_gk20a.h @@ -0,0 +1,231 @@ +/* + * drivers/video/tegra/host/gk20a/hw_pri_ringstation_fbp_gk20a.h + * + * Copyright (c) 2012-2013, 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. + */ + + /* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ + +#ifndef __hw_pri_ringstation_fbp_gk20a_h__ +#define __hw_pri_ringstation_fbp_gk20a_h__ +/*This file is autogenerated. Do not edit. */ + +static inline u32 pri_ringstation_fbp_master_config_r(u32 i) +{ + return 0x00124300+((i)*4); +} +static inline u32 pri_ringstation_fbp_master_config__size_1_v(void) +{ + return 64; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_s(void) +{ + return 18; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_f(u32 v) +{ + return (v & 0x3ffff) << 0; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_m(void) +{ + return 0x3ffff << 0; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_v(u32 r) +{ + return (r >> 0) & 0x3ffff; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_i_v(void) +{ + return 0x00000064; +} +static inline u32 pri_ringstation_fbp_master_config_timeout_i_f(void) +{ + return 0x64; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_s(void) +{ + return 1; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_f(u32 v) +{ + return (v & 0x1) << 30; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_m(void) +{ + return 0x1 << 30; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_v(u32 r) +{ + return (r >> 30) & 0x1; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_error_v(void) +{ + return 0x00000000; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_error_f(void) +{ + return 0x0; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_soldier_on_v(void) +{ + return 0x00000001; +} +static inline u32 pri_ringstation_fbp_master_config_fs_action_soldier_on_f(void) +{ + return 0x40000000; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_s(void) +{ + return 1; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_f(u32 v) +{ + return (v & 0x1) << 31; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_m(void) +{ + return 0x1 << 31; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_v(u32 r) +{ + return (r >> 31) & 0x1; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_error_v(void) +{ + return 0x00000000; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_error_f(void) +{ + return 0x0; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_soldier_on_v(void) +{ + return 0x00000001; +} +static inline u32 pri_ringstation_fbp_master_config_reset_action_soldier_on_f(void) +{ + return 0x80000000; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_s(void) +{ + return 3; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_f(u32 v) +{ + return (v & 0x7) << 20; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_m(void) +{ + return 0x7 << 20; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_v(u32 r) +{ + return (r >> 20) & 0x7; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_i_v(void) +{ + return 0x00000000; +} +static inline u32 pri_ringstation_fbp_master_config_setup_clocks_i_f(void) +{ + return 0x0; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_s(void) +{ + return 3; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_f(u32 v) +{ + return (v & 0x7) << 24; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_m(void) +{ + return 0x7 << 24; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_v(u32 r) +{ + return (r >> 24) & 0x7; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_i_v(void) +{ + return 0x00000000; +} +static inline u32 pri_ringstation_fbp_master_config_wait_clocks_i_f(void) +{ + return 0x0; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_s(void) +{ + return 3; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_f(u32 v) +{ + return (v & 0x7) << 27; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_m(void) +{ + return 0x7 << 27; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_v(u32 r) +{ + return (r >> 27) & 0x7; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_i_v(void) +{ + return 0x00000000; +} +static inline u32 pri_ringstation_fbp_master_config_hold_clocks_i_f(void) +{ + return 0x0; +} + +#endif /* __hw_pri_ringstation_fbp_gk20a_h__ */ diff --git a/include/nvgpu/hw/gk20a/hw_pri_ringstation_gpc_gk20a.h b/include/nvgpu/hw/gk20a/hw_pri_ringstation_gpc_gk20a.h new file mode 100644 index 0000000..6b57429 --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_pri_ringstation_gpc_gk20a.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_gpc_gk20a_h_ +#define _hw_pri_ringstation_gpc_gk20a_h_ + +static inline u32 pri_ringstation_gpc_master_config_r(u32 i) +{ + return 0x00128300U + i*4U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_adr_r(void) +{ + return 0x00128120U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_wrdat_r(void) +{ + return 0x00128124U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_info_r(void) +{ + return 0x00128128U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_code_r(void) +{ + return 0x0012812cU; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_pri_ringstation_sys_gk20a.h b/include/nvgpu/hw/gk20a/hw_pri_ringstation_sys_gk20a.h new file mode 100644 index 0000000..e4d5c3b --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_pri_ringstation_sys_gk20a.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_sys_gk20a_h_ +#define _hw_pri_ringstation_sys_gk20a_h_ + +static inline u32 pri_ringstation_sys_master_config_r(u32 i) +{ + return 0x00122300U + i*4U; +} +static inline u32 pri_ringstation_sys_decode_config_r(void) +{ + return 0x00122204U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_m(void) +{ + return 0x7U << 0U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_drop_on_ring_not_started_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringstation_sys_priv_error_adr_r(void) +{ + return 0x00122120U; +} +static inline u32 pri_ringstation_sys_priv_error_wrdat_r(void) +{ + return 0x00122124U; +} +static inline u32 pri_ringstation_sys_priv_error_info_r(void) +{ + return 0x00122128U; +} +static inline u32 pri_ringstation_sys_priv_error_code_r(void) +{ + return 0x0012212cU; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_proj_gk20a.h b/include/nvgpu/hw/gk20a/hw_proj_gk20a.h new file mode 100644 index 0000000..10509ca --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_proj_gk20a.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2012-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_proj_gk20a_h_ +#define _hw_proj_gk20a_h_ + +static inline u32 proj_gpc_base_v(void) +{ + return 0x00500000U; +} +static inline u32 proj_gpc_shared_base_v(void) +{ + return 0x00418000U; +} +static inline u32 proj_gpc_stride_v(void) +{ + return 0x00008000U; +} +static inline u32 proj_gpc_priv_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_ltc_stride_v(void) +{ + return 0x00002000U; +} +static inline u32 proj_lts_stride_v(void) +{ + return 0x00000400U; +} +static inline u32 proj_fbpa_stride_v(void) +{ + return 0x00001000U; +} +static inline u32 proj_ppc_in_gpc_base_v(void) +{ + return 0x00003000U; +} +static inline u32 proj_ppc_in_gpc_shared_base_v(void) +{ + return 0x00003e00U; +} +static inline u32 proj_ppc_in_gpc_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_rop_base_v(void) +{ + return 0x00410000U; +} +static inline u32 proj_rop_shared_base_v(void) +{ + return 0x00408800U; +} +static inline u32 proj_rop_stride_v(void) +{ + return 0x00000400U; +} +static inline u32 proj_tpc_in_gpc_base_v(void) +{ + return 0x00004000U; +} +static inline u32 proj_tpc_in_gpc_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_tpc_in_gpc_shared_base_v(void) +{ + return 0x00001800U; +} +static inline u32 proj_host_num_engines_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_host_num_pbdma_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_tpc_per_gpc_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_fbps_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_fbpas_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_gpcs_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_pes_per_gpc_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_tpcs_per_pes_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_zcull_banks_v(void) +{ + return 0x00000004U; +} +static inline u32 proj_scal_max_gpcs_v(void) +{ + return 0x00000020U; +} +static inline u32 proj_scal_max_tpc_per_gpc_v(void) +{ + return 0x00000008U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_pwr_gk20a.h b/include/nvgpu/hw/gk20a/hw_pwr_gk20a.h new file mode 100644 index 0000000..b879563 --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_pwr_gk20a.h @@ -0,0 +1,827 @@ +/* + * Copyright (c) 2012-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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pwr_gk20a_h_ +#define _hw_pwr_gk20a_h_ + +static inline u32 pwr_falcon_irqsset_r(void) +{ + return 0x0010a000U; +} +static inline u32 pwr_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqsclr_r(void) +{ + return 0x0010a004U; +} +static inline u32 pwr_falcon_irqstat_r(void) +{ + return 0x0010a008U; +} +static inline u32 pwr_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 pwr_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 pwr_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqmode_r(void) +{ + return 0x0010a00cU; +} +static inline u32 pwr_falcon_irqmset_r(void) +{ + return 0x0010a010U; +} +static inline u32 pwr_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_r(void) +{ + return 0x0010a014U; +} +static inline u32 pwr_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqmask_r(void) +{ + return 0x0010a018U; +} +static inline u32 pwr_falcon_irqdest_r(void) +{ + return 0x0010a01cU; +} +static inline u32 pwr_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 pwr_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 pwr_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 pwr_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 pwr_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 pwr_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 pwr_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 pwr_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 pwr_falcon_curctx_r(void) +{ + return 0x0010a050U; +} +static inline u32 pwr_falcon_nxtctx_r(void) +{ + return 0x0010a054U; +} +static inline u32 pwr_falcon_mailbox0_r(void) +{ + return 0x0010a040U; +} +static inline u32 pwr_falcon_mailbox1_r(void) +{ + return 0x0010a044U; +} +static inline u32 pwr_falcon_itfen_r(void) +{ + return 0x0010a048U; +} +static inline u32 pwr_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 pwr_falcon_idlestate_r(void) +{ + return 0x0010a04cU; +} +static inline u32 pwr_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 pwr_falcon_os_r(void) +{ + return 0x0010a080U; +} +static inline u32 pwr_falcon_engctl_r(void) +{ + return 0x0010a0a4U; +} +static inline u32 pwr_falcon_cpuctl_r(void) +{ + return 0x0010a100U; +} +static inline u32 pwr_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pwr_falcon_imemc_r(u32 i) +{ + return 0x0010a180U + i*16U; +} +static inline u32 pwr_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_imemd_r(u32 i) +{ + return 0x0010a184U + i*16U; +} +static inline u32 pwr_falcon_imemt_r(u32 i) +{ + return 0x0010a188U + i*16U; +} +static inline u32 pwr_falcon_bootvec_r(void) +{ + return 0x0010a104U; +} +static inline u32 pwr_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_falcon_dmactl_r(void) +{ + return 0x0010a10cU; +} +static inline u32 pwr_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 pwr_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_falcon_hwcfg_r(void) +{ + return 0x0010a108U; +} +static inline u32 pwr_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 pwr_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 pwr_falcon_dmatrfbase_r(void) +{ + return 0x0010a110U; +} +static inline u32 pwr_falcon_dmatrfmoffs_r(void) +{ + return 0x0010a114U; +} +static inline u32 pwr_falcon_dmatrfcmd_r(void) +{ + return 0x0010a118U; +} +static inline u32 pwr_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 pwr_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 pwr_falcon_dmatrffboffs_r(void) +{ + return 0x0010a11cU; +} +static inline u32 pwr_falcon_exterraddr_r(void) +{ + return 0x0010a168U; +} +static inline u32 pwr_falcon_exterrstat_r(void) +{ + return 0x0010a16cU; +} +static inline u32 pwr_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 pwr_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 pwr_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_r(void) +{ + return 0x0010a200U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 pwr_pmu_falcon_icd_rdata_r(void) +{ + return 0x0010a20cU; +} +static inline u32 pwr_falcon_dmemc_r(u32 i) +{ + return 0x0010a1c0U + i*8U; +} +static inline u32 pwr_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 pwr_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 pwr_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 pwr_falcon_dmemd_r(u32 i) +{ + return 0x0010a1c4U + i*8U; +} +static inline u32 pwr_pmu_new_instblk_r(void) +{ + return 0x0010a480U; +} +static inline u32 pwr_pmu_new_instblk_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 pwr_pmu_new_instblk_target_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 pwr_pmu_new_instblk_valid_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 pwr_pmu_mutex_id_r(void) +{ + return 0x0010a488U; +} +static inline u32 pwr_pmu_mutex_id_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_id_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_value_not_avail_v(void) +{ + return 0x000000ffU; +} +static inline u32 pwr_pmu_mutex_id_release_r(void) +{ + return 0x0010a48cU; +} +static inline u32 pwr_pmu_mutex_id_release_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_m(void) +{ + return 0xffU << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_mutex_r(u32 i) +{ + return 0x0010a580U + i*4U; +} +static inline u32 pwr_pmu_mutex__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 pwr_pmu_mutex_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_value_initial_lock_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_queue_head_r(u32 i) +{ + return 0x0010a4a0U + i*4U; +} +static inline u32 pwr_pmu_queue_head__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_queue_head_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_head_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_queue_tail_r(u32 i) +{ + return 0x0010a4b0U + i*4U; +} +static inline u32 pwr_pmu_queue_tail__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_queue_tail_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_tail_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_head_r(void) +{ + return 0x0010a4c8U; +} +static inline u32 pwr_pmu_msgq_head_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_head_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_tail_r(void) +{ + return 0x0010a4ccU; +} +static inline u32 pwr_pmu_msgq_tail_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_tail_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_idle_mask_r(u32 i) +{ + return 0x0010a504U + i*16U; +} +static inline u32 pwr_pmu_idle_mask_gr_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pwr_pmu_idle_mask_ce_2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 pwr_pmu_idle_mask_1_r(u32 i) +{ + return 0x0010aa34U + i*8U; +} +static inline u32 pwr_pmu_idle_count_r(u32 i) +{ + return 0x0010a508U + i*16U; +} +static inline u32 pwr_pmu_idle_count_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_count_value_v(u32 r) +{ + return (r >> 0U) & 0x7fffffffU; +} +static inline u32 pwr_pmu_idle_count_reset_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 pwr_pmu_idle_ctrl_r(u32 i) +{ + return 0x0010a50cU + i*16U; +} +static inline u32 pwr_pmu_idle_ctrl_value_m(void) +{ + return 0x3U << 0U; +} +static inline u32 pwr_pmu_idle_ctrl_value_busy_f(void) +{ + return 0x2U; +} +static inline u32 pwr_pmu_idle_ctrl_value_always_f(void) +{ + return 0x3U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_disabled_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_idle_threshold_r(u32 i) +{ + return 0x0010a8a0U + i*4U; +} +static inline u32 pwr_pmu_idle_threshold_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_intr_r(void) +{ + return 0x0010a9e8U; +} +static inline u32 pwr_pmu_idle_intr_en_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_en_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_idle_intr_en_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_r(void) +{ + return 0x0010a9ecU; +} +static inline u32 pwr_pmu_idle_intr_status_intr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_m(void) +{ + return 0x1U << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_pmu_idle_mask_supp_r(u32 i) +{ + return 0x0010a9f0U + i*8U; +} +static inline u32 pwr_pmu_idle_mask_1_supp_r(u32 i) +{ + return 0x0010a9f4U + i*8U; +} +static inline u32 pwr_pmu_idle_ctrl_supp_r(u32 i) +{ + return 0x0010aa30U + i*8U; +} +static inline u32 pwr_pmu_debug_r(u32 i) +{ + return 0x0010a5c0U + i*4U; +} +static inline u32 pwr_pmu_debug__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_mailbox_r(u32 i) +{ + return 0x0010a450U + i*4U; +} +static inline u32 pwr_pmu_mailbox__size_1_v(void) +{ + return 0x0000000cU; +} +static inline u32 pwr_pmu_bar0_addr_r(void) +{ + return 0x0010a7a0U; +} +static inline u32 pwr_pmu_bar0_data_r(void) +{ + return 0x0010a7a4U; +} +static inline u32 pwr_pmu_bar0_ctl_r(void) +{ + return 0x0010a7acU; +} +static inline u32 pwr_pmu_bar0_timeout_r(void) +{ + return 0x0010a7a8U; +} +static inline u32 pwr_pmu_bar0_fecs_error_r(void) +{ + return 0x0010a988U; +} +static inline u32 pwr_pmu_bar0_error_status_r(void) +{ + return 0x0010a7b0U; +} +static inline u32 pwr_pmu_pg_idlefilth_r(u32 i) +{ + return 0x0010a6c0U + i*4U; +} +static inline u32 pwr_pmu_pg_ppuidlefilth_r(u32 i) +{ + return 0x0010a6e8U + i*4U; +} +static inline u32 pwr_pmu_pg_idle_cnt_r(u32 i) +{ + return 0x0010a710U + i*4U; +} +static inline u32 pwr_pmu_pg_intren_r(u32 i) +{ + return 0x0010a760U + i*4U; +} +static inline u32 pwr_fbif_transcfg_r(u32 i) +{ + return 0x0010a600U + i*4U; +} +static inline u32 pwr_fbif_transcfg_target_local_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_target_coherent_sysmem_f(void) +{ + return 0x1U; +} +static inline u32 pwr_fbif_transcfg_target_noncoherent_sysmem_f(void) +{ + return 0x2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_s(void) +{ + return 1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_virtual_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_mem_type_physical_f(void) +{ + return 0x4U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_ram_gk20a.h b/include/nvgpu/hw/gk20a/hw_ram_gk20a.h new file mode 100644 index 0000000..ed385d9 --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_ram_gk20a.h @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ram_gk20a_h_ +#define _hw_ram_gk20a_h_ + +static inline u32 ram_in_ramfc_s(void) +{ + return 4096U; +} +static inline u32 ram_in_ramfc_w(void) +{ + return 0U; +} +static inline u32 ram_in_page_dir_base_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ram_in_page_dir_base_target_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 ram_in_page_dir_base_vol_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_page_dir_base_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_page_dir_base_lo_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_page_dir_base_hi_w(void) +{ + return 129U; +} +static inline u32 ram_in_adr_limit_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_adr_limit_lo_w(void) +{ + return 130U; +} +static inline u32 ram_in_adr_limit_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_adr_limit_hi_w(void) +{ + return 131U; +} +static inline u32 ram_in_engine_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_cs_wfi_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_engine_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_engine_cs_fg_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_engine_cs_fg_f(void) +{ + return 0x8U; +} +static inline u32 ram_in_gr_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_gr_wfi_target_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_mode_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_mode_physical_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_gr_wfi_mode_physical_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_gr_wfi_mode_virtual_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_gr_wfi_mode_virtual_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_gr_wfi_ptr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_gr_wfi_ptr_lo_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_ptr_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_gr_wfi_ptr_hi_w(void) +{ + return 133U; +} +static inline u32 ram_in_base_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 ram_in_alloc_size_v(void) +{ + return 0x00001000U; +} +static inline u32 ram_fc_size_val_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_fc_gp_put_w(void) +{ + return 0U; +} +static inline u32 ram_fc_userd_w(void) +{ + return 2U; +} +static inline u32 ram_fc_userd_hi_w(void) +{ + return 3U; +} +static inline u32 ram_fc_signature_w(void) +{ + return 4U; +} +static inline u32 ram_fc_gp_get_w(void) +{ + return 5U; +} +static inline u32 ram_fc_pb_get_w(void) +{ + return 6U; +} +static inline u32 ram_fc_pb_get_hi_w(void) +{ + return 7U; +} +static inline u32 ram_fc_pb_top_level_get_w(void) +{ + return 8U; +} +static inline u32 ram_fc_pb_top_level_get_hi_w(void) +{ + return 9U; +} +static inline u32 ram_fc_acquire_w(void) +{ + return 12U; +} +static inline u32 ram_fc_semaphorea_w(void) +{ + return 14U; +} +static inline u32 ram_fc_semaphoreb_w(void) +{ + return 15U; +} +static inline u32 ram_fc_semaphorec_w(void) +{ + return 16U; +} +static inline u32 ram_fc_semaphored_w(void) +{ + return 17U; +} +static inline u32 ram_fc_gp_base_w(void) +{ + return 18U; +} +static inline u32 ram_fc_gp_base_hi_w(void) +{ + return 19U; +} +static inline u32 ram_fc_gp_fetch_w(void) +{ + return 20U; +} +static inline u32 ram_fc_pb_fetch_w(void) +{ + return 21U; +} +static inline u32 ram_fc_pb_fetch_hi_w(void) +{ + return 22U; +} +static inline u32 ram_fc_pb_put_w(void) +{ + return 23U; +} +static inline u32 ram_fc_pb_put_hi_w(void) +{ + return 24U; +} +static inline u32 ram_fc_pb_header_w(void) +{ + return 33U; +} +static inline u32 ram_fc_pb_count_w(void) +{ + return 34U; +} +static inline u32 ram_fc_subdevice_w(void) +{ + return 37U; +} +static inline u32 ram_fc_formats_w(void) +{ + return 39U; +} +static inline u32 ram_fc_syncpointa_w(void) +{ + return 41U; +} +static inline u32 ram_fc_syncpointb_w(void) +{ + return 42U; +} +static inline u32 ram_fc_target_w(void) +{ + return 43U; +} +static inline u32 ram_fc_hce_ctrl_w(void) +{ + return 57U; +} +static inline u32 ram_fc_chid_w(void) +{ + return 58U; +} +static inline u32 ram_fc_chid_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_fc_chid_id_w(void) +{ + return 0U; +} +static inline u32 ram_fc_runlist_timeslice_w(void) +{ + return 62U; +} +static inline u32 ram_fc_pb_timeslice_w(void) +{ + return 63U; +} +static inline u32 ram_userd_base_shift_v(void) +{ + return 0x00000009U; +} +static inline u32 ram_userd_chan_size_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_userd_put_w(void) +{ + return 16U; +} +static inline u32 ram_userd_get_w(void) +{ + return 17U; +} +static inline u32 ram_userd_ref_w(void) +{ + return 18U; +} +static inline u32 ram_userd_put_hi_w(void) +{ + return 19U; +} +static inline u32 ram_userd_ref_threshold_w(void) +{ + return 20U; +} +static inline u32 ram_userd_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_userd_get_hi_w(void) +{ + return 24U; +} +static inline u32 ram_userd_gp_get_w(void) +{ + return 34U; +} +static inline u32 ram_userd_gp_put_w(void) +{ + return 35U; +} +static inline u32 ram_userd_gp_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_gp_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_rl_entry_size_v(void) +{ + return 0x00000008U; +} +static inline u32 ram_rl_entry_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_type_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 ram_rl_entry_type_chid_f(void) +{ + return 0x0U; +} +static inline u32 ram_rl_entry_type_tsg_f(void) +{ + return 0x2000U; +} +static inline u32 ram_rl_entry_timeslice_scale_f(u32 v) +{ + return (v & 0xfU) << 14U; +} +static inline u32 ram_rl_entry_timeslice_scale_3_f(void) +{ + return 0xc000U; +} +static inline u32 ram_rl_entry_timeslice_timeout_f(u32 v) +{ + return (v & 0xffU) << 18U; +} +static inline u32 ram_rl_entry_timeslice_timeout_128_f(void) +{ + return 0x2000000U; +} +static inline u32 ram_rl_entry_tsg_length_f(u32 v) +{ + return (v & 0x3fU) << 26U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_therm_gk20a.h b/include/nvgpu/hw/gk20a/hw_therm_gk20a.h new file mode 100644 index 0000000..075c9bc --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_therm_gk20a.h @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_therm_gk20a_h_ +#define _hw_therm_gk20a_h_ + +static inline u32 therm_use_a_r(void) +{ + return 0x00020798U; +} +static inline u32 therm_use_a_ext_therm_0_enable_f(void) +{ + return 0x1U; +} +static inline u32 therm_use_a_ext_therm_1_enable_f(void) +{ + return 0x2U; +} +static inline u32 therm_use_a_ext_therm_2_enable_f(void) +{ + return 0x4U; +} +static inline u32 therm_evt_ext_therm_0_r(void) +{ + return 0x00020700U; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_init_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_0_priority_f(u32 v) +{ + return (v & 0x1fU) << 24U; +} +static inline u32 therm_evt_ext_therm_1_r(void) +{ + return 0x00020704U; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_init_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_1_priority_f(u32 v) +{ + return (v & 0x1fU) << 24U; +} +static inline u32 therm_evt_ext_therm_2_r(void) +{ + return 0x00020708U; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_init_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_2_priority_f(u32 v) +{ + return (v & 0x1fU) << 24U; +} +static inline u32 therm_weight_1_r(void) +{ + return 0x00020024U; +} +static inline u32 therm_config1_r(void) +{ + return 0x00020050U; +} +static inline u32 therm_config2_r(void) +{ + return 0x00020130U; +} +static inline u32 therm_config2_slowdown_factor_extended_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 therm_config2_grad_enable_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 therm_gate_ctrl_r(u32 i) +{ + return 0x00020200U + i*4U; +} +static inline u32 therm_gate_ctrl_eng_clk_m(void) +{ + return 0x3U << 0U; +} +static inline u32 therm_gate_ctrl_eng_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_eng_clk_auto_f(void) +{ + return 0x1U; +} +static inline u32 therm_gate_ctrl_eng_clk_stop_f(void) +{ + return 0x2U; +} +static inline u32 therm_gate_ctrl_blk_clk_m(void) +{ + return 0x3U << 2U; +} +static inline u32 therm_gate_ctrl_blk_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_blk_clk_auto_f(void) +{ + return 0x4U; +} +static inline u32 therm_gate_ctrl_eng_pwr_m(void) +{ + return 0x3U << 4U; +} +static inline u32 therm_gate_ctrl_eng_pwr_auto_f(void) +{ + return 0x10U; +} +static inline u32 therm_gate_ctrl_eng_pwr_off_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_gate_ctrl_eng_pwr_off_f(void) +{ + return 0x20U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_m(void) +{ + return 0x1fU << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_f(u32 v) +{ + return (v & 0x7U) << 13U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_m(void) +{ + return 0x7U << 13U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_m(void) +{ + return 0xfU << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_m(void) +{ + return 0xfU << 20U; +} +static inline u32 therm_fecs_idle_filter_r(void) +{ + return 0x00020288U; +} +static inline u32 therm_fecs_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_hubmmu_idle_filter_r(void) +{ + return 0x0002028cU; +} +static inline u32 therm_hubmmu_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_clk_slowdown_r(u32 i) +{ + return 0x00020160U + i*4U; +} +static inline u32 therm_clk_slowdown_idle_factor_f(u32 v) +{ + return (v & 0x3fU) << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_m(void) +{ + return 0x3fU << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_v(u32 r) +{ + return (r >> 16U) & 0x3fU; +} +static inline u32 therm_clk_slowdown_idle_factor_disabled_f(void) +{ + return 0x0U; +} +static inline u32 therm_grad_stepping_table_r(u32 i) +{ + return 0x000202c8U + i*4U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by1p5_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by2_f(void) +{ + return 0x2U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by4_f(void) +{ + return 0x6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f(void) +{ + return 0xeU; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_f(u32 v) +{ + return (v & 0x3fU) << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_m(void) +{ + return 0x3fU << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_f(u32 v) +{ + return (v & 0x3fU) << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_m(void) +{ + return 0x3fU << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_m(void) +{ + return 0x3fU << 24U; +} +static inline u32 therm_grad_stepping0_r(void) +{ + return 0x000202c0U; +} +static inline u32 therm_grad_stepping0_feature_s(void) +{ + return 1U; +} +static inline u32 therm_grad_stepping0_feature_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 therm_grad_stepping0_feature_m(void) +{ + return 0x1U << 0U; +} +static inline u32 therm_grad_stepping0_feature_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 therm_grad_stepping0_feature_enable_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping1_r(void) +{ + return 0x000202c4U; +} +static inline u32 therm_grad_stepping1_pdiv_duration_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 therm_clk_timing_r(u32 i) +{ + return 0x000203c0U + i*4U; +} +static inline u32 therm_clk_timing_grad_slowdown_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_m(void) +{ + return 0x1U << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_enabled_f(void) +{ + return 0x10000U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_timer_gk20a.h b/include/nvgpu/hw/gk20a/hw_timer_gk20a.h new file mode 100644 index 0000000..972d68a --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_timer_gk20a.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_timer_gk20a_h_ +#define _hw_timer_gk20a_h_ + +static inline u32 timer_pri_timeout_r(void) +{ + return 0x00009080U; +} +static inline u32 timer_pri_timeout_period_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 timer_pri_timeout_period_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 timer_pri_timeout_period_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 timer_pri_timeout_en_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 timer_pri_timeout_en_m(void) +{ + return 0x1U << 31U; +} +static inline u32 timer_pri_timeout_en_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_en_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 timer_pri_timeout_en_en_disabled_f(void) +{ + return 0x0U; +} +static inline u32 timer_pri_timeout_save_0_r(void) +{ + return 0x00009084U; +} +static inline u32 timer_pri_timeout_save_0_fecs_tgt_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_save_0_addr_v(u32 r) +{ + return (r >> 2U) & 0x3fffffU; +} +static inline u32 timer_pri_timeout_save_0_write_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 timer_pri_timeout_save_1_r(void) +{ + return 0x00009088U; +} +static inline u32 timer_pri_timeout_fecs_errcode_r(void) +{ + return 0x0000908cU; +} +static inline u32 timer_time_0_r(void) +{ + return 0x00009400U; +} +static inline u32 timer_time_1_r(void) +{ + return 0x00009410U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_top_gk20a.h b/include/nvgpu/hw/gk20a/hw_top_gk20a.h new file mode 100644 index 0000000..be7fa4a --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_top_gk20a.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_top_gk20a_h_ +#define _hw_top_gk20a_h_ + +static inline u32 top_num_gpcs_r(void) +{ + return 0x00022430U; +} +static inline u32 top_num_gpcs_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_tpc_per_gpc_r(void) +{ + return 0x00022434U; +} +static inline u32 top_tpc_per_gpc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_fbps_r(void) +{ + return 0x00022438U; +} +static inline u32 top_num_fbps_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_device_info_r(u32 i) +{ + return 0x00022700U + i*4U; +} +static inline u32 top_device_info__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 top_device_info_chain_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 top_device_info_chain_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_engine_enum_v(u32 r) +{ + return (r >> 26U) & 0xfU; +} +static inline u32 top_device_info_runlist_enum_v(u32 r) +{ + return (r >> 21U) & 0xfU; +} +static inline u32 top_device_info_intr_enum_v(u32 r) +{ + return (r >> 15U) & 0x1fU; +} +static inline u32 top_device_info_reset_enum_v(u32 r) +{ + return (r >> 9U) & 0x1fU; +} +static inline u32 top_device_info_type_enum_v(u32 r) +{ + return (r >> 2U) & 0x1fffffffU; +} +static inline u32 top_device_info_type_enum_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_type_enum_graphics_f(void) +{ + return 0x0U; +} +static inline u32 top_device_info_type_enum_copy0_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_type_enum_copy0_f(void) +{ + return 0x4U; +} +static inline u32 top_device_info_type_enum_copy1_v(void) +{ + return 0x00000002U; +} +static inline u32 top_device_info_type_enum_copy1_f(void) +{ + return 0x8U; +} +static inline u32 top_device_info_type_enum_copy2_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_type_enum_copy2_f(void) +{ + return 0xcU; +} +static inline u32 top_device_info_engine_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 top_device_info_runlist_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 top_device_info_intr_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 top_device_info_reset_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_entry_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 top_device_info_entry_not_valid_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_entry_enum_v(void) +{ + return 0x00000002U; +} +static inline u32 top_device_info_entry_engine_type_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_entry_data_v(void) +{ + return 0x00000001U; +} +static inline u32 top_fs_status_fbp_r(void) +{ + return 0x00022548U; +} +static inline u32 top_fs_status_fbp_cluster_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 top_fs_status_fbp_cluster_enable_v(void) +{ + return 0x00000000U; +} +static inline u32 top_fs_status_fbp_cluster_enable_f(void) +{ + return 0x0U; +} +static inline u32 top_fs_status_fbp_cluster_disable_v(void) +{ + return 0x00000001U; +} +static inline u32 top_fs_status_fbp_cluster_disable_f(void) +{ + return 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gk20a/hw_trim_gk20a.h b/include/nvgpu/hw/gk20a/hw_trim_gk20a.h new file mode 100644 index 0000000..f28c21f --- /dev/null +++ b/include/nvgpu/hw/gk20a/hw_trim_gk20a.h @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2012-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_trim_gk20a_h_ +#define _hw_trim_gk20a_h_ + +static inline u32 trim_sys_gpcpll_cfg_r(void) +{ + return 0x00137000U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_m(void) +{ + return 0x1U << 0U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_no_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_yes_f(void) +{ + return 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_iddq_m(void) +{ + return 0x1U << 1U; +} +static inline u32 trim_sys_gpcpll_cfg_iddq_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_iddq_power_on_v(void) +{ + return 0x00000000U; +} +static inline u32 trim_sys_gpcpll_cfg_enb_lckdet_m(void) +{ + return 0x1U << 4U; +} +static inline u32 trim_sys_gpcpll_cfg_enb_lckdet_power_on_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpcpll_cfg_enb_lckdet_power_off_f(void) +{ + return 0x10U; +} +static inline u32 trim_sys_gpcpll_cfg_pll_lock_v(u32 r) +{ + return (r >> 17U) & 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_pll_lock_true_f(void) +{ + return 0x20000U; +} +static inline u32 trim_sys_gpcpll_coeff_r(void) +{ + return 0x00137004U; +} +static inline u32 trim_sys_gpcpll_coeff_mdiv_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 trim_sys_gpcpll_coeff_mdiv_m(void) +{ + return 0xffU << 0U; +} +static inline u32 trim_sys_gpcpll_coeff_mdiv_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 trim_sys_gpcpll_coeff_ndiv_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 trim_sys_gpcpll_coeff_ndiv_m(void) +{ + return 0xffU << 8U; +} +static inline u32 trim_sys_gpcpll_coeff_ndiv_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 trim_sys_gpcpll_coeff_pldiv_f(u32 v) +{ + return (v & 0x3fU) << 16U; +} +static inline u32 trim_sys_gpcpll_coeff_pldiv_m(void) +{ + return 0x3fU << 16U; +} +static inline u32 trim_sys_gpcpll_coeff_pldiv_v(u32 r) +{ + return (r >> 16U) & 0x3fU; +} +static inline u32 trim_sys_sel_vco_r(void) +{ + return 0x00137100U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_m(void) +{ + return 0x1U << 0U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_init_v(void) +{ + return 0x00000000U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_init_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_bypass_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_vco_f(void) +{ + return 0x1U; +} +static inline u32 trim_sys_gpc2clk_out_r(void) +{ + return 0x00137250U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_s(void) +{ + return 6U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_by31_f(void) +{ + return 0x3cU; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_s(void) +{ + return 6U; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_m(void) +{ + return 0x3fU << 8U; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_v(u32 r) +{ + return (r >> 8U) & 0x3fU; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_by1_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpc2clk_out_sdiv14_m(void) +{ + return 0x1U << 31U; +} +static inline u32 trim_sys_gpc2clk_out_sdiv14_indiv4_mode_f(void) +{ + return 0x80000000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_r(u32 i) +{ + return 0x00134124U + i*512U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_noofipclks_f(u32 v) +{ + return (v & 0x3fffU) << 0U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_write_en_asserted_f(void) +{ + return 0x10000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_enable_asserted_f(void) +{ + return 0x100000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_reset_asserted_f(void) +{ + return 0x1000000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cnt_r(u32 i) +{ + return 0x00134128U + i*512U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cnt_value_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 trim_sys_gpcpll_cfg2_r(void) +{ + return 0x0013700cU; +} +static inline u32 trim_sys_gpcpll_cfg2_pll_stepa_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 trim_sys_gpcpll_cfg2_pll_stepa_m(void) +{ + return 0xffU << 24U; +} +static inline u32 trim_sys_gpcpll_cfg3_r(void) +{ + return 0x00137018U; +} +static inline u32 trim_sys_gpcpll_cfg3_pll_stepb_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 trim_sys_gpcpll_cfg3_pll_stepb_m(void) +{ + return 0xffU << 16U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_r(void) +{ + return 0x0013701cU; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_m(void) +{ + return 0x1U << 22U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_yes_f(void) +{ + return 0x400000U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_no_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_en_dynramp_m(void) +{ + return 0x1U << 31U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_en_dynramp_yes_f(void) +{ + return 0x80000000U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_en_dynramp_no_f(void) +{ + return 0x0U; +} +static inline u32 trim_gpc_bcast_gpcpll_ndiv_slowdown_debug_r(void) +{ + return 0x001328a0U; +} +static inline u32 trim_gpc_bcast_gpcpll_ndiv_slowdown_debug_pll_dynramp_done_synced_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_bus_gm20b.h b/include/nvgpu/hw/gm20b/hw_bus_gm20b.h new file mode 100644 index 0000000..15cddae --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_bus_gm20b.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_bus_gm20b_h_ +#define _hw_bus_gm20b_h_ + +static inline u32 bus_bar0_window_r(void) +{ + return 0x00001700U; +} +static inline u32 bus_bar0_window_base_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 bus_bar0_window_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar0_window_target_sys_mem_coherent_f(void) +{ + return 0x2000000U; +} +static inline u32 bus_bar0_window_target_sys_mem_noncoherent_f(void) +{ + return 0x3000000U; +} +static inline u32 bus_bar0_window_target_bar0_window_base_shift_v(void) +{ + return 0x00000010U; +} +static inline u32 bus_bar1_block_r(void) +{ + return 0x00001704U; +} +static inline u32 bus_bar1_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar1_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar1_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar1_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar1_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar2_block_r(void) +{ + return 0x00001714U; +} +static inline u32 bus_bar2_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar2_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar2_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar2_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar2_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar1_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bar2_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bind_status_r(void) +{ + return 0x00001710U; +} +static inline u32 bus_bind_status_bar1_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 bus_bind_status_bar1_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar1_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 bus_bind_status_bar1_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 bus_bind_status_bar1_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar1_outstanding_true_f(void) +{ + return 0x2U; +} +static inline u32 bus_bind_status_bar2_pending_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 bus_bind_status_bar2_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar2_pending_busy_f(void) +{ + return 0x4U; +} +static inline u32 bus_bind_status_bar2_outstanding_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 bus_bind_status_bar2_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar2_outstanding_true_f(void) +{ + return 0x8U; +} +static inline u32 bus_intr_0_r(void) +{ + return 0x00001100U; +} +static inline u32 bus_intr_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +static inline u32 bus_intr_en_0_r(void) +{ + return 0x00001140U; +} +static inline u32 bus_intr_en_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_en_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_en_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_ccsr_gm20b.h b/include/nvgpu/hw/gm20b/hw_ccsr_gm20b.h new file mode 100644 index 0000000..adfce72 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_ccsr_gm20b.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ccsr_gm20b_h_ +#define _hw_ccsr_gm20b_h_ + +static inline u32 ccsr_channel_inst_r(u32 i) +{ + return 0x00800000U + i*8U; +} +static inline u32 ccsr_channel_inst__size_1_v(void) +{ + return 0x00000200U; +} +static inline u32 ccsr_channel_inst_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 ccsr_channel_inst_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 ccsr_channel_inst_bind_false_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_bind_true_f(void) +{ + return 0x80000000U; +} +static inline u32 ccsr_channel_r(u32 i) +{ + return 0x00800004U + i*8U; +} +static inline u32 ccsr_channel__size_1_v(void) +{ + return 0x00000200U; +} +static inline u32 ccsr_channel_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ccsr_channel_enable_set_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ccsr_channel_enable_set_true_f(void) +{ + return 0x400U; +} +static inline u32 ccsr_channel_enable_clr_true_f(void) +{ + return 0x800U; +} +static inline u32 ccsr_channel_status_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ccsr_channel_status_pending_ctx_reload_v(void) +{ + return 0x00000002U; +} +static inline u32 ccsr_channel_status_pending_acq_ctx_reload_v(void) +{ + return 0x00000004U; +} +static inline u32 ccsr_channel_status_on_pbdma_ctx_reload_v(void) +{ + return 0x0000000aU; +} +static inline u32 ccsr_channel_status_on_pbdma_and_eng_ctx_reload_v(void) +{ + return 0x0000000bU; +} +static inline u32 ccsr_channel_status_on_eng_ctx_reload_v(void) +{ + return 0x0000000cU; +} +static inline u32 ccsr_channel_status_on_eng_pending_ctx_reload_v(void) +{ + return 0x0000000dU; +} +static inline u32 ccsr_channel_status_on_eng_pending_acq_ctx_reload_v(void) +{ + return 0x0000000eU; +} +static inline u32 ccsr_channel_next_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ccsr_channel_next_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ccsr_channel_force_ctx_reload_true_f(void) +{ + return 0x100U; +} +static inline u32 ccsr_channel_busy_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_ce2_gm20b.h b/include/nvgpu/hw/gm20b/hw_ce2_gm20b.h new file mode 100644 index 0000000..fb741a7 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_ce2_gm20b.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ce2_gm20b_h_ +#define _hw_ce2_gm20b_h_ + +static inline u32 ce2_intr_status_r(void) +{ + return 0x00106908U; +} +static inline u32 ce2_intr_status_blockpipe_pending_f(void) +{ + return 0x1U; +} +static inline u32 ce2_intr_status_blockpipe_reset_f(void) +{ + return 0x1U; +} +static inline u32 ce2_intr_status_nonblockpipe_pending_f(void) +{ + return 0x2U; +} +static inline u32 ce2_intr_status_nonblockpipe_reset_f(void) +{ + return 0x2U; +} +static inline u32 ce2_intr_status_launcherr_pending_f(void) +{ + return 0x4U; +} +static inline u32 ce2_intr_status_launcherr_reset_f(void) +{ + return 0x4U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_ctxsw_prog_gm20b.h b/include/nvgpu/hw/gm20b/hw_ctxsw_prog_gm20b.h new file mode 100644 index 0000000..6b5632a --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_ctxsw_prog_gm20b.h @@ -0,0 +1,475 @@ +/* + * Copyright (c) 2014-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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ctxsw_prog_gm20b_h_ +#define _hw_ctxsw_prog_gm20b_h_ + +static inline u32 ctxsw_prog_fecs_header_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_main_image_num_gpcs_o(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_main_image_ctl_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_main_image_ctl_cde_enabled_f(void) +{ + return 0x400U; +} +static inline u32 ctxsw_prog_main_image_ctl_cde_disabled_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_patch_count_o(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_main_image_context_id_o(void) +{ + return 0x000000f0U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_lo_o(void) +{ + return 0x00000014U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_hi_o(void) +{ + return 0x00000018U; +} +static inline u32 ctxsw_prog_main_image_zcull_o(void) +{ + return 0x0000001cU; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_no_ctxsw_v(void) +{ + return 0x00000001U; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_separate_buffer_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_zcull_ptr_o(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_main_image_pm_o(void) +{ + return 0x00000028U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_m(void) +{ + return 0x7U << 0U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_ctxsw_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_m(void) +{ + return 0x7U << 3U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_ctxsw_f(void) +{ + return 0x8U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_pc_sampling_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 ctxsw_prog_main_image_pm_pc_sampling_m(void) +{ + return 0x1U << 6U; +} +static inline u32 ctxsw_prog_main_image_pm_ptr_o(void) +{ + return 0x0000002cU; +} +static inline u32 ctxsw_prog_main_image_num_save_ops_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_main_image_num_restore_ops_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_main_image_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_main_image_magic_value_v_value_v(void) +{ + return 0x600dc0deU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_local_image_ppc_info_num_ppcs_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_ppc_mask_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_num_tpcs_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_local_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_local_magic_value_v_value_v(void) +{ + return 0xad0becabU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_o(void) +{ + return 0x000000ecU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_size_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 ctxsw_prog_extended_buffer_segments_size_in_bytes_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_extended_marker_size_in_bytes_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_register_stride_v(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_control_register_stride_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_o(void) +{ + return 0x000000a0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_s(void) +{ + return 2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_m(void) +{ + return 0x3U << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_allow_all_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_use_map_f(void) +{ + return 0x2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_lo_o(void) +{ + return 0x000000a4U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_hi_o(void) +{ + return 0x000000a8U; +} +static inline u32 ctxsw_prog_main_image_misc_options_o(void) +{ + return 0x0000003cU; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_disabled_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_control_o(void) +{ + return 0x000000acU; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_control_num_records_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_o(void) +{ + return 0x000000b0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_v_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_sys_mem_coherent_f(void) +{ + return 0x20000000U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_sys_mem_noncoherent_f(void) +{ + return 0x30000000U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_o(void) +{ + return 0x000000b4U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_record_timestamp_record_size_in_bytes_v(void) +{ + return 0x00000080U; +} +static inline u32 ctxsw_prog_record_timestamp_record_size_in_words_v(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_lo_o(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_lo_v_value_v(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_hi_o(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_hi_v_value_v(void) +{ + return 0x600dbeefU; +} +static inline u32 ctxsw_prog_record_timestamp_context_id_o(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_record_timestamp_context_ptr_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_record_timestamp_new_context_id_o(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_record_timestamp_new_context_ptr_o(void) +{ + return 0x00000014U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_lo_o(void) +{ + return 0x00000018U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_o(void) +{ + return 0x0000001cU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_v_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_v_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_m(void) +{ + return 0xffU << 24U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_v(u32 r) +{ + return (r >> 24U) & 0xffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_ctxsw_req_by_host_v(void) +{ + return 0x00000001U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_ctxsw_req_by_host_f(void) +{ + return 0x1000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_f(void) +{ + return 0x2000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_wfi_v(void) +{ + return 0x0000000aU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_wfi_f(void) +{ + return 0xa000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_gfxp_v(void) +{ + return 0x0000000bU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_gfxp_f(void) +{ + return 0xb000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_ctap_v(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_ctap_f(void) +{ + return 0xc000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_cilp_v(void) +{ + return 0x0000000dU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_cilp_f(void) +{ + return 0xd000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_save_end_v(void) +{ + return 0x00000003U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_save_end_f(void) +{ + return 0x3000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_restore_start_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_restore_start_f(void) +{ + return 0x4000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_context_start_v(void) +{ + return 0x00000005U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_context_start_f(void) +{ + return 0x5000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_invalid_timestamp_v(void) +{ + return 0x000000ffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_invalid_timestamp_f(void) +{ + return 0xff000000U; +} +static inline u32 ctxsw_prog_main_image_preemption_options_o(void) +{ + return 0x00000060U; +} +static inline u32 ctxsw_prog_main_image_preemption_options_control_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_preemption_options_control_cta_enabled_f(void) +{ + return 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_falcon_gm20b.h b/include/nvgpu/hw/gm20b/hw_falcon_gm20b.h new file mode 100644 index 0000000..c598568 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_falcon_gm20b.h @@ -0,0 +1,599 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_falcon_gm20b_h_ +#define _hw_falcon_gm20b_h_ + +static inline u32 falcon_falcon_irqsset_r(void) +{ + return 0x00000000U; +} +static inline u32 falcon_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqsclr_r(void) +{ + return 0x00000004U; +} +static inline u32 falcon_falcon_irqstat_r(void) +{ + return 0x00000008U; +} +static inline u32 falcon_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 falcon_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 falcon_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqmode_r(void) +{ + return 0x0000000cU; +} +static inline u32 falcon_falcon_irqmset_r(void) +{ + return 0x00000010U; +} +static inline u32 falcon_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_r(void) +{ + return 0x00000014U; +} +static inline u32 falcon_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqmask_r(void) +{ + return 0x00000018U; +} +static inline u32 falcon_falcon_irqdest_r(void) +{ + return 0x0000001cU; +} +static inline u32 falcon_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 falcon_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 falcon_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 falcon_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 falcon_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 falcon_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 falcon_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 falcon_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 falcon_falcon_curctx_r(void) +{ + return 0x00000050U; +} +static inline u32 falcon_falcon_nxtctx_r(void) +{ + return 0x00000054U; +} +static inline u32 falcon_falcon_mailbox0_r(void) +{ + return 0x00000040U; +} +static inline u32 falcon_falcon_mailbox1_r(void) +{ + return 0x00000044U; +} +static inline u32 falcon_falcon_itfen_r(void) +{ + return 0x00000048U; +} +static inline u32 falcon_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 falcon_falcon_idlestate_r(void) +{ + return 0x0000004cU; +} +static inline u32 falcon_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 falcon_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 falcon_falcon_os_r(void) +{ + return 0x00000080U; +} +static inline u32 falcon_falcon_engctl_r(void) +{ + return 0x000000a4U; +} +static inline u32 falcon_falcon_cpuctl_r(void) +{ + return 0x00000100U; +} +static inline u32 falcon_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_cpuctl_sreset_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_cpuctl_hreset_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_stopped_m(void) +{ + return 0x1U << 5U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_alias_r(void) +{ + return 0x00000130U; +} +static inline u32 falcon_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_imemc_r(u32 i) +{ + return 0x00000180U + i*16U; +} +static inline u32 falcon_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_imemc_secure_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 falcon_falcon_imemd_r(u32 i) +{ + return 0x00000184U + i*16U; +} +static inline u32 falcon_falcon_imemt_r(u32 i) +{ + return 0x00000188U + i*16U; +} +static inline u32 falcon_falcon_sctl_r(void) +{ + return 0x00000240U; +} +static inline u32 falcon_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 falcon_falcon_bootvec_r(void) +{ + return 0x00000104U; +} +static inline u32 falcon_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 falcon_falcon_dmactl_r(void) +{ + return 0x0000010cU; +} +static inline u32 falcon_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 falcon_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 falcon_falcon_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_hwcfg_r(void) +{ + return 0x00000108U; +} +static inline u32 falcon_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 falcon_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 falcon_falcon_dmatrfbase_r(void) +{ + return 0x00000110U; +} +static inline u32 falcon_falcon_dmatrfmoffs_r(void) +{ + return 0x00000114U; +} +static inline u32 falcon_falcon_dmatrfcmd_r(void) +{ + return 0x00000118U; +} +static inline u32 falcon_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 falcon_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 falcon_falcon_dmatrffboffs_r(void) +{ + return 0x0000011cU; +} +static inline u32 falcon_falcon_imctl_debug_r(void) +{ + return 0x0000015cU; +} +static inline u32 falcon_falcon_imctl_debug_addr_blk_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 falcon_falcon_imctl_debug_cmd_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 falcon_falcon_imstat_r(void) +{ + return 0x00000144U; +} +static inline u32 falcon_falcon_traceidx_r(void) +{ + return 0x00000148U; +} +static inline u32 falcon_falcon_traceidx_maxidx_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 falcon_falcon_traceidx_idx_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 falcon_falcon_tracepc_r(void) +{ + return 0x0000014cU; +} +static inline u32 falcon_falcon_tracepc_pc_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 falcon_falcon_exterraddr_r(void) +{ + return 0x00000168U; +} +static inline u32 falcon_falcon_exterrstat_r(void) +{ + return 0x0000016cU; +} +static inline u32 falcon_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 falcon_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 falcon_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 falcon_falcon_icd_cmd_r(void) +{ + return 0x00000200U; +} +static inline u32 falcon_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 falcon_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 falcon_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 falcon_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 falcon_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 falcon_falcon_icd_rdata_r(void) +{ + return 0x0000020cU; +} +static inline u32 falcon_falcon_dmemc_r(u32 i) +{ + return 0x000001c0U + i*8U; +} +static inline u32 falcon_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 falcon_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 falcon_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 falcon_falcon_dmemd_r(u32 i) +{ + return 0x000001c4U + i*8U; +} +static inline u32 falcon_falcon_debug1_r(void) +{ + return 0x00000090U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_s(void) +{ + return 1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_m(void) +{ + return 0x1U << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_init_f(void) +{ + return 0x0U; +} +static inline u32 falcon_falcon_debuginfo_r(void) +{ + return 0x00000094U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_fb_gm20b.h b/include/nvgpu/hw/gm20b/hw_fb_gm20b.h new file mode 100644 index 0000000..e6464c1 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_fb_gm20b.h @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fb_gm20b_h_ +#define _hw_fb_gm20b_h_ + +static inline u32 fb_fbhub_num_active_ltcs_r(void) +{ + return 0x00100800U; +} +static inline u32 fb_mmu_ctrl_r(void) +{ + return 0x00100c80U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_space_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 fb_mmu_ctrl_use_pdb_big_page_size_v(u32 r) +{ + return (r >> 11U) & 0x1U; +} +static inline u32 fb_mmu_ctrl_use_pdb_big_page_size_true_f(void) +{ + return 0x800U; +} +static inline u32 fb_mmu_ctrl_use_pdb_big_page_size_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_use_full_comp_tag_line_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fb_mmu_ctrl_use_full_comp_tag_line_true_f(void) +{ + return 0x1000U; +} +static inline u32 fb_priv_mmu_phy_secure_r(void) +{ + return 0x00100ce4U; +} +static inline u32 fb_mmu_invalidate_pdb_r(void) +{ + return 0x00100cb8U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_sys_mem_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_pdb_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_invalidate_r(void) +{ + return 0x00100cbcU; +} +static inline u32 fb_mmu_invalidate_all_va_true_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_invalidate_all_pdb_true_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_trigger_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_trigger_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_trigger_true_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_debug_wr_r(void) +{ + return 0x00100cc8U; +} +static inline u32 fb_mmu_debug_wr_aperture_s(void) +{ + return 2U; +} +static inline u32 fb_mmu_debug_wr_aperture_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_m(void) +{ + return 0x3U << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fb_mmu_debug_wr_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_wr_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_vol_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_wr_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_debug_wr_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_wr_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_rd_r(void) +{ + return 0x00100cccU; +} +static inline u32 fb_mmu_debug_rd_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_rd_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_rd_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_ctrl_r(void) +{ + return 0x00100cc4U; +} +static inline u32 fb_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 fb_mmu_debug_ctrl_debug_m(void) +{ + return 0x1U << 16U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_vpr_info_r(void) +{ + return 0x00100cd0U; +} +static inline u32 fb_mmu_vpr_info_index_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fb_mmu_vpr_info_index_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fb_mmu_vpr_info_index_addr_lo_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_vpr_info_index_addr_hi_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_vpr_info_index_cya_lo_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_vpr_info_index_cya_hi_v(void) +{ + return 0x00000003U; +} +static inline u32 fb_mmu_vpr_info_fetch_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 fb_mmu_vpr_info_fetch_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 fb_mmu_vpr_info_fetch_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_vpr_info_fetch_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_wpr_info_r(void) +{ + return 0x00100cd4U; +} +static inline u32 fb_mmu_wpr_info_index_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 fb_mmu_wpr_info_index_allow_read_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_wpr_info_index_allow_write_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_wpr_info_index_wpr1_addr_lo_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_wpr_info_index_wpr1_addr_hi_v(void) +{ + return 0x00000003U; +} +static inline u32 fb_mmu_wpr_info_index_wpr2_addr_lo_v(void) +{ + return 0x00000004U; +} +static inline u32 fb_mmu_wpr_info_index_wpr2_addr_hi_v(void) +{ + return 0x00000005U; +} +static inline u32 fb_niso_flush_sysmem_addr_r(void) +{ + return 0x00100c10U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_fifo_gm20b.h b/include/nvgpu/hw/gm20b/hw_fifo_gm20b.h new file mode 100644 index 0000000..d32506d --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_fifo_gm20b.h @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fifo_gm20b_h_ +#define _hw_fifo_gm20b_h_ + +static inline u32 fifo_bar1_base_r(void) +{ + return 0x00002254U; +} +static inline u32 fifo_bar1_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_bar1_base_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_bar1_base_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 fifo_bar1_base_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_runlist_base_r(void) +{ + return 0x00002270U; +} +static inline u32 fifo_runlist_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_runlist_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fifo_runlist_base_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_runlist_base_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 fifo_runlist_r(void) +{ + return 0x00002274U; +} +static inline u32 fifo_runlist_engine_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 fifo_eng_runlist_base_r(u32 i) +{ + return 0x00002280U + i*8U; +} +static inline u32 fifo_eng_runlist_base__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_eng_runlist_r(u32 i) +{ + return 0x00002284U + i*8U; +} +static inline u32 fifo_eng_runlist__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_eng_runlist_length_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fifo_eng_runlist_length_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 fifo_eng_runlist_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_pb_timeslice_r(u32 i) +{ + return 0x00002350U + i*4U; +} +static inline u32 fifo_pb_timeslice_timeout_16_f(void) +{ + return 0x10U; +} +static inline u32 fifo_pb_timeslice_timescale_0_f(void) +{ + return 0x0U; +} +static inline u32 fifo_pb_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_pbdma_map_r(u32 i) +{ + return 0x00002390U + i*4U; +} +static inline u32 fifo_intr_0_r(void) +{ + return 0x00002100U; +} +static inline u32 fifo_intr_0_bind_error_pending_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_bind_error_reset_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_sched_error_pending_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_sched_error_reset_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_chsw_error_pending_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_chsw_error_reset_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_fb_flush_timeout_pending_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_fb_flush_timeout_reset_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_lb_error_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_lb_error_reset_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_dropped_mmu_fault_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 fifo_intr_0_dropped_mmu_fault_reset_f(void) +{ + return 0x8000000U; +} +static inline u32 fifo_intr_0_mmu_fault_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_intr_0_pbdma_intr_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_intr_0_runlist_event_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 fifo_intr_0_channel_intr_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_intr_en_0_r(void) +{ + return 0x00002140U; +} +static inline u32 fifo_intr_en_0_sched_error_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_intr_en_0_sched_error_m(void) +{ + return 0x1U << 8U; +} +static inline u32 fifo_intr_en_0_mmu_fault_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 fifo_intr_en_0_mmu_fault_m(void) +{ + return 0x1U << 28U; +} +static inline u32 fifo_intr_en_1_r(void) +{ + return 0x00002528U; +} +static inline u32 fifo_intr_bind_error_r(void) +{ + return 0x0000252cU; +} +static inline u32 fifo_intr_sched_error_r(void) +{ + return 0x0000254cU; +} +static inline u32 fifo_intr_sched_error_code_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fifo_intr_sched_error_code_ctxsw_timeout_v(void) +{ + return 0x0000000aU; +} +static inline u32 fifo_intr_chsw_error_r(void) +{ + return 0x0000256cU; +} +static inline u32 fifo_intr_mmu_fault_id_r(void) +{ + return 0x0000259cU; +} +static inline u32 fifo_intr_mmu_fault_eng_id_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_intr_mmu_fault_eng_id_graphics_f(void) +{ + return 0x0U; +} +static inline u32 fifo_intr_mmu_fault_inst_r(u32 i) +{ + return 0x00002800U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_inst_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 fifo_intr_mmu_fault_inst_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_intr_mmu_fault_lo_r(u32 i) +{ + return 0x00002804U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_hi_r(u32 i) +{ + return 0x00002808U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_info_r(u32 i) +{ + return 0x0000280cU + i*16U; +} +static inline u32 fifo_intr_mmu_fault_info_type_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 fifo_intr_mmu_fault_info_write_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 fifo_intr_mmu_fault_info_engine_subid_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 fifo_intr_mmu_fault_info_engine_subid_gpc_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_intr_mmu_fault_info_engine_subid_hub_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_mmu_fault_info_client_v(u32 r) +{ + return (r >> 8U) & 0x3fU; +} +static inline u32 fifo_intr_pbdma_id_r(void) +{ + return 0x000025a0U; +} +static inline u32 fifo_intr_pbdma_id_status_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_intr_pbdma_id_status_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fifo_intr_pbdma_id_status__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_runlist_r(void) +{ + return 0x00002a00U; +} +static inline u32 fifo_fb_timeout_r(void) +{ + return 0x00002a04U; +} +static inline u32 fifo_fb_timeout_period_m(void) +{ + return 0x3fffffffU << 0U; +} +static inline u32 fifo_fb_timeout_period_max_f(void) +{ + return 0x3fffffffU; +} +static inline u32 fifo_error_sched_disable_r(void) +{ + return 0x0000262cU; +} +static inline u32 fifo_sched_disable_r(void) +{ + return 0x00002630U; +} +static inline u32 fifo_sched_disable_runlist_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_sched_disable_runlist_m(u32 i) +{ + return 0x1U << (0U + i*1U); +} +static inline u32 fifo_sched_disable_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_preempt_r(void) +{ + return 0x00002634U; +} +static inline u32 fifo_preempt_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_preempt_type_channel_f(void) +{ + return 0x0U; +} +static inline u32 fifo_preempt_type_tsg_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_preempt_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_preempt_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_trigger_mmu_fault_r(u32 i) +{ + return 0x00002a30U + i*4U; +} +static inline u32 fifo_trigger_mmu_fault_id_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 fifo_trigger_mmu_fault_enable_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_engine_status_r(u32 i) +{ + return 0x00002640U + i*8U; +} +static inline u32 fifo_engine_status__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fifo_engine_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_engine_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_engine_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_engine_status_ctx_status_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_ctx_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_engine_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_engine_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_engine_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_faulted_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fifo_engine_status_faulted_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_engine_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fifo_engine_status_engine_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_engine_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_f(void) +{ + return 0x8000U; +} +static inline u32 fifo_pbdma_status_r(u32 i) +{ + return 0x00003080U + i*4U; +} +static inline u32 fifo_pbdma_status__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_pbdma_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_pbdma_status_chan_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_pbdma_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_pbdma_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_chsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_pbdma_status_chsw_in_progress_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_flush_gm20b.h b/include/nvgpu/hw/gm20b/hw_flush_gm20b.h new file mode 100644 index 0000000..3b5801b --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_flush_gm20b.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_flush_gm20b_h_ +#define _hw_flush_gm20b_h_ + +static inline u32 flush_l2_system_invalidate_r(void) +{ + return 0x00070004U; +} +static inline u32 flush_l2_system_invalidate_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_r(void) +{ + return 0x00070010U; +} +static inline u32 flush_l2_flush_dirty_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_r(void) +{ + return 0x0007000cU; +} +static inline u32 flush_l2_clean_comptags_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_r(void) +{ + return 0x00070000U; +} +static inline u32 flush_fb_flush_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_fb_flush_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_fb_flush_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_fb_flush_outstanding_true_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_fuse_gm20b.h b/include/nvgpu/hw/gm20b/hw_fuse_gm20b.h new file mode 100644 index 0000000..d97eb7d --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_fuse_gm20b.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fuse_gm20b_h_ +#define _hw_fuse_gm20b_h_ + +static inline u32 fuse_status_opt_gpc_r(void) +{ + return 0x00021c1cU; +} +static inline u32 fuse_status_opt_tpc_gpc_r(u32 i) +{ + return 0x00021c38U + i*4U; +} +static inline u32 fuse_ctrl_opt_tpc_gpc_r(u32 i) +{ + return 0x00021838U + i*4U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_r(void) +{ + return 0x00021944U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_m(void) +{ + return 0x3U << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_r(void) +{ + return 0x00021948U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_yes_f(void) +{ + return 0x1U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_no_f(void) +{ + return 0x0U; +} +static inline u32 fuse_status_opt_fbio_r(void) +{ + return 0x00021c14U; +} +static inline u32 fuse_status_opt_fbio_data_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fuse_status_opt_fbio_data_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fuse_status_opt_fbio_data_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fuse_status_opt_rop_l2_fbp_r(u32 i) +{ + return 0x00021d70U + i*4U; +} +static inline u32 fuse_status_opt_fbp_r(void) +{ + return 0x00021d38U; +} +static inline u32 fuse_status_opt_fbp_idx_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fuse_opt_sec_debug_en_r(void) +{ + return 0x00021218U; +} +static inline u32 fuse_opt_priv_sec_en_r(void) +{ + return 0x00021434U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_gmmu_gm20b.h b/include/nvgpu/hw/gm20b/hw_gmmu_gm20b.h new file mode 100644 index 0000000..11cc3d7 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_gmmu_gm20b.h @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gmmu_gm20b_h_ +#define _hw_gmmu_gm20b_h_ + +static inline u32 gmmu_pde_aperture_big_w(void) +{ + return 0U; +} +static inline u32 gmmu_pde_aperture_big_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_aperture_big_video_memory_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pde_aperture_big_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_pde_aperture_big_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 gmmu_pde_size_w(void) +{ + return 0U; +} +static inline u32 gmmu_pde_size_full_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_address_big_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_pde_address_big_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_pde_aperture_small_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_aperture_small_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_aperture_small_video_memory_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pde_aperture_small_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_pde_aperture_small_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 gmmu_pde_vol_small_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_vol_small_true_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_pde_vol_small_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_vol_big_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_vol_big_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_pde_vol_big_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pde_address_small_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_pde_address_small_sys_w(void) +{ + return 1U; +} +static inline u32 gmmu_pde_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_pde__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_pte__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_pte_valid_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_valid_true_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pte_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_privilege_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_privilege_true_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_pte_privilege_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_address_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_pte_address_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_address_vid_f(u32 v) +{ + return (v & 0x1ffffffU) << 4U; +} +static inline u32 gmmu_pte_address_vid_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_vol_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_vol_true_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_pte_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_aperture_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_aperture_video_memory_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_pte_aperture_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_pte_aperture_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_pte_read_only_w(void) +{ + return 0U; +} +static inline u32 gmmu_pte_read_only_true_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_pte_write_disable_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_write_disable_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gmmu_pte_read_disable_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_read_disable_true_f(void) +{ + return 0x40000000U; +} +static inline u32 gmmu_pte_comptagline_s(void) +{ + return 17U; +} +static inline u32 gmmu_pte_comptagline_f(u32 v) +{ + return (v & 0x1ffffU) << 12U; +} +static inline u32 gmmu_pte_comptagline_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_pte_kind_f(u32 v) +{ + return (v & 0xffU) << 4U; +} +static inline u32 gmmu_pte_kind_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_kind_invalid_v(void) +{ + return 0x000000ffU; +} +static inline u32 gmmu_pte_kind_pitch_v(void) +{ + return 0x00000000U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_gr_gm20b.h b/include/nvgpu/hw/gm20b/hw_gr_gm20b.h new file mode 100644 index 0000000..5bbb3b9 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_gr_gm20b.h @@ -0,0 +1,3927 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gr_gm20b_h_ +#define _hw_gr_gm20b_h_ + +static inline u32 gr_intr_r(void) +{ + return 0x00400100U; +} +static inline u32 gr_intr_notify_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_notify_reset_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_semaphore_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_semaphore_reset_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_illegal_method_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_method_reset_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_notify_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_illegal_notify_reset_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 gr_intr_firmware_method_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_firmware_method_reset_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_illegal_class_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_illegal_class_reset_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_fecs_error_pending_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_fecs_error_reset_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_class_error_pending_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_class_error_reset_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_exception_pending_f(void) +{ + return 0x200000U; +} +static inline u32 gr_intr_exception_reset_f(void) +{ + return 0x200000U; +} +static inline u32 gr_fecs_intr_r(void) +{ + return 0x00400144U; +} +static inline u32 gr_class_error_r(void) +{ + return 0x00400110U; +} +static inline u32 gr_class_error_code_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_intr_nonstall_r(void) +{ + return 0x00400120U; +} +static inline u32 gr_intr_nonstall_trap_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_en_r(void) +{ + return 0x0040013cU; +} +static inline u32 gr_exception_r(void) +{ + return 0x00400108U; +} +static inline u32 gr_exception_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception_gpc_m(void) +{ + return 0x1U << 24U; +} +static inline u32 gr_exception_memfmt_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_exception_ds_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_exception_sked_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_exception_pd_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_exception_scc_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_exception_ssync_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_exception_mme_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_exception1_r(void) +{ + return 0x00400118U; +} +static inline u32 gr_exception1_gpc_0_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_exception2_r(void) +{ + return 0x0040011cU; +} +static inline u32 gr_exception_en_r(void) +{ + return 0x00400138U; +} +static inline u32 gr_exception_en_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception1_en_r(void) +{ + return 0x00400130U; +} +static inline u32 gr_exception2_en_r(void) +{ + return 0x00400134U; +} +static inline u32 gr_gpfifo_ctl_r(void) +{ + return 0x00400500U; +} +static inline u32 gr_gpfifo_ctl_access_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpfifo_ctl_access_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpfifo_ctl_access_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpfifo_status_r(void) +{ + return 0x00400504U; +} +static inline u32 gr_trapped_addr_r(void) +{ + return 0x00400704U; +} +static inline u32 gr_trapped_addr_mthd_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 gr_trapped_addr_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 gr_trapped_addr_mme_generated_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 gr_trapped_addr_datahigh_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 gr_trapped_addr_priv_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 gr_trapped_addr_status_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_trapped_data_lo_r(void) +{ + return 0x00400708U; +} +static inline u32 gr_trapped_data_hi_r(void) +{ + return 0x0040070cU; +} +static inline u32 gr_trapped_data_mme_r(void) +{ + return 0x00400710U; +} +static inline u32 gr_trapped_data_mme_pc_v(u32 r) +{ + return (r >> 0U) & 0x7ffU; +} +static inline u32 gr_status_r(void) +{ + return 0x00400700U; +} +static inline u32 gr_status_fe_method_upper_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_status_fe_gi_v(u32 r) +{ + return (r >> 21U) & 0x1U; +} +static inline u32 gr_status_mask_r(void) +{ + return 0x00400610U; +} +static inline u32 gr_status_1_r(void) +{ + return 0x00400604U; +} +static inline u32 gr_status_2_r(void) +{ + return 0x00400608U; +} +static inline u32 gr_engine_status_r(void) +{ + return 0x0040060cU; +} +static inline u32 gr_engine_status_value_busy_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_be0_becs_be_exception_r(void) +{ + return 0x00410204U; +} +static inline u32 gr_pri_be0_becs_be_exception_en_r(void) +{ + return 0x00410208U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_en_r(void) +{ + return 0x00502c94U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_activity_0_r(void) +{ + return 0x00400380U; +} +static inline u32 gr_activity_1_r(void) +{ + return 0x00400384U; +} +static inline u32 gr_activity_2_r(void) +{ + return 0x00400388U; +} +static inline u32 gr_activity_4_r(void) +{ + return 0x00400390U; +} +static inline u32 gr_pri_gpc0_gcc_dbg_r(void) +{ + return 0x00501000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_r(void) +{ + return 0x00419000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_invalidate_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cache_control_r(void) +{ + return 0x005046a4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_r(void) +{ + return 0x00419ea4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_invalidate_cache_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_sked_activity_r(void) +{ + return 0x00407054U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity0_r(void) +{ + return 0x00502c80U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity1_r(void) +{ + return 0x00502c84U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity2_r(void) +{ + return 0x00502c88U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity3_r(void) +{ + return 0x00502c8cU; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x00504500U; +} +static inline u32 gr_pri_gpc0_tpc1_tpccs_tpc_activity_0_r(void) +{ + return 0x00504d00U; +} +static inline u32 gr_pri_gpc0_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00501d00U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_0_r(void) +{ + return 0x0041ac80U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_1_r(void) +{ + return 0x0041ac84U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_2_r(void) +{ + return 0x0041ac88U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_3_r(void) +{ + return 0x0041ac8cU; +} +static inline u32 gr_pri_gpcs_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x0041c500U; +} +static inline u32 gr_pri_gpcs_tpc1_tpccs_tpc_activity_0_r(void) +{ + return 0x0041cd00U; +} +static inline u32 gr_pri_gpcs_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00419d00U; +} +static inline u32 gr_pri_be0_becs_be_activity0_r(void) +{ + return 0x00410200U; +} +static inline u32 gr_pri_be1_becs_be_activity0_r(void) +{ + return 0x00410600U; +} +static inline u32 gr_pri_bes_becs_be_activity0_r(void) +{ + return 0x00408a00U; +} +static inline u32 gr_pri_ds_mpipe_status_r(void) +{ + return 0x00405858U; +} +static inline u32 gr_pri_fe_go_idle_on_status_r(void) +{ + return 0x00404150U; +} +static inline u32 gr_pri_fe_go_idle_check_r(void) +{ + return 0x00404158U; +} +static inline u32 gr_pri_fe_go_idle_info_r(void) +{ + return 0x00404194U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_tex_subunits_status_r(void) +{ + return 0x00504238U; +} +static inline u32 gr_pri_be0_crop_status1_r(void) +{ + return 0x00410134U; +} +static inline u32 gr_pri_bes_crop_status1_r(void) +{ + return 0x00408934U; +} +static inline u32 gr_pri_be0_zrop_status_r(void) +{ + return 0x00410048U; +} +static inline u32 gr_pri_be0_zrop_status2_r(void) +{ + return 0x0041004cU; +} +static inline u32 gr_pri_bes_zrop_status_r(void) +{ + return 0x00408848U; +} +static inline u32 gr_pri_bes_zrop_status2_r(void) +{ + return 0x0040884cU; +} +static inline u32 gr_pipe_bundle_address_r(void) +{ + return 0x00400200U; +} +static inline u32 gr_pipe_bundle_address_value_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pipe_bundle_data_r(void) +{ + return 0x00400204U; +} +static inline u32 gr_pipe_bundle_config_r(void) +{ + return 0x00400208U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_r(void) +{ + return 0x00404000U; +} +static inline u32 gr_fe_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_fe_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_info_r(void) +{ + return 0x004041b0U; +} +static inline u32 gr_fe_go_idle_timeout_r(void) +{ + return 0x00404154U; +} +static inline u32 gr_fe_go_idle_timeout_count_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fe_go_idle_timeout_count_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_go_idle_timeout_count_prod_f(void) +{ + return 0x800U; +} +static inline u32 gr_fe_object_table_r(u32 i) +{ + return 0x00404200U + i*4U; +} +static inline u32 gr_fe_object_table_nvclass_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_fe_tpc_fs_r(void) +{ + return 0x004041c4U; +} +static inline u32 gr_pri_mme_shadow_raw_index_r(void) +{ + return 0x00404488U; +} +static inline u32 gr_pri_mme_shadow_raw_index_write_trigger_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pri_mme_shadow_raw_data_r(void) +{ + return 0x0040448cU; +} +static inline u32 gr_mme_hww_esr_r(void) +{ + return 0x00404490U; +} +static inline u32 gr_mme_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_mme_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_mme_hww_esr_info_r(void) +{ + return 0x00404494U; +} +static inline u32 gr_memfmt_hww_esr_r(void) +{ + return 0x00404600U; +} +static inline u32 gr_memfmt_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_memfmt_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fecs_cpuctl_r(void) +{ + return 0x00409100U; +} +static inline u32 gr_fecs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_cpuctl_alias_r(void) +{ + return 0x00409130U; +} +static inline u32 gr_fecs_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_dmactl_r(void) +{ + return 0x0040910cU; +} +static inline u32 gr_fecs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_fecs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_fecs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_fecs_os_r(void) +{ + return 0x00409080U; +} +static inline u32 gr_fecs_idlestate_r(void) +{ + return 0x0040904cU; +} +static inline u32 gr_fecs_mailbox0_r(void) +{ + return 0x00409040U; +} +static inline u32 gr_fecs_mailbox1_r(void) +{ + return 0x00409044U; +} +static inline u32 gr_fecs_irqstat_r(void) +{ + return 0x00409008U; +} +static inline u32 gr_fecs_irqmode_r(void) +{ + return 0x0040900cU; +} +static inline u32 gr_fecs_irqmask_r(void) +{ + return 0x00409018U; +} +static inline u32 gr_fecs_irqdest_r(void) +{ + return 0x0040901cU; +} +static inline u32 gr_fecs_curctx_r(void) +{ + return 0x00409050U; +} +static inline u32 gr_fecs_nxtctx_r(void) +{ + return 0x00409054U; +} +static inline u32 gr_fecs_engctl_r(void) +{ + return 0x004090a4U; +} +static inline u32 gr_fecs_debug1_r(void) +{ + return 0x00409090U; +} +static inline u32 gr_fecs_debuginfo_r(void) +{ + return 0x00409094U; +} +static inline u32 gr_fecs_icd_cmd_r(void) +{ + return 0x00409200U; +} +static inline u32 gr_fecs_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 gr_fecs_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 gr_fecs_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 gr_fecs_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 gr_fecs_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 gr_fecs_icd_rdata_r(void) +{ + return 0x0040920cU; +} +static inline u32 gr_fecs_imemc_r(u32 i) +{ + return 0x00409180U + i*16U; +} +static inline u32 gr_fecs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_imemd_r(u32 i) +{ + return 0x00409184U + i*16U; +} +static inline u32 gr_fecs_imemt_r(u32 i) +{ + return 0x00409188U + i*16U; +} +static inline u32 gr_fecs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_dmemc_r(u32 i) +{ + return 0x004091c0U + i*8U; +} +static inline u32 gr_fecs_dmemc_offs_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 gr_fecs_dmemc_offs_v(u32 r) +{ + return (r >> 2U) & 0x3fU; +} +static inline u32 gr_fecs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_dmemd_r(u32 i) +{ + return 0x004091c4U + i*8U; +} +static inline u32 gr_fecs_dmatrfbase_r(void) +{ + return 0x00409110U; +} +static inline u32 gr_fecs_dmatrfmoffs_r(void) +{ + return 0x00409114U; +} +static inline u32 gr_fecs_dmatrffboffs_r(void) +{ + return 0x0040911cU; +} +static inline u32 gr_fecs_dmatrfcmd_r(void) +{ + return 0x00409118U; +} +static inline u32 gr_fecs_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_fecs_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_fecs_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_fecs_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_fecs_bootvec_r(void) +{ + return 0x00409104U; +} +static inline u32 gr_fecs_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_falcon_hwcfg_r(void) +{ + return 0x00409108U; +} +static inline u32 gr_gpcs_gpccs_falcon_hwcfg_r(void) +{ + return 0x0041a108U; +} +static inline u32 gr_fecs_falcon_rm_r(void) +{ + return 0x00409084U; +} +static inline u32 gr_fecs_current_ctx_r(void) +{ + return 0x00409b00U; +} +static inline u32 gr_fecs_current_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_current_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_current_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_current_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_current_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_current_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_current_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_current_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_current_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_current_ctx_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_method_data_r(void) +{ + return 0x00409500U; +} +static inline u32 gr_fecs_method_push_r(void) +{ + return 0x00409504U; +} +static inline u32 gr_fecs_method_push_adr_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_v(void) +{ + return 0x00000003U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_f(void) +{ + return 0x3U; +} +static inline u32 gr_fecs_method_push_adr_discover_image_size_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_method_push_adr_wfi_golden_save_v(void) +{ + return 0x00000009U; +} +static inline u32 gr_fecs_method_push_adr_restore_golden_v(void) +{ + return 0x00000015U; +} +static inline u32 gr_fecs_method_push_adr_discover_zcull_image_size_v(void) +{ + return 0x00000016U; +} +static inline u32 gr_fecs_method_push_adr_discover_pm_image_size_v(void) +{ + return 0x00000025U; +} +static inline u32 gr_fecs_method_push_adr_discover_reglist_image_size_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_bind_instance_v(void) +{ + return 0x00000031U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_virtual_address_v(void) +{ + return 0x00000032U; +} +static inline u32 gr_fecs_method_push_adr_stop_ctxsw_v(void) +{ + return 0x00000038U; +} +static inline u32 gr_fecs_method_push_adr_start_ctxsw_v(void) +{ + return 0x00000039U; +} +static inline u32 gr_fecs_method_push_adr_set_watchdog_timeout_f(void) +{ + return 0x21U; +} +static inline u32 gr_fecs_method_push_adr_write_timestamp_record_v(void) +{ + return 0x0000003dU; +} +static inline u32 gr_fecs_method_push_adr_halt_pipeline_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_fecs_host_int_status_r(void) +{ + return 0x00409c18U; +} +static inline u32 gr_fecs_host_int_status_fault_during_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_fecs_host_int_status_umimp_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 gr_fecs_host_int_status_umimp_illegal_method_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 gr_fecs_host_int_status_watchdog_active_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_host_int_status_ctxsw_intr_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_host_int_clear_r(void) +{ + return 0x00409c20U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_clear_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_r(void) +{ + return 0x00409c24U; +} +static inline u32 gr_fecs_host_int_enable_ctxsw_intr1_enable_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_fault_during_ctxsw_enable_f(void) +{ + return 0x10000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_firmware_method_enable_f(void) +{ + return 0x20000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_illegal_method_enable_f(void) +{ + return 0x40000U; +} +static inline u32 gr_fecs_host_int_enable_watchdog_enable_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_r(void) +{ + return 0x00409614U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_engine_reset_disabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_engine_reset_disabled_f(void) +{ + return 0x20U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_engine_reset_disabled_f(void) +{ + return 0x40U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_disabled_f(void) +{ + return 0x100U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_disabled_f(void) +{ + return 0x200U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_disabled_f(void) +{ + return 0x400U; +} +static inline u32 gr_fecs_ctx_state_store_major_rev_id_r(void) +{ + return 0x0040960cU; +} +static inline u32 gr_fecs_ctxsw_mailbox_r(u32 i) +{ + return 0x00409800U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_fail_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_r(u32 i) +{ + return 0x004098c0U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_r(u32 i) +{ + return 0x00409840U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_fs_r(void) +{ + return 0x00409604U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_fs_num_available_fbps_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_fbps_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_m(void) +{ + return 0x1fU << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_fecs_cfg_r(void) +{ + return 0x00409620U; +} +static inline u32 gr_fecs_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_fecs_rc_lanes_r(void) +{ + return 0x00409880U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_fecs_ctxsw_status_1_r(void) +{ + return 0x00409400U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_m(void) +{ + return 0x1U << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_adr_r(void) +{ + return 0x00409a24U; +} +static inline u32 gr_fecs_new_ctx_r(void) +{ + return 0x00409b04U; +} +static inline u32 gr_fecs_new_ctx_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_new_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_new_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_new_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_new_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_new_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_new_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_new_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_new_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_new_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_new_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_ptr_r(void) +{ + return 0x00409a0cU; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_arb_ctx_cmd_r(void) +{ + return 0x00409a10U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_ctxsw_status_fe_0_r(void) +{ + return 0x00409c00U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_gpc_0_r(void) +{ + return 0x00502c04U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_1_r(void) +{ + return 0x00502400U; +} +static inline u32 gr_fecs_ctxsw_idlestate_r(void) +{ + return 0x00409420U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_idlestate_r(void) +{ + return 0x00502420U; +} +static inline u32 gr_rstr2d_gpc_map0_r(void) +{ + return 0x0040780cU; +} +static inline u32 gr_rstr2d_gpc_map1_r(void) +{ + return 0x00407810U; +} +static inline u32 gr_rstr2d_gpc_map2_r(void) +{ + return 0x00407814U; +} +static inline u32 gr_rstr2d_gpc_map3_r(void) +{ + return 0x00407818U; +} +static inline u32 gr_rstr2d_gpc_map4_r(void) +{ + return 0x0040781cU; +} +static inline u32 gr_rstr2d_gpc_map5_r(void) +{ + return 0x00407820U; +} +static inline u32 gr_rstr2d_map_table_cfg_r(void) +{ + return 0x004078bcU; +} +static inline u32 gr_rstr2d_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_rstr2d_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_hww_esr_r(void) +{ + return 0x00406018U; +} +static inline u32 gr_pd_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pd_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_num_tpc_per_gpc_r(u32 i) +{ + return 0x00406028U + i*4U; +} +static inline u32 gr_pd_num_tpc_per_gpc__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count1_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count2_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count3_f(u32 v) +{ + return (v & 0xfU) << 12U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count4_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count5_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count6_f(u32 v) +{ + return (v & 0xfU) << 24U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count7_f(u32 v) +{ + return (v & 0xfU) << 28U; +} +static inline u32 gr_pd_ab_dist_cfg0_r(void) +{ + return 0x004064c0U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_en_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_dis_f(void) +{ + return 0x0U; +} +static inline u32 gr_pd_ab_dist_cfg1_r(void) +{ + return 0x004064c4U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_batches_init_f(void) +{ + return 0xffffU; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_granularity_v(void) +{ + return 0x00000080U; +} +static inline u32 gr_pd_ab_dist_cfg2_r(void) +{ + return 0x004064c8U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_init_v(void) +{ + return 0x000001c0U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_f(u32 v) +{ + return (v & 0xfffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_scc_bundle_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_min_gpm_fifo_depths_v(void) +{ + return 0x00000182U; +} +static inline u32 gr_pd_pagepool_r(void) +{ + return 0x004064ccU; +} +static inline u32 gr_pd_pagepool_total_pages_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_pagepool_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_dist_skip_table_r(u32 i) +{ + return 0x004064d0U + i*4U; +} +static inline u32 gr_pd_dist_skip_table__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n0_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n1_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n2_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n3_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_ds_debug_r(void) +{ + return 0x00405800U; +} +static inline u32 gr_ds_debug_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_debug_timeslice_mode_enable_f(void) +{ + return 0x8000000U; +} +static inline u32 gr_ds_zbc_color_r_r(void) +{ + return 0x00405804U; +} +static inline u32 gr_ds_zbc_color_r_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_g_r(void) +{ + return 0x00405808U; +} +static inline u32 gr_ds_zbc_color_g_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_b_r(void) +{ + return 0x0040580cU; +} +static inline u32 gr_ds_zbc_color_b_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_a_r(void) +{ + return 0x00405810U; +} +static inline u32 gr_ds_zbc_color_a_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_r(void) +{ + return 0x00405814U; +} +static inline u32 gr_ds_zbc_color_fmt_val_f(u32 v) +{ + return (v & 0x7fU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_zero_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_color_fmt_val_unorm_one_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_ds_zbc_color_fmt_val_rf32_gf32_bf32_af32_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_ds_zbc_color_fmt_val_a8_b8_g8_r8_v(void) +{ + return 0x00000028U; +} +static inline u32 gr_ds_zbc_z_r(void) +{ + return 0x00405818U; +} +static inline u32 gr_ds_zbc_z_val_s(void) +{ + return 32U; +} +static inline u32 gr_ds_zbc_z_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_z_val_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_ds_zbc_z_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_ds_zbc_z_val__init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_ds_zbc_z_val__init_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_r(void) +{ + return 0x0040581cU; +} +static inline u32 gr_ds_zbc_z_fmt_val_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_fp32_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_tbl_index_r(void) +{ + return 0x00405820U; +} +static inline u32 gr_ds_zbc_tbl_index_val_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_ds_zbc_tbl_ld_r(void) +{ + return 0x00405824U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_c_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_z_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_zbc_tbl_ld_action_write_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_trigger_active_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_tga_constraintlogic_r(void) +{ + return 0x00405830U; +} +static inline u32 gr_ds_tga_constraintlogic_beta_cbsize_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_ds_tga_constraintlogic_alpha_cbsize_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_ds_hww_esr_r(void) +{ + return 0x00405840U; +} +static inline u32 gr_ds_hww_esr_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_esr_2_r(void) +{ + return 0x00405848U; +} +static inline u32 gr_ds_hww_esr_2_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_2_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_2_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_2_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_2_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_2_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_2_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_report_mask_r(void) +{ + return 0x00405844U; +} +static inline u32 gr_ds_hww_report_mask_sph0_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_hww_report_mask_sph1_err_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_ds_hww_report_mask_sph2_err_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_hww_report_mask_sph3_err_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_ds_hww_report_mask_sph4_err_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_ds_hww_report_mask_sph5_err_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_ds_hww_report_mask_sph6_err_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_ds_hww_report_mask_sph7_err_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_ds_hww_report_mask_sph8_err_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_ds_hww_report_mask_sph9_err_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_ds_hww_report_mask_sph10_err_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_ds_hww_report_mask_sph11_err_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_ds_hww_report_mask_sph12_err_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_ds_hww_report_mask_sph13_err_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_ds_hww_report_mask_sph14_err_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_ds_hww_report_mask_sph15_err_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_ds_hww_report_mask_sph16_err_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_ds_hww_report_mask_sph17_err_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_ds_hww_report_mask_sph18_err_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_ds_hww_report_mask_sph19_err_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_ds_hww_report_mask_sph20_err_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_ds_hww_report_mask_sph21_err_report_f(void) +{ + return 0x200000U; +} +static inline u32 gr_ds_hww_report_mask_sph22_err_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_ds_hww_report_mask_sph23_err_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_ds_hww_report_mask_2_r(void) +{ + return 0x0040584cU; +} +static inline u32 gr_ds_hww_report_mask_2_sph24_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_num_tpc_per_gpc_r(u32 i) +{ + return 0x00405870U + i*4U; +} +static inline u32 gr_scc_bundle_cb_base_r(void) +{ + return 0x00408004U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_bundle_cb_size_r(void) +{ + return 0x00408008U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b__prod_v(void) +{ + return 0x00000018U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_scc_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_pagepool_base_r(void) +{ + return 0x0040800cU; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_pagepool_r(void) +{ + return 0x00408010U; +} +static inline u32 gr_scc_pagepool_total_pages_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_value_v(void) +{ + return 0x00000080U; +} +static inline u32 gr_scc_pagepool_total_pages_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_s(void) +{ + return 8U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_m(void) +{ + return 0xffU << 8U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 gr_scc_pagepool_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_init_r(void) +{ + return 0x0040802cU; +} +static inline u32 gr_scc_init_ram_trigger_f(void) +{ + return 0x1U; +} +static inline u32 gr_scc_hww_esr_r(void) +{ + return 0x00408030U; +} +static inline u32 gr_scc_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_scc_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_sked_hww_esr_r(void) +{ + return 0x00407020U; +} +static inline u32 gr_sked_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_cwd_fs_r(void) +{ + return 0x00405b00U; +} +static inline u32 gr_cwd_fs_num_gpcs_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_fs_num_tpcs_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_cwd_gpc_tpc_id_r(u32 i) +{ + return 0x00405b60U + i*4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc0_s(void) +{ + return 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_cwd_gpc_tpc_id_gpc0_s(void) +{ + return 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_gpc0_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc1_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_cwd_sm_id_r(u32 i) +{ + return 0x00405ba0U + i*4U; +} +static inline u32 gr_cwd_sm_id__size_1_v(void) +{ + return 0x00000006U; +} +static inline u32 gr_cwd_sm_id_tpc0_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_sm_id_tpc1_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpc0_fs_gpc_r(void) +{ + return 0x00502608U; +} +static inline u32 gr_gpc0_fs_gpc_num_available_tpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_gpc0_fs_gpc_num_available_zculls_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_gpc0_cfg_r(void) +{ + return 0x00502620U; +} +static inline u32 gr_gpc0_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpccs_rc_lanes_r(void) +{ + return 0x00502880U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_rc_lane_size_r(u32 i) +{ + return 0x00502910U + i*0U; +} +static inline u32 gr_gpccs_rc_lane_size__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpccs_rc_lane_size_v_s(void) +{ + return 24U; +} +static inline u32 gr_gpccs_rc_lane_size_v_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_zcull_fs_r(void) +{ + return 0x00500910U; +} +static inline u32 gr_gpc0_zcull_fs_num_sms_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 gr_gpc0_zcull_fs_num_active_banks_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_gpc0_zcull_ram_addr_r(void) +{ + return 0x00500914U; +} +static inline u32 gr_gpc0_zcull_ram_addr_tiles_per_hypertile_row_per_gpc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_gpc0_zcull_ram_addr_row_offset_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_r(void) +{ + return 0x00500918U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative__max_v(void) +{ + return 0x00800000U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_r(void) +{ + return 0x00500920U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_num_aliquots_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_zcsize_r(u32 i) +{ + return 0x00500a04U + i*32U; +} +static inline u32 gr_gpc0_zcull_zcsize_height_subregion__multiple_v(void) +{ + return 0x00000040U; +} +static inline u32 gr_gpc0_zcull_zcsize_width_subregion__multiple_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_r(u32 i) +{ + return 0x00500c10U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_id_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_r(u32 i) +{ + return 0x00500c30U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_mask_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_r(void) +{ + return 0x00504088U; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_value_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_r(void) +{ + return 0x00504698U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_sm_id_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_sm_id_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_r(void) +{ + return 0x0050469cU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_warp_count_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_spa_version_v(u32 r) +{ + return (r >> 8U) & 0xfffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_sm_version_v(u32 r) +{ + return (r >> 20U) & 0xfffU; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_r(void) +{ + return 0x00503018U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_true_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_r(void) +{ + return 0x005030c0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_default_v(void) +{ + return 0x00000400U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_offset_r(void) +{ + return 0x005030f4U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_r(void) +{ + return 0x005030e4U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_default_v(void) +{ + return 0x00000800U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_offset_r(void) +{ + return 0x005030f8U; +} +static inline u32 gr_gpcs_tpcs_tex_m_dbg2_r(void) +{ + return 0x00419a3cU; +} +static inline u32 gr_gpcs_tpcs_tex_m_dbg2_lg_rd_coalesce_en_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_gpcs_tpcs_tex_m_dbg2_lg_rd_coalesce_en_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpcs_tpcs_tex_m_dbg2_su_rd_coalesce_en_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_gpcs_tpcs_tex_m_dbg2_su_rd_coalesce_en_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpccs_falcon_addr_r(void) +{ + return 0x0041a0acU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_msb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_v(u32 r) +{ + return (r >> 6U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_s(void) +{ + return 12U; +} +static inline u32 gr_gpccs_falcon_addr_ext_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_m(void) +{ + return 0xfffU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_gpccs_cpuctl_r(void) +{ + return 0x0041a100U; +} +static inline u32 gr_gpccs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_gpccs_dmactl_r(void) +{ + return 0x0041a10cU; +} +static inline u32 gr_gpccs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpccs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpccs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpccs_imemc_r(u32 i) +{ + return 0x0041a180U + i*16U; +} +static inline u32 gr_gpccs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_imemd_r(u32 i) +{ + return 0x0041a184U + i*16U; +} +static inline u32 gr_gpccs_imemt_r(u32 i) +{ + return 0x0041a188U + i*16U; +} +static inline u32 gr_gpccs_imemt__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_gpccs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpccs_dmemc_r(u32 i) +{ + return 0x0041a1c0U + i*8U; +} +static inline u32 gr_gpccs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_dmemd_r(u32 i) +{ + return 0x0041a1c4U + i*8U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_r(u32 i) +{ + return 0x0041a800U + i*4U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_r(void) +{ + return 0x00418e24U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_s(void) +{ + return 32U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_r(void) +{ + return 0x00418e28U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_s(void) +{ + return 11U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_m(void) +{ + return 0x7ffU << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_v(u32 r) +{ + return (r >> 0U) & 0x7ffU; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_init_v(void) +{ + return 0x00000018U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_init_f(void) +{ + return 0x18U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_s(void) +{ + return 1U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_r(u32 i) +{ + return 0x00418ea0U + i*4U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_v_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_v_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_div3_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_div3_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 gr_gpcs_swdx_rm_pagepool_r(void) +{ + return 0x00418e30U; +} +static inline u32 gr_gpcs_swdx_rm_pagepool_total_pages_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpcs_swdx_rm_pagepool_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_r(void) +{ + return 0x00418810U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_align_bits_v(void) +{ + return 0x0000000cU; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_crstr_gpc_map0_r(void) +{ + return 0x00418b08U; +} +static inline u32 gr_crstr_gpc_map0_tile0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map0_tile1_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map0_tile2_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map0_tile3_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map0_tile4_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map0_tile5_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map1_r(void) +{ + return 0x00418b0cU; +} +static inline u32 gr_crstr_gpc_map1_tile6_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map1_tile7_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map1_tile8_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map1_tile9_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map1_tile10_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map1_tile11_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map2_r(void) +{ + return 0x00418b10U; +} +static inline u32 gr_crstr_gpc_map2_tile12_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map2_tile13_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map2_tile14_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map2_tile15_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map2_tile16_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map2_tile17_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map3_r(void) +{ + return 0x00418b14U; +} +static inline u32 gr_crstr_gpc_map3_tile18_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map3_tile19_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map3_tile20_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map3_tile21_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map3_tile22_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map3_tile23_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map4_r(void) +{ + return 0x00418b18U; +} +static inline u32 gr_crstr_gpc_map4_tile24_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map4_tile25_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map4_tile26_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map4_tile27_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map4_tile28_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map4_tile29_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map5_r(void) +{ + return 0x00418b1cU; +} +static inline u32 gr_crstr_gpc_map5_tile30_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map5_tile31_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map5_tile32_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map5_tile33_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map5_tile34_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map5_tile35_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_map_table_cfg_r(void) +{ + return 0x00418bb8U; +} +static inline u32 gr_crstr_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_crstr_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_r(void) +{ + return 0x00418980U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_1_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_2_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_3_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_4_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_5_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_6_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_7_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_r(void) +{ + return 0x00418984U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_8_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_9_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_10_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_11_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_12_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_13_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_14_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_15_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_r(void) +{ + return 0x00418988U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_16_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_17_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_18_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_19_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_20_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_21_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_22_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_s(void) +{ + return 3U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_m(void) +{ + return 0x7U << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_v(u32 r) +{ + return (r >> 28U) & 0x7U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_r(void) +{ + return 0x0041898cU; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_24_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_25_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_26_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_27_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_28_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_29_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_30_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_31_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_r(void) +{ + return 0x00418c6cU; +} +static inline u32 gr_gpcs_gpm_pd_cfg_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_timeslice_mode_enable_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_r(void) +{ + return 0x00419004U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_gcc_pagepool_r(void) +{ + return 0x00419008U; +} +static inline u32 gr_gpcs_gcc_pagepool_total_pages_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_r(void) +{ + return 0x0041980cU; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_fast_mode_switch_true_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_r(void) +{ + return 0x00419848U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_r(void) +{ + return 0x00419c00U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_enabled_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_r(void) +{ + return 0x00419c2cU; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_r(void) +{ + return 0x00419e44U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_stack_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_api_stack_error_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_ret_empty_stack_error_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_wrap_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_pc_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_overflow_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_immc_addr_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_reg_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_encoding_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_sph_instr_combo_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_reg_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_addr_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_addr_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_addr_space_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param2_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_ldc_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_mmu_fault_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_stack_overflow_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_geometry_sm_error_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_divergent_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_report_mask_r(void) +{ + return 0x00504644U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_r(void) +{ + return 0x00419e4cU; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_sm_to_sm_fault_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_l1_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_multiple_warp_errors_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_physical_stack_overflow_error_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_int_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_pause_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_single_step_complete_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_report_mask_r(void) +{ + return 0x0050464cU; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_r(void) +{ + return 0x00419d0cU; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_tex_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_r(void) +{ + return 0x0041ac94U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_tpc_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gcc_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_0_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_r(void) +{ + return 0x00504610U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_on_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_off_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_off_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_single_step_mode_enable_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_single_step_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_stop_on_any_warp_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_stop_on_any_sm_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_warp_valid_mask_r(void) +{ + return 0x00504614U; +} +static inline u32 gr_gpc0_tpc0_sm_warp_valid_mask_1_r(void) +{ + return 0x00504618U; +} +static inline u32 gr_gpc0_tpc0_sm_warp_valid_mask_2_r(void) +{ + return 0x0050461cU; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_r(void) +{ + return 0x00504624U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_1_r(void) +{ + return 0x00504628U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_2_r(void) +{ + return 0x00504750U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_r(void) +{ + return 0x00504634U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_1_r(void) +{ + return 0x00504638U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_2_r(void) +{ + return 0x00504758U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_bpt_pause_mask_r(void) +{ + return 0x00419e24U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_r(void) +{ + return 0x0050460cU; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_sm_in_trap_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_locked_down_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_locked_down_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_r(void) +{ + return 0x00419e50U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_sm_to_sm_fault_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_l1_error_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_multiple_warp_errors_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_physical_stack_overflow_error_pending_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_timeout_error_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_r(void) +{ + return 0x00504650U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_sm_to_sm_fault_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_l1_error_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_multiple_warp_errors_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_physical_stack_overflow_error_pending_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_timeout_error_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_r(void) +{ + return 0x00504224U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_intr_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_r(void) +{ + return 0x00504648U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_none_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_none_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_pc_r(void) +{ + return 0x00504654U; +} +static inline u32 gr_gpc0_tpc0_sm_halfctl_ctrl_r(void) +{ + return 0x00504770U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_r(void) +{ + return 0x00419f70U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_gpc0_tpc0_sm_debug_sfe_control_r(void) +{ + return 0x0050477cU; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_r(void) +{ + return 0x00419f7cU; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_r(void) +{ + return 0x0041be08U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_fast_mode_switch_true_f(void) +{ + return 0x4U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map0_r(void) +{ + return 0x0041bf00U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map1_r(void) +{ + return 0x0041bf04U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map2_r(void) +{ + return 0x0041bf08U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map3_r(void) +{ + return 0x0041bf0cU; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map4_r(void) +{ + return 0x0041bf10U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map5_r(void) +{ + return 0x0041bf14U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_r(void) +{ + return 0x0041bfd0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_num_entries_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_shift_value_f(u32 v) +{ + return (v & 0x7U) << 21U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff5_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 24U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_r(void) +{ + return 0x0041bfd4U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_r(void) +{ + return 0x0041bfe4U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff6_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff7_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 5U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff8_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 10U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff9_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 15U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff10_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 20U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff11_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 25U; +} +static inline u32 gr_bes_zrop_settings_r(void) +{ + return 0x00408850U; +} +static inline u32 gr_bes_zrop_settings_num_active_ltcs_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_be0_crop_debug3_r(void) +{ + return 0x00410108U; +} +static inline u32 gr_bes_crop_debug3_r(void) +{ + return 0x00408908U; +} +static inline u32 gr_bes_crop_debug3_comp_vdc_4to2_disable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_bes_crop_settings_r(void) +{ + return 0x00408958U; +} +static inline u32 gr_bes_crop_settings_num_active_ltcs_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_zcull_bytes_per_aliquot_per_gpu_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_header_bytes_per_gpc_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_subregion_header_bytes_per_gpc_v(void) +{ + return 0x000000c0U; +} +static inline u32 gr_zcull_subregion_qty_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel0_r(void) +{ + return 0x00504604U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel1_r(void) +{ + return 0x00504608U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control0_r(void) +{ + return 0x0050465cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control1_r(void) +{ + return 0x00504660U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control2_r(void) +{ + return 0x00504664U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control3_r(void) +{ + return 0x00504668U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control4_r(void) +{ + return 0x0050466cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control5_r(void) +{ + return 0x00504658U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_control_r(void) +{ + return 0x00504730U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_control_r(void) +{ + return 0x00504734U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_control_r(void) +{ + return 0x00504738U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_control_r(void) +{ + return 0x0050473cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter4_control_r(void) +{ + return 0x00504740U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter5_control_r(void) +{ + return 0x00504744U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter6_control_r(void) +{ + return 0x00504748U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter7_control_r(void) +{ + return 0x0050474cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_status_s1_r(void) +{ + return 0x00504678U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_status1_r(void) +{ + return 0x00504694U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_s0_r(void) +{ + return 0x005046f0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_s1_r(void) +{ + return 0x00504700U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_s0_r(void) +{ + return 0x005046f4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_s1_r(void) +{ + return 0x00504704U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_s0_r(void) +{ + return 0x005046f8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_s1_r(void) +{ + return 0x00504708U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_s0_r(void) +{ + return 0x005046fcU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_s1_r(void) +{ + return 0x0050470cU; +} +static inline u32 gr_fe_pwr_mode_r(void) +{ + return 0x00404170U; +} +static inline u32 gr_fe_pwr_mode_mode_auto_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_pwr_mode_mode_force_on_f(void) +{ + return 0x2U; +} +static inline u32 gr_fe_pwr_mode_req_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_fe_pwr_mode_req_send_f(void) +{ + return 0x10U; +} +static inline u32 gr_fe_pwr_mode_req_done_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_r(void) +{ + return 0x00418880U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_vm_pg_size_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_use_pdb_big_page_size_m(void) +{ + return 0x1U << 11U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_use_full_comp_tag_line_m(void) +{ + return 0x1U << 12U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_vol_fault_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_comp_fault_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_miss_gran_m(void) +{ + return 0x3U << 3U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_cache_mode_m(void) +{ + return 0x3U << 5U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_aperture_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_vol_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_disable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_pri_mmu_pm_unit_mask_r(void) +{ + return 0x00418890U; +} +static inline u32 gr_gpcs_pri_mmu_pm_req_mask_r(void) +{ + return 0x00418894U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_r(void) +{ + return 0x004188b0U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_m(void) +{ + return 0x1U << 16U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_pri_mmu_debug_wr_r(void) +{ + return 0x004188b4U; +} +static inline u32 gr_gpcs_pri_mmu_debug_rd_r(void) +{ + return 0x004188b8U; +} +static inline u32 gr_gpcs_mmu_num_active_ltcs_r(void) +{ + return 0x004188acU; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_r(void) +{ + return 0x00419e10U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_debugger_mode_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_enable_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_ltc_gm20b.h b/include/nvgpu/hw/gm20b/hw_ltc_gm20b.h new file mode 100644 index 0000000..2c3ebb4 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_ltc_gm20b.h @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ltc_gm20b_h_ +#define _hw_ltc_gm20b_h_ + +static inline u32 ltc_pltcg_base_v(void) +{ + return 0x00140000U; +} +static inline u32 ltc_pltcg_extent_v(void) +{ + return 0x0017ffffU; +} +static inline u32 ltc_ltc0_ltss_v(void) +{ + return 0x00140200U; +} +static inline u32 ltc_ltc0_lts0_v(void) +{ + return 0x00140400U; +} +static inline u32 ltc_ltcs_ltss_v(void) +{ + return 0x0017e200U; +} +static inline u32 ltc_ltcs_lts0_cbc_ctrl1_r(void) +{ + return 0x0014046cU; +} +static inline u32 ltc_ltc0_lts0_dstg_cfg0_r(void) +{ + return 0x00140518U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_r(void) +{ + return 0x0017e318U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_vdc_4to2_disable_m(void) +{ + return 0x1U << 15U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_r(void) +{ + return 0x00140494U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_ways_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_v(u32 r) +{ + return (r >> 16U) & 0x3U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_all_v(void) +{ + return 0x00000000U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_half_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_quarter_v(void) +{ + return 0x00000002U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void) +{ + return 0x0017e26cU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(void) +{ + return 0x2U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_f(void) +{ + return 0x4U; +} +static inline u32 ltc_ltc0_lts0_cbc_ctrl1_r(void) +{ + return 0x0014046cU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_r(void) +{ + return 0x0017e270U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_r(void) +{ + return 0x0017e274U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_init_v(void) +{ + return 0x0001ffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_r(void) +{ + return 0x0017e278U; +} +static inline u32 ltc_ltcs_ltss_cbc_base_alignment_shift_v(void) +{ + return 0x0000000bU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_address_v(u32 r) +{ + return (r >> 0U) & 0x3ffffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_r(void) +{ + return 0x0017e27cU; +} +static inline u32 ltc_ltcs_misc_ltc_num_active_ltcs_r(void) +{ + return 0x0017e000U; +} +static inline u32 ltc_ltcs_ltss_cbc_param_r(void) +{ + return 0x0017e280U; +} +static inline u32 ltc_ltcs_ltss_cbc_param_comptags_per_cache_line_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_cache_line_size_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_slices_per_ltc_v(u32 r) +{ + return (r >> 28U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_r(void) +{ + return 0x0017e2acU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_max_ways_evict_last_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_r(void) +{ + return 0x0017e338U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_address_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value_r(u32 i) +{ + return 0x0017e33cU + i*4U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_r(void) +{ + return 0x0017e34cU; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_s(void) +{ + return 32U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_r(void) +{ + return 0x0017e2b0U; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_l2_bypass_mode_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_r(void) +{ + return 0x0017e214U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_r(void) +{ + return 0x00140214U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_r(void) +{ + return 0x00142214U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_intr_r(void) +{ + return 0x0017e20cU; +} +static inline u32 ltc_ltcs_ltss_intr_en_evicted_cb_m(void) +{ + return 0x1U << 20U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_access_m(void) +{ + return 0x1U << 30U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_m(void) +{ + return 0x1U << 21U; +} +static inline u32 ltc_ltc0_lts0_intr_r(void) +{ + return 0x0014040cU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_r(void) +{ + return 0x0017e2a0U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_r(void) +{ + return 0x0017e2a4U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_f(void) +{ + return 0x10000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_r(void) +{ + return 0x001402a0U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_r(void) +{ + return 0x001402a4U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_r(void) +{ + return 0x001422a0U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_r(void) +{ + return 0x001422a4U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_mc_gm20b.h b/include/nvgpu/hw/gm20b/hw_mc_gm20b.h new file mode 100644 index 0000000..0264803 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_mc_gm20b.h @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_mc_gm20b_h_ +#define _hw_mc_gm20b_h_ + +static inline u32 mc_boot_0_r(void) +{ + return 0x00000000U; +} +static inline u32 mc_boot_0_architecture_v(u32 r) +{ + return (r >> 24U) & 0x1fU; +} +static inline u32 mc_boot_0_implementation_v(u32 r) +{ + return (r >> 20U) & 0xfU; +} +static inline u32 mc_boot_0_major_revision_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 mc_boot_0_minor_revision_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 mc_intr_r(u32 i) +{ + return 0x00000100U + i*4U; +} +static inline u32 mc_intr_pfifo_pending_f(void) +{ + return 0x100U; +} +static inline u32 mc_intr_pmu_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_ltc_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 mc_intr_priv_ring_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 mc_intr_pbus_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_intr_mask_0_r(void) +{ + return 0x00000640U; +} +static inline u32 mc_intr_mask_0_pmu_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_en_0_r(void) +{ + return 0x00000140U; +} +static inline u32 mc_intr_en_0_inta_disabled_f(void) +{ + return 0x0U; +} +static inline u32 mc_intr_en_0_inta_hardware_f(void) +{ + return 0x1U; +} +static inline u32 mc_intr_mask_1_r(void) +{ + return 0x00000644U; +} +static inline u32 mc_intr_mask_1_pmu_s(void) +{ + return 1U; +} +static inline u32 mc_intr_mask_1_pmu_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 mc_intr_mask_1_pmu_m(void) +{ + return 0x1U << 24U; +} +static inline u32 mc_intr_mask_1_pmu_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 mc_intr_mask_1_pmu_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_en_1_r(void) +{ + return 0x00000144U; +} +static inline u32 mc_intr_en_1_inta_disabled_f(void) +{ + return 0x0U; +} +static inline u32 mc_intr_en_1_inta_hardware_f(void) +{ + return 0x1U; +} +static inline u32 mc_enable_r(void) +{ + return 0x00000200U; +} +static inline u32 mc_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_enable_l2_enabled_f(void) +{ + return 0x8U; +} +static inline u32 mc_enable_pmedia_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pmedia_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 mc_enable_pmedia_m(void) +{ + return 0x1U << 4U; +} +static inline u32 mc_enable_pmedia_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 mc_enable_priv_ring_enabled_f(void) +{ + return 0x20U; +} +static inline u32 mc_enable_ce0_m(void) +{ + return 0x1U << 6U; +} +static inline u32 mc_enable_pfifo_enabled_f(void) +{ + return 0x100U; +} +static inline u32 mc_enable_pgraph_enabled_f(void) +{ + return 0x1000U; +} +static inline u32 mc_enable_pwr_v(u32 r) +{ + return (r >> 13U) & 0x1U; +} +static inline u32 mc_enable_pwr_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 mc_enable_pwr_enabled_f(void) +{ + return 0x2000U; +} +static inline u32 mc_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_enable_ce2_m(void) +{ + return 0x1U << 21U; +} +static inline u32 mc_enable_ce2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 mc_enable_blg_enabled_f(void) +{ + return 0x8000000U; +} +static inline u32 mc_enable_perfmon_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +static inline u32 mc_intr_ltc_r(void) +{ + return 0x0000017cU; +} +static inline u32 mc_enable_pb_r(void) +{ + return 0x00000204U; +} +static inline u32 mc_enable_pb_0_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pb_0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 mc_enable_pb_0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 mc_enable_pb_0_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 mc_enable_pb_0_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 mc_enable_pb_sel_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 mc_elpg_enable_r(void) +{ + return 0x0000020cU; +} +static inline u32 mc_elpg_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_elpg_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_elpg_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_pbdma_gm20b.h b/include/nvgpu/hw/gm20b/hw_pbdma_gm20b.h new file mode 100644 index 0000000..10ed9ec --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_pbdma_gm20b.h @@ -0,0 +1,579 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pbdma_gm20b_h_ +#define _hw_pbdma_gm20b_h_ + +static inline u32 pbdma_gp_entry1_r(void) +{ + return 0x10000004U; +} +static inline u32 pbdma_gp_entry1_get_hi_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pbdma_gp_entry1_length_f(u32 v) +{ + return (v & 0x1fffffU) << 10U; +} +static inline u32 pbdma_gp_entry1_length_v(u32 r) +{ + return (r >> 10U) & 0x1fffffU; +} +static inline u32 pbdma_gp_base_r(u32 i) +{ + return 0x00040048U + i*8192U; +} +static inline u32 pbdma_gp_base__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 pbdma_gp_base_offset_f(u32 v) +{ + return (v & 0x1fffffffU) << 3U; +} +static inline u32 pbdma_gp_base_rsvd_s(void) +{ + return 3U; +} +static inline u32 pbdma_gp_base_hi_r(u32 i) +{ + return 0x0004004cU + i*8192U; +} +static inline u32 pbdma_gp_base_hi_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_gp_base_hi_limit2_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 pbdma_gp_fetch_r(u32 i) +{ + return 0x00040050U + i*8192U; +} +static inline u32 pbdma_gp_get_r(u32 i) +{ + return 0x00040014U + i*8192U; +} +static inline u32 pbdma_gp_put_r(u32 i) +{ + return 0x00040000U + i*8192U; +} +static inline u32 pbdma_pb_fetch_r(u32 i) +{ + return 0x00040054U + i*8192U; +} +static inline u32 pbdma_pb_fetch_hi_r(u32 i) +{ + return 0x00040058U + i*8192U; +} +static inline u32 pbdma_get_r(u32 i) +{ + return 0x00040018U + i*8192U; +} +static inline u32 pbdma_get_hi_r(u32 i) +{ + return 0x0004001cU + i*8192U; +} +static inline u32 pbdma_put_r(u32 i) +{ + return 0x0004005cU + i*8192U; +} +static inline u32 pbdma_put_hi_r(u32 i) +{ + return 0x00040060U + i*8192U; +} +static inline u32 pbdma_formats_r(u32 i) +{ + return 0x0004009cU + i*8192U; +} +static inline u32 pbdma_formats_gp_fermi0_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_formats_pb_fermi1_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_formats_mp_fermi0_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_r(u32 i) +{ + return 0x00040084U + i*8192U; +} +static inline u32 pbdma_pb_header_priv_user_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_method_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_subchannel_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_level_main_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_pb_header_type_inc_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_pb_header_type_non_inc_f(void) +{ + return 0x60000000U; +} +static inline u32 pbdma_hdr_shadow_r(u32 i) +{ + return 0x00040118U + i*8192U; +} +static inline u32 pbdma_gp_shadow_0_r(u32 i) +{ + return 0x00040110U + i*8192U; +} +static inline u32 pbdma_gp_shadow_1_r(u32 i) +{ + return 0x00040114U + i*8192U; +} +static inline u32 pbdma_subdevice_r(u32 i) +{ + return 0x00040094U + i*8192U; +} +static inline u32 pbdma_subdevice_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 pbdma_subdevice_status_active_f(void) +{ + return 0x10000000U; +} +static inline u32 pbdma_subdevice_channel_dma_enable_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_method0_r(u32 i) +{ + return 0x000400c0U + i*8192U; +} +static inline u32 pbdma_method0_fifo_size_v(void) +{ + return 0x00000004U; +} +static inline u32 pbdma_method0_addr_f(u32 v) +{ + return (v & 0xfffU) << 2U; +} +static inline u32 pbdma_method0_addr_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 pbdma_method0_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 pbdma_method0_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_method0_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_method1_r(u32 i) +{ + return 0x000400c8U + i*8192U; +} +static inline u32 pbdma_method2_r(u32 i) +{ + return 0x000400d0U + i*8192U; +} +static inline u32 pbdma_method3_r(u32 i) +{ + return 0x000400d8U + i*8192U; +} +static inline u32 pbdma_data0_r(u32 i) +{ + return 0x000400c4U + i*8192U; +} +static inline u32 pbdma_target_r(u32 i) +{ + return 0x000400acU + i*8192U; +} +static inline u32 pbdma_target_engine_sw_f(void) +{ + return 0x1fU; +} +static inline u32 pbdma_acquire_r(u32 i) +{ + return 0x00040030U + i*8192U; +} +static inline u32 pbdma_acquire_retry_man_2_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_acquire_retry_exp_2_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_acquire_timeout_exp_f(u32 v) +{ + return (v & 0xfU) << 11U; +} +static inline u32 pbdma_acquire_timeout_exp_max_v(void) +{ + return 0x0000000fU; +} +static inline u32 pbdma_acquire_timeout_exp_max_f(void) +{ + return 0x7800U; +} +static inline u32 pbdma_acquire_timeout_man_f(u32 v) +{ + return (v & 0xffffU) << 15U; +} +static inline u32 pbdma_acquire_timeout_man_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 pbdma_acquire_timeout_man_max_f(void) +{ + return 0x7fff8000U; +} +static inline u32 pbdma_acquire_timeout_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_acquire_timeout_en_disable_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_status_r(u32 i) +{ + return 0x00040100U + i*8192U; +} +static inline u32 pbdma_channel_r(u32 i) +{ + return 0x00040120U + i*8192U; +} +static inline u32 pbdma_signature_r(u32 i) +{ + return 0x00040010U + i*8192U; +} +static inline u32 pbdma_signature_hw_valid_f(void) +{ + return 0xfaceU; +} +static inline u32 pbdma_signature_sw_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_r(u32 i) +{ + return 0x00040008U + i*8192U; +} +static inline u32 pbdma_userd_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_userd_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 pbdma_userd_addr_f(u32 v) +{ + return (v & 0x7fffffU) << 9U; +} +static inline u32 pbdma_userd_hi_r(u32 i) +{ + return 0x0004000cU + i*8192U; +} +static inline u32 pbdma_userd_hi_addr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_hce_ctrl_r(u32 i) +{ + return 0x000400e4U + i*8192U; +} +static inline u32 pbdma_hce_ctrl_hce_priv_mode_yes_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_r(u32 i) +{ + return 0x00040108U + i*8192U; +} +static inline u32 pbdma_intr_0_memreq_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pbdma_intr_0_memreq_pending_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_intr_0_memack_timeout_pending_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_intr_0_memack_extra_pending_f(void) +{ + return 0x4U; +} +static inline u32 pbdma_intr_0_memdat_timeout_pending_f(void) +{ + return 0x8U; +} +static inline u32 pbdma_intr_0_memdat_extra_pending_f(void) +{ + return 0x10U; +} +static inline u32 pbdma_intr_0_memflush_pending_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_memop_pending_f(void) +{ + return 0x40U; +} +static inline u32 pbdma_intr_0_lbconnect_pending_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_intr_0_lbreq_pending_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_0_lback_timeout_pending_f(void) +{ + return 0x200U; +} +static inline u32 pbdma_intr_0_lback_extra_pending_f(void) +{ + return 0x400U; +} +static inline u32 pbdma_intr_0_lbdat_timeout_pending_f(void) +{ + return 0x800U; +} +static inline u32 pbdma_intr_0_lbdat_extra_pending_f(void) +{ + return 0x1000U; +} +static inline u32 pbdma_intr_0_gpfifo_pending_f(void) +{ + return 0x2000U; +} +static inline u32 pbdma_intr_0_gpptr_pending_f(void) +{ + return 0x4000U; +} +static inline u32 pbdma_intr_0_gpentry_pending_f(void) +{ + return 0x8000U; +} +static inline u32 pbdma_intr_0_gpcrc_pending_f(void) +{ + return 0x10000U; +} +static inline u32 pbdma_intr_0_pbptr_pending_f(void) +{ + return 0x20000U; +} +static inline u32 pbdma_intr_0_pbentry_pending_f(void) +{ + return 0x40000U; +} +static inline u32 pbdma_intr_0_pbcrc_pending_f(void) +{ + return 0x80000U; +} +static inline u32 pbdma_intr_0_xbarconnect_pending_f(void) +{ + return 0x100000U; +} +static inline u32 pbdma_intr_0_method_pending_f(void) +{ + return 0x200000U; +} +static inline u32 pbdma_intr_0_methodcrc_pending_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_intr_0_device_pending_f(void) +{ + return 0x800000U; +} +static inline u32 pbdma_intr_0_semaphore_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 pbdma_intr_0_acquire_pending_f(void) +{ + return 0x4000000U; +} +static inline u32 pbdma_intr_0_pri_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 pbdma_intr_0_no_ctxsw_seg_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_intr_0_pbseg_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 pbdma_intr_0_signature_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_intr_1_r(u32 i) +{ + return 0x00040148U + i*8192U; +} +static inline u32 pbdma_intr_en_0_r(u32 i) +{ + return 0x0004010cU + i*8192U; +} +static inline u32 pbdma_intr_en_0_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_en_1_r(u32 i) +{ + return 0x0004014cU + i*8192U; +} +static inline u32 pbdma_intr_stall_r(u32 i) +{ + return 0x0004013cU + i*8192U; +} +static inline u32 pbdma_intr_stall_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_stall_1_r(u32 i) +{ + return 0x00040140U + i*8192U; +} +static inline u32 pbdma_intr_stall_1_hce_illegal_op_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_udma_nop_r(void) +{ + return 0x00000008U; +} +static inline u32 pbdma_syncpointa_r(u32 i) +{ + return 0x000400a4U + i*8192U; +} +static inline u32 pbdma_syncpointa_payload_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pbdma_syncpointb_r(u32 i) +{ + return 0x000400a8U + i*8192U; +} +static inline u32 pbdma_syncpointb_op_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 pbdma_syncpointb_op_wait_v(void) +{ + return 0x00000000U; +} +static inline u32 pbdma_syncpointb_wait_switch_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pbdma_syncpointb_wait_switch_en_v(void) +{ + return 0x00000001U; +} +static inline u32 pbdma_syncpointb_syncpt_index_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 pbdma_runlist_timeslice_r(u32 i) +{ + return 0x000400f8U + i*8192U; +} +static inline u32 pbdma_runlist_timeslice_timeout_128_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_runlist_timeslice_timescale_3_f(void) +{ + return 0x3000U; +} +static inline u32 pbdma_runlist_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_perf_gm20b.h b/include/nvgpu/hw/gm20b/hw_perf_gm20b.h new file mode 100644 index 0000000..a94ba30 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_perf_gm20b.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2015-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_perf_gm20b_h_ +#define _hw_perf_gm20b_h_ + +static inline u32 perf_pmmsys_base_v(void) +{ + return 0x001b0000U; +} +static inline u32 perf_pmmsys_extent_v(void) +{ + return 0x001b0fffU; +} +static inline u32 perf_pmasys_control_r(void) +{ + return 0x001b4000U; +} +static inline u32 perf_pmasys_control_membuf_status_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_f(void) +{ + return 0x10U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_f(void) +{ + return 0x20U; +} +static inline u32 perf_pmasys_mem_block_r(void) +{ + return 0x001b4070U; +} +static inline u32 perf_pmasys_mem_block_base_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 perf_pmasys_mem_block_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 perf_pmasys_mem_block_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 perf_pmasys_mem_block_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 perf_pmasys_mem_block_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 perf_pmasys_mem_block_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_mem_block_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_outbase_r(void) +{ + return 0x001b4074U; +} +static inline u32 perf_pmasys_outbase_ptr_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_outbaseupper_r(void) +{ + return 0x001b4078U; +} +static inline u32 perf_pmasys_outbaseupper_ptr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 perf_pmasys_outsize_r(void) +{ + return 0x001b407cU; +} +static inline u32 perf_pmasys_outsize_numbytes_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_mem_bytes_r(void) +{ + return 0x001b4084U; +} +static inline u32 perf_pmasys_mem_bytes_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_mem_bump_r(void) +{ + return 0x001b4088U; +} +static inline u32 perf_pmasys_mem_bump_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_enginestatus_r(void) +{ + return 0x001b40a4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_f(void) +{ + return 0x10U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_pram_gm20b.h b/include/nvgpu/hw/gm20b/hw_pram_gm20b.h new file mode 100644 index 0000000..47a6bfa --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_pram_gm20b.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pram_gm20b_h_ +#define _hw_pram_gm20b_h_ + +static inline u32 pram_data032_r(u32 i) +{ + return 0x00700000U + i*4U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_pri_ringmaster_gm20b.h b/include/nvgpu/hw/gm20b/hw_pri_ringmaster_gm20b.h new file mode 100644 index 0000000..c6f08ed --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_pri_ringmaster_gm20b.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringmaster_gm20b_h_ +#define _hw_pri_ringmaster_gm20b_h_ + +static inline u32 pri_ringmaster_command_r(void) +{ + return 0x0012004cU; +} +static inline u32 pri_ringmaster_command_cmd_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 pri_ringmaster_command_cmd_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 pri_ringmaster_command_cmd_no_cmd_v(void) +{ + return 0x00000000U; +} +static inline u32 pri_ringmaster_command_cmd_start_ring_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_command_cmd_ack_interrupt_f(void) +{ + return 0x2U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_f(void) +{ + return 0x3U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_bc_grp_all_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_command_data_r(void) +{ + return 0x00120048U; +} +static inline u32 pri_ringmaster_start_results_r(void) +{ + return 0x00120050U; +} +static inline u32 pri_ringmaster_start_results_connectivity_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_start_results_connectivity_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 pri_ringmaster_intr_status0_r(void) +{ + return 0x00120058U; +} +static inline u32 pri_ringmaster_intr_status0_ring_start_conn_fault_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_disconnect_fault_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_overflow_fault_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_gbl_write_error_sys_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status1_r(void) +{ + return 0x0012005cU; +} +static inline u32 pri_ringmaster_global_ctl_r(void) +{ + return 0x00120060U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_asserted_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_deasserted_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_enum_fbp_r(void) +{ + return 0x00120074U; +} +static inline u32 pri_ringmaster_enum_fbp_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_gpc_r(void) +{ + return 0x00120078U; +} +static inline u32 pri_ringmaster_enum_gpc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_ltc_r(void) +{ + return 0x0012006cU; +} +static inline u32 pri_ringmaster_enum_ltc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_pri_ringstation_gpc_gm20b.h b/include/nvgpu/hw/gm20b/hw_pri_ringstation_gpc_gm20b.h new file mode 100644 index 0000000..8d1ffb2 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_pri_ringstation_gpc_gm20b.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_gpc_gm20b_h_ +#define _hw_pri_ringstation_gpc_gm20b_h_ + +static inline u32 pri_ringstation_gpc_master_config_r(u32 i) +{ + return 0x00128300U + i*4U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_adr_r(void) +{ + return 0x00128120U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_wrdat_r(void) +{ + return 0x00128124U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_info_r(void) +{ + return 0x00128128U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_code_r(void) +{ + return 0x0012812cU; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_pri_ringstation_sys_gm20b.h b/include/nvgpu/hw/gm20b/hw_pri_ringstation_sys_gm20b.h new file mode 100644 index 0000000..ac1d245 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_pri_ringstation_sys_gm20b.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_sys_gm20b_h_ +#define _hw_pri_ringstation_sys_gm20b_h_ + +static inline u32 pri_ringstation_sys_master_config_r(u32 i) +{ + return 0x00122300U + i*4U; +} +static inline u32 pri_ringstation_sys_decode_config_r(void) +{ + return 0x00122204U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_m(void) +{ + return 0x7U << 0U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_drop_on_ring_not_started_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringstation_sys_priv_error_adr_r(void) +{ + return 0x00122120U; +} +static inline u32 pri_ringstation_sys_priv_error_wrdat_r(void) +{ + return 0x00122124U; +} +static inline u32 pri_ringstation_sys_priv_error_info_r(void) +{ + return 0x00122128U; +} +static inline u32 pri_ringstation_sys_priv_error_code_r(void) +{ + return 0x0012212cU; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_proj_gm20b.h b/include/nvgpu/hw/gm20b/hw_proj_gm20b.h new file mode 100644 index 0000000..8129ea6 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_proj_gm20b.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_proj_gm20b_h_ +#define _hw_proj_gm20b_h_ + +static inline u32 proj_gpc_base_v(void) +{ + return 0x00500000U; +} +static inline u32 proj_gpc_shared_base_v(void) +{ + return 0x00418000U; +} +static inline u32 proj_gpc_stride_v(void) +{ + return 0x00008000U; +} +static inline u32 proj_gpc_priv_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_ltc_stride_v(void) +{ + return 0x00002000U; +} +static inline u32 proj_lts_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_fbpa_stride_v(void) +{ + return 0x00001000U; +} +static inline u32 proj_ppc_in_gpc_base_v(void) +{ + return 0x00003000U; +} +static inline u32 proj_ppc_in_gpc_shared_base_v(void) +{ + return 0x00003e00U; +} +static inline u32 proj_ppc_in_gpc_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_rop_base_v(void) +{ + return 0x00410000U; +} +static inline u32 proj_rop_shared_base_v(void) +{ + return 0x00408800U; +} +static inline u32 proj_rop_stride_v(void) +{ + return 0x00000400U; +} +static inline u32 proj_tpc_in_gpc_base_v(void) +{ + return 0x00004000U; +} +static inline u32 proj_tpc_in_gpc_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_tpc_in_gpc_shared_base_v(void) +{ + return 0x00001800U; +} +static inline u32 proj_host_num_engines_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_host_num_pbdma_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_tpc_per_gpc_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_scal_litter_num_sm_per_tpc_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_fbps_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_fbpas_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_gpcs_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_pes_per_gpc_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_tpcs_per_pes_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_scal_litter_num_zcull_banks_v(void) +{ + return 0x00000004U; +} +static inline u32 proj_scal_max_gpcs_v(void) +{ + return 0x00000020U; +} +static inline u32 proj_scal_max_tpc_per_gpc_v(void) +{ + return 0x00000008U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_pwr_gm20b.h b/include/nvgpu/hw/gm20b/hw_pwr_gm20b.h new file mode 100644 index 0000000..a7c409d --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_pwr_gm20b.h @@ -0,0 +1,879 @@ +/* + * Copyright (c) 2014-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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pwr_gm20b_h_ +#define _hw_pwr_gm20b_h_ + +static inline u32 pwr_falcon_irqsset_r(void) +{ + return 0x0010a000U; +} +static inline u32 pwr_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqsclr_r(void) +{ + return 0x0010a004U; +} +static inline u32 pwr_falcon_irqstat_r(void) +{ + return 0x0010a008U; +} +static inline u32 pwr_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 pwr_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 pwr_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqmode_r(void) +{ + return 0x0010a00cU; +} +static inline u32 pwr_falcon_irqmset_r(void) +{ + return 0x0010a010U; +} +static inline u32 pwr_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_r(void) +{ + return 0x0010a014U; +} +static inline u32 pwr_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqmask_r(void) +{ + return 0x0010a018U; +} +static inline u32 pwr_falcon_irqdest_r(void) +{ + return 0x0010a01cU; +} +static inline u32 pwr_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 pwr_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 pwr_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 pwr_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 pwr_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 pwr_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 pwr_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 pwr_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 pwr_falcon_curctx_r(void) +{ + return 0x0010a050U; +} +static inline u32 pwr_falcon_nxtctx_r(void) +{ + return 0x0010a054U; +} +static inline u32 pwr_falcon_mailbox0_r(void) +{ + return 0x0010a040U; +} +static inline u32 pwr_falcon_mailbox1_r(void) +{ + return 0x0010a044U; +} +static inline u32 pwr_falcon_itfen_r(void) +{ + return 0x0010a048U; +} +static inline u32 pwr_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 pwr_falcon_idlestate_r(void) +{ + return 0x0010a04cU; +} +static inline u32 pwr_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 pwr_falcon_os_r(void) +{ + return 0x0010a080U; +} +static inline u32 pwr_falcon_engctl_r(void) +{ + return 0x0010a0a4U; +} +static inline u32 pwr_falcon_cpuctl_r(void) +{ + return 0x0010a100U; +} +static inline u32 pwr_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 pwr_falcon_cpuctl_alias_r(void) +{ + return 0x0010a130U; +} +static inline u32 pwr_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_pmu_scpctl_stat_r(void) +{ + return 0x0010ac08U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_m(void) +{ + return 0x1U << 20U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 pwr_falcon_imemc_r(u32 i) +{ + return 0x0010a180U + i*16U; +} +static inline u32 pwr_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_imemd_r(u32 i) +{ + return 0x0010a184U + i*16U; +} +static inline u32 pwr_falcon_imemt_r(u32 i) +{ + return 0x0010a188U + i*16U; +} +static inline u32 pwr_falcon_sctl_r(void) +{ + return 0x0010a240U; +} +static inline u32 pwr_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 pwr_falcon_bootvec_r(void) +{ + return 0x0010a104U; +} +static inline u32 pwr_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_falcon_dmactl_r(void) +{ + return 0x0010a10cU; +} +static inline u32 pwr_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 pwr_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_falcon_hwcfg_r(void) +{ + return 0x0010a108U; +} +static inline u32 pwr_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 pwr_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 pwr_falcon_dmatrfbase_r(void) +{ + return 0x0010a110U; +} +static inline u32 pwr_falcon_dmatrfmoffs_r(void) +{ + return 0x0010a114U; +} +static inline u32 pwr_falcon_dmatrfcmd_r(void) +{ + return 0x0010a118U; +} +static inline u32 pwr_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 pwr_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 pwr_falcon_dmatrffboffs_r(void) +{ + return 0x0010a11cU; +} +static inline u32 pwr_falcon_exterraddr_r(void) +{ + return 0x0010a168U; +} +static inline u32 pwr_falcon_exterrstat_r(void) +{ + return 0x0010a16cU; +} +static inline u32 pwr_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 pwr_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 pwr_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_r(void) +{ + return 0x0010a200U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 pwr_pmu_falcon_icd_rdata_r(void) +{ + return 0x0010a20cU; +} +static inline u32 pwr_falcon_dmemc_r(u32 i) +{ + return 0x0010a1c0U + i*8U; +} +static inline u32 pwr_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 pwr_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 pwr_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 pwr_falcon_dmemd_r(u32 i) +{ + return 0x0010a1c4U + i*8U; +} +static inline u32 pwr_pmu_new_instblk_r(void) +{ + return 0x0010a480U; +} +static inline u32 pwr_pmu_new_instblk_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 pwr_pmu_new_instblk_target_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 pwr_pmu_new_instblk_valid_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 pwr_pmu_mutex_id_r(void) +{ + return 0x0010a488U; +} +static inline u32 pwr_pmu_mutex_id_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_id_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_value_not_avail_v(void) +{ + return 0x000000ffU; +} +static inline u32 pwr_pmu_mutex_id_release_r(void) +{ + return 0x0010a48cU; +} +static inline u32 pwr_pmu_mutex_id_release_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_m(void) +{ + return 0xffU << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_mutex_r(u32 i) +{ + return 0x0010a580U + i*4U; +} +static inline u32 pwr_pmu_mutex__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 pwr_pmu_mutex_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_value_initial_lock_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_queue_head_r(u32 i) +{ + return 0x0010a4a0U + i*4U; +} +static inline u32 pwr_pmu_queue_head__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_queue_head_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_head_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_queue_tail_r(u32 i) +{ + return 0x0010a4b0U + i*4U; +} +static inline u32 pwr_pmu_queue_tail__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_queue_tail_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_tail_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_head_r(void) +{ + return 0x0010a4c8U; +} +static inline u32 pwr_pmu_msgq_head_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_head_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_tail_r(void) +{ + return 0x0010a4ccU; +} +static inline u32 pwr_pmu_msgq_tail_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_tail_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_idle_mask_r(u32 i) +{ + return 0x0010a504U + i*16U; +} +static inline u32 pwr_pmu_idle_mask_gr_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pwr_pmu_idle_mask_ce_2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 pwr_pmu_idle_mask_1_r(u32 i) +{ + return 0x0010aa34U + i*8U; +} +static inline u32 pwr_pmu_idle_count_r(u32 i) +{ + return 0x0010a508U + i*16U; +} +static inline u32 pwr_pmu_idle_count_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_count_value_v(u32 r) +{ + return (r >> 0U) & 0x7fffffffU; +} +static inline u32 pwr_pmu_idle_count_reset_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 pwr_pmu_idle_ctrl_r(u32 i) +{ + return 0x0010a50cU + i*16U; +} +static inline u32 pwr_pmu_idle_ctrl_value_m(void) +{ + return 0x3U << 0U; +} +static inline u32 pwr_pmu_idle_ctrl_value_busy_f(void) +{ + return 0x2U; +} +static inline u32 pwr_pmu_idle_ctrl_value_always_f(void) +{ + return 0x3U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_disabled_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_idle_threshold_r(u32 i) +{ + return 0x0010a8a0U + i*4U; +} +static inline u32 pwr_pmu_idle_threshold_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_intr_r(void) +{ + return 0x0010a9e8U; +} +static inline u32 pwr_pmu_idle_intr_en_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_en_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_idle_intr_en_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_r(void) +{ + return 0x0010a9ecU; +} +static inline u32 pwr_pmu_idle_intr_status_intr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_m(void) +{ + return 0x1U << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_mask_supp_r(u32 i) +{ + return 0x0010a9f0U + i*8U; +} +static inline u32 pwr_pmu_idle_mask_1_supp_r(u32 i) +{ + return 0x0010a9f4U + i*8U; +} +static inline u32 pwr_pmu_idle_ctrl_supp_r(u32 i) +{ + return 0x0010aa30U + i*8U; +} +static inline u32 pwr_pmu_debug_r(u32 i) +{ + return 0x0010a5c0U + i*4U; +} +static inline u32 pwr_pmu_debug__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_mailbox_r(u32 i) +{ + return 0x0010a450U + i*4U; +} +static inline u32 pwr_pmu_mailbox__size_1_v(void) +{ + return 0x0000000cU; +} +static inline u32 pwr_pmu_bar0_addr_r(void) +{ + return 0x0010a7a0U; +} +static inline u32 pwr_pmu_bar0_data_r(void) +{ + return 0x0010a7a4U; +} +static inline u32 pwr_pmu_bar0_ctl_r(void) +{ + return 0x0010a7acU; +} +static inline u32 pwr_pmu_bar0_timeout_r(void) +{ + return 0x0010a7a8U; +} +static inline u32 pwr_pmu_bar0_fecs_error_r(void) +{ + return 0x0010a988U; +} +static inline u32 pwr_pmu_bar0_error_status_r(void) +{ + return 0x0010a7b0U; +} +static inline u32 pwr_pmu_pg_idlefilth_r(u32 i) +{ + return 0x0010a6c0U + i*4U; +} +static inline u32 pwr_pmu_pg_ppuidlefilth_r(u32 i) +{ + return 0x0010a6e8U + i*4U; +} +static inline u32 pwr_pmu_pg_idle_cnt_r(u32 i) +{ + return 0x0010a710U + i*4U; +} +static inline u32 pwr_pmu_pg_intren_r(u32 i) +{ + return 0x0010a760U + i*4U; +} +static inline u32 pwr_fbif_transcfg_r(u32 i) +{ + return 0x0010ae00U + i*4U; +} +static inline u32 pwr_fbif_transcfg_target_local_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_target_coherent_sysmem_f(void) +{ + return 0x1U; +} +static inline u32 pwr_fbif_transcfg_target_noncoherent_sysmem_f(void) +{ + return 0x2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_s(void) +{ + return 1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_virtual_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_mem_type_physical_f(void) +{ + return 0x4U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_ram_gm20b.h b/include/nvgpu/hw/gm20b/hw_ram_gm20b.h new file mode 100644 index 0000000..2414abf --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_ram_gm20b.h @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ram_gm20b_h_ +#define _hw_ram_gm20b_h_ + +static inline u32 ram_in_ramfc_s(void) +{ + return 4096U; +} +static inline u32 ram_in_ramfc_w(void) +{ + return 0U; +} +static inline u32 ram_in_page_dir_base_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ram_in_page_dir_base_target_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 ram_in_page_dir_base_vol_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_big_page_size_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 ram_in_big_page_size_m(void) +{ + return 0x1U << 11U; +} +static inline u32 ram_in_big_page_size_w(void) +{ + return 128U; +} +static inline u32 ram_in_big_page_size_128kb_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_big_page_size_64kb_f(void) +{ + return 0x800U; +} +static inline u32 ram_in_page_dir_base_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_page_dir_base_lo_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_page_dir_base_hi_w(void) +{ + return 129U; +} +static inline u32 ram_in_adr_limit_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_adr_limit_lo_w(void) +{ + return 130U; +} +static inline u32 ram_in_adr_limit_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_adr_limit_hi_w(void) +{ + return 131U; +} +static inline u32 ram_in_engine_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_cs_wfi_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_engine_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_engine_cs_fg_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_engine_cs_fg_f(void) +{ + return 0x8U; +} +static inline u32 ram_in_gr_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_gr_wfi_target_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_mode_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_mode_physical_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_gr_wfi_mode_physical_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_gr_wfi_mode_virtual_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_gr_wfi_mode_virtual_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_gr_wfi_ptr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_gr_wfi_ptr_lo_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_ptr_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_gr_wfi_ptr_hi_w(void) +{ + return 133U; +} +static inline u32 ram_in_base_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 ram_in_alloc_size_v(void) +{ + return 0x00001000U; +} +static inline u32 ram_fc_size_val_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_fc_gp_put_w(void) +{ + return 0U; +} +static inline u32 ram_fc_userd_w(void) +{ + return 2U; +} +static inline u32 ram_fc_userd_hi_w(void) +{ + return 3U; +} +static inline u32 ram_fc_signature_w(void) +{ + return 4U; +} +static inline u32 ram_fc_gp_get_w(void) +{ + return 5U; +} +static inline u32 ram_fc_pb_get_w(void) +{ + return 6U; +} +static inline u32 ram_fc_pb_get_hi_w(void) +{ + return 7U; +} +static inline u32 ram_fc_pb_top_level_get_w(void) +{ + return 8U; +} +static inline u32 ram_fc_pb_top_level_get_hi_w(void) +{ + return 9U; +} +static inline u32 ram_fc_acquire_w(void) +{ + return 12U; +} +static inline u32 ram_fc_semaphorea_w(void) +{ + return 14U; +} +static inline u32 ram_fc_semaphoreb_w(void) +{ + return 15U; +} +static inline u32 ram_fc_semaphorec_w(void) +{ + return 16U; +} +static inline u32 ram_fc_semaphored_w(void) +{ + return 17U; +} +static inline u32 ram_fc_gp_base_w(void) +{ + return 18U; +} +static inline u32 ram_fc_gp_base_hi_w(void) +{ + return 19U; +} +static inline u32 ram_fc_gp_fetch_w(void) +{ + return 20U; +} +static inline u32 ram_fc_pb_fetch_w(void) +{ + return 21U; +} +static inline u32 ram_fc_pb_fetch_hi_w(void) +{ + return 22U; +} +static inline u32 ram_fc_pb_put_w(void) +{ + return 23U; +} +static inline u32 ram_fc_pb_put_hi_w(void) +{ + return 24U; +} +static inline u32 ram_fc_pb_header_w(void) +{ + return 33U; +} +static inline u32 ram_fc_pb_count_w(void) +{ + return 34U; +} +static inline u32 ram_fc_subdevice_w(void) +{ + return 37U; +} +static inline u32 ram_fc_formats_w(void) +{ + return 39U; +} +static inline u32 ram_fc_syncpointa_w(void) +{ + return 41U; +} +static inline u32 ram_fc_syncpointb_w(void) +{ + return 42U; +} +static inline u32 ram_fc_target_w(void) +{ + return 43U; +} +static inline u32 ram_fc_hce_ctrl_w(void) +{ + return 57U; +} +static inline u32 ram_fc_chid_w(void) +{ + return 58U; +} +static inline u32 ram_fc_chid_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_fc_chid_id_w(void) +{ + return 0U; +} +static inline u32 ram_fc_runlist_timeslice_w(void) +{ + return 62U; +} +static inline u32 ram_userd_base_shift_v(void) +{ + return 0x00000009U; +} +static inline u32 ram_userd_chan_size_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_userd_put_w(void) +{ + return 16U; +} +static inline u32 ram_userd_get_w(void) +{ + return 17U; +} +static inline u32 ram_userd_ref_w(void) +{ + return 18U; +} +static inline u32 ram_userd_put_hi_w(void) +{ + return 19U; +} +static inline u32 ram_userd_ref_threshold_w(void) +{ + return 20U; +} +static inline u32 ram_userd_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_userd_get_hi_w(void) +{ + return 24U; +} +static inline u32 ram_userd_gp_get_w(void) +{ + return 34U; +} +static inline u32 ram_userd_gp_put_w(void) +{ + return 35U; +} +static inline u32 ram_userd_gp_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_gp_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_rl_entry_size_v(void) +{ + return 0x00000008U; +} +static inline u32 ram_rl_entry_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_type_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 ram_rl_entry_type_chid_f(void) +{ + return 0x0U; +} +static inline u32 ram_rl_entry_type_tsg_f(void) +{ + return 0x2000U; +} +static inline u32 ram_rl_entry_timeslice_scale_f(u32 v) +{ + return (v & 0xfU) << 14U; +} +static inline u32 ram_rl_entry_timeslice_scale_3_f(void) +{ + return 0xc000U; +} +static inline u32 ram_rl_entry_timeslice_timeout_f(u32 v) +{ + return (v & 0xffU) << 18U; +} +static inline u32 ram_rl_entry_timeslice_timeout_128_f(void) +{ + return 0x2000000U; +} +static inline u32 ram_rl_entry_tsg_length_f(u32 v) +{ + return (v & 0x3fU) << 26U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_therm_gm20b.h b/include/nvgpu/hw/gm20b/hw_therm_gm20b.h new file mode 100644 index 0000000..fc1cd51 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_therm_gm20b.h @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_therm_gm20b_h_ +#define _hw_therm_gm20b_h_ + +static inline u32 therm_use_a_r(void) +{ + return 0x00020798U; +} +static inline u32 therm_use_a_ext_therm_0_enable_f(void) +{ + return 0x1U; +} +static inline u32 therm_use_a_ext_therm_1_enable_f(void) +{ + return 0x2U; +} +static inline u32 therm_use_a_ext_therm_2_enable_f(void) +{ + return 0x4U; +} +static inline u32 therm_evt_ext_therm_0_r(void) +{ + return 0x00020700U; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_init_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_1_r(void) +{ + return 0x00020704U; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_init_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_2_r(void) +{ + return 0x00020708U; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_init_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_weight_1_r(void) +{ + return 0x00020024U; +} +static inline u32 therm_config1_r(void) +{ + return 0x00020050U; +} +static inline u32 therm_config2_r(void) +{ + return 0x00020130U; +} +static inline u32 therm_config2_slowdown_factor_extended_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 therm_config2_grad_enable_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 therm_gate_ctrl_r(u32 i) +{ + return 0x00020200U + i*4U; +} +static inline u32 therm_gate_ctrl_eng_clk_m(void) +{ + return 0x3U << 0U; +} +static inline u32 therm_gate_ctrl_eng_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_eng_clk_auto_f(void) +{ + return 0x1U; +} +static inline u32 therm_gate_ctrl_eng_clk_stop_f(void) +{ + return 0x2U; +} +static inline u32 therm_gate_ctrl_blk_clk_m(void) +{ + return 0x3U << 2U; +} +static inline u32 therm_gate_ctrl_blk_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_blk_clk_auto_f(void) +{ + return 0x4U; +} +static inline u32 therm_gate_ctrl_eng_pwr_m(void) +{ + return 0x3U << 4U; +} +static inline u32 therm_gate_ctrl_eng_pwr_auto_f(void) +{ + return 0x10U; +} +static inline u32 therm_gate_ctrl_eng_pwr_off_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_gate_ctrl_eng_pwr_off_f(void) +{ + return 0x20U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_m(void) +{ + return 0x1fU << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_f(u32 v) +{ + return (v & 0x7U) << 13U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_m(void) +{ + return 0x7U << 13U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_m(void) +{ + return 0xfU << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_m(void) +{ + return 0xfU << 20U; +} +static inline u32 therm_fecs_idle_filter_r(void) +{ + return 0x00020288U; +} +static inline u32 therm_fecs_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_hubmmu_idle_filter_r(void) +{ + return 0x0002028cU; +} +static inline u32 therm_hubmmu_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_clk_slowdown_r(u32 i) +{ + return 0x00020160U + i*4U; +} +static inline u32 therm_clk_slowdown_idle_factor_f(u32 v) +{ + return (v & 0x3fU) << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_m(void) +{ + return 0x3fU << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_v(u32 r) +{ + return (r >> 16U) & 0x3fU; +} +static inline u32 therm_clk_slowdown_idle_factor_disabled_f(void) +{ + return 0x0U; +} +static inline u32 therm_grad_stepping_table_r(u32 i) +{ + return 0x000202c8U + i*4U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by1p5_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by2_f(void) +{ + return 0x2U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by4_f(void) +{ + return 0x6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f(void) +{ + return 0xeU; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_f(u32 v) +{ + return (v & 0x3fU) << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_m(void) +{ + return 0x3fU << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_f(u32 v) +{ + return (v & 0x3fU) << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_m(void) +{ + return 0x3fU << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_m(void) +{ + return 0x3fU << 24U; +} +static inline u32 therm_grad_stepping0_r(void) +{ + return 0x000202c0U; +} +static inline u32 therm_grad_stepping0_feature_s(void) +{ + return 1U; +} +static inline u32 therm_grad_stepping0_feature_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 therm_grad_stepping0_feature_m(void) +{ + return 0x1U << 0U; +} +static inline u32 therm_grad_stepping0_feature_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 therm_grad_stepping0_feature_enable_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping1_r(void) +{ + return 0x000202c4U; +} +static inline u32 therm_grad_stepping1_pdiv_duration_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 therm_clk_timing_r(u32 i) +{ + return 0x000203c0U + i*4U; +} +static inline u32 therm_clk_timing_grad_slowdown_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_m(void) +{ + return 0x1U << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_enabled_f(void) +{ + return 0x10000U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_timer_gm20b.h b/include/nvgpu/hw/gm20b/hw_timer_gm20b.h new file mode 100644 index 0000000..f409367 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_timer_gm20b.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_timer_gm20b_h_ +#define _hw_timer_gm20b_h_ + +static inline u32 timer_pri_timeout_r(void) +{ + return 0x00009080U; +} +static inline u32 timer_pri_timeout_period_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 timer_pri_timeout_period_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 timer_pri_timeout_period_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 timer_pri_timeout_en_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 timer_pri_timeout_en_m(void) +{ + return 0x1U << 31U; +} +static inline u32 timer_pri_timeout_en_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_en_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 timer_pri_timeout_en_en_disabled_f(void) +{ + return 0x0U; +} +static inline u32 timer_pri_timeout_save_0_r(void) +{ + return 0x00009084U; +} +static inline u32 timer_pri_timeout_save_0_fecs_tgt_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_save_0_addr_v(u32 r) +{ + return (r >> 2U) & 0x3fffffU; +} +static inline u32 timer_pri_timeout_save_0_write_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 timer_pri_timeout_save_1_r(void) +{ + return 0x00009088U; +} +static inline u32 timer_pri_timeout_fecs_errcode_r(void) +{ + return 0x0000908cU; +} +static inline u32 timer_time_0_r(void) +{ + return 0x00009400U; +} +static inline u32 timer_time_1_r(void) +{ + return 0x00009410U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_top_gm20b.h b/include/nvgpu/hw/gm20b/hw_top_gm20b.h new file mode 100644 index 0000000..6d48839 --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_top_gm20b.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_top_gm20b_h_ +#define _hw_top_gm20b_h_ + +static inline u32 top_num_gpcs_r(void) +{ + return 0x00022430U; +} +static inline u32 top_num_gpcs_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_tpc_per_gpc_r(void) +{ + return 0x00022434U; +} +static inline u32 top_tpc_per_gpc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_fbps_r(void) +{ + return 0x00022438U; +} +static inline u32 top_num_fbps_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_ltc_per_fbp_r(void) +{ + return 0x00022450U; +} +static inline u32 top_ltc_per_fbp_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_slices_per_ltc_r(void) +{ + return 0x0002245cU; +} +static inline u32 top_slices_per_ltc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_ltcs_r(void) +{ + return 0x00022454U; +} +static inline u32 top_device_info_r(u32 i) +{ + return 0x00022700U + i*4U; +} +static inline u32 top_device_info__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 top_device_info_chain_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 top_device_info_chain_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_engine_enum_v(u32 r) +{ + return (r >> 26U) & 0xfU; +} +static inline u32 top_device_info_runlist_enum_v(u32 r) +{ + return (r >> 21U) & 0xfU; +} +static inline u32 top_device_info_intr_enum_v(u32 r) +{ + return (r >> 15U) & 0x1fU; +} +static inline u32 top_device_info_reset_enum_v(u32 r) +{ + return (r >> 9U) & 0x1fU; +} +static inline u32 top_device_info_type_enum_v(u32 r) +{ + return (r >> 2U) & 0x1fffffffU; +} +static inline u32 top_device_info_type_enum_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_type_enum_graphics_f(void) +{ + return 0x0U; +} +static inline u32 top_device_info_type_enum_copy0_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_type_enum_copy0_f(void) +{ + return 0x4U; +} +static inline u32 top_device_info_type_enum_copy1_v(void) +{ + return 0x00000002U; +} +static inline u32 top_device_info_type_enum_copy1_f(void) +{ + return 0x8U; +} +static inline u32 top_device_info_type_enum_copy2_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_type_enum_copy2_f(void) +{ + return 0xcU; +} +static inline u32 top_device_info_engine_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 top_device_info_runlist_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 top_device_info_intr_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 top_device_info_reset_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_entry_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 top_device_info_entry_not_valid_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_entry_enum_v(void) +{ + return 0x00000002U; +} +static inline u32 top_device_info_entry_engine_type_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_entry_data_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_data_type_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 top_device_info_data_type_enum2_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_data_pri_base_v(u32 r) +{ + return (r >> 12U) & 0x7ffU; +} +static inline u32 top_device_info_data_pri_base_align_v(void) +{ + return 0x0000000cU; +} +static inline u32 top_device_info_data_fault_id_enum_v(u32 r) +{ + return (r >> 3U) & 0x1fU; +} +static inline u32 top_device_info_data_fault_id_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_data_fault_id_valid_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gm20b/hw_trim_gm20b.h b/include/nvgpu/hw/gm20b/hw_trim_gm20b.h new file mode 100644 index 0000000..8f0a77a --- /dev/null +++ b/include/nvgpu/hw/gm20b/hw_trim_gm20b.h @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_trim_gm20b_h_ +#define _hw_trim_gm20b_h_ + +static inline u32 trim_sys_gpcpll_cfg_r(void) +{ + return 0x00137000U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_m(void) +{ + return 0x1U << 0U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_no_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpcpll_cfg_enable_yes_f(void) +{ + return 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_iddq_m(void) +{ + return 0x1U << 1U; +} +static inline u32 trim_sys_gpcpll_cfg_iddq_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_iddq_power_on_v(void) +{ + return 0x00000000U; +} +static inline u32 trim_sys_gpcpll_cfg_sync_mode_m(void) +{ + return 0x1U << 2U; +} +static inline u32 trim_sys_gpcpll_cfg_sync_mode_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_sync_mode_enable_f(void) +{ + return 0x4U; +} +static inline u32 trim_sys_gpcpll_cfg_sync_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpcpll_cfg_enb_lckdet_m(void) +{ + return 0x1U << 4U; +} +static inline u32 trim_sys_gpcpll_cfg_enb_lckdet_power_on_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpcpll_cfg_enb_lckdet_power_off_f(void) +{ + return 0x10U; +} +static inline u32 trim_sys_gpcpll_cfg_pll_lock_v(u32 r) +{ + return (r >> 17U) & 0x1U; +} +static inline u32 trim_sys_gpcpll_cfg_pll_lock_true_f(void) +{ + return 0x20000U; +} +static inline u32 trim_sys_gpcpll_coeff_r(void) +{ + return 0x00137004U; +} +static inline u32 trim_sys_gpcpll_coeff_mdiv_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 trim_sys_gpcpll_coeff_mdiv_m(void) +{ + return 0xffU << 0U; +} +static inline u32 trim_sys_gpcpll_coeff_mdiv_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 trim_sys_gpcpll_coeff_ndiv_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 trim_sys_gpcpll_coeff_ndiv_m(void) +{ + return 0xffU << 8U; +} +static inline u32 trim_sys_gpcpll_coeff_ndiv_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 trim_sys_gpcpll_coeff_pldiv_f(u32 v) +{ + return (v & 0x3fU) << 16U; +} +static inline u32 trim_sys_gpcpll_coeff_pldiv_m(void) +{ + return 0x3fU << 16U; +} +static inline u32 trim_sys_gpcpll_coeff_pldiv_v(u32 r) +{ + return (r >> 16U) & 0x3fU; +} +static inline u32 trim_sys_sel_vco_r(void) +{ + return 0x00137100U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_m(void) +{ + return 0x1U << 0U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_init_v(void) +{ + return 0x00000000U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_init_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_bypass_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_sel_vco_gpc2clk_out_vco_f(void) +{ + return 0x1U; +} +static inline u32 trim_sys_gpc2clk_out_r(void) +{ + return 0x00137250U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_s(void) +{ + return 6U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 trim_sys_gpc2clk_out_bypdiv_by31_f(void) +{ + return 0x3cU; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_s(void) +{ + return 6U; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_m(void) +{ + return 0x3fU << 8U; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_v(u32 r) +{ + return (r >> 8U) & 0x3fU; +} +static inline u32 trim_sys_gpc2clk_out_vcodiv_by1_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpc2clk_out_sdiv14_m(void) +{ + return 0x1U << 31U; +} +static inline u32 trim_sys_gpc2clk_out_sdiv14_indiv4_mode_f(void) +{ + return 0x80000000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_r(u32 i) +{ + return 0x00134124U + i*512U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_noofipclks_f(u32 v) +{ + return (v & 0x3fffU) << 0U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_write_en_asserted_f(void) +{ + return 0x10000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_enable_asserted_f(void) +{ + return 0x100000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cfg_reset_asserted_f(void) +{ + return 0x1000000U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cnt_r(u32 i) +{ + return 0x00134128U + i*512U; +} +static inline u32 trim_gpc_clk_cntr_ncgpcclk_cnt_value_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 trim_sys_gpcpll_cfg2_r(void) +{ + return 0x0013700cU; +} +static inline u32 trim_sys_gpcpll_cfg2_sdm_din_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 trim_sys_gpcpll_cfg2_sdm_din_m(void) +{ + return 0xffU << 0U; +} +static inline u32 trim_sys_gpcpll_cfg2_sdm_din_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 trim_sys_gpcpll_cfg2_sdm_din_new_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 trim_sys_gpcpll_cfg2_sdm_din_new_m(void) +{ + return 0xffU << 8U; +} +static inline u32 trim_sys_gpcpll_cfg2_sdm_din_new_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 trim_sys_gpcpll_cfg2_pll_stepa_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 trim_sys_gpcpll_cfg2_pll_stepa_m(void) +{ + return 0xffU << 24U; +} +static inline u32 trim_sys_gpcpll_cfg3_r(void) +{ + return 0x00137018U; +} +static inline u32 trim_sys_gpcpll_cfg3_vco_ctrl_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 trim_sys_gpcpll_cfg3_vco_ctrl_m(void) +{ + return 0x1ffU << 0U; +} +static inline u32 trim_sys_gpcpll_cfg3_pll_stepb_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 trim_sys_gpcpll_cfg3_pll_stepb_m(void) +{ + return 0xffU << 16U; +} +static inline u32 trim_sys_gpcpll_cfg3_dfs_testout_v(u32 r) +{ + return (r >> 24U) & 0x7fU; +} +static inline u32 trim_sys_gpcpll_dvfs0_r(void) +{ + return 0x00137010U; +} +static inline u32 trim_sys_gpcpll_dvfs0_dfs_coeff_f(u32 v) +{ + return (v & 0x7fU) << 0U; +} +static inline u32 trim_sys_gpcpll_dvfs0_dfs_coeff_m(void) +{ + return 0x7fU << 0U; +} +static inline u32 trim_sys_gpcpll_dvfs0_dfs_coeff_v(u32 r) +{ + return (r >> 0U) & 0x7fU; +} +static inline u32 trim_sys_gpcpll_dvfs0_dfs_det_max_f(u32 v) +{ + return (v & 0x7fU) << 8U; +} +static inline u32 trim_sys_gpcpll_dvfs0_dfs_det_max_m(void) +{ + return 0x7fU << 8U; +} +static inline u32 trim_sys_gpcpll_dvfs0_dfs_det_max_v(u32 r) +{ + return (r >> 8U) & 0x7fU; +} +static inline u32 trim_sys_gpcpll_dvfs0_dfs_dc_offset_f(u32 v) +{ + return (v & 0x3fU) << 16U; +} +static inline u32 trim_sys_gpcpll_dvfs0_dfs_dc_offset_m(void) +{ + return 0x3fU << 16U; +} +static inline u32 trim_sys_gpcpll_dvfs0_dfs_dc_offset_v(u32 r) +{ + return (r >> 16U) & 0x3fU; +} +static inline u32 trim_sys_gpcpll_dvfs0_mode_m(void) +{ + return 0x1U << 28U; +} +static inline u32 trim_sys_gpcpll_dvfs0_mode_dvfspll_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpcpll_dvfs1_r(void) +{ + return 0x00137014U; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_ext_det_f(u32 v) +{ + return (v & 0x7fU) << 0U; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_ext_det_m(void) +{ + return 0x7fU << 0U; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_ext_det_v(u32 r) +{ + return (r >> 0U) & 0x7fU; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_ext_strb_m(void) +{ + return 0x1U << 7U; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_ext_cal_f(u32 v) +{ + return (v & 0x7fU) << 8U; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_ext_cal_m(void) +{ + return 0x7fU << 8U; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_ext_cal_v(u32 r) +{ + return (r >> 8U) & 0x7fU; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_ext_sel_m(void) +{ + return 0x1U << 15U; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_ctrl_f(u32 v) +{ + return (v & 0xfffU) << 16U; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_ctrl_m(void) +{ + return 0xfffU << 16U; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_ctrl_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 trim_sys_gpcpll_dvfs1_en_sdm_m(void) +{ + return 0x1U << 28U; +} +static inline u32 trim_sys_gpcpll_dvfs1_en_dfs_m(void) +{ + return 0x1U << 29U; +} +static inline u32 trim_sys_gpcpll_dvfs1_en_dfs_cal_m(void) +{ + return 0x1U << 30U; +} +static inline u32 trim_sys_gpcpll_dvfs1_dfs_cal_done_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 trim_sys_gpcpll_dvfs2_r(void) +{ + return 0x00137020U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_r(void) +{ + return 0x0013701cU; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_m(void) +{ + return 0x1U << 22U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_yes_f(void) +{ + return 0x400000U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_no_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_en_dynramp_m(void) +{ + return 0x1U << 31U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_en_dynramp_yes_f(void) +{ + return 0x80000000U; +} +static inline u32 trim_sys_gpcpll_ndiv_slowdown_en_dynramp_no_f(void) +{ + return 0x0U; +} +static inline u32 trim_gpc_bcast_gpcpll_ndiv_slowdown_debug_r(void) +{ + return 0x001328a0U; +} +static inline u32 trim_gpc_bcast_gpcpll_ndiv_slowdown_debug_pll_dynramp_done_synced_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 trim_gpc_bcast_gpcpll_dvfs2_r(void) +{ + return 0x00132820U; +} +static inline u32 trim_sys_bypassctrl_r(void) +{ + return 0x00137340U; +} +static inline u32 trim_sys_bypassctrl_gpcpll_m(void) +{ + return 0x1U << 0U; +} +static inline u32 trim_sys_bypassctrl_gpcpll_bypassclk_f(void) +{ + return 0x1U; +} +static inline u32 trim_sys_bypassctrl_gpcpll_vco_f(void) +{ + return 0x0U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_bus_gp106.h b/include/nvgpu/hw/gp106/hw_bus_gp106.h new file mode 100644 index 0000000..ce3aafd --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_bus_gp106.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_bus_gp106_h_ +#define _hw_bus_gp106_h_ + +static inline u32 bus_bar0_window_r(void) +{ + return 0x00001700U; +} +static inline u32 bus_bar0_window_base_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 bus_bar0_window_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar0_window_target_sys_mem_coherent_f(void) +{ + return 0x2000000U; +} +static inline u32 bus_bar0_window_target_sys_mem_noncoherent_f(void) +{ + return 0x3000000U; +} +static inline u32 bus_bar0_window_target_bar0_window_base_shift_v(void) +{ + return 0x00000010U; +} +static inline u32 bus_bar1_block_r(void) +{ + return 0x00001704U; +} +static inline u32 bus_bar1_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar1_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar1_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar1_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar1_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar2_block_r(void) +{ + return 0x00001714U; +} +static inline u32 bus_bar2_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar2_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar2_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar2_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar2_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar1_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bar2_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bind_status_r(void) +{ + return 0x00001710U; +} +static inline u32 bus_bind_status_bar1_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 bus_bind_status_bar1_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar1_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 bus_bind_status_bar1_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 bus_bind_status_bar1_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar1_outstanding_true_f(void) +{ + return 0x2U; +} +static inline u32 bus_bind_status_bar2_pending_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 bus_bind_status_bar2_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar2_pending_busy_f(void) +{ + return 0x4U; +} +static inline u32 bus_bind_status_bar2_outstanding_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 bus_bind_status_bar2_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar2_outstanding_true_f(void) +{ + return 0x8U; +} +static inline u32 bus_intr_0_r(void) +{ + return 0x00001100U; +} +static inline u32 bus_intr_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +static inline u32 bus_intr_en_0_r(void) +{ + return 0x00001140U; +} +static inline u32 bus_intr_en_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_en_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_en_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_ccsr_gp106.h b/include/nvgpu/hw/gp106/hw_ccsr_gp106.h new file mode 100644 index 0000000..cd63777 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_ccsr_gp106.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ccsr_gp106_h_ +#define _hw_ccsr_gp106_h_ + +static inline u32 ccsr_channel_inst_r(u32 i) +{ + return 0x00800000U + i*8U; +} +static inline u32 ccsr_channel_inst__size_1_v(void) +{ + return 0x00001000U; +} +static inline u32 ccsr_channel_inst_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 ccsr_channel_inst_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 ccsr_channel_inst_bind_false_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_bind_true_f(void) +{ + return 0x80000000U; +} +static inline u32 ccsr_channel_r(u32 i) +{ + return 0x00800004U + i*8U; +} +static inline u32 ccsr_channel__size_1_v(void) +{ + return 0x00001000U; +} +static inline u32 ccsr_channel_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ccsr_channel_enable_set_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ccsr_channel_enable_set_true_f(void) +{ + return 0x400U; +} +static inline u32 ccsr_channel_enable_clr_true_f(void) +{ + return 0x800U; +} +static inline u32 ccsr_channel_status_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ccsr_channel_status_pending_ctx_reload_v(void) +{ + return 0x00000002U; +} +static inline u32 ccsr_channel_status_pending_acq_ctx_reload_v(void) +{ + return 0x00000004U; +} +static inline u32 ccsr_channel_status_on_pbdma_ctx_reload_v(void) +{ + return 0x0000000aU; +} +static inline u32 ccsr_channel_status_on_pbdma_and_eng_ctx_reload_v(void) +{ + return 0x0000000bU; +} +static inline u32 ccsr_channel_status_on_eng_ctx_reload_v(void) +{ + return 0x0000000cU; +} +static inline u32 ccsr_channel_status_on_eng_pending_ctx_reload_v(void) +{ + return 0x0000000dU; +} +static inline u32 ccsr_channel_status_on_eng_pending_acq_ctx_reload_v(void) +{ + return 0x0000000eU; +} +static inline u32 ccsr_channel_next_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ccsr_channel_next_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ccsr_channel_force_ctx_reload_true_f(void) +{ + return 0x100U; +} +static inline u32 ccsr_channel_busy_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_ce_gp106.h b/include/nvgpu/hw/gp106/hw_ce_gp106.h new file mode 100644 index 0000000..8892f42 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_ce_gp106.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ce_gp106_h_ +#define _hw_ce_gp106_h_ + +static inline u32 ce_intr_status_r(u32 i) +{ + return 0x00104410U + i*128U; +} +static inline u32 ce_intr_status_blockpipe_pending_f(void) +{ + return 0x1U; +} +static inline u32 ce_intr_status_blockpipe_reset_f(void) +{ + return 0x1U; +} +static inline u32 ce_intr_status_nonblockpipe_pending_f(void) +{ + return 0x2U; +} +static inline u32 ce_intr_status_nonblockpipe_reset_f(void) +{ + return 0x2U; +} +static inline u32 ce_intr_status_launcherr_pending_f(void) +{ + return 0x4U; +} +static inline u32 ce_intr_status_launcherr_reset_f(void) +{ + return 0x4U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_ctxsw_prog_gp106.h b/include/nvgpu/hw/gp106/hw_ctxsw_prog_gp106.h new file mode 100644 index 0000000..3387d23 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_ctxsw_prog_gp106.h @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ctxsw_prog_gp106_h_ +#define _hw_ctxsw_prog_gp106_h_ + +static inline u32 ctxsw_prog_fecs_header_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_main_image_num_gpcs_o(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_main_image_patch_count_o(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_lo_o(void) +{ + return 0x00000014U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_hi_o(void) +{ + return 0x00000018U; +} +static inline u32 ctxsw_prog_main_image_zcull_o(void) +{ + return 0x0000001cU; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_no_ctxsw_v(void) +{ + return 0x00000001U; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_separate_buffer_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_zcull_ptr_o(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_main_image_pm_o(void) +{ + return 0x00000028U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_m(void) +{ + return 0x7U << 0U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_m(void) +{ + return 0x7U << 3U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_ctxsw_f(void) +{ + return 0x8U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_ptr_o(void) +{ + return 0x0000002cU; +} +static inline u32 ctxsw_prog_main_image_num_save_ops_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_main_image_num_wfi_save_ops_o(void) +{ + return 0x000000d0U; +} +static inline u32 ctxsw_prog_main_image_num_cta_save_ops_o(void) +{ + return 0x000000d4U; +} +static inline u32 ctxsw_prog_main_image_num_gfxp_save_ops_o(void) +{ + return 0x000000d8U; +} +static inline u32 ctxsw_prog_main_image_num_cilp_save_ops_o(void) +{ + return 0x000000dcU; +} +static inline u32 ctxsw_prog_main_image_num_restore_ops_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_main_image_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_main_image_magic_value_v_value_v(void) +{ + return 0x600dc0deU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_local_image_ppc_info_num_ppcs_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_ppc_mask_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_num_tpcs_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_local_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_local_magic_value_v_value_v(void) +{ + return 0xad0becabU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_o(void) +{ + return 0x000000ecU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_size_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 ctxsw_prog_extended_buffer_segments_size_in_bytes_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_extended_marker_size_in_bytes_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_register_stride_v(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_control_register_stride_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_o(void) +{ + return 0x000000a0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_s(void) +{ + return 2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_m(void) +{ + return 0x3U << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_allow_all_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_use_map_f(void) +{ + return 0x2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_lo_o(void) +{ + return 0x000000a4U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_hi_o(void) +{ + return 0x000000a8U; +} +static inline u32 ctxsw_prog_main_image_misc_options_o(void) +{ + return 0x0000003cU; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_disabled_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_o(void) +{ + return 0x00000080U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_control_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_control_gfxp_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_o(void) +{ + return 0x00000068U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_o(void) +{ + return 0x00000084U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_cta_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_cilp_f(void) +{ + return 0x2U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_falcon_gp106.h b/include/nvgpu/hw/gp106/hw_falcon_gp106.h new file mode 100644 index 0000000..d899e3f --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_falcon_gp106.h @@ -0,0 +1,603 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_falcon_gp106_h_ +#define _hw_falcon_gp106_h_ + +static inline u32 falcon_falcon_irqsset_r(void) +{ + return 0x00000000U; +} +static inline u32 falcon_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqsclr_r(void) +{ + return 0x00000004U; +} +static inline u32 falcon_falcon_irqstat_r(void) +{ + return 0x00000008U; +} +static inline u32 falcon_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 falcon_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 falcon_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqmode_r(void) +{ + return 0x0000000cU; +} +static inline u32 falcon_falcon_irqmset_r(void) +{ + return 0x00000010U; +} +static inline u32 falcon_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_r(void) +{ + return 0x00000014U; +} +static inline u32 falcon_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqmask_r(void) +{ + return 0x00000018U; +} +static inline u32 falcon_falcon_irqdest_r(void) +{ + return 0x0000001cU; +} +static inline u32 falcon_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 falcon_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 falcon_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 falcon_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 falcon_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 falcon_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 falcon_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 falcon_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 falcon_falcon_curctx_r(void) +{ + return 0x00000050U; +} +static inline u32 falcon_falcon_nxtctx_r(void) +{ + return 0x00000054U; +} +static inline u32 falcon_falcon_mailbox0_r(void) +{ + return 0x00000040U; +} +static inline u32 falcon_falcon_mailbox1_r(void) +{ + return 0x00000044U; +} +static inline u32 falcon_falcon_itfen_r(void) +{ + return 0x00000048U; +} +static inline u32 falcon_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 falcon_falcon_idlestate_r(void) +{ + return 0x0000004cU; +} +static inline u32 falcon_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 falcon_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 falcon_falcon_os_r(void) +{ + return 0x00000080U; +} +static inline u32 falcon_falcon_engctl_r(void) +{ + return 0x000000a4U; +} +static inline u32 falcon_falcon_cpuctl_r(void) +{ + return 0x00000100U; +} +static inline u32 falcon_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_cpuctl_sreset_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_cpuctl_hreset_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_stopped_m(void) +{ + return 0x1U << 5U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_alias_r(void) +{ + return 0x00000130U; +} +static inline u32 falcon_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_imemc_r(u32 i) +{ + return 0x00000180U + i*16U; +} +static inline u32 falcon_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_imemc_secure_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 falcon_falcon_imemd_r(u32 i) +{ + return 0x00000184U + i*16U; +} +static inline u32 falcon_falcon_imemt_r(u32 i) +{ + return 0x00000188U + i*16U; +} +static inline u32 falcon_falcon_sctl_r(void) +{ + return 0x00000240U; +} +static inline u32 falcon_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 falcon_falcon_bootvec_r(void) +{ + return 0x00000104U; +} +static inline u32 falcon_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 falcon_falcon_dmactl_r(void) +{ + return 0x0000010cU; +} +static inline u32 falcon_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 falcon_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 falcon_falcon_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_hwcfg_r(void) +{ + return 0x00000108U; +} +static inline u32 falcon_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 falcon_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 falcon_falcon_dmatrfbase_r(void) +{ + return 0x00000110U; +} +static inline u32 falcon_falcon_dmatrfbase1_r(void) +{ + return 0x00000128U; +} +static inline u32 falcon_falcon_dmatrfmoffs_r(void) +{ + return 0x00000114U; +} +static inline u32 falcon_falcon_dmatrfcmd_r(void) +{ + return 0x00000118U; +} +static inline u32 falcon_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 falcon_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 falcon_falcon_dmatrffboffs_r(void) +{ + return 0x0000011cU; +} +static inline u32 falcon_falcon_imctl_debug_r(void) +{ + return 0x0000015cU; +} +static inline u32 falcon_falcon_imctl_debug_addr_blk_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 falcon_falcon_imctl_debug_cmd_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 falcon_falcon_imstat_r(void) +{ + return 0x00000144U; +} +static inline u32 falcon_falcon_traceidx_r(void) +{ + return 0x00000148U; +} +static inline u32 falcon_falcon_traceidx_maxidx_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 falcon_falcon_traceidx_idx_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 falcon_falcon_tracepc_r(void) +{ + return 0x0000014cU; +} +static inline u32 falcon_falcon_tracepc_pc_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 falcon_falcon_exterraddr_r(void) +{ + return 0x00000168U; +} +static inline u32 falcon_falcon_exterrstat_r(void) +{ + return 0x0000016cU; +} +static inline u32 falcon_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 falcon_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 falcon_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 falcon_falcon_icd_cmd_r(void) +{ + return 0x00000200U; +} +static inline u32 falcon_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 falcon_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 falcon_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 falcon_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 falcon_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 falcon_falcon_icd_rdata_r(void) +{ + return 0x0000020cU; +} +static inline u32 falcon_falcon_dmemc_r(u32 i) +{ + return 0x000001c0U + i*8U; +} +static inline u32 falcon_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 falcon_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 falcon_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 falcon_falcon_dmemd_r(u32 i) +{ + return 0x000001c4U + i*8U; +} +static inline u32 falcon_falcon_debug1_r(void) +{ + return 0x00000090U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_s(void) +{ + return 1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_m(void) +{ + return 0x1U << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_init_f(void) +{ + return 0x0U; +} +static inline u32 falcon_falcon_debuginfo_r(void) +{ + return 0x00000094U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_fb_gp106.h b/include/nvgpu/hw/gp106/hw_fb_gp106.h new file mode 100644 index 0000000..1c2a1ac --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_fb_gp106.h @@ -0,0 +1,563 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fb_gp106_h_ +#define _hw_fb_gp106_h_ + +static inline u32 fb_fbhub_num_active_ltcs_r(void) +{ + return 0x00100800U; +} +static inline u32 fb_mmu_ctrl_r(void) +{ + return 0x00100c80U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_space_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 fb_priv_mmu_phy_secure_r(void) +{ + return 0x00100ce4U; +} +static inline u32 fb_mmu_invalidate_pdb_r(void) +{ + return 0x00100cb8U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_sys_mem_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_pdb_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_invalidate_r(void) +{ + return 0x00100cbcU; +} +static inline u32 fb_mmu_invalidate_all_va_true_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_invalidate_all_pdb_true_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_m(void) +{ + return 0x1U << 2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_true_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_invalidate_replay_s(void) +{ + return 3U; +} +static inline u32 fb_mmu_invalidate_replay_f(u32 v) +{ + return (v & 0x7U) << 3U; +} +static inline u32 fb_mmu_invalidate_replay_m(void) +{ + return 0x7U << 3U; +} +static inline u32 fb_mmu_invalidate_replay_v(u32 r) +{ + return (r >> 3U) & 0x7U; +} +static inline u32 fb_mmu_invalidate_replay_none_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_replay_start_f(void) +{ + return 0x8U; +} +static inline u32 fb_mmu_invalidate_replay_start_ack_all_f(void) +{ + return 0x10U; +} +static inline u32 fb_mmu_invalidate_replay_cancel_targeted_f(void) +{ + return 0x18U; +} +static inline u32 fb_mmu_invalidate_replay_cancel_global_f(void) +{ + return 0x20U; +} +static inline u32 fb_mmu_invalidate_replay_cancel_f(void) +{ + return 0x20U; +} +static inline u32 fb_mmu_invalidate_sys_membar_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_sys_membar_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 fb_mmu_invalidate_sys_membar_m(void) +{ + return 0x1U << 6U; +} +static inline u32 fb_mmu_invalidate_sys_membar_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_sys_membar_true_f(void) +{ + return 0x40U; +} +static inline u32 fb_mmu_invalidate_ack_s(void) +{ + return 2U; +} +static inline u32 fb_mmu_invalidate_ack_f(u32 v) +{ + return (v & 0x3U) << 7U; +} +static inline u32 fb_mmu_invalidate_ack_m(void) +{ + return 0x3U << 7U; +} +static inline u32 fb_mmu_invalidate_ack_v(u32 r) +{ + return (r >> 7U) & 0x3U; +} +static inline u32 fb_mmu_invalidate_ack_ack_none_required_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_ack_ack_intranode_f(void) +{ + return 0x100U; +} +static inline u32 fb_mmu_invalidate_ack_ack_globally_f(void) +{ + return 0x80U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_s(void) +{ + return 6U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_f(u32 v) +{ + return (v & 0x3fU) << 9U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_m(void) +{ + return 0x3fU << 9U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_v(u32 r) +{ + return (r >> 9U) & 0x3fU; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_s(void) +{ + return 5U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_f(u32 v) +{ + return (v & 0x1fU) << 15U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_m(void) +{ + return 0x1fU << 15U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_v(u32 r) +{ + return (r >> 15U) & 0x1fU; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_m(void) +{ + return 0x1U << 20U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_gpc_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_hub_f(void) +{ + return 0x100000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_s(void) +{ + return 3U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_m(void) +{ + return 0x7U << 24U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_v(u32 r) +{ + return (r >> 24U) & 0x7U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_all_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_pte_only_f(void) +{ + return 0x1000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde0_f(void) +{ + return 0x2000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde1_f(void) +{ + return 0x3000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde2_f(void) +{ + return 0x4000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde3_f(void) +{ + return 0x5000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde4_f(void) +{ + return 0x6000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde5_f(void) +{ + return 0x7000000U; +} +static inline u32 fb_mmu_invalidate_trigger_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_trigger_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_trigger_true_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_debug_wr_r(void) +{ + return 0x00100cc8U; +} +static inline u32 fb_mmu_debug_wr_aperture_s(void) +{ + return 2U; +} +static inline u32 fb_mmu_debug_wr_aperture_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_m(void) +{ + return 0x3U << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fb_mmu_debug_wr_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_wr_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_vol_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_wr_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_debug_wr_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_wr_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_rd_r(void) +{ + return 0x00100cccU; +} +static inline u32 fb_mmu_debug_rd_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_rd_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_rd_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_ctrl_r(void) +{ + return 0x00100cc4U; +} +static inline u32 fb_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 fb_mmu_debug_ctrl_debug_m(void) +{ + return 0x1U << 16U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_priv_level_mask_r(void) +{ + return 0x00100cdcU; +} +static inline u32 fb_mmu_priv_level_mask_write_violation_m(void) +{ + return 0x1U << 7U; +} +static inline u32 fb_niso_flush_sysmem_addr_r(void) +{ + return 0x00100c10U; +} +static inline u32 fb_mmu_local_memory_range_r(void) +{ + return 0x00100ce0U; +} +static inline u32 fb_mmu_local_memory_range_lower_scale_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 fb_mmu_local_memory_range_lower_mag_v(u32 r) +{ + return (r >> 4U) & 0x3fU; +} +static inline u32 fb_mmu_local_memory_range_ecc_mode_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fb_fbpa_fbio_delay_r(void) +{ + return 0x009a065cU; +} +static inline u32 fb_fbpa_fbio_delay_src_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 fb_fbpa_fbio_delay_src_m(void) +{ + return 0xfU << 0U; +} +static inline u32 fb_fbpa_fbio_delay_src_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 fb_fbpa_fbio_delay_src_max_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_fbpa_fbio_delay_priv_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 fb_fbpa_fbio_delay_priv_m(void) +{ + return 0xfU << 4U; +} +static inline u32 fb_fbpa_fbio_delay_priv_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 fb_fbpa_fbio_delay_priv_max_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_fbpa_fbio_cmd_delay_r(void) +{ + return 0x009a08e0U; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_m(void) +{ + return 0xfU << 0U; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_max_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_m(void) +{ + return 0xfU << 4U; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_max_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_niso_scrub_status_r(void) +{ + return 0x00100b20U; +} +static inline u32 fb_niso_scrub_status_flag_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 fb_fbpa_fbio_iref_byte_rx_ctrl_r(void) +{ + return 0x009a0eb0U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_fbpa_gp106.h b/include/nvgpu/hw/gp106/hw_fbpa_gp106.h new file mode 100644 index 0000000..797a40c --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_fbpa_gp106.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fbpa_gp106_h_ +#define _hw_fbpa_gp106_h_ + +static inline u32 fbpa_cstatus_r(void) +{ + return 0x009a020cU; +} +static inline u32 fbpa_cstatus_ramamount_v(u32 r) +{ + return (r >> 0U) & 0x1ffffU; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_fifo_gp106.h b/include/nvgpu/hw/gp106/hw_fifo_gp106.h new file mode 100644 index 0000000..804e9e4 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_fifo_gp106.h @@ -0,0 +1,695 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fifo_gp106_h_ +#define _hw_fifo_gp106_h_ + +static inline u32 fifo_bar1_base_r(void) +{ + return 0x00002254U; +} +static inline u32 fifo_bar1_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_bar1_base_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_bar1_base_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 fifo_bar1_base_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_runlist_base_r(void) +{ + return 0x00002270U; +} +static inline u32 fifo_runlist_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_runlist_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fifo_runlist_base_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_runlist_base_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 fifo_runlist_r(void) +{ + return 0x00002274U; +} +static inline u32 fifo_runlist_engine_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 fifo_eng_runlist_base_r(u32 i) +{ + return 0x00002280U + i*8U; +} +static inline u32 fifo_eng_runlist_base__size_1_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_eng_runlist_r(u32 i) +{ + return 0x00002284U + i*8U; +} +static inline u32 fifo_eng_runlist__size_1_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_eng_runlist_length_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fifo_eng_runlist_length_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 fifo_eng_runlist_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_pb_timeslice_r(u32 i) +{ + return 0x00002350U + i*4U; +} +static inline u32 fifo_pb_timeslice_timeout_16_f(void) +{ + return 0x10U; +} +static inline u32 fifo_pb_timeslice_timescale_0_f(void) +{ + return 0x0U; +} +static inline u32 fifo_pb_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_pbdma_map_r(u32 i) +{ + return 0x00002390U + i*4U; +} +static inline u32 fifo_intr_0_r(void) +{ + return 0x00002100U; +} +static inline u32 fifo_intr_0_bind_error_pending_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_bind_error_reset_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_sched_error_pending_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_sched_error_reset_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_chsw_error_pending_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_chsw_error_reset_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_fb_flush_timeout_pending_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_fb_flush_timeout_reset_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_lb_error_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_lb_error_reset_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_replayable_fault_error_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 fifo_intr_0_dropped_mmu_fault_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 fifo_intr_0_dropped_mmu_fault_reset_f(void) +{ + return 0x8000000U; +} +static inline u32 fifo_intr_0_mmu_fault_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_intr_0_pbdma_intr_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_intr_0_runlist_event_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 fifo_intr_0_channel_intr_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_intr_en_0_r(void) +{ + return 0x00002140U; +} +static inline u32 fifo_intr_en_0_sched_error_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_intr_en_0_sched_error_m(void) +{ + return 0x1U << 8U; +} +static inline u32 fifo_intr_en_0_mmu_fault_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 fifo_intr_en_0_mmu_fault_m(void) +{ + return 0x1U << 28U; +} +static inline u32 fifo_intr_en_1_r(void) +{ + return 0x00002528U; +} +static inline u32 fifo_intr_bind_error_r(void) +{ + return 0x0000252cU; +} +static inline u32 fifo_intr_sched_error_r(void) +{ + return 0x0000254cU; +} +static inline u32 fifo_intr_sched_error_code_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fifo_intr_sched_error_code_ctxsw_timeout_v(void) +{ + return 0x0000000aU; +} +static inline u32 fifo_intr_chsw_error_r(void) +{ + return 0x0000256cU; +} +static inline u32 fifo_intr_mmu_fault_id_r(void) +{ + return 0x0000259cU; +} +static inline u32 fifo_intr_mmu_fault_eng_id_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_intr_mmu_fault_eng_id_graphics_f(void) +{ + return 0x0U; +} +static inline u32 fifo_intr_mmu_fault_inst_r(u32 i) +{ + return 0x00002800U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_inst_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 fifo_intr_mmu_fault_inst_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_intr_mmu_fault_lo_r(u32 i) +{ + return 0x00002804U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_hi_r(u32 i) +{ + return 0x00002808U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_info_r(u32 i) +{ + return 0x0000280cU + i*16U; +} +static inline u32 fifo_intr_mmu_fault_info_type_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 fifo_intr_mmu_fault_info_client_type_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 fifo_intr_mmu_fault_info_client_type_gpc_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_intr_mmu_fault_info_client_type_hub_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_mmu_fault_info_client_v(u32 r) +{ + return (r >> 8U) & 0x7fU; +} +static inline u32 fifo_intr_pbdma_id_r(void) +{ + return 0x000025a0U; +} +static inline u32 fifo_intr_pbdma_id_status_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_intr_pbdma_id_status_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fifo_intr_pbdma_id_status__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 fifo_intr_runlist_r(void) +{ + return 0x00002a00U; +} +static inline u32 fifo_fb_timeout_r(void) +{ + return 0x00002a04U; +} +static inline u32 fifo_fb_timeout_period_m(void) +{ + return 0x3fffffffU << 0U; +} +static inline u32 fifo_fb_timeout_period_max_f(void) +{ + return 0x3fffffffU; +} +static inline u32 fifo_error_sched_disable_r(void) +{ + return 0x0000262cU; +} +static inline u32 fifo_sched_disable_r(void) +{ + return 0x00002630U; +} +static inline u32 fifo_sched_disable_runlist_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_sched_disable_runlist_m(u32 i) +{ + return 0x1U << (0U + i*1U); +} +static inline u32 fifo_sched_disable_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_preempt_r(void) +{ + return 0x00002634U; +} +static inline u32 fifo_preempt_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_preempt_type_channel_f(void) +{ + return 0x0U; +} +static inline u32 fifo_preempt_type_tsg_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_preempt_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_preempt_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_trigger_mmu_fault_r(u32 i) +{ + return 0x00002a30U + i*4U; +} +static inline u32 fifo_trigger_mmu_fault_id_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 fifo_trigger_mmu_fault_enable_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_engine_status_r(u32 i) +{ + return 0x00002640U + i*8U; +} +static inline u32 fifo_engine_status__size_1_v(void) +{ + return 0x00000009U; +} +static inline u32 fifo_engine_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_engine_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_engine_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_engine_status_ctx_status_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_ctx_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_engine_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_engine_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_engine_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_faulted_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fifo_engine_status_faulted_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_engine_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fifo_engine_status_engine_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_engine_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_f(void) +{ + return 0x8000U; +} +static inline u32 fifo_pbdma_status_r(u32 i) +{ + return 0x00003080U + i*4U; +} +static inline u32 fifo_pbdma_status__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 fifo_pbdma_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_pbdma_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_pbdma_status_chan_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_pbdma_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_pbdma_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_chsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_pbdma_status_chsw_in_progress_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_lo_r(void) +{ + return 0x00002a70U; +} +static inline u32 fifo_replay_fault_buffer_lo_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 fifo_replay_fault_buffer_lo_enable_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_lo_enable_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_lo_base_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 fifo_replay_fault_buffer_lo_base_reset_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_hi_r(void) +{ + return 0x00002a74U; +} +static inline u32 fifo_replay_fault_buffer_hi_base_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fifo_replay_fault_buffer_hi_base_reset_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_size_r(void) +{ + return 0x00002a78U; +} +static inline u32 fifo_replay_fault_buffer_size_hw_f(u32 v) +{ + return (v & 0x3fffU) << 0U; +} +static inline u32 fifo_replay_fault_buffer_size_hw_entries_v(void) +{ + return 0x00001200U; +} +static inline u32 fifo_replay_fault_buffer_get_r(void) +{ + return 0x00002a7cU; +} +static inline u32 fifo_replay_fault_buffer_get_offset_hw_f(u32 v) +{ + return (v & 0x3fffU) << 0U; +} +static inline u32 fifo_replay_fault_buffer_get_offset_hw_init_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_put_r(void) +{ + return 0x00002a80U; +} +static inline u32 fifo_replay_fault_buffer_put_offset_hw_f(u32 v) +{ + return (v & 0x3fffU) << 0U; +} +static inline u32 fifo_replay_fault_buffer_put_offset_hw_init_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_info_r(void) +{ + return 0x00002a84U; +} +static inline u32 fifo_replay_fault_buffer_info_overflow_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fifo_replay_fault_buffer_info_overflow_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_info_overflow_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_info_overflow_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_info_write_nack_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 fifo_replay_fault_buffer_info_write_nack_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_info_write_nack_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_info_write_nack_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_info_fault_while_buffer_disabled_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 fifo_replay_fault_buffer_info_fault_while_buffer_disabled_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_info_fault_while_buffer_disabled_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_info_fault_while_buffer_disabled_clear_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_flush_gp106.h b/include/nvgpu/hw/gp106/hw_flush_gp106.h new file mode 100644 index 0000000..c4e1c32 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_flush_gp106.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_flush_gp106_h_ +#define _hw_flush_gp106_h_ + +static inline u32 flush_l2_system_invalidate_r(void) +{ + return 0x00070004U; +} +static inline u32 flush_l2_system_invalidate_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_r(void) +{ + return 0x00070010U; +} +static inline u32 flush_l2_flush_dirty_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_r(void) +{ + return 0x0007000cU; +} +static inline u32 flush_l2_clean_comptags_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_r(void) +{ + return 0x00070000U; +} +static inline u32 flush_fb_flush_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_fb_flush_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_fb_flush_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_fb_flush_outstanding_true_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_fuse_gp106.h b/include/nvgpu/hw/gp106/hw_fuse_gp106.h new file mode 100644 index 0000000..bfb19b9 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_fuse_gp106.h @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fuse_gp106_h_ +#define _hw_fuse_gp106_h_ + +static inline u32 fuse_status_opt_gpc_r(void) +{ + return 0x00021c1cU; +} +static inline u32 fuse_status_opt_tpc_gpc_r(u32 i) +{ + return 0x00021c38U + i*4U; +} +static inline u32 fuse_ctrl_opt_tpc_gpc_r(u32 i) +{ + return 0x00021838U + i*4U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_r(void) +{ + return 0x00021944U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_m(void) +{ + return 0x3U << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_r(void) +{ + return 0x00021948U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_yes_f(void) +{ + return 0x1U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_no_f(void) +{ + return 0x0U; +} +static inline u32 fuse_status_opt_fbio_r(void) +{ + return 0x00021c14U; +} +static inline u32 fuse_status_opt_fbio_data_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fuse_status_opt_fbio_data_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fuse_status_opt_fbio_data_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fuse_status_opt_rop_l2_fbp_r(u32 i) +{ + return 0x00021d70U + i*4U; +} +static inline u32 fuse_status_opt_fbp_r(void) +{ + return 0x00021d38U; +} +static inline u32 fuse_status_opt_fbp_idx_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fuse_vin_cal_fuse_rev_r(void) +{ + return 0x0002164cU; +} +static inline u32 fuse_vin_cal_fuse_rev_data_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fuse_vin_cal_gpc0_r(void) +{ + return 0x00021650U; +} +static inline u32 fuse_vin_cal_gpc0_icpt_int_data_s(void) +{ + return 12U; +} +static inline u32 fuse_vin_cal_gpc0_icpt_int_data_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fuse_vin_cal_gpc0_icpt_frac_data_s(void) +{ + return 2U; +} +static inline u32 fuse_vin_cal_gpc0_icpt_frac_data_v(u32 r) +{ + return (r >> 14U) & 0x3U; +} +static inline u32 fuse_vin_cal_gpc0_slope_int_data_s(void) +{ + return 4U; +} +static inline u32 fuse_vin_cal_gpc0_slope_int_data_v(u32 r) +{ + return (r >> 10U) & 0xfU; +} +static inline u32 fuse_vin_cal_gpc0_slope_frac_data_s(void) +{ + return 10U; +} +static inline u32 fuse_vin_cal_gpc0_slope_frac_data_v(u32 r) +{ + return (r >> 0U) & 0x3ffU; +} +static inline u32 fuse_vin_cal_gpc1_delta_r(void) +{ + return 0x00021654U; +} +static inline u32 fuse_vin_cal_gpc1_delta_icpt_int_data_s(void) +{ + return 8U; +} +static inline u32 fuse_vin_cal_gpc1_delta_icpt_int_data_v(u32 r) +{ + return (r >> 14U) & 0xffU; +} +static inline u32 fuse_vin_cal_gpc1_delta_icpt_frac_data_s(void) +{ + return 2U; +} +static inline u32 fuse_vin_cal_gpc1_delta_icpt_frac_data_v(u32 r) +{ + return (r >> 12U) & 0x3U; +} +static inline u32 fuse_vin_cal_gpc1_delta_icpt_sign_data_s(void) +{ + return 1U; +} +static inline u32 fuse_vin_cal_gpc1_delta_icpt_sign_data_v(u32 r) +{ + return (r >> 22U) & 0x1U; +} +static inline u32 fuse_vin_cal_gpc1_delta_slope_int_data_s(void) +{ + return 1U; +} +static inline u32 fuse_vin_cal_gpc1_delta_slope_int_data_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 fuse_vin_cal_gpc1_delta_slope_frac_data_s(void) +{ + return 10U; +} +static inline u32 fuse_vin_cal_gpc1_delta_slope_frac_data_v(u32 r) +{ + return (r >> 0U) & 0x3ffU; +} +static inline u32 fuse_vin_cal_gpc1_delta_slope_sign_data_s(void) +{ + return 1U; +} +static inline u32 fuse_vin_cal_gpc1_delta_slope_sign_data_v(u32 r) +{ + return (r >> 11U) & 0x1U; +} +static inline u32 fuse_vin_cal_gpc2_delta_r(void) +{ + return 0x00021658U; +} +static inline u32 fuse_vin_cal_gpc3_delta_r(void) +{ + return 0x0002165cU; +} +static inline u32 fuse_vin_cal_gpc4_delta_r(void) +{ + return 0x00021660U; +} +static inline u32 fuse_vin_cal_gpc5_delta_r(void) +{ + return 0x00021664U; +} +static inline u32 fuse_vin_cal_shared_delta_r(void) +{ + return 0x00021668U; +} +static inline u32 fuse_vin_cal_sram_delta_r(void) +{ + return 0x0002166cU; +} +static inline u32 fuse_vin_cal_sram_delta_icpt_int_data_s(void) +{ + return 9U; +} +static inline u32 fuse_vin_cal_sram_delta_icpt_int_data_v(u32 r) +{ + return (r >> 13U) & 0x1ffU; +} +static inline u32 fuse_vin_cal_sram_delta_icpt_frac_data_s(void) +{ + return 1U; +} +static inline u32 fuse_vin_cal_sram_delta_icpt_frac_data_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_gc6_gp106.h b/include/nvgpu/hw/gp106/hw_gc6_gp106.h new file mode 100644 index 0000000..91e9d7b --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_gc6_gp106.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gc6_gp106_h_ +#define _hw_gc6_gp106_h_ +static inline u32 gc6_sci_strap_r(void) +{ + return 0x00010ebb0; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_gmmu_gp106.h b/include/nvgpu/hw/gp106/hw_gmmu_gp106.h new file mode 100644 index 0000000..8369001 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_gmmu_gp106.h @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gmmu_gp106_h_ +#define _hw_gmmu_gp106_h_ + +static inline u32 gmmu_new_pde_is_pte_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_is_pte_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_aperture_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_aperture_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_aperture_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_pde_aperture_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_pde_aperture_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_pde_address_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pde_address_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_vol_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_vol_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_pde_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_new_pde__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_dual_pde_is_pte_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_is_pte_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_dual_pde_address_big_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_new_dual_pde_address_big_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_dual_pde_vol_small_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_vol_small_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_dual_pde_vol_small_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_vol_big_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_vol_big_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_dual_pde_vol_big_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_address_small_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_dual_pde_address_small_sys_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_new_dual_pde_address_big_shift_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_dual_pde__size_v(void) +{ + return 0x00000010U; +} +static inline u32 gmmu_new_pte__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_pte_valid_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_valid_true_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_new_pte_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_privilege_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_privilege_true_f(void) +{ + return 0x20U; +} +static inline u32 gmmu_new_pte_privilege_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_address_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pte_address_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_address_vid_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pte_address_vid_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_vol_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_vol_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_pte_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_aperture_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_aperture_video_memory_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_aperture_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_pte_aperture_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_pte_read_only_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_read_only_true_f(void) +{ + return 0x40U; +} +static inline u32 gmmu_new_pte_comptagline_f(u32 v) +{ + return (v & 0x3ffffU) << 4U; +} +static inline u32 gmmu_new_pte_comptagline_w(void) +{ + return 1U; +} +static inline u32 gmmu_new_pte_kind_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gmmu_new_pte_kind_w(void) +{ + return 1U; +} +static inline u32 gmmu_new_pte_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_pte_kind_f(u32 v) +{ + return (v & 0xffU) << 4U; +} +static inline u32 gmmu_pte_kind_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_kind_invalid_v(void) +{ + return 0x000000ffU; +} +static inline u32 gmmu_pte_kind_pitch_v(void) +{ + return 0x00000000U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_gr_gp106.h b/include/nvgpu/hw/gp106/hw_gr_gp106.h new file mode 100644 index 0000000..3ebed7e --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_gr_gp106.h @@ -0,0 +1,4163 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gr_gp106_h_ +#define _hw_gr_gp106_h_ + +static inline u32 gr_intr_r(void) +{ + return 0x00400100U; +} +static inline u32 gr_intr_notify_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_notify_reset_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_semaphore_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_semaphore_reset_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_illegal_method_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_method_reset_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_notify_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_illegal_notify_reset_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 gr_intr_firmware_method_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_firmware_method_reset_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_illegal_class_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_illegal_class_reset_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_fecs_error_pending_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_fecs_error_reset_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_class_error_pending_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_class_error_reset_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_exception_pending_f(void) +{ + return 0x200000U; +} +static inline u32 gr_intr_exception_reset_f(void) +{ + return 0x200000U; +} +static inline u32 gr_fecs_intr_r(void) +{ + return 0x00400144U; +} +static inline u32 gr_class_error_r(void) +{ + return 0x00400110U; +} +static inline u32 gr_class_error_code_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_intr_nonstall_r(void) +{ + return 0x00400120U; +} +static inline u32 gr_intr_nonstall_trap_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_en_r(void) +{ + return 0x0040013cU; +} +static inline u32 gr_exception_r(void) +{ + return 0x00400108U; +} +static inline u32 gr_exception_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception_gpc_m(void) +{ + return 0x1U << 24U; +} +static inline u32 gr_exception_memfmt_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_exception_ds_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_exception_sked_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_exception_pd_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_exception_scc_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_exception_ssync_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_exception_mme_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_exception1_r(void) +{ + return 0x00400118U; +} +static inline u32 gr_exception1_gpc_0_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_exception2_r(void) +{ + return 0x0040011cU; +} +static inline u32 gr_exception_en_r(void) +{ + return 0x00400138U; +} +static inline u32 gr_exception_en_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception1_en_r(void) +{ + return 0x00400130U; +} +static inline u32 gr_exception2_en_r(void) +{ + return 0x00400134U; +} +static inline u32 gr_gpfifo_ctl_r(void) +{ + return 0x00400500U; +} +static inline u32 gr_gpfifo_ctl_access_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpfifo_ctl_access_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpfifo_ctl_access_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpfifo_status_r(void) +{ + return 0x00400504U; +} +static inline u32 gr_trapped_addr_r(void) +{ + return 0x00400704U; +} +static inline u32 gr_trapped_addr_mthd_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 gr_trapped_addr_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 gr_trapped_addr_mme_generated_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 gr_trapped_addr_datahigh_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 gr_trapped_addr_priv_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 gr_trapped_addr_status_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_trapped_data_lo_r(void) +{ + return 0x00400708U; +} +static inline u32 gr_trapped_data_hi_r(void) +{ + return 0x0040070cU; +} +static inline u32 gr_trapped_data_mme_r(void) +{ + return 0x00400710U; +} +static inline u32 gr_trapped_data_mme_pc_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_status_r(void) +{ + return 0x00400700U; +} +static inline u32 gr_status_fe_method_upper_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_status_fe_gi_v(u32 r) +{ + return (r >> 21U) & 0x1U; +} +static inline u32 gr_status_mask_r(void) +{ + return 0x00400610U; +} +static inline u32 gr_status_1_r(void) +{ + return 0x00400604U; +} +static inline u32 gr_status_2_r(void) +{ + return 0x00400608U; +} +static inline u32 gr_engine_status_r(void) +{ + return 0x0040060cU; +} +static inline u32 gr_engine_status_value_busy_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_be0_becs_be_exception_r(void) +{ + return 0x00410204U; +} +static inline u32 gr_pri_be0_becs_be_exception_en_r(void) +{ + return 0x00410208U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_en_r(void) +{ + return 0x00502c94U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_activity_0_r(void) +{ + return 0x00400380U; +} +static inline u32 gr_activity_1_r(void) +{ + return 0x00400384U; +} +static inline u32 gr_activity_2_r(void) +{ + return 0x00400388U; +} +static inline u32 gr_activity_4_r(void) +{ + return 0x00400390U; +} +static inline u32 gr_activity_4_gpc0_s(void) +{ + return 3U; +} +static inline u32 gr_activity_4_gpc0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_activity_4_gpc0_m(void) +{ + return 0x7U << 0U; +} +static inline u32 gr_activity_4_gpc0_v(u32 r) +{ + return (r >> 0U) & 0x7U; +} +static inline u32 gr_activity_4_gpc0_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_activity_4_gpc0_preempted_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_pri_gpc0_gcc_dbg_r(void) +{ + return 0x00501000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_r(void) +{ + return 0x00419000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_invalidate_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cache_control_r(void) +{ + return 0x005046a4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_r(void) +{ + return 0x00419ea4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_invalidate_cache_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_sked_activity_r(void) +{ + return 0x00407054U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity0_r(void) +{ + return 0x00502c80U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity1_r(void) +{ + return 0x00502c84U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity2_r(void) +{ + return 0x00502c88U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity3_r(void) +{ + return 0x00502c8cU; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x00504500U; +} +static inline u32 gr_pri_gpc0_tpc1_tpccs_tpc_activity_0_r(void) +{ + return 0x00504d00U; +} +static inline u32 gr_pri_gpc0_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00501d00U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_0_r(void) +{ + return 0x0041ac80U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_1_r(void) +{ + return 0x0041ac84U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_2_r(void) +{ + return 0x0041ac88U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_3_r(void) +{ + return 0x0041ac8cU; +} +static inline u32 gr_pri_gpcs_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x0041c500U; +} +static inline u32 gr_pri_gpcs_tpc1_tpccs_tpc_activity_0_r(void) +{ + return 0x0041cd00U; +} +static inline u32 gr_pri_gpcs_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00419d00U; +} +static inline u32 gr_pri_be0_becs_be_activity0_r(void) +{ + return 0x00410200U; +} +static inline u32 gr_pri_be1_becs_be_activity0_r(void) +{ + return 0x00410600U; +} +static inline u32 gr_pri_bes_becs_be_activity0_r(void) +{ + return 0x00408a00U; +} +static inline u32 gr_pri_ds_mpipe_status_r(void) +{ + return 0x00405858U; +} +static inline u32 gr_pri_fe_go_idle_info_r(void) +{ + return 0x00404194U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_tex_subunits_status_r(void) +{ + return 0x00504238U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_r(void) +{ + return 0x005046b8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp0_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp1_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp2_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp3_pending_f(void) +{ + return 0x80U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp0_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp1_pending_f(void) +{ + return 0x200U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp2_pending_f(void) +{ + return 0x400U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp3_pending_f(void) +{ + return 0x800U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_r(void) +{ + return 0x005044a0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_corrected_shm0_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_corrected_shm1_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_detected_shm0_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_detected_shm1_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_double_err_detected_shm0_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_double_err_detected_shm1_pending_f(void) +{ + return 0x200U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_single_err_count_r(void) +{ + return 0x005046bcU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_double_err_count_r(void) +{ + return 0x005046c0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_r(void) +{ + return 0x005044a4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_corrected_m(void) +{ + return 0xffU << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_corrected_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_detected_m(void) +{ + return 0xffU << 8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_detected_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_double_detected_m(void) +{ + return 0xffU << 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_double_detected_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_r(void) +{ + return 0x005042c4U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_default_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe0_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe1_f(void) +{ + return 0x2U; +} +static inline u32 gr_pri_be0_crop_status1_r(void) +{ + return 0x00410134U; +} +static inline u32 gr_pri_bes_crop_status1_r(void) +{ + return 0x00408934U; +} +static inline u32 gr_pri_be0_zrop_status_r(void) +{ + return 0x00410048U; +} +static inline u32 gr_pri_be0_zrop_status2_r(void) +{ + return 0x0041004cU; +} +static inline u32 gr_pri_bes_zrop_status_r(void) +{ + return 0x00408848U; +} +static inline u32 gr_pri_bes_zrop_status2_r(void) +{ + return 0x0040884cU; +} +static inline u32 gr_pipe_bundle_address_r(void) +{ + return 0x00400200U; +} +static inline u32 gr_pipe_bundle_address_value_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pipe_bundle_data_r(void) +{ + return 0x00400204U; +} +static inline u32 gr_pipe_bundle_config_r(void) +{ + return 0x00400208U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_r(void) +{ + return 0x00404000U; +} +static inline u32 gr_fe_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_fe_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_info_r(void) +{ + return 0x004041b0U; +} +static inline u32 gr_fe_go_idle_timeout_r(void) +{ + return 0x00404154U; +} +static inline u32 gr_fe_go_idle_timeout_count_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fe_go_idle_timeout_count_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_go_idle_timeout_count_prod_f(void) +{ + return 0x1800U; +} +static inline u32 gr_fe_object_table_r(u32 i) +{ + return 0x00404200U + i*4U; +} +static inline u32 gr_fe_object_table_nvclass_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_fe_tpc_fs_r(void) +{ + return 0x004041c4U; +} +static inline u32 gr_pri_mme_shadow_raw_index_r(void) +{ + return 0x00404488U; +} +static inline u32 gr_pri_mme_shadow_raw_index_write_trigger_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pri_mme_shadow_raw_data_r(void) +{ + return 0x0040448cU; +} +static inline u32 gr_mme_hww_esr_r(void) +{ + return 0x00404490U; +} +static inline u32 gr_mme_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_mme_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_mme_hww_esr_info_r(void) +{ + return 0x00404494U; +} +static inline u32 gr_memfmt_hww_esr_r(void) +{ + return 0x00404600U; +} +static inline u32 gr_memfmt_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_memfmt_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fecs_cpuctl_r(void) +{ + return 0x00409100U; +} +static inline u32 gr_fecs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_cpuctl_alias_r(void) +{ + return 0x00409130U; +} +static inline u32 gr_fecs_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_dmactl_r(void) +{ + return 0x0040910cU; +} +static inline u32 gr_fecs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_fecs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_fecs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_fecs_os_r(void) +{ + return 0x00409080U; +} +static inline u32 gr_fecs_idlestate_r(void) +{ + return 0x0040904cU; +} +static inline u32 gr_fecs_mailbox0_r(void) +{ + return 0x00409040U; +} +static inline u32 gr_fecs_mailbox1_r(void) +{ + return 0x00409044U; +} +static inline u32 gr_fecs_irqstat_r(void) +{ + return 0x00409008U; +} +static inline u32 gr_fecs_irqmode_r(void) +{ + return 0x0040900cU; +} +static inline u32 gr_fecs_irqmask_r(void) +{ + return 0x00409018U; +} +static inline u32 gr_fecs_irqdest_r(void) +{ + return 0x0040901cU; +} +static inline u32 gr_fecs_curctx_r(void) +{ + return 0x00409050U; +} +static inline u32 gr_fecs_nxtctx_r(void) +{ + return 0x00409054U; +} +static inline u32 gr_fecs_engctl_r(void) +{ + return 0x004090a4U; +} +static inline u32 gr_fecs_debug1_r(void) +{ + return 0x00409090U; +} +static inline u32 gr_fecs_debuginfo_r(void) +{ + return 0x00409094U; +} +static inline u32 gr_fecs_icd_cmd_r(void) +{ + return 0x00409200U; +} +static inline u32 gr_fecs_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 gr_fecs_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 gr_fecs_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 gr_fecs_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 gr_fecs_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 gr_fecs_icd_rdata_r(void) +{ + return 0x0040920cU; +} +static inline u32 gr_fecs_imemc_r(u32 i) +{ + return 0x00409180U + i*16U; +} +static inline u32 gr_fecs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_imemd_r(u32 i) +{ + return 0x00409184U + i*16U; +} +static inline u32 gr_fecs_imemt_r(u32 i) +{ + return 0x00409188U + i*16U; +} +static inline u32 gr_fecs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_dmemc_r(u32 i) +{ + return 0x004091c0U + i*8U; +} +static inline u32 gr_fecs_dmemc_offs_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 gr_fecs_dmemc_offs_v(u32 r) +{ + return (r >> 2U) & 0x3fU; +} +static inline u32 gr_fecs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_dmemd_r(u32 i) +{ + return 0x004091c4U + i*8U; +} +static inline u32 gr_fecs_dmatrfbase_r(void) +{ + return 0x00409110U; +} +static inline u32 gr_fecs_dmatrfmoffs_r(void) +{ + return 0x00409114U; +} +static inline u32 gr_fecs_dmatrffboffs_r(void) +{ + return 0x0040911cU; +} +static inline u32 gr_fecs_dmatrfcmd_r(void) +{ + return 0x00409118U; +} +static inline u32 gr_fecs_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_fecs_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_fecs_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_fecs_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_fecs_bootvec_r(void) +{ + return 0x00409104U; +} +static inline u32 gr_fecs_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_falcon_hwcfg_r(void) +{ + return 0x00409108U; +} +static inline u32 gr_gpcs_gpccs_falcon_hwcfg_r(void) +{ + return 0x0041a108U; +} +static inline u32 gr_fecs_falcon_rm_r(void) +{ + return 0x00409084U; +} +static inline u32 gr_fecs_current_ctx_r(void) +{ + return 0x00409b00U; +} +static inline u32 gr_fecs_current_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_current_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_current_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_current_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_current_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_current_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_current_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_current_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_current_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_current_ctx_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_method_data_r(void) +{ + return 0x00409500U; +} +static inline u32 gr_fecs_method_push_r(void) +{ + return 0x00409504U; +} +static inline u32 gr_fecs_method_push_adr_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_v(void) +{ + return 0x00000003U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_f(void) +{ + return 0x3U; +} +static inline u32 gr_fecs_method_push_adr_discover_image_size_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_method_push_adr_wfi_golden_save_v(void) +{ + return 0x00000009U; +} +static inline u32 gr_fecs_method_push_adr_restore_golden_v(void) +{ + return 0x00000015U; +} +static inline u32 gr_fecs_method_push_adr_discover_zcull_image_size_v(void) +{ + return 0x00000016U; +} +static inline u32 gr_fecs_method_push_adr_discover_pm_image_size_v(void) +{ + return 0x00000025U; +} +static inline u32 gr_fecs_method_push_adr_discover_reglist_image_size_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_bind_instance_v(void) +{ + return 0x00000031U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_virtual_address_v(void) +{ + return 0x00000032U; +} +static inline u32 gr_fecs_method_push_adr_stop_ctxsw_v(void) +{ + return 0x00000038U; +} +static inline u32 gr_fecs_method_push_adr_start_ctxsw_v(void) +{ + return 0x00000039U; +} +static inline u32 gr_fecs_method_push_adr_set_watchdog_timeout_f(void) +{ + return 0x21U; +} +static inline u32 gr_fecs_method_push_adr_discover_preemption_image_size_v(void) +{ + return 0x0000001aU; +} +static inline u32 gr_fecs_method_push_adr_halt_pipeline_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_fecs_host_int_status_r(void) +{ + return 0x00409c18U; +} +static inline u32 gr_fecs_host_int_status_fault_during_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_fecs_host_int_status_umimp_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 gr_fecs_host_int_status_umimp_illegal_method_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 gr_fecs_host_int_clear_r(void) +{ + return 0x00409c20U; +} +static inline u32 gr_fecs_host_int_enable_r(void) +{ + return 0x00409c24U; +} +static inline u32 gr_fecs_host_int_enable_fault_during_ctxsw_enable_f(void) +{ + return 0x10000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_firmware_method_enable_f(void) +{ + return 0x20000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_illegal_method_enable_f(void) +{ + return 0x40000U; +} +static inline u32 gr_fecs_host_int_enable_watchdog_enable_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_r(void) +{ + return 0x00409614U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_engine_reset_disabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_engine_reset_disabled_f(void) +{ + return 0x20U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_engine_reset_disabled_f(void) +{ + return 0x40U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_disabled_f(void) +{ + return 0x100U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_disabled_f(void) +{ + return 0x200U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_disabled_f(void) +{ + return 0x400U; +} +static inline u32 gr_fecs_ctx_state_store_major_rev_id_r(void) +{ + return 0x0040960cU; +} +static inline u32 gr_fecs_ctxsw_mailbox_r(u32 i) +{ + return 0x00409800U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_fail_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_r(u32 i) +{ + return 0x004098c0U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_r(u32 i) +{ + return 0x00409840U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_fs_r(void) +{ + return 0x00409604U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_fs_num_available_fbps_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_fbps_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_m(void) +{ + return 0x1fU << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_fecs_cfg_r(void) +{ + return 0x00409620U; +} +static inline u32 gr_fecs_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_fecs_rc_lanes_r(void) +{ + return 0x00409880U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_fecs_ctxsw_status_1_r(void) +{ + return 0x00409400U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_m(void) +{ + return 0x1U << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_adr_r(void) +{ + return 0x00409a24U; +} +static inline u32 gr_fecs_new_ctx_r(void) +{ + return 0x00409b04U; +} +static inline u32 gr_fecs_new_ctx_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_new_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_new_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_new_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_new_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_new_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_new_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_new_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_new_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_new_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_new_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_ptr_r(void) +{ + return 0x00409a0cU; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_arb_ctx_cmd_r(void) +{ + return 0x00409a10U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_ctxsw_status_fe_0_r(void) +{ + return 0x00409c00U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_gpc_0_r(void) +{ + return 0x00502c04U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_1_r(void) +{ + return 0x00502400U; +} +static inline u32 gr_fecs_ctxsw_idlestate_r(void) +{ + return 0x00409420U; +} +static inline u32 gr_fecs_feature_override_ecc_r(void) +{ + return 0x00409658U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_idlestate_r(void) +{ + return 0x00502420U; +} +static inline u32 gr_rstr2d_gpc_map0_r(void) +{ + return 0x0040780cU; +} +static inline u32 gr_rstr2d_gpc_map1_r(void) +{ + return 0x00407810U; +} +static inline u32 gr_rstr2d_gpc_map2_r(void) +{ + return 0x00407814U; +} +static inline u32 gr_rstr2d_gpc_map3_r(void) +{ + return 0x00407818U; +} +static inline u32 gr_rstr2d_gpc_map4_r(void) +{ + return 0x0040781cU; +} +static inline u32 gr_rstr2d_gpc_map5_r(void) +{ + return 0x00407820U; +} +static inline u32 gr_rstr2d_map_table_cfg_r(void) +{ + return 0x004078bcU; +} +static inline u32 gr_rstr2d_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_rstr2d_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_hww_esr_r(void) +{ + return 0x00406018U; +} +static inline u32 gr_pd_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pd_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_num_tpc_per_gpc_r(u32 i) +{ + return 0x00406028U + i*4U; +} +static inline u32 gr_pd_num_tpc_per_gpc__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count1_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count2_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count3_f(u32 v) +{ + return (v & 0xfU) << 12U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count4_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count5_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count6_f(u32 v) +{ + return (v & 0xfU) << 24U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count7_f(u32 v) +{ + return (v & 0xfU) << 28U; +} +static inline u32 gr_pd_ab_dist_cfg0_r(void) +{ + return 0x004064c0U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_en_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_dis_f(void) +{ + return 0x0U; +} +static inline u32 gr_pd_ab_dist_cfg1_r(void) +{ + return 0x004064c4U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_batches_init_f(void) +{ + return 0xffffU; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_granularity_v(void) +{ + return 0x00000080U; +} +static inline u32 gr_pd_ab_dist_cfg2_r(void) +{ + return 0x004064c8U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_f(u32 v) +{ + return (v & 0x1fffU) << 0U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_init_v(void) +{ + return 0x00000900U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_f(u32 v) +{ + return (v & 0x1fffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_scc_bundle_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_min_gpm_fifo_depths_v(void) +{ + return 0x00000900U; +} +static inline u32 gr_pd_dist_skip_table_r(u32 i) +{ + return 0x004064d0U + i*4U; +} +static inline u32 gr_pd_dist_skip_table__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n0_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n1_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n2_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n3_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_ds_debug_r(void) +{ + return 0x00405800U; +} +static inline u32 gr_ds_debug_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_debug_timeslice_mode_enable_f(void) +{ + return 0x8000000U; +} +static inline u32 gr_ds_zbc_color_r_r(void) +{ + return 0x00405804U; +} +static inline u32 gr_ds_zbc_color_r_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_g_r(void) +{ + return 0x00405808U; +} +static inline u32 gr_ds_zbc_color_g_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_b_r(void) +{ + return 0x0040580cU; +} +static inline u32 gr_ds_zbc_color_b_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_a_r(void) +{ + return 0x00405810U; +} +static inline u32 gr_ds_zbc_color_a_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_r(void) +{ + return 0x00405814U; +} +static inline u32 gr_ds_zbc_color_fmt_val_f(u32 v) +{ + return (v & 0x7fU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_zero_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_color_fmt_val_unorm_one_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_ds_zbc_color_fmt_val_rf32_gf32_bf32_af32_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_ds_zbc_color_fmt_val_a8_b8_g8_r8_v(void) +{ + return 0x00000028U; +} +static inline u32 gr_ds_zbc_z_r(void) +{ + return 0x00405818U; +} +static inline u32 gr_ds_zbc_z_val_s(void) +{ + return 32U; +} +static inline u32 gr_ds_zbc_z_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_z_val_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_ds_zbc_z_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_ds_zbc_z_val__init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_ds_zbc_z_val__init_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_r(void) +{ + return 0x0040581cU; +} +static inline u32 gr_ds_zbc_z_fmt_val_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_fp32_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_tbl_index_r(void) +{ + return 0x00405820U; +} +static inline u32 gr_ds_zbc_tbl_index_val_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_ds_zbc_tbl_ld_r(void) +{ + return 0x00405824U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_c_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_z_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_zbc_tbl_ld_action_write_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_trigger_active_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_tga_constraintlogic_beta_r(void) +{ + return 0x00405830U; +} +static inline u32 gr_ds_tga_constraintlogic_beta_cbsize_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_ds_tga_constraintlogic_alpha_r(void) +{ + return 0x0040585cU; +} +static inline u32 gr_ds_tga_constraintlogic_alpha_cbsize_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_ds_hww_esr_r(void) +{ + return 0x00405840U; +} +static inline u32 gr_ds_hww_esr_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_esr_2_r(void) +{ + return 0x00405848U; +} +static inline u32 gr_ds_hww_esr_2_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_2_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_2_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_2_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_2_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_2_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_2_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_report_mask_r(void) +{ + return 0x00405844U; +} +static inline u32 gr_ds_hww_report_mask_sph0_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_hww_report_mask_sph1_err_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_ds_hww_report_mask_sph2_err_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_hww_report_mask_sph3_err_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_ds_hww_report_mask_sph4_err_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_ds_hww_report_mask_sph5_err_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_ds_hww_report_mask_sph6_err_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_ds_hww_report_mask_sph7_err_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_ds_hww_report_mask_sph8_err_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_ds_hww_report_mask_sph9_err_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_ds_hww_report_mask_sph10_err_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_ds_hww_report_mask_sph11_err_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_ds_hww_report_mask_sph12_err_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_ds_hww_report_mask_sph13_err_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_ds_hww_report_mask_sph14_err_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_ds_hww_report_mask_sph15_err_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_ds_hww_report_mask_sph16_err_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_ds_hww_report_mask_sph17_err_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_ds_hww_report_mask_sph18_err_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_ds_hww_report_mask_sph19_err_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_ds_hww_report_mask_sph20_err_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_ds_hww_report_mask_sph21_err_report_f(void) +{ + return 0x200000U; +} +static inline u32 gr_ds_hww_report_mask_sph22_err_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_ds_hww_report_mask_sph23_err_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_ds_hww_report_mask_2_r(void) +{ + return 0x0040584cU; +} +static inline u32 gr_ds_hww_report_mask_2_sph24_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_num_tpc_per_gpc_r(u32 i) +{ + return 0x00405870U + i*4U; +} +static inline u32 gr_scc_bundle_cb_base_r(void) +{ + return 0x00408004U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_bundle_cb_size_r(void) +{ + return 0x00408008U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b__prod_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_scc_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_pagepool_base_r(void) +{ + return 0x0040800cU; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_pagepool_r(void) +{ + return 0x00408010U; +} +static inline u32 gr_scc_pagepool_total_pages_f(u32 v) +{ + return (v & 0x3ffU) << 0U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_value_v(void) +{ + return 0x00000200U; +} +static inline u32 gr_scc_pagepool_total_pages_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_s(void) +{ + return 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_f(u32 v) +{ + return (v & 0x3ffU) << 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_m(void) +{ + return 0x3ffU << 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_v(u32 r) +{ + return (r >> 10U) & 0x3ffU; +} +static inline u32 gr_scc_pagepool_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_init_r(void) +{ + return 0x0040802cU; +} +static inline u32 gr_scc_init_ram_trigger_f(void) +{ + return 0x1U; +} +static inline u32 gr_scc_hww_esr_r(void) +{ + return 0x00408030U; +} +static inline u32 gr_scc_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_scc_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_sked_hww_esr_r(void) +{ + return 0x00407020U; +} +static inline u32 gr_sked_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_cwd_fs_r(void) +{ + return 0x00405b00U; +} +static inline u32 gr_cwd_fs_num_gpcs_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_fs_num_tpcs_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_cwd_gpc_tpc_id_r(u32 i) +{ + return 0x00405b60U + i*4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc0_s(void) +{ + return 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_cwd_gpc_tpc_id_gpc0_s(void) +{ + return 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_gpc0_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc1_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_cwd_sm_id_r(u32 i) +{ + return 0x00405ba0U + i*4U; +} +static inline u32 gr_cwd_sm_id__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_cwd_sm_id_tpc0_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_sm_id_tpc1_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpc0_fs_gpc_r(void) +{ + return 0x00502608U; +} +static inline u32 gr_gpc0_fs_gpc_num_available_tpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_gpc0_fs_gpc_num_available_zculls_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_gpc0_cfg_r(void) +{ + return 0x00502620U; +} +static inline u32 gr_gpc0_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpccs_rc_lanes_r(void) +{ + return 0x00502880U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_rc_lane_size_r(void) +{ + return 0x00502910U; +} +static inline u32 gr_gpccs_rc_lane_size_v_s(void) +{ + return 24U; +} +static inline u32 gr_gpccs_rc_lane_size_v_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_zcull_fs_r(void) +{ + return 0x00500910U; +} +static inline u32 gr_gpc0_zcull_fs_num_sms_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 gr_gpc0_zcull_fs_num_active_banks_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_gpc0_zcull_ram_addr_r(void) +{ + return 0x00500914U; +} +static inline u32 gr_gpc0_zcull_ram_addr_tiles_per_hypertile_row_per_gpc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_gpc0_zcull_ram_addr_row_offset_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_r(void) +{ + return 0x00500918U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative__max_v(void) +{ + return 0x00800000U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_r(void) +{ + return 0x00500920U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_num_aliquots_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_zcsize_r(u32 i) +{ + return 0x00500a04U + i*32U; +} +static inline u32 gr_gpc0_zcull_zcsize_height_subregion__multiple_v(void) +{ + return 0x00000040U; +} +static inline u32 gr_gpc0_zcull_zcsize_width_subregion__multiple_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_r(u32 i) +{ + return 0x00500c10U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_id_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_r(u32 i) +{ + return 0x00500c30U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_mask_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_r(void) +{ + return 0x00504088U; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_value_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_r(void) +{ + return 0x00504698U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_sm_id_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_arch_r(void) +{ + return 0x0050469cU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_warp_count_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_spa_version_v(u32 r) +{ + return (r >> 8U) & 0xfffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_sm_version_v(u32 r) +{ + return (r >> 20U) & 0xfffU; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_r(void) +{ + return 0x00503018U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_true_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_r(void) +{ + return 0x005030c0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_m(void) +{ + return 0x3fffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_default_v(void) +{ + return 0x00000320U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_gfxp_v(void) +{ + return 0x00000ba8U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_offset_r(void) +{ + return 0x005030f4U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_r(void) +{ + return 0x005030e4U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_default_v(void) +{ + return 0x00000800U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_offset_r(void) +{ + return 0x005030f8U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_r(void) +{ + return 0x005030f0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_v_default_v(void) +{ + return 0x00000320U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_0_r(void) +{ + return 0x00419b00U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_0_base_addr_43_12_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_r(void) +{ + return 0x00419b04U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_s(void) +{ + return 21U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_f(u32 v) +{ + return (v & 0x1fffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_m(void) +{ + return 0x1fffffU << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_v(u32 r) +{ + return (r >> 0U) & 0x1fffffU; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_granularity_f(void) +{ + return 0x80U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_s(void) +{ + return 1U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpccs_falcon_addr_r(void) +{ + return 0x0041a0acU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_msb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_v(u32 r) +{ + return (r >> 6U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_s(void) +{ + return 12U; +} +static inline u32 gr_gpccs_falcon_addr_ext_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_m(void) +{ + return 0xfffU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_gpccs_cpuctl_r(void) +{ + return 0x0041a100U; +} +static inline u32 gr_gpccs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_gpccs_dmactl_r(void) +{ + return 0x0041a10cU; +} +static inline u32 gr_gpccs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpccs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpccs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpccs_imemc_r(u32 i) +{ + return 0x0041a180U + i*16U; +} +static inline u32 gr_gpccs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_imemd_r(u32 i) +{ + return 0x0041a184U + i*16U; +} +static inline u32 gr_gpccs_imemt_r(u32 i) +{ + return 0x0041a188U + i*16U; +} +static inline u32 gr_gpccs_imemt__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_gpccs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpccs_dmemc_r(u32 i) +{ + return 0x0041a1c0U + i*8U; +} +static inline u32 gr_gpccs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_dmemd_r(u32 i) +{ + return 0x0041a1c4U + i*8U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_r(u32 i) +{ + return 0x0041a800U + i*4U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_r(void) +{ + return 0x00418e24U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_s(void) +{ + return 32U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_r(void) +{ + return 0x00418e28U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_s(void) +{ + return 11U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_m(void) +{ + return 0x7ffU << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_v(u32 r) +{ + return (r >> 0U) & 0x7ffU; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_init_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_init_f(void) +{ + return 0x30U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_s(void) +{ + return 1U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_r(void) +{ + return 0x005001dcU; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_default_v(void) +{ + return 0x00000de0U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_r(void) +{ + return 0x005001d8U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_r(void) +{ + return 0x004181e4U; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_cbes_reserve_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_cbes_reserve_gfxp_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_gpcs_ppcs_cbm_beta_cb_ctrl_r(void) +{ + return 0x0041befcU; +} +static inline u32 gr_gpcs_ppcs_cbm_beta_cb_ctrl_cbes_reserve_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_r(u32 i) +{ + return 0x00418ea0U + i*4U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_v_m(void) +{ + return 0x3fffffU << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_r_r(u32 i) +{ + return 0x00418010U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_r_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_g_r(u32 i) +{ + return 0x0041804cU + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_g_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_b_r(u32 i) +{ + return 0x00418088U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_b_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_a_r(u32 i) +{ + return 0x004180c4U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_a_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_c_01_to_04_format_r(void) +{ + return 0x00500100U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_r(u32 i) +{ + return 0x00418110U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_01_to_04_format_r(void) +{ + return 0x0050014cU; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_r(void) +{ + return 0x00418810U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_align_bits_v(void) +{ + return 0x0000000cU; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_crstr_gpc_map0_r(void) +{ + return 0x00418b08U; +} +static inline u32 gr_crstr_gpc_map0_tile0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map0_tile1_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map0_tile2_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map0_tile3_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map0_tile4_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map0_tile5_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map1_r(void) +{ + return 0x00418b0cU; +} +static inline u32 gr_crstr_gpc_map1_tile6_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map1_tile7_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map1_tile8_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map1_tile9_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map1_tile10_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map1_tile11_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map2_r(void) +{ + return 0x00418b10U; +} +static inline u32 gr_crstr_gpc_map2_tile12_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map2_tile13_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map2_tile14_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map2_tile15_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map2_tile16_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map2_tile17_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map3_r(void) +{ + return 0x00418b14U; +} +static inline u32 gr_crstr_gpc_map3_tile18_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map3_tile19_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map3_tile20_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map3_tile21_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map3_tile22_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map3_tile23_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map4_r(void) +{ + return 0x00418b18U; +} +static inline u32 gr_crstr_gpc_map4_tile24_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map4_tile25_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map4_tile26_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map4_tile27_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map4_tile28_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map4_tile29_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map5_r(void) +{ + return 0x00418b1cU; +} +static inline u32 gr_crstr_gpc_map5_tile30_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map5_tile31_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map5_tile32_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map5_tile33_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map5_tile34_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map5_tile35_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_map_table_cfg_r(void) +{ + return 0x00418bb8U; +} +static inline u32 gr_crstr_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_crstr_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_r(void) +{ + return 0x00418980U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_1_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_2_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_3_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_4_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_5_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_6_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_7_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_r(void) +{ + return 0x00418984U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_8_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_9_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_10_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_11_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_12_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_13_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_14_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_15_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_r(void) +{ + return 0x00418988U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_16_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_17_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_18_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_19_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_20_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_21_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_22_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_s(void) +{ + return 3U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_m(void) +{ + return 0x7U << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_v(u32 r) +{ + return (r >> 28U) & 0x7U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_r(void) +{ + return 0x0041898cU; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_24_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_25_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_26_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_27_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_28_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_29_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_30_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_31_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_r(void) +{ + return 0x00418c6cU; +} +static inline u32 gr_gpcs_gpm_pd_cfg_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_timeslice_mode_enable_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_r(void) +{ + return 0x00419004U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_gcc_pagepool_r(void) +{ + return 0x00419008U; +} +static inline u32 gr_gpcs_gcc_pagepool_total_pages_f(u32 v) +{ + return (v & 0x3ffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_r(void) +{ + return 0x0041980cU; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_fast_mode_switch_true_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_r(void) +{ + return 0x00419848U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_r(void) +{ + return 0x00419c00U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_enabled_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_r(void) +{ + return 0x00419c2cU; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_r(void) +{ + return 0x00419e44U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_stack_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_api_stack_error_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_ret_empty_stack_error_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_wrap_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_pc_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_overflow_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_immc_addr_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_reg_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_encoding_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_sph_instr_combo_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_reg_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_addr_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_addr_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_addr_space_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param2_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_ldc_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_mmu_fault_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_stack_overflow_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_geometry_sm_error_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_divergent_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_report_mask_r(void) +{ + return 0x00504644U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_r(void) +{ + return 0x00419e4cU; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_sm_to_sm_fault_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_l1_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_multiple_warp_errors_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_physical_stack_overflow_error_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_int_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_ecc_sec_error_report_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_ecc_ded_error_report_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_pause_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_single_step_complete_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_report_mask_r(void) +{ + return 0x0050464cU; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_r(void) +{ + return 0x00419d0cU; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_tex_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_r(void) +{ + return 0x0041ac94U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_tpc_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gcc_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_0_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_r(void) +{ + return 0x00504610U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_on_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_off_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_off_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_warp_valid_mask_r(void) +{ + return 0x00504614U; +} +static inline u32 gr_gpc0_tpc0_sm_warp_valid_mask_1_r(void) +{ + return 0x00504618U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_r(void) +{ + return 0x00504624U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_1_r(void) +{ + return 0x00504628U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_r(void) +{ + return 0x00504634U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_1_r(void) +{ + return 0x00504638U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_bpt_pause_mask_r(void) +{ + return 0x00419e24U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_bpt_pause_mask_stop_on_any_warp_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_bpt_pause_mask_stop_on_any_sm_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_r(void) +{ + return 0x0050460cU; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_sm_in_trap_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_locked_down_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_locked_down_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_r(void) +{ + return 0x00419e50U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_r(void) +{ + return 0x00504650U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_ecc_sec_error_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_ecc_ded_error_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_r(void) +{ + return 0x00504224U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_intr_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_r(void) +{ + return 0x00504648U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_none_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_none_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_halfctl_ctrl_r(void) +{ + return 0x00504770U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_r(void) +{ + return 0x00419f70U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_gpc0_tpc0_sm_debug_sfe_control_r(void) +{ + return 0x0050477cU; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_r(void) +{ + return 0x00419f7cU; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_r(void) +{ + return 0x0041be08U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_fast_mode_switch_true_f(void) +{ + return 0x4U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map0_r(void) +{ + return 0x0041bf00U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map1_r(void) +{ + return 0x0041bf04U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map2_r(void) +{ + return 0x0041bf08U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map3_r(void) +{ + return 0x0041bf0cU; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map4_r(void) +{ + return 0x0041bf10U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map5_r(void) +{ + return 0x0041bf14U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_r(void) +{ + return 0x0041bfd0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_num_entries_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_shift_value_f(u32 v) +{ + return (v & 0x7U) << 21U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff5_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 24U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_r(void) +{ + return 0x0041bfd4U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_r(void) +{ + return 0x0041bfe4U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff6_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff7_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 5U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff8_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 10U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff9_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 15U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff10_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 20U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff11_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 25U; +} +static inline u32 gr_bes_zrop_settings_r(void) +{ + return 0x00408850U; +} +static inline u32 gr_bes_zrop_settings_num_active_ltcs_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_be0_crop_debug3_r(void) +{ + return 0x00410108U; +} +static inline u32 gr_bes_crop_debug3_r(void) +{ + return 0x00408908U; +} +static inline u32 gr_bes_crop_debug3_comp_vdc_4to2_disable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_enabled_f(void) +{ + return 0x4U; +} +static inline u32 gr_bes_crop_debug4_r(void) +{ + return 0x0040894cU; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_m(void) +{ + return 0x1U << 18U; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_to_inf_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_to_maxval_f(void) +{ + return 0x40000U; +} +static inline u32 gr_bes_crop_settings_r(void) +{ + return 0x00408958U; +} +static inline u32 gr_bes_crop_settings_num_active_ltcs_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_zcull_bytes_per_aliquot_per_gpu_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_header_bytes_per_gpc_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_subregion_header_bytes_per_gpc_v(void) +{ + return 0x000000c0U; +} +static inline u32 gr_zcull_subregion_qty_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel0_r(void) +{ + return 0x00504604U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel1_r(void) +{ + return 0x00504608U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control0_r(void) +{ + return 0x0050465cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control1_r(void) +{ + return 0x00504660U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control2_r(void) +{ + return 0x00504664U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control3_r(void) +{ + return 0x00504668U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control4_r(void) +{ + return 0x0050466cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control5_r(void) +{ + return 0x00504658U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_control_r(void) +{ + return 0x00504730U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_control_r(void) +{ + return 0x00504734U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_control_r(void) +{ + return 0x00504738U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_control_r(void) +{ + return 0x0050473cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter4_control_r(void) +{ + return 0x00504740U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter5_control_r(void) +{ + return 0x00504744U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter6_control_r(void) +{ + return 0x00504748U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter7_control_r(void) +{ + return 0x0050474cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_status_s1_r(void) +{ + return 0x00504678U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_status1_r(void) +{ + return 0x00504694U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_s0_r(void) +{ + return 0x005046f0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_s1_r(void) +{ + return 0x00504700U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_s0_r(void) +{ + return 0x005046f4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_s1_r(void) +{ + return 0x00504704U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_s0_r(void) +{ + return 0x005046f8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_s1_r(void) +{ + return 0x00504708U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_s0_r(void) +{ + return 0x005046fcU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_s1_r(void) +{ + return 0x0050470cU; +} +static inline u32 gr_fe_pwr_mode_r(void) +{ + return 0x00404170U; +} +static inline u32 gr_fe_pwr_mode_mode_auto_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_pwr_mode_mode_force_on_f(void) +{ + return 0x2U; +} +static inline u32 gr_fe_pwr_mode_req_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_fe_pwr_mode_req_send_f(void) +{ + return 0x10U; +} +static inline u32 gr_fe_pwr_mode_req_done_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_r(void) +{ + return 0x00418880U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_vm_pg_size_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_use_pdb_big_page_size_m(void) +{ + return 0x1U << 11U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_vol_fault_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_comp_fault_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_miss_gran_m(void) +{ + return 0x3U << 3U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_cache_mode_m(void) +{ + return 0x3U << 5U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_aperture_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_vol_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_disable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_pri_mmu_pm_unit_mask_r(void) +{ + return 0x00418890U; +} +static inline u32 gr_gpcs_pri_mmu_pm_req_mask_r(void) +{ + return 0x00418894U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_r(void) +{ + return 0x004188b0U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_pri_mmu_debug_wr_r(void) +{ + return 0x004188b4U; +} +static inline u32 gr_gpcs_pri_mmu_debug_rd_r(void) +{ + return 0x004188b8U; +} +static inline u32 gr_gpcs_mmu_num_active_ltcs_r(void) +{ + return 0x004188acU; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_r(void) +{ + return 0x00419e10U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_debugger_mode_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_r(void) +{ + return 0x004041c0U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_count_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_count_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_r(void) +{ + return 0x00419c84U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_m(void) +{ + return 0x7U << 8U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_arm_63_48_match_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_r(void) +{ + return 0x00419f78U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_re_suppress_m(void) +{ + return 0x3U << 11U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_re_suppress_disable_f(void) +{ + return 0x1000U; +} +static inline u32 gr_gpcs_tc_debug0_r(void) +{ + return 0x00418708U; +} +static inline u32 gr_gpcs_tc_debug0_limit_coalesce_buffer_size_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 gr_gpcs_tc_debug0_limit_coalesce_buffer_size_m(void) +{ + return 0x1ffU << 0U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_ltc_gp106.h b/include/nvgpu/hw/gp106/hw_ltc_gp106.h new file mode 100644 index 0000000..e4e87aa --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_ltc_gp106.h @@ -0,0 +1,559 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ltc_gp106_h_ +#define _hw_ltc_gp106_h_ + +static inline u32 ltc_ltcs_lts0_cbc_ctrl1_r(void) +{ + return 0x0014046cU; +} +static inline u32 ltc_ltc0_lts0_dstg_cfg0_r(void) +{ + return 0x00140518U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_r(void) +{ + return 0x0017e318U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_vdc_4to2_disable_m(void) +{ + return 0x1U << 15U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_r(void) +{ + return 0x00140494U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_ways_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_v(u32 r) +{ + return (r >> 16U) & 0x3U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_all_v(void) +{ + return 0x00000000U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_half_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_quarter_v(void) +{ + return 0x00000002U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void) +{ + return 0x0017e26cU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(void) +{ + return 0x2U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_f(void) +{ + return 0x4U; +} +static inline u32 ltc_ltc0_lts0_cbc_ctrl1_r(void) +{ + return 0x0014046cU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_r(void) +{ + return 0x0017e270U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(u32 v) +{ + return (v & 0x3ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_r(void) +{ + return 0x0017e274U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(u32 v) +{ + return (v & 0x3ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_init_v(void) +{ + return 0x0003ffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_r(void) +{ + return 0x0017e278U; +} +static inline u32 ltc_ltcs_ltss_cbc_base_alignment_shift_v(void) +{ + return 0x0000000bU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_address_v(u32 r) +{ + return (r >> 0U) & 0x3ffffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_r(void) +{ + return 0x0017e27cU; +} +static inline u32 ltc_ltcs_misc_ltc_num_active_ltcs_r(void) +{ + return 0x0017e000U; +} +static inline u32 ltc_ltcs_ltss_cbc_param_r(void) +{ + return 0x0017e280U; +} +static inline u32 ltc_ltcs_ltss_cbc_param_comptags_per_cache_line_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_cache_line_size_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_slices_per_ltc_v(u32 r) +{ + return (r >> 28U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_cbc_param2_r(void) +{ + return 0x0017e3f4U; +} +static inline u32 ltc_ltcs_ltss_cbc_param2_gobs_per_comptagline_per_slice_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_r(void) +{ + return 0x0017e2acU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_max_ways_evict_last_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_r(void) +{ + return 0x0017e338U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_address_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value_r(u32 i) +{ + return 0x0017e33cU + i*4U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_r(void) +{ + return 0x0017e34cU; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_s(void) +{ + return 32U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_r(void) +{ + return 0x0017e2b0U; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_l2_bypass_mode_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_r(void) +{ + return 0x0017e214U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_r(void) +{ + return 0x00140214U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_r(void) +{ + return 0x00142214U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_intr_r(void) +{ + return 0x0017e20cU; +} +static inline u32 ltc_ltcs_ltss_intr_ecc_sec_error_pending_f(void) +{ + return 0x100U; +} +static inline u32 ltc_ltcs_ltss_intr_ecc_ded_error_pending_f(void) +{ + return 0x200U; +} +static inline u32 ltc_ltcs_ltss_intr_en_evicted_cb_m(void) +{ + return 0x1U << 20U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_access_m(void) +{ + return 0x1U << 30U; +} +static inline u32 ltc_ltcs_ltss_intr_en_ecc_sec_error_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 ltc_ltcs_ltss_intr_en_ecc_ded_error_enabled_f(void) +{ + return 0x2000000U; +} +static inline u32 ltc_ltc0_lts0_intr_r(void) +{ + return 0x0014040cU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_r(void) +{ + return 0x0014051cU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_sec_count_m(void) +{ + return 0xffU << 0U; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_sec_count_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_ded_count_m(void) +{ + return 0xffU << 16U; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_ded_count_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_r(void) +{ + return 0x0017e2a0U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_r(void) +{ + return 0x0017e2a4U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_f(void) +{ + return 0x10000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_r(void) +{ + return 0x001402a0U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_r(void) +{ + return 0x001402a4U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_r(void) +{ + return 0x001422a0U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_r(void) +{ + return 0x001422a4U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_r(void) +{ + return 0x0014058cU; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_slice_size_in_kb_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_slices_per_l2_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_mc_gp106.h b/include/nvgpu/hw/gp106/hw_mc_gp106.h new file mode 100644 index 0000000..349e2d7 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_mc_gp106.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_mc_gp106_h_ +#define _hw_mc_gp106_h_ + +static inline u32 mc_boot_0_r(void) +{ + return 0x00000000U; +} +static inline u32 mc_boot_0_architecture_v(u32 r) +{ + return (r >> 24U) & 0x1fU; +} +static inline u32 mc_boot_0_implementation_v(u32 r) +{ + return (r >> 20U) & 0xfU; +} +static inline u32 mc_boot_0_major_revision_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 mc_boot_0_minor_revision_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 mc_intr_r(u32 i) +{ + return 0x00000100U + i*4U; +} +static inline u32 mc_intr_pfifo_pending_f(void) +{ + return 0x100U; +} +static inline u32 mc_intr_replayable_fault_pending_f(void) +{ + return 0x200U; +} +static inline u32 mc_intr_pgraph_pending_f(void) +{ + return 0x1000U; +} +static inline u32 mc_intr_pmu_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_ltc_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 mc_intr_priv_ring_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 mc_intr_pbus_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_intr_en_r(u32 i) +{ + return 0x00000140U + i*4U; +} +static inline u32 mc_intr_en_set_r(u32 i) +{ + return 0x00000160U + i*4U; +} +static inline u32 mc_intr_en_clear_r(u32 i) +{ + return 0x00000180U + i*4U; +} +static inline u32 mc_enable_r(void) +{ + return 0x00000200U; +} +static inline u32 mc_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_enable_l2_enabled_f(void) +{ + return 0x8U; +} +static inline u32 mc_enable_pmedia_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pmedia_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 mc_enable_pmedia_m(void) +{ + return 0x1U << 4U; +} +static inline u32 mc_enable_pmedia_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 mc_enable_priv_ring_enabled_f(void) +{ + return 0x20U; +} +static inline u32 mc_enable_ce0_m(void) +{ + return 0x1U << 6U; +} +static inline u32 mc_enable_pfifo_enabled_f(void) +{ + return 0x100U; +} +static inline u32 mc_enable_pgraph_enabled_f(void) +{ + return 0x1000U; +} +static inline u32 mc_enable_pwr_v(u32 r) +{ + return (r >> 13U) & 0x1U; +} +static inline u32 mc_enable_pwr_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 mc_enable_pwr_enabled_f(void) +{ + return 0x2000U; +} +static inline u32 mc_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_enable_ce2_m(void) +{ + return 0x1U << 21U; +} +static inline u32 mc_enable_ce2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 mc_enable_blg_enabled_f(void) +{ + return 0x8000000U; +} +static inline u32 mc_enable_perfmon_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +static inline u32 mc_intr_ltc_r(void) +{ + return 0x000001c0U; +} +static inline u32 mc_enable_pb_r(void) +{ + return 0x00000204U; +} +static inline u32 mc_enable_pb_0_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pb_0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 mc_enable_pb_0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 mc_enable_pb_0_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 mc_enable_pb_0_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 mc_enable_pb_sel_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 mc_elpg_enable_r(void) +{ + return 0x0000020cU; +} +static inline u32 mc_elpg_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_elpg_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_elpg_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_pbdma_gp106.h b/include/nvgpu/hw/gp106/hw_pbdma_gp106.h new file mode 100644 index 0000000..1005c5a --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_pbdma_gp106.h @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pbdma_gp106_h_ +#define _hw_pbdma_gp106_h_ + +static inline u32 pbdma_gp_entry1_r(void) +{ + return 0x10000004U; +} +static inline u32 pbdma_gp_entry1_get_hi_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pbdma_gp_entry1_length_f(u32 v) +{ + return (v & 0x1fffffU) << 10U; +} +static inline u32 pbdma_gp_entry1_length_v(u32 r) +{ + return (r >> 10U) & 0x1fffffU; +} +static inline u32 pbdma_gp_base_r(u32 i) +{ + return 0x00040048U + i*8192U; +} +static inline u32 pbdma_gp_base__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pbdma_gp_base_offset_f(u32 v) +{ + return (v & 0x1fffffffU) << 3U; +} +static inline u32 pbdma_gp_base_rsvd_s(void) +{ + return 3U; +} +static inline u32 pbdma_gp_base_hi_r(u32 i) +{ + return 0x0004004cU + i*8192U; +} +static inline u32 pbdma_gp_base_hi_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_gp_base_hi_limit2_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 pbdma_gp_fetch_r(u32 i) +{ + return 0x00040050U + i*8192U; +} +static inline u32 pbdma_gp_get_r(u32 i) +{ + return 0x00040014U + i*8192U; +} +static inline u32 pbdma_gp_put_r(u32 i) +{ + return 0x00040000U + i*8192U; +} +static inline u32 pbdma_pb_fetch_r(u32 i) +{ + return 0x00040054U + i*8192U; +} +static inline u32 pbdma_pb_fetch_hi_r(u32 i) +{ + return 0x00040058U + i*8192U; +} +static inline u32 pbdma_get_r(u32 i) +{ + return 0x00040018U + i*8192U; +} +static inline u32 pbdma_get_hi_r(u32 i) +{ + return 0x0004001cU + i*8192U; +} +static inline u32 pbdma_put_r(u32 i) +{ + return 0x0004005cU + i*8192U; +} +static inline u32 pbdma_put_hi_r(u32 i) +{ + return 0x00040060U + i*8192U; +} +static inline u32 pbdma_formats_r(u32 i) +{ + return 0x0004009cU + i*8192U; +} +static inline u32 pbdma_formats_gp_fermi0_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_formats_pb_fermi1_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_formats_mp_fermi0_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_r(u32 i) +{ + return 0x00040084U + i*8192U; +} +static inline u32 pbdma_pb_header_priv_user_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_method_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_subchannel_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_level_main_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_pb_header_type_inc_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_pb_header_type_non_inc_f(void) +{ + return 0x60000000U; +} +static inline u32 pbdma_hdr_shadow_r(u32 i) +{ + return 0x00040118U + i*8192U; +} +static inline u32 pbdma_gp_shadow_0_r(u32 i) +{ + return 0x00040110U + i*8192U; +} +static inline u32 pbdma_gp_shadow_1_r(u32 i) +{ + return 0x00040114U + i*8192U; +} +static inline u32 pbdma_subdevice_r(u32 i) +{ + return 0x00040094U + i*8192U; +} +static inline u32 pbdma_subdevice_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 pbdma_subdevice_status_active_f(void) +{ + return 0x10000000U; +} +static inline u32 pbdma_subdevice_channel_dma_enable_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_method0_r(u32 i) +{ + return 0x000400c0U + i*8192U; +} +static inline u32 pbdma_method0_fifo_size_v(void) +{ + return 0x00000004U; +} +static inline u32 pbdma_method0_addr_f(u32 v) +{ + return (v & 0xfffU) << 2U; +} +static inline u32 pbdma_method0_addr_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 pbdma_method0_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 pbdma_method0_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_method0_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_method1_r(u32 i) +{ + return 0x000400c8U + i*8192U; +} +static inline u32 pbdma_method2_r(u32 i) +{ + return 0x000400d0U + i*8192U; +} +static inline u32 pbdma_method3_r(u32 i) +{ + return 0x000400d8U + i*8192U; +} +static inline u32 pbdma_data0_r(u32 i) +{ + return 0x000400c4U + i*8192U; +} +static inline u32 pbdma_target_r(u32 i) +{ + return 0x000400acU + i*8192U; +} +static inline u32 pbdma_target_engine_sw_f(void) +{ + return 0x1fU; +} +static inline u32 pbdma_acquire_r(u32 i) +{ + return 0x00040030U + i*8192U; +} +static inline u32 pbdma_acquire_retry_man_2_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_acquire_retry_exp_2_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_acquire_timeout_exp_max_f(void) +{ + return 0x7800U; +} +static inline u32 pbdma_acquire_timeout_man_max_f(void) +{ + return 0x7fff8000U; +} +static inline u32 pbdma_acquire_timeout_en_disable_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_status_r(u32 i) +{ + return 0x00040100U + i*8192U; +} +static inline u32 pbdma_channel_r(u32 i) +{ + return 0x00040120U + i*8192U; +} +static inline u32 pbdma_signature_r(u32 i) +{ + return 0x00040010U + i*8192U; +} +static inline u32 pbdma_signature_hw_valid_f(void) +{ + return 0xfaceU; +} +static inline u32 pbdma_signature_sw_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_r(u32 i) +{ + return 0x00040008U + i*8192U; +} +static inline u32 pbdma_userd_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_userd_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 pbdma_userd_addr_f(u32 v) +{ + return (v & 0x7fffffU) << 9U; +} +static inline u32 pbdma_userd_hi_r(u32 i) +{ + return 0x0004000cU + i*8192U; +} +static inline u32 pbdma_userd_hi_addr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_config_r(u32 i) +{ + return 0x000400f4U + i*8192U; +} +static inline u32 pbdma_config_auth_level_privileged_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_hce_ctrl_r(u32 i) +{ + return 0x000400e4U + i*8192U; +} +static inline u32 pbdma_hce_ctrl_hce_priv_mode_yes_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_r(u32 i) +{ + return 0x00040108U + i*8192U; +} +static inline u32 pbdma_intr_0_memreq_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pbdma_intr_0_memreq_pending_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_intr_0_memack_timeout_pending_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_intr_0_memack_extra_pending_f(void) +{ + return 0x4U; +} +static inline u32 pbdma_intr_0_memdat_timeout_pending_f(void) +{ + return 0x8U; +} +static inline u32 pbdma_intr_0_memdat_extra_pending_f(void) +{ + return 0x10U; +} +static inline u32 pbdma_intr_0_memflush_pending_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_memop_pending_f(void) +{ + return 0x40U; +} +static inline u32 pbdma_intr_0_lbconnect_pending_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_intr_0_lbreq_pending_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_0_lback_timeout_pending_f(void) +{ + return 0x200U; +} +static inline u32 pbdma_intr_0_lback_extra_pending_f(void) +{ + return 0x400U; +} +static inline u32 pbdma_intr_0_lbdat_timeout_pending_f(void) +{ + return 0x800U; +} +static inline u32 pbdma_intr_0_lbdat_extra_pending_f(void) +{ + return 0x1000U; +} +static inline u32 pbdma_intr_0_gpfifo_pending_f(void) +{ + return 0x2000U; +} +static inline u32 pbdma_intr_0_gpptr_pending_f(void) +{ + return 0x4000U; +} +static inline u32 pbdma_intr_0_gpentry_pending_f(void) +{ + return 0x8000U; +} +static inline u32 pbdma_intr_0_gpcrc_pending_f(void) +{ + return 0x10000U; +} +static inline u32 pbdma_intr_0_pbptr_pending_f(void) +{ + return 0x20000U; +} +static inline u32 pbdma_intr_0_pbentry_pending_f(void) +{ + return 0x40000U; +} +static inline u32 pbdma_intr_0_pbcrc_pending_f(void) +{ + return 0x80000U; +} +static inline u32 pbdma_intr_0_xbarconnect_pending_f(void) +{ + return 0x100000U; +} +static inline u32 pbdma_intr_0_method_pending_f(void) +{ + return 0x200000U; +} +static inline u32 pbdma_intr_0_methodcrc_pending_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_intr_0_device_pending_f(void) +{ + return 0x800000U; +} +static inline u32 pbdma_intr_0_semaphore_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 pbdma_intr_0_acquire_pending_f(void) +{ + return 0x4000000U; +} +static inline u32 pbdma_intr_0_pri_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 pbdma_intr_0_no_ctxsw_seg_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_intr_0_pbseg_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 pbdma_intr_0_signature_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_intr_1_r(u32 i) +{ + return 0x00040148U + i*8192U; +} +static inline u32 pbdma_intr_en_0_r(u32 i) +{ + return 0x0004010cU + i*8192U; +} +static inline u32 pbdma_intr_en_0_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_en_1_r(u32 i) +{ + return 0x0004014cU + i*8192U; +} +static inline u32 pbdma_intr_stall_r(u32 i) +{ + return 0x0004013cU + i*8192U; +} +static inline u32 pbdma_intr_stall_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_stall_1_r(u32 i) +{ + return 0x00040140U + i*8192U; +} +static inline u32 pbdma_intr_stall_1_hce_illegal_op_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_udma_nop_r(void) +{ + return 0x00000008U; +} +static inline u32 pbdma_runlist_timeslice_r(u32 i) +{ + return 0x000400f8U + i*8192U; +} +static inline u32 pbdma_runlist_timeslice_timeout_128_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_runlist_timeslice_timescale_3_f(void) +{ + return 0x3000U; +} +static inline u32 pbdma_runlist_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_perf_gp106.h b/include/nvgpu/hw/gp106/hw_perf_gp106.h new file mode 100644 index 0000000..334cd20 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_perf_gp106.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_perf_gp106_h_ +#define _hw_perf_gp106_h_ + +static inline u32 perf_pmmsys_base_v(void) +{ + return 0x001b0000U; +} +static inline u32 perf_pmmsys_extent_v(void) +{ + return 0x001b0fffU; +} +static inline u32 perf_pmasys_control_r(void) +{ + return 0x001b4000U; +} +static inline u32 perf_pmasys_control_membuf_status_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_f(void) +{ + return 0x10U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_f(void) +{ + return 0x20U; +} +static inline u32 perf_pmasys_mem_block_r(void) +{ + return 0x001b4070U; +} +static inline u32 perf_pmasys_mem_block_base_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 perf_pmasys_mem_block_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 perf_pmasys_mem_block_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 perf_pmasys_mem_block_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 perf_pmasys_mem_block_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 perf_pmasys_mem_block_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_mem_block_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_outbase_r(void) +{ + return 0x001b4074U; +} +static inline u32 perf_pmasys_outbase_ptr_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_outbaseupper_r(void) +{ + return 0x001b4078U; +} +static inline u32 perf_pmasys_outbaseupper_ptr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 perf_pmasys_outsize_r(void) +{ + return 0x001b407cU; +} +static inline u32 perf_pmasys_outsize_numbytes_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_mem_bytes_r(void) +{ + return 0x001b4084U; +} +static inline u32 perf_pmasys_mem_bytes_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_mem_bump_r(void) +{ + return 0x001b4088U; +} +static inline u32 perf_pmasys_mem_bump_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_enginestatus_r(void) +{ + return 0x001b40a4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_f(void) +{ + return 0x10U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_pram_gp106.h b/include/nvgpu/hw/gp106/hw_pram_gp106.h new file mode 100644 index 0000000..7e33e71 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_pram_gp106.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pram_gp106_h_ +#define _hw_pram_gp106_h_ + +static inline u32 pram_data032_r(u32 i) +{ + return 0x00700000U + i*4U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_pri_ringmaster_gp106.h b/include/nvgpu/hw/gp106/hw_pri_ringmaster_gp106.h new file mode 100644 index 0000000..efdedc3 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_pri_ringmaster_gp106.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringmaster_gp106_h_ +#define _hw_pri_ringmaster_gp106_h_ + +static inline u32 pri_ringmaster_command_r(void) +{ + return 0x0012004cU; +} +static inline u32 pri_ringmaster_command_cmd_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 pri_ringmaster_command_cmd_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 pri_ringmaster_command_cmd_no_cmd_v(void) +{ + return 0x00000000U; +} +static inline u32 pri_ringmaster_command_cmd_start_ring_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_command_cmd_ack_interrupt_f(void) +{ + return 0x2U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_f(void) +{ + return 0x3U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_bc_grp_all_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_command_data_r(void) +{ + return 0x00120048U; +} +static inline u32 pri_ringmaster_start_results_r(void) +{ + return 0x00120050U; +} +static inline u32 pri_ringmaster_start_results_connectivity_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_start_results_connectivity_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 pri_ringmaster_intr_status0_r(void) +{ + return 0x00120058U; +} +static inline u32 pri_ringmaster_intr_status1_r(void) +{ + return 0x0012005cU; +} +static inline u32 pri_ringmaster_global_ctl_r(void) +{ + return 0x00120060U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_asserted_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_deasserted_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_enum_fbp_r(void) +{ + return 0x00120074U; +} +static inline u32 pri_ringmaster_enum_fbp_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_gpc_r(void) +{ + return 0x00120078U; +} +static inline u32 pri_ringmaster_enum_gpc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_ltc_r(void) +{ + return 0x0012006cU; +} +static inline u32 pri_ringmaster_enum_ltc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_pri_ringstation_gpc_gp106.h b/include/nvgpu/hw/gp106/hw_pri_ringstation_gpc_gp106.h new file mode 100644 index 0000000..711938d --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_pri_ringstation_gpc_gp106.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_gpc_gp106_h_ +#define _hw_pri_ringstation_gpc_gp106_h_ + +static inline u32 pri_ringstation_gpc_master_config_r(u32 i) +{ + return 0x00128300U + i*4U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_adr_r(void) +{ + return 0x00128120U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_wrdat_r(void) +{ + return 0x00128124U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_info_r(void) +{ + return 0x00128128U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_code_r(void) +{ + return 0x0012812cU; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_pri_ringstation_sys_gp106.h b/include/nvgpu/hw/gp106/hw_pri_ringstation_sys_gp106.h new file mode 100644 index 0000000..a3a1447 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_pri_ringstation_sys_gp106.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_sys_gp106_h_ +#define _hw_pri_ringstation_sys_gp106_h_ + +static inline u32 pri_ringstation_sys_master_config_r(u32 i) +{ + return 0x00122300U + i*4U; +} +static inline u32 pri_ringstation_sys_decode_config_r(void) +{ + return 0x00122204U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_m(void) +{ + return 0x7U << 0U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_drop_on_ring_not_started_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringstation_sys_priv_error_adr_r(void) +{ + return 0x00122120U; +} +static inline u32 pri_ringstation_sys_priv_error_wrdat_r(void) +{ + return 0x00122124U; +} +static inline u32 pri_ringstation_sys_priv_error_info_r(void) +{ + return 0x00122128U; +} +static inline u32 pri_ringstation_sys_priv_error_code_r(void) +{ + return 0x0012212cU; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_proj_gp106.h b/include/nvgpu/hw/gp106/hw_proj_gp106.h new file mode 100644 index 0000000..866bc7b --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_proj_gp106.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_proj_gp106_h_ +#define _hw_proj_gp106_h_ + +static inline u32 proj_gpc_base_v(void) +{ + return 0x00500000U; +} +static inline u32 proj_gpc_shared_base_v(void) +{ + return 0x00418000U; +} +static inline u32 proj_gpc_stride_v(void) +{ + return 0x00008000U; +} +static inline u32 proj_gpc_priv_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_ltc_stride_v(void) +{ + return 0x00002000U; +} +static inline u32 proj_lts_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_fbpa_base_v(void) +{ + return 0x00900000U; +} +static inline u32 proj_fbpa_shared_base_v(void) +{ + return 0x009a0000U; +} +static inline u32 proj_fbpa_stride_v(void) +{ + return 0x00004000U; +} +static inline u32 proj_ppc_in_gpc_base_v(void) +{ + return 0x00003000U; +} +static inline u32 proj_ppc_in_gpc_shared_base_v(void) +{ + return 0x00003e00U; +} +static inline u32 proj_ppc_in_gpc_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_rop_base_v(void) +{ + return 0x00410000U; +} +static inline u32 proj_rop_shared_base_v(void) +{ + return 0x00408800U; +} +static inline u32 proj_rop_stride_v(void) +{ + return 0x00000400U; +} +static inline u32 proj_tpc_in_gpc_base_v(void) +{ + return 0x00004000U; +} +static inline u32 proj_tpc_in_gpc_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_tpc_in_gpc_shared_base_v(void) +{ + return 0x00001800U; +} +static inline u32 proj_host_num_engines_v(void) +{ + return 0x00000009U; +} +static inline u32 proj_host_num_pbdma_v(void) +{ + return 0x00000004U; +} +static inline u32 proj_scal_litter_num_tpc_per_gpc_v(void) +{ + return 0x00000005U; +} +static inline u32 proj_scal_litter_num_sm_per_tpc_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_fbps_v(void) +{ + return 0x00000006U; +} +static inline u32 proj_scal_litter_num_fbpas_v(void) +{ + return 0x00000006U; +} +static inline u32 proj_scal_litter_num_gpcs_v(void) +{ + return 0x00000006U; +} +static inline u32 proj_scal_litter_num_pes_per_gpc_v(void) +{ + return 0x00000003U; +} +static inline u32 proj_scal_litter_num_tpcs_per_pes_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_scal_litter_num_zcull_banks_v(void) +{ + return 0x00000004U; +} +static inline u32 proj_scal_max_gpcs_v(void) +{ + return 0x00000020U; +} +static inline u32 proj_scal_max_tpc_per_gpc_v(void) +{ + return 0x00000008U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_psec_gp106.h b/include/nvgpu/hw/gp106/hw_psec_gp106.h new file mode 100644 index 0000000..b91c09b --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_psec_gp106.h @@ -0,0 +1,615 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_psec_gp106_h_ +#define _hw_psec_gp106_h_ + +static inline u32 psec_falcon_irqsset_r(void) +{ + return 0x00087000U; +} +static inline u32 psec_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 psec_falcon_irqsclr_r(void) +{ + return 0x00087004U; +} +static inline u32 psec_falcon_irqstat_r(void) +{ + return 0x00087008U; +} +static inline u32 psec_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 psec_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 psec_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 psec_falcon_irqmode_r(void) +{ + return 0x0008700cU; +} +static inline u32 psec_falcon_irqmset_r(void) +{ + return 0x00087010U; +} +static inline u32 psec_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 psec_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 psec_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 psec_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 psec_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 psec_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 psec_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 psec_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 psec_falcon_irqmclr_r(void) +{ + return 0x00087014U; +} +static inline u32 psec_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 psec_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 psec_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 psec_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 psec_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 psec_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 psec_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 psec_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 psec_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 psec_falcon_irqmask_r(void) +{ + return 0x00087018U; +} +static inline u32 psec_falcon_irqdest_r(void) +{ + return 0x0008701cU; +} +static inline u32 psec_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 psec_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 psec_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 psec_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 psec_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 psec_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 psec_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 psec_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 psec_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 psec_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 psec_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 psec_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 psec_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 psec_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 psec_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 psec_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 psec_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 psec_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 psec_falcon_curctx_r(void) +{ + return 0x00087050U; +} +static inline u32 psec_falcon_nxtctx_r(void) +{ + return 0x00087054U; +} +static inline u32 psec_falcon_mailbox0_r(void) +{ + return 0x00087040U; +} +static inline u32 psec_falcon_mailbox1_r(void) +{ + return 0x00087044U; +} +static inline u32 psec_falcon_itfen_r(void) +{ + return 0x00087048U; +} +static inline u32 psec_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 psec_falcon_idlestate_r(void) +{ + return 0x0008704cU; +} +static inline u32 psec_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 psec_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 psec_falcon_os_r(void) +{ + return 0x00087080U; +} +static inline u32 psec_falcon_engctl_r(void) +{ + return 0x000870a4U; +} +static inline u32 psec_falcon_cpuctl_r(void) +{ + return 0x00087100U; +} +static inline u32 psec_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 psec_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 psec_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 psec_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 psec_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 psec_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 psec_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 psec_falcon_cpuctl_alias_r(void) +{ + return 0x00087130U; +} +static inline u32 psec_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 psec_falcon_imemc_r(u32 i) +{ + return 0x00087180U + i*16U; +} +static inline u32 psec_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 psec_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 psec_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 psec_falcon_imemd_r(u32 i) +{ + return 0x00087184U + i*16U; +} +static inline u32 psec_falcon_imemt_r(u32 i) +{ + return 0x00087188U + i*16U; +} +static inline u32 psec_falcon_sctl_r(void) +{ + return 0x00087240U; +} +static inline u32 psec_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 psec_falcon_bootvec_r(void) +{ + return 0x00087104U; +} +static inline u32 psec_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 psec_falcon_dmactl_r(void) +{ + return 0x0008710cU; +} +static inline u32 psec_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 psec_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 psec_falcon_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 psec_falcon_hwcfg_r(void) +{ + return 0x00087108U; +} +static inline u32 psec_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 psec_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 psec_falcon_dmatrfbase_r(void) +{ + return 0x00087110U; +} +static inline u32 psec_falcon_dmatrfbase1_r(void) +{ + return 0x00087128U; +} +static inline u32 psec_falcon_dmatrfmoffs_r(void) +{ + return 0x00087114U; +} +static inline u32 psec_falcon_dmatrfcmd_r(void) +{ + return 0x00087118U; +} +static inline u32 psec_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 psec_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 psec_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 psec_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 psec_falcon_dmatrffboffs_r(void) +{ + return 0x0008711cU; +} +static inline u32 psec_falcon_exterraddr_r(void) +{ + return 0x00087168U; +} +static inline u32 psec_falcon_exterrstat_r(void) +{ + return 0x0008716cU; +} +static inline u32 psec_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 psec_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 psec_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 psec_sec2_falcon_icd_cmd_r(void) +{ + return 0x00087200U; +} +static inline u32 psec_sec2_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 psec_sec2_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 psec_sec2_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 psec_sec2_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 psec_sec2_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 psec_sec2_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 psec_sec2_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 psec_sec2_falcon_icd_rdata_r(void) +{ + return 0x0008720cU; +} +static inline u32 psec_falcon_dmemc_r(u32 i) +{ + return 0x000871c0U + i*8U; +} +static inline u32 psec_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 psec_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 psec_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 psec_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 psec_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 psec_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 psec_falcon_dmemd_r(u32 i) +{ + return 0x000871c4U + i*8U; +} +static inline u32 psec_falcon_debug1_r(void) +{ + return 0x00087090U; +} +static inline u32 psec_falcon_debug1_ctxsw_mode_s(void) +{ + return 1U; +} +static inline u32 psec_falcon_debug1_ctxsw_mode_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 psec_falcon_debug1_ctxsw_mode_m(void) +{ + return 0x1U << 16U; +} +static inline u32 psec_falcon_debug1_ctxsw_mode_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 psec_falcon_debug1_ctxsw_mode_init_f(void) +{ + return 0x0U; +} +static inline u32 psec_fbif_transcfg_r(u32 i) +{ + return 0x00087600U + i*4U; +} +static inline u32 psec_fbif_transcfg_target_local_fb_f(void) +{ + return 0x0U; +} +static inline u32 psec_fbif_transcfg_target_coherent_sysmem_f(void) +{ + return 0x1U; +} +static inline u32 psec_fbif_transcfg_target_noncoherent_sysmem_f(void) +{ + return 0x2U; +} +static inline u32 psec_fbif_transcfg_mem_type_s(void) +{ + return 1U; +} +static inline u32 psec_fbif_transcfg_mem_type_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 psec_fbif_transcfg_mem_type_m(void) +{ + return 0x1U << 2U; +} +static inline u32 psec_fbif_transcfg_mem_type_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 psec_fbif_transcfg_mem_type_virtual_f(void) +{ + return 0x0U; +} +static inline u32 psec_fbif_transcfg_mem_type_physical_f(void) +{ + return 0x4U; +} +static inline u32 psec_falcon_engine_r(void) +{ + return 0x000873c0U; +} +static inline u32 psec_falcon_engine_reset_true_f(void) +{ + return 0x1U; +} +static inline u32 psec_falcon_engine_reset_false_f(void) +{ + return 0x0U; +} +static inline u32 psec_fbif_ctl_r(void) +{ + return 0x00087624U; +} +static inline u32 psec_fbif_ctl_allow_phys_no_ctx_init_f(void) +{ + return 0x0U; +} +static inline u32 psec_fbif_ctl_allow_phys_no_ctx_disallow_f(void) +{ + return 0x0U; +} +static inline u32 psec_fbif_ctl_allow_phys_no_ctx_allow_f(void) +{ + return 0x80U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_pwr_gp106.h b/include/nvgpu/hw/gp106/hw_pwr_gp106.h new file mode 100644 index 0000000..2e75fa6 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_pwr_gp106.h @@ -0,0 +1,895 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pwr_gp106_h_ +#define _hw_pwr_gp106_h_ + +static inline u32 pwr_falcon_irqsset_r(void) +{ + return 0x0010a000U; +} +static inline u32 pwr_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqsclr_r(void) +{ + return 0x0010a004U; +} +static inline u32 pwr_falcon_irqstat_r(void) +{ + return 0x0010a008U; +} +static inline u32 pwr_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 pwr_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 pwr_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqmode_r(void) +{ + return 0x0010a00cU; +} +static inline u32 pwr_falcon_irqmset_r(void) +{ + return 0x0010a010U; +} +static inline u32 pwr_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_r(void) +{ + return 0x0010a014U; +} +static inline u32 pwr_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqmask_r(void) +{ + return 0x0010a018U; +} +static inline u32 pwr_falcon_irqdest_r(void) +{ + return 0x0010a01cU; +} +static inline u32 pwr_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 pwr_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 pwr_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 pwr_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 pwr_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 pwr_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 pwr_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 pwr_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 pwr_falcon_curctx_r(void) +{ + return 0x0010a050U; +} +static inline u32 pwr_falcon_nxtctx_r(void) +{ + return 0x0010a054U; +} +static inline u32 pwr_falcon_mailbox0_r(void) +{ + return 0x0010a040U; +} +static inline u32 pwr_falcon_mailbox1_r(void) +{ + return 0x0010a044U; +} +static inline u32 pwr_falcon_itfen_r(void) +{ + return 0x0010a048U; +} +static inline u32 pwr_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 pwr_falcon_idlestate_r(void) +{ + return 0x0010a04cU; +} +static inline u32 pwr_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 pwr_falcon_os_r(void) +{ + return 0x0010a080U; +} +static inline u32 pwr_falcon_engctl_r(void) +{ + return 0x0010a0a4U; +} +static inline u32 pwr_falcon_cpuctl_r(void) +{ + return 0x0010a100U; +} +static inline u32 pwr_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 pwr_falcon_cpuctl_alias_r(void) +{ + return 0x0010a130U; +} +static inline u32 pwr_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_pmu_scpctl_stat_r(void) +{ + return 0x0010ac08U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_m(void) +{ + return 0x1U << 20U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 pwr_falcon_imemc_r(u32 i) +{ + return 0x0010a180U + i*16U; +} +static inline u32 pwr_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_imemd_r(u32 i) +{ + return 0x0010a184U + i*16U; +} +static inline u32 pwr_falcon_imemt_r(u32 i) +{ + return 0x0010a188U + i*16U; +} +static inline u32 pwr_falcon_sctl_r(void) +{ + return 0x0010a240U; +} +static inline u32 pwr_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 pwr_falcon_bootvec_r(void) +{ + return 0x0010a104U; +} +static inline u32 pwr_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_falcon_dmactl_r(void) +{ + return 0x0010a10cU; +} +static inline u32 pwr_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 pwr_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_falcon_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_hwcfg_r(void) +{ + return 0x0010a108U; +} +static inline u32 pwr_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 pwr_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 pwr_falcon_dmatrfbase_r(void) +{ + return 0x0010a110U; +} +static inline u32 pwr_falcon_dmatrfbase1_r(void) +{ + return 0x0010a128U; +} +static inline u32 pwr_falcon_dmatrfmoffs_r(void) +{ + return 0x0010a114U; +} +static inline u32 pwr_falcon_dmatrfcmd_r(void) +{ + return 0x0010a118U; +} +static inline u32 pwr_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 pwr_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 pwr_falcon_dmatrffboffs_r(void) +{ + return 0x0010a11cU; +} +static inline u32 pwr_falcon_exterraddr_r(void) +{ + return 0x0010a168U; +} +static inline u32 pwr_falcon_exterrstat_r(void) +{ + return 0x0010a16cU; +} +static inline u32 pwr_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 pwr_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 pwr_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_r(void) +{ + return 0x0010a200U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 pwr_pmu_falcon_icd_rdata_r(void) +{ + return 0x0010a20cU; +} +static inline u32 pwr_falcon_dmemc_r(u32 i) +{ + return 0x0010a1c0U + i*8U; +} +static inline u32 pwr_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 pwr_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 pwr_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 pwr_falcon_dmemd_r(u32 i) +{ + return 0x0010a1c4U + i*8U; +} +static inline u32 pwr_pmu_new_instblk_r(void) +{ + return 0x0010a480U; +} +static inline u32 pwr_pmu_new_instblk_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 pwr_pmu_new_instblk_target_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 pwr_pmu_new_instblk_valid_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 pwr_pmu_mutex_id_r(void) +{ + return 0x0010a488U; +} +static inline u32 pwr_pmu_mutex_id_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_id_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_value_not_avail_v(void) +{ + return 0x000000ffU; +} +static inline u32 pwr_pmu_mutex_id_release_r(void) +{ + return 0x0010a48cU; +} +static inline u32 pwr_pmu_mutex_id_release_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_m(void) +{ + return 0xffU << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_mutex_r(u32 i) +{ + return 0x0010a580U + i*4U; +} +static inline u32 pwr_pmu_mutex__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 pwr_pmu_mutex_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_value_initial_lock_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_queue_head_r(u32 i) +{ + return 0x0010a4a0U + i*4U; +} +static inline u32 pwr_pmu_queue_head__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_queue_head_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_head_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_queue_tail_r(u32 i) +{ + return 0x0010a4b0U + i*4U; +} +static inline u32 pwr_pmu_queue_tail__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_queue_tail_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_tail_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_head_r(void) +{ + return 0x0010a4c8U; +} +static inline u32 pwr_pmu_msgq_head_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_head_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_tail_r(void) +{ + return 0x0010a4ccU; +} +static inline u32 pwr_pmu_msgq_tail_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_tail_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_idle_mask_r(u32 i) +{ + return 0x0010a504U + i*16U; +} +static inline u32 pwr_pmu_idle_mask_gr_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pwr_pmu_idle_mask_ce_2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 pwr_pmu_idle_count_r(u32 i) +{ + return 0x0010a508U + i*16U; +} +static inline u32 pwr_pmu_idle_count_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_count_value_v(u32 r) +{ + return (r >> 0U) & 0x7fffffffU; +} +static inline u32 pwr_pmu_idle_count_reset_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 pwr_pmu_idle_ctrl_r(u32 i) +{ + return 0x0010a50cU + i*16U; +} +static inline u32 pwr_pmu_idle_ctrl_value_m(void) +{ + return 0x3U << 0U; +} +static inline u32 pwr_pmu_idle_ctrl_value_busy_f(void) +{ + return 0x2U; +} +static inline u32 pwr_pmu_idle_ctrl_value_always_f(void) +{ + return 0x3U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_disabled_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_idle_threshold_r(u32 i) +{ + return 0x0010a8a0U + i*4U; +} +static inline u32 pwr_pmu_idle_threshold_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_intr_r(void) +{ + return 0x0010a9e8U; +} +static inline u32 pwr_pmu_idle_intr_en_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_en_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_idle_intr_en_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_r(void) +{ + return 0x0010a9ecU; +} +static inline u32 pwr_pmu_idle_intr_status_intr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_m(void) +{ + return U32(0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_mask_supp_r(u32 i) +{ + return 0x0010a9f0U + i*8U; +} +static inline u32 pwr_pmu_idle_mask_1_supp_r(u32 i) +{ + return 0x0010a9f4U + i*8U; +} +static inline u32 pwr_pmu_idle_ctrl_supp_r(u32 i) +{ + return 0x0010aa30U + i*8U; +} +static inline u32 pwr_pmu_debug_r(u32 i) +{ + return 0x0010a5c0U + i*4U; +} +static inline u32 pwr_pmu_debug__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_mailbox_r(u32 i) +{ + return 0x0010a450U + i*4U; +} +static inline u32 pwr_pmu_mailbox__size_1_v(void) +{ + return 0x0000000cU; +} +static inline u32 pwr_pmu_bar0_addr_r(void) +{ + return 0x0010a7a0U; +} +static inline u32 pwr_pmu_bar0_data_r(void) +{ + return 0x0010a7a4U; +} +static inline u32 pwr_pmu_bar0_ctl_r(void) +{ + return 0x0010a7acU; +} +static inline u32 pwr_pmu_bar0_timeout_r(void) +{ + return 0x0010a7a8U; +} +static inline u32 pwr_pmu_bar0_fecs_error_r(void) +{ + return 0x0010a988U; +} +static inline u32 pwr_pmu_bar0_error_status_r(void) +{ + return 0x0010a7b0U; +} +static inline u32 pwr_pmu_pg_idlefilth_r(u32 i) +{ + return 0x0010a6c0U + i*4U; +} +static inline u32 pwr_pmu_pg_ppuidlefilth_r(u32 i) +{ + return 0x0010a6e8U + i*4U; +} +static inline u32 pwr_pmu_pg_idle_cnt_r(u32 i) +{ + return 0x0010a710U + i*4U; +} +static inline u32 pwr_pmu_pg_intren_r(u32 i) +{ + return 0x0010a760U + i*4U; +} +static inline u32 pwr_fbif_transcfg_r(u32 i) +{ + return 0x0010ae00U + i*4U; +} +static inline u32 pwr_fbif_transcfg_target_local_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_target_coherent_sysmem_f(void) +{ + return 0x1U; +} +static inline u32 pwr_fbif_transcfg_target_noncoherent_sysmem_f(void) +{ + return 0x2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_s(void) +{ + return 1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_virtual_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_mem_type_physical_f(void) +{ + return 0x4U; +} +static inline u32 pwr_falcon_engine_r(void) +{ + return 0x0010a3c0U; +} +static inline u32 pwr_falcon_engine_reset_true_f(void) +{ + return 0x1U; +} +static inline u32 pwr_falcon_engine_reset_false_f(void) +{ + return 0x0U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_ram_gp106.h b/include/nvgpu/hw/gp106/hw_ram_gp106.h new file mode 100644 index 0000000..1de8aa2 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_ram_gp106.h @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ram_gp106_h_ +#define _hw_ram_gp106_h_ + +static inline u32 ram_in_ramfc_s(void) +{ + return 4096U; +} +static inline u32 ram_in_ramfc_w(void) +{ + return 0U; +} +static inline u32 ram_in_page_dir_base_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ram_in_page_dir_base_target_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 ram_in_page_dir_base_vol_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_m(void) +{ + return 0x1U << 4U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_true_f(void) +{ + return 0x10U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_m(void) +{ + return 0x1U << 5U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_true_f(void) +{ + return 0x20U; +} +static inline u32 ram_in_use_ver2_pt_format_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ram_in_use_ver2_pt_format_m(void) +{ + return 0x1U << 10U; +} +static inline u32 ram_in_use_ver2_pt_format_w(void) +{ + return 128U; +} +static inline u32 ram_in_use_ver2_pt_format_true_f(void) +{ + return 0x400U; +} +static inline u32 ram_in_use_ver2_pt_format_false_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_big_page_size_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 ram_in_big_page_size_m(void) +{ + return 0x1U << 11U; +} +static inline u32 ram_in_big_page_size_w(void) +{ + return 128U; +} +static inline u32 ram_in_big_page_size_128kb_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_big_page_size_64kb_f(void) +{ + return 0x800U; +} +static inline u32 ram_in_page_dir_base_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_page_dir_base_lo_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_hi_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_in_page_dir_base_hi_w(void) +{ + return 129U; +} +static inline u32 ram_in_adr_limit_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_adr_limit_lo_w(void) +{ + return 130U; +} +static inline u32 ram_in_adr_limit_hi_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_in_adr_limit_hi_w(void) +{ + return 131U; +} +static inline u32 ram_in_engine_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_cs_wfi_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_engine_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_engine_cs_fg_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_engine_cs_fg_f(void) +{ + return 0x8U; +} +static inline u32 ram_in_gr_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_gr_wfi_target_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_mode_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_mode_physical_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_gr_wfi_mode_physical_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_gr_wfi_mode_virtual_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_gr_wfi_mode_virtual_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_gr_wfi_ptr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_gr_wfi_ptr_lo_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_ptr_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_gr_wfi_ptr_hi_w(void) +{ + return 133U; +} +static inline u32 ram_in_base_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 ram_in_alloc_size_v(void) +{ + return 0x00001000U; +} +static inline u32 ram_fc_size_val_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_fc_gp_put_w(void) +{ + return 0U; +} +static inline u32 ram_fc_userd_w(void) +{ + return 2U; +} +static inline u32 ram_fc_userd_hi_w(void) +{ + return 3U; +} +static inline u32 ram_fc_signature_w(void) +{ + return 4U; +} +static inline u32 ram_fc_gp_get_w(void) +{ + return 5U; +} +static inline u32 ram_fc_pb_get_w(void) +{ + return 6U; +} +static inline u32 ram_fc_pb_get_hi_w(void) +{ + return 7U; +} +static inline u32 ram_fc_pb_top_level_get_w(void) +{ + return 8U; +} +static inline u32 ram_fc_pb_top_level_get_hi_w(void) +{ + return 9U; +} +static inline u32 ram_fc_acquire_w(void) +{ + return 12U; +} +static inline u32 ram_fc_semaphorea_w(void) +{ + return 14U; +} +static inline u32 ram_fc_semaphoreb_w(void) +{ + return 15U; +} +static inline u32 ram_fc_semaphorec_w(void) +{ + return 16U; +} +static inline u32 ram_fc_semaphored_w(void) +{ + return 17U; +} +static inline u32 ram_fc_gp_base_w(void) +{ + return 18U; +} +static inline u32 ram_fc_gp_base_hi_w(void) +{ + return 19U; +} +static inline u32 ram_fc_gp_fetch_w(void) +{ + return 20U; +} +static inline u32 ram_fc_pb_fetch_w(void) +{ + return 21U; +} +static inline u32 ram_fc_pb_fetch_hi_w(void) +{ + return 22U; +} +static inline u32 ram_fc_pb_put_w(void) +{ + return 23U; +} +static inline u32 ram_fc_pb_put_hi_w(void) +{ + return 24U; +} +static inline u32 ram_fc_pb_header_w(void) +{ + return 33U; +} +static inline u32 ram_fc_pb_count_w(void) +{ + return 34U; +} +static inline u32 ram_fc_subdevice_w(void) +{ + return 37U; +} +static inline u32 ram_fc_formats_w(void) +{ + return 39U; +} +static inline u32 ram_fc_target_w(void) +{ + return 43U; +} +static inline u32 ram_fc_hce_ctrl_w(void) +{ + return 57U; +} +static inline u32 ram_fc_chid_w(void) +{ + return 58U; +} +static inline u32 ram_fc_chid_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_fc_chid_id_w(void) +{ + return 0U; +} +static inline u32 ram_fc_config_w(void) +{ + return 61U; +} +static inline u32 ram_fc_runlist_timeslice_w(void) +{ + return 62U; +} +static inline u32 ram_userd_base_shift_v(void) +{ + return 0x00000009U; +} +static inline u32 ram_userd_chan_size_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_userd_put_w(void) +{ + return 16U; +} +static inline u32 ram_userd_get_w(void) +{ + return 17U; +} +static inline u32 ram_userd_ref_w(void) +{ + return 18U; +} +static inline u32 ram_userd_put_hi_w(void) +{ + return 19U; +} +static inline u32 ram_userd_ref_threshold_w(void) +{ + return 20U; +} +static inline u32 ram_userd_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_userd_get_hi_w(void) +{ + return 24U; +} +static inline u32 ram_userd_gp_get_w(void) +{ + return 34U; +} +static inline u32 ram_userd_gp_put_w(void) +{ + return 35U; +} +static inline u32 ram_userd_gp_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_gp_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_rl_entry_size_v(void) +{ + return 0x00000008U; +} +static inline u32 ram_rl_entry_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_type_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 ram_rl_entry_type_chid_f(void) +{ + return 0x0U; +} +static inline u32 ram_rl_entry_type_tsg_f(void) +{ + return 0x2000U; +} +static inline u32 ram_rl_entry_timeslice_scale_f(u32 v) +{ + return (v & 0xfU) << 14U; +} +static inline u32 ram_rl_entry_timeslice_scale_3_f(void) +{ + return 0xc000U; +} +static inline u32 ram_rl_entry_timeslice_timeout_f(u32 v) +{ + return (v & 0xffU) << 18U; +} +static inline u32 ram_rl_entry_timeslice_timeout_128_f(void) +{ + return 0x2000000U; +} +static inline u32 ram_rl_entry_tsg_length_f(u32 v) +{ + return (v & 0x3fU) << 26U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_therm_gp106.h b/include/nvgpu/hw/gp106/hw_therm_gp106.h new file mode 100644 index 0000000..ee58032 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_therm_gp106.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_therm_gp106_h_ +#define _hw_therm_gp106_h_ + +static inline u32 therm_temp_sensor_tsense_r(void) +{ + return 0x00020460U; +} +static inline u32 therm_temp_sensor_tsense_fixed_point_f(u32 v) +{ + return (v & 0x3fffU) << 3U; +} +static inline u32 therm_temp_sensor_tsense_fixed_point_m(void) +{ + return 0x3fffU << 3U; +} +static inline u32 therm_temp_sensor_tsense_fixed_point_v(u32 r) +{ + return (r >> 3U) & 0x3fffU; +} +static inline u32 therm_temp_sensor_tsense_fixed_point_min_v(void) +{ + return 0x00003b00U; +} +static inline u32 therm_temp_sensor_tsense_fixed_point_max_v(void) +{ + return 0x000010e0U; +} +static inline u32 therm_temp_sensor_tsense_state_f(u32 v) +{ + return (v & 0x3U) << 29U; +} +static inline u32 therm_temp_sensor_tsense_state_m(void) +{ + return 0x3U << 29U; +} +static inline u32 therm_temp_sensor_tsense_state_v(u32 r) +{ + return (r >> 29U) & 0x3U; +} +static inline u32 therm_temp_sensor_tsense_state_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 therm_temp_sensor_tsense_state_shadow_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_gate_ctrl_r(u32 i) +{ + return 0x00020200U + i*4U; +} +static inline u32 therm_gate_ctrl_eng_clk_m(void) +{ + return 0x3U << 0U; +} +static inline u32 therm_gate_ctrl_eng_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_eng_clk_auto_f(void) +{ + return 0x1U; +} +static inline u32 therm_gate_ctrl_eng_clk_stop_f(void) +{ + return 0x2U; +} +static inline u32 therm_gate_ctrl_blk_clk_m(void) +{ + return 0x3U << 2U; +} +static inline u32 therm_gate_ctrl_blk_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_blk_clk_auto_f(void) +{ + return 0x4U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_m(void) +{ + return 0x1fU << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_f(u32 v) +{ + return (v & 0x7U) << 13U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_m(void) +{ + return 0x7U << 13U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_m(void) +{ + return 0xfU << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_m(void) +{ + return 0xfU << 20U; +} +static inline u32 therm_fecs_idle_filter_r(void) +{ + return 0x00020288U; +} +static inline u32 therm_fecs_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_hubmmu_idle_filter_r(void) +{ + return 0x0002028cU; +} +static inline u32 therm_hubmmu_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_timer_gp106.h b/include/nvgpu/hw/gp106/hw_timer_gp106.h new file mode 100644 index 0000000..7fd722f --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_timer_gp106.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_timer_gp106_h_ +#define _hw_timer_gp106_h_ + +static inline u32 timer_pri_timeout_r(void) +{ + return 0x00009080U; +} +static inline u32 timer_pri_timeout_period_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 timer_pri_timeout_period_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 timer_pri_timeout_period_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 timer_pri_timeout_en_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 timer_pri_timeout_en_m(void) +{ + return 0x1U << 31U; +} +static inline u32 timer_pri_timeout_en_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_en_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 timer_pri_timeout_en_en_disabled_f(void) +{ + return 0x0U; +} +static inline u32 timer_pri_timeout_save_0_r(void) +{ + return 0x00009084U; +} +static inline u32 timer_pri_timeout_save_1_r(void) +{ + return 0x00009088U; +} +static inline u32 timer_pri_timeout_fecs_errcode_r(void) +{ + return 0x0000908cU; +} +static inline u32 timer_time_0_r(void) +{ + return 0x00009400U; +} +static inline u32 timer_time_1_r(void) +{ + return 0x00009410U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_top_gp106.h b/include/nvgpu/hw/gp106/hw_top_gp106.h new file mode 100644 index 0000000..749f66e --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_top_gp106.h @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_top_gp106_h_ +#define _hw_top_gp106_h_ + +static inline u32 top_num_gpcs_r(void) +{ + return 0x00022430U; +} +static inline u32 top_num_gpcs_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_tpc_per_gpc_r(void) +{ + return 0x00022434U; +} +static inline u32 top_tpc_per_gpc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_fbps_r(void) +{ + return 0x00022438U; +} +static inline u32 top_num_fbps_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_fbpas_r(void) +{ + return 0x0002243cU; +} +static inline u32 top_num_fbpas_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_ltc_per_fbp_r(void) +{ + return 0x00022450U; +} +static inline u32 top_ltc_per_fbp_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_slices_per_ltc_r(void) +{ + return 0x0002245cU; +} +static inline u32 top_slices_per_ltc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_ltcs_r(void) +{ + return 0x00022454U; +} +static inline u32 top_device_info_r(u32 i) +{ + return 0x00022700U + i*4U; +} +static inline u32 top_device_info__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 top_device_info_chain_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 top_device_info_chain_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_engine_enum_v(u32 r) +{ + return (r >> 26U) & 0xfU; +} +static inline u32 top_device_info_runlist_enum_v(u32 r) +{ + return (r >> 21U) & 0xfU; +} +static inline u32 top_device_info_intr_enum_v(u32 r) +{ + return (r >> 15U) & 0x1fU; +} +static inline u32 top_device_info_reset_enum_v(u32 r) +{ + return (r >> 9U) & 0x1fU; +} +static inline u32 top_device_info_type_enum_v(u32 r) +{ + return (r >> 2U) & 0x1fffffffU; +} +static inline u32 top_device_info_type_enum_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_type_enum_graphics_f(void) +{ + return 0x0U; +} +static inline u32 top_device_info_type_enum_copy0_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_type_enum_copy0_f(void) +{ + return 0x4U; +} +static inline u32 top_device_info_type_enum_copy2_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_type_enum_copy2_f(void) +{ + return 0xcU; +} +static inline u32 top_device_info_type_enum_lce_v(void) +{ + return 0x00000013U; +} +static inline u32 top_device_info_type_enum_lce_f(void) +{ + return 0x4cU; +} +static inline u32 top_device_info_engine_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 top_device_info_runlist_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 top_device_info_intr_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 top_device_info_reset_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_entry_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 top_device_info_entry_not_valid_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_entry_enum_v(void) +{ + return 0x00000002U; +} +static inline u32 top_device_info_entry_engine_type_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_entry_data_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_data_type_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 top_device_info_data_type_enum2_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_data_inst_id_v(u32 r) +{ + return (r >> 26U) & 0xfU; +} +static inline u32 top_device_info_data_pri_base_v(u32 r) +{ + return (r >> 12U) & 0xfffU; +} +static inline u32 top_device_info_data_pri_base_align_v(void) +{ + return 0x0000000cU; +} +static inline u32 top_device_info_data_fault_id_enum_v(u32 r) +{ + return (r >> 3U) & 0x1fU; +} +static inline u32 top_device_info_data_fault_id_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_data_fault_id_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 top_scratch1_r(void) +{ + return 0x0002240cU; +} +static inline u32 top_scratch1_devinit_completed_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_trim_gp106.h b/include/nvgpu/hw/gp106/hw_trim_gp106.h new file mode 100644 index 0000000..cebb6d4 --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_trim_gp106.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_trim_gp106_h_ +#define _hw_trim_gp106_h_ + +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_r(void) +{ + return 0x00132924U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_noofipclks_s(void) +{ + return 16U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_noofipclks_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_noofipclks_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_noofipclks_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_write_en_s(void) +{ + return 1U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_write_en_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_write_en_m(void) +{ + return 0x1U << 16U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_write_en_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_write_en_deasserted_f(void) +{ + return 0x0U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_write_en_asserted_f(void) +{ + return 0x10000U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_enable_s(void) +{ + return 1U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_enable_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_enable_m(void) +{ + return 0x1U << 20U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_enable_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_enable_deasserted_f(void) +{ + return 0x0U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_enable_asserted_f(void) +{ + return 0x100000U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_reset_s(void) +{ + return 1U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_reset_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_reset_m(void) +{ + return 0x1U << 24U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_reset_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_reset_deasserted_f(void) +{ + return 0x0U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_reset_asserted_f(void) +{ + return 0x1000000U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cfg_source_gpc2clk_f(void) +{ + return 0x70000000U; +} +static inline u32 trim_gpc_bcast_clk_cntr_ncgpcclk_cnt_r(void) +{ + return 0x00132928U; +} +static inline u32 trim_fbpa_bcast_clk_cntr_ncltcclk_cfg_r(void) +{ + return 0x00132128U; +} +static inline u32 trim_fbpa_bcast_clk_cntr_ncltcclk_cfg_source_dramdiv4_rec_clk1_f(void) +{ + return 0x30000000U; +} +static inline u32 trim_fbpa_bcast_clk_cntr_ncltcclk_cnt_r(void) +{ + return 0x0013212cU; +} +static inline u32 trim_sys_clk_cntr_ncltcpll_cfg_r(void) +{ + return 0x001373c0U; +} +static inline u32 trim_sys_clk_cntr_ncltcpll_cfg_source_xbar2clk_f(void) +{ + return 0x20000000U; +} +static inline u32 trim_sys_clk_cntr_ncltcpll_cnt_r(void) +{ + return 0x001373c4U; +} +static inline u32 trim_sys_clk_cntr_ncsyspll_cfg_r(void) +{ + return 0x001373b0U; +} +static inline u32 trim_sys_clk_cntr_ncsyspll_cfg_source_sys2clk_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_clk_cntr_ncsyspll_cnt_r(void) +{ + return 0x001373b4U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_xp_gp106.h b/include/nvgpu/hw/gp106/hw_xp_gp106.h new file mode 100644 index 0000000..f6c843c --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_xp_gp106.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_xp_gp106_h_ +#define _hw_xp_gp106_h_ + +static inline u32 xp_dl_mgr_r(u32 i) +{ + return 0x0008b8c0U + i*4U; +} +static inline u32 xp_dl_mgr_safe_timing_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 xp_pl_link_config_r(u32 i) +{ + return 0x0008c040U + i*4U; +} +static inline u32 xp_pl_link_config_ltssm_status_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 xp_pl_link_config_ltssm_status_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 xp_pl_link_config_ltssm_directive_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 xp_pl_link_config_ltssm_directive_m(void) +{ + return 0xfU << 0U; +} +static inline u32 xp_pl_link_config_ltssm_directive_normal_operations_v(void) +{ + return 0x00000000U; +} +static inline u32 xp_pl_link_config_ltssm_directive_change_speed_v(void) +{ + return 0x00000001U; +} +static inline u32 xp_pl_link_config_max_link_rate_f(u32 v) +{ + return (v & 0x3U) << 18U; +} +static inline u32 xp_pl_link_config_max_link_rate_m(void) +{ + return 0x3U << 18U; +} +static inline u32 xp_pl_link_config_max_link_rate_2500_mtps_v(void) +{ + return 0x00000002U; +} +static inline u32 xp_pl_link_config_max_link_rate_5000_mtps_v(void) +{ + return 0x00000001U; +} +static inline u32 xp_pl_link_config_max_link_rate_8000_mtps_v(void) +{ + return 0x00000000U; +} +static inline u32 xp_pl_link_config_target_tx_width_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 xp_pl_link_config_target_tx_width_m(void) +{ + return 0x7U << 20U; +} +static inline u32 xp_pl_link_config_target_tx_width_x1_v(void) +{ + return 0x00000007U; +} +static inline u32 xp_pl_link_config_target_tx_width_x2_v(void) +{ + return 0x00000006U; +} +static inline u32 xp_pl_link_config_target_tx_width_x4_v(void) +{ + return 0x00000005U; +} +static inline u32 xp_pl_link_config_target_tx_width_x8_v(void) +{ + return 0x00000004U; +} +static inline u32 xp_pl_link_config_target_tx_width_x16_v(void) +{ + return 0x00000000U; +} +#endif diff --git a/include/nvgpu/hw/gp106/hw_xve_gp106.h b/include/nvgpu/hw/gp106/hw_xve_gp106.h new file mode 100644 index 0000000..e61d13f --- /dev/null +++ b/include/nvgpu/hw/gp106/hw_xve_gp106.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_xve_gp106_h_ +#define _hw_xve_gp106_h_ + +static inline u32 xve_rom_ctrl_r(void) +{ + return 0x00000050U; +} +static inline u32 xve_rom_ctrl_rom_shadow_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 xve_rom_ctrl_rom_shadow_disabled_f(void) +{ + return 0x0U; +} +static inline u32 xve_rom_ctrl_rom_shadow_enabled_f(void) +{ + return 0x1U; +} +static inline u32 xve_link_control_status_r(void) +{ + return 0x00000088U; +} +static inline u32 xve_link_control_status_link_speed_m(void) +{ + return 0xfU << 16U; +} +static inline u32 xve_link_control_status_link_speed_v(u32 r) +{ + return (r >> 16U) & 0xfU; +} +static inline u32 xve_link_control_status_link_speed_link_speed_2p5_v(void) +{ + return 0x00000001U; +} +static inline u32 xve_link_control_status_link_speed_link_speed_5p0_v(void) +{ + return 0x00000002U; +} +static inline u32 xve_link_control_status_link_speed_link_speed_8p0_v(void) +{ + return 0x00000003U; +} +static inline u32 xve_link_control_status_link_width_m(void) +{ + return 0x3fU << 20U; +} +static inline u32 xve_link_control_status_link_width_v(u32 r) +{ + return (r >> 20U) & 0x3fU; +} +static inline u32 xve_link_control_status_link_width_x1_v(void) +{ + return 0x00000001U; +} +static inline u32 xve_link_control_status_link_width_x2_v(void) +{ + return 0x00000002U; +} +static inline u32 xve_link_control_status_link_width_x4_v(void) +{ + return 0x00000004U; +} +static inline u32 xve_link_control_status_link_width_x8_v(void) +{ + return 0x00000008U; +} +static inline u32 xve_link_control_status_link_width_x16_v(void) +{ + return 0x00000010U; +} +static inline u32 xve_priv_xv_r(void) +{ + return 0x00000150U; +} +static inline u32 xve_priv_xv_cya_l0s_enable_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 xve_priv_xv_cya_l0s_enable_m(void) +{ + return 0x1U << 7U; +} +static inline u32 xve_priv_xv_cya_l0s_enable_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 xve_priv_xv_cya_l1_enable_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 xve_priv_xv_cya_l1_enable_m(void) +{ + return 0x1U << 8U; +} +static inline u32 xve_priv_xv_cya_l1_enable_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 xve_cya_2_r(void) +{ + return 0x00000704U; +} +static inline u32 xve_reset_r(void) +{ + return 0x00000718U; +} +static inline u32 xve_reset_reset_m(void) +{ + return 0x1U << 0U; +} +static inline u32 xve_reset_gpu_on_sw_reset_m(void) +{ + return 0x1U << 1U; +} +static inline u32 xve_reset_counter_en_m(void) +{ + return 0x1U << 2U; +} +static inline u32 xve_reset_counter_val_f(u32 v) +{ + return (v & 0x7ffU) << 4U; +} +static inline u32 xve_reset_counter_val_m(void) +{ + return 0x7ffU << 4U; +} +static inline u32 xve_reset_counter_val_v(u32 r) +{ + return (r >> 4U) & 0x7ffU; +} +static inline u32 xve_reset_clock_on_sw_reset_m(void) +{ + return 0x1U << 15U; +} +static inline u32 xve_reset_clock_counter_en_m(void) +{ + return 0x1U << 16U; +} +static inline u32 xve_reset_clock_counter_val_f(u32 v) +{ + return (v & 0x7ffU) << 17U; +} +static inline u32 xve_reset_clock_counter_val_m(void) +{ + return 0x7ffU << 17U; +} +static inline u32 xve_reset_clock_counter_val_v(u32 r) +{ + return (r >> 17U) & 0x7ffU; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_bus_gp10b.h b/include/nvgpu/hw/gp10b/hw_bus_gp10b.h new file mode 100644 index 0000000..b06ea66 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_bus_gp10b.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_bus_gp10b_h_ +#define _hw_bus_gp10b_h_ + +static inline u32 bus_bar0_window_r(void) +{ + return 0x00001700U; +} +static inline u32 bus_bar0_window_base_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 bus_bar0_window_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar0_window_target_sys_mem_coherent_f(void) +{ + return 0x2000000U; +} +static inline u32 bus_bar0_window_target_sys_mem_noncoherent_f(void) +{ + return 0x3000000U; +} +static inline u32 bus_bar0_window_target_bar0_window_base_shift_v(void) +{ + return 0x00000010U; +} +static inline u32 bus_bar1_block_r(void) +{ + return 0x00001704U; +} +static inline u32 bus_bar1_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar1_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar1_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar1_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar1_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar2_block_r(void) +{ + return 0x00001714U; +} +static inline u32 bus_bar2_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar2_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar2_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar2_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar2_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar1_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bar2_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bind_status_r(void) +{ + return 0x00001710U; +} +static inline u32 bus_bind_status_bar1_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 bus_bind_status_bar1_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar1_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 bus_bind_status_bar1_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 bus_bind_status_bar1_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar1_outstanding_true_f(void) +{ + return 0x2U; +} +static inline u32 bus_bind_status_bar2_pending_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 bus_bind_status_bar2_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar2_pending_busy_f(void) +{ + return 0x4U; +} +static inline u32 bus_bind_status_bar2_outstanding_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 bus_bind_status_bar2_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar2_outstanding_true_f(void) +{ + return 0x8U; +} +static inline u32 bus_intr_0_r(void) +{ + return 0x00001100U; +} +static inline u32 bus_intr_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +static inline u32 bus_intr_en_0_r(void) +{ + return 0x00001140U; +} +static inline u32 bus_intr_en_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_en_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_en_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_ccsr_gp10b.h b/include/nvgpu/hw/gp10b/hw_ccsr_gp10b.h new file mode 100644 index 0000000..00879c1 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_ccsr_gp10b.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ccsr_gp10b_h_ +#define _hw_ccsr_gp10b_h_ + +static inline u32 ccsr_channel_inst_r(u32 i) +{ + return 0x00800000U + i*8U; +} +static inline u32 ccsr_channel_inst__size_1_v(void) +{ + return 0x00000200U; +} +static inline u32 ccsr_channel_inst_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 ccsr_channel_inst_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 ccsr_channel_inst_bind_false_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_bind_true_f(void) +{ + return 0x80000000U; +} +static inline u32 ccsr_channel_r(u32 i) +{ + return 0x00800004U + i*8U; +} +static inline u32 ccsr_channel__size_1_v(void) +{ + return 0x00000200U; +} +static inline u32 ccsr_channel_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ccsr_channel_enable_set_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ccsr_channel_enable_set_true_f(void) +{ + return 0x400U; +} +static inline u32 ccsr_channel_enable_clr_true_f(void) +{ + return 0x800U; +} +static inline u32 ccsr_channel_status_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ccsr_channel_status_pending_ctx_reload_v(void) +{ + return 0x00000002U; +} +static inline u32 ccsr_channel_status_pending_acq_ctx_reload_v(void) +{ + return 0x00000004U; +} +static inline u32 ccsr_channel_status_on_pbdma_ctx_reload_v(void) +{ + return 0x0000000aU; +} +static inline u32 ccsr_channel_status_on_pbdma_and_eng_ctx_reload_v(void) +{ + return 0x0000000bU; +} +static inline u32 ccsr_channel_status_on_eng_ctx_reload_v(void) +{ + return 0x0000000cU; +} +static inline u32 ccsr_channel_status_on_eng_pending_ctx_reload_v(void) +{ + return 0x0000000dU; +} +static inline u32 ccsr_channel_status_on_eng_pending_acq_ctx_reload_v(void) +{ + return 0x0000000eU; +} +static inline u32 ccsr_channel_next_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ccsr_channel_next_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ccsr_channel_force_ctx_reload_true_f(void) +{ + return 0x100U; +} +static inline u32 ccsr_channel_busy_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_ce_gp10b.h b/include/nvgpu/hw/gp10b/hw_ce_gp10b.h new file mode 100644 index 0000000..c293771 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_ce_gp10b.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ce_gp10b_h_ +#define _hw_ce_gp10b_h_ + +static inline u32 ce_intr_status_r(u32 i) +{ + return 0x00104410U + i*128U; +} +static inline u32 ce_intr_status_blockpipe_pending_f(void) +{ + return 0x1U; +} +static inline u32 ce_intr_status_blockpipe_reset_f(void) +{ + return 0x1U; +} +static inline u32 ce_intr_status_nonblockpipe_pending_f(void) +{ + return 0x2U; +} +static inline u32 ce_intr_status_nonblockpipe_reset_f(void) +{ + return 0x2U; +} +static inline u32 ce_intr_status_launcherr_pending_f(void) +{ + return 0x4U; +} +static inline u32 ce_intr_status_launcherr_reset_f(void) +{ + return 0x4U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_ctxsw_prog_gp10b.h b/include/nvgpu/hw/gp10b/hw_ctxsw_prog_gp10b.h new file mode 100644 index 0000000..d83320f --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_ctxsw_prog_gp10b.h @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2014-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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ctxsw_prog_gp10b_h_ +#define _hw_ctxsw_prog_gp10b_h_ + +static inline u32 ctxsw_prog_fecs_header_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_main_image_num_gpcs_o(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_main_image_patch_count_o(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_main_image_context_id_o(void) +{ + return 0x000000f0U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_lo_o(void) +{ + return 0x00000014U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_hi_o(void) +{ + return 0x00000018U; +} +static inline u32 ctxsw_prog_main_image_zcull_o(void) +{ + return 0x0000001cU; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_no_ctxsw_v(void) +{ + return 0x00000001U; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_separate_buffer_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_zcull_ptr_o(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_main_image_pm_o(void) +{ + return 0x00000028U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_m(void) +{ + return 0x7U << 0U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_ctxsw_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_m(void) +{ + return 0x7U << 3U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_ctxsw_f(void) +{ + return 0x8U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_ptr_o(void) +{ + return 0x0000002cU; +} +static inline u32 ctxsw_prog_main_image_num_save_ops_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_main_image_num_wfi_save_ops_o(void) +{ + return 0x000000d0U; +} +static inline u32 ctxsw_prog_main_image_num_cta_save_ops_o(void) +{ + return 0x000000d4U; +} +static inline u32 ctxsw_prog_main_image_num_gfxp_save_ops_o(void) +{ + return 0x000000d8U; +} +static inline u32 ctxsw_prog_main_image_num_cilp_save_ops_o(void) +{ + return 0x000000dcU; +} +static inline u32 ctxsw_prog_main_image_num_restore_ops_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_main_image_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_main_image_magic_value_v_value_v(void) +{ + return 0x600dc0deU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_local_image_ppc_info_num_ppcs_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_ppc_mask_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_num_tpcs_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_local_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_local_magic_value_v_value_v(void) +{ + return 0xad0becabU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_o(void) +{ + return 0x000000ecU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_size_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 ctxsw_prog_extended_buffer_segments_size_in_bytes_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_extended_marker_size_in_bytes_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_register_stride_v(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_control_register_stride_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_o(void) +{ + return 0x000000a0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_s(void) +{ + return 2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_m(void) +{ + return 0x3U << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_allow_all_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_use_map_f(void) +{ + return 0x2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_lo_o(void) +{ + return 0x000000a4U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_hi_o(void) +{ + return 0x000000a8U; +} +static inline u32 ctxsw_prog_main_image_misc_options_o(void) +{ + return 0x0000003cU; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_disabled_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pmu_options_o(void) +{ + return 0x00000070U; +} +static inline u32 ctxsw_prog_main_image_pmu_options_boost_clock_frequencies_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_o(void) +{ + return 0x00000080U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_control_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_control_gfxp_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_o(void) +{ + return 0x00000068U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_o(void) +{ + return 0x00000084U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_cta_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_cilp_f(void) +{ + return 0x2U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_control_o(void) +{ + return 0x000000acU; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_control_num_records_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_o(void) +{ + return 0x000000b0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_v_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_sys_mem_coherent_f(void) +{ + return 0x20000000U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_target_sys_mem_noncoherent_f(void) +{ + return 0x30000000U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_o(void) +{ + return 0x000000b4U; +} +static inline u32 ctxsw_prog_main_image_context_timestamp_buffer_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_record_timestamp_record_size_in_bytes_v(void) +{ + return 0x00000080U; +} +static inline u32 ctxsw_prog_record_timestamp_record_size_in_words_v(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_lo_o(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_lo_v_value_v(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_hi_o(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_record_timestamp_magic_value_hi_v_value_v(void) +{ + return 0x600dbeefU; +} +static inline u32 ctxsw_prog_record_timestamp_context_id_o(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_record_timestamp_context_ptr_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_lo_o(void) +{ + return 0x00000018U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_o(void) +{ + return 0x0000001cU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_v_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_v_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_m(void) +{ + return 0xffU << 24U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_v(u32 r) +{ + return (r >> 24U) & 0xffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_ctxsw_req_by_host_v(void) +{ + return 0x00000001U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_ctxsw_req_by_host_f(void) +{ + return 0x1000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_f(void) +{ + return 0x2000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_wfi_v(void) +{ + return 0x0000000aU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_wfi_f(void) +{ + return 0xa000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_gfxp_v(void) +{ + return 0x0000000bU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_gfxp_f(void) +{ + return 0xb000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_ctap_v(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_ctap_f(void) +{ + return 0xc000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_cilp_v(void) +{ + return 0x0000000dU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_fe_ack_cilp_f(void) +{ + return 0xd000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_save_end_v(void) +{ + return 0x00000003U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_save_end_f(void) +{ + return 0x3000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_restore_start_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_restore_start_f(void) +{ + return 0x4000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_context_start_v(void) +{ + return 0x00000005U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_context_start_f(void) +{ + return 0x5000000U; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_invalid_timestamp_v(void) +{ + return 0x000000ffU; +} +static inline u32 ctxsw_prog_record_timestamp_timestamp_hi_tag_invalid_timestamp_f(void) +{ + return 0xff000000U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_falcon_gp10b.h b/include/nvgpu/hw/gp10b/hw_falcon_gp10b.h new file mode 100644 index 0000000..6dc401d --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_falcon_gp10b.h @@ -0,0 +1,603 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_falcon_gp10b_h_ +#define _hw_falcon_gp10b_h_ + +static inline u32 falcon_falcon_irqsset_r(void) +{ + return 0x00000000U; +} +static inline u32 falcon_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqsclr_r(void) +{ + return 0x00000004U; +} +static inline u32 falcon_falcon_irqstat_r(void) +{ + return 0x00000008U; +} +static inline u32 falcon_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 falcon_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 falcon_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqmode_r(void) +{ + return 0x0000000cU; +} +static inline u32 falcon_falcon_irqmset_r(void) +{ + return 0x00000010U; +} +static inline u32 falcon_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_r(void) +{ + return 0x00000014U; +} +static inline u32 falcon_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqmask_r(void) +{ + return 0x00000018U; +} +static inline u32 falcon_falcon_irqdest_r(void) +{ + return 0x0000001cU; +} +static inline u32 falcon_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 falcon_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 falcon_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 falcon_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 falcon_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 falcon_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 falcon_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 falcon_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 falcon_falcon_curctx_r(void) +{ + return 0x00000050U; +} +static inline u32 falcon_falcon_nxtctx_r(void) +{ + return 0x00000054U; +} +static inline u32 falcon_falcon_mailbox0_r(void) +{ + return 0x00000040U; +} +static inline u32 falcon_falcon_mailbox1_r(void) +{ + return 0x00000044U; +} +static inline u32 falcon_falcon_itfen_r(void) +{ + return 0x00000048U; +} +static inline u32 falcon_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 falcon_falcon_idlestate_r(void) +{ + return 0x0000004cU; +} +static inline u32 falcon_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 falcon_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 falcon_falcon_os_r(void) +{ + return 0x00000080U; +} +static inline u32 falcon_falcon_engctl_r(void) +{ + return 0x000000a4U; +} +static inline u32 falcon_falcon_cpuctl_r(void) +{ + return 0x00000100U; +} +static inline u32 falcon_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_cpuctl_sreset_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_cpuctl_hreset_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_stopped_m(void) +{ + return 0x1U << 5U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_alias_r(void) +{ + return 0x00000130U; +} +static inline u32 falcon_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_imemc_r(u32 i) +{ + return 0x00000180U + i*16U; +} +static inline u32 falcon_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_imemc_secure_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 falcon_falcon_imemd_r(u32 i) +{ + return 0x00000184U + i*16U; +} +static inline u32 falcon_falcon_imemt_r(u32 i) +{ + return 0x00000188U + i*16U; +} +static inline u32 falcon_falcon_sctl_r(void) +{ + return 0x00000240U; +} +static inline u32 falcon_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 falcon_falcon_bootvec_r(void) +{ + return 0x00000104U; +} +static inline u32 falcon_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 falcon_falcon_dmactl_r(void) +{ + return 0x0000010cU; +} +static inline u32 falcon_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 falcon_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 falcon_falcon_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_hwcfg_r(void) +{ + return 0x00000108U; +} +static inline u32 falcon_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 falcon_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 falcon_falcon_dmatrfbase_r(void) +{ + return 0x00000110U; +} +static inline u32 falcon_falcon_dmatrfbase1_r(void) +{ + return 0x00000128U; +} +static inline u32 falcon_falcon_dmatrfmoffs_r(void) +{ + return 0x00000114U; +} +static inline u32 falcon_falcon_imctl_debug_r(void) +{ + return 0x0000015cU; +} +static inline u32 falcon_falcon_imctl_debug_addr_blk_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 falcon_falcon_imctl_debug_cmd_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 falcon_falcon_imstat_r(void) +{ + return 0x00000144U; +} +static inline u32 falcon_falcon_traceidx_r(void) +{ + return 0x00000148U; +} +static inline u32 falcon_falcon_traceidx_maxidx_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 falcon_falcon_traceidx_idx_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 falcon_falcon_tracepc_r(void) +{ + return 0x0000014cU; +} +static inline u32 falcon_falcon_tracepc_pc_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 falcon_falcon_dmatrfcmd_r(void) +{ + return 0x00000118U; +} +static inline u32 falcon_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 falcon_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 falcon_falcon_dmatrffboffs_r(void) +{ + return 0x0000011cU; +} +static inline u32 falcon_falcon_exterraddr_r(void) +{ + return 0x00000168U; +} +static inline u32 falcon_falcon_exterrstat_r(void) +{ + return 0x0000016cU; +} +static inline u32 falcon_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 falcon_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 falcon_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 falcon_falcon_icd_cmd_r(void) +{ + return 0x00000200U; +} +static inline u32 falcon_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 falcon_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 falcon_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 falcon_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 falcon_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 falcon_falcon_icd_rdata_r(void) +{ + return 0x0000020cU; +} +static inline u32 falcon_falcon_dmemc_r(u32 i) +{ + return 0x000001c0U + i*8U; +} +static inline u32 falcon_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 falcon_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 falcon_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 falcon_falcon_dmemd_r(u32 i) +{ + return 0x000001c4U + i*8U; +} +static inline u32 falcon_falcon_debug1_r(void) +{ + return 0x00000090U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_s(void) +{ + return 1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_m(void) +{ + return 0x1U << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_init_f(void) +{ + return 0x0U; +} +static inline u32 falcon_falcon_debuginfo_r(void) +{ + return 0x00000094U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_fb_gp10b.h b/include/nvgpu/hw/gp10b/hw_fb_gp10b.h new file mode 100644 index 0000000..c1ef471 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_fb_gp10b.h @@ -0,0 +1,463 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fb_gp10b_h_ +#define _hw_fb_gp10b_h_ + +static inline u32 fb_fbhub_num_active_ltcs_r(void) +{ + return 0x00100800U; +} +static inline u32 fb_mmu_ctrl_r(void) +{ + return 0x00100c80U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_space_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 fb_priv_mmu_phy_secure_r(void) +{ + return 0x00100ce4U; +} +static inline u32 fb_mmu_invalidate_pdb_r(void) +{ + return 0x00100cb8U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_sys_mem_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_pdb_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_invalidate_r(void) +{ + return 0x00100cbcU; +} +static inline u32 fb_mmu_invalidate_all_va_true_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_invalidate_all_pdb_true_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_m(void) +{ + return 0x1U << 2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_true_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_invalidate_replay_s(void) +{ + return 3U; +} +static inline u32 fb_mmu_invalidate_replay_f(u32 v) +{ + return (v & 0x7U) << 3U; +} +static inline u32 fb_mmu_invalidate_replay_m(void) +{ + return 0x7U << 3U; +} +static inline u32 fb_mmu_invalidate_replay_v(u32 r) +{ + return (r >> 3U) & 0x7U; +} +static inline u32 fb_mmu_invalidate_replay_none_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_replay_start_f(void) +{ + return 0x8U; +} +static inline u32 fb_mmu_invalidate_replay_start_ack_all_f(void) +{ + return 0x10U; +} +static inline u32 fb_mmu_invalidate_replay_cancel_targeted_f(void) +{ + return 0x18U; +} +static inline u32 fb_mmu_invalidate_replay_cancel_global_f(void) +{ + return 0x20U; +} +static inline u32 fb_mmu_invalidate_replay_cancel_f(void) +{ + return 0x20U; +} +static inline u32 fb_mmu_invalidate_sys_membar_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_sys_membar_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 fb_mmu_invalidate_sys_membar_m(void) +{ + return 0x1U << 6U; +} +static inline u32 fb_mmu_invalidate_sys_membar_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_sys_membar_true_f(void) +{ + return 0x40U; +} +static inline u32 fb_mmu_invalidate_ack_s(void) +{ + return 2U; +} +static inline u32 fb_mmu_invalidate_ack_f(u32 v) +{ + return (v & 0x3U) << 7U; +} +static inline u32 fb_mmu_invalidate_ack_m(void) +{ + return 0x3U << 7U; +} +static inline u32 fb_mmu_invalidate_ack_v(u32 r) +{ + return (r >> 7U) & 0x3U; +} +static inline u32 fb_mmu_invalidate_ack_ack_none_required_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_ack_ack_intranode_f(void) +{ + return 0x100U; +} +static inline u32 fb_mmu_invalidate_ack_ack_globally_f(void) +{ + return 0x80U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_s(void) +{ + return 6U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_f(u32 v) +{ + return (v & 0x3fU) << 9U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_m(void) +{ + return 0x3fU << 9U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_v(u32 r) +{ + return (r >> 9U) & 0x3fU; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_s(void) +{ + return 5U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_f(u32 v) +{ + return (v & 0x1fU) << 15U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_m(void) +{ + return 0x1fU << 15U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_v(u32 r) +{ + return (r >> 15U) & 0x1fU; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_m(void) +{ + return 0x1U << 20U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_gpc_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_hub_f(void) +{ + return 0x100000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_s(void) +{ + return 3U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_m(void) +{ + return 0x7U << 24U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_v(u32 r) +{ + return (r >> 24U) & 0x7U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_all_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_pte_only_f(void) +{ + return 0x1000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde0_f(void) +{ + return 0x2000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde1_f(void) +{ + return 0x3000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde2_f(void) +{ + return 0x4000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde3_f(void) +{ + return 0x5000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde4_f(void) +{ + return 0x6000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde5_f(void) +{ + return 0x7000000U; +} +static inline u32 fb_mmu_invalidate_trigger_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_trigger_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_trigger_true_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_debug_wr_r(void) +{ + return 0x00100cc8U; +} +static inline u32 fb_mmu_debug_wr_aperture_s(void) +{ + return 2U; +} +static inline u32 fb_mmu_debug_wr_aperture_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_m(void) +{ + return 0x3U << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fb_mmu_debug_wr_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_wr_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_vol_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_wr_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_debug_wr_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_wr_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_rd_r(void) +{ + return 0x00100cccU; +} +static inline u32 fb_mmu_debug_rd_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_rd_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_rd_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_ctrl_r(void) +{ + return 0x00100cc4U; +} +static inline u32 fb_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 fb_mmu_debug_ctrl_debug_m(void) +{ + return 0x1U << 16U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_vpr_info_r(void) +{ + return 0x00100cd0U; +} +static inline u32 fb_mmu_vpr_info_fetch_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 fb_mmu_vpr_info_fetch_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_vpr_info_fetch_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_niso_flush_sysmem_addr_r(void) +{ + return 0x00100c10U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_fifo_gp10b.h b/include/nvgpu/hw/gp10b/hw_fifo_gp10b.h new file mode 100644 index 0000000..7170162 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_fifo_gp10b.h @@ -0,0 +1,699 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fifo_gp10b_h_ +#define _hw_fifo_gp10b_h_ + +static inline u32 fifo_bar1_base_r(void) +{ + return 0x00002254U; +} +static inline u32 fifo_bar1_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_bar1_base_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_bar1_base_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 fifo_bar1_base_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_runlist_base_r(void) +{ + return 0x00002270U; +} +static inline u32 fifo_runlist_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_runlist_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fifo_runlist_base_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_runlist_base_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 fifo_runlist_r(void) +{ + return 0x00002274U; +} +static inline u32 fifo_runlist_engine_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 fifo_eng_runlist_base_r(u32 i) +{ + return 0x00002280U + i*8U; +} +static inline u32 fifo_eng_runlist_base__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_eng_runlist_r(u32 i) +{ + return 0x00002284U + i*8U; +} +static inline u32 fifo_eng_runlist__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_eng_runlist_length_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fifo_eng_runlist_length_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 fifo_eng_runlist_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_pb_timeslice_r(u32 i) +{ + return 0x00002350U + i*4U; +} +static inline u32 fifo_pb_timeslice_timeout_16_f(void) +{ + return 0x10U; +} +static inline u32 fifo_pb_timeslice_timescale_0_f(void) +{ + return 0x0U; +} +static inline u32 fifo_pb_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_pbdma_map_r(u32 i) +{ + return 0x00002390U + i*4U; +} +static inline u32 fifo_intr_0_r(void) +{ + return 0x00002100U; +} +static inline u32 fifo_intr_0_bind_error_pending_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_bind_error_reset_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_sched_error_pending_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_sched_error_reset_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_chsw_error_pending_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_chsw_error_reset_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_fb_flush_timeout_pending_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_fb_flush_timeout_reset_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_lb_error_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_lb_error_reset_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_replayable_fault_error_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 fifo_intr_0_dropped_mmu_fault_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 fifo_intr_0_dropped_mmu_fault_reset_f(void) +{ + return 0x8000000U; +} +static inline u32 fifo_intr_0_mmu_fault_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_intr_0_pbdma_intr_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_intr_0_runlist_event_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 fifo_intr_0_channel_intr_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_intr_en_0_r(void) +{ + return 0x00002140U; +} +static inline u32 fifo_intr_en_0_sched_error_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_intr_en_0_sched_error_m(void) +{ + return 0x1U << 8U; +} +static inline u32 fifo_intr_en_0_mmu_fault_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 fifo_intr_en_0_mmu_fault_m(void) +{ + return 0x1U << 28U; +} +static inline u32 fifo_intr_en_1_r(void) +{ + return 0x00002528U; +} +static inline u32 fifo_intr_bind_error_r(void) +{ + return 0x0000252cU; +} +static inline u32 fifo_intr_sched_error_r(void) +{ + return 0x0000254cU; +} +static inline u32 fifo_intr_sched_error_code_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fifo_intr_sched_error_code_ctxsw_timeout_v(void) +{ + return 0x0000000aU; +} +static inline u32 fifo_intr_chsw_error_r(void) +{ + return 0x0000256cU; +} +static inline u32 fifo_intr_mmu_fault_id_r(void) +{ + return 0x0000259cU; +} +static inline u32 fifo_intr_mmu_fault_eng_id_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_intr_mmu_fault_eng_id_graphics_f(void) +{ + return 0x0U; +} +static inline u32 fifo_intr_mmu_fault_inst_r(u32 i) +{ + return 0x00002800U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_inst_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 fifo_intr_mmu_fault_inst_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_intr_mmu_fault_lo_r(u32 i) +{ + return 0x00002804U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_hi_r(u32 i) +{ + return 0x00002808U + i*16U; +} +static inline u32 fifo_intr_mmu_fault_info_r(u32 i) +{ + return 0x0000280cU + i*16U; +} +static inline u32 fifo_intr_mmu_fault_info_type_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 fifo_intr_mmu_fault_info_access_type_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 fifo_intr_mmu_fault_info_client_type_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 fifo_intr_mmu_fault_info_client_type_gpc_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_intr_mmu_fault_info_client_type_hub_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_mmu_fault_info_client_v(u32 r) +{ + return (r >> 8U) & 0x7fU; +} +static inline u32 fifo_intr_pbdma_id_r(void) +{ + return 0x000025a0U; +} +static inline u32 fifo_intr_pbdma_id_status_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_intr_pbdma_id_status_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fifo_intr_pbdma_id_status__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_runlist_r(void) +{ + return 0x00002a00U; +} +static inline u32 fifo_fb_timeout_r(void) +{ + return 0x00002a04U; +} +static inline u32 fifo_fb_timeout_period_m(void) +{ + return 0x3fffffffU << 0U; +} +static inline u32 fifo_fb_timeout_period_max_f(void) +{ + return 0x3fffffffU; +} +static inline u32 fifo_error_sched_disable_r(void) +{ + return 0x0000262cU; +} +static inline u32 fifo_sched_disable_r(void) +{ + return 0x00002630U; +} +static inline u32 fifo_sched_disable_runlist_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_sched_disable_runlist_m(u32 i) +{ + return 0x1U << (0U + i*1U); +} +static inline u32 fifo_sched_disable_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_preempt_r(void) +{ + return 0x00002634U; +} +static inline u32 fifo_preempt_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_preempt_type_channel_f(void) +{ + return 0x0U; +} +static inline u32 fifo_preempt_type_tsg_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_preempt_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_preempt_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_trigger_mmu_fault_r(u32 i) +{ + return 0x00002a30U + i*4U; +} +static inline u32 fifo_trigger_mmu_fault_id_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 fifo_trigger_mmu_fault_enable_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_engine_status_r(u32 i) +{ + return 0x00002640U + i*8U; +} +static inline u32 fifo_engine_status__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fifo_engine_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_engine_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_engine_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_engine_status_ctx_status_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_ctx_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_engine_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_engine_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_engine_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_faulted_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fifo_engine_status_faulted_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_engine_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fifo_engine_status_engine_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_engine_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_f(void) +{ + return 0x8000U; +} +static inline u32 fifo_pbdma_status_r(u32 i) +{ + return 0x00003080U + i*4U; +} +static inline u32 fifo_pbdma_status__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_pbdma_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_pbdma_status_chan_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_pbdma_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_pbdma_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_chsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_pbdma_status_chsw_in_progress_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_lo_r(void) +{ + return 0x00002a70U; +} +static inline u32 fifo_replay_fault_buffer_lo_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 fifo_replay_fault_buffer_lo_enable_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_lo_enable_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_lo_base_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 fifo_replay_fault_buffer_lo_base_reset_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_hi_r(void) +{ + return 0x00002a74U; +} +static inline u32 fifo_replay_fault_buffer_hi_base_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fifo_replay_fault_buffer_hi_base_reset_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_size_r(void) +{ + return 0x00002a78U; +} +static inline u32 fifo_replay_fault_buffer_size_hw_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 fifo_replay_fault_buffer_size_hw_entries_v(void) +{ + return 0x000000c0U; +} +static inline u32 fifo_replay_fault_buffer_get_r(void) +{ + return 0x00002a7cU; +} +static inline u32 fifo_replay_fault_buffer_get_offset_hw_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 fifo_replay_fault_buffer_get_offset_hw_init_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_put_r(void) +{ + return 0x00002a80U; +} +static inline u32 fifo_replay_fault_buffer_put_offset_hw_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 fifo_replay_fault_buffer_put_offset_hw_init_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_info_r(void) +{ + return 0x00002a84U; +} +static inline u32 fifo_replay_fault_buffer_info_overflow_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fifo_replay_fault_buffer_info_overflow_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_info_overflow_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_info_overflow_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_info_write_nack_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 fifo_replay_fault_buffer_info_write_nack_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_info_write_nack_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_info_write_nack_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_info_fault_while_buffer_disabled_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 fifo_replay_fault_buffer_info_fault_while_buffer_disabled_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_replay_fault_buffer_info_fault_while_buffer_disabled_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_replay_fault_buffer_info_fault_while_buffer_disabled_clear_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_flush_gp10b.h b/include/nvgpu/hw/gp10b/hw_flush_gp10b.h new file mode 100644 index 0000000..ae6eabf --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_flush_gp10b.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_flush_gp10b_h_ +#define _hw_flush_gp10b_h_ + +static inline u32 flush_l2_system_invalidate_r(void) +{ + return 0x00070004U; +} +static inline u32 flush_l2_system_invalidate_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_r(void) +{ + return 0x00070010U; +} +static inline u32 flush_l2_flush_dirty_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_r(void) +{ + return 0x0007000cU; +} +static inline u32 flush_l2_clean_comptags_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_r(void) +{ + return 0x00070000U; +} +static inline u32 flush_fb_flush_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_fb_flush_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_fb_flush_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_fb_flush_outstanding_true_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_fuse_gp10b.h b/include/nvgpu/hw/gp10b/hw_fuse_gp10b.h new file mode 100644 index 0000000..521dcfe --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_fuse_gp10b.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fuse_gp10b_h_ +#define _hw_fuse_gp10b_h_ + +static inline u32 fuse_status_opt_gpc_r(void) +{ + return 0x00021c1cU; +} +static inline u32 fuse_status_opt_tpc_gpc_r(u32 i) +{ + return 0x00021c38U + i*4U; +} +static inline u32 fuse_ctrl_opt_tpc_gpc_r(u32 i) +{ + return 0x00021838U + i*4U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_r(void) +{ + return 0x00021944U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_m(void) +{ + return 0xffU << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_r(void) +{ + return 0x00021948U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_yes_f(void) +{ + return 0x1U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_no_f(void) +{ + return 0x0U; +} +static inline u32 fuse_status_opt_fbio_r(void) +{ + return 0x00021c14U; +} +static inline u32 fuse_status_opt_fbio_data_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fuse_status_opt_fbio_data_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fuse_status_opt_fbio_data_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fuse_status_opt_rop_l2_fbp_r(u32 i) +{ + return 0x00021d70U + i*4U; +} +static inline u32 fuse_status_opt_fbp_r(void) +{ + return 0x00021d38U; +} +static inline u32 fuse_status_opt_fbp_idx_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fuse_opt_ecc_en_r(void) +{ + return 0x00021228U; +} +static inline u32 fuse_opt_feature_fuses_override_disable_r(void) +{ + return 0x000213f0U; +} +static inline u32 fuse_opt_sec_debug_en_r(void) +{ + return 0x00021218U; +} +static inline u32 fuse_opt_priv_sec_en_r(void) +{ + return 0x00021434U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_gmmu_gp10b.h b/include/nvgpu/hw/gp10b/hw_gmmu_gp10b.h new file mode 100644 index 0000000..6aeb435 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_gmmu_gp10b.h @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2014-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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gmmu_gp10b_h_ +#define _hw_gmmu_gp10b_h_ + +static inline u32 gmmu_new_pde_is_pte_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_is_pte_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_aperture_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_aperture_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_aperture_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_pde_aperture_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_pde_aperture_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_pde_address_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pde_address_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_vol_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_vol_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_pde_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_new_pde__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_dual_pde_is_pte_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_is_pte_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_dual_pde_address_big_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_new_dual_pde_address_big_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_dual_pde_vol_small_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_vol_small_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_dual_pde_vol_small_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_vol_big_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_vol_big_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_dual_pde_vol_big_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_address_small_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_dual_pde_address_small_sys_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_new_dual_pde_address_big_shift_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_dual_pde__size_v(void) +{ + return 0x00000010U; +} +static inline u32 gmmu_new_pte__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_pte_valid_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_valid_true_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_new_pte_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_privilege_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_privilege_true_f(void) +{ + return 0x20U; +} +static inline u32 gmmu_new_pte_privilege_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_address_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pte_address_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_address_vid_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pte_address_vid_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_vol_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_vol_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_pte_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_aperture_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_aperture_video_memory_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_aperture_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_pte_aperture_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_pte_read_only_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_read_only_true_f(void) +{ + return 0x40U; +} +static inline u32 gmmu_new_pte_comptagline_f(u32 v) +{ + return (v & 0x3ffffU) << 4U; +} +static inline u32 gmmu_new_pte_comptagline_w(void) +{ + return 1U; +} +static inline u32 gmmu_new_pte_kind_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gmmu_new_pte_kind_w(void) +{ + return 1U; +} +static inline u32 gmmu_new_pte_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_pte_kind_f(u32 v) +{ + return (v & 0xffU) << 4U; +} +static inline u32 gmmu_pte_kind_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_kind_invalid_v(void) +{ + return 0x000000ffU; +} +static inline u32 gmmu_pte_kind_pitch_v(void) +{ + return 0x00000000U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_gr_gp10b.h b/include/nvgpu/hw/gp10b/hw_gr_gp10b.h new file mode 100644 index 0000000..f7bc4c2 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_gr_gp10b.h @@ -0,0 +1,4415 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gr_gp10b_h_ +#define _hw_gr_gp10b_h_ + +static inline u32 gr_intr_r(void) +{ + return 0x00400100U; +} +static inline u32 gr_intr_notify_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_notify_reset_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_semaphore_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_semaphore_reset_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_illegal_method_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_method_reset_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_notify_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_illegal_notify_reset_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 gr_intr_firmware_method_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_firmware_method_reset_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_illegal_class_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_illegal_class_reset_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_fecs_error_pending_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_fecs_error_reset_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_class_error_pending_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_class_error_reset_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_exception_pending_f(void) +{ + return 0x200000U; +} +static inline u32 gr_intr_exception_reset_f(void) +{ + return 0x200000U; +} +static inline u32 gr_fecs_intr_r(void) +{ + return 0x00400144U; +} +static inline u32 gr_class_error_r(void) +{ + return 0x00400110U; +} +static inline u32 gr_class_error_code_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_intr_nonstall_r(void) +{ + return 0x00400120U; +} +static inline u32 gr_intr_nonstall_trap_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_en_r(void) +{ + return 0x0040013cU; +} +static inline u32 gr_exception_r(void) +{ + return 0x00400108U; +} +static inline u32 gr_exception_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception_gpc_m(void) +{ + return 0x1U << 24U; +} +static inline u32 gr_exception_memfmt_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_exception_ds_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_exception_sked_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_exception_pd_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_exception_scc_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_exception_ssync_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_exception_mme_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_exception1_r(void) +{ + return 0x00400118U; +} +static inline u32 gr_exception1_gpc_0_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_exception2_r(void) +{ + return 0x0040011cU; +} +static inline u32 gr_exception_en_r(void) +{ + return 0x00400138U; +} +static inline u32 gr_exception_en_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception1_en_r(void) +{ + return 0x00400130U; +} +static inline u32 gr_exception2_en_r(void) +{ + return 0x00400134U; +} +static inline u32 gr_gpfifo_ctl_r(void) +{ + return 0x00400500U; +} +static inline u32 gr_gpfifo_ctl_access_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpfifo_ctl_access_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpfifo_ctl_access_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpfifo_status_r(void) +{ + return 0x00400504U; +} +static inline u32 gr_trapped_addr_r(void) +{ + return 0x00400704U; +} +static inline u32 gr_trapped_addr_mthd_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 gr_trapped_addr_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 gr_trapped_addr_mme_generated_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 gr_trapped_addr_datahigh_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 gr_trapped_addr_priv_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 gr_trapped_addr_status_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_trapped_data_lo_r(void) +{ + return 0x00400708U; +} +static inline u32 gr_trapped_data_hi_r(void) +{ + return 0x0040070cU; +} +static inline u32 gr_trapped_data_mme_r(void) +{ + return 0x00400710U; +} +static inline u32 gr_trapped_data_mme_pc_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_status_r(void) +{ + return 0x00400700U; +} +static inline u32 gr_status_fe_method_upper_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_status_fe_gi_v(u32 r) +{ + return (r >> 21U) & 0x1U; +} +static inline u32 gr_status_mask_r(void) +{ + return 0x00400610U; +} +static inline u32 gr_status_1_r(void) +{ + return 0x00400604U; +} +static inline u32 gr_status_2_r(void) +{ + return 0x00400608U; +} +static inline u32 gr_engine_status_r(void) +{ + return 0x0040060cU; +} +static inline u32 gr_engine_status_value_busy_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_be0_becs_be_exception_r(void) +{ + return 0x00410204U; +} +static inline u32 gr_pri_be0_becs_be_exception_en_r(void) +{ + return 0x00410208U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_en_r(void) +{ + return 0x00502c94U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_activity_0_r(void) +{ + return 0x00400380U; +} +static inline u32 gr_activity_1_r(void) +{ + return 0x00400384U; +} +static inline u32 gr_activity_2_r(void) +{ + return 0x00400388U; +} +static inline u32 gr_activity_4_r(void) +{ + return 0x00400390U; +} +static inline u32 gr_activity_4_gpc0_s(void) +{ + return 3U; +} +static inline u32 gr_activity_4_gpc0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_activity_4_gpc0_m(void) +{ + return 0x7U << 0U; +} +static inline u32 gr_activity_4_gpc0_v(u32 r) +{ + return (r >> 0U) & 0x7U; +} +static inline u32 gr_activity_4_gpc0_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_activity_4_gpc0_preempted_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_pri_gpc0_gcc_dbg_r(void) +{ + return 0x00501000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_r(void) +{ + return 0x00419000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_invalidate_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cache_control_r(void) +{ + return 0x005046a4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_r(void) +{ + return 0x00419ea4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_invalidate_cache_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_sked_activity_r(void) +{ + return 0x00407054U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity0_r(void) +{ + return 0x00502c80U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity1_r(void) +{ + return 0x00502c84U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity2_r(void) +{ + return 0x00502c88U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity3_r(void) +{ + return 0x00502c8cU; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x00504500U; +} +static inline u32 gr_pri_gpc0_tpc1_tpccs_tpc_activity_0_r(void) +{ + return 0x00504d00U; +} +static inline u32 gr_pri_gpc0_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00501d00U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_0_r(void) +{ + return 0x0041ac80U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_1_r(void) +{ + return 0x0041ac84U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_2_r(void) +{ + return 0x0041ac88U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_3_r(void) +{ + return 0x0041ac8cU; +} +static inline u32 gr_pri_gpcs_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x0041c500U; +} +static inline u32 gr_pri_gpcs_tpc1_tpccs_tpc_activity_0_r(void) +{ + return 0x0041cd00U; +} +static inline u32 gr_pri_gpcs_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00419d00U; +} +static inline u32 gr_pri_be0_becs_be_activity0_r(void) +{ + return 0x00410200U; +} +static inline u32 gr_pri_be1_becs_be_activity0_r(void) +{ + return 0x00410600U; +} +static inline u32 gr_pri_bes_becs_be_activity0_r(void) +{ + return 0x00408a00U; +} +static inline u32 gr_pri_ds_mpipe_status_r(void) +{ + return 0x00405858U; +} +static inline u32 gr_pri_fe_go_idle_info_r(void) +{ + return 0x00404194U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_tex_subunits_status_r(void) +{ + return 0x00504238U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_r(void) +{ + return 0x005046b8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp0_b(void) +{ + return 4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp0_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp1_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp2_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp3_pending_f(void) +{ + return 0x80U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp0_b(void) +{ + return 8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp0_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp1_pending_f(void) +{ + return 0x200U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp2_pending_f(void) +{ + return 0x400U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp3_pending_f(void) +{ + return 0x800U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_r(void) +{ + return 0x005044a0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_corrected_shm0_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_corrected_shm1_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_detected_shm0_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_detected_shm1_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_double_err_detected_shm0_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_status_double_err_detected_shm1_pending_f(void) +{ + return 0x200U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_single_err_count_r(void) +{ + return 0x005046bcU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_double_err_count_r(void) +{ + return 0x005046c0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_r(void) +{ + return 0x005044a4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_corrected_m(void) +{ + return 0xffU << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_corrected_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_detected_m(void) +{ + return 0xffU << 8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_detected_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_double_detected_m(void) +{ + return 0xffU << 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_double_detected_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_r(void) +{ + return 0x005042c4U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_default_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe0_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe1_f(void) +{ + return 0x2U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r(void) +{ + return 0x00504218U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r(void) +{ + return 0x005042ecU; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 gr_pri_be0_crop_status1_r(void) +{ + return 0x00410134U; +} +static inline u32 gr_pri_bes_crop_status1_r(void) +{ + return 0x00408934U; +} +static inline u32 gr_pri_be0_zrop_status_r(void) +{ + return 0x00410048U; +} +static inline u32 gr_pri_be0_zrop_status2_r(void) +{ + return 0x0041004cU; +} +static inline u32 gr_pri_bes_zrop_status_r(void) +{ + return 0x00408848U; +} +static inline u32 gr_pri_bes_zrop_status2_r(void) +{ + return 0x0040884cU; +} +static inline u32 gr_pipe_bundle_address_r(void) +{ + return 0x00400200U; +} +static inline u32 gr_pipe_bundle_address_value_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pipe_bundle_data_r(void) +{ + return 0x00400204U; +} +static inline u32 gr_pipe_bundle_config_r(void) +{ + return 0x00400208U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_r(void) +{ + return 0x00404000U; +} +static inline u32 gr_fe_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_fe_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_info_r(void) +{ + return 0x004041b0U; +} +static inline u32 gr_fe_go_idle_timeout_r(void) +{ + return 0x00404154U; +} +static inline u32 gr_fe_go_idle_timeout_count_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fe_go_idle_timeout_count_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_go_idle_timeout_count_prod_f(void) +{ + return 0x7fffffffU; +} +static inline u32 gr_fe_object_table_r(u32 i) +{ + return 0x00404200U + i*4U; +} +static inline u32 gr_fe_object_table_nvclass_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_fe_tpc_fs_r(void) +{ + return 0x004041c4U; +} +static inline u32 gr_pri_mme_shadow_raw_index_r(void) +{ + return 0x00404488U; +} +static inline u32 gr_pri_mme_shadow_raw_index_write_trigger_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pri_mme_shadow_raw_data_r(void) +{ + return 0x0040448cU; +} +static inline u32 gr_mme_hww_esr_r(void) +{ + return 0x00404490U; +} +static inline u32 gr_mme_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_mme_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_mme_hww_esr_info_r(void) +{ + return 0x00404494U; +} +static inline u32 gr_memfmt_hww_esr_r(void) +{ + return 0x00404600U; +} +static inline u32 gr_memfmt_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_memfmt_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fecs_cpuctl_r(void) +{ + return 0x00409100U; +} +static inline u32 gr_fecs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_cpuctl_alias_r(void) +{ + return 0x00409130U; +} +static inline u32 gr_fecs_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_dmactl_r(void) +{ + return 0x0040910cU; +} +static inline u32 gr_fecs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_fecs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_fecs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_fecs_os_r(void) +{ + return 0x00409080U; +} +static inline u32 gr_fecs_idlestate_r(void) +{ + return 0x0040904cU; +} +static inline u32 gr_fecs_mailbox0_r(void) +{ + return 0x00409040U; +} +static inline u32 gr_fecs_mailbox1_r(void) +{ + return 0x00409044U; +} +static inline u32 gr_fecs_irqstat_r(void) +{ + return 0x00409008U; +} +static inline u32 gr_fecs_irqmode_r(void) +{ + return 0x0040900cU; +} +static inline u32 gr_fecs_irqmask_r(void) +{ + return 0x00409018U; +} +static inline u32 gr_fecs_irqdest_r(void) +{ + return 0x0040901cU; +} +static inline u32 gr_fecs_curctx_r(void) +{ + return 0x00409050U; +} +static inline u32 gr_fecs_nxtctx_r(void) +{ + return 0x00409054U; +} +static inline u32 gr_fecs_engctl_r(void) +{ + return 0x004090a4U; +} +static inline u32 gr_fecs_debug1_r(void) +{ + return 0x00409090U; +} +static inline u32 gr_fecs_debuginfo_r(void) +{ + return 0x00409094U; +} +static inline u32 gr_fecs_icd_cmd_r(void) +{ + return 0x00409200U; +} +static inline u32 gr_fecs_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 gr_fecs_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 gr_fecs_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 gr_fecs_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 gr_fecs_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 gr_fecs_icd_rdata_r(void) +{ + return 0x0040920cU; +} +static inline u32 gr_fecs_imemc_r(u32 i) +{ + return 0x00409180U + i*16U; +} +static inline u32 gr_fecs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_imemd_r(u32 i) +{ + return 0x00409184U + i*16U; +} +static inline u32 gr_fecs_imemt_r(u32 i) +{ + return 0x00409188U + i*16U; +} +static inline u32 gr_fecs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_dmemc_r(u32 i) +{ + return 0x004091c0U + i*8U; +} +static inline u32 gr_fecs_dmemc_offs_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 gr_fecs_dmemc_offs_v(u32 r) +{ + return (r >> 2U) & 0x3fU; +} +static inline u32 gr_fecs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_dmemd_r(u32 i) +{ + return 0x004091c4U + i*8U; +} +static inline u32 gr_fecs_dmatrfbase_r(void) +{ + return 0x00409110U; +} +static inline u32 gr_fecs_dmatrfmoffs_r(void) +{ + return 0x00409114U; +} +static inline u32 gr_fecs_dmatrffboffs_r(void) +{ + return 0x0040911cU; +} +static inline u32 gr_fecs_dmatrfcmd_r(void) +{ + return 0x00409118U; +} +static inline u32 gr_fecs_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_fecs_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_fecs_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_fecs_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_fecs_bootvec_r(void) +{ + return 0x00409104U; +} +static inline u32 gr_fecs_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_falcon_hwcfg_r(void) +{ + return 0x00409108U; +} +static inline u32 gr_gpcs_gpccs_falcon_hwcfg_r(void) +{ + return 0x0041a108U; +} +static inline u32 gr_fecs_falcon_rm_r(void) +{ + return 0x00409084U; +} +static inline u32 gr_fecs_current_ctx_r(void) +{ + return 0x00409b00U; +} +static inline u32 gr_fecs_current_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_current_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_current_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_current_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_current_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_current_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_current_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_current_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_current_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_current_ctx_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_method_data_r(void) +{ + return 0x00409500U; +} +static inline u32 gr_fecs_method_push_r(void) +{ + return 0x00409504U; +} +static inline u32 gr_fecs_method_push_adr_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_v(void) +{ + return 0x00000003U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_f(void) +{ + return 0x3U; +} +static inline u32 gr_fecs_method_push_adr_discover_image_size_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_method_push_adr_wfi_golden_save_v(void) +{ + return 0x00000009U; +} +static inline u32 gr_fecs_method_push_adr_restore_golden_v(void) +{ + return 0x00000015U; +} +static inline u32 gr_fecs_method_push_adr_discover_zcull_image_size_v(void) +{ + return 0x00000016U; +} +static inline u32 gr_fecs_method_push_adr_discover_pm_image_size_v(void) +{ + return 0x00000025U; +} +static inline u32 gr_fecs_method_push_adr_discover_reglist_image_size_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_bind_instance_v(void) +{ + return 0x00000031U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_virtual_address_v(void) +{ + return 0x00000032U; +} +static inline u32 gr_fecs_method_push_adr_stop_ctxsw_v(void) +{ + return 0x00000038U; +} +static inline u32 gr_fecs_method_push_adr_start_ctxsw_v(void) +{ + return 0x00000039U; +} +static inline u32 gr_fecs_method_push_adr_set_watchdog_timeout_f(void) +{ + return 0x21U; +} +static inline u32 gr_fecs_method_push_adr_write_timestamp_record_v(void) +{ + return 0x0000003dU; +} +static inline u32 gr_fecs_method_push_adr_discover_preemption_image_size_v(void) +{ + return 0x0000001aU; +} +static inline u32 gr_fecs_method_push_adr_halt_pipeline_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_fecs_method_push_adr_configure_interrupt_completion_option_v(void) +{ + return 0x0000003aU; +} +static inline u32 gr_fecs_host_int_status_r(void) +{ + return 0x00409c18U; +} +static inline u32 gr_fecs_host_int_status_fault_during_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_fecs_host_int_status_umimp_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 gr_fecs_host_int_status_umimp_illegal_method_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 gr_fecs_host_int_status_watchdog_active_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_host_int_status_ctxsw_intr_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_host_int_clear_r(void) +{ + return 0x00409c20U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_clear_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_r(void) +{ + return 0x00409c24U; +} +static inline u32 gr_fecs_host_int_enable_ctxsw_intr1_enable_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_fault_during_ctxsw_enable_f(void) +{ + return 0x10000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_firmware_method_enable_f(void) +{ + return 0x20000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_illegal_method_enable_f(void) +{ + return 0x40000U; +} +static inline u32 gr_fecs_host_int_enable_watchdog_enable_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_r(void) +{ + return 0x00409614U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_engine_reset_disabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_engine_reset_disabled_f(void) +{ + return 0x20U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_engine_reset_disabled_f(void) +{ + return 0x40U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_disabled_f(void) +{ + return 0x100U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_disabled_f(void) +{ + return 0x200U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_disabled_f(void) +{ + return 0x400U; +} +static inline u32 gr_fecs_ctx_state_store_major_rev_id_r(void) +{ + return 0x0040960cU; +} +static inline u32 gr_fecs_ctxsw_mailbox_r(u32 i) +{ + return 0x00409800U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_fail_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_r(u32 i) +{ + return 0x004098c0U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_r(u32 i) +{ + return 0x00409840U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_fs_r(void) +{ + return 0x00409604U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_fs_num_available_fbps_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_fbps_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_m(void) +{ + return 0x1fU << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_fecs_cfg_r(void) +{ + return 0x00409620U; +} +static inline u32 gr_fecs_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_fecs_rc_lanes_r(void) +{ + return 0x00409880U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_fecs_ctxsw_status_1_r(void) +{ + return 0x00409400U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_m(void) +{ + return 0x1U << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_adr_r(void) +{ + return 0x00409a24U; +} +static inline u32 gr_fecs_new_ctx_r(void) +{ + return 0x00409b04U; +} +static inline u32 gr_fecs_new_ctx_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_new_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_new_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_new_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_new_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_new_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_new_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_new_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_new_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_new_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_new_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_ptr_r(void) +{ + return 0x00409a0cU; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_arb_ctx_cmd_r(void) +{ + return 0x00409a10U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_ctxsw_status_fe_0_r(void) +{ + return 0x00409c00U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_gpc_0_r(void) +{ + return 0x00502c04U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_1_r(void) +{ + return 0x00502400U; +} +static inline u32 gr_fecs_ctxsw_idlestate_r(void) +{ + return 0x00409420U; +} +static inline u32 gr_fecs_feature_override_ecc_r(void) +{ + return 0x00409658U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_lrf_override_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_shm_override_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_tex_override_v(u32 r) +{ + return (r >> 11U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_ltc_override_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_lrf_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_shm_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_tex_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_ltc_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_idlestate_r(void) +{ + return 0x00502420U; +} +static inline u32 gr_rstr2d_gpc_map0_r(void) +{ + return 0x0040780cU; +} +static inline u32 gr_rstr2d_gpc_map1_r(void) +{ + return 0x00407810U; +} +static inline u32 gr_rstr2d_gpc_map2_r(void) +{ + return 0x00407814U; +} +static inline u32 gr_rstr2d_gpc_map3_r(void) +{ + return 0x00407818U; +} +static inline u32 gr_rstr2d_gpc_map4_r(void) +{ + return 0x0040781cU; +} +static inline u32 gr_rstr2d_gpc_map5_r(void) +{ + return 0x00407820U; +} +static inline u32 gr_rstr2d_map_table_cfg_r(void) +{ + return 0x004078bcU; +} +static inline u32 gr_rstr2d_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_rstr2d_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_hww_esr_r(void) +{ + return 0x00406018U; +} +static inline u32 gr_pd_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pd_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_num_tpc_per_gpc_r(u32 i) +{ + return 0x00406028U + i*4U; +} +static inline u32 gr_pd_num_tpc_per_gpc__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count1_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count2_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count3_f(u32 v) +{ + return (v & 0xfU) << 12U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count4_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count5_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count6_f(u32 v) +{ + return (v & 0xfU) << 24U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count7_f(u32 v) +{ + return (v & 0xfU) << 28U; +} +static inline u32 gr_pd_ab_dist_cfg0_r(void) +{ + return 0x004064c0U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_en_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_dis_f(void) +{ + return 0x0U; +} +static inline u32 gr_pd_ab_dist_cfg1_r(void) +{ + return 0x004064c4U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_batches_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_batches_init_f(void) +{ + return 0xffffU; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_granularity_v(void) +{ + return 0x00000080U; +} +static inline u32 gr_pd_ab_dist_cfg2_r(void) +{ + return 0x004064c8U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_f(u32 v) +{ + return (v & 0x1fffU) << 0U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_init_v(void) +{ + return 0x000001c0U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_f(u32 v) +{ + return (v & 0x1fffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_scc_bundle_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_min_gpm_fifo_depths_v(void) +{ + return 0x00000182U; +} +static inline u32 gr_pd_dist_skip_table_r(u32 i) +{ + return 0x004064d0U + i*4U; +} +static inline u32 gr_pd_dist_skip_table__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n0_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n1_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n2_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n3_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_ds_debug_r(void) +{ + return 0x00405800U; +} +static inline u32 gr_ds_debug_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_debug_timeslice_mode_enable_f(void) +{ + return 0x8000000U; +} +static inline u32 gr_ds_zbc_color_r_r(void) +{ + return 0x00405804U; +} +static inline u32 gr_ds_zbc_color_r_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_g_r(void) +{ + return 0x00405808U; +} +static inline u32 gr_ds_zbc_color_g_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_b_r(void) +{ + return 0x0040580cU; +} +static inline u32 gr_ds_zbc_color_b_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_a_r(void) +{ + return 0x00405810U; +} +static inline u32 gr_ds_zbc_color_a_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_r(void) +{ + return 0x00405814U; +} +static inline u32 gr_ds_zbc_color_fmt_val_f(u32 v) +{ + return (v & 0x7fU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_zero_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_color_fmt_val_unorm_one_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_ds_zbc_color_fmt_val_rf32_gf32_bf32_af32_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_ds_zbc_color_fmt_val_a8_b8_g8_r8_v(void) +{ + return 0x00000028U; +} +static inline u32 gr_ds_zbc_z_r(void) +{ + return 0x00405818U; +} +static inline u32 gr_ds_zbc_z_val_s(void) +{ + return 32U; +} +static inline u32 gr_ds_zbc_z_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_z_val_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_ds_zbc_z_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_ds_zbc_z_val__init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_ds_zbc_z_val__init_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_r(void) +{ + return 0x0040581cU; +} +static inline u32 gr_ds_zbc_z_fmt_val_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_fp32_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_tbl_index_r(void) +{ + return 0x00405820U; +} +static inline u32 gr_ds_zbc_tbl_index_val_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_ds_zbc_tbl_ld_r(void) +{ + return 0x00405824U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_c_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_z_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_zbc_tbl_ld_action_write_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_trigger_active_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_tga_constraintlogic_beta_r(void) +{ + return 0x00405830U; +} +static inline u32 gr_ds_tga_constraintlogic_beta_cbsize_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_ds_tga_constraintlogic_alpha_r(void) +{ + return 0x0040585cU; +} +static inline u32 gr_ds_tga_constraintlogic_alpha_cbsize_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_ds_hww_esr_r(void) +{ + return 0x00405840U; +} +static inline u32 gr_ds_hww_esr_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_esr_2_r(void) +{ + return 0x00405848U; +} +static inline u32 gr_ds_hww_esr_2_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_2_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_2_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_2_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_2_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_2_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_2_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_report_mask_r(void) +{ + return 0x00405844U; +} +static inline u32 gr_ds_hww_report_mask_sph0_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_hww_report_mask_sph1_err_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_ds_hww_report_mask_sph2_err_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_hww_report_mask_sph3_err_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_ds_hww_report_mask_sph4_err_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_ds_hww_report_mask_sph5_err_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_ds_hww_report_mask_sph6_err_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_ds_hww_report_mask_sph7_err_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_ds_hww_report_mask_sph8_err_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_ds_hww_report_mask_sph9_err_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_ds_hww_report_mask_sph10_err_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_ds_hww_report_mask_sph11_err_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_ds_hww_report_mask_sph12_err_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_ds_hww_report_mask_sph13_err_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_ds_hww_report_mask_sph14_err_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_ds_hww_report_mask_sph15_err_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_ds_hww_report_mask_sph16_err_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_ds_hww_report_mask_sph17_err_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_ds_hww_report_mask_sph18_err_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_ds_hww_report_mask_sph19_err_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_ds_hww_report_mask_sph20_err_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_ds_hww_report_mask_sph21_err_report_f(void) +{ + return 0x200000U; +} +static inline u32 gr_ds_hww_report_mask_sph22_err_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_ds_hww_report_mask_sph23_err_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_ds_hww_report_mask_2_r(void) +{ + return 0x0040584cU; +} +static inline u32 gr_ds_hww_report_mask_2_sph24_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_num_tpc_per_gpc_r(u32 i) +{ + return 0x00405870U + i*4U; +} +static inline u32 gr_scc_bundle_cb_base_r(void) +{ + return 0x00408004U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_bundle_cb_size_r(void) +{ + return 0x00408008U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b__prod_v(void) +{ + return 0x00000018U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_scc_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_pagepool_base_r(void) +{ + return 0x0040800cU; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_pagepool_r(void) +{ + return 0x00408010U; +} +static inline u32 gr_scc_pagepool_total_pages_f(u32 v) +{ + return (v & 0x3ffU) << 0U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_value_v(void) +{ + return 0x00000200U; +} +static inline u32 gr_scc_pagepool_total_pages_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_s(void) +{ + return 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_f(u32 v) +{ + return (v & 0x3ffU) << 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_m(void) +{ + return 0x3ffU << 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_v(u32 r) +{ + return (r >> 10U) & 0x3ffU; +} +static inline u32 gr_scc_pagepool_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_init_r(void) +{ + return 0x0040802cU; +} +static inline u32 gr_scc_init_ram_trigger_f(void) +{ + return 0x1U; +} +static inline u32 gr_scc_hww_esr_r(void) +{ + return 0x00408030U; +} +static inline u32 gr_scc_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_scc_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_sked_hww_esr_r(void) +{ + return 0x00407020U; +} +static inline u32 gr_sked_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_cwd_fs_r(void) +{ + return 0x00405b00U; +} +static inline u32 gr_cwd_fs_num_gpcs_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_fs_num_tpcs_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_cwd_gpc_tpc_id_r(u32 i) +{ + return 0x00405b60U + i*4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc0_s(void) +{ + return 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_cwd_gpc_tpc_id_gpc0_s(void) +{ + return 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_gpc0_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc1_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_cwd_sm_id_r(u32 i) +{ + return 0x00405ba0U + i*4U; +} +static inline u32 gr_cwd_sm_id__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_cwd_sm_id_tpc0_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_sm_id_tpc1_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpc0_fs_gpc_r(void) +{ + return 0x00502608U; +} +static inline u32 gr_gpc0_fs_gpc_num_available_tpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_gpc0_fs_gpc_num_available_zculls_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_gpc0_cfg_r(void) +{ + return 0x00502620U; +} +static inline u32 gr_gpc0_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpccs_rc_lanes_r(void) +{ + return 0x00502880U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_rc_lane_size_r(void) +{ + return 0x00502910U; +} +static inline u32 gr_gpccs_rc_lane_size_v_s(void) +{ + return 24U; +} +static inline u32 gr_gpccs_rc_lane_size_v_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_zcull_fs_r(void) +{ + return 0x00500910U; +} +static inline u32 gr_gpc0_zcull_fs_num_sms_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 gr_gpc0_zcull_fs_num_active_banks_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_gpc0_zcull_ram_addr_r(void) +{ + return 0x00500914U; +} +static inline u32 gr_gpc0_zcull_ram_addr_tiles_per_hypertile_row_per_gpc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_gpc0_zcull_ram_addr_row_offset_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_r(void) +{ + return 0x00500918U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative__max_v(void) +{ + return 0x00800000U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_r(void) +{ + return 0x00500920U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_num_aliquots_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_zcsize_r(u32 i) +{ + return 0x00500a04U + i*32U; +} +static inline u32 gr_gpc0_zcull_zcsize_height_subregion__multiple_v(void) +{ + return 0x00000040U; +} +static inline u32 gr_gpc0_zcull_zcsize_width_subregion__multiple_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_r(u32 i) +{ + return 0x00500c10U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_id_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_r(u32 i) +{ + return 0x00500c30U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_mask_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_r(void) +{ + return 0x00504088U; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_value_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_r(void) +{ + return 0x00504698U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_sm_id_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_sm_id_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_r(void) +{ + return 0x0050469cU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_warp_count_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_spa_version_v(u32 r) +{ + return (r >> 8U) & 0xfffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_sm_version_v(u32 r) +{ + return (r >> 20U) & 0xfffU; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_r(void) +{ + return 0x00503018U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_true_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_r(void) +{ + return 0x005030c0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_m(void) +{ + return 0x3fffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_default_v(void) +{ + return 0x00030000U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_gfxp_v(void) +{ + return 0x00030a00U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_offset_r(void) +{ + return 0x005030f4U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_r(void) +{ + return 0x005030e4U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_default_v(void) +{ + return 0x00000800U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_offset_r(void) +{ + return 0x005030f8U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_r(void) +{ + return 0x005030f0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_v_default_v(void) +{ + return 0x00030000U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_0_r(void) +{ + return 0x00419b00U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_0_base_addr_43_12_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_r(void) +{ + return 0x00419b04U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_s(void) +{ + return 21U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_f(u32 v) +{ + return (v & 0x1fffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_m(void) +{ + return 0x1fffffU << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_v(u32 r) +{ + return (r >> 0U) & 0x1fffffU; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_granularity_f(void) +{ + return 0x80U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_s(void) +{ + return 1U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpcs_tpcs_tex_m_dbg2_r(void) +{ + return 0x00419a3cU; +} +static inline u32 gr_gpcs_tpcs_tex_m_dbg2_lg_rd_coalesce_en_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_gpcs_tpcs_tex_m_dbg2_lg_rd_coalesce_en_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpcs_tpcs_tex_m_dbg2_su_rd_coalesce_en_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_gpcs_tpcs_tex_m_dbg2_su_rd_coalesce_en_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpccs_falcon_addr_r(void) +{ + return 0x0041a0acU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_msb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_v(u32 r) +{ + return (r >> 6U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_s(void) +{ + return 12U; +} +static inline u32 gr_gpccs_falcon_addr_ext_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_m(void) +{ + return 0xfffU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_gpccs_cpuctl_r(void) +{ + return 0x0041a100U; +} +static inline u32 gr_gpccs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_gpccs_dmactl_r(void) +{ + return 0x0041a10cU; +} +static inline u32 gr_gpccs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpccs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpccs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpccs_imemc_r(u32 i) +{ + return 0x0041a180U + i*16U; +} +static inline u32 gr_gpccs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_imemd_r(u32 i) +{ + return 0x0041a184U + i*16U; +} +static inline u32 gr_gpccs_imemt_r(u32 i) +{ + return 0x0041a188U + i*16U; +} +static inline u32 gr_gpccs_imemt__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_gpccs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpccs_dmemc_r(u32 i) +{ + return 0x0041a1c0U + i*8U; +} +static inline u32 gr_gpccs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_dmemd_r(u32 i) +{ + return 0x0041a1c4U + i*8U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_r(u32 i) +{ + return 0x0041a800U + i*4U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_r(void) +{ + return 0x00418e24U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_s(void) +{ + return 32U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_r(void) +{ + return 0x00418e28U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_s(void) +{ + return 11U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_m(void) +{ + return 0x7ffU << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_v(u32 r) +{ + return (r >> 0U) & 0x7ffU; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_init_v(void) +{ + return 0x00000018U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_init_f(void) +{ + return 0x18U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_s(void) +{ + return 1U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_r(void) +{ + return 0x00500ee4U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_default_v(void) +{ + return 0x00000250U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_r(void) +{ + return 0x00500ee0U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_r(void) +{ + return 0x00418eecU; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_cbes_reserve_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_cbes_reserve_gfxp_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_gpcs_ppcs_cbm_beta_cb_ctrl_r(void) +{ + return 0x0041befcU; +} +static inline u32 gr_gpcs_ppcs_cbm_beta_cb_ctrl_cbes_reserve_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_r(u32 i) +{ + return 0x00418ea0U + i*4U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_v_m(void) +{ + return 0x3fffffU << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_r_r(u32 i) +{ + return 0x00418010U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_r_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_g_r(u32 i) +{ + return 0x0041804cU + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_g_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_b_r(u32 i) +{ + return 0x00418088U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_b_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_a_r(u32 i) +{ + return 0x004180c4U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_a_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_c_01_to_04_format_r(void) +{ + return 0x00500100U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_r(u32 i) +{ + return 0x00418110U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_01_to_04_format_r(void) +{ + return 0x0050014cU; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_r(void) +{ + return 0x00418810U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_align_bits_v(void) +{ + return 0x0000000cU; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_crstr_gpc_map0_r(void) +{ + return 0x00418b08U; +} +static inline u32 gr_crstr_gpc_map0_tile0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map0_tile1_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map0_tile2_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map0_tile3_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map0_tile4_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map0_tile5_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map1_r(void) +{ + return 0x00418b0cU; +} +static inline u32 gr_crstr_gpc_map1_tile6_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map1_tile7_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map1_tile8_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map1_tile9_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map1_tile10_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map1_tile11_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map2_r(void) +{ + return 0x00418b10U; +} +static inline u32 gr_crstr_gpc_map2_tile12_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map2_tile13_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map2_tile14_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map2_tile15_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map2_tile16_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map2_tile17_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map3_r(void) +{ + return 0x00418b14U; +} +static inline u32 gr_crstr_gpc_map3_tile18_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map3_tile19_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map3_tile20_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map3_tile21_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map3_tile22_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map3_tile23_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map4_r(void) +{ + return 0x00418b18U; +} +static inline u32 gr_crstr_gpc_map4_tile24_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map4_tile25_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map4_tile26_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map4_tile27_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map4_tile28_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map4_tile29_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_gpc_map5_r(void) +{ + return 0x00418b1cU; +} +static inline u32 gr_crstr_gpc_map5_tile30_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_crstr_gpc_map5_tile31_f(u32 v) +{ + return (v & 0x7U) << 5U; +} +static inline u32 gr_crstr_gpc_map5_tile32_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 gr_crstr_gpc_map5_tile33_f(u32 v) +{ + return (v & 0x7U) << 15U; +} +static inline u32 gr_crstr_gpc_map5_tile34_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_crstr_gpc_map5_tile35_f(u32 v) +{ + return (v & 0x7U) << 25U; +} +static inline u32 gr_crstr_map_table_cfg_r(void) +{ + return 0x00418bb8U; +} +static inline u32 gr_crstr_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_crstr_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_r(void) +{ + return 0x00418980U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_1_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_2_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_3_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_4_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_5_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_6_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map0_tile_7_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_r(void) +{ + return 0x00418984U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_8_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_9_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_10_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_11_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_12_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_13_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_14_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map1_tile_15_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_r(void) +{ + return 0x00418988U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_16_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_17_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_18_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_19_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_20_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_21_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_22_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_s(void) +{ + return 3U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_m(void) +{ + return 0x7U << 28U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map2_tile_23_v(u32 r) +{ + return (r >> 28U) & 0x7U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_r(void) +{ + return 0x0041898cU; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_24_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_25_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_26_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_27_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_28_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_29_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_30_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map3_tile_31_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_r(void) +{ + return 0x00418c6cU; +} +static inline u32 gr_gpcs_gpm_pd_cfg_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_timeslice_mode_enable_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_r(void) +{ + return 0x00419004U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_gcc_pagepool_r(void) +{ + return 0x00419008U; +} +static inline u32 gr_gpcs_gcc_pagepool_total_pages_f(u32 v) +{ + return (v & 0x3ffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_r(void) +{ + return 0x0041980cU; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_fast_mode_switch_true_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_r(void) +{ + return 0x00419848U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_r(void) +{ + return 0x00419c00U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_enabled_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_r(void) +{ + return 0x00419c2cU; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_r(void) +{ + return 0x00419e44U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_stack_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_api_stack_error_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_ret_empty_stack_error_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_wrap_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_pc_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_pc_overflow_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_immc_addr_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_reg_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_encoding_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_sph_instr_combo_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_reg_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_oor_addr_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_misaligned_addr_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_addr_space_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_illegal_instr_param2_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_invalid_const_addr_ldc_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_mmu_fault_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_stack_overflow_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_geometry_sm_error_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_warp_esr_report_mask_divergent_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_report_mask_r(void) +{ + return 0x00504644U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_r(void) +{ + return 0x00419e4cU; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_sm_to_sm_fault_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_l1_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_multiple_warp_errors_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_physical_stack_overflow_error_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_int_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_ecc_sec_error_report_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_ecc_ded_error_report_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_bpt_pause_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_report_mask_single_step_complete_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_report_mask_r(void) +{ + return 0x0050464cU; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_r(void) +{ + return 0x00419d0cU; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_tex_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_r(void) +{ + return 0x0041ac94U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_tpc_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gcc_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_0_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_r(void) +{ + return 0x00504610U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_debugger_mode_off_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_single_step_mode_enable_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_single_step_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_warp_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_stop_on_any_warp_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_control0_stop_on_any_sm_stop_on_any_sm_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_warp_valid_mask_r(void) +{ + return 0x00504614U; +} +static inline u32 gr_gpc0_tpc0_sm_warp_valid_mask_1_r(void) +{ + return 0x00504618U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_r(void) +{ + return 0x00504624U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_pause_mask_1_r(void) +{ + return 0x00504628U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_r(void) +{ + return 0x00504634U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_bpt_trap_mask_1_r(void) +{ + return 0x00504638U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_bpt_pause_mask_r(void) +{ + return 0x00419e24U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_r(void) +{ + return 0x0050460cU; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_sm_in_trap_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_locked_down_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_dbgr_status0_locked_down_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_r(void) +{ + return 0x00419e50U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_sm_to_sm_fault_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_l1_error_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_multiple_warp_errors_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_physical_stack_overflow_error_pending_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_hww_global_esr_timeout_error_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_r(void) +{ + return 0x00504650U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_ecc_sec_error_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_ecc_ded_error_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_sm_to_sm_fault_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_l1_error_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_multiple_warp_errors_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_physical_stack_overflow_error_pending_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_global_esr_timeout_error_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_r(void) +{ + return 0x00504224U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_intr_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_ecc_sec_pending_f(void) +{ + return 0x80U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_ecc_ded_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpc0_tpc0_tex_m_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_r(void) +{ + return 0x00504648U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_none_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_error_none_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_addr_valid_m(void) +{ + return 0x1U << 24U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_addr_error_type_m(void) +{ + return 0x7U << 25U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_addr_error_type_none_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_hww_warp_esr_pc_r(void) +{ + return 0x00504654U; +} +static inline u32 gr_gpc0_tpc0_sm_halfctl_ctrl_r(void) +{ + return 0x00504770U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_r(void) +{ + return 0x00419f70U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_gpc0_tpc0_sm_debug_sfe_control_r(void) +{ + return 0x0050477cU; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_r(void) +{ + return 0x00419f7cU; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_r(void) +{ + return 0x0041be08U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_fast_mode_switch_true_f(void) +{ + return 0x4U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map0_r(void) +{ + return 0x0041bf00U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map1_r(void) +{ + return 0x0041bf04U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map2_r(void) +{ + return 0x0041bf08U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map3_r(void) +{ + return 0x0041bf0cU; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map4_r(void) +{ + return 0x0041bf10U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map5_r(void) +{ + return 0x0041bf14U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_r(void) +{ + return 0x0041bfd0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_num_entries_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_shift_value_f(u32 v) +{ + return (v & 0x7U) << 21U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff5_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 24U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_r(void) +{ + return 0x0041bfd4U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_r(void) +{ + return 0x0041bfe4U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff6_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff7_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 5U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff8_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 10U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff9_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 15U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff10_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 20U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg2_coeff11_mod_value_f(u32 v) +{ + return (v & 0x1fU) << 25U; +} +static inline u32 gr_bes_zrop_settings_r(void) +{ + return 0x00408850U; +} +static inline u32 gr_bes_zrop_settings_num_active_ltcs_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_be0_crop_debug3_r(void) +{ + return 0x00410108U; +} +static inline u32 gr_bes_crop_debug3_r(void) +{ + return 0x00408908U; +} +static inline u32 gr_bes_crop_debug3_comp_vdc_4to2_disable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_enabled_f(void) +{ + return 0x4U; +} +static inline u32 gr_bes_crop_debug4_r(void) +{ + return 0x0040894cU; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_m(void) +{ + return 0x1U << 18U; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_to_inf_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_to_maxval_f(void) +{ + return 0x40000U; +} +static inline u32 gr_bes_crop_settings_r(void) +{ + return 0x00408958U; +} +static inline u32 gr_bes_crop_settings_num_active_ltcs_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_zcull_bytes_per_aliquot_per_gpu_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_header_bytes_per_gpc_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_subregion_header_bytes_per_gpc_v(void) +{ + return 0x000000c0U; +} +static inline u32 gr_zcull_subregion_qty_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel0_r(void) +{ + return 0x00504604U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control_sel1_r(void) +{ + return 0x00504608U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control0_r(void) +{ + return 0x0050465cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control1_r(void) +{ + return 0x00504660U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control2_r(void) +{ + return 0x00504664U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control3_r(void) +{ + return 0x00504668U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control4_r(void) +{ + return 0x0050466cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_control5_r(void) +{ + return 0x00504658U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_control_r(void) +{ + return 0x00504730U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_control_r(void) +{ + return 0x00504734U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_control_r(void) +{ + return 0x00504738U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_control_r(void) +{ + return 0x0050473cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter4_control_r(void) +{ + return 0x00504740U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter5_control_r(void) +{ + return 0x00504744U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter6_control_r(void) +{ + return 0x00504748U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter7_control_r(void) +{ + return 0x0050474cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_status_s1_r(void) +{ + return 0x00504678U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter_status1_r(void) +{ + return 0x00504694U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_s0_r(void) +{ + return 0x005046f0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter0_s1_r(void) +{ + return 0x00504700U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_s0_r(void) +{ + return 0x005046f4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter1_s1_r(void) +{ + return 0x00504704U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_s0_r(void) +{ + return 0x005046f8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter2_s1_r(void) +{ + return 0x00504708U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_s0_r(void) +{ + return 0x005046fcU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_dsm_perf_counter3_s1_r(void) +{ + return 0x0050470cU; +} +static inline u32 gr_fe_pwr_mode_r(void) +{ + return 0x00404170U; +} +static inline u32 gr_fe_pwr_mode_mode_auto_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_pwr_mode_mode_force_on_f(void) +{ + return 0x2U; +} +static inline u32 gr_fe_pwr_mode_req_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_fe_pwr_mode_req_send_f(void) +{ + return 0x10U; +} +static inline u32 gr_fe_pwr_mode_req_done_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_r(void) +{ + return 0x00418880U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_vm_pg_size_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_use_pdb_big_page_size_m(void) +{ + return 0x1U << 11U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_vol_fault_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_comp_fault_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_miss_gran_m(void) +{ + return 0x3U << 3U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_cache_mode_m(void) +{ + return 0x3U << 5U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_aperture_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_vol_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_disable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_pri_mmu_pm_unit_mask_r(void) +{ + return 0x00418890U; +} +static inline u32 gr_gpcs_pri_mmu_pm_req_mask_r(void) +{ + return 0x00418894U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_r(void) +{ + return 0x004188b0U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_pri_mmu_debug_wr_r(void) +{ + return 0x004188b4U; +} +static inline u32 gr_gpcs_pri_mmu_debug_rd_r(void) +{ + return 0x004188b8U; +} +static inline u32 gr_gpcs_mmu_num_active_ltcs_r(void) +{ + return 0x004188acU; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_r(void) +{ + return 0x00419e10U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_debugger_mode_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_enable_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_r(void) +{ + return 0x004041c0U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_count_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_count_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_debug_2_r(void) +{ + return 0x00400088U; +} +static inline u32 gr_debug_2_gfxp_wfi_always_injects_wfi_m(void) +{ + return 0x1U << 23U; +} +static inline u32 gr_debug_2_gfxp_wfi_always_injects_wfi_v(u32 r) +{ + return (r >> 23U) & 0x1U; +} +static inline u32 gr_debug_2_gfxp_wfi_always_injects_wfi_enabled_f(void) +{ + return 0x800000U; +} +static inline u32 gr_debug_2_gfxp_wfi_always_injects_wfi_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_r(void) +{ + return 0x00419c84U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_m(void) +{ + return 0x7U << 8U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_arm_63_48_match_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_r(void) +{ + return 0x00419f78U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_re_suppress_m(void) +{ + return 0x3U << 11U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_re_suppress_disable_f(void) +{ + return 0x1000U; +} +static inline u32 gr_gpcs_tc_debug0_r(void) +{ + return 0x00418708U; +} +static inline u32 gr_gpcs_tc_debug0_limit_coalesce_buffer_size_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpcs_tc_debug0_limit_coalesce_buffer_size_m(void) +{ + return 0xffU << 0U; +} +static inline u32 gr_gpc0_prop_debug1_r(void) +{ + return 0x00500400U; +} +static inline u32 gr_gpc0_prop_debug1_czf_bypass_f(u32 v) +{ + return (v & 0x3U) << 14U; +} +static inline u32 gr_gpc0_prop_debug1_czf_bypass_m(void) +{ + return 0x3U << 14U; +} +static inline u32 gr_gpc0_prop_debug1_czf_bypass_init_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_ltc_gp10b.h b/include/nvgpu/hw/gp10b/hw_ltc_gp10b.h new file mode 100644 index 0000000..721a48a --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_ltc_gp10b.h @@ -0,0 +1,587 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ltc_gp10b_h_ +#define _hw_ltc_gp10b_h_ + +static inline u32 ltc_pltcg_base_v(void) +{ + return 0x00140000U; +} +static inline u32 ltc_pltcg_extent_v(void) +{ + return 0x0017ffffU; +} +static inline u32 ltc_ltc0_ltss_v(void) +{ + return 0x00140200U; +} +static inline u32 ltc_ltc0_lts0_v(void) +{ + return 0x00140400U; +} +static inline u32 ltc_ltcs_ltss_v(void) +{ + return 0x0017e200U; +} +static inline u32 ltc_ltcs_lts0_cbc_ctrl1_r(void) +{ + return 0x0014046cU; +} +static inline u32 ltc_ltc0_lts0_dstg_cfg0_r(void) +{ + return 0x00140518U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_r(void) +{ + return 0x0017e318U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_vdc_4to2_disable_m(void) +{ + return 0x1U << 15U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_r(void) +{ + return 0x00140494U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_ways_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_v(u32 r) +{ + return (r >> 16U) & 0x3U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_all_v(void) +{ + return 0x00000000U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_half_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_quarter_v(void) +{ + return 0x00000002U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void) +{ + return 0x0017e26cU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(void) +{ + return 0x2U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_f(void) +{ + return 0x4U; +} +static inline u32 ltc_ltc0_lts0_cbc_ctrl1_r(void) +{ + return 0x0014046cU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_r(void) +{ + return 0x0017e270U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(u32 v) +{ + return (v & 0x3ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_r(void) +{ + return 0x0017e274U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(u32 v) +{ + return (v & 0x3ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_init_v(void) +{ + return 0x0003ffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_r(void) +{ + return 0x0017e278U; +} +static inline u32 ltc_ltcs_ltss_cbc_base_alignment_shift_v(void) +{ + return 0x0000000bU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_address_v(u32 r) +{ + return (r >> 0U) & 0x3ffffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_r(void) +{ + return 0x0017e27cU; +} +static inline u32 ltc_ltcs_misc_ltc_num_active_ltcs_r(void) +{ + return 0x0017e000U; +} +static inline u32 ltc_ltcs_ltss_cbc_param_r(void) +{ + return 0x0017e280U; +} +static inline u32 ltc_ltcs_ltss_cbc_param_comptags_per_cache_line_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_cache_line_size_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_slices_per_ltc_v(u32 r) +{ + return (r >> 28U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_cbc_param2_r(void) +{ + return 0x0017e3f4U; +} +static inline u32 ltc_ltcs_ltss_cbc_param2_gobs_per_comptagline_per_slice_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_r(void) +{ + return 0x0017e2acU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_max_ways_evict_last_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_r(void) +{ + return 0x0017e338U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_address_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value_r(u32 i) +{ + return 0x0017e33cU + i*4U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_r(void) +{ + return 0x0017e34cU; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_s(void) +{ + return 32U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_r(void) +{ + return 0x0017e2b0U; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_l2_bypass_mode_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_r(void) +{ + return 0x0017e214U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_r(void) +{ + return 0x00140214U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_r(void) +{ + return 0x00142214U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_intr_r(void) +{ + return 0x0017e20cU; +} +static inline u32 ltc_ltcs_ltss_intr_ecc_sec_error_pending_f(void) +{ + return 0x100U; +} +static inline u32 ltc_ltcs_ltss_intr_ecc_ded_error_pending_f(void) +{ + return 0x200U; +} +static inline u32 ltc_ltcs_ltss_intr_en_evicted_cb_m(void) +{ + return 0x1U << 20U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_access_m(void) +{ + return 0x1U << 30U; +} +static inline u32 ltc_ltcs_ltss_intr_en_ecc_sec_error_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 ltc_ltcs_ltss_intr_en_ecc_ded_error_enabled_f(void) +{ + return 0x2000000U; +} +static inline u32 ltc_ltc0_lts0_intr_r(void) +{ + return 0x0014040cU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_r(void) +{ + return 0x0014051cU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_sec_count_m(void) +{ + return 0xffU << 0U; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_sec_count_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_ded_count_m(void) +{ + return 0xffU << 16U; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_ded_count_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_r(void) +{ + return 0x0017e2a0U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_r(void) +{ + return 0x0017e2a4U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_f(void) +{ + return 0x10000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_r(void) +{ + return 0x001402a0U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_r(void) +{ + return 0x001402a4U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_r(void) +{ + return 0x001422a0U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_r(void) +{ + return 0x001422a4U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_r(void) +{ + return 0x0014058cU; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_slice_size_in_kb_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_slices_per_l2_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 ltc_ltca_g_axi_pctrl_r(void) +{ + return 0x00160000U; +} +static inline u32 ltc_ltca_g_axi_pctrl_user_sid_f(u32 v) +{ + return (v & 0xffU) << 2U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_mc_gp10b.h b/include/nvgpu/hw/gp10b/hw_mc_gp10b.h new file mode 100644 index 0000000..39c132a --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_mc_gp10b.h @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_mc_gp10b_h_ +#define _hw_mc_gp10b_h_ + +static inline u32 mc_boot_0_r(void) +{ + return 0x00000000U; +} +static inline u32 mc_boot_0_architecture_v(u32 r) +{ + return (r >> 24U) & 0x1fU; +} +static inline u32 mc_boot_0_implementation_v(u32 r) +{ + return (r >> 20U) & 0xfU; +} +static inline u32 mc_boot_0_major_revision_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 mc_boot_0_minor_revision_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 mc_intr_r(u32 i) +{ + return 0x00000100U + i*4U; +} +static inline u32 mc_intr_pfifo_pending_f(void) +{ + return 0x100U; +} +static inline u32 mc_intr_replayable_fault_pending_f(void) +{ + return 0x200U; +} +static inline u32 mc_intr_pfb_pending_f(void) +{ + return 0x2000U; +} +static inline u32 mc_intr_pgraph_pending_f(void) +{ + return 0x1000U; +} +static inline u32 mc_intr_pmu_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_ltc_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 mc_intr_priv_ring_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 mc_intr_pbus_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_intr_en_r(u32 i) +{ + return 0x00000140U + i*4U; +} +static inline u32 mc_intr_en_set_r(u32 i) +{ + return 0x00000160U + i*4U; +} +static inline u32 mc_intr_en_clear_r(u32 i) +{ + return 0x00000180U + i*4U; +} +static inline u32 mc_enable_r(void) +{ + return 0x00000200U; +} +static inline u32 mc_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_enable_l2_enabled_f(void) +{ + return 0x8U; +} +static inline u32 mc_enable_pmedia_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pmedia_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 mc_enable_pmedia_m(void) +{ + return 0x1U << 4U; +} +static inline u32 mc_enable_pmedia_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 mc_enable_priv_ring_enabled_f(void) +{ + return 0x20U; +} +static inline u32 mc_enable_ce0_m(void) +{ + return 0x1U << 6U; +} +static inline u32 mc_enable_pfifo_enabled_f(void) +{ + return 0x100U; +} +static inline u32 mc_enable_pgraph_enabled_f(void) +{ + return 0x1000U; +} +static inline u32 mc_enable_pwr_v(u32 r) +{ + return (r >> 13U) & 0x1U; +} +static inline u32 mc_enable_pwr_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 mc_enable_pwr_enabled_f(void) +{ + return 0x2000U; +} +static inline u32 mc_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_enable_ce2_m(void) +{ + return 0x1U << 21U; +} +static inline u32 mc_enable_ce2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 mc_enable_blg_enabled_f(void) +{ + return 0x8000000U; +} +static inline u32 mc_enable_perfmon_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +static inline u32 mc_intr_ltc_r(void) +{ + return 0x000001c0U; +} +static inline u32 mc_enable_pb_r(void) +{ + return 0x00000204U; +} +static inline u32 mc_enable_pb_0_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pb_0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 mc_enable_pb_0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 mc_enable_pb_0_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 mc_enable_pb_0_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 mc_enable_pb_sel_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 mc_elpg_enable_r(void) +{ + return 0x0000020cU; +} +static inline u32 mc_elpg_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_elpg_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_elpg_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_pbdma_gp10b.h b/include/nvgpu/hw/gp10b/hw_pbdma_gp10b.h new file mode 100644 index 0000000..66e8ddb --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_pbdma_gp10b.h @@ -0,0 +1,615 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pbdma_gp10b_h_ +#define _hw_pbdma_gp10b_h_ + +static inline u32 pbdma_gp_entry1_r(void) +{ + return 0x10000004U; +} +static inline u32 pbdma_gp_entry1_get_hi_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pbdma_gp_entry1_length_f(u32 v) +{ + return (v & 0x1fffffU) << 10U; +} +static inline u32 pbdma_gp_entry1_length_v(u32 r) +{ + return (r >> 10U) & 0x1fffffU; +} +static inline u32 pbdma_gp_base_r(u32 i) +{ + return 0x00040048U + i*8192U; +} +static inline u32 pbdma_gp_base__size_1_v(void) +{ + return 0x00000001U; +} +static inline u32 pbdma_gp_base_offset_f(u32 v) +{ + return (v & 0x1fffffffU) << 3U; +} +static inline u32 pbdma_gp_base_rsvd_s(void) +{ + return 3U; +} +static inline u32 pbdma_gp_base_hi_r(u32 i) +{ + return 0x0004004cU + i*8192U; +} +static inline u32 pbdma_gp_base_hi_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_gp_base_hi_limit2_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 pbdma_gp_fetch_r(u32 i) +{ + return 0x00040050U + i*8192U; +} +static inline u32 pbdma_gp_get_r(u32 i) +{ + return 0x00040014U + i*8192U; +} +static inline u32 pbdma_gp_put_r(u32 i) +{ + return 0x00040000U + i*8192U; +} +static inline u32 pbdma_pb_fetch_r(u32 i) +{ + return 0x00040054U + i*8192U; +} +static inline u32 pbdma_pb_fetch_hi_r(u32 i) +{ + return 0x00040058U + i*8192U; +} +static inline u32 pbdma_get_r(u32 i) +{ + return 0x00040018U + i*8192U; +} +static inline u32 pbdma_get_hi_r(u32 i) +{ + return 0x0004001cU + i*8192U; +} +static inline u32 pbdma_put_r(u32 i) +{ + return 0x0004005cU + i*8192U; +} +static inline u32 pbdma_put_hi_r(u32 i) +{ + return 0x00040060U + i*8192U; +} +static inline u32 pbdma_formats_r(u32 i) +{ + return 0x0004009cU + i*8192U; +} +static inline u32 pbdma_formats_gp_fermi0_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_formats_pb_fermi1_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_formats_mp_fermi0_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_r(u32 i) +{ + return 0x00040084U + i*8192U; +} +static inline u32 pbdma_pb_header_priv_user_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_method_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_subchannel_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_level_main_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_pb_header_type_inc_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_pb_header_type_non_inc_f(void) +{ + return 0x60000000U; +} +static inline u32 pbdma_hdr_shadow_r(u32 i) +{ + return 0x00040118U + i*8192U; +} +static inline u32 pbdma_gp_shadow_0_r(u32 i) +{ + return 0x00040110U + i*8192U; +} +static inline u32 pbdma_gp_shadow_1_r(u32 i) +{ + return 0x00040114U + i*8192U; +} +static inline u32 pbdma_subdevice_r(u32 i) +{ + return 0x00040094U + i*8192U; +} +static inline u32 pbdma_subdevice_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 pbdma_subdevice_status_active_f(void) +{ + return 0x10000000U; +} +static inline u32 pbdma_subdevice_channel_dma_enable_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_method0_r(u32 i) +{ + return 0x000400c0U + i*8192U; +} +static inline u32 pbdma_method0_fifo_size_v(void) +{ + return 0x00000004U; +} +static inline u32 pbdma_method0_addr_f(u32 v) +{ + return (v & 0xfffU) << 2U; +} +static inline u32 pbdma_method0_addr_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 pbdma_method0_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 pbdma_method0_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_method0_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_method1_r(u32 i) +{ + return 0x000400c8U + i*8192U; +} +static inline u32 pbdma_method2_r(u32 i) +{ + return 0x000400d0U + i*8192U; +} +static inline u32 pbdma_method3_r(u32 i) +{ + return 0x000400d8U + i*8192U; +} +static inline u32 pbdma_data0_r(u32 i) +{ + return 0x000400c4U + i*8192U; +} +static inline u32 pbdma_target_r(u32 i) +{ + return 0x000400acU + i*8192U; +} +static inline u32 pbdma_target_engine_sw_f(void) +{ + return 0x1fU; +} +static inline u32 pbdma_acquire_r(u32 i) +{ + return 0x00040030U + i*8192U; +} +static inline u32 pbdma_acquire_retry_man_2_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_acquire_retry_exp_2_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_acquire_timeout_exp_f(u32 v) +{ + return (v & 0xfU) << 11U; +} +static inline u32 pbdma_acquire_timeout_exp_max_v(void) +{ + return 0x0000000fU; +} +static inline u32 pbdma_acquire_timeout_exp_max_f(void) +{ + return 0x7800U; +} +static inline u32 pbdma_acquire_timeout_man_f(u32 v) +{ + return (v & 0xffffU) << 15U; +} +static inline u32 pbdma_acquire_timeout_man_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 pbdma_acquire_timeout_man_max_f(void) +{ + return 0x7fff8000U; +} +static inline u32 pbdma_acquire_timeout_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_acquire_timeout_en_disable_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_status_r(u32 i) +{ + return 0x00040100U + i*8192U; +} +static inline u32 pbdma_channel_r(u32 i) +{ + return 0x00040120U + i*8192U; +} +static inline u32 pbdma_signature_r(u32 i) +{ + return 0x00040010U + i*8192U; +} +static inline u32 pbdma_signature_hw_valid_f(void) +{ + return 0xfaceU; +} +static inline u32 pbdma_signature_sw_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_r(u32 i) +{ + return 0x00040008U + i*8192U; +} +static inline u32 pbdma_userd_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_userd_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 pbdma_userd_addr_f(u32 v) +{ + return (v & 0x7fffffU) << 9U; +} +static inline u32 pbdma_userd_hi_r(u32 i) +{ + return 0x0004000cU + i*8192U; +} +static inline u32 pbdma_userd_hi_addr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_config_r(u32 i) +{ + return 0x000400f4U + i*8192U; +} +static inline u32 pbdma_config_auth_level_privileged_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_hce_ctrl_r(u32 i) +{ + return 0x000400e4U + i*8192U; +} +static inline u32 pbdma_hce_ctrl_hce_priv_mode_yes_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_r(u32 i) +{ + return 0x00040108U + i*8192U; +} +static inline u32 pbdma_intr_0_memreq_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pbdma_intr_0_memreq_pending_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_intr_0_memack_timeout_pending_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_intr_0_memack_extra_pending_f(void) +{ + return 0x4U; +} +static inline u32 pbdma_intr_0_memdat_timeout_pending_f(void) +{ + return 0x8U; +} +static inline u32 pbdma_intr_0_memdat_extra_pending_f(void) +{ + return 0x10U; +} +static inline u32 pbdma_intr_0_memflush_pending_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_memop_pending_f(void) +{ + return 0x40U; +} +static inline u32 pbdma_intr_0_lbconnect_pending_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_intr_0_lbreq_pending_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_0_lback_timeout_pending_f(void) +{ + return 0x200U; +} +static inline u32 pbdma_intr_0_lback_extra_pending_f(void) +{ + return 0x400U; +} +static inline u32 pbdma_intr_0_lbdat_timeout_pending_f(void) +{ + return 0x800U; +} +static inline u32 pbdma_intr_0_lbdat_extra_pending_f(void) +{ + return 0x1000U; +} +static inline u32 pbdma_intr_0_gpfifo_pending_f(void) +{ + return 0x2000U; +} +static inline u32 pbdma_intr_0_gpptr_pending_f(void) +{ + return 0x4000U; +} +static inline u32 pbdma_intr_0_gpentry_pending_f(void) +{ + return 0x8000U; +} +static inline u32 pbdma_intr_0_gpcrc_pending_f(void) +{ + return 0x10000U; +} +static inline u32 pbdma_intr_0_pbptr_pending_f(void) +{ + return 0x20000U; +} +static inline u32 pbdma_intr_0_pbentry_pending_f(void) +{ + return 0x40000U; +} +static inline u32 pbdma_intr_0_pbcrc_pending_f(void) +{ + return 0x80000U; +} +static inline u32 pbdma_intr_0_xbarconnect_pending_f(void) +{ + return 0x100000U; +} +static inline u32 pbdma_intr_0_method_pending_f(void) +{ + return 0x200000U; +} +static inline u32 pbdma_intr_0_methodcrc_pending_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_intr_0_device_pending_f(void) +{ + return 0x800000U; +} +static inline u32 pbdma_intr_0_semaphore_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 pbdma_intr_0_acquire_pending_f(void) +{ + return 0x4000000U; +} +static inline u32 pbdma_intr_0_pri_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 pbdma_intr_0_no_ctxsw_seg_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_intr_0_pbseg_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 pbdma_intr_0_signature_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_intr_0_syncpoint_illegal_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 pbdma_intr_1_r(u32 i) +{ + return 0x00040148U + i*8192U; +} +static inline u32 pbdma_intr_en_0_r(u32 i) +{ + return 0x0004010cU + i*8192U; +} +static inline u32 pbdma_intr_en_0_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_en_1_r(u32 i) +{ + return 0x0004014cU + i*8192U; +} +static inline u32 pbdma_intr_stall_r(u32 i) +{ + return 0x0004013cU + i*8192U; +} +static inline u32 pbdma_intr_stall_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_stall_1_r(u32 i) +{ + return 0x00040140U + i*8192U; +} +static inline u32 pbdma_intr_stall_1_hce_illegal_op_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_udma_nop_r(void) +{ + return 0x00000008U; +} +static inline u32 pbdma_allowed_syncpoints_r(u32 i) +{ + return 0x000400e8U + i*8192U; +} +static inline u32 pbdma_allowed_syncpoints_0_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 pbdma_allowed_syncpoints_0_index_f(u32 v) +{ + return (v & 0x7fffU) << 16U; +} +static inline u32 pbdma_allowed_syncpoints_0_index_v(u32 r) +{ + return (r >> 16U) & 0x7fffU; +} +static inline u32 pbdma_allowed_syncpoints_1_valid_f(u32 v) +{ + return (v & 0x1U) << 15U; +} +static inline u32 pbdma_allowed_syncpoints_1_index_f(u32 v) +{ + return (v & 0x7fffU) << 0U; +} +static inline u32 pbdma_syncpointa_r(u32 i) +{ + return 0x000400a4U + i*8192U; +} +static inline u32 pbdma_syncpointa_payload_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pbdma_syncpointb_r(u32 i) +{ + return 0x000400a8U + i*8192U; +} +static inline u32 pbdma_syncpointb_op_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pbdma_syncpointb_op_wait_v(void) +{ + return 0x00000000U; +} +static inline u32 pbdma_syncpointb_wait_switch_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pbdma_syncpointb_wait_switch_en_v(void) +{ + return 0x00000001U; +} +static inline u32 pbdma_syncpointb_syncpt_index_v(u32 r) +{ + return (r >> 8U) & 0xfffU; +} +static inline u32 pbdma_runlist_timeslice_r(u32 i) +{ + return 0x000400f8U + i*8192U; +} +static inline u32 pbdma_runlist_timeslice_timeout_128_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_runlist_timeslice_timescale_3_f(void) +{ + return 0x3000U; +} +static inline u32 pbdma_runlist_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_perf_gp10b.h b/include/nvgpu/hw/gp10b/hw_perf_gp10b.h new file mode 100644 index 0000000..43424e1 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_perf_gp10b.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2015-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_perf_gp10b_h_ +#define _hw_perf_gp10b_h_ + +static inline u32 perf_pmmsys_base_v(void) +{ + return 0x001b0000U; +} +static inline u32 perf_pmmsys_extent_v(void) +{ + return 0x001b0fffU; +} +static inline u32 perf_pmasys_control_r(void) +{ + return 0x001b4000U; +} +static inline u32 perf_pmasys_control_membuf_status_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_f(void) +{ + return 0x10U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_f(void) +{ + return 0x20U; +} +static inline u32 perf_pmasys_mem_block_r(void) +{ + return 0x001b4070U; +} +static inline u32 perf_pmasys_mem_block_base_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 perf_pmasys_mem_block_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 perf_pmasys_mem_block_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 perf_pmasys_mem_block_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 perf_pmasys_mem_block_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 perf_pmasys_mem_block_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_mem_block_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_outbase_r(void) +{ + return 0x001b4074U; +} +static inline u32 perf_pmasys_outbase_ptr_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_outbaseupper_r(void) +{ + return 0x001b4078U; +} +static inline u32 perf_pmasys_outbaseupper_ptr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 perf_pmasys_outsize_r(void) +{ + return 0x001b407cU; +} +static inline u32 perf_pmasys_outsize_numbytes_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_mem_bytes_r(void) +{ + return 0x001b4084U; +} +static inline u32 perf_pmasys_mem_bytes_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_mem_bump_r(void) +{ + return 0x001b4088U; +} +static inline u32 perf_pmasys_mem_bump_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_enginestatus_r(void) +{ + return 0x001b40a4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_f(void) +{ + return 0x10U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_pram_gp10b.h b/include/nvgpu/hw/gp10b/hw_pram_gp10b.h new file mode 100644 index 0000000..aef0e69 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_pram_gp10b.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pram_gp10b_h_ +#define _hw_pram_gp10b_h_ + +static inline u32 pram_data032_r(u32 i) +{ + return 0x00700000U + i*4U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_pri_ringmaster_gp10b.h b/include/nvgpu/hw/gp10b/hw_pri_ringmaster_gp10b.h new file mode 100644 index 0000000..03a3854 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_pri_ringmaster_gp10b.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringmaster_gp10b_h_ +#define _hw_pri_ringmaster_gp10b_h_ + +static inline u32 pri_ringmaster_command_r(void) +{ + return 0x0012004cU; +} +static inline u32 pri_ringmaster_command_cmd_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 pri_ringmaster_command_cmd_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 pri_ringmaster_command_cmd_no_cmd_v(void) +{ + return 0x00000000U; +} +static inline u32 pri_ringmaster_command_cmd_start_ring_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_command_cmd_ack_interrupt_f(void) +{ + return 0x2U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_f(void) +{ + return 0x3U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_bc_grp_all_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_command_data_r(void) +{ + return 0x00120048U; +} +static inline u32 pri_ringmaster_start_results_r(void) +{ + return 0x00120050U; +} +static inline u32 pri_ringmaster_start_results_connectivity_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_start_results_connectivity_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 pri_ringmaster_intr_status0_r(void) +{ + return 0x00120058U; +} +static inline u32 pri_ringmaster_intr_status0_ring_start_conn_fault_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_disconnect_fault_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_overflow_fault_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_gbl_write_error_sys_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status1_r(void) +{ + return 0x0012005cU; +} +static inline u32 pri_ringmaster_global_ctl_r(void) +{ + return 0x00120060U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_asserted_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_deasserted_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_enum_fbp_r(void) +{ + return 0x00120074U; +} +static inline u32 pri_ringmaster_enum_fbp_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_gpc_r(void) +{ + return 0x00120078U; +} +static inline u32 pri_ringmaster_enum_gpc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_ltc_r(void) +{ + return 0x0012006cU; +} +static inline u32 pri_ringmaster_enum_ltc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_pri_ringstation_gpc_gp10b.h b/include/nvgpu/hw/gp10b/hw_pri_ringstation_gpc_gp10b.h new file mode 100644 index 0000000..ba55658 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_pri_ringstation_gpc_gp10b.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_gpc_gp10b_h_ +#define _hw_pri_ringstation_gpc_gp10b_h_ + +static inline u32 pri_ringstation_gpc_master_config_r(u32 i) +{ + return 0x00128300U + i*4U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_adr_r(void) +{ + return 0x00128120U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_wrdat_r(void) +{ + return 0x00128124U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_info_r(void) +{ + return 0x00128128U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_info_subid_v(u32 r) +{ + return (r >> 24U) & 0x3fU; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_info_priv_level_v(u32 r) +{ + return (r >> 20U) & 0x3U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_code_r(void) +{ + return 0x0012812cU; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_pri_ringstation_sys_gp10b.h b/include/nvgpu/hw/gp10b/hw_pri_ringstation_sys_gp10b.h new file mode 100644 index 0000000..1dcb1a3 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_pri_ringstation_sys_gp10b.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_sys_gp10b_h_ +#define _hw_pri_ringstation_sys_gp10b_h_ + +static inline u32 pri_ringstation_sys_master_config_r(u32 i) +{ + return 0x00122300U + i*4U; +} +static inline u32 pri_ringstation_sys_decode_config_r(void) +{ + return 0x00122204U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_m(void) +{ + return 0x7U << 0U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_drop_on_ring_not_started_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringstation_sys_priv_error_adr_r(void) +{ + return 0x00122120U; +} +static inline u32 pri_ringstation_sys_priv_error_wrdat_r(void) +{ + return 0x00122124U; +} +static inline u32 pri_ringstation_sys_priv_error_info_r(void) +{ + return 0x00122128U; +} +static inline u32 pri_ringstation_sys_priv_error_info_subid_v(u32 r) +{ + return (r >> 24U) & 0x3fU; +} +static inline u32 pri_ringstation_sys_priv_error_info_priv_level_v(u32 r) +{ + return (r >> 20U) & 0x3U; +} +static inline u32 pri_ringstation_sys_priv_error_code_r(void) +{ + return 0x0012212cU; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_proj_gp10b.h b/include/nvgpu/hw/gp10b/hw_proj_gp10b.h new file mode 100644 index 0000000..a885e93 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_proj_gp10b.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_proj_gp10b_h_ +#define _hw_proj_gp10b_h_ + +static inline u32 proj_gpc_base_v(void) +{ + return 0x00500000U; +} +static inline u32 proj_gpc_shared_base_v(void) +{ + return 0x00418000U; +} +static inline u32 proj_gpc_stride_v(void) +{ + return 0x00008000U; +} +static inline u32 proj_gpc_priv_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_ltc_stride_v(void) +{ + return 0x00002000U; +} +static inline u32 proj_lts_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_fbpa_base_v(void) +{ + return 0x00900000U; +} +static inline u32 proj_fbpa_shared_base_v(void) +{ + return 0x009a0000U; +} +static inline u32 proj_fbpa_stride_v(void) +{ + return 0x00004000U; +} +static inline u32 proj_ppc_in_gpc_base_v(void) +{ + return 0x00003000U; +} +static inline u32 proj_ppc_in_gpc_shared_base_v(void) +{ + return 0x00003e00U; +} +static inline u32 proj_ppc_in_gpc_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_rop_base_v(void) +{ + return 0x00410000U; +} +static inline u32 proj_rop_shared_base_v(void) +{ + return 0x00408800U; +} +static inline u32 proj_rop_stride_v(void) +{ + return 0x00000400U; +} +static inline u32 proj_tpc_in_gpc_base_v(void) +{ + return 0x00004000U; +} +static inline u32 proj_tpc_in_gpc_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_tpc_in_gpc_shared_base_v(void) +{ + return 0x00001800U; +} +static inline u32 proj_host_num_engines_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_host_num_pbdma_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_tpc_per_gpc_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_scal_litter_num_sm_per_tpc_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_fbps_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_fbpas_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_gpcs_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_pes_per_gpc_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_tpcs_per_pes_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_scal_litter_num_zcull_banks_v(void) +{ + return 0x00000004U; +} +static inline u32 proj_scal_max_gpcs_v(void) +{ + return 0x00000020U; +} +static inline u32 proj_scal_max_tpc_per_gpc_v(void) +{ + return 0x00000008U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_pwr_gp10b.h b/include/nvgpu/hw/gp10b/hw_pwr_gp10b.h new file mode 100644 index 0000000..f067be7 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_pwr_gp10b.h @@ -0,0 +1,883 @@ +/* + * Copyright (c) 2014-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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pwr_gp10b_h_ +#define _hw_pwr_gp10b_h_ + +static inline u32 pwr_falcon_irqsset_r(void) +{ + return 0x0010a000U; +} +static inline u32 pwr_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqsclr_r(void) +{ + return 0x0010a004U; +} +static inline u32 pwr_falcon_irqstat_r(void) +{ + return 0x0010a008U; +} +static inline u32 pwr_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 pwr_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 pwr_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqmode_r(void) +{ + return 0x0010a00cU; +} +static inline u32 pwr_falcon_irqmset_r(void) +{ + return 0x0010a010U; +} +static inline u32 pwr_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_r(void) +{ + return 0x0010a014U; +} +static inline u32 pwr_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqmask_r(void) +{ + return 0x0010a018U; +} +static inline u32 pwr_falcon_irqdest_r(void) +{ + return 0x0010a01cU; +} +static inline u32 pwr_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 pwr_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 pwr_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 pwr_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 pwr_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 pwr_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 pwr_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 pwr_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 pwr_falcon_curctx_r(void) +{ + return 0x0010a050U; +} +static inline u32 pwr_falcon_nxtctx_r(void) +{ + return 0x0010a054U; +} +static inline u32 pwr_falcon_mailbox0_r(void) +{ + return 0x0010a040U; +} +static inline u32 pwr_falcon_mailbox1_r(void) +{ + return 0x0010a044U; +} +static inline u32 pwr_falcon_itfen_r(void) +{ + return 0x0010a048U; +} +static inline u32 pwr_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 pwr_falcon_idlestate_r(void) +{ + return 0x0010a04cU; +} +static inline u32 pwr_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 pwr_falcon_os_r(void) +{ + return 0x0010a080U; +} +static inline u32 pwr_falcon_engctl_r(void) +{ + return 0x0010a0a4U; +} +static inline u32 pwr_falcon_cpuctl_r(void) +{ + return 0x0010a100U; +} +static inline u32 pwr_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 pwr_falcon_cpuctl_alias_r(void) +{ + return 0x0010a130U; +} +static inline u32 pwr_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_pmu_scpctl_stat_r(void) +{ + return 0x0010ac08U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_m(void) +{ + return 0x1U << 20U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 pwr_falcon_imemc_r(u32 i) +{ + return 0x0010a180U + i*16U; +} +static inline u32 pwr_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_imemd_r(u32 i) +{ + return 0x0010a184U + i*16U; +} +static inline u32 pwr_falcon_imemt_r(u32 i) +{ + return 0x0010a188U + i*16U; +} +static inline u32 pwr_falcon_sctl_r(void) +{ + return 0x0010a240U; +} +static inline u32 pwr_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 pwr_falcon_bootvec_r(void) +{ + return 0x0010a104U; +} +static inline u32 pwr_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_falcon_dmactl_r(void) +{ + return 0x0010a10cU; +} +static inline u32 pwr_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 pwr_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_falcon_hwcfg_r(void) +{ + return 0x0010a108U; +} +static inline u32 pwr_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 pwr_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 pwr_falcon_dmatrfbase_r(void) +{ + return 0x0010a110U; +} +static inline u32 pwr_falcon_dmatrfbase1_r(void) +{ + return 0x0010a128U; +} +static inline u32 pwr_falcon_dmatrfmoffs_r(void) +{ + return 0x0010a114U; +} +static inline u32 pwr_falcon_dmatrfcmd_r(void) +{ + return 0x0010a118U; +} +static inline u32 pwr_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 pwr_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 pwr_falcon_dmatrffboffs_r(void) +{ + return 0x0010a11cU; +} +static inline u32 pwr_falcon_exterraddr_r(void) +{ + return 0x0010a168U; +} +static inline u32 pwr_falcon_exterrstat_r(void) +{ + return 0x0010a16cU; +} +static inline u32 pwr_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 pwr_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 pwr_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_r(void) +{ + return 0x0010a200U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 pwr_pmu_falcon_icd_rdata_r(void) +{ + return 0x0010a20cU; +} +static inline u32 pwr_falcon_dmemc_r(u32 i) +{ + return 0x0010a1c0U + i*8U; +} +static inline u32 pwr_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 pwr_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 pwr_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 pwr_falcon_dmemd_r(u32 i) +{ + return 0x0010a1c4U + i*8U; +} +static inline u32 pwr_pmu_new_instblk_r(void) +{ + return 0x0010a480U; +} +static inline u32 pwr_pmu_new_instblk_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 pwr_pmu_new_instblk_target_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 pwr_pmu_new_instblk_valid_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 pwr_pmu_mutex_id_r(void) +{ + return 0x0010a488U; +} +static inline u32 pwr_pmu_mutex_id_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_id_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_value_not_avail_v(void) +{ + return 0x000000ffU; +} +static inline u32 pwr_pmu_mutex_id_release_r(void) +{ + return 0x0010a48cU; +} +static inline u32 pwr_pmu_mutex_id_release_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_m(void) +{ + return 0xffU << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_mutex_r(u32 i) +{ + return 0x0010a580U + i*4U; +} +static inline u32 pwr_pmu_mutex__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 pwr_pmu_mutex_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_value_initial_lock_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_queue_head_r(u32 i) +{ + return 0x0010a4a0U + i*4U; +} +static inline u32 pwr_pmu_queue_head__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_queue_head_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_head_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_queue_tail_r(u32 i) +{ + return 0x0010a4b0U + i*4U; +} +static inline u32 pwr_pmu_queue_tail__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_queue_tail_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_tail_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_head_r(void) +{ + return 0x0010a4c8U; +} +static inline u32 pwr_pmu_msgq_head_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_head_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_tail_r(void) +{ + return 0x0010a4ccU; +} +static inline u32 pwr_pmu_msgq_tail_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_tail_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_idle_mask_r(u32 i) +{ + return 0x0010a504U + i*16U; +} +static inline u32 pwr_pmu_idle_mask_gr_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pwr_pmu_idle_mask_ce_2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 pwr_pmu_idle_mask_1_r(u32 i) +{ + return 0x0010aa34U + i*8U; +} +static inline u32 pwr_pmu_idle_count_r(u32 i) +{ + return 0x0010a508U + i*16U; +} +static inline u32 pwr_pmu_idle_count_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_count_value_v(u32 r) +{ + return (r >> 0U) & 0x7fffffffU; +} +static inline u32 pwr_pmu_idle_count_reset_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 pwr_pmu_idle_ctrl_r(u32 i) +{ + return 0x0010a50cU + i*16U; +} +static inline u32 pwr_pmu_idle_ctrl_value_m(void) +{ + return 0x3U << 0U; +} +static inline u32 pwr_pmu_idle_ctrl_value_busy_f(void) +{ + return 0x2U; +} +static inline u32 pwr_pmu_idle_ctrl_value_always_f(void) +{ + return 0x3U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_disabled_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_idle_threshold_r(u32 i) +{ + return 0x0010a8a0U + i*4U; +} +static inline u32 pwr_pmu_idle_threshold_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_intr_r(void) +{ + return 0x0010a9e8U; +} +static inline u32 pwr_pmu_idle_intr_en_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_en_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_idle_intr_en_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_r(void) +{ + return 0x0010a9ecU; +} +static inline u32 pwr_pmu_idle_intr_status_intr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_m(void) +{ + return 0x1U << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_mask_supp_r(u32 i) +{ + return 0x0010a9f0U + i*8U; +} +static inline u32 pwr_pmu_idle_mask_1_supp_r(u32 i) +{ + return 0x0010a9f4U + i*8U; +} +static inline u32 pwr_pmu_idle_ctrl_supp_r(u32 i) +{ + return 0x0010aa30U + i*8U; +} +static inline u32 pwr_pmu_debug_r(u32 i) +{ + return 0x0010a5c0U + i*4U; +} +static inline u32 pwr_pmu_debug__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_mailbox_r(u32 i) +{ + return 0x0010a450U + i*4U; +} +static inline u32 pwr_pmu_mailbox__size_1_v(void) +{ + return 0x0000000cU; +} +static inline u32 pwr_pmu_bar0_addr_r(void) +{ + return 0x0010a7a0U; +} +static inline u32 pwr_pmu_bar0_data_r(void) +{ + return 0x0010a7a4U; +} +static inline u32 pwr_pmu_bar0_ctl_r(void) +{ + return 0x0010a7acU; +} +static inline u32 pwr_pmu_bar0_timeout_r(void) +{ + return 0x0010a7a8U; +} +static inline u32 pwr_pmu_bar0_fecs_error_r(void) +{ + return 0x0010a988U; +} +static inline u32 pwr_pmu_bar0_error_status_r(void) +{ + return 0x0010a7b0U; +} +static inline u32 pwr_pmu_pg_idlefilth_r(u32 i) +{ + return 0x0010a6c0U + i*4U; +} +static inline u32 pwr_pmu_pg_ppuidlefilth_r(u32 i) +{ + return 0x0010a6e8U + i*4U; +} +static inline u32 pwr_pmu_pg_idle_cnt_r(u32 i) +{ + return 0x0010a710U + i*4U; +} +static inline u32 pwr_pmu_pg_intren_r(u32 i) +{ + return 0x0010a760U + i*4U; +} +static inline u32 pwr_fbif_transcfg_r(u32 i) +{ + return 0x0010ae00U + i*4U; +} +static inline u32 pwr_fbif_transcfg_target_local_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_target_coherent_sysmem_f(void) +{ + return 0x1U; +} +static inline u32 pwr_fbif_transcfg_target_noncoherent_sysmem_f(void) +{ + return 0x2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_s(void) +{ + return 1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_virtual_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_mem_type_physical_f(void) +{ + return 0x4U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_ram_gp10b.h b/include/nvgpu/hw/gp10b/hw_ram_gp10b.h new file mode 100644 index 0000000..cc83f52 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_ram_gp10b.h @@ -0,0 +1,519 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ram_gp10b_h_ +#define _hw_ram_gp10b_h_ + +static inline u32 ram_in_ramfc_s(void) +{ + return 4096U; +} +static inline u32 ram_in_ramfc_w(void) +{ + return 0U; +} +static inline u32 ram_in_page_dir_base_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ram_in_page_dir_base_target_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 ram_in_page_dir_base_vol_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_m(void) +{ + return 0x1U << 4U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_true_f(void) +{ + return 0x10U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_m(void) +{ + return 0x1U << 5U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_true_f(void) +{ + return 0x20U; +} +static inline u32 ram_in_use_ver2_pt_format_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ram_in_use_ver2_pt_format_m(void) +{ + return 0x1U << 10U; +} +static inline u32 ram_in_use_ver2_pt_format_w(void) +{ + return 128U; +} +static inline u32 ram_in_use_ver2_pt_format_true_f(void) +{ + return 0x400U; +} +static inline u32 ram_in_use_ver2_pt_format_false_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_big_page_size_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 ram_in_big_page_size_m(void) +{ + return 0x1U << 11U; +} +static inline u32 ram_in_big_page_size_w(void) +{ + return 128U; +} +static inline u32 ram_in_big_page_size_128kb_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_big_page_size_64kb_f(void) +{ + return 0x800U; +} +static inline u32 ram_in_page_dir_base_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_page_dir_base_lo_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_page_dir_base_hi_w(void) +{ + return 129U; +} +static inline u32 ram_in_adr_limit_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_adr_limit_lo_w(void) +{ + return 130U; +} +static inline u32 ram_in_adr_limit_hi_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_in_adr_limit_hi_w(void) +{ + return 131U; +} +static inline u32 ram_in_engine_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_cs_wfi_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_engine_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_engine_cs_fg_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_engine_cs_fg_f(void) +{ + return 0x8U; +} +static inline u32 ram_in_gr_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_gr_wfi_target_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_mode_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_mode_physical_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_gr_wfi_mode_physical_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_gr_wfi_mode_virtual_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_gr_wfi_mode_virtual_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_gr_wfi_ptr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_gr_wfi_ptr_lo_w(void) +{ + return 132U; +} +static inline u32 ram_in_gr_wfi_ptr_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_gr_wfi_ptr_hi_w(void) +{ + return 133U; +} +static inline u32 ram_in_base_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 ram_in_alloc_size_v(void) +{ + return 0x00001000U; +} +static inline u32 ram_fc_size_val_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_fc_gp_put_w(void) +{ + return 0U; +} +static inline u32 ram_fc_userd_w(void) +{ + return 2U; +} +static inline u32 ram_fc_userd_hi_w(void) +{ + return 3U; +} +static inline u32 ram_fc_signature_w(void) +{ + return 4U; +} +static inline u32 ram_fc_gp_get_w(void) +{ + return 5U; +} +static inline u32 ram_fc_pb_get_w(void) +{ + return 6U; +} +static inline u32 ram_fc_pb_get_hi_w(void) +{ + return 7U; +} +static inline u32 ram_fc_pb_top_level_get_w(void) +{ + return 8U; +} +static inline u32 ram_fc_pb_top_level_get_hi_w(void) +{ + return 9U; +} +static inline u32 ram_fc_acquire_w(void) +{ + return 12U; +} +static inline u32 ram_fc_semaphorea_w(void) +{ + return 14U; +} +static inline u32 ram_fc_semaphoreb_w(void) +{ + return 15U; +} +static inline u32 ram_fc_semaphorec_w(void) +{ + return 16U; +} +static inline u32 ram_fc_semaphored_w(void) +{ + return 17U; +} +static inline u32 ram_fc_gp_base_w(void) +{ + return 18U; +} +static inline u32 ram_fc_gp_base_hi_w(void) +{ + return 19U; +} +static inline u32 ram_fc_gp_fetch_w(void) +{ + return 20U; +} +static inline u32 ram_fc_pb_fetch_w(void) +{ + return 21U; +} +static inline u32 ram_fc_pb_fetch_hi_w(void) +{ + return 22U; +} +static inline u32 ram_fc_pb_put_w(void) +{ + return 23U; +} +static inline u32 ram_fc_pb_put_hi_w(void) +{ + return 24U; +} +static inline u32 ram_fc_pb_header_w(void) +{ + return 33U; +} +static inline u32 ram_fc_pb_count_w(void) +{ + return 34U; +} +static inline u32 ram_fc_subdevice_w(void) +{ + return 37U; +} +static inline u32 ram_fc_formats_w(void) +{ + return 39U; +} +static inline u32 ram_fc_allowed_syncpoints_w(void) +{ + return 58U; +} +static inline u32 ram_fc_syncpointa_w(void) +{ + return 41U; +} +static inline u32 ram_fc_syncpointb_w(void) +{ + return 42U; +} +static inline u32 ram_fc_target_w(void) +{ + return 43U; +} +static inline u32 ram_fc_hce_ctrl_w(void) +{ + return 57U; +} +static inline u32 ram_fc_chid_w(void) +{ + return 58U; +} +static inline u32 ram_fc_chid_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_fc_chid_id_w(void) +{ + return 0U; +} +static inline u32 ram_fc_config_w(void) +{ + return 61U; +} +static inline u32 ram_fc_runlist_timeslice_w(void) +{ + return 62U; +} +static inline u32 ram_userd_base_shift_v(void) +{ + return 0x00000009U; +} +static inline u32 ram_userd_chan_size_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_userd_put_w(void) +{ + return 16U; +} +static inline u32 ram_userd_get_w(void) +{ + return 17U; +} +static inline u32 ram_userd_ref_w(void) +{ + return 18U; +} +static inline u32 ram_userd_put_hi_w(void) +{ + return 19U; +} +static inline u32 ram_userd_ref_threshold_w(void) +{ + return 20U; +} +static inline u32 ram_userd_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_userd_get_hi_w(void) +{ + return 24U; +} +static inline u32 ram_userd_gp_get_w(void) +{ + return 34U; +} +static inline u32 ram_userd_gp_put_w(void) +{ + return 35U; +} +static inline u32 ram_userd_gp_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_gp_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_rl_entry_size_v(void) +{ + return 0x00000008U; +} +static inline u32 ram_rl_entry_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_type_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 ram_rl_entry_type_chid_f(void) +{ + return 0x0U; +} +static inline u32 ram_rl_entry_type_tsg_f(void) +{ + return 0x2000U; +} +static inline u32 ram_rl_entry_timeslice_scale_f(u32 v) +{ + return (v & 0xfU) << 14U; +} +static inline u32 ram_rl_entry_timeslice_scale_3_f(void) +{ + return 0xc000U; +} +static inline u32 ram_rl_entry_timeslice_timeout_f(u32 v) +{ + return (v & 0xffU) << 18U; +} +static inline u32 ram_rl_entry_timeslice_timeout_128_f(void) +{ + return 0x2000000U; +} +static inline u32 ram_rl_entry_tsg_length_f(u32 v) +{ + return (v & 0x3fU) << 26U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_therm_gp10b.h b/include/nvgpu/hw/gp10b/hw_therm_gp10b.h new file mode 100644 index 0000000..49fb718 --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_therm_gp10b.h @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2014-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_therm_gp10b_h_ +#define _hw_therm_gp10b_h_ + +static inline u32 therm_use_a_r(void) +{ + return 0x00020798U; +} +static inline u32 therm_use_a_ext_therm_0_enable_f(void) +{ + return 0x1U; +} +static inline u32 therm_use_a_ext_therm_1_enable_f(void) +{ + return 0x2U; +} +static inline u32 therm_use_a_ext_therm_2_enable_f(void) +{ + return 0x4U; +} +static inline u32 therm_evt_ext_therm_0_r(void) +{ + return 0x00020700U; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_init_v(void) +{ + return 0x00000001U; +} +static inline u32 therm_evt_ext_therm_0_mode_f(u32 v) +{ + return (v & 0x3U) << 30U; +} +static inline u32 therm_evt_ext_therm_0_mode_normal_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_0_mode_inverted_v(void) +{ + return 0x00000001U; +} +static inline u32 therm_evt_ext_therm_0_mode_forced_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_evt_ext_therm_0_mode_cleared_v(void) +{ + return 0x00000003U; +} +static inline u32 therm_evt_ext_therm_1_r(void) +{ + return 0x00020704U; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_init_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_evt_ext_therm_1_mode_f(u32 v) +{ + return (v & 0x3U) << 30U; +} +static inline u32 therm_evt_ext_therm_1_mode_normal_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_1_mode_inverted_v(void) +{ + return 0x00000001U; +} +static inline u32 therm_evt_ext_therm_1_mode_forced_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_evt_ext_therm_1_mode_cleared_v(void) +{ + return 0x00000003U; +} +static inline u32 therm_evt_ext_therm_2_r(void) +{ + return 0x00020708U; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_init_v(void) +{ + return 0x00000003U; +} +static inline u32 therm_evt_ext_therm_2_mode_f(u32 v) +{ + return (v & 0x3U) << 30U; +} +static inline u32 therm_evt_ext_therm_2_mode_normal_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_2_mode_inverted_v(void) +{ + return 0x00000001U; +} +static inline u32 therm_evt_ext_therm_2_mode_forced_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_evt_ext_therm_2_mode_cleared_v(void) +{ + return 0x00000003U; +} +static inline u32 therm_weight_1_r(void) +{ + return 0x00020024U; +} +static inline u32 therm_config1_r(void) +{ + return 0x00020050U; +} +static inline u32 therm_config2_r(void) +{ + return 0x00020130U; +} +static inline u32 therm_config2_slowdown_factor_extended_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 therm_config2_grad_enable_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 therm_gate_ctrl_r(u32 i) +{ + return 0x00020200U + i*4U; +} +static inline u32 therm_gate_ctrl_eng_clk_m(void) +{ + return 0x3U << 0U; +} +static inline u32 therm_gate_ctrl_eng_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_eng_clk_auto_f(void) +{ + return 0x1U; +} +static inline u32 therm_gate_ctrl_eng_clk_stop_f(void) +{ + return 0x2U; +} +static inline u32 therm_gate_ctrl_blk_clk_m(void) +{ + return 0x3U << 2U; +} +static inline u32 therm_gate_ctrl_blk_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_blk_clk_auto_f(void) +{ + return 0x4U; +} +static inline u32 therm_gate_ctrl_eng_pwr_m(void) +{ + return 0x3U << 4U; +} +static inline u32 therm_gate_ctrl_eng_pwr_auto_f(void) +{ + return 0x10U; +} +static inline u32 therm_gate_ctrl_eng_pwr_off_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_gate_ctrl_eng_pwr_off_f(void) +{ + return 0x20U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_m(void) +{ + return 0x1fU << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_f(u32 v) +{ + return (v & 0x7U) << 13U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_m(void) +{ + return 0x7U << 13U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_m(void) +{ + return 0xfU << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_m(void) +{ + return 0xfU << 20U; +} +static inline u32 therm_fecs_idle_filter_r(void) +{ + return 0x00020288U; +} +static inline u32 therm_fecs_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_hubmmu_idle_filter_r(void) +{ + return 0x0002028cU; +} +static inline u32 therm_hubmmu_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_clk_slowdown_r(u32 i) +{ + return 0x00020160U + i*4U; +} +static inline u32 therm_clk_slowdown_idle_factor_f(u32 v) +{ + return (v & 0x3fU) << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_m(void) +{ + return 0x3fU << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_v(u32 r) +{ + return (r >> 16U) & 0x3fU; +} +static inline u32 therm_clk_slowdown_idle_factor_disabled_f(void) +{ + return 0x0U; +} +static inline u32 therm_grad_stepping_table_r(u32 i) +{ + return 0x000202c8U + i*4U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by1p5_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by2_f(void) +{ + return 0x2U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by4_f(void) +{ + return 0x6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f(void) +{ + return 0xeU; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_f(u32 v) +{ + return (v & 0x3fU) << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_m(void) +{ + return 0x3fU << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_f(u32 v) +{ + return (v & 0x3fU) << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_m(void) +{ + return 0x3fU << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_m(void) +{ + return 0x3fU << 24U; +} +static inline u32 therm_grad_stepping0_r(void) +{ + return 0x000202c0U; +} +static inline u32 therm_grad_stepping0_feature_s(void) +{ + return 1U; +} +static inline u32 therm_grad_stepping0_feature_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 therm_grad_stepping0_feature_m(void) +{ + return 0x1U << 0U; +} +static inline u32 therm_grad_stepping0_feature_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 therm_grad_stepping0_feature_enable_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping1_r(void) +{ + return 0x000202c4U; +} +static inline u32 therm_grad_stepping1_pdiv_duration_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 therm_clk_timing_r(u32 i) +{ + return 0x000203c0U + i*4U; +} +static inline u32 therm_clk_timing_grad_slowdown_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_m(void) +{ + return 0x1U << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_enabled_f(void) +{ + return 0x10000U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_timer_gp10b.h b/include/nvgpu/hw/gp10b/hw_timer_gp10b.h new file mode 100644 index 0000000..54facfc --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_timer_gp10b.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_timer_gp10b_h_ +#define _hw_timer_gp10b_h_ + +static inline u32 timer_pri_timeout_r(void) +{ + return 0x00009080U; +} +static inline u32 timer_pri_timeout_period_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 timer_pri_timeout_period_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 timer_pri_timeout_period_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 timer_pri_timeout_en_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 timer_pri_timeout_en_m(void) +{ + return 0x1U << 31U; +} +static inline u32 timer_pri_timeout_en_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_en_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 timer_pri_timeout_en_en_disabled_f(void) +{ + return 0x0U; +} +static inline u32 timer_pri_timeout_save_0_r(void) +{ + return 0x00009084U; +} +static inline u32 timer_pri_timeout_save_0_fecs_tgt_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_save_0_addr_v(u32 r) +{ + return (r >> 2U) & 0x3fffffU; +} +static inline u32 timer_pri_timeout_save_0_write_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 timer_pri_timeout_save_1_r(void) +{ + return 0x00009088U; +} +static inline u32 timer_pri_timeout_fecs_errcode_r(void) +{ + return 0x0000908cU; +} +static inline u32 timer_time_0_r(void) +{ + return 0x00009400U; +} +static inline u32 timer_time_1_r(void) +{ + return 0x00009410U; +} +#endif diff --git a/include/nvgpu/hw/gp10b/hw_top_gp10b.h b/include/nvgpu/hw/gp10b/hw_top_gp10b.h new file mode 100644 index 0000000..a7b7c2b --- /dev/null +++ b/include/nvgpu/hw/gp10b/hw_top_gp10b.h @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_top_gp10b_h_ +#define _hw_top_gp10b_h_ + +static inline u32 top_num_gpcs_r(void) +{ + return 0x00022430U; +} +static inline u32 top_num_gpcs_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_tpc_per_gpc_r(void) +{ + return 0x00022434U; +} +static inline u32 top_tpc_per_gpc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_fbps_r(void) +{ + return 0x00022438U; +} +static inline u32 top_num_fbps_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_ltc_per_fbp_r(void) +{ + return 0x00022450U; +} +static inline u32 top_ltc_per_fbp_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_slices_per_ltc_r(void) +{ + return 0x0002245cU; +} +static inline u32 top_slices_per_ltc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_ltcs_r(void) +{ + return 0x00022454U; +} +static inline u32 top_device_info_r(u32 i) +{ + return 0x00022700U + i*4U; +} +static inline u32 top_device_info__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 top_device_info_chain_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 top_device_info_chain_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_engine_enum_v(u32 r) +{ + return (r >> 26U) & 0xfU; +} +static inline u32 top_device_info_runlist_enum_v(u32 r) +{ + return (r >> 21U) & 0xfU; +} +static inline u32 top_device_info_intr_enum_v(u32 r) +{ + return (r >> 15U) & 0x1fU; +} +static inline u32 top_device_info_reset_enum_v(u32 r) +{ + return (r >> 9U) & 0x1fU; +} +static inline u32 top_device_info_type_enum_v(u32 r) +{ + return (r >> 2U) & 0x1fffffffU; +} +static inline u32 top_device_info_type_enum_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_type_enum_graphics_f(void) +{ + return 0x0U; +} +static inline u32 top_device_info_type_enum_copy2_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_type_enum_copy2_f(void) +{ + return 0xcU; +} +static inline u32 top_device_info_type_enum_lce_v(void) +{ + return 0x00000013U; +} +static inline u32 top_device_info_type_enum_lce_f(void) +{ + return 0x4cU; +} +static inline u32 top_device_info_engine_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 top_device_info_runlist_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 top_device_info_intr_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 top_device_info_reset_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_entry_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 top_device_info_entry_not_valid_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_entry_enum_v(void) +{ + return 0x00000002U; +} +static inline u32 top_device_info_entry_engine_type_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_entry_data_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_data_type_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 top_device_info_data_type_enum2_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_data_inst_id_v(u32 r) +{ + return (r >> 26U) & 0xfU; +} +static inline u32 top_device_info_data_pri_base_v(u32 r) +{ + return (r >> 12U) & 0xfffU; +} +static inline u32 top_device_info_data_pri_base_align_v(void) +{ + return 0x0000000cU; +} +static inline u32 top_device_info_data_fault_id_enum_v(u32 r) +{ + return (r >> 3U) & 0x1fU; +} +static inline u32 top_device_info_data_fault_id_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_data_fault_id_valid_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_bus_gv100.h b/include/nvgpu/hw/gv100/hw_bus_gv100.h new file mode 100644 index 0000000..7771f1e --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_bus_gv100.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_bus_gv100_h_ +#define _hw_bus_gv100_h_ + +static inline u32 bus_sw_scratch_r(u32 i) +{ + return 0x00001580U + i*4U; +} +static inline u32 bus_bar0_window_r(void) +{ + return 0x00001700U; +} +static inline u32 bus_bar0_window_base_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 bus_bar0_window_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar0_window_target_sys_mem_coherent_f(void) +{ + return 0x2000000U; +} +static inline u32 bus_bar0_window_target_sys_mem_noncoherent_f(void) +{ + return 0x3000000U; +} +static inline u32 bus_bar0_window_target_bar0_window_base_shift_v(void) +{ + return 0x00000010U; +} +static inline u32 bus_bar1_block_r(void) +{ + return 0x00001704U; +} +static inline u32 bus_bar1_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar1_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar1_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar1_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar1_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar2_block_r(void) +{ + return 0x00001714U; +} +static inline u32 bus_bar2_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar2_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar2_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar2_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar2_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar1_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bar2_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bind_status_r(void) +{ + return 0x00001710U; +} +static inline u32 bus_bind_status_bar1_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 bus_bind_status_bar1_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar1_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 bus_bind_status_bar1_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 bus_bind_status_bar1_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar1_outstanding_true_f(void) +{ + return 0x2U; +} +static inline u32 bus_bind_status_bar2_pending_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 bus_bind_status_bar2_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar2_pending_busy_f(void) +{ + return 0x4U; +} +static inline u32 bus_bind_status_bar2_outstanding_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 bus_bind_status_bar2_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar2_outstanding_true_f(void) +{ + return 0x8U; +} +static inline u32 bus_intr_0_r(void) +{ + return 0x00001100U; +} +static inline u32 bus_intr_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +static inline u32 bus_intr_en_0_r(void) +{ + return 0x00001140U; +} +static inline u32 bus_intr_en_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_en_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_en_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_ccsr_gv100.h b/include/nvgpu/hw/gv100/hw_ccsr_gv100.h new file mode 100644 index 0000000..b147803 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_ccsr_gv100.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ccsr_gv100_h_ +#define _hw_ccsr_gv100_h_ + +static inline u32 ccsr_channel_inst_r(u32 i) +{ + return 0x00800000U + i*8U; +} +static inline u32 ccsr_channel_inst__size_1_v(void) +{ + return 0x00001000U; +} +static inline u32 ccsr_channel_inst_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 ccsr_channel_inst_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 ccsr_channel_inst_bind_false_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_bind_true_f(void) +{ + return 0x80000000U; +} +static inline u32 ccsr_channel_r(u32 i) +{ + return 0x00800004U + i*8U; +} +static inline u32 ccsr_channel__size_1_v(void) +{ + return 0x00001000U; +} +static inline u32 ccsr_channel_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ccsr_channel_enable_set_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ccsr_channel_enable_set_true_f(void) +{ + return 0x400U; +} +static inline u32 ccsr_channel_enable_clr_true_f(void) +{ + return 0x800U; +} +static inline u32 ccsr_channel_status_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ccsr_channel_status_pending_ctx_reload_v(void) +{ + return 0x00000002U; +} +static inline u32 ccsr_channel_status_pending_acq_ctx_reload_v(void) +{ + return 0x00000004U; +} +static inline u32 ccsr_channel_status_on_pbdma_ctx_reload_v(void) +{ + return 0x0000000aU; +} +static inline u32 ccsr_channel_status_on_pbdma_and_eng_ctx_reload_v(void) +{ + return 0x0000000bU; +} +static inline u32 ccsr_channel_status_on_eng_ctx_reload_v(void) +{ + return 0x0000000cU; +} +static inline u32 ccsr_channel_status_on_eng_pending_ctx_reload_v(void) +{ + return 0x0000000dU; +} +static inline u32 ccsr_channel_status_on_eng_pending_acq_ctx_reload_v(void) +{ + return 0x0000000eU; +} +static inline u32 ccsr_channel_next_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ccsr_channel_next_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ccsr_channel_force_ctx_reload_true_f(void) +{ + return 0x100U; +} +static inline u32 ccsr_channel_pbdma_faulted_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 ccsr_channel_pbdma_faulted_reset_f(void) +{ + return 0x400000U; +} +static inline u32 ccsr_channel_eng_faulted_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 ccsr_channel_eng_faulted_v(u32 r) +{ + return (r >> 23U) & 0x1U; +} +static inline u32 ccsr_channel_eng_faulted_reset_f(void) +{ + return 0x800000U; +} +static inline u32 ccsr_channel_eng_faulted_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ccsr_channel_busy_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_ce_gv100.h b/include/nvgpu/hw/gv100/hw_ce_gv100.h new file mode 100644 index 0000000..18b5fc6 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_ce_gv100.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ce_gv100_h_ +#define _hw_ce_gv100_h_ + +static inline u32 ce_intr_status_r(u32 i) +{ + return 0x00104410U + i*128U; +} +static inline u32 ce_intr_status_blockpipe_pending_f(void) +{ + return 0x1U; +} +static inline u32 ce_intr_status_blockpipe_reset_f(void) +{ + return 0x1U; +} +static inline u32 ce_intr_status_nonblockpipe_pending_f(void) +{ + return 0x2U; +} +static inline u32 ce_intr_status_nonblockpipe_reset_f(void) +{ + return 0x2U; +} +static inline u32 ce_intr_status_launcherr_pending_f(void) +{ + return 0x4U; +} +static inline u32 ce_intr_status_launcherr_reset_f(void) +{ + return 0x4U; +} +static inline u32 ce_intr_status_invalid_config_pending_f(void) +{ + return 0x8U; +} +static inline u32 ce_intr_status_invalid_config_reset_f(void) +{ + return 0x8U; +} +static inline u32 ce_intr_status_mthd_buffer_fault_pending_f(void) +{ + return 0x10U; +} +static inline u32 ce_intr_status_mthd_buffer_fault_reset_f(void) +{ + return 0x10U; +} +static inline u32 ce_pce_map_r(void) +{ + return 0x00104028U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_ctxsw_prog_gv100.h b/include/nvgpu/hw/gv100/hw_ctxsw_prog_gv100.h new file mode 100644 index 0000000..b7f3df2 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_ctxsw_prog_gv100.h @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ctxsw_prog_gv100_h_ +#define _hw_ctxsw_prog_gv100_h_ + +static inline u32 ctxsw_prog_fecs_header_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_main_image_num_gpcs_o(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_main_image_ctl_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_main_image_ctl_type_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_undefined_v(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_opengl_v(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_dx9_v(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_dx10_v(void) +{ + return 0x00000011U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_dx11_v(void) +{ + return 0x00000012U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_compute_v(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_per_veid_header_v(void) +{ + return 0x00000021U; +} +static inline u32 ctxsw_prog_main_image_patch_count_o(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_main_image_context_id_o(void) +{ + return 0x000000f0U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_lo_o(void) +{ + return 0x00000014U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_hi_o(void) +{ + return 0x00000018U; +} +static inline u32 ctxsw_prog_main_image_zcull_o(void) +{ + return 0x0000001cU; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_no_ctxsw_v(void) +{ + return 0x00000001U; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_separate_buffer_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_zcull_ptr_o(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_main_image_pm_o(void) +{ + return 0x00000028U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_m(void) +{ + return 0x7U << 0U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_stream_out_ctxsw_f(void) +{ + return 0x2U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_m(void) +{ + return 0x7U << 3U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_ctxsw_f(void) +{ + return 0x8U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_ptr_o(void) +{ + return 0x0000002cU; +} +static inline u32 ctxsw_prog_main_image_num_save_ops_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_main_image_num_wfi_save_ops_o(void) +{ + return 0x000000d0U; +} +static inline u32 ctxsw_prog_main_image_num_cta_save_ops_o(void) +{ + return 0x000000d4U; +} +static inline u32 ctxsw_prog_main_image_num_gfxp_save_ops_o(void) +{ + return 0x000000d8U; +} +static inline u32 ctxsw_prog_main_image_num_cilp_save_ops_o(void) +{ + return 0x000000dcU; +} +static inline u32 ctxsw_prog_main_image_num_restore_ops_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_main_image_zcull_ptr_hi_o(void) +{ + return 0x00000060U; +} +static inline u32 ctxsw_prog_main_image_zcull_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_pm_ptr_hi_o(void) +{ + return 0x00000094U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_hi_o(void) +{ + return 0x00000064U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_o(void) +{ + return 0x00000068U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_veid0_hi_o(void) +{ + return 0x00000070U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_veid0_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_veid0_o(void) +{ + return 0x00000074U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_veid0_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_buffer_ptr_hi_o(void) +{ + return 0x00000078U; +} +static inline u32 ctxsw_prog_main_image_context_buffer_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_buffer_ptr_o(void) +{ + return 0x0000007cU; +} +static inline u32 ctxsw_prog_main_image_context_buffer_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_main_image_magic_value_v_value_v(void) +{ + return 0x600dc0deU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_main_image_global_cb_ptr_o(void) +{ + return 0x000000b8U; +} +static inline u32 ctxsw_prog_main_image_global_cb_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_global_cb_ptr_hi_o(void) +{ + return 0x000000bcU; +} +static inline u32 ctxsw_prog_main_image_global_cb_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_global_pagepool_ptr_o(void) +{ + return 0x000000c0U; +} +static inline u32 ctxsw_prog_main_image_global_pagepool_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_global_pagepool_ptr_hi_o(void) +{ + return 0x000000c4U; +} +static inline u32 ctxsw_prog_main_image_global_pagepool_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_control_block_ptr_o(void) +{ + return 0x000000c8U; +} +static inline u32 ctxsw_prog_main_image_control_block_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_control_block_ptr_hi_o(void) +{ + return 0x000000ccU; +} +static inline u32 ctxsw_prog_main_image_control_block_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_ramchain_buffer_addr_lo_o(void) +{ + return 0x000000e0U; +} +static inline u32 ctxsw_prog_main_image_context_ramchain_buffer_addr_lo_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_ramchain_buffer_addr_hi_o(void) +{ + return 0x000000e4U; +} +static inline u32 ctxsw_prog_main_image_context_ramchain_buffer_addr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_local_image_ppc_info_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_local_image_ppc_info_num_ppcs_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_ppc_mask_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_num_tpcs_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_local_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_local_magic_value_v_value_v(void) +{ + return 0xad0becabU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_o(void) +{ + return 0x000000ecU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_size_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 ctxsw_prog_extended_buffer_segments_size_in_bytes_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_extended_marker_size_in_bytes_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_register_stride_v(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_control_register_stride_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_o(void) +{ + return 0x000000a0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_s(void) +{ + return 2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_m(void) +{ + return 0x3U << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_allow_all_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_use_map_f(void) +{ + return 0x2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_lo_o(void) +{ + return 0x000000a4U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_hi_o(void) +{ + return 0x000000a8U; +} +static inline u32 ctxsw_prog_main_image_misc_options_o(void) +{ + return 0x0000003cU; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_disabled_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_o(void) +{ + return 0x00000080U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_control_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_control_gfxp_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_o(void) +{ + return 0x00000084U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_cta_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_cilp_f(void) +{ + return 0x2U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_falcon_gv100.h b/include/nvgpu/hw/gv100/hw_falcon_gv100.h new file mode 100644 index 0000000..3492d68 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_falcon_gv100.h @@ -0,0 +1,603 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_falcon_gv100_h_ +#define _hw_falcon_gv100_h_ + +static inline u32 falcon_falcon_irqsset_r(void) +{ + return 0x00000000U; +} +static inline u32 falcon_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqsclr_r(void) +{ + return 0x00000004U; +} +static inline u32 falcon_falcon_irqstat_r(void) +{ + return 0x00000008U; +} +static inline u32 falcon_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 falcon_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 falcon_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqmode_r(void) +{ + return 0x0000000cU; +} +static inline u32 falcon_falcon_irqmset_r(void) +{ + return 0x00000010U; +} +static inline u32 falcon_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_r(void) +{ + return 0x00000014U; +} +static inline u32 falcon_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqmask_r(void) +{ + return 0x00000018U; +} +static inline u32 falcon_falcon_irqdest_r(void) +{ + return 0x0000001cU; +} +static inline u32 falcon_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 falcon_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 falcon_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 falcon_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 falcon_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 falcon_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 falcon_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 falcon_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 falcon_falcon_curctx_r(void) +{ + return 0x00000050U; +} +static inline u32 falcon_falcon_nxtctx_r(void) +{ + return 0x00000054U; +} +static inline u32 falcon_falcon_mailbox0_r(void) +{ + return 0x00000040U; +} +static inline u32 falcon_falcon_mailbox1_r(void) +{ + return 0x00000044U; +} +static inline u32 falcon_falcon_itfen_r(void) +{ + return 0x00000048U; +} +static inline u32 falcon_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 falcon_falcon_idlestate_r(void) +{ + return 0x0000004cU; +} +static inline u32 falcon_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 falcon_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 falcon_falcon_os_r(void) +{ + return 0x00000080U; +} +static inline u32 falcon_falcon_engctl_r(void) +{ + return 0x000000a4U; +} +static inline u32 falcon_falcon_cpuctl_r(void) +{ + return 0x00000100U; +} +static inline u32 falcon_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_cpuctl_sreset_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_cpuctl_hreset_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_stopped_m(void) +{ + return 0x1U << 5U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_alias_r(void) +{ + return 0x00000130U; +} +static inline u32 falcon_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_imemc_r(u32 i) +{ + return 0x00000180U + i*16U; +} +static inline u32 falcon_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_imemc_secure_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 falcon_falcon_imemd_r(u32 i) +{ + return 0x00000184U + i*16U; +} +static inline u32 falcon_falcon_imemt_r(u32 i) +{ + return 0x00000188U + i*16U; +} +static inline u32 falcon_falcon_sctl_r(void) +{ + return 0x00000240U; +} +static inline u32 falcon_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 falcon_falcon_bootvec_r(void) +{ + return 0x00000104U; +} +static inline u32 falcon_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 falcon_falcon_dmactl_r(void) +{ + return 0x0000010cU; +} +static inline u32 falcon_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 falcon_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 falcon_falcon_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_hwcfg_r(void) +{ + return 0x00000108U; +} +static inline u32 falcon_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 falcon_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 falcon_falcon_dmatrfbase_r(void) +{ + return 0x00000110U; +} +static inline u32 falcon_falcon_dmatrfbase1_r(void) +{ + return 0x00000128U; +} +static inline u32 falcon_falcon_dmatrfmoffs_r(void) +{ + return 0x00000114U; +} +static inline u32 falcon_falcon_dmatrfcmd_r(void) +{ + return 0x00000118U; +} +static inline u32 falcon_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 falcon_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 falcon_falcon_dmatrffboffs_r(void) +{ + return 0x0000011cU; +} +static inline u32 falcon_falcon_imctl_debug_r(void) +{ + return 0x0000015cU; +} +static inline u32 falcon_falcon_imctl_debug_addr_blk_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 falcon_falcon_imctl_debug_cmd_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 falcon_falcon_imstat_r(void) +{ + return 0x00000144U; +} +static inline u32 falcon_falcon_traceidx_r(void) +{ + return 0x00000148U; +} +static inline u32 falcon_falcon_traceidx_maxidx_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 falcon_falcon_traceidx_idx_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 falcon_falcon_tracepc_r(void) +{ + return 0x0000014cU; +} +static inline u32 falcon_falcon_tracepc_pc_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 falcon_falcon_exterraddr_r(void) +{ + return 0x00000168U; +} +static inline u32 falcon_falcon_exterrstat_r(void) +{ + return 0x0000016cU; +} +static inline u32 falcon_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 falcon_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 falcon_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 falcon_falcon_icd_cmd_r(void) +{ + return 0x00000200U; +} +static inline u32 falcon_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 falcon_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 falcon_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 falcon_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 falcon_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 falcon_falcon_icd_rdata_r(void) +{ + return 0x0000020cU; +} +static inline u32 falcon_falcon_dmemc_r(u32 i) +{ + return 0x000001c0U + i*8U; +} +static inline u32 falcon_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 falcon_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 falcon_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 falcon_falcon_dmemd_r(u32 i) +{ + return 0x000001c4U + i*8U; +} +static inline u32 falcon_falcon_debug1_r(void) +{ + return 0x00000090U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_s(void) +{ + return 1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_m(void) +{ + return 0x1U << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_init_f(void) +{ + return 0x0U; +} +static inline u32 falcon_falcon_debuginfo_r(void) +{ + return 0x00000094U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_fb_gv100.h b/include/nvgpu/hw/gv100/hw_fb_gv100.h new file mode 100644 index 0000000..ac248b5 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_fb_gv100.h @@ -0,0 +1,1923 @@ +/* + * Copyright (c) 2017-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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fb_gv100_h_ +#define _hw_fb_gv100_h_ + +static inline u32 fb_fbhub_num_active_ltcs_r(void) +{ + return 0x00100800U; +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_m(void) +{ + return 0xffU << 16U; +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_peer_f(u32 v, u32 i) +{ + return (v & 0x1U) << (16U + i*1U); +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_peer_m(u32 i) +{ + return 0x1U << (16U + i*1U); +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_peer_v(u32 r, u32 i) +{ + return (r >> (16U + i*1U)) & 0x1U; +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_peer___size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_peer___size_1_f(u32 i) +{ + return 0x0U << (32U + i*1U); +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_peer_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_peer_enabled_f(u32 i) +{ + return 0x1U << (32U + i*1U); +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_peer_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_fbhub_num_active_ltcs_use_nvlink_peer_disabled_f(u32 i) +{ + return 0x0U << (32U + i*1U); +} +static inline u32 fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_m(void) +{ + return 0x1U << 25U; +} +static inline u32 fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_v(u32 r) +{ + return (r >> 25U) & 0x1U; +} +static inline u32 fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_use_read_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_use_read_f(void) +{ + return 0x0U; +} +static inline u32 fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_use_rmw_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_use_rmw_f(void) +{ + return 0x2000000U; +} +static inline u32 fb_mmu_ctrl_r(void) +{ + return 0x00100c80U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_space_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_f(u32 v) +{ + return (v & 0x3U) << 24U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_m(void) +{ + return 0x3U << 24U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_v(u32 r) +{ + return (r >> 24U) & 0x3U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_l2_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_l2_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_atomic_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_atomic_f(void) +{ + return 0x1000000U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_rmw_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_rmw_f(void) +{ + return 0x2000000U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_power_v(void) +{ + return 0x00000003U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_power_f(void) +{ + return 0x3000000U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_r(void) +{ + return 0x001fac80U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_f(u32 v) +{ + return (v & 0x3U) << 24U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_m(void) +{ + return 0x3U << 24U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_v(u32 r) +{ + return (r >> 24U) & 0x3U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_l2_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_l2_f(void) +{ + return 0x0U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_atomic_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_atomic_f(void) +{ + return 0x1000000U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_rmw_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_rmw_f(void) +{ + return 0x2000000U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_power_v(void) +{ + return 0x00000003U; +} +static inline u32 fb_hsmmu_pri_mmu_ctrl_atomic_capability_mode_power_f(void) +{ + return 0x3000000U; +} +static inline u32 fb_hsmmu_pri_mmu_debug_ctrl_r(void) +{ + return 0x001facc4U; +} +static inline u32 fb_hsmmu_pri_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 fb_hsmmu_pri_mmu_debug_ctrl_debug_m(void) +{ + return 0x1U << 16U; +} +static inline u32 fb_hsmmu_pri_mmu_debug_ctrl_debug_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 fb_hsmmu_pri_mmu_debug_ctrl_debug_disabled_f(void) +{ + return 0x0U; +} +static inline u32 fb_hshub_num_active_ltcs_r(void) +{ + return 0x001fbc20U; +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_m(void) +{ + return 0xffU << 16U; +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_peer_f(u32 v, u32 i) +{ + return (v & 0x1U) << (16U + i*1U); +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_peer_m(u32 i) +{ + return 0x1U << (16U + i*1U); +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_peer_v(u32 r, u32 i) +{ + return (r >> (16U + i*1U)) & 0x1U; +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_peer___size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_peer___size_1_f(u32 i) +{ + return 0x0U << (32U + i*1U); +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_peer_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_peer_enabled_f(u32 i) +{ + return 0x1U << (32U + i*1U); +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_peer_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_hshub_num_active_ltcs_use_nvlink_peer_disabled_f(u32 i) +{ + return 0x0U << (32U + i*1U); +} +static inline u32 fb_hshub_num_active_ltcs_hub_sys_atomic_mode_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 fb_hshub_num_active_ltcs_hub_sys_atomic_mode_m(void) +{ + return 0x1U << 25U; +} +static inline u32 fb_hshub_num_active_ltcs_hub_sys_atomic_mode_v(u32 r) +{ + return (r >> 25U) & 0x1U; +} +static inline u32 fb_hshub_num_active_ltcs_hub_sys_atomic_mode_use_read_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_hshub_num_active_ltcs_hub_sys_atomic_mode_use_read_f(void) +{ + return 0x0U; +} +static inline u32 fb_hshub_num_active_ltcs_hub_sys_atomic_mode_use_rmw_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_hshub_num_active_ltcs_hub_sys_atomic_mode_use_rmw_f(void) +{ + return 0x2000000U; +} +static inline u32 fb_priv_mmu_phy_secure_r(void) +{ + return 0x00100ce4U; +} +static inline u32 fb_mmu_invalidate_pdb_r(void) +{ + return 0x00100cb8U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_sys_mem_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_pdb_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_invalidate_r(void) +{ + return 0x00100cbcU; +} +static inline u32 fb_mmu_invalidate_all_va_true_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_invalidate_all_pdb_true_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_m(void) +{ + return 0x1U << 2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_true_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_invalidate_replay_s(void) +{ + return 3U; +} +static inline u32 fb_mmu_invalidate_replay_f(u32 v) +{ + return (v & 0x7U) << 3U; +} +static inline u32 fb_mmu_invalidate_replay_m(void) +{ + return 0x7U << 3U; +} +static inline u32 fb_mmu_invalidate_replay_v(u32 r) +{ + return (r >> 3U) & 0x7U; +} +static inline u32 fb_mmu_invalidate_replay_none_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_replay_start_f(void) +{ + return 0x8U; +} +static inline u32 fb_mmu_invalidate_replay_start_ack_all_f(void) +{ + return 0x10U; +} +static inline u32 fb_mmu_invalidate_replay_cancel_global_f(void) +{ + return 0x20U; +} +static inline u32 fb_mmu_invalidate_sys_membar_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_sys_membar_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 fb_mmu_invalidate_sys_membar_m(void) +{ + return 0x1U << 6U; +} +static inline u32 fb_mmu_invalidate_sys_membar_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_sys_membar_true_f(void) +{ + return 0x40U; +} +static inline u32 fb_mmu_invalidate_ack_s(void) +{ + return 2U; +} +static inline u32 fb_mmu_invalidate_ack_f(u32 v) +{ + return (v & 0x3U) << 7U; +} +static inline u32 fb_mmu_invalidate_ack_m(void) +{ + return 0x3U << 7U; +} +static inline u32 fb_mmu_invalidate_ack_v(u32 r) +{ + return (r >> 7U) & 0x3U; +} +static inline u32 fb_mmu_invalidate_ack_ack_none_required_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_ack_ack_intranode_f(void) +{ + return 0x100U; +} +static inline u32 fb_mmu_invalidate_ack_ack_globally_f(void) +{ + return 0x80U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_s(void) +{ + return 6U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_f(u32 v) +{ + return (v & 0x3fU) << 9U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_m(void) +{ + return 0x3fU << 9U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_v(u32 r) +{ + return (r >> 9U) & 0x3fU; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_s(void) +{ + return 5U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_f(u32 v) +{ + return (v & 0x1fU) << 15U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_m(void) +{ + return 0x1fU << 15U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_v(u32 r) +{ + return (r >> 15U) & 0x1fU; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_m(void) +{ + return 0x1U << 20U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_gpc_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_hub_f(void) +{ + return 0x100000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_s(void) +{ + return 3U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_m(void) +{ + return 0x7U << 24U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_v(u32 r) +{ + return (r >> 24U) & 0x7U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_all_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_pte_only_f(void) +{ + return 0x1000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde0_f(void) +{ + return 0x2000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde1_f(void) +{ + return 0x3000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde2_f(void) +{ + return 0x4000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde3_f(void) +{ + return 0x5000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde4_f(void) +{ + return 0x6000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde5_f(void) +{ + return 0x7000000U; +} +static inline u32 fb_mmu_invalidate_trigger_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_trigger_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_trigger_true_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_debug_wr_r(void) +{ + return 0x00100cc8U; +} +static inline u32 fb_mmu_debug_wr_aperture_s(void) +{ + return 2U; +} +static inline u32 fb_mmu_debug_wr_aperture_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_m(void) +{ + return 0x3U << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fb_mmu_debug_wr_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_wr_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_vol_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_wr_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_debug_wr_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_wr_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_rd_r(void) +{ + return 0x00100cccU; +} +static inline u32 fb_mmu_debug_rd_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_rd_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_rd_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_ctrl_r(void) +{ + return 0x00100cc4U; +} +static inline u32 fb_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 fb_mmu_debug_ctrl_debug_m(void) +{ + return 0x1U << 16U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_f(void) +{ + return 0x0U; +} +static inline u32 fb_niso_cfg1_r(void) +{ + return 0x00100c14U; +} +static inline u32 fb_niso_cfg1_sysmem_nvlink_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 fb_niso_cfg1_sysmem_nvlink_m(void) +{ + return 0x1U << 17U; +} +static inline u32 fb_niso_cfg1_sysmem_nvlink_v(u32 r) +{ + return (r >> 17U) & 0x1U; +} +static inline u32 fb_niso_cfg1_sysmem_nvlink_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_niso_cfg1_sysmem_nvlink_enabled_f(void) +{ + return 0x20000U; +} +static inline u32 fb_niso_flush_sysmem_addr_r(void) +{ + return 0x00100c10U; +} +static inline u32 fb_niso_intr_r(void) +{ + return 0x00100a20U; +} +static inline u32 fb_niso_intr_hub_access_counter_notify_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fb_niso_intr_hub_access_counter_notify_pending_f(void) +{ + return 0x1U; +} +static inline u32 fb_niso_intr_hub_access_counter_error_m(void) +{ + return 0x1U << 1U; +} +static inline u32 fb_niso_intr_hub_access_counter_error_pending_f(void) +{ + return 0x2U; +} +static inline u32 fb_niso_intr_mmu_replayable_fault_notify_m(void) +{ + return 0x1U << 27U; +} +static inline u32 fb_niso_intr_mmu_replayable_fault_notify_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 fb_niso_intr_mmu_replayable_fault_overflow_m(void) +{ + return 0x1U << 28U; +} +static inline u32 fb_niso_intr_mmu_replayable_fault_overflow_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 fb_niso_intr_mmu_nonreplayable_fault_notify_m(void) +{ + return 0x1U << 29U; +} +static inline u32 fb_niso_intr_mmu_nonreplayable_fault_notify_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 fb_niso_intr_mmu_nonreplayable_fault_overflow_m(void) +{ + return 0x1U << 30U; +} +static inline u32 fb_niso_intr_mmu_nonreplayable_fault_overflow_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_niso_intr_mmu_other_fault_notify_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_niso_intr_mmu_other_fault_notify_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_niso_intr_en_r(u32 i) +{ + return 0x00100a24U + i*4U; +} +static inline u32 fb_niso_intr_en__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_niso_intr_en_hub_access_counter_notify_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fb_niso_intr_en_hub_access_counter_notify_enabled_f(void) +{ + return 0x1U; +} +static inline u32 fb_niso_intr_en_hub_access_counter_error_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 fb_niso_intr_en_hub_access_counter_error_enabled_f(void) +{ + return 0x2U; +} +static inline u32 fb_niso_intr_en_mmu_replayable_fault_notify_f(u32 v) +{ + return (v & 0x1U) << 27U; +} +static inline u32 fb_niso_intr_en_mmu_replayable_fault_notify_enabled_f(void) +{ + return 0x8000000U; +} +static inline u32 fb_niso_intr_en_mmu_replayable_fault_overflow_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 fb_niso_intr_en_mmu_replayable_fault_overflow_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 fb_niso_intr_en_mmu_nonreplayable_fault_notify_f(u32 v) +{ + return (v & 0x1U) << 29U; +} +static inline u32 fb_niso_intr_en_mmu_nonreplayable_fault_notify_enabled_f(void) +{ + return 0x20000000U; +} +static inline u32 fb_niso_intr_en_mmu_nonreplayable_fault_overflow_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_niso_intr_en_mmu_nonreplayable_fault_overflow_enabled_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_niso_intr_en_mmu_other_fault_notify_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_niso_intr_en_mmu_other_fault_notify_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_niso_intr_en_set_r(u32 i) +{ + return 0x00100a2cU + i*4U; +} +static inline u32 fb_niso_intr_en_set__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_niso_intr_en_set_hub_access_counter_notify_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fb_niso_intr_en_set_hub_access_counter_notify_set_f(void) +{ + return 0x1U; +} +static inline u32 fb_niso_intr_en_set_hub_access_counter_error_m(void) +{ + return 0x1U << 1U; +} +static inline u32 fb_niso_intr_en_set_hub_access_counter_error_set_f(void) +{ + return 0x2U; +} +static inline u32 fb_niso_intr_en_set_mmu_replayable_fault_notify_m(void) +{ + return 0x1U << 27U; +} +static inline u32 fb_niso_intr_en_set_mmu_replayable_fault_notify_set_f(void) +{ + return 0x8000000U; +} +static inline u32 fb_niso_intr_en_set_mmu_replayable_fault_overflow_m(void) +{ + return 0x1U << 28U; +} +static inline u32 fb_niso_intr_en_set_mmu_replayable_fault_overflow_set_f(void) +{ + return 0x10000000U; +} +static inline u32 fb_niso_intr_en_set_mmu_nonreplayable_fault_notify_m(void) +{ + return 0x1U << 29U; +} +static inline u32 fb_niso_intr_en_set_mmu_nonreplayable_fault_notify_set_f(void) +{ + return 0x20000000U; +} +static inline u32 fb_niso_intr_en_set_mmu_nonreplayable_fault_overflow_m(void) +{ + return 0x1U << 30U; +} +static inline u32 fb_niso_intr_en_set_mmu_nonreplayable_fault_overflow_set_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_niso_intr_en_set_mmu_other_fault_notify_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_niso_intr_en_set_mmu_other_fault_notify_set_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_niso_intr_en_clr_r(u32 i) +{ + return 0x00100a34U + i*4U; +} +static inline u32 fb_niso_intr_en_clr__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_niso_intr_en_clr_hub_access_counter_notify_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fb_niso_intr_en_clr_hub_access_counter_notify_set_f(void) +{ + return 0x1U; +} +static inline u32 fb_niso_intr_en_clr_hub_access_counter_error_m(void) +{ + return 0x1U << 1U; +} +static inline u32 fb_niso_intr_en_clr_hub_access_counter_error_set_f(void) +{ + return 0x2U; +} +static inline u32 fb_niso_intr_en_clr_mmu_replayable_fault_notify_m(void) +{ + return 0x1U << 27U; +} +static inline u32 fb_niso_intr_en_clr_mmu_replayable_fault_notify_set_f(void) +{ + return 0x8000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_replayable_fault_overflow_m(void) +{ + return 0x1U << 28U; +} +static inline u32 fb_niso_intr_en_clr_mmu_replayable_fault_overflow_set_f(void) +{ + return 0x10000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_nonreplayable_fault_notify_m(void) +{ + return 0x1U << 29U; +} +static inline u32 fb_niso_intr_en_clr_mmu_nonreplayable_fault_notify_set_f(void) +{ + return 0x20000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_nonreplayable_fault_overflow_m(void) +{ + return 0x1U << 30U; +} +static inline u32 fb_niso_intr_en_clr_mmu_nonreplayable_fault_overflow_set_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_other_fault_notify_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_niso_intr_en_clr_mmu_other_fault_notify_set_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_non_replay_fault_buffer_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_replay_fault_buffer_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_lo_r(u32 i) +{ + return 0x00100e24U + i*20U; +} +static inline u32 fb_mmu_fault_buffer_lo__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_virtual_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_virtual_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_physical_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_physical_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_f(u32 v) +{ + return (v & 0x3U) << 1U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_v(u32 r) +{ + return (r >> 1U) & 0x3U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_sys_coh_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_sys_nocoh_v(void) +{ + return 0x00000003U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_sys_nocoh_f(void) +{ + return 0x6U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_vol_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_vol_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_buffer_hi_r(u32 i) +{ + return 0x00100e28U + i*20U; +} +static inline u32 fb_mmu_fault_buffer_hi__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_hi_addr_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 fb_mmu_fault_buffer_hi_addr_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 fb_mmu_fault_buffer_get_r(u32 i) +{ + return 0x00100e2cU + i*20U; +} +static inline u32 fb_mmu_fault_buffer_get__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_get_ptr_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 fb_mmu_fault_buffer_get_ptr_m(void) +{ + return 0xfffffU << 0U; +} +static inline u32 fb_mmu_fault_buffer_get_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_buffer_get_getptr_corrupted_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_mmu_fault_buffer_get_getptr_corrupted_m(void) +{ + return 0x1U << 30U; +} +static inline u32 fb_mmu_fault_buffer_get_getptr_corrupted_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_get_getptr_corrupted_clear_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_mmu_fault_buffer_get_overflow_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_fault_buffer_get_overflow_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_fault_buffer_get_overflow_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_get_overflow_clear_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_fault_buffer_put_r(u32 i) +{ + return 0x00100e30U + i*20U; +} +static inline u32 fb_mmu_fault_buffer_put__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_put_ptr_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 fb_mmu_fault_buffer_put_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_yes_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_yes_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_no_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_no_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_buffer_put_overflow_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_fault_buffer_put_overflow_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_put_overflow_yes_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_put_overflow_yes_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_fault_buffer_size_r(u32 i) +{ + return 0x00100e34U + i*20U; +} +static inline u32 fb_mmu_fault_buffer_size__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_size_val_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 fb_mmu_fault_buffer_size_val_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_buffer_size_overflow_intr_f(u32 v) +{ + return (v & 0x1U) << 29U; +} +static inline u32 fb_mmu_fault_buffer_size_overflow_intr_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_size_overflow_intr_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_size_overflow_intr_enable_f(void) +{ + return 0x20000000U; +} +static inline u32 fb_mmu_fault_buffer_size_set_default_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_mmu_fault_buffer_size_set_default_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_size_set_default_yes_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_size_set_default_yes_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_mmu_fault_buffer_size_enable_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_fault_buffer_size_enable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_fault_buffer_size_enable_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_size_enable_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_size_enable_true_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_fault_addr_lo_r(void) +{ + return 0x00100e4cU; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_sys_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_sys_nocoh_v(void) +{ + return 0x00000003U; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_sys_nocoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_fault_addr_lo_addr_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 fb_mmu_fault_addr_lo_addr_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_addr_hi_r(void) +{ + return 0x00100e50U; +} +static inline u32 fb_mmu_fault_addr_hi_addr_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 fb_mmu_fault_addr_hi_addr_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 fb_mmu_fault_inst_lo_r(void) +{ + return 0x00100e54U; +} +static inline u32 fb_mmu_fault_inst_lo_engine_id_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 fb_mmu_fault_inst_lo_aperture_v(u32 r) +{ + return (r >> 10U) & 0x3U; +} +static inline u32 fb_mmu_fault_inst_lo_aperture_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_inst_lo_aperture_sys_nocoh_v(void) +{ + return 0x00000003U; +} +static inline u32 fb_mmu_fault_inst_lo_addr_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 fb_mmu_fault_inst_lo_addr_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_inst_hi_r(void) +{ + return 0x00100e58U; +} +static inline u32 fb_mmu_fault_inst_hi_addr_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 fb_mmu_fault_info_r(void) +{ + return 0x00100e5cU; +} +static inline u32 fb_mmu_fault_info_fault_type_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 fb_mmu_fault_info_replayable_fault_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 fb_mmu_fault_info_client_v(u32 r) +{ + return (r >> 8U) & 0x7fU; +} +static inline u32 fb_mmu_fault_info_access_type_v(u32 r) +{ + return (r >> 16U) & 0xfU; +} +static inline u32 fb_mmu_fault_info_client_type_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 fb_mmu_fault_info_gpc_id_v(u32 r) +{ + return (r >> 24U) & 0x1fU; +} +static inline u32 fb_mmu_fault_info_protected_mode_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 fb_mmu_fault_info_replayable_fault_en_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fb_mmu_fault_info_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_fault_status_r(void) +{ + return 0x00100e60U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_phys_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_phys_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_phys_set_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_phys_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_phys_clear_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_virt_m(void) +{ + return 0x1U << 1U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_virt_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_virt_set_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_virt_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_virt_clear_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_phys_m(void) +{ + return 0x1U << 2U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_phys_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_phys_set_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_phys_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_phys_clear_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_virt_m(void) +{ + return 0x1U << 3U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_virt_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_virt_set_f(void) +{ + return 0x8U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_virt_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_virt_clear_f(void) +{ + return 0x8U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_phys_m(void) +{ + return 0x1U << 4U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_phys_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_phys_set_f(void) +{ + return 0x10U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_phys_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_phys_clear_f(void) +{ + return 0x10U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_virt_m(void) +{ + return 0x1U << 5U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_virt_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_virt_set_f(void) +{ + return 0x20U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_virt_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_virt_clear_f(void) +{ + return 0x20U; +} +static inline u32 fb_mmu_fault_status_dropped_other_phys_m(void) +{ + return 0x1U << 6U; +} +static inline u32 fb_mmu_fault_status_dropped_other_phys_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_other_phys_set_f(void) +{ + return 0x40U; +} +static inline u32 fb_mmu_fault_status_dropped_other_phys_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_other_phys_clear_f(void) +{ + return 0x40U; +} +static inline u32 fb_mmu_fault_status_dropped_other_virt_m(void) +{ + return 0x1U << 7U; +} +static inline u32 fb_mmu_fault_status_dropped_other_virt_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_other_virt_set_f(void) +{ + return 0x80U; +} +static inline u32 fb_mmu_fault_status_dropped_other_virt_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_other_virt_clear_f(void) +{ + return 0x80U; +} +static inline u32 fb_mmu_fault_status_replayable_m(void) +{ + return 0x1U << 8U; +} +static inline u32 fb_mmu_fault_status_replayable_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_replayable_set_f(void) +{ + return 0x100U; +} +static inline u32 fb_mmu_fault_status_replayable_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_non_replayable_m(void) +{ + return 0x1U << 9U; +} +static inline u32 fb_mmu_fault_status_non_replayable_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_non_replayable_set_f(void) +{ + return 0x200U; +} +static inline u32 fb_mmu_fault_status_non_replayable_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_replayable_error_m(void) +{ + return 0x1U << 10U; +} +static inline u32 fb_mmu_fault_status_replayable_error_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_replayable_error_set_f(void) +{ + return 0x400U; +} +static inline u32 fb_mmu_fault_status_replayable_error_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_non_replayable_error_m(void) +{ + return 0x1U << 11U; +} +static inline u32 fb_mmu_fault_status_non_replayable_error_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_non_replayable_error_set_f(void) +{ + return 0x800U; +} +static inline u32 fb_mmu_fault_status_non_replayable_error_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_replayable_overflow_m(void) +{ + return 0x1U << 12U; +} +static inline u32 fb_mmu_fault_status_replayable_overflow_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_replayable_overflow_set_f(void) +{ + return 0x1000U; +} +static inline u32 fb_mmu_fault_status_replayable_overflow_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_non_replayable_overflow_m(void) +{ + return 0x1U << 13U; +} +static inline u32 fb_mmu_fault_status_non_replayable_overflow_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_non_replayable_overflow_set_f(void) +{ + return 0x2000U; +} +static inline u32 fb_mmu_fault_status_non_replayable_overflow_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_replayable_getptr_corrupted_m(void) +{ + return 0x1U << 14U; +} +static inline u32 fb_mmu_fault_status_replayable_getptr_corrupted_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_replayable_getptr_corrupted_set_f(void) +{ + return 0x4000U; +} +static inline u32 fb_mmu_fault_status_non_replayable_getptr_corrupted_m(void) +{ + return 0x1U << 15U; +} +static inline u32 fb_mmu_fault_status_non_replayable_getptr_corrupted_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_non_replayable_getptr_corrupted_set_f(void) +{ + return 0x8000U; +} +static inline u32 fb_mmu_fault_status_busy_m(void) +{ + return 0x1U << 30U; +} +static inline u32 fb_mmu_fault_status_busy_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_busy_true_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_mmu_fault_status_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_fault_status_valid_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_valid_set_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_fault_status_valid_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_valid_clear_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_local_memory_range_r(void) +{ + return 0x00100ce0U; +} +static inline u32 fb_mmu_local_memory_range_lower_scale_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 fb_mmu_local_memory_range_lower_mag_v(u32 r) +{ + return (r >> 4U) & 0x3fU; +} +static inline u32 fb_mmu_local_memory_range_ecc_mode_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fb_niso_scrub_status_r(void) +{ + return 0x00100b20U; +} +static inline u32 fb_niso_scrub_status_flag_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 fb_mmu_priv_level_mask_r(void) +{ + return 0x00100cdcU; +} +static inline u32 fb_mmu_priv_level_mask_write_violation_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 fb_mmu_priv_level_mask_write_violation_m(void) +{ + return 0x1U << 7U; +} +static inline u32 fb_mmu_priv_level_mask_write_violation_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 fb_hshub_config0_r(void) +{ + return 0x001fbc00U; +} +static inline u32 fb_hshub_config0_sysmem_nvlink_mask_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fb_hshub_config0_sysmem_nvlink_mask_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fb_hshub_config0_sysmem_nvlink_mask_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fb_hshub_config0_peer_pcie_mask_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 fb_hshub_config0_peer_pcie_mask_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 fb_hshub_config1_r(void) +{ + return 0x001fbc04U; +} +static inline u32 fb_hshub_config1_peer_0_nvlink_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fb_hshub_config1_peer_0_nvlink_mask_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 fb_hshub_config1_peer_1_nvlink_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 fb_hshub_config1_peer_1_nvlink_mask_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 fb_hshub_config1_peer_2_nvlink_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 fb_hshub_config1_peer_2_nvlink_mask_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 fb_hshub_config1_peer_3_nvlink_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 fb_hshub_config1_peer_3_nvlink_mask_v(u32 r) +{ + return (r >> 24U) & 0xffU; +} +static inline u32 fb_hshub_config2_r(void) +{ + return 0x001fbc08U; +} +static inline u32 fb_hshub_config2_peer_4_nvlink_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fb_hshub_config2_peer_4_nvlink_mask_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 fb_hshub_config2_peer_5_nvlink_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 fb_hshub_config2_peer_5_nvlink_mask_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 fb_hshub_config2_peer_6_nvlink_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 fb_hshub_config2_peer_6_nvlink_mask_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 fb_hshub_config2_peer_7_nvlink_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 fb_hshub_config2_peer_7_nvlink_mask_v(u32 r) +{ + return (r >> 24U) & 0xffU; +} +static inline u32 fb_hshub_config6_r(void) +{ + return 0x001fbc18U; +} +static inline u32 fb_hshub_config7_r(void) +{ + return 0x001fbc1cU; +} +static inline u32 fb_hshub_config7_nvlink_logical_0_physical_portmap_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 fb_hshub_config7_nvlink_logical_0_physical_portmap_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 fb_hshub_config7_nvlink_logical_1_physical_portmap_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 fb_hshub_config7_nvlink_logical_1_physical_portmap_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 fb_hshub_config7_nvlink_logical_2_physical_portmap_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 fb_hshub_config7_nvlink_logical_2_physical_portmap_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 fb_hshub_config7_nvlink_logical_3_physical_portmap_f(u32 v) +{ + return (v & 0xfU) << 12U; +} +static inline u32 fb_hshub_config7_nvlink_logical_3_physical_portmap_v(u32 r) +{ + return (r >> 12U) & 0xfU; +} +static inline u32 fb_hshub_config7_nvlink_logical_4_physical_portmap_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 fb_hshub_config7_nvlink_logical_4_physical_portmap_v(u32 r) +{ + return (r >> 16U) & 0xfU; +} +static inline u32 fb_hshub_config7_nvlink_logical_5_physical_portmap_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 fb_hshub_config7_nvlink_logical_5_physical_portmap_v(u32 r) +{ + return (r >> 20U) & 0xfU; +} +static inline u32 fb_hshub_config7_nvlink_logical_6_physical_portmap_f(u32 v) +{ + return (v & 0xfU) << 24U; +} +static inline u32 fb_hshub_config7_nvlink_logical_6_physical_portmap_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 fb_hshub_config7_nvlink_logical_7_physical_portmap_f(u32 v) +{ + return (v & 0xfU) << 28U; +} +static inline u32 fb_hshub_config7_nvlink_logical_7_physical_portmap_v(u32 r) +{ + return (r >> 28U) & 0xfU; +} +static inline u32 fb_hshub_nvl_cfg_priv_level_mask_r(void) +{ + return 0x001fbc50U; +} +static inline u32 fb_hshub_nvl_cfg_priv_level_mask_write_protection_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 fb_hshub_nvl_cfg_priv_level_mask_write_protection_v(u32 r) +{ + return (r >> 4U) & 0x7U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_fifo_gv100.h b/include/nvgpu/hw/gv100/hw_fifo_gv100.h new file mode 100644 index 0000000..4e9b590 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_fifo_gv100.h @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fifo_gv100_h_ +#define _hw_fifo_gv100_h_ + +static inline u32 fifo_bar1_base_r(void) +{ + return 0x00002254U; +} +static inline u32 fifo_bar1_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_bar1_base_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_bar1_base_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 fifo_bar1_base_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_userd_writeback_r(void) +{ + return 0x0000225cU; +} +static inline u32 fifo_userd_writeback_timer_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fifo_userd_writeback_timer_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_userd_writeback_timer_shorter_v(void) +{ + return 0x00000003U; +} +static inline u32 fifo_userd_writeback_timer_100us_v(void) +{ + return 0x00000064U; +} +static inline u32 fifo_userd_writeback_timescale_f(u32 v) +{ + return (v & 0xfU) << 12U; +} +static inline u32 fifo_userd_writeback_timescale_0_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_runlist_base_r(void) +{ + return 0x00002270U; +} +static inline u32 fifo_runlist_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_runlist_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fifo_runlist_base_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_runlist_base_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 fifo_runlist_r(void) +{ + return 0x00002274U; +} +static inline u32 fifo_runlist_engine_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 fifo_eng_runlist_base_r(u32 i) +{ + return 0x00002280U + i*8U; +} +static inline u32 fifo_eng_runlist_base__size_1_v(void) +{ + return 0x0000000dU; +} +static inline u32 fifo_eng_runlist_r(u32 i) +{ + return 0x00002284U + i*8U; +} +static inline u32 fifo_eng_runlist__size_1_v(void) +{ + return 0x0000000dU; +} +static inline u32 fifo_eng_runlist_length_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fifo_eng_runlist_length_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 fifo_eng_runlist_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_pb_timeslice_r(u32 i) +{ + return 0x00002350U + i*4U; +} +static inline u32 fifo_pb_timeslice_timeout_16_f(void) +{ + return 0x10U; +} +static inline u32 fifo_pb_timeslice_timescale_0_f(void) +{ + return 0x0U; +} +static inline u32 fifo_pb_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_pbdma_map_r(u32 i) +{ + return 0x00002390U + i*4U; +} +static inline u32 fifo_intr_0_r(void) +{ + return 0x00002100U; +} +static inline u32 fifo_intr_0_bind_error_pending_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_bind_error_reset_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_sched_error_pending_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_sched_error_reset_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_chsw_error_pending_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_chsw_error_reset_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_memop_timeout_pending_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_memop_timeout_reset_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_lb_error_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_lb_error_reset_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_pbdma_intr_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_intr_0_runlist_event_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 fifo_intr_0_channel_intr_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_intr_en_0_r(void) +{ + return 0x00002140U; +} +static inline u32 fifo_intr_en_0_sched_error_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_intr_en_0_sched_error_m(void) +{ + return 0x1U << 8U; +} +static inline u32 fifo_intr_en_1_r(void) +{ + return 0x00002528U; +} +static inline u32 fifo_intr_bind_error_r(void) +{ + return 0x0000252cU; +} +static inline u32 fifo_intr_sched_error_r(void) +{ + return 0x0000254cU; +} +static inline u32 fifo_intr_sched_error_code_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fifo_intr_chsw_error_r(void) +{ + return 0x0000256cU; +} +static inline u32 fifo_intr_pbdma_id_r(void) +{ + return 0x000025a0U; +} +static inline u32 fifo_intr_pbdma_id_status_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_intr_pbdma_id_status_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fifo_intr_pbdma_id_status__size_1_v(void) +{ + return 0x0000000eU; +} +static inline u32 fifo_intr_runlist_r(void) +{ + return 0x00002a00U; +} +static inline u32 fifo_fb_timeout_r(void) +{ + return 0x00002a04U; +} +static inline u32 fifo_fb_timeout_period_m(void) +{ + return 0x3fffffffU << 0U; +} +static inline u32 fifo_fb_timeout_period_max_f(void) +{ + return 0x3fffffffU; +} +static inline u32 fifo_fb_timeout_period_init_f(void) +{ + return 0x3c00U; +} +static inline u32 fifo_sched_disable_r(void) +{ + return 0x00002630U; +} +static inline u32 fifo_sched_disable_runlist_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_sched_disable_runlist_m(u32 i) +{ + return 0x1U << (0U + i*1U); +} +static inline u32 fifo_sched_disable_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_runlist_preempt_r(void) +{ + return 0x00002638U; +} +static inline u32 fifo_runlist_preempt_runlist_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_runlist_preempt_runlist_m(u32 i) +{ + return 0x1U << (0U + i*1U); +} +static inline u32 fifo_runlist_preempt_runlist_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_preempt_r(void) +{ + return 0x00002634U; +} +static inline u32 fifo_preempt_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_preempt_type_channel_f(void) +{ + return 0x0U; +} +static inline u32 fifo_preempt_type_tsg_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_preempt_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_preempt_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_engine_status_r(u32 i) +{ + return 0x00002640U + i*8U; +} +static inline u32 fifo_engine_status__size_1_v(void) +{ + return 0x0000000fU; +} +static inline u32 fifo_engine_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_engine_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_engine_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_engine_status_ctx_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_engine_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_engine_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_engine_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_eng_reload_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 fifo_engine_status_faulted_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fifo_engine_status_faulted_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_engine_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fifo_engine_status_engine_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_engine_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_f(void) +{ + return 0x8000U; +} +static inline u32 fifo_pbdma_status_r(u32 i) +{ + return 0x00003080U + i*4U; +} +static inline u32 fifo_pbdma_status__size_1_v(void) +{ + return 0x0000000eU; +} +static inline u32 fifo_pbdma_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_pbdma_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_pbdma_status_chan_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_pbdma_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_pbdma_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_chsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_pbdma_status_chsw_in_progress_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_cfg0_r(void) +{ + return 0x00002004U; +} +static inline u32 fifo_cfg0_num_pbdma_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 fifo_cfg0_pbdma_fault_id_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_flush_gv100.h b/include/nvgpu/hw/gv100/hw_flush_gv100.h new file mode 100644 index 0000000..b604562 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_flush_gv100.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_flush_gv100_h_ +#define _hw_flush_gv100_h_ + +static inline u32 flush_l2_system_invalidate_r(void) +{ + return 0x00070004U; +} +static inline u32 flush_l2_system_invalidate_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_r(void) +{ + return 0x00070010U; +} +static inline u32 flush_l2_flush_dirty_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_r(void) +{ + return 0x0007000cU; +} +static inline u32 flush_l2_clean_comptags_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_r(void) +{ + return 0x00070000U; +} +static inline u32 flush_fb_flush_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_fb_flush_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_fb_flush_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_fb_flush_outstanding_true_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_fuse_gv100.h b/include/nvgpu/hw/gv100/hw_fuse_gv100.h new file mode 100644 index 0000000..48194ea --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_fuse_gv100.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fuse_gv100_h_ +#define _hw_fuse_gv100_h_ + +static inline u32 fuse_status_opt_gpc_r(void) +{ + return 0x00021c1cU; +} +static inline u32 fuse_status_opt_tpc_gpc_r(u32 i) +{ + return 0x00021c38U + i*4U; +} +static inline u32 fuse_ctrl_opt_tpc_gpc_r(u32 i) +{ + return 0x00021838U + i*4U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_r(void) +{ + return 0x00021944U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_m(void) +{ + return 0xffU << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_r(void) +{ + return 0x00021948U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_yes_f(void) +{ + return 0x1U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_no_f(void) +{ + return 0x0U; +} +static inline u32 fuse_status_opt_fbio_r(void) +{ + return 0x00021c14U; +} +static inline u32 fuse_status_opt_fbio_data_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fuse_status_opt_fbio_data_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fuse_status_opt_fbio_data_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fuse_status_opt_rop_l2_fbp_r(u32 i) +{ + return 0x00021d70U + i*4U; +} +static inline u32 fuse_status_opt_fbp_r(void) +{ + return 0x00021d38U; +} +static inline u32 fuse_status_opt_fbp_idx_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fuse_opt_ecc_en_r(void) +{ + return 0x00021228U; +} +static inline u32 fuse_opt_feature_fuses_override_disable_r(void) +{ + return 0x000213f0U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_gmmu_gv100.h b/include/nvgpu/hw/gv100/hw_gmmu_gv100.h new file mode 100644 index 0000000..8cccfa9 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_gmmu_gv100.h @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gmmu_gv100_h_ +#define _hw_gmmu_gv100_h_ + +static inline u32 gmmu_new_pde_is_pte_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_is_pte_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_aperture_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_aperture_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_aperture_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_pde_aperture_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_pde_aperture_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_pde_address_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pde_address_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_vol_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_vol_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_pde_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_new_pde__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_dual_pde_is_pte_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_is_pte_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_dual_pde_address_big_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_new_dual_pde_address_big_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_dual_pde_vol_small_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_vol_small_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_dual_pde_vol_small_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_vol_big_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_vol_big_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_dual_pde_vol_big_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_address_small_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_dual_pde_address_small_sys_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_new_dual_pde_address_big_shift_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_dual_pde__size_v(void) +{ + return 0x00000010U; +} +static inline u32 gmmu_new_pte__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_pte_valid_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_valid_true_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_new_pte_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_privilege_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_privilege_true_f(void) +{ + return 0x20U; +} +static inline u32 gmmu_new_pte_privilege_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_address_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pte_address_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_address_vid_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pte_address_vid_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_vol_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_vol_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_pte_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_aperture_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_aperture_video_memory_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_aperture_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_pte_aperture_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_pte_read_only_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_read_only_true_f(void) +{ + return 0x40U; +} +static inline u32 gmmu_new_pte_comptagline_f(u32 v) +{ + return (v & 0x3ffffU) << 4U; +} +static inline u32 gmmu_new_pte_comptagline_w(void) +{ + return 1U; +} +static inline u32 gmmu_new_pte_kind_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gmmu_new_pte_kind_w(void) +{ + return 1U; +} +static inline u32 gmmu_new_pte_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_pte_kind_f(u32 v) +{ + return (v & 0xffU) << 4U; +} +static inline u32 gmmu_pte_kind_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_kind_invalid_v(void) +{ + return 0x000000ffU; +} +static inline u32 gmmu_pte_kind_pitch_v(void) +{ + return 0x00000000U; +} +static inline u32 gmmu_fault_client_type_gpc_v(void) +{ + return 0x00000000U; +} +static inline u32 gmmu_fault_client_type_hub_v(void) +{ + return 0x00000001U; +} +static inline u32 gmmu_fault_type_unbound_inst_block_v(void) +{ + return 0x00000004U; +} +static inline u32 gmmu_fault_mmu_eng_id_bar2_v(void) +{ + return 0x00000005U; +} +static inline u32 gmmu_fault_mmu_eng_id_physical_v(void) +{ + return 0x0000001fU; +} +static inline u32 gmmu_fault_mmu_eng_id_ce0_v(void) +{ + return 0x0000000fU; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_gr_gv100.h b/include/nvgpu/hw/gv100/hw_gr_gv100.h new file mode 100644 index 0000000..0f83d6b --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_gr_gv100.h @@ -0,0 +1,4119 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gr_gv100_h_ +#define _hw_gr_gv100_h_ + +static inline u32 gr_intr_r(void) +{ + return 0x00400100U; +} +static inline u32 gr_intr_notify_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_notify_reset_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_semaphore_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_semaphore_reset_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_illegal_method_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_method_reset_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_notify_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_illegal_notify_reset_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 gr_intr_firmware_method_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_firmware_method_reset_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_illegal_class_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_illegal_class_reset_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_fecs_error_pending_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_fecs_error_reset_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_class_error_pending_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_class_error_reset_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_exception_pending_f(void) +{ + return 0x200000U; +} +static inline u32 gr_intr_exception_reset_f(void) +{ + return 0x200000U; +} +static inline u32 gr_fecs_intr_r(void) +{ + return 0x00400144U; +} +static inline u32 gr_class_error_r(void) +{ + return 0x00400110U; +} +static inline u32 gr_class_error_code_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_intr_nonstall_r(void) +{ + return 0x00400120U; +} +static inline u32 gr_intr_nonstall_trap_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_en_r(void) +{ + return 0x0040013cU; +} +static inline u32 gr_exception_r(void) +{ + return 0x00400108U; +} +static inline u32 gr_exception_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception_gpc_m(void) +{ + return 0x1U << 24U; +} +static inline u32 gr_exception_memfmt_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_exception_ds_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_exception_sked_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_exception_pd_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_exception_scc_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_exception_ssync_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_exception_mme_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_exception1_r(void) +{ + return 0x00400118U; +} +static inline u32 gr_exception1_gpc_0_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_exception2_r(void) +{ + return 0x0040011cU; +} +static inline u32 gr_exception_en_r(void) +{ + return 0x00400138U; +} +static inline u32 gr_exception_en_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception_en_fe_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_exception_en_gpc_m(void) +{ + return 0x1U << 24U; +} +static inline u32 gr_exception_en_gpc_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 gr_exception_en_memfmt_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_exception_en_memfmt_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_exception_en_ds_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_exception_en_ds_enabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_exception_en_pd_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_exception_en_pd_enabled_f(void) +{ + return 0x4U; +} +static inline u32 gr_exception_en_scc_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_exception_en_scc_enabled_f(void) +{ + return 0x8U; +} +static inline u32 gr_exception_en_ssync_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_exception_en_ssync_enabled_f(void) +{ + return 0x20U; +} +static inline u32 gr_exception_en_mme_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_exception_en_mme_enabled_f(void) +{ + return 0x80U; +} +static inline u32 gr_exception_en_sked_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_exception_en_sked_enabled_f(void) +{ + return 0x100U; +} +static inline u32 gr_exception1_en_r(void) +{ + return 0x00400130U; +} +static inline u32 gr_exception2_en_r(void) +{ + return 0x00400134U; +} +static inline u32 gr_gpfifo_ctl_r(void) +{ + return 0x00400500U; +} +static inline u32 gr_gpfifo_ctl_access_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpfifo_ctl_access_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpfifo_ctl_access_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpfifo_status_r(void) +{ + return 0x00400504U; +} +static inline u32 gr_trapped_addr_r(void) +{ + return 0x00400704U; +} +static inline u32 gr_trapped_addr_mthd_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 gr_trapped_addr_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 gr_trapped_addr_mme_generated_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 gr_trapped_addr_datahigh_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 gr_trapped_addr_priv_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 gr_trapped_addr_status_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_trapped_data_lo_r(void) +{ + return 0x00400708U; +} +static inline u32 gr_trapped_data_hi_r(void) +{ + return 0x0040070cU; +} +static inline u32 gr_trapped_data_mme_r(void) +{ + return 0x00400710U; +} +static inline u32 gr_trapped_data_mme_pc_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_status_r(void) +{ + return 0x00400700U; +} +static inline u32 gr_status_fe_method_upper_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_status_fe_gi_v(u32 r) +{ + return (r >> 21U) & 0x1U; +} +static inline u32 gr_status_mask_r(void) +{ + return 0x00400610U; +} +static inline u32 gr_status_1_r(void) +{ + return 0x00400604U; +} +static inline u32 gr_status_2_r(void) +{ + return 0x00400608U; +} +static inline u32 gr_engine_status_r(void) +{ + return 0x0040060cU; +} +static inline u32 gr_engine_status_value_busy_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_be0_becs_be_exception_r(void) +{ + return 0x00410204U; +} +static inline u32 gr_pri_be0_becs_be_exception_en_r(void) +{ + return 0x00410208U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_en_r(void) +{ + return 0x00502c94U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_activity_0_r(void) +{ + return 0x00400380U; +} +static inline u32 gr_activity_1_r(void) +{ + return 0x00400384U; +} +static inline u32 gr_activity_2_r(void) +{ + return 0x00400388U; +} +static inline u32 gr_activity_4_r(void) +{ + return 0x00400390U; +} +static inline u32 gr_activity_4_gpc0_s(void) +{ + return 3U; +} +static inline u32 gr_activity_4_gpc0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_activity_4_gpc0_m(void) +{ + return 0x7U << 0U; +} +static inline u32 gr_activity_4_gpc0_v(u32 r) +{ + return (r >> 0U) & 0x7U; +} +static inline u32 gr_activity_4_gpc0_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_activity_4_gpc0_preempted_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_pri_gpc0_gcc_dbg_r(void) +{ + return 0x00501000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_r(void) +{ + return 0x00419000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_invalidate_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cache_control_r(void) +{ + return 0x0050433cU; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_r(void) +{ + return 0x00419b3cU; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_invalidate_cache_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_sked_activity_r(void) +{ + return 0x00407054U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity0_r(void) +{ + return 0x00502c80U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity1_r(void) +{ + return 0x00502c84U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity2_r(void) +{ + return 0x00502c88U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity3_r(void) +{ + return 0x00502c8cU; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x00504500U; +} +static inline u32 gr_pri_gpc0_tpc1_tpccs_tpc_activity_0_r(void) +{ + return 0x00504d00U; +} +static inline u32 gr_pri_gpc0_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00501d00U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_0_r(void) +{ + return 0x0041ac80U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_1_r(void) +{ + return 0x0041ac84U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_2_r(void) +{ + return 0x0041ac88U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_3_r(void) +{ + return 0x0041ac8cU; +} +static inline u32 gr_pri_gpcs_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x0041c500U; +} +static inline u32 gr_pri_gpcs_tpc1_tpccs_tpc_activity_0_r(void) +{ + return 0x0041cd00U; +} +static inline u32 gr_pri_gpcs_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00419d00U; +} +static inline u32 gr_pri_be0_becs_be_activity0_r(void) +{ + return 0x00410200U; +} +static inline u32 gr_pri_be1_becs_be_activity0_r(void) +{ + return 0x00410600U; +} +static inline u32 gr_pri_bes_becs_be_activity0_r(void) +{ + return 0x00408a00U; +} +static inline u32 gr_pri_ds_mpipe_status_r(void) +{ + return 0x00405858U; +} +static inline u32 gr_pri_fe_go_idle_info_r(void) +{ + return 0x00404194U; +} +static inline u32 gr_pri_fe_chip_def_info_r(void) +{ + return 0x00404030U; +} +static inline u32 gr_pri_fe_chip_def_info_max_veid_count_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_pri_fe_chip_def_info_max_veid_count_init_v(void) +{ + return 0x00000040U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_tex_subunits_status_r(void) +{ + return 0x00504238U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_r(void) +{ + return 0x00504358U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp1_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp2_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp3_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp4_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp5_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp6_m(void) +{ + return 0x1U << 6U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp7_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp0_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp1_m(void) +{ + return 0x1U << 9U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp2_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp3_m(void) +{ + return 0x1U << 11U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp4_m(void) +{ + return 0x1U << 12U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp5_m(void) +{ + return 0x1U << 13U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp6_m(void) +{ + return 0x1U << 14U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp7_m(void) +{ + return 0x1U << 15U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 26U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_corrected_err_count_r(void) +{ + return 0x0050435cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_uncorrected_err_count_r(void) +{ + return 0x00504360U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_r(void) +{ + return 0x0050436cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_corrected_err_el1_0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_corrected_err_el1_1_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_uncorrected_err_el1_0_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_uncorrected_err_el1_1_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_corrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_uncorrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_corrected_err_count_r(void) +{ + return 0x00504370U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_uncorrected_err_count_r(void) +{ + return 0x00504374U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_r(void) +{ + return 0x00504638U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_corrected_err_warp_sm0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_corrected_err_warp_sm1_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_corrected_err_barrier_sm0_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_corrected_err_barrier_sm1_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_uncorrected_err_warp_sm0_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_uncorrected_err_warp_sm1_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_uncorrected_err_barrier_sm0_m(void) +{ + return 0x1U << 6U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_uncorrected_err_barrier_sm1_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_corrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_uncorrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 18U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_corrected_err_count_r(void) +{ + return 0x0050463cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_uncorrected_err_count_r(void) +{ + return 0x00504640U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_r(void) +{ + return 0x005042c4U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_default_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe0_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe1_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_mpc_hww_esr_r(void) +{ + return 0x00504430U; +} +static inline u32 gr_gpc0_tpc0_mpc_hww_esr_reset_trigger_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_mpc_hww_esr_info_r(void) +{ + return 0x00504434U; +} +static inline u32 gr_gpc0_tpc0_mpc_hww_esr_info_veid_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_pri_be0_crop_status1_r(void) +{ + return 0x00410134U; +} +static inline u32 gr_pri_bes_crop_status1_r(void) +{ + return 0x00408934U; +} +static inline u32 gr_pri_be0_zrop_status_r(void) +{ + return 0x00410048U; +} +static inline u32 gr_pri_be0_zrop_status2_r(void) +{ + return 0x0041004cU; +} +static inline u32 gr_pri_bes_zrop_status_r(void) +{ + return 0x00408848U; +} +static inline u32 gr_pri_bes_zrop_status2_r(void) +{ + return 0x0040884cU; +} +static inline u32 gr_pipe_bundle_address_r(void) +{ + return 0x00400200U; +} +static inline u32 gr_pipe_bundle_address_value_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pipe_bundle_address_veid_f(u32 v) +{ + return (v & 0x3fU) << 20U; +} +static inline u32 gr_pipe_bundle_address_veid_w(void) +{ + return 0U; +} +static inline u32 gr_pipe_bundle_data_r(void) +{ + return 0x00400204U; +} +static inline u32 gr_pipe_bundle_config_r(void) +{ + return 0x00400208U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_r(void) +{ + return 0x00404000U; +} +static inline u32 gr_fe_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_fe_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_info_r(void) +{ + return 0x004041b0U; +} +static inline u32 gr_gpcs_tpcs_sms_hww_global_esr_report_mask_r(void) +{ + return 0x00419eacU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_r(void) +{ + return 0x0050472cU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_multiple_warp_errors_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_bpt_int_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_bpt_pause_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_single_step_complete_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_error_in_trap_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpcs_tpcs_sms_hww_global_esr_r(void) +{ + return 0x00419eb4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_r(void) +{ + return 0x00504734U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_bpt_int_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_bpt_pause_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_single_step_complete_m(void) +{ + return 0x1U << 6U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_multiple_warp_errors_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_multiple_warp_errors_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_error_in_trap_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_error_in_trap_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_fe_go_idle_timeout_r(void) +{ + return 0x00404154U; +} +static inline u32 gr_fe_go_idle_timeout_count_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fe_go_idle_timeout_count_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_go_idle_timeout_count_prod_f(void) +{ + return 0x1800U; +} +static inline u32 gr_fe_object_table_r(u32 i) +{ + return 0x00404200U + i*4U; +} +static inline u32 gr_fe_object_table_nvclass_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_fe_tpc_fs_r(u32 i) +{ + return 0x0040a200U + i*4U; +} +static inline u32 gr_pri_mme_shadow_raw_index_r(void) +{ + return 0x00404488U; +} +static inline u32 gr_pri_mme_shadow_raw_index_write_trigger_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pri_mme_shadow_raw_data_r(void) +{ + return 0x0040448cU; +} +static inline u32 gr_mme_hww_esr_r(void) +{ + return 0x00404490U; +} +static inline u32 gr_mme_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_mme_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_mme_hww_esr_info_r(void) +{ + return 0x00404494U; +} +static inline u32 gr_memfmt_hww_esr_r(void) +{ + return 0x00404600U; +} +static inline u32 gr_memfmt_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_memfmt_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fecs_cpuctl_r(void) +{ + return 0x00409100U; +} +static inline u32 gr_fecs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_cpuctl_alias_r(void) +{ + return 0x00409130U; +} +static inline u32 gr_fecs_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_dmactl_r(void) +{ + return 0x0040910cU; +} +static inline u32 gr_fecs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_fecs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_fecs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_fecs_os_r(void) +{ + return 0x00409080U; +} +static inline u32 gr_fecs_idlestate_r(void) +{ + return 0x0040904cU; +} +static inline u32 gr_fecs_mailbox0_r(void) +{ + return 0x00409040U; +} +static inline u32 gr_fecs_mailbox1_r(void) +{ + return 0x00409044U; +} +static inline u32 gr_fecs_irqstat_r(void) +{ + return 0x00409008U; +} +static inline u32 gr_fecs_irqmode_r(void) +{ + return 0x0040900cU; +} +static inline u32 gr_fecs_irqmask_r(void) +{ + return 0x00409018U; +} +static inline u32 gr_fecs_irqdest_r(void) +{ + return 0x0040901cU; +} +static inline u32 gr_fecs_curctx_r(void) +{ + return 0x00409050U; +} +static inline u32 gr_fecs_nxtctx_r(void) +{ + return 0x00409054U; +} +static inline u32 gr_fecs_engctl_r(void) +{ + return 0x004090a4U; +} +static inline u32 gr_fecs_debug1_r(void) +{ + return 0x00409090U; +} +static inline u32 gr_fecs_debuginfo_r(void) +{ + return 0x00409094U; +} +static inline u32 gr_fecs_icd_cmd_r(void) +{ + return 0x00409200U; +} +static inline u32 gr_fecs_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 gr_fecs_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 gr_fecs_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 gr_fecs_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 gr_fecs_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 gr_fecs_icd_rdata_r(void) +{ + return 0x0040920cU; +} +static inline u32 gr_fecs_imemc_r(u32 i) +{ + return 0x00409180U + i*16U; +} +static inline u32 gr_fecs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_imemd_r(u32 i) +{ + return 0x00409184U + i*16U; +} +static inline u32 gr_fecs_imemt_r(u32 i) +{ + return 0x00409188U + i*16U; +} +static inline u32 gr_fecs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_dmemc_r(u32 i) +{ + return 0x004091c0U + i*8U; +} +static inline u32 gr_fecs_dmemc_offs_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 gr_fecs_dmemc_offs_v(u32 r) +{ + return (r >> 2U) & 0x3fU; +} +static inline u32 gr_fecs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_dmemd_r(u32 i) +{ + return 0x004091c4U + i*8U; +} +static inline u32 gr_fecs_dmatrfbase_r(void) +{ + return 0x00409110U; +} +static inline u32 gr_fecs_dmatrfmoffs_r(void) +{ + return 0x00409114U; +} +static inline u32 gr_fecs_dmatrffboffs_r(void) +{ + return 0x0040911cU; +} +static inline u32 gr_fecs_dmatrfcmd_r(void) +{ + return 0x00409118U; +} +static inline u32 gr_fecs_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_fecs_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_fecs_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_fecs_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_fecs_bootvec_r(void) +{ + return 0x00409104U; +} +static inline u32 gr_fecs_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_falcon_hwcfg_r(void) +{ + return 0x00409108U; +} +static inline u32 gr_gpcs_gpccs_falcon_hwcfg_r(void) +{ + return 0x0041a108U; +} +static inline u32 gr_fecs_falcon_rm_r(void) +{ + return 0x00409084U; +} +static inline u32 gr_fecs_current_ctx_r(void) +{ + return 0x00409b00U; +} +static inline u32 gr_fecs_current_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_current_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_current_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_current_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_current_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_current_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_current_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_current_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_current_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_current_ctx_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_method_data_r(void) +{ + return 0x00409500U; +} +static inline u32 gr_fecs_method_push_r(void) +{ + return 0x00409504U; +} +static inline u32 gr_fecs_method_push_adr_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_v(void) +{ + return 0x00000003U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_f(void) +{ + return 0x3U; +} +static inline u32 gr_fecs_method_push_adr_discover_image_size_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_method_push_adr_wfi_golden_save_v(void) +{ + return 0x00000009U; +} +static inline u32 gr_fecs_method_push_adr_restore_golden_v(void) +{ + return 0x00000015U; +} +static inline u32 gr_fecs_method_push_adr_discover_zcull_image_size_v(void) +{ + return 0x00000016U; +} +static inline u32 gr_fecs_method_push_adr_discover_pm_image_size_v(void) +{ + return 0x00000025U; +} +static inline u32 gr_fecs_method_push_adr_discover_reglist_image_size_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_bind_instance_v(void) +{ + return 0x00000031U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_virtual_address_v(void) +{ + return 0x00000032U; +} +static inline u32 gr_fecs_method_push_adr_stop_ctxsw_v(void) +{ + return 0x00000038U; +} +static inline u32 gr_fecs_method_push_adr_start_ctxsw_v(void) +{ + return 0x00000039U; +} +static inline u32 gr_fecs_method_push_adr_set_watchdog_timeout_f(void) +{ + return 0x21U; +} +static inline u32 gr_fecs_method_push_adr_discover_preemption_image_size_v(void) +{ + return 0x0000001aU; +} +static inline u32 gr_fecs_method_push_adr_halt_pipeline_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_fecs_method_push_adr_configure_interrupt_completion_option_v(void) +{ + return 0x0000003aU; +} +static inline u32 gr_fecs_host_int_status_r(void) +{ + return 0x00409c18U; +} +static inline u32 gr_fecs_host_int_status_fault_during_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_fecs_host_int_status_umimp_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 gr_fecs_host_int_status_umimp_illegal_method_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 gr_fecs_host_int_status_ctxsw_intr_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_host_int_clear_r(void) +{ + return 0x00409c20U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_clear_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_r(void) +{ + return 0x00409c24U; +} +static inline u32 gr_fecs_host_int_enable_ctxsw_intr1_enable_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_fault_during_ctxsw_enable_f(void) +{ + return 0x10000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_firmware_method_enable_f(void) +{ + return 0x20000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_illegal_method_enable_f(void) +{ + return 0x40000U; +} +static inline u32 gr_fecs_host_int_enable_watchdog_enable_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_r(void) +{ + return 0x00409614U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_engine_reset_disabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_engine_reset_disabled_f(void) +{ + return 0x20U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_engine_reset_disabled_f(void) +{ + return 0x40U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_disabled_f(void) +{ + return 0x100U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_disabled_f(void) +{ + return 0x200U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_disabled_f(void) +{ + return 0x400U; +} +static inline u32 gr_fecs_ctx_state_store_major_rev_id_r(void) +{ + return 0x0040960cU; +} +static inline u32 gr_fecs_ctxsw_mailbox_r(u32 i) +{ + return 0x00409800U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_fail_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_r(u32 i) +{ + return 0x004098c0U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_r(u32 i) +{ + return 0x00409840U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_fs_r(void) +{ + return 0x00409604U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_fs_num_available_fbps_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_fbps_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_m(void) +{ + return 0x1fU << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_fecs_cfg_r(void) +{ + return 0x00409620U; +} +static inline u32 gr_fecs_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_fecs_rc_lanes_r(void) +{ + return 0x00409880U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_fecs_ctxsw_status_1_r(void) +{ + return 0x00409400U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_m(void) +{ + return 0x1U << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_adr_r(void) +{ + return 0x00409a24U; +} +static inline u32 gr_fecs_new_ctx_r(void) +{ + return 0x00409b04U; +} +static inline u32 gr_fecs_new_ctx_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_new_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_new_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_new_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_new_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_new_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_new_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_new_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_ptr_r(void) +{ + return 0x00409a0cU; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_arb_ctx_cmd_r(void) +{ + return 0x00409a10U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_ctxsw_status_fe_0_r(void) +{ + return 0x00409c00U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_gpc_0_r(void) +{ + return 0x00502c04U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_1_r(void) +{ + return 0x00502400U; +} +static inline u32 gr_fecs_ctxsw_idlestate_r(void) +{ + return 0x00409420U; +} +static inline u32 gr_fecs_feature_override_ecc_r(void) +{ + return 0x00409658U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_lrf_override_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_ltc_override_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_lrf_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_ltc_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_idlestate_r(void) +{ + return 0x00502420U; +} +static inline u32 gr_rstr2d_gpc_map_r(u32 i) +{ + return 0x0040780cU + i*4U; +} +static inline u32 gr_rstr2d_map_table_cfg_r(void) +{ + return 0x004078bcU; +} +static inline u32 gr_rstr2d_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_rstr2d_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_hww_esr_r(void) +{ + return 0x00406018U; +} +static inline u32 gr_pd_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pd_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_num_tpc_per_gpc_r(u32 i) +{ + return 0x00406028U + i*4U; +} +static inline u32 gr_pd_num_tpc_per_gpc__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count1_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count2_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count3_f(u32 v) +{ + return (v & 0xfU) << 12U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count4_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count5_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count6_f(u32 v) +{ + return (v & 0xfU) << 24U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count7_f(u32 v) +{ + return (v & 0xfU) << 28U; +} +static inline u32 gr_pd_ab_dist_cfg0_r(void) +{ + return 0x004064c0U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_en_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_dis_f(void) +{ + return 0x0U; +} +static inline u32 gr_pd_ab_dist_cfg1_r(void) +{ + return 0x004064c4U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_batches_init_f(void) +{ + return 0xffffU; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_granularity_v(void) +{ + return 0x00000080U; +} +static inline u32 gr_pd_ab_dist_cfg2_r(void) +{ + return 0x004064c8U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_f(u32 v) +{ + return (v & 0x1fffU) << 0U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_init_v(void) +{ + return 0x00001680U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_f(u32 v) +{ + return (v & 0x1fffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_scc_bundle_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_min_gpm_fifo_depths_v(void) +{ + return 0x00001680U; +} +static inline u32 gr_pd_dist_skip_table_r(u32 i) +{ + return 0x004064d0U + i*4U; +} +static inline u32 gr_pd_dist_skip_table__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n0_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n1_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n2_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n3_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_ds_debug_r(void) +{ + return 0x00405800U; +} +static inline u32 gr_ds_debug_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_debug_timeslice_mode_enable_f(void) +{ + return 0x8000000U; +} +static inline u32 gr_ds_zbc_color_r_r(void) +{ + return 0x00405804U; +} +static inline u32 gr_ds_zbc_color_r_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_g_r(void) +{ + return 0x00405808U; +} +static inline u32 gr_ds_zbc_color_g_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_b_r(void) +{ + return 0x0040580cU; +} +static inline u32 gr_ds_zbc_color_b_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_a_r(void) +{ + return 0x00405810U; +} +static inline u32 gr_ds_zbc_color_a_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_r(void) +{ + return 0x00405814U; +} +static inline u32 gr_ds_zbc_color_fmt_val_f(u32 v) +{ + return (v & 0x7fU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_zero_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_color_fmt_val_unorm_one_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_ds_zbc_color_fmt_val_rf32_gf32_bf32_af32_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_ds_zbc_color_fmt_val_a8_b8_g8_r8_v(void) +{ + return 0x00000028U; +} +static inline u32 gr_ds_zbc_z_r(void) +{ + return 0x00405818U; +} +static inline u32 gr_ds_zbc_z_val_s(void) +{ + return 32U; +} +static inline u32 gr_ds_zbc_z_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_z_val_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_ds_zbc_z_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_ds_zbc_z_val__init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_ds_zbc_z_val__init_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_r(void) +{ + return 0x0040581cU; +} +static inline u32 gr_ds_zbc_z_fmt_val_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_fp32_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_tbl_index_r(void) +{ + return 0x00405820U; +} +static inline u32 gr_ds_zbc_tbl_index_val_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_ds_zbc_tbl_ld_r(void) +{ + return 0x00405824U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_c_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_z_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_zbc_tbl_ld_action_write_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_trigger_active_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_tga_constraintlogic_beta_r(void) +{ + return 0x00405830U; +} +static inline u32 gr_ds_tga_constraintlogic_beta_cbsize_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_ds_tga_constraintlogic_alpha_r(void) +{ + return 0x0040585cU; +} +static inline u32 gr_ds_tga_constraintlogic_alpha_cbsize_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_ds_hww_esr_r(void) +{ + return 0x00405840U; +} +static inline u32 gr_ds_hww_esr_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_esr_2_r(void) +{ + return 0x00405848U; +} +static inline u32 gr_ds_hww_esr_2_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_2_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_2_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_2_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_2_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_2_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_2_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_report_mask_r(void) +{ + return 0x00405844U; +} +static inline u32 gr_ds_hww_report_mask_sph0_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_hww_report_mask_sph1_err_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_ds_hww_report_mask_sph2_err_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_hww_report_mask_sph3_err_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_ds_hww_report_mask_sph4_err_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_ds_hww_report_mask_sph5_err_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_ds_hww_report_mask_sph6_err_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_ds_hww_report_mask_sph7_err_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_ds_hww_report_mask_sph8_err_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_ds_hww_report_mask_sph9_err_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_ds_hww_report_mask_sph10_err_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_ds_hww_report_mask_sph11_err_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_ds_hww_report_mask_sph12_err_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_ds_hww_report_mask_sph13_err_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_ds_hww_report_mask_sph14_err_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_ds_hww_report_mask_sph15_err_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_ds_hww_report_mask_sph16_err_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_ds_hww_report_mask_sph17_err_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_ds_hww_report_mask_sph18_err_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_ds_hww_report_mask_sph19_err_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_ds_hww_report_mask_sph20_err_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_ds_hww_report_mask_sph21_err_report_f(void) +{ + return 0x200000U; +} +static inline u32 gr_ds_hww_report_mask_sph22_err_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_ds_hww_report_mask_sph23_err_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_ds_hww_report_mask_2_r(void) +{ + return 0x0040584cU; +} +static inline u32 gr_ds_hww_report_mask_2_sph24_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_num_tpc_per_gpc_r(u32 i) +{ + return 0x00405870U + i*4U; +} +static inline u32 gr_scc_bundle_cb_base_r(void) +{ + return 0x00408004U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_bundle_cb_size_r(void) +{ + return 0x00408008U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b__prod_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_scc_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_pagepool_base_r(void) +{ + return 0x0040800cU; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_pagepool_r(void) +{ + return 0x00408010U; +} +static inline u32 gr_scc_pagepool_total_pages_f(u32 v) +{ + return (v & 0x3ffU) << 0U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_value_v(void) +{ + return 0x00000200U; +} +static inline u32 gr_scc_pagepool_total_pages_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_s(void) +{ + return 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_f(u32 v) +{ + return (v & 0x3ffU) << 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_m(void) +{ + return 0x3ffU << 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_v(u32 r) +{ + return (r >> 10U) & 0x3ffU; +} +static inline u32 gr_scc_pagepool_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_init_r(void) +{ + return 0x0040802cU; +} +static inline u32 gr_scc_init_ram_trigger_f(void) +{ + return 0x1U; +} +static inline u32 gr_scc_hww_esr_r(void) +{ + return 0x00408030U; +} +static inline u32 gr_scc_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_scc_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ssync_hww_esr_r(void) +{ + return 0x00405a14U; +} +static inline u32 gr_ssync_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ssync_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_sked_hww_esr_r(void) +{ + return 0x00407020U; +} +static inline u32 gr_sked_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_sked_hww_esr_en_r(void) +{ + return 0x00407024U; +} +static inline u32 gr_sked_hww_esr_en_skedcheck18_l1_config_too_small_m(void) +{ + return 0x1U << 25U; +} +static inline u32 gr_sked_hww_esr_en_skedcheck18_l1_config_too_small_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_sked_hww_esr_en_skedcheck18_l1_config_too_small_enabled_f(void) +{ + return 0x2000000U; +} +static inline u32 gr_cwd_fs_r(void) +{ + return 0x00405b00U; +} +static inline u32 gr_cwd_fs_num_gpcs_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_fs_num_tpcs_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_cwd_gpc_tpc_id_r(u32 i) +{ + return 0x00405b60U + i*4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc0_s(void) +{ + return 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_cwd_gpc_tpc_id_gpc0_s(void) +{ + return 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_gpc0_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc1_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_cwd_sm_id_r(u32 i) +{ + return 0x00405ba0U + i*4U; +} +static inline u32 gr_cwd_sm_id__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_cwd_sm_id_tpc0_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_sm_id_tpc1_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpc0_fs_gpc_r(void) +{ + return 0x00502608U; +} +static inline u32 gr_gpc0_fs_gpc_num_available_tpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_gpc0_fs_gpc_num_available_zculls_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_gpc0_cfg_r(void) +{ + return 0x00502620U; +} +static inline u32 gr_gpc0_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpccs_rc_lanes_r(void) +{ + return 0x00502880U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_rc_lane_size_r(void) +{ + return 0x00502910U; +} +static inline u32 gr_gpccs_rc_lane_size_v_s(void) +{ + return 24U; +} +static inline u32 gr_gpccs_rc_lane_size_v_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_zcull_fs_r(void) +{ + return 0x00500910U; +} +static inline u32 gr_gpc0_zcull_fs_num_sms_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 gr_gpc0_zcull_fs_num_active_banks_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_gpc0_zcull_ram_addr_r(void) +{ + return 0x00500914U; +} +static inline u32 gr_gpc0_zcull_ram_addr_tiles_per_hypertile_row_per_gpc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_gpc0_zcull_ram_addr_row_offset_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_r(void) +{ + return 0x00500918U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative__max_v(void) +{ + return 0x00800000U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_r(void) +{ + return 0x00500920U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_num_aliquots_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_zcsize_r(u32 i) +{ + return 0x00500a04U + i*32U; +} +static inline u32 gr_gpc0_zcull_zcsize_height_subregion__multiple_v(void) +{ + return 0x00000040U; +} +static inline u32 gr_gpc0_zcull_zcsize_width_subregion__multiple_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_r(u32 i) +{ + return 0x00500c10U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_id_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_r(u32 i) +{ + return 0x00500c30U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_mask_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_r(void) +{ + return 0x00504088U; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_value_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_r(void) +{ + return 0x00504608U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_tpc_id_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_tpc_id_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_r(void) +{ + return 0x00504330U; +} +static inline u32 gr_gpc0_tpc0_sm_arch_warp_count_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_spa_version_v(u32 r) +{ + return (r >> 8U) & 0xfffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_sm_version_v(u32 r) +{ + return (r >> 20U) & 0xfffU; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_r(void) +{ + return 0x00503018U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_true_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_r(void) +{ + return 0x005030c0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_m(void) +{ + return 0x3fffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_default_v(void) +{ + return 0x00000480U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_gfxp_v(void) +{ + return 0x00000d10U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_offset_r(void) +{ + return 0x005030f4U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_r(void) +{ + return 0x005030e4U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_default_v(void) +{ + return 0x00000800U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_offset_r(void) +{ + return 0x005030f8U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_r(void) +{ + return 0x005030f0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_v_default_v(void) +{ + return 0x00000480U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_0_r(void) +{ + return 0x00419e00U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_0_base_addr_43_12_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_r(void) +{ + return 0x00419e04U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_s(void) +{ + return 21U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_f(u32 v) +{ + return (v & 0x1fffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_m(void) +{ + return 0x1fffffU << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_v(u32 r) +{ + return (r >> 0U) & 0x1fffffU; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_granularity_f(void) +{ + return 0x80U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_s(void) +{ + return 1U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpccs_falcon_addr_r(void) +{ + return 0x0041a0acU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_msb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_v(u32 r) +{ + return (r >> 6U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_s(void) +{ + return 12U; +} +static inline u32 gr_gpccs_falcon_addr_ext_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_m(void) +{ + return 0xfffU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_gpccs_cpuctl_r(void) +{ + return 0x0041a100U; +} +static inline u32 gr_gpccs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_gpccs_dmactl_r(void) +{ + return 0x0041a10cU; +} +static inline u32 gr_gpccs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpccs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpccs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpccs_imemc_r(u32 i) +{ + return 0x0041a180U + i*16U; +} +static inline u32 gr_gpccs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_imemd_r(u32 i) +{ + return 0x0041a184U + i*16U; +} +static inline u32 gr_gpccs_imemt_r(u32 i) +{ + return 0x0041a188U + i*16U; +} +static inline u32 gr_gpccs_imemt__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_gpccs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpccs_dmemc_r(u32 i) +{ + return 0x0041a1c0U + i*8U; +} +static inline u32 gr_gpccs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_dmemd_r(u32 i) +{ + return 0x0041a1c4U + i*8U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_r(u32 i) +{ + return 0x0041a800U + i*4U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_r(void) +{ + return 0x00418e24U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_s(void) +{ + return 32U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_r(void) +{ + return 0x00418e28U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_s(void) +{ + return 11U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_m(void) +{ + return 0x7ffU << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_v(u32 r) +{ + return (r >> 0U) & 0x7ffU; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_init_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_init_f(void) +{ + return 0x30U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_s(void) +{ + return 1U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_r(void) +{ + return 0x005001dcU; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_default_v(void) +{ + return 0x000004b0U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_r(void) +{ + return 0x005001d8U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_r(void) +{ + return 0x004181e4U; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_cbes_reserve_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_cbes_reserve_gfxp_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_gpcs_ppcs_cbm_beta_cb_ctrl_r(void) +{ + return 0x0041befcU; +} +static inline u32 gr_gpcs_ppcs_cbm_beta_cb_ctrl_cbes_reserve_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_r(u32 i) +{ + return 0x00418ea0U + i*4U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_v_m(void) +{ + return 0x3fffffU << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_r_r(u32 i) +{ + return 0x00418010U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_r_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_g_r(u32 i) +{ + return 0x0041804cU + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_g_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_b_r(u32 i) +{ + return 0x00418088U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_b_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_a_r(u32 i) +{ + return 0x004180c4U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_a_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_c_01_to_04_format_r(void) +{ + return 0x00418100U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_r(u32 i) +{ + return 0x00418110U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_01_to_04_format_r(void) +{ + return 0x0041814cU; +} +static inline u32 gr_gpcs_swdx_dss_zbc_s_r(u32 i) +{ + return 0x0041815cU + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_s_val_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_s_01_to_04_format_r(void) +{ + return 0x00418198U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_r(void) +{ + return 0x00418810U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_align_bits_v(void) +{ + return 0x0000000cU; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_crstr_gpc_map_r(u32 i) +{ + return 0x00418b08U + i*4U; +} +static inline u32 gr_crstr_gpc_map_tile0_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_crstr_gpc_map_tile1_f(u32 v) +{ + return (v & 0x1fU) << 5U; +} +static inline u32 gr_crstr_gpc_map_tile2_f(u32 v) +{ + return (v & 0x1fU) << 10U; +} +static inline u32 gr_crstr_gpc_map_tile3_f(u32 v) +{ + return (v & 0x1fU) << 15U; +} +static inline u32 gr_crstr_gpc_map_tile4_f(u32 v) +{ + return (v & 0x1fU) << 20U; +} +static inline u32 gr_crstr_gpc_map_tile5_f(u32 v) +{ + return (v & 0x1fU) << 25U; +} +static inline u32 gr_crstr_map_table_cfg_r(void) +{ + return 0x00418bb8U; +} +static inline u32 gr_crstr_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_crstr_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_r(u32 i) +{ + return 0x00418980U + i*4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_1_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_2_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_3_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_4_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_5_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_6_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_7_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_r(void) +{ + return 0x00418c6cU; +} +static inline u32 gr_gpcs_gcc_pagepool_base_r(void) +{ + return 0x00419004U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_gcc_pagepool_r(void) +{ + return 0x00419008U; +} +static inline u32 gr_gpcs_gcc_pagepool_total_pages_f(u32 v) +{ + return (v & 0x3ffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_r(void) +{ + return 0x0041980cU; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_fast_mode_switch_true_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_r(void) +{ + return 0x00419848U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_r(void) +{ + return 0x00419c00U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_enabled_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_r(void) +{ + return 0x00419c2cU; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_sms_hww_warp_esr_report_mask_r(void) +{ + return 0x00419ea8U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_r(void) +{ + return 0x00504728U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_stack_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_api_stack_error_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_pc_wrap_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_misaligned_pc_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_pc_overflow_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_misaligned_reg_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_illegal_instr_encoding_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_illegal_instr_param_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_oor_reg_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_oor_addr_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_misaligned_addr_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_invalid_addr_space_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_invalid_const_addr_ldc_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_mmu_fault_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_stack_overflow_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_mmu_nack_report_f(void) +{ + return 0x4000000U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_r(void) +{ + return 0x00419d0cU; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_tex_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_mpc_enabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_mpc_enabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_r(void) +{ + return 0x0041ac94U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_gcc_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_tpc_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gcc_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_0_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_mpc_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_mpc_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_r(void) +{ + return 0x00504704U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_on_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_off_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_off_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_stop_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_single_step_mode_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_single_step_mode_enable_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_single_step_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_sm0_warp_valid_mask_0_r(void) +{ + return 0x00504708U; +} +static inline u32 gr_gpc0_tpc0_sm0_warp_valid_mask_1_r(void) +{ + return 0x0050470cU; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_bpt_pause_mask_0_r(void) +{ + return 0x00504710U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_bpt_pause_mask_1_r(void) +{ + return 0x00504714U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_bpt_trap_mask_0_r(void) +{ + return 0x00504718U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_bpt_trap_mask_1_r(void) +{ + return 0x0050471cU; +} +static inline u32 gr_gpcs_tpcs_sms_dbgr_bpt_pause_mask_0_r(void) +{ + return 0x00419e90U; +} +static inline u32 gr_gpcs_tpcs_sms_dbgr_bpt_pause_mask_1_r(void) +{ + return 0x00419e94U; +} +static inline u32 gr_gpcs_tpcs_sms_dbgr_status0_r(void) +{ + return 0x00419e80U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_status0_r(void) +{ + return 0x00504700U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_status0_sm_in_trap_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_status0_locked_down_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_status0_locked_down_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_r(void) +{ + return 0x00504730U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_none_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_none_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_stack_error_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_api_stack_error_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_pc_wrap_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_misaligned_pc_f(void) +{ + return 0x5U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_pc_overflow_f(void) +{ + return 0x6U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_misaligned_reg_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_illegal_instr_encoding_f(void) +{ + return 0x9U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_illegal_instr_param_f(void) +{ + return 0xbU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_oor_reg_f(void) +{ + return 0xdU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_oor_addr_f(void) +{ + return 0xeU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_misaligned_addr_f(void) +{ + return 0xfU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_invalid_addr_space_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_invalid_const_addr_ldc_f(void) +{ + return 0x12U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_stack_overflow_f(void) +{ + return 0x16U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_mmu_fault_f(void) +{ + return 0x17U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_tex_format_f(void) +{ + return 0x18U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_tex_layout_f(void) +{ + return 0x19U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_mmu_nack_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_wrap_id_m(void) +{ + return 0xffU << 16U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_addr_error_type_m(void) +{ + return 0xfU << 24U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_addr_error_type_none_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_tpc_esr_sm_sel_r(void) +{ + return 0x0050460cU; +} +static inline u32 gr_gpc0_tpc0_sm_tpc_esr_sm_sel_sm0_error_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_tpc_esr_sm_sel_sm1_error_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_pc_r(void) +{ + return 0x00504738U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_pc_hi_r(void) +{ + return 0x0050473cU; +} +static inline u32 gr_gpc0_tpc0_sm_halfctl_ctrl_r(void) +{ + return 0x005043a0U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_r(void) +{ + return 0x00419ba0U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_gpc0_tpc0_sm_debug_sfe_control_r(void) +{ + return 0x005043b0U; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_r(void) +{ + return 0x00419bb0U; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_r(void) +{ + return 0x0041be08U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_fast_mode_switch_true_f(void) +{ + return 0x4U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map_r(u32 i) +{ + return 0x0041bf00U + i*4U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_r(void) +{ + return 0x0041bfd0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_num_entries_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_shift_value_f(u32 v) +{ + return (v & 0x7U) << 21U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_r(void) +{ + return 0x0041bfd4U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff_r(u32 i) +{ + return 0x0041bfb0U + i*4U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff__size_1_v(void) +{ + return 0x00000005U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff_0_mod_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff_1_mod_value_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff_2_mod_value_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff_3_mod_value_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_bes_zrop_settings_r(void) +{ + return 0x00408850U; +} +static inline u32 gr_bes_zrop_settings_num_active_ltcs_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_be0_crop_debug3_r(void) +{ + return 0x00410108U; +} +static inline u32 gr_bes_crop_debug3_r(void) +{ + return 0x00408908U; +} +static inline u32 gr_bes_crop_debug3_comp_vdc_4to2_disable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_enabled_f(void) +{ + return 0x4U; +} +static inline u32 gr_bes_crop_debug4_r(void) +{ + return 0x0040894cU; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_m(void) +{ + return 0x1U << 18U; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_to_inf_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_to_maxval_f(void) +{ + return 0x40000U; +} +static inline u32 gr_bes_crop_settings_r(void) +{ + return 0x00408958U; +} +static inline u32 gr_bes_crop_settings_num_active_ltcs_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_zcull_bytes_per_aliquot_per_gpu_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_header_bytes_per_gpc_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_subregion_header_bytes_per_gpc_v(void) +{ + return 0x000000c0U; +} +static inline u32 gr_zcull_subregion_qty_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpcs_tpcs_tex_in_dbg_r(void) +{ + return 0x00419a00U; +} +static inline u32 gr_gpcs_tpcs_tex_in_dbg_tsl1_rvch_invalidate_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 gr_gpcs_tpcs_tex_in_dbg_tsl1_rvch_invalidate_m(void) +{ + return 0x1U << 19U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_r(void) +{ + return 0x00419bf0U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_cache_surface_ld_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_cache_surface_ld_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_cache_surface_st_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_cache_surface_st_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_always_cut_collector_m(void) +{ + return 0x1U << 28U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_always_cut_collector_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_always_cut_collector_enable_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_fe_pwr_mode_r(void) +{ + return 0x00404170U; +} +static inline u32 gr_fe_pwr_mode_mode_auto_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_pwr_mode_mode_force_on_f(void) +{ + return 0x2U; +} +static inline u32 gr_fe_pwr_mode_req_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_fe_pwr_mode_req_send_f(void) +{ + return 0x10U; +} +static inline u32 gr_fe_pwr_mode_req_done_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_r(void) +{ + return 0x00418880U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_vm_pg_size_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_use_pdb_big_page_size_m(void) +{ + return 0x1U << 11U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_vol_fault_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_comp_fault_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_miss_gran_m(void) +{ + return 0x3U << 3U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_cache_mode_m(void) +{ + return 0x3U << 5U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_aperture_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_vol_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_disable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_pri_mmu_pm_unit_mask_r(void) +{ + return 0x00418890U; +} +static inline u32 gr_gpcs_pri_mmu_pm_req_mask_r(void) +{ + return 0x00418894U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_r(void) +{ + return 0x004188b0U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_pri_mmu_debug_wr_r(void) +{ + return 0x004188b4U; +} +static inline u32 gr_gpcs_pri_mmu_debug_rd_r(void) +{ + return 0x004188b8U; +} +static inline u32 gr_gpcs_mmu_num_active_ltcs_r(void) +{ + return 0x004188acU; +} +static inline u32 gr_gpcs_tpcs_sms_dbgr_control0_r(void) +{ + return 0x00419e84U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_r(void) +{ + return 0x004041c0U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_count_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_count_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_r(void) +{ + return 0x00419bd8U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_m(void) +{ + return 0x7U << 8U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_arm_63_48_match_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_r(void) +{ + return 0x00419ba4U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_re_suppress_m(void) +{ + return 0x3U << 11U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_re_suppress_disable_f(void) +{ + return 0x1000U; +} +static inline u32 gr_gpcs_tc_debug0_r(void) +{ + return 0x00418708U; +} +static inline u32 gr_gpcs_tc_debug0_limit_coalesce_buffer_size_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 gr_gpcs_tc_debug0_limit_coalesce_buffer_size_m(void) +{ + return 0x1ffU << 0U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_ioctrl_gv100.h b/include/nvgpu/hw/gv100/hw_ioctrl_gv100.h new file mode 100644 index 0000000..c27e607 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_ioctrl_gv100.h @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ioctrl_gv100_h_ +#define _hw_ioctrl_gv100_h_ + +static inline u32 ioctrl_reset_r(void) +{ + return 0x00000140U; +} +static inline u32 ioctrl_reset_sw_post_reset_delay_microseconds_v(void) +{ + return 0x00000008U; +} +static inline u32 ioctrl_reset_linkreset_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 ioctrl_reset_linkreset_m(void) +{ + return 0x3fU << 8U; +} +static inline u32 ioctrl_reset_linkreset_v(u32 r) +{ + return (r >> 8U) & 0x3fU; +} +static inline u32 ioctrl_debug_reset_r(void) +{ + return 0x00000144U; +} +static inline u32 ioctrl_debug_reset_link_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 ioctrl_debug_reset_link_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 ioctrl_debug_reset_link_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 ioctrl_debug_reset_common_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 ioctrl_debug_reset_common_m(void) +{ + return 0x1U << 31U; +} +static inline u32 ioctrl_debug_reset_common_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 ioctrl_clock_control_r(u32 i) +{ + return 0x00000180U + i*4U; +} +static inline u32 ioctrl_clock_control__size_1_v(void) +{ + return 0x00000006U; +} +static inline u32 ioctrl_clock_control_clkdis_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ioctrl_clock_control_clkdis_m(void) +{ + return 0x1U << 0U; +} +static inline u32 ioctrl_clock_control_clkdis_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ioctrl_top_intr_0_status_r(void) +{ + return 0x00000200U; +} +static inline u32 ioctrl_top_intr_0_status_link_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 ioctrl_top_intr_0_status_link_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 ioctrl_top_intr_0_status_link_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 ioctrl_top_intr_0_status_common_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 ioctrl_top_intr_0_status_common_m(void) +{ + return 0x1U << 31U; +} +static inline u32 ioctrl_top_intr_0_status_common_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 ioctrl_common_intr_0_mask_r(void) +{ + return 0x00000220U; +} +static inline u32 ioctrl_common_intr_0_mask_fatal_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ioctrl_common_intr_0_mask_fatal_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ioctrl_common_intr_0_mask_nonfatal_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 ioctrl_common_intr_0_mask_nonfatal_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ioctrl_common_intr_0_mask_correctable_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 ioctrl_common_intr_0_mask_correctable_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 ioctrl_common_intr_0_mask_intra_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 ioctrl_common_intr_0_mask_intra_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 ioctrl_common_intr_0_mask_intrb_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ioctrl_common_intr_0_mask_intrb_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 ioctrl_common_intr_0_status_r(void) +{ + return 0x00000224U; +} +static inline u32 ioctrl_common_intr_0_status_fatal_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ioctrl_common_intr_0_status_fatal_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ioctrl_common_intr_0_status_nonfatal_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 ioctrl_common_intr_0_status_nonfatal_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ioctrl_common_intr_0_status_correctable_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 ioctrl_common_intr_0_status_correctable_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 ioctrl_common_intr_0_status_intra_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 ioctrl_common_intr_0_status_intra_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 ioctrl_common_intr_0_status_intrb_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ioctrl_common_intr_0_status_intrb_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 ioctrl_link_intr_0_mask_r(u32 i) +{ + return 0x00000240U + i*20U; +} +static inline u32 ioctrl_link_intr_0_mask_fatal_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ioctrl_link_intr_0_mask_fatal_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ioctrl_link_intr_0_mask_nonfatal_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 ioctrl_link_intr_0_mask_nonfatal_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ioctrl_link_intr_0_mask_correctable_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 ioctrl_link_intr_0_mask_correctable_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 ioctrl_link_intr_0_mask_intra_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 ioctrl_link_intr_0_mask_intra_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 ioctrl_link_intr_0_mask_intrb_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ioctrl_link_intr_0_mask_intrb_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 ioctrl_link_intr_0_status_r(u32 i) +{ + return 0x00000244U + i*20U; +} +static inline u32 ioctrl_link_intr_0_status_fatal_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ioctrl_link_intr_0_status_fatal_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ioctrl_link_intr_0_status_nonfatal_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 ioctrl_link_intr_0_status_nonfatal_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ioctrl_link_intr_0_status_correctable_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 ioctrl_link_intr_0_status_correctable_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 ioctrl_link_intr_0_status_intra_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 ioctrl_link_intr_0_status_intra_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 ioctrl_link_intr_0_status_intrb_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ioctrl_link_intr_0_status_intrb_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_ioctrlmif_gv100.h b/include/nvgpu/hw/gv100/hw_ioctrlmif_gv100.h new file mode 100644 index 0000000..5747a9b --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_ioctrlmif_gv100.h @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ioctrlmif_gv100_h_ +#define _hw_ioctrlmif_gv100_h_ + +static inline u32 ioctrlmif_rx_err_contain_en_0_r(void) +{ + return 0x00000e0cU; +} +static inline u32 ioctrlmif_rx_err_contain_en_0_rxramdataparityerr_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 ioctrlmif_rx_err_contain_en_0_rxramdataparityerr_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ioctrlmif_rx_err_contain_en_0_rxramdataparityerr_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 ioctrlmif_rx_err_contain_en_0_rxramdataparityerr__prod_v(void) +{ + return 0x00000001U; +} +static inline u32 ioctrlmif_rx_err_contain_en_0_rxramdataparityerr__prod_f(void) +{ + return 0x8U; +} +static inline u32 ioctrlmif_rx_err_contain_en_0_rxramhdrparityerr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ioctrlmif_rx_err_contain_en_0_rxramhdrparityerr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 ioctrlmif_rx_err_contain_en_0_rxramhdrparityerr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 ioctrlmif_rx_err_contain_en_0_rxramhdrparityerr__prod_v(void) +{ + return 0x00000001U; +} +static inline u32 ioctrlmif_rx_err_contain_en_0_rxramhdrparityerr__prod_f(void) +{ + return 0x10U; +} +static inline u32 ioctrlmif_rx_err_log_en_0_r(void) +{ + return 0x00000e04U; +} +static inline u32 ioctrlmif_rx_err_log_en_0_rxramdataparityerr_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 ioctrlmif_rx_err_log_en_0_rxramdataparityerr_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ioctrlmif_rx_err_log_en_0_rxramdataparityerr_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 ioctrlmif_rx_err_log_en_0_rxramhdrparityerr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ioctrlmif_rx_err_log_en_0_rxramhdrparityerr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 ioctrlmif_rx_err_log_en_0_rxramhdrparityerr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 ioctrlmif_rx_err_report_en_0_r(void) +{ + return 0x00000e08U; +} +static inline u32 ioctrlmif_rx_err_report_en_0_rxramdataparityerr_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 ioctrlmif_rx_err_report_en_0_rxramdataparityerr_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ioctrlmif_rx_err_report_en_0_rxramdataparityerr_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 ioctrlmif_rx_err_report_en_0_rxramhdrparityerr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ioctrlmif_rx_err_report_en_0_rxramhdrparityerr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 ioctrlmif_rx_err_report_en_0_rxramhdrparityerr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 ioctrlmif_rx_err_status_0_r(void) +{ + return 0x00000e00U; +} +static inline u32 ioctrlmif_rx_err_status_0_rxramdataparityerr_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 ioctrlmif_rx_err_status_0_rxramdataparityerr_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ioctrlmif_rx_err_status_0_rxramdataparityerr_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 ioctrlmif_rx_err_status_0_rxramhdrparityerr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ioctrlmif_rx_err_status_0_rxramhdrparityerr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 ioctrlmif_rx_err_status_0_rxramhdrparityerr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 ioctrlmif_rx_err_first_0_r(void) +{ + return 0x00000e14U; +} +static inline u32 ioctrlmif_tx_err_contain_en_0_r(void) +{ + return 0x00000a90U; +} +static inline u32 ioctrlmif_tx_err_contain_en_0_txramdataparityerr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ioctrlmif_tx_err_contain_en_0_txramdataparityerr_m(void) +{ + return 0x1U << 0U; +} +static inline u32 ioctrlmif_tx_err_contain_en_0_txramdataparityerr_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ioctrlmif_tx_err_contain_en_0_txramdataparityerr__prod_v(void) +{ + return 0x00000001U; +} +static inline u32 ioctrlmif_tx_err_contain_en_0_txramdataparityerr__prod_f(void) +{ + return 0x1U; +} +static inline u32 ioctrlmif_tx_err_contain_en_0_txramhdrparityerr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 ioctrlmif_tx_err_contain_en_0_txramhdrparityerr_m(void) +{ + return 0x1U << 1U; +} +static inline u32 ioctrlmif_tx_err_contain_en_0_txramhdrparityerr_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ioctrlmif_tx_err_contain_en_0_txramhdrparityerr__prod_v(void) +{ + return 0x00000001U; +} +static inline u32 ioctrlmif_tx_err_contain_en_0_txramhdrparityerr__prod_f(void) +{ + return 0x2U; +} +static inline u32 ioctrlmif_tx_err_log_en_0_r(void) +{ + return 0x00000a88U; +} +static inline u32 ioctrlmif_tx_err_log_en_0_txramdataparityerr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ioctrlmif_tx_err_log_en_0_txramdataparityerr_m(void) +{ + return 0x1U << 0U; +} +static inline u32 ioctrlmif_tx_err_log_en_0_txramdataparityerr_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ioctrlmif_tx_err_log_en_0_txramhdrparityerr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 ioctrlmif_tx_err_log_en_0_txramhdrparityerr_m(void) +{ + return 0x1U << 1U; +} +static inline u32 ioctrlmif_tx_err_log_en_0_txramhdrparityerr_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ioctrlmif_tx_err_report_en_0_r(void) +{ + return 0x00000e08U; +} +static inline u32 ioctrlmif_tx_err_report_en_0_txramdataparityerr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ioctrlmif_tx_err_report_en_0_txramdataparityerr_m(void) +{ + return 0x1U << 0U; +} +static inline u32 ioctrlmif_tx_err_report_en_0_txramdataparityerr_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ioctrlmif_tx_err_report_en_0_txramhdrparityerr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 ioctrlmif_tx_err_report_en_0_txramhdrparityerr_m(void) +{ + return 0x1U << 1U; +} +static inline u32 ioctrlmif_tx_err_report_en_0_txramhdrparityerr_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ioctrlmif_tx_err_status_0_r(void) +{ + return 0x00000a84U; +} +static inline u32 ioctrlmif_tx_err_status_0_txramdataparityerr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ioctrlmif_tx_err_status_0_txramdataparityerr_m(void) +{ + return 0x1U << 0U; +} +static inline u32 ioctrlmif_tx_err_status_0_txramdataparityerr_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ioctrlmif_tx_err_status_0_txramhdrparityerr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 ioctrlmif_tx_err_status_0_txramhdrparityerr_m(void) +{ + return 0x1U << 1U; +} +static inline u32 ioctrlmif_tx_err_status_0_txramhdrparityerr_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ioctrlmif_tx_err_first_0_r(void) +{ + return 0x00000a98U; +} +static inline u32 ioctrlmif_tx_ctrl_buffer_ready_r(void) +{ + return 0x00000a7cU; +} +static inline u32 ioctrlmif_rx_ctrl_buffer_ready_r(void) +{ + return 0x00000dfcU; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_ltc_gv100.h b/include/nvgpu/hw/gv100/hw_ltc_gv100.h new file mode 100644 index 0000000..042cb7d --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_ltc_gv100.h @@ -0,0 +1,631 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ltc_gv100_h_ +#define _hw_ltc_gv100_h_ + +static inline u32 ltc_pltcg_base_v(void) +{ + return 0x00140000U; +} +static inline u32 ltc_pltcg_extent_v(void) +{ + return 0x0017ffffU; +} +static inline u32 ltc_ltc0_ltss_v(void) +{ + return 0x00140200U; +} +static inline u32 ltc_ltc0_lts0_v(void) +{ + return 0x00140400U; +} +static inline u32 ltc_ltcs_ltss_v(void) +{ + return 0x0017e200U; +} +static inline u32 ltc_ltcs_lts0_cbc_ctrl1_r(void) +{ + return 0x0014046cU; +} +static inline u32 ltc_ltc0_lts0_dstg_cfg0_r(void) +{ + return 0x00140518U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_r(void) +{ + return 0x0017e318U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_vdc_4to2_disable_m(void) +{ + return 0x1U << 15U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_r(void) +{ + return 0x00140494U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_ways_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_v(u32 r) +{ + return (r >> 16U) & 0x3U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_all_v(void) +{ + return 0x00000000U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_half_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_quarter_v(void) +{ + return 0x00000002U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void) +{ + return 0x0017e26cU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(void) +{ + return 0x2U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_f(void) +{ + return 0x4U; +} +static inline u32 ltc_ltc0_lts0_cbc_ctrl1_r(void) +{ + return 0x0014046cU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_r(void) +{ + return 0x0017e270U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(u32 v) +{ + return (v & 0x3ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_r(void) +{ + return 0x0017e274U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(u32 v) +{ + return (v & 0x3ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_init_v(void) +{ + return 0x0003ffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_r(void) +{ + return 0x0017e278U; +} +static inline u32 ltc_ltcs_ltss_cbc_base_alignment_shift_v(void) +{ + return 0x0000000bU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_address_v(u32 r) +{ + return (r >> 0U) & 0x3ffffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_r(void) +{ + return 0x0017e27cU; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs__v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_nvlink_peer_through_l2_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_nvlink_peer_through_l2_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_serialize_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_serialize_v(u32 r) +{ + return (r >> 25U) & 0x1U; +} +static inline u32 ltc_ltcs_misc_ltc_num_active_ltcs_r(void) +{ + return 0x0017e000U; +} +static inline u32 ltc_ltcs_ltss_cbc_param_r(void) +{ + return 0x0017e280U; +} +static inline u32 ltc_ltcs_ltss_cbc_param_comptags_per_cache_line_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_cache_line_size_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_slices_per_ltc_v(u32 r) +{ + return (r >> 28U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_cbc_param2_r(void) +{ + return 0x0017e3f4U; +} +static inline u32 ltc_ltcs_ltss_cbc_param2_gobs_per_comptagline_per_slice_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_r(void) +{ + return 0x0017e2acU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_max_ways_evict_last_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_r(void) +{ + return 0x0017e338U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_address_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value_r(u32 i) +{ + return 0x0017e33cU + i*4U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_r(void) +{ + return 0x0017e34cU; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_s(void) +{ + return 32U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_stencil_clear_value_r(void) +{ + return 0x0017e204U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_stencil_clear_value_field_s(void) +{ + return 8U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_stencil_clear_value_field_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_stencil_clear_value_field_m(void) +{ + return 0xffU << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_stencil_clear_value_field_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_r(void) +{ + return 0x0017e2b0U; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_l2_bypass_mode_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_r(void) +{ + return 0x0017e214U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_r(void) +{ + return 0x00140214U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_r(void) +{ + return 0x00142214U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_intr_r(void) +{ + return 0x0017e20cU; +} +static inline u32 ltc_ltcs_ltss_intr_ecc_sec_error_pending_f(void) +{ + return 0x100U; +} +static inline u32 ltc_ltcs_ltss_intr_ecc_ded_error_pending_f(void) +{ + return 0x200U; +} +static inline u32 ltc_ltcs_ltss_intr_en_evicted_cb_m(void) +{ + return 0x1U << 20U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_m(void) +{ + return 0x1U << 21U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_disabled_f(void) +{ + return 0x0U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_access_m(void) +{ + return 0x1U << 30U; +} +static inline u32 ltc_ltcs_ltss_intr_en_ecc_sec_error_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 ltc_ltcs_ltss_intr_en_ecc_ded_error_enabled_f(void) +{ + return 0x2000000U; +} +static inline u32 ltc_ltc0_lts0_intr_r(void) +{ + return 0x0014040cU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_r(void) +{ + return 0x0014051cU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_sec_count_m(void) +{ + return 0xffU << 0U; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_sec_count_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_ded_count_m(void) +{ + return 0xffU << 16U; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_ded_count_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_r(void) +{ + return 0x0017e2a0U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_r(void) +{ + return 0x0017e2a4U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_f(void) +{ + return 0x10000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_r(void) +{ + return 0x001402a0U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_r(void) +{ + return 0x001402a4U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_r(void) +{ + return 0x001422a0U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_r(void) +{ + return 0x001422a4U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_r(void) +{ + return 0x0014058cU; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_slice_size_in_kb_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_slices_per_l2_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_mc_gv100.h b/include/nvgpu/hw/gv100/hw_mc_gv100.h new file mode 100644 index 0000000..cf406c3 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_mc_gv100.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_mc_gv100_h_ +#define _hw_mc_gv100_h_ + +static inline u32 mc_boot_0_r(void) +{ + return 0x00000000U; +} +static inline u32 mc_boot_0_architecture_v(u32 r) +{ + return (r >> 24U) & 0x1fU; +} +static inline u32 mc_boot_0_implementation_v(u32 r) +{ + return (r >> 20U) & 0xfU; +} +static inline u32 mc_boot_0_major_revision_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 mc_boot_0_minor_revision_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 mc_intr_r(u32 i) +{ + return 0x00000100U + i*4U; +} +static inline u32 mc_intr_pfifo_pending_f(void) +{ + return 0x100U; +} +static inline u32 mc_intr_hub_pending_f(void) +{ + return 0x200U; +} +static inline u32 mc_intr_pgraph_pending_f(void) +{ + return 0x1000U; +} +static inline u32 mc_intr_pmu_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_ltc_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 mc_intr_priv_ring_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 mc_intr_pbus_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_intr_nvlink_pending_f(void) +{ + return 0x400000U; +} +static inline u32 mc_intr_en_r(u32 i) +{ + return 0x00000140U + i*4U; +} +static inline u32 mc_intr_en_set_r(u32 i) +{ + return 0x00000160U + i*4U; +} +static inline u32 mc_intr_en_clear_r(u32 i) +{ + return 0x00000180U + i*4U; +} +static inline u32 mc_enable_r(void) +{ + return 0x00000200U; +} +static inline u32 mc_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_enable_l2_enabled_f(void) +{ + return 0x8U; +} +static inline u32 mc_enable_pmedia_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pmedia_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 mc_enable_pmedia_m(void) +{ + return 0x1U << 4U; +} +static inline u32 mc_enable_pmedia_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 mc_enable_ce0_m(void) +{ + return 0x1U << 6U; +} +static inline u32 mc_enable_pfifo_enabled_f(void) +{ + return 0x100U; +} +static inline u32 mc_enable_pgraph_enabled_f(void) +{ + return 0x1000U; +} +static inline u32 mc_enable_pwr_v(u32 r) +{ + return (r >> 13U) & 0x1U; +} +static inline u32 mc_enable_pwr_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 mc_enable_pwr_enabled_f(void) +{ + return 0x2000U; +} +static inline u32 mc_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_enable_ce2_m(void) +{ + return 0x1U << 21U; +} +static inline u32 mc_enable_ce2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 mc_enable_blg_enabled_f(void) +{ + return 0x8000000U; +} +static inline u32 mc_enable_perfmon_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +static inline u32 mc_enable_nvdec_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 mc_enable_nvdec_enabled_f(void) +{ + return 0x8000U; +} +static inline u32 mc_enable_nvlink_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 mc_enable_nvlink_disabled_f(void) +{ + return 0x0U; +} +static inline u32 mc_enable_nvlink_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 mc_enable_nvlink_enabled_f(void) +{ + return 0x2000000U; +} +static inline u32 mc_intr_ltc_r(void) +{ + return 0x000001c0U; +} +static inline u32 mc_enable_pb_r(void) +{ + return 0x00000204U; +} +static inline u32 mc_enable_pb_0_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pb_0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 mc_enable_pb_0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 mc_enable_pb_0_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 mc_enable_pb_0_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 mc_enable_pb_sel_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_minion_gv100.h b/include/nvgpu/hw/gv100/hw_minion_gv100.h new file mode 100644 index 0000000..e4bbf23 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_minion_gv100.h @@ -0,0 +1,943 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_minion_gv100_h_ +#define _hw_minion_gv100_h_ + +static inline u32 minion_minion_status_r(void) +{ + return 0x00000830U; +} +static inline u32 minion_minion_status_status_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 minion_minion_status_status_m(void) +{ + return 0xffU << 0U; +} +static inline u32 minion_minion_status_status_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 minion_minion_status_status_boot_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_minion_status_status_boot_f(void) +{ + return 0x1U; +} +static inline u32 minion_minion_status_intr_code_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 minion_minion_status_intr_code_m(void) +{ + return 0xffffffU << 8U; +} +static inline u32 minion_minion_status_intr_code_v(u32 r) +{ + return (r >> 8U) & 0xffffffU; +} +static inline u32 minion_falcon_irqstat_r(void) +{ + return 0x00000008U; +} +static inline u32 minion_falcon_irqstat_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 minion_falcon_irqstat_halt_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 minion_falcon_irqstat_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 minion_falcon_irqstat_exterr_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 minion_falcon_irqstat_exterr_true_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 minion_falcon_irqmask_r(void) +{ + return 0x00000018U; +} +static inline u32 minion_falcon_irqsclr_r(void) +{ + return 0x00000004U; +} +static inline u32 minion_falcon_irqsset_r(void) +{ + return 0x00000000U; +} +static inline u32 minion_falcon_irqmset_r(void) +{ + return 0x00000010U; +} +static inline u32 minion_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 minion_falcon_irqmset_wdtmr_m(void) +{ + return 0x1U << 1U; +} +static inline u32 minion_falcon_irqmset_wdtmr_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 minion_falcon_irqmset_wdtmr_set_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_falcon_irqmset_wdtmr_set_f(void) +{ + return 0x2U; +} +static inline u32 minion_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 minion_falcon_irqmset_halt_m(void) +{ + return 0x1U << 4U; +} +static inline u32 minion_falcon_irqmset_halt_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 minion_falcon_irqmset_halt_set_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_falcon_irqmset_halt_set_f(void) +{ + return 0x10U; +} +static inline u32 minion_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 minion_falcon_irqmset_exterr_m(void) +{ + return 0x1U << 5U; +} +static inline u32 minion_falcon_irqmset_exterr_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 minion_falcon_irqmset_exterr_set_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_falcon_irqmset_exterr_set_f(void) +{ + return 0x20U; +} +static inline u32 minion_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 minion_falcon_irqmset_swgen0_m(void) +{ + return 0x1U << 6U; +} +static inline u32 minion_falcon_irqmset_swgen0_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 minion_falcon_irqmset_swgen0_set_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_falcon_irqmset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 minion_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 minion_falcon_irqmset_swgen1_m(void) +{ + return 0x1U << 7U; +} +static inline u32 minion_falcon_irqmset_swgen1_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 minion_falcon_irqmset_swgen1_set_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_falcon_irqmset_swgen1_set_f(void) +{ + return 0x80U; +} +static inline u32 minion_falcon_irqdest_r(void) +{ + return 0x0000001cU; +} +static inline u32 minion_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 minion_falcon_irqdest_host_wdtmr_m(void) +{ + return 0x1U << 1U; +} +static inline u32 minion_falcon_irqdest_host_wdtmr_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 minion_falcon_irqdest_host_wdtmr_host_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_falcon_irqdest_host_wdtmr_host_f(void) +{ + return 0x2U; +} +static inline u32 minion_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 minion_falcon_irqdest_host_halt_m(void) +{ + return 0x1U << 4U; +} +static inline u32 minion_falcon_irqdest_host_halt_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 minion_falcon_irqdest_host_halt_host_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_falcon_irqdest_host_halt_host_f(void) +{ + return 0x10U; +} +static inline u32 minion_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 minion_falcon_irqdest_host_exterr_m(void) +{ + return 0x1U << 5U; +} +static inline u32 minion_falcon_irqdest_host_exterr_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 minion_falcon_irqdest_host_exterr_host_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_falcon_irqdest_host_exterr_host_f(void) +{ + return 0x20U; +} +static inline u32 minion_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 minion_falcon_irqdest_host_swgen0_m(void) +{ + return 0x1U << 6U; +} +static inline u32 minion_falcon_irqdest_host_swgen0_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 minion_falcon_irqdest_host_swgen0_host_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_falcon_irqdest_host_swgen0_host_f(void) +{ + return 0x40U; +} +static inline u32 minion_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 minion_falcon_irqdest_host_swgen1_m(void) +{ + return 0x1U << 7U; +} +static inline u32 minion_falcon_irqdest_host_swgen1_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 minion_falcon_irqdest_host_swgen1_host_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_falcon_irqdest_host_swgen1_host_f(void) +{ + return 0x80U; +} +static inline u32 minion_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 minion_falcon_irqdest_target_wdtmr_m(void) +{ + return 0x1U << 17U; +} +static inline u32 minion_falcon_irqdest_target_wdtmr_v(u32 r) +{ + return (r >> 17U) & 0x1U; +} +static inline u32 minion_falcon_irqdest_target_wdtmr_host_normal_v(void) +{ + return 0x00000000U; +} +static inline u32 minion_falcon_irqdest_target_wdtmr_host_normal_f(void) +{ + return 0x0U; +} +static inline u32 minion_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 minion_falcon_irqdest_target_halt_m(void) +{ + return 0x1U << 20U; +} +static inline u32 minion_falcon_irqdest_target_halt_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 minion_falcon_irqdest_target_halt_host_normal_v(void) +{ + return 0x00000000U; +} +static inline u32 minion_falcon_irqdest_target_halt_host_normal_f(void) +{ + return 0x0U; +} +static inline u32 minion_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 minion_falcon_irqdest_target_exterr_m(void) +{ + return 0x1U << 21U; +} +static inline u32 minion_falcon_irqdest_target_exterr_v(u32 r) +{ + return (r >> 21U) & 0x1U; +} +static inline u32 minion_falcon_irqdest_target_exterr_host_normal_v(void) +{ + return 0x00000000U; +} +static inline u32 minion_falcon_irqdest_target_exterr_host_normal_f(void) +{ + return 0x0U; +} +static inline u32 minion_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 minion_falcon_irqdest_target_swgen0_m(void) +{ + return 0x1U << 22U; +} +static inline u32 minion_falcon_irqdest_target_swgen0_v(u32 r) +{ + return (r >> 22U) & 0x1U; +} +static inline u32 minion_falcon_irqdest_target_swgen0_host_normal_v(void) +{ + return 0x00000000U; +} +static inline u32 minion_falcon_irqdest_target_swgen0_host_normal_f(void) +{ + return 0x0U; +} +static inline u32 minion_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 minion_falcon_irqdest_target_swgen1_m(void) +{ + return 0x1U << 23U; +} +static inline u32 minion_falcon_irqdest_target_swgen1_v(u32 r) +{ + return (r >> 23U) & 0x1U; +} +static inline u32 minion_falcon_irqdest_target_swgen1_host_normal_v(void) +{ + return 0x00000000U; +} +static inline u32 minion_falcon_irqdest_target_swgen1_host_normal_f(void) +{ + return 0x0U; +} +static inline u32 minion_falcon_os_r(void) +{ + return 0x00000080U; +} +static inline u32 minion_falcon_mailbox1_r(void) +{ + return 0x00000044U; +} +static inline u32 minion_minion_intr_r(void) +{ + return 0x00000810U; +} +static inline u32 minion_minion_intr_fatal_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 minion_minion_intr_fatal_m(void) +{ + return 0x1U << 0U; +} +static inline u32 minion_minion_intr_fatal_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 minion_minion_intr_nonfatal_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 minion_minion_intr_nonfatal_m(void) +{ + return 0x1U << 1U; +} +static inline u32 minion_minion_intr_nonfatal_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 minion_minion_intr_falcon_stall_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 minion_minion_intr_falcon_stall_m(void) +{ + return 0x1U << 2U; +} +static inline u32 minion_minion_intr_falcon_stall_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 minion_minion_intr_falcon_nostall_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 minion_minion_intr_falcon_nostall_m(void) +{ + return 0x1U << 3U; +} +static inline u32 minion_minion_intr_falcon_nostall_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 minion_minion_intr_link_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 minion_minion_intr_link_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 minion_minion_intr_link_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 minion_minion_intr_nonstall_en_r(void) +{ + return 0x0000081cU; +} +static inline u32 minion_minion_intr_stall_en_r(void) +{ + return 0x00000818U; +} +static inline u32 minion_minion_intr_stall_en_fatal_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 minion_minion_intr_stall_en_fatal_m(void) +{ + return 0x1U << 0U; +} +static inline u32 minion_minion_intr_stall_en_fatal_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 minion_minion_intr_stall_en_fatal_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_minion_intr_stall_en_fatal_enable_f(void) +{ + return 0x1U; +} +static inline u32 minion_minion_intr_stall_en_fatal_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 minion_minion_intr_stall_en_fatal_disable_f(void) +{ + return 0x0U; +} +static inline u32 minion_minion_intr_stall_en_nonfatal_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 minion_minion_intr_stall_en_nonfatal_m(void) +{ + return 0x1U << 1U; +} +static inline u32 minion_minion_intr_stall_en_nonfatal_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 minion_minion_intr_stall_en_nonfatal_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_minion_intr_stall_en_nonfatal_enable_f(void) +{ + return 0x2U; +} +static inline u32 minion_minion_intr_stall_en_nonfatal_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 minion_minion_intr_stall_en_nonfatal_disable_f(void) +{ + return 0x0U; +} +static inline u32 minion_minion_intr_stall_en_falcon_stall_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 minion_minion_intr_stall_en_falcon_stall_m(void) +{ + return 0x1U << 2U; +} +static inline u32 minion_minion_intr_stall_en_falcon_stall_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 minion_minion_intr_stall_en_falcon_stall_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_minion_intr_stall_en_falcon_stall_enable_f(void) +{ + return 0x4U; +} +static inline u32 minion_minion_intr_stall_en_falcon_stall_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 minion_minion_intr_stall_en_falcon_stall_disable_f(void) +{ + return 0x0U; +} +static inline u32 minion_minion_intr_stall_en_falcon_nostall_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 minion_minion_intr_stall_en_falcon_nostall_m(void) +{ + return 0x1U << 3U; +} +static inline u32 minion_minion_intr_stall_en_falcon_nostall_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 minion_minion_intr_stall_en_falcon_nostall_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_minion_intr_stall_en_falcon_nostall_enable_f(void) +{ + return 0x8U; +} +static inline u32 minion_minion_intr_stall_en_falcon_nostall_disable_v(void) +{ + return 0x00000000U; +} +static inline u32 minion_minion_intr_stall_en_falcon_nostall_disable_f(void) +{ + return 0x0U; +} +static inline u32 minion_minion_intr_stall_en_link_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 minion_minion_intr_stall_en_link_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 minion_minion_intr_stall_en_link_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 minion_nvlink_dl_cmd_r(u32 i) +{ + return 0x00000900U + i*4U; +} +static inline u32 minion_nvlink_dl_cmd___size_1_v(void) +{ + return 0x00000006U; +} +static inline u32 minion_nvlink_dl_cmd_command_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 minion_nvlink_dl_cmd_command_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 minion_nvlink_dl_cmd_command_configeom_v(void) +{ + return 0x00000040U; +} +static inline u32 minion_nvlink_dl_cmd_command_configeom_f(void) +{ + return 0x40U; +} +static inline u32 minion_nvlink_dl_cmd_command_nop_v(void) +{ + return 0x00000000U; +} +static inline u32 minion_nvlink_dl_cmd_command_nop_f(void) +{ + return 0x0U; +} +static inline u32 minion_nvlink_dl_cmd_command_initphy_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_nvlink_dl_cmd_command_initphy_f(void) +{ + return 0x1U; +} +static inline u32 minion_nvlink_dl_cmd_command_initlaneenable_v(void) +{ + return 0x00000003U; +} +static inline u32 minion_nvlink_dl_cmd_command_initlaneenable_f(void) +{ + return 0x3U; +} +static inline u32 minion_nvlink_dl_cmd_command_initdlpl_v(void) +{ + return 0x00000004U; +} +static inline u32 minion_nvlink_dl_cmd_command_initdlpl_f(void) +{ + return 0x4U; +} +static inline u32 minion_nvlink_dl_cmd_command_lanedisable_v(void) +{ + return 0x00000008U; +} +static inline u32 minion_nvlink_dl_cmd_command_lanedisable_f(void) +{ + return 0x8U; +} +static inline u32 minion_nvlink_dl_cmd_command_fastlanedisable_v(void) +{ + return 0x00000009U; +} +static inline u32 minion_nvlink_dl_cmd_command_fastlanedisable_f(void) +{ + return 0x9U; +} +static inline u32 minion_nvlink_dl_cmd_command_laneshutdown_v(void) +{ + return 0x0000000cU; +} +static inline u32 minion_nvlink_dl_cmd_command_laneshutdown_f(void) +{ + return 0xcU; +} +static inline u32 minion_nvlink_dl_cmd_command_setacmode_v(void) +{ + return 0x0000000aU; +} +static inline u32 minion_nvlink_dl_cmd_command_setacmode_f(void) +{ + return 0xaU; +} +static inline u32 minion_nvlink_dl_cmd_command_clracmode_v(void) +{ + return 0x0000000bU; +} +static inline u32 minion_nvlink_dl_cmd_command_clracmode_f(void) +{ + return 0xbU; +} +static inline u32 minion_nvlink_dl_cmd_command_enablepm_v(void) +{ + return 0x00000010U; +} +static inline u32 minion_nvlink_dl_cmd_command_enablepm_f(void) +{ + return 0x10U; +} +static inline u32 minion_nvlink_dl_cmd_command_disablepm_v(void) +{ + return 0x00000011U; +} +static inline u32 minion_nvlink_dl_cmd_command_disablepm_f(void) +{ + return 0x11U; +} +static inline u32 minion_nvlink_dl_cmd_command_savestate_v(void) +{ + return 0x00000018U; +} +static inline u32 minion_nvlink_dl_cmd_command_savestate_f(void) +{ + return 0x18U; +} +static inline u32 minion_nvlink_dl_cmd_command_restorestate_v(void) +{ + return 0x00000019U; +} +static inline u32 minion_nvlink_dl_cmd_command_restorestate_f(void) +{ + return 0x19U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_0_v(void) +{ + return 0x00000020U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_0_f(void) +{ + return 0x20U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_1_v(void) +{ + return 0x00000021U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_1_f(void) +{ + return 0x21U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_2_v(void) +{ + return 0x00000022U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_2_f(void) +{ + return 0x22U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_3_v(void) +{ + return 0x00000023U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_3_f(void) +{ + return 0x23U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_4_v(void) +{ + return 0x00000024U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_4_f(void) +{ + return 0x24U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_5_v(void) +{ + return 0x00000025U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_5_f(void) +{ + return 0x25U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_6_v(void) +{ + return 0x00000026U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_6_f(void) +{ + return 0x26U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_7_v(void) +{ + return 0x00000027U; +} +static inline u32 minion_nvlink_dl_cmd_command_initpll_7_f(void) +{ + return 0x27U; +} +static inline u32 minion_nvlink_dl_cmd_fault_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 minion_nvlink_dl_cmd_fault_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 minion_nvlink_dl_cmd_ready_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 minion_nvlink_dl_cmd_ready_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 minion_misc_0_r(void) +{ + return 0x000008b0U; +} +static inline u32 minion_misc_0_scratch_swrw_0_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 minion_misc_0_scratch_swrw_0_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 minion_nvlink_link_intr_r(u32 i) +{ + return 0x00000a00U + i*4U; +} +static inline u32 minion_nvlink_link_intr___size_1_v(void) +{ + return 0x00000006U; +} +static inline u32 minion_nvlink_link_intr_code_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 minion_nvlink_link_intr_code_m(void) +{ + return 0xffU << 0U; +} +static inline u32 minion_nvlink_link_intr_code_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 minion_nvlink_link_intr_code_na_v(void) +{ + return 0x00000000U; +} +static inline u32 minion_nvlink_link_intr_code_na_f(void) +{ + return 0x0U; +} +static inline u32 minion_nvlink_link_intr_code_swreq_v(void) +{ + return 0x00000001U; +} +static inline u32 minion_nvlink_link_intr_code_swreq_f(void) +{ + return 0x1U; +} +static inline u32 minion_nvlink_link_intr_code_dlreq_v(void) +{ + return 0x00000002U; +} +static inline u32 minion_nvlink_link_intr_code_dlreq_f(void) +{ + return 0x2U; +} +static inline u32 minion_nvlink_link_intr_code_pmdisabled_v(void) +{ + return 0x00000003U; +} +static inline u32 minion_nvlink_link_intr_code_pmdisabled_f(void) +{ + return 0x3U; +} +static inline u32 minion_nvlink_link_intr_subcode_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 minion_nvlink_link_intr_subcode_m(void) +{ + return 0xffU << 8U; +} +static inline u32 minion_nvlink_link_intr_subcode_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 minion_nvlink_link_intr_state_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 minion_nvlink_link_intr_state_m(void) +{ + return 0x1U << 31U; +} +static inline u32 minion_nvlink_link_intr_state_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_nvl_gv100.h b/include/nvgpu/hw/gv100/hw_nvl_gv100.h new file mode 100644 index 0000000..2e4ec16 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_nvl_gv100.h @@ -0,0 +1,1571 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_nvl_gv100_h_ +#define _hw_nvl_gv100_h_ + +static inline u32 nvl_link_state_r(void) +{ + return 0x00000000U; +} +static inline u32 nvl_link_state_state_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 nvl_link_state_state_m(void) +{ + return 0xffU << 0U; +} +static inline u32 nvl_link_state_state_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 nvl_link_state_state_init_v(void) +{ + return 0x00000000U; +} +static inline u32 nvl_link_state_state_init_f(void) +{ + return 0x0U; +} +static inline u32 nvl_link_state_state_hwcfg_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_link_state_state_hwcfg_f(void) +{ + return 0x1U; +} +static inline u32 nvl_link_state_state_swcfg_v(void) +{ + return 0x00000002U; +} +static inline u32 nvl_link_state_state_swcfg_f(void) +{ + return 0x2U; +} +static inline u32 nvl_link_state_state_active_v(void) +{ + return 0x00000003U; +} +static inline u32 nvl_link_state_state_active_f(void) +{ + return 0x3U; +} +static inline u32 nvl_link_state_state_fault_v(void) +{ + return 0x00000004U; +} +static inline u32 nvl_link_state_state_fault_f(void) +{ + return 0x4U; +} +static inline u32 nvl_link_state_state_rcvy_ac_v(void) +{ + return 0x00000008U; +} +static inline u32 nvl_link_state_state_rcvy_ac_f(void) +{ + return 0x8U; +} +static inline u32 nvl_link_state_state_rcvy_sw_v(void) +{ + return 0x00000009U; +} +static inline u32 nvl_link_state_state_rcvy_sw_f(void) +{ + return 0x9U; +} +static inline u32 nvl_link_state_state_rcvy_rx_v(void) +{ + return 0x0000000aU; +} +static inline u32 nvl_link_state_state_rcvy_rx_f(void) +{ + return 0xaU; +} +static inline u32 nvl_link_state_an0_busy_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 nvl_link_state_an0_busy_m(void) +{ + return 0x1U << 12U; +} +static inline u32 nvl_link_state_an0_busy_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 nvl_link_state_tl_busy_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 nvl_link_state_tl_busy_m(void) +{ + return 0x1U << 13U; +} +static inline u32 nvl_link_state_tl_busy_v(u32 r) +{ + return (r >> 13U) & 0x1U; +} +static inline u32 nvl_link_state_dbg_substate_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 nvl_link_state_dbg_substate_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 nvl_link_state_dbg_substate_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 nvl_link_activity_r(void) +{ + return 0x0000000cU; +} +static inline u32 nvl_link_activity_blkact_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 nvl_link_activity_blkact_m(void) +{ + return 0x7U << 0U; +} +static inline u32 nvl_link_activity_blkact_v(u32 r) +{ + return (r >> 0U) & 0x7U; +} +static inline u32 nvl_sublink_activity_r(u32 i) +{ + return 0x00000010U + i*4U; +} +static inline u32 nvl_sublink_activity_blkact0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 nvl_sublink_activity_blkact0_m(void) +{ + return 0x7U << 0U; +} +static inline u32 nvl_sublink_activity_blkact0_v(u32 r) +{ + return (r >> 0U) & 0x7U; +} +static inline u32 nvl_sublink_activity_blkact1_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 nvl_sublink_activity_blkact1_m(void) +{ + return 0x7U << 8U; +} +static inline u32 nvl_sublink_activity_blkact1_v(u32 r) +{ + return (r >> 8U) & 0x7U; +} +static inline u32 nvl_link_config_r(void) +{ + return 0x00000018U; +} +static inline u32 nvl_link_config_ac_safe_en_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 nvl_link_config_ac_safe_en_m(void) +{ + return 0x1U << 30U; +} +static inline u32 nvl_link_config_ac_safe_en_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 nvl_link_config_ac_safe_en_on_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_link_config_ac_safe_en_on_f(void) +{ + return 0x40000000U; +} +static inline u32 nvl_link_config_link_en_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 nvl_link_config_link_en_m(void) +{ + return 0x1U << 31U; +} +static inline u32 nvl_link_config_link_en_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 nvl_link_config_link_en_on_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_link_config_link_en_on_f(void) +{ + return 0x80000000U; +} +static inline u32 nvl_link_change_r(void) +{ + return 0x00000040U; +} +static inline u32 nvl_link_change_oldstate_mask_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 nvl_link_change_oldstate_mask_m(void) +{ + return 0xfU << 16U; +} +static inline u32 nvl_link_change_oldstate_mask_v(u32 r) +{ + return (r >> 16U) & 0xfU; +} +static inline u32 nvl_link_change_oldstate_mask_dontcare_v(void) +{ + return 0x0000000fU; +} +static inline u32 nvl_link_change_oldstate_mask_dontcare_f(void) +{ + return 0xf0000U; +} +static inline u32 nvl_link_change_newstate_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 nvl_link_change_newstate_m(void) +{ + return 0xfU << 4U; +} +static inline u32 nvl_link_change_newstate_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 nvl_link_change_newstate_hwcfg_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_link_change_newstate_hwcfg_f(void) +{ + return 0x10U; +} +static inline u32 nvl_link_change_newstate_swcfg_v(void) +{ + return 0x00000002U; +} +static inline u32 nvl_link_change_newstate_swcfg_f(void) +{ + return 0x20U; +} +static inline u32 nvl_link_change_newstate_active_v(void) +{ + return 0x00000003U; +} +static inline u32 nvl_link_change_newstate_active_f(void) +{ + return 0x30U; +} +static inline u32 nvl_link_change_action_f(u32 v) +{ + return (v & 0x3U) << 2U; +} +static inline u32 nvl_link_change_action_m(void) +{ + return 0x3U << 2U; +} +static inline u32 nvl_link_change_action_v(u32 r) +{ + return (r >> 2U) & 0x3U; +} +static inline u32 nvl_link_change_action_ltssm_change_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_link_change_action_ltssm_change_f(void) +{ + return 0x4U; +} +static inline u32 nvl_link_change_status_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 nvl_link_change_status_m(void) +{ + return 0x3U << 0U; +} +static inline u32 nvl_link_change_status_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 nvl_link_change_status_done_v(void) +{ + return 0x00000000U; +} +static inline u32 nvl_link_change_status_done_f(void) +{ + return 0x0U; +} +static inline u32 nvl_link_change_status_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_link_change_status_busy_f(void) +{ + return 0x1U; +} +static inline u32 nvl_link_change_status_fault_v(void) +{ + return 0x00000002U; +} +static inline u32 nvl_link_change_status_fault_f(void) +{ + return 0x2U; +} +static inline u32 nvl_sublink_change_r(void) +{ + return 0x00000044U; +} +static inline u32 nvl_sublink_change_countdown_f(u32 v) +{ + return (v & 0xfffU) << 20U; +} +static inline u32 nvl_sublink_change_countdown_m(void) +{ + return 0xfffU << 20U; +} +static inline u32 nvl_sublink_change_countdown_v(u32 r) +{ + return (r >> 20U) & 0xfffU; +} +static inline u32 nvl_sublink_change_oldstate_mask_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 nvl_sublink_change_oldstate_mask_m(void) +{ + return 0xfU << 16U; +} +static inline u32 nvl_sublink_change_oldstate_mask_v(u32 r) +{ + return (r >> 16U) & 0xfU; +} +static inline u32 nvl_sublink_change_oldstate_mask_dontcare_v(void) +{ + return 0x0000000fU; +} +static inline u32 nvl_sublink_change_oldstate_mask_dontcare_f(void) +{ + return 0xf0000U; +} +static inline u32 nvl_sublink_change_sublink_f(u32 v) +{ + return (v & 0xfU) << 12U; +} +static inline u32 nvl_sublink_change_sublink_m(void) +{ + return 0xfU << 12U; +} +static inline u32 nvl_sublink_change_sublink_v(u32 r) +{ + return (r >> 12U) & 0xfU; +} +static inline u32 nvl_sublink_change_sublink_tx_v(void) +{ + return 0x00000000U; +} +static inline u32 nvl_sublink_change_sublink_tx_f(void) +{ + return 0x0U; +} +static inline u32 nvl_sublink_change_sublink_rx_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_sublink_change_sublink_rx_f(void) +{ + return 0x1000U; +} +static inline u32 nvl_sublink_change_newstate_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 nvl_sublink_change_newstate_m(void) +{ + return 0xfU << 4U; +} +static inline u32 nvl_sublink_change_newstate_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 nvl_sublink_change_newstate_hs_v(void) +{ + return 0x00000000U; +} +static inline u32 nvl_sublink_change_newstate_hs_f(void) +{ + return 0x0U; +} +static inline u32 nvl_sublink_change_newstate_eighth_v(void) +{ + return 0x00000004U; +} +static inline u32 nvl_sublink_change_newstate_eighth_f(void) +{ + return 0x40U; +} +static inline u32 nvl_sublink_change_newstate_train_v(void) +{ + return 0x00000005U; +} +static inline u32 nvl_sublink_change_newstate_train_f(void) +{ + return 0x50U; +} +static inline u32 nvl_sublink_change_newstate_safe_v(void) +{ + return 0x00000006U; +} +static inline u32 nvl_sublink_change_newstate_safe_f(void) +{ + return 0x60U; +} +static inline u32 nvl_sublink_change_newstate_off_v(void) +{ + return 0x00000007U; +} +static inline u32 nvl_sublink_change_newstate_off_f(void) +{ + return 0x70U; +} +static inline u32 nvl_sublink_change_action_f(u32 v) +{ + return (v & 0x3U) << 2U; +} +static inline u32 nvl_sublink_change_action_m(void) +{ + return 0x3U << 2U; +} +static inline u32 nvl_sublink_change_action_v(u32 r) +{ + return (r >> 2U) & 0x3U; +} +static inline u32 nvl_sublink_change_action_slsm_change_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_sublink_change_action_slsm_change_f(void) +{ + return 0x4U; +} +static inline u32 nvl_sublink_change_status_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 nvl_sublink_change_status_m(void) +{ + return 0x3U << 0U; +} +static inline u32 nvl_sublink_change_status_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 nvl_sublink_change_status_done_v(void) +{ + return 0x00000000U; +} +static inline u32 nvl_sublink_change_status_done_f(void) +{ + return 0x0U; +} +static inline u32 nvl_sublink_change_status_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_sublink_change_status_busy_f(void) +{ + return 0x1U; +} +static inline u32 nvl_sublink_change_status_fault_v(void) +{ + return 0x00000002U; +} +static inline u32 nvl_sublink_change_status_fault_f(void) +{ + return 0x2U; +} +static inline u32 nvl_link_test_r(void) +{ + return 0x00000048U; +} +static inline u32 nvl_link_test_mode_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 nvl_link_test_mode_m(void) +{ + return 0x1U << 0U; +} +static inline u32 nvl_link_test_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 nvl_link_test_mode_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_link_test_mode_enable_f(void) +{ + return 0x1U; +} +static inline u32 nvl_link_test_auto_hwcfg_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 nvl_link_test_auto_hwcfg_m(void) +{ + return 0x1U << 30U; +} +static inline u32 nvl_link_test_auto_hwcfg_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 nvl_link_test_auto_hwcfg_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_link_test_auto_hwcfg_enable_f(void) +{ + return 0x40000000U; +} +static inline u32 nvl_link_test_auto_nvhs_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 nvl_link_test_auto_nvhs_m(void) +{ + return 0x1U << 31U; +} +static inline u32 nvl_link_test_auto_nvhs_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 nvl_link_test_auto_nvhs_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_link_test_auto_nvhs_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 nvl_sl0_slsm_status_tx_r(void) +{ + return 0x00002024U; +} +static inline u32 nvl_sl0_slsm_status_tx_substate_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 nvl_sl0_slsm_status_tx_substate_m(void) +{ + return 0xfU << 0U; +} +static inline u32 nvl_sl0_slsm_status_tx_substate_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_m(void) +{ + return 0xfU << 4U; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_hs_v(void) +{ + return 0x00000000U; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_hs_f(void) +{ + return 0x0U; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_eighth_v(void) +{ + return 0x00000004U; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_eighth_f(void) +{ + return 0x40U; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_train_v(void) +{ + return 0x00000005U; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_train_f(void) +{ + return 0x50U; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_off_v(void) +{ + return 0x00000007U; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_off_f(void) +{ + return 0x70U; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_safe_v(void) +{ + return 0x00000006U; +} +static inline u32 nvl_sl0_slsm_status_tx_primary_state_safe_f(void) +{ + return 0x60U; +} +static inline u32 nvl_sl1_slsm_status_rx_r(void) +{ + return 0x00003014U; +} +static inline u32 nvl_sl1_slsm_status_rx_substate_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 nvl_sl1_slsm_status_rx_substate_m(void) +{ + return 0xfU << 0U; +} +static inline u32 nvl_sl1_slsm_status_rx_substate_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_m(void) +{ + return 0xfU << 4U; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_hs_v(void) +{ + return 0x00000000U; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_hs_f(void) +{ + return 0x0U; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_eighth_v(void) +{ + return 0x00000004U; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_eighth_f(void) +{ + return 0x40U; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_train_v(void) +{ + return 0x00000005U; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_train_f(void) +{ + return 0x50U; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_off_v(void) +{ + return 0x00000007U; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_off_f(void) +{ + return 0x70U; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_safe_v(void) +{ + return 0x00000006U; +} +static inline u32 nvl_sl1_slsm_status_rx_primary_state_safe_f(void) +{ + return 0x60U; +} +static inline u32 nvl_sl0_safe_ctrl2_tx_r(void) +{ + return 0x00002008U; +} +static inline u32 nvl_sl0_safe_ctrl2_tx_ctr_init_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 nvl_sl0_safe_ctrl2_tx_ctr_init_m(void) +{ + return 0x7ffU << 0U; +} +static inline u32 nvl_sl0_safe_ctrl2_tx_ctr_init_v(u32 r) +{ + return (r >> 0U) & 0x7ffU; +} +static inline u32 nvl_sl0_safe_ctrl2_tx_ctr_init_init_v(void) +{ + return 0x00000728U; +} +static inline u32 nvl_sl0_safe_ctrl2_tx_ctr_init_init_f(void) +{ + return 0x728U; +} +static inline u32 nvl_sl0_safe_ctrl2_tx_ctr_initscl_f(u32 v) +{ + return (v & 0x1fU) << 11U; +} +static inline u32 nvl_sl0_safe_ctrl2_tx_ctr_initscl_m(void) +{ + return 0x1fU << 11U; +} +static inline u32 nvl_sl0_safe_ctrl2_tx_ctr_initscl_v(u32 r) +{ + return (r >> 11U) & 0x1fU; +} +static inline u32 nvl_sl0_safe_ctrl2_tx_ctr_initscl_init_v(void) +{ + return 0x0000000fU; +} +static inline u32 nvl_sl0_safe_ctrl2_tx_ctr_initscl_init_f(void) +{ + return 0x7800U; +} +static inline u32 nvl_sl1_error_rate_ctrl_r(void) +{ + return 0x00003284U; +} +static inline u32 nvl_sl1_error_rate_ctrl_short_threshold_man_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 nvl_sl1_error_rate_ctrl_short_threshold_man_m(void) +{ + return 0x7U << 0U; +} +static inline u32 nvl_sl1_error_rate_ctrl_short_threshold_man_v(u32 r) +{ + return (r >> 0U) & 0x7U; +} +static inline u32 nvl_sl1_error_rate_ctrl_long_threshold_man_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 nvl_sl1_error_rate_ctrl_long_threshold_man_m(void) +{ + return 0x7U << 16U; +} +static inline u32 nvl_sl1_error_rate_ctrl_long_threshold_man_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 nvl_sl1_rxslsm_timeout_2_r(void) +{ + return 0x00003034U; +} +static inline u32 nvl_txiobist_configreg_r(void) +{ + return 0x00002e14U; +} +static inline u32 nvl_txiobist_configreg_io_bist_mode_in_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 nvl_txiobist_configreg_io_bist_mode_in_m(void) +{ + return 0x1U << 17U; +} +static inline u32 nvl_txiobist_configreg_io_bist_mode_in_v(u32 r) +{ + return (r >> 17U) & 0x1U; +} +static inline u32 nvl_txiobist_config_r(void) +{ + return 0x00002e10U; +} +static inline u32 nvl_txiobist_config_dpg_prbsseedld_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 nvl_txiobist_config_dpg_prbsseedld_m(void) +{ + return 0x1U << 2U; +} +static inline u32 nvl_txiobist_config_dpg_prbsseedld_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 nvl_intr_r(void) +{ + return 0x00000050U; +} +static inline u32 nvl_intr_tx_replay_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 nvl_intr_tx_replay_m(void) +{ + return 0x1U << 0U; +} +static inline u32 nvl_intr_tx_replay_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 nvl_intr_tx_recovery_short_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 nvl_intr_tx_recovery_short_m(void) +{ + return 0x1U << 1U; +} +static inline u32 nvl_intr_tx_recovery_short_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 nvl_intr_tx_recovery_long_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 nvl_intr_tx_recovery_long_m(void) +{ + return 0x1U << 2U; +} +static inline u32 nvl_intr_tx_recovery_long_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 nvl_intr_tx_fault_ram_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 nvl_intr_tx_fault_ram_m(void) +{ + return 0x1U << 4U; +} +static inline u32 nvl_intr_tx_fault_ram_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 nvl_intr_tx_fault_interface_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 nvl_intr_tx_fault_interface_m(void) +{ + return 0x1U << 5U; +} +static inline u32 nvl_intr_tx_fault_interface_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 nvl_intr_tx_fault_sublink_change_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 nvl_intr_tx_fault_sublink_change_m(void) +{ + return 0x1U << 8U; +} +static inline u32 nvl_intr_tx_fault_sublink_change_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 nvl_intr_rx_fault_sublink_change_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 nvl_intr_rx_fault_sublink_change_m(void) +{ + return 0x1U << 16U; +} +static inline u32 nvl_intr_rx_fault_sublink_change_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 nvl_intr_rx_fault_dl_protocol_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 nvl_intr_rx_fault_dl_protocol_m(void) +{ + return 0x1U << 20U; +} +static inline u32 nvl_intr_rx_fault_dl_protocol_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 nvl_intr_rx_short_error_rate_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 nvl_intr_rx_short_error_rate_m(void) +{ + return 0x1U << 21U; +} +static inline u32 nvl_intr_rx_short_error_rate_v(u32 r) +{ + return (r >> 21U) & 0x1U; +} +static inline u32 nvl_intr_rx_long_error_rate_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 nvl_intr_rx_long_error_rate_m(void) +{ + return 0x1U << 22U; +} +static inline u32 nvl_intr_rx_long_error_rate_v(u32 r) +{ + return (r >> 22U) & 0x1U; +} +static inline u32 nvl_intr_rx_ila_trigger_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 nvl_intr_rx_ila_trigger_m(void) +{ + return 0x1U << 23U; +} +static inline u32 nvl_intr_rx_ila_trigger_v(u32 r) +{ + return (r >> 23U) & 0x1U; +} +static inline u32 nvl_intr_rx_crc_counter_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 nvl_intr_rx_crc_counter_m(void) +{ + return 0x1U << 24U; +} +static inline u32 nvl_intr_rx_crc_counter_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 nvl_intr_ltssm_fault_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 nvl_intr_ltssm_fault_m(void) +{ + return 0x1U << 28U; +} +static inline u32 nvl_intr_ltssm_fault_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 nvl_intr_ltssm_protocol_f(u32 v) +{ + return (v & 0x1U) << 29U; +} +static inline u32 nvl_intr_ltssm_protocol_m(void) +{ + return 0x1U << 29U; +} +static inline u32 nvl_intr_ltssm_protocol_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 nvl_intr_minion_request_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 nvl_intr_minion_request_m(void) +{ + return 0x1U << 30U; +} +static inline u32 nvl_intr_minion_request_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 nvl_intr_sw2_r(void) +{ + return 0x00000054U; +} +static inline u32 nvl_intr_minion_r(void) +{ + return 0x00000060U; +} +static inline u32 nvl_intr_minion_tx_replay_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 nvl_intr_minion_tx_replay_m(void) +{ + return 0x1U << 0U; +} +static inline u32 nvl_intr_minion_tx_replay_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 nvl_intr_minion_tx_recovery_short_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 nvl_intr_minion_tx_recovery_short_m(void) +{ + return 0x1U << 1U; +} +static inline u32 nvl_intr_minion_tx_recovery_short_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 nvl_intr_minion_tx_recovery_long_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 nvl_intr_minion_tx_recovery_long_m(void) +{ + return 0x1U << 2U; +} +static inline u32 nvl_intr_minion_tx_recovery_long_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 nvl_intr_minion_tx_fault_ram_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 nvl_intr_minion_tx_fault_ram_m(void) +{ + return 0x1U << 4U; +} +static inline u32 nvl_intr_minion_tx_fault_ram_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 nvl_intr_minion_tx_fault_interface_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 nvl_intr_minion_tx_fault_interface_m(void) +{ + return 0x1U << 5U; +} +static inline u32 nvl_intr_minion_tx_fault_interface_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 nvl_intr_minion_tx_fault_sublink_change_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 nvl_intr_minion_tx_fault_sublink_change_m(void) +{ + return 0x1U << 8U; +} +static inline u32 nvl_intr_minion_tx_fault_sublink_change_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 nvl_intr_minion_rx_fault_sublink_change_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 nvl_intr_minion_rx_fault_sublink_change_m(void) +{ + return 0x1U << 16U; +} +static inline u32 nvl_intr_minion_rx_fault_sublink_change_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 nvl_intr_minion_rx_fault_dl_protocol_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 nvl_intr_minion_rx_fault_dl_protocol_m(void) +{ + return 0x1U << 20U; +} +static inline u32 nvl_intr_minion_rx_fault_dl_protocol_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 nvl_intr_minion_rx_short_error_rate_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 nvl_intr_minion_rx_short_error_rate_m(void) +{ + return 0x1U << 21U; +} +static inline u32 nvl_intr_minion_rx_short_error_rate_v(u32 r) +{ + return (r >> 21U) & 0x1U; +} +static inline u32 nvl_intr_minion_rx_long_error_rate_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 nvl_intr_minion_rx_long_error_rate_m(void) +{ + return 0x1U << 22U; +} +static inline u32 nvl_intr_minion_rx_long_error_rate_v(u32 r) +{ + return (r >> 22U) & 0x1U; +} +static inline u32 nvl_intr_minion_rx_ila_trigger_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 nvl_intr_minion_rx_ila_trigger_m(void) +{ + return 0x1U << 23U; +} +static inline u32 nvl_intr_minion_rx_ila_trigger_v(u32 r) +{ + return (r >> 23U) & 0x1U; +} +static inline u32 nvl_intr_minion_rx_crc_counter_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 nvl_intr_minion_rx_crc_counter_m(void) +{ + return 0x1U << 24U; +} +static inline u32 nvl_intr_minion_rx_crc_counter_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 nvl_intr_minion_ltssm_fault_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 nvl_intr_minion_ltssm_fault_m(void) +{ + return 0x1U << 28U; +} +static inline u32 nvl_intr_minion_ltssm_fault_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 nvl_intr_minion_ltssm_protocol_f(u32 v) +{ + return (v & 0x1U) << 29U; +} +static inline u32 nvl_intr_minion_ltssm_protocol_m(void) +{ + return 0x1U << 29U; +} +static inline u32 nvl_intr_minion_ltssm_protocol_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 nvl_intr_minion_minion_request_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 nvl_intr_minion_minion_request_m(void) +{ + return 0x1U << 30U; +} +static inline u32 nvl_intr_minion_minion_request_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 nvl_intr_nonstall_en_r(void) +{ + return 0x0000005cU; +} +static inline u32 nvl_intr_stall_en_r(void) +{ + return 0x00000058U; +} +static inline u32 nvl_intr_stall_en_tx_replay_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 nvl_intr_stall_en_tx_replay_m(void) +{ + return 0x1U << 0U; +} +static inline u32 nvl_intr_stall_en_tx_replay_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_tx_recovery_short_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 nvl_intr_stall_en_tx_recovery_short_m(void) +{ + return 0x1U << 1U; +} +static inline u32 nvl_intr_stall_en_tx_recovery_short_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_tx_recovery_short_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_tx_recovery_short_enable_f(void) +{ + return 0x2U; +} +static inline u32 nvl_intr_stall_en_tx_recovery_long_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 nvl_intr_stall_en_tx_recovery_long_m(void) +{ + return 0x1U << 2U; +} +static inline u32 nvl_intr_stall_en_tx_recovery_long_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_tx_recovery_long_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_tx_recovery_long_enable_f(void) +{ + return 0x4U; +} +static inline u32 nvl_intr_stall_en_tx_fault_ram_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 nvl_intr_stall_en_tx_fault_ram_m(void) +{ + return 0x1U << 4U; +} +static inline u32 nvl_intr_stall_en_tx_fault_ram_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_tx_fault_ram_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_tx_fault_ram_enable_f(void) +{ + return 0x10U; +} +static inline u32 nvl_intr_stall_en_tx_fault_interface_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 nvl_intr_stall_en_tx_fault_interface_m(void) +{ + return 0x1U << 5U; +} +static inline u32 nvl_intr_stall_en_tx_fault_interface_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_tx_fault_interface_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_tx_fault_interface_enable_f(void) +{ + return 0x20U; +} +static inline u32 nvl_intr_stall_en_tx_fault_sublink_change_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 nvl_intr_stall_en_tx_fault_sublink_change_m(void) +{ + return 0x1U << 8U; +} +static inline u32 nvl_intr_stall_en_tx_fault_sublink_change_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_tx_fault_sublink_change_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_tx_fault_sublink_change_enable_f(void) +{ + return 0x100U; +} +static inline u32 nvl_intr_stall_en_rx_fault_sublink_change_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 nvl_intr_stall_en_rx_fault_sublink_change_m(void) +{ + return 0x1U << 16U; +} +static inline u32 nvl_intr_stall_en_rx_fault_sublink_change_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_rx_fault_sublink_change_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_rx_fault_sublink_change_enable_f(void) +{ + return 0x10000U; +} +static inline u32 nvl_intr_stall_en_rx_fault_dl_protocol_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 nvl_intr_stall_en_rx_fault_dl_protocol_m(void) +{ + return 0x1U << 20U; +} +static inline u32 nvl_intr_stall_en_rx_fault_dl_protocol_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_rx_fault_dl_protocol_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_rx_fault_dl_protocol_enable_f(void) +{ + return 0x100000U; +} +static inline u32 nvl_intr_stall_en_rx_short_error_rate_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 nvl_intr_stall_en_rx_short_error_rate_m(void) +{ + return 0x1U << 21U; +} +static inline u32 nvl_intr_stall_en_rx_short_error_rate_v(u32 r) +{ + return (r >> 21U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_rx_short_error_rate_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_rx_short_error_rate_enable_f(void) +{ + return 0x200000U; +} +static inline u32 nvl_intr_stall_en_rx_long_error_rate_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 nvl_intr_stall_en_rx_long_error_rate_m(void) +{ + return 0x1U << 22U; +} +static inline u32 nvl_intr_stall_en_rx_long_error_rate_v(u32 r) +{ + return (r >> 22U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_rx_long_error_rate_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_rx_long_error_rate_enable_f(void) +{ + return 0x400000U; +} +static inline u32 nvl_intr_stall_en_rx_ila_trigger_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 nvl_intr_stall_en_rx_ila_trigger_m(void) +{ + return 0x1U << 23U; +} +static inline u32 nvl_intr_stall_en_rx_ila_trigger_v(u32 r) +{ + return (r >> 23U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_rx_ila_trigger_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_rx_ila_trigger_enable_f(void) +{ + return 0x800000U; +} +static inline u32 nvl_intr_stall_en_rx_crc_counter_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 nvl_intr_stall_en_rx_crc_counter_m(void) +{ + return 0x1U << 24U; +} +static inline u32 nvl_intr_stall_en_rx_crc_counter_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_rx_crc_counter_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_rx_crc_counter_enable_f(void) +{ + return 0x1000000U; +} +static inline u32 nvl_intr_stall_en_ltssm_fault_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 nvl_intr_stall_en_ltssm_fault_m(void) +{ + return 0x1U << 28U; +} +static inline u32 nvl_intr_stall_en_ltssm_fault_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_ltssm_fault_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_ltssm_fault_enable_f(void) +{ + return 0x10000000U; +} +static inline u32 nvl_intr_stall_en_ltssm_protocol_f(u32 v) +{ + return (v & 0x1U) << 29U; +} +static inline u32 nvl_intr_stall_en_ltssm_protocol_m(void) +{ + return 0x1U << 29U; +} +static inline u32 nvl_intr_stall_en_ltssm_protocol_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_ltssm_protocol_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_ltssm_protocol_enable_f(void) +{ + return 0x20000000U; +} +static inline u32 nvl_intr_stall_en_minion_request_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 nvl_intr_stall_en_minion_request_m(void) +{ + return 0x1U << 30U; +} +static inline u32 nvl_intr_stall_en_minion_request_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 nvl_intr_stall_en_minion_request_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_intr_stall_en_minion_request_enable_f(void) +{ + return 0x40000000U; +} +static inline u32 nvl_br0_cfg_cal_r(void) +{ + return 0x0000281cU; +} +static inline u32 nvl_br0_cfg_cal_rxcal_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 nvl_br0_cfg_cal_rxcal_m(void) +{ + return 0x1U << 0U; +} +static inline u32 nvl_br0_cfg_cal_rxcal_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 nvl_br0_cfg_cal_rxcal_on_v(void) +{ + return 0x00000001U; +} +static inline u32 nvl_br0_cfg_cal_rxcal_on_f(void) +{ + return 0x1U; +} +static inline u32 nvl_br0_cfg_status_cal_r(void) +{ + return 0x00002838U; +} +static inline u32 nvl_br0_cfg_status_cal_rxcal_done_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 nvl_br0_cfg_status_cal_rxcal_done_m(void) +{ + return 0x1U << 2U; +} +static inline u32 nvl_br0_cfg_status_cal_rxcal_done_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_nvlinkip_discovery_gv100.h b/include/nvgpu/hw/gv100/hw_nvlinkip_discovery_gv100.h new file mode 100644 index 0000000..9d33a9f --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_nvlinkip_discovery_gv100.h @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_nvlinkip_discovery_gv100_h_ +#define _hw_nvlinkip_discovery_gv100_h_ + +static inline u32 nvlinkip_discovery_common_r(void) +{ + return 0x00000000U; +} +static inline u32 nvlinkip_discovery_common_entry_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 nvlinkip_discovery_common_entry_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 nvlinkip_discovery_common_entry_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 nvlinkip_discovery_common_entry_enum_v(void) +{ + return 0x00000001U; +} +static inline u32 nvlinkip_discovery_common_entry_data1_v(void) +{ + return 0x00000002U; +} +static inline u32 nvlinkip_discovery_common_entry_data2_v(void) +{ + return 0x00000003U; +} +static inline u32 nvlinkip_discovery_common_contents_f(u32 v) +{ + return (v & 0x1fffffffU) << 2U; +} +static inline u32 nvlinkip_discovery_common_contents_v(u32 r) +{ + return (r >> 2U) & 0x1fffffffU; +} +static inline u32 nvlinkip_discovery_common_chain_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 nvlinkip_discovery_common_chain_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 nvlinkip_discovery_common_chain_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 nvlinkip_discovery_common_device_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 nvlinkip_discovery_common_device_v(u32 r) +{ + return (r >> 2U) & 0x3fU; +} +static inline u32 nvlinkip_discovery_common_device_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 nvlinkip_discovery_common_device_ioctrl_v(void) +{ + return 0x00000001U; +} +static inline u32 nvlinkip_discovery_common_device_nvltl_v(void) +{ + return 0x00000002U; +} +static inline u32 nvlinkip_discovery_common_device_nvlink_v(void) +{ + return 0x00000003U; +} +static inline u32 nvlinkip_discovery_common_device_minion_v(void) +{ + return 0x00000004U; +} +static inline u32 nvlinkip_discovery_common_device_nvlipt_v(void) +{ + return 0x00000005U; +} +static inline u32 nvlinkip_discovery_common_device_nvltlc_v(void) +{ + return 0x00000006U; +} +static inline u32 nvlinkip_discovery_common_device_dlpl_v(void) +{ + return 0x0000000bU; +} +static inline u32 nvlinkip_discovery_common_device_ioctrlmif_v(void) +{ + return 0x00000007U; +} +static inline u32 nvlinkip_discovery_common_device_dlpl_multicast_v(void) +{ + return 0x00000008U; +} +static inline u32 nvlinkip_discovery_common_device_nvltlc_multicast_v(void) +{ + return 0x00000009U; +} +static inline u32 nvlinkip_discovery_common_device_ioctrlmif_multicast_v(void) +{ + return 0x0000000aU; +} +static inline u32 nvlinkip_discovery_common_device_sioctrl_v(void) +{ + return 0x0000000cU; +} +static inline u32 nvlinkip_discovery_common_device_tioctrl_v(void) +{ + return 0x0000000dU; +} +static inline u32 nvlinkip_discovery_common_id_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 nvlinkip_discovery_common_id_v(u32 r) +{ + return (r >> 8U) & 0xffU; +} +static inline u32 nvlinkip_discovery_common_version_f(u32 v) +{ + return (v & 0x7ffU) << 20U; +} +static inline u32 nvlinkip_discovery_common_version_v(u32 r) +{ + return (r >> 20U) & 0x7ffU; +} +static inline u32 nvlinkip_discovery_common_pri_base_f(u32 v) +{ + return (v & 0xfffU) << 12U; +} +static inline u32 nvlinkip_discovery_common_pri_base_v(u32 r) +{ + return (r >> 12U) & 0xfffU; +} +static inline u32 nvlinkip_discovery_common_intr_f(u32 v) +{ + return (v & 0x1fU) << 7U; +} +static inline u32 nvlinkip_discovery_common_intr_v(u32 r) +{ + return (r >> 7U) & 0x1fU; +} +static inline u32 nvlinkip_discovery_common_reset_f(u32 v) +{ + return (v & 0x1fU) << 2U; +} +static inline u32 nvlinkip_discovery_common_reset_v(u32 r) +{ + return (r >> 2U) & 0x1fU; +} +static inline u32 nvlinkip_discovery_common_ioctrl_length_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 nvlinkip_discovery_common_ioctrl_length_v(u32 r) +{ + return (r >> 24U) & 0x3fU; +} +static inline u32 nvlinkip_discovery_common_dlpl_num_tx_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 nvlinkip_discovery_common_dlpl_num_tx_v(u32 r) +{ + return (r >> 24U) & 0x7U; +} +static inline u32 nvlinkip_discovery_common_dlpl_num_rx_f(u32 v) +{ + return (v & 0x7U) << 27U; +} +static inline u32 nvlinkip_discovery_common_dlpl_num_rx_v(u32 r) +{ + return (r >> 27U) & 0x7U; +} +static inline u32 nvlinkip_discovery_common_data1_ioctrl_length_f(u32 v) +{ + return (v & 0x7ffffU) << 12U; +} +static inline u32 nvlinkip_discovery_common_data1_ioctrl_length_v(u32 r) +{ + return (r >> 12U) & 0x7ffffU; +} +static inline u32 nvlinkip_discovery_common_data2_type_f(u32 v) +{ + return (v & 0x1fU) << 26U; +} +static inline u32 nvlinkip_discovery_common_data2_type_v(u32 r) +{ + return (r >> 26U) & 0x1fU; +} +static inline u32 nvlinkip_discovery_common_data2_type_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 nvlinkip_discovery_common_data2_type_pllcontrol_v(void) +{ + return 0x00000001U; +} +static inline u32 nvlinkip_discovery_common_data2_type_resetreg_v(void) +{ + return 0x00000002U; +} +static inline u32 nvlinkip_discovery_common_data2_type_intrreg_v(void) +{ + return 0x00000003U; +} +static inline u32 nvlinkip_discovery_common_data2_type_discovery_v(void) +{ + return 0x00000004U; +} +static inline u32 nvlinkip_discovery_common_data2_type_unicast_v(void) +{ + return 0x00000005U; +} +static inline u32 nvlinkip_discovery_common_data2_type_broadcast_v(void) +{ + return 0x00000006U; +} +static inline u32 nvlinkip_discovery_common_data2_addr_f(u32 v) +{ + return (v & 0xffffffU) << 2U; +} +static inline u32 nvlinkip_discovery_common_data2_addr_v(u32 r) +{ + return (r >> 2U) & 0xffffffU; +} +static inline u32 nvlinkip_discovery_common_dlpl_data2_type_f(u32 v) +{ + return (v & 0x1fU) << 26U; +} +static inline u32 nvlinkip_discovery_common_dlpl_data2_type_v(u32 r) +{ + return (r >> 26U) & 0x1fU; +} +static inline u32 nvlinkip_discovery_common_dlpl_data2_master_f(u32 v) +{ + return (v & 0x1U) << 15U; +} +static inline u32 nvlinkip_discovery_common_dlpl_data2_master_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 nvlinkip_discovery_common_dlpl_data2_masterid_f(u32 v) +{ + return (v & 0x7fU) << 8U; +} +static inline u32 nvlinkip_discovery_common_dlpl_data2_masterid_v(u32 r) +{ + return (r >> 8U) & 0x7fU; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_nvlipt_gv100.h b/include/nvgpu/hw/gv100/hw_nvlipt_gv100.h new file mode 100644 index 0000000..5f73fab --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_nvlipt_gv100.h @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_nvlipt_gv100_h_ +#define _hw_nvlipt_gv100_h_ + +static inline u32 nvlipt_intr_control_link0_r(void) +{ + return 0x000004b4U; +} +static inline u32 nvlipt_intr_control_link0_stallenable_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 nvlipt_intr_control_link0_stallenable_m(void) +{ + return 0x1U << 0U; +} +static inline u32 nvlipt_intr_control_link0_stallenable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 nvlipt_intr_control_link0_nostallenable_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 nvlipt_intr_control_link0_nostallenable_m(void) +{ + return 0x1U << 1U; +} +static inline u32 nvlipt_intr_control_link0_nostallenable_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 nvlipt_err_uc_status_link0_r(void) +{ + return 0x00000524U; +} +static inline u32 nvlipt_err_uc_status_link0_dlprotocol_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 nvlipt_err_uc_status_link0_dlprotocol_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 nvlipt_err_uc_status_link0_datapoisoned_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 nvlipt_err_uc_status_link0_datapoisoned_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 nvlipt_err_uc_status_link0_flowcontrol_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 nvlipt_err_uc_status_link0_flowcontrol_v(u32 r) +{ + return (r >> 13U) & 0x1U; +} +static inline u32 nvlipt_err_uc_status_link0_responsetimeout_f(u32 v) +{ + return (v & 0x1U) << 14U; +} +static inline u32 nvlipt_err_uc_status_link0_responsetimeout_v(u32 r) +{ + return (r >> 14U) & 0x1U; +} +static inline u32 nvlipt_err_uc_status_link0_targeterror_f(u32 v) +{ + return (v & 0x1U) << 15U; +} +static inline u32 nvlipt_err_uc_status_link0_targeterror_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 nvlipt_err_uc_status_link0_unexpectedresponse_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 nvlipt_err_uc_status_link0_unexpectedresponse_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 nvlipt_err_uc_status_link0_receiveroverflow_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 nvlipt_err_uc_status_link0_receiveroverflow_v(u32 r) +{ + return (r >> 17U) & 0x1U; +} +static inline u32 nvlipt_err_uc_status_link0_malformedpacket_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 nvlipt_err_uc_status_link0_malformedpacket_v(u32 r) +{ + return (r >> 18U) & 0x1U; +} +static inline u32 nvlipt_err_uc_status_link0_stompedpacketreceived_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 nvlipt_err_uc_status_link0_stompedpacketreceived_v(u32 r) +{ + return (r >> 19U) & 0x1U; +} +static inline u32 nvlipt_err_uc_status_link0_unsupportedrequest_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 nvlipt_err_uc_status_link0_unsupportedrequest_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 nvlipt_err_uc_status_link0_ucinternal_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 nvlipt_err_uc_status_link0_ucinternal_v(u32 r) +{ + return (r >> 22U) & 0x1U; +} +static inline u32 nvlipt_err_uc_mask_link0_r(void) +{ + return 0x00000528U; +} +static inline u32 nvlipt_err_uc_severity_link0_r(void) +{ + return 0x0000052cU; +} +static inline u32 nvlipt_err_uc_first_link0_r(void) +{ + return 0x00000530U; +} +static inline u32 nvlipt_err_uc_advisory_link0_r(void) +{ + return 0x00000534U; +} +static inline u32 nvlipt_err_c_status_link0_r(void) +{ + return 0x00000538U; +} +static inline u32 nvlipt_err_c_mask_link0_r(void) +{ + return 0x0000053cU; +} +static inline u32 nvlipt_err_c_first_link0_r(void) +{ + return 0x00000540U; +} +static inline u32 nvlipt_err_control_link0_r(void) +{ + return 0x00000544U; +} +static inline u32 nvlipt_err_control_link0_fatalenable_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 nvlipt_err_control_link0_fatalenable_m(void) +{ + return 0x1U << 1U; +} +static inline u32 nvlipt_err_control_link0_fatalenable_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 nvlipt_err_control_link0_nonfatalenable_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 nvlipt_err_control_link0_nonfatalenable_m(void) +{ + return 0x1U << 2U; +} +static inline u32 nvlipt_err_control_link0_nonfatalenable_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 nvlipt_intr_control_common_r(void) +{ + return 0x000004b0U; +} +static inline u32 nvlipt_intr_control_common_stallenable_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 nvlipt_intr_control_common_stallenable_m(void) +{ + return 0x1U << 0U; +} +static inline u32 nvlipt_intr_control_common_stallenable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 nvlipt_intr_control_common_nonstallenable_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 nvlipt_intr_control_common_nonstallenable_m(void) +{ + return 0x1U << 1U; +} +static inline u32 nvlipt_intr_control_common_nonstallenable_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 nvlipt_scratch_cold_r(void) +{ + return 0x000007d4U; +} +static inline u32 nvlipt_scratch_cold_data_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 nvlipt_scratch_cold_data_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 nvlipt_scratch_cold_data_init_v(void) +{ + return 0xdeadbaadU; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_nvtlc_gv100.h b/include/nvgpu/hw/gv100/hw_nvtlc_gv100.h new file mode 100644 index 0000000..cc31b12 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_nvtlc_gv100.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_nvtlc_gv100_h_ +#define _hw_nvtlc_gv100_h_ + +static inline u32 nvtlc_tx_err_report_en_0_r(void) +{ + return 0x00000708U; +} +static inline u32 nvtlc_rx_err_report_en_0_r(void) +{ + return 0x00000f08U; +} +static inline u32 nvtlc_rx_err_report_en_1_r(void) +{ + return 0x00000f20U; +} +static inline u32 nvtlc_tx_err_status_0_r(void) +{ + return 0x00000700U; +} +static inline u32 nvtlc_rx_err_status_0_r(void) +{ + return 0x00000f00U; +} +static inline u32 nvtlc_rx_err_status_1_r(void) +{ + return 0x00000f18U; +} +static inline u32 nvtlc_tx_err_first_0_r(void) +{ + return 0x00000714U; +} +static inline u32 nvtlc_rx_err_first_0_r(void) +{ + return 0x00000f14U; +} +static inline u32 nvtlc_rx_err_first_1_r(void) +{ + return 0x00000f2cU; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_pbdma_gv100.h b/include/nvgpu/hw/gv100/hw_pbdma_gv100.h new file mode 100644 index 0000000..41d7d1b --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_pbdma_gv100.h @@ -0,0 +1,651 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pbdma_gv100_h_ +#define _hw_pbdma_gv100_h_ + +static inline u32 pbdma_gp_entry1_r(void) +{ + return 0x10000004U; +} +static inline u32 pbdma_gp_entry1_get_hi_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pbdma_gp_entry1_length_f(u32 v) +{ + return (v & 0x1fffffU) << 10U; +} +static inline u32 pbdma_gp_entry1_length_v(u32 r) +{ + return (r >> 10U) & 0x1fffffU; +} +static inline u32 pbdma_gp_base_r(u32 i) +{ + return 0x00040048U + i*8192U; +} +static inline u32 pbdma_gp_base__size_1_v(void) +{ + return 0x0000000eU; +} +static inline u32 pbdma_gp_base_offset_f(u32 v) +{ + return (v & 0x1fffffffU) << 3U; +} +static inline u32 pbdma_gp_base_rsvd_s(void) +{ + return 3U; +} +static inline u32 pbdma_gp_base_hi_r(u32 i) +{ + return 0x0004004cU + i*8192U; +} +static inline u32 pbdma_gp_base_hi_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_gp_base_hi_limit2_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 pbdma_gp_fetch_r(u32 i) +{ + return 0x00040050U + i*8192U; +} +static inline u32 pbdma_gp_get_r(u32 i) +{ + return 0x00040014U + i*8192U; +} +static inline u32 pbdma_gp_put_r(u32 i) +{ + return 0x00040000U + i*8192U; +} +static inline u32 pbdma_pb_fetch_r(u32 i) +{ + return 0x00040054U + i*8192U; +} +static inline u32 pbdma_pb_fetch_hi_r(u32 i) +{ + return 0x00040058U + i*8192U; +} +static inline u32 pbdma_get_r(u32 i) +{ + return 0x00040018U + i*8192U; +} +static inline u32 pbdma_get_hi_r(u32 i) +{ + return 0x0004001cU + i*8192U; +} +static inline u32 pbdma_put_r(u32 i) +{ + return 0x0004005cU + i*8192U; +} +static inline u32 pbdma_put_hi_r(u32 i) +{ + return 0x00040060U + i*8192U; +} +static inline u32 pbdma_pb_header_r(u32 i) +{ + return 0x00040084U + i*8192U; +} +static inline u32 pbdma_pb_header_priv_user_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_method_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_subchannel_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_level_main_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_pb_header_type_inc_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_pb_header_type_non_inc_f(void) +{ + return 0x60000000U; +} +static inline u32 pbdma_hdr_shadow_r(u32 i) +{ + return 0x00040118U + i*8192U; +} +static inline u32 pbdma_gp_shadow_0_r(u32 i) +{ + return 0x00040110U + i*8192U; +} +static inline u32 pbdma_gp_shadow_1_r(u32 i) +{ + return 0x00040114U + i*8192U; +} +static inline u32 pbdma_subdevice_r(u32 i) +{ + return 0x00040094U + i*8192U; +} +static inline u32 pbdma_subdevice_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 pbdma_subdevice_status_active_f(void) +{ + return 0x10000000U; +} +static inline u32 pbdma_subdevice_channel_dma_enable_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_method0_r(u32 i) +{ + return 0x000400c0U + i*8192U; +} +static inline u32 pbdma_method0_fifo_size_v(void) +{ + return 0x00000004U; +} +static inline u32 pbdma_method0_addr_f(u32 v) +{ + return (v & 0xfffU) << 2U; +} +static inline u32 pbdma_method0_addr_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 pbdma_method0_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 pbdma_method0_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_method0_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_method1_r(u32 i) +{ + return 0x000400c8U + i*8192U; +} +static inline u32 pbdma_method2_r(u32 i) +{ + return 0x000400d0U + i*8192U; +} +static inline u32 pbdma_method3_r(u32 i) +{ + return 0x000400d8U + i*8192U; +} +static inline u32 pbdma_data0_r(u32 i) +{ + return 0x000400c4U + i*8192U; +} +static inline u32 pbdma_acquire_r(u32 i) +{ + return 0x00040030U + i*8192U; +} +static inline u32 pbdma_acquire_retry_man_2_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_acquire_retry_exp_2_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_acquire_timeout_exp_f(u32 v) +{ + return (v & 0xfU) << 11U; +} +static inline u32 pbdma_acquire_timeout_exp_max_v(void) +{ + return 0x0000000fU; +} +static inline u32 pbdma_acquire_timeout_exp_max_f(void) +{ + return 0x7800U; +} +static inline u32 pbdma_acquire_timeout_man_f(u32 v) +{ + return (v & 0xffffU) << 15U; +} +static inline u32 pbdma_acquire_timeout_man_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 pbdma_acquire_timeout_man_max_f(void) +{ + return 0x7fff8000U; +} +static inline u32 pbdma_acquire_timeout_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_acquire_timeout_en_disable_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_status_r(u32 i) +{ + return 0x00040100U + i*8192U; +} +static inline u32 pbdma_channel_r(u32 i) +{ + return 0x00040120U + i*8192U; +} +static inline u32 pbdma_signature_r(u32 i) +{ + return 0x00040010U + i*8192U; +} +static inline u32 pbdma_signature_hw_valid_f(void) +{ + return 0xfaceU; +} +static inline u32 pbdma_signature_sw_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_r(u32 i) +{ + return 0x00040008U + i*8192U; +} +static inline u32 pbdma_userd_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_userd_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 pbdma_userd_addr_f(u32 v) +{ + return (v & 0x7fffffU) << 9U; +} +static inline u32 pbdma_config_r(u32 i) +{ + return 0x000400f4U + i*8192U; +} +static inline u32 pbdma_config_l2_evict_first_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_config_l2_evict_normal_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_config_ce_split_enable_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_config_ce_split_disable_f(void) +{ + return 0x10U; +} +static inline u32 pbdma_config_auth_level_non_privileged_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_config_auth_level_privileged_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_config_userd_writeback_disable_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_config_userd_writeback_enable_f(void) +{ + return 0x1000U; +} +static inline u32 pbdma_userd_hi_r(u32 i) +{ + return 0x0004000cU + i*8192U; +} +static inline u32 pbdma_userd_hi_addr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_hce_ctrl_r(u32 i) +{ + return 0x000400e4U + i*8192U; +} +static inline u32 pbdma_hce_ctrl_hce_priv_mode_yes_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_r(u32 i) +{ + return 0x00040108U + i*8192U; +} +static inline u32 pbdma_intr_0_memreq_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pbdma_intr_0_memreq_pending_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_intr_0_memack_timeout_pending_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_intr_0_memack_extra_pending_f(void) +{ + return 0x4U; +} +static inline u32 pbdma_intr_0_memdat_timeout_pending_f(void) +{ + return 0x8U; +} +static inline u32 pbdma_intr_0_memdat_extra_pending_f(void) +{ + return 0x10U; +} +static inline u32 pbdma_intr_0_memflush_pending_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_memop_pending_f(void) +{ + return 0x40U; +} +static inline u32 pbdma_intr_0_lbconnect_pending_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_intr_0_lbreq_pending_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_0_lback_timeout_pending_f(void) +{ + return 0x200U; +} +static inline u32 pbdma_intr_0_lback_extra_pending_f(void) +{ + return 0x400U; +} +static inline u32 pbdma_intr_0_lbdat_timeout_pending_f(void) +{ + return 0x800U; +} +static inline u32 pbdma_intr_0_lbdat_extra_pending_f(void) +{ + return 0x1000U; +} +static inline u32 pbdma_intr_0_gpfifo_pending_f(void) +{ + return 0x2000U; +} +static inline u32 pbdma_intr_0_gpptr_pending_f(void) +{ + return 0x4000U; +} +static inline u32 pbdma_intr_0_gpentry_pending_f(void) +{ + return 0x8000U; +} +static inline u32 pbdma_intr_0_gpcrc_pending_f(void) +{ + return 0x10000U; +} +static inline u32 pbdma_intr_0_pbptr_pending_f(void) +{ + return 0x20000U; +} +static inline u32 pbdma_intr_0_pbentry_pending_f(void) +{ + return 0x40000U; +} +static inline u32 pbdma_intr_0_pbcrc_pending_f(void) +{ + return 0x80000U; +} +static inline u32 pbdma_intr_0_clear_faulted_error_pending_f(void) +{ + return 0x100000U; +} +static inline u32 pbdma_intr_0_method_pending_f(void) +{ + return 0x200000U; +} +static inline u32 pbdma_intr_0_methodcrc_pending_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_intr_0_device_pending_f(void) +{ + return 0x800000U; +} +static inline u32 pbdma_intr_0_eng_reset_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 pbdma_intr_0_semaphore_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 pbdma_intr_0_acquire_pending_f(void) +{ + return 0x4000000U; +} +static inline u32 pbdma_intr_0_pri_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 pbdma_intr_0_no_ctxsw_seg_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_intr_0_pbseg_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 pbdma_intr_0_signature_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_intr_1_r(u32 i) +{ + return 0x00040148U + i*8192U; +} +static inline u32 pbdma_intr_1_ctxnotvalid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 pbdma_intr_1_ctxnotvalid_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_intr_en_0_r(u32 i) +{ + return 0x0004010cU + i*8192U; +} +static inline u32 pbdma_intr_en_0_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_en_1_r(u32 i) +{ + return 0x0004014cU + i*8192U; +} +static inline u32 pbdma_intr_stall_r(u32 i) +{ + return 0x0004013cU + i*8192U; +} +static inline u32 pbdma_intr_stall_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_stall_1_r(u32 i) +{ + return 0x00040140U + i*8192U; +} +static inline u32 pbdma_intr_stall_1_hce_illegal_op_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_udma_nop_r(void) +{ + return 0x00000008U; +} +static inline u32 pbdma_runlist_timeslice_r(u32 i) +{ + return 0x000400f8U + i*8192U; +} +static inline u32 pbdma_runlist_timeslice_timeout_128_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_runlist_timeslice_timescale_3_f(void) +{ + return 0x3000U; +} +static inline u32 pbdma_runlist_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +static inline u32 pbdma_target_r(u32 i) +{ + return 0x000400acU + i*8192U; +} +static inline u32 pbdma_target_engine_sw_f(void) +{ + return 0x1fU; +} +static inline u32 pbdma_target_eng_ctx_valid_true_f(void) +{ + return 0x10000U; +} +static inline u32 pbdma_target_eng_ctx_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_target_ce_ctx_valid_true_f(void) +{ + return 0x20000U; +} +static inline u32 pbdma_target_ce_ctx_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_target_host_tsg_event_reason_pbdma_idle_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_target_host_tsg_event_reason_semaphore_acquire_failure_f(void) +{ + return 0x1000000U; +} +static inline u32 pbdma_target_host_tsg_event_reason_tsg_yield_f(void) +{ + return 0x2000000U; +} +static inline u32 pbdma_target_host_tsg_event_reason_host_subchannel_switch_f(void) +{ + return 0x3000000U; +} +static inline u32 pbdma_target_should_send_tsg_event_true_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_target_should_send_tsg_event_false_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_target_needs_host_tsg_event_true_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_target_needs_host_tsg_event_false_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_set_channel_info_r(u32 i) +{ + return 0x000400fcU + i*8192U; +} +static inline u32 pbdma_set_channel_info_veid_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 pbdma_timeout_r(u32 i) +{ + return 0x0004012cU + i*8192U; +} +static inline u32 pbdma_timeout_period_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 pbdma_timeout_period_max_f(void) +{ + return 0xffffffffU; +} +static inline u32 pbdma_timeout_period_init_f(void) +{ + return 0x10000U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_perf_gv100.h b/include/nvgpu/hw/gv100/hw_perf_gv100.h new file mode 100644 index 0000000..40107ee --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_perf_gv100.h @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_perf_gv100_h_ +#define _hw_perf_gv100_h_ + +static inline u32 perf_pmmgpc_perdomain_offset_v(void) +{ + return 0x00000200U; +} +static inline u32 perf_pmmsys_perdomain_offset_v(void) +{ + return 0x00000200U; +} +static inline u32 perf_pmmgpc_base_v(void) +{ + return 0x00180000U; +} +static inline u32 perf_pmmgpc_extent_v(void) +{ + return 0x00183fffU; +} +static inline u32 perf_pmmsys_base_v(void) +{ + return 0x00240000U; +} +static inline u32 perf_pmmsys_extent_v(void) +{ + return 0x00243fffU; +} +static inline u32 perf_pmmfbp_base_v(void) +{ + return 0x00200000U; +} +static inline u32 perf_pmasys_control_r(void) +{ + return 0x0024a000U; +} +static inline u32 perf_pmasys_control_membuf_status_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_f(void) +{ + return 0x10U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_f(void) +{ + return 0x20U; +} +static inline u32 perf_pmasys_mem_block_r(void) +{ + return 0x0024a070U; +} +static inline u32 perf_pmasys_mem_block_base_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 perf_pmasys_mem_block_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 perf_pmasys_mem_block_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 perf_pmasys_mem_block_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 perf_pmasys_mem_block_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 perf_pmasys_mem_block_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_mem_block_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_outbase_r(void) +{ + return 0x0024a074U; +} +static inline u32 perf_pmasys_outbase_ptr_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_outbaseupper_r(void) +{ + return 0x0024a078U; +} +static inline u32 perf_pmasys_outbaseupper_ptr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 perf_pmasys_outsize_r(void) +{ + return 0x0024a07cU; +} +static inline u32 perf_pmasys_outsize_numbytes_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_mem_bytes_r(void) +{ + return 0x0024a084U; +} +static inline u32 perf_pmasys_mem_bytes_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_mem_bump_r(void) +{ + return 0x0024a088U; +} +static inline u32 perf_pmasys_mem_bump_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_enginestatus_r(void) +{ + return 0x0024a0a4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_f(void) +{ + return 0x10U; +} +static inline u32 perf_pmmsys_engine_sel_r(u32 i) +{ + return 0x0024006cU + i*512U; +} +static inline u32 perf_pmmsys_engine_sel__size_1_v(void) +{ + return 0x00000020U; +} +static inline u32 perf_pmmfbp_engine_sel_r(u32 i) +{ + return 0x0020006cU + i*512U; +} +static inline u32 perf_pmmfbp_engine_sel__size_1_v(void) +{ + return 0x00000020U; +} +static inline u32 perf_pmmgpc_engine_sel_r(u32 i) +{ + return 0x0018006cU + i*512U; +} +static inline u32 perf_pmmgpc_engine_sel__size_1_v(void) +{ + return 0x00000020U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_pgsp_gv100.h b/include/nvgpu/hw/gv100/hw_pgsp_gv100.h new file mode 100644 index 0000000..34d0eae --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_pgsp_gv100.h @@ -0,0 +1,643 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pgsp_gv100_h_ +#define _hw_pgsp_gv100_h_ + +static inline u32 pgsp_falcon_irqsset_r(void) +{ + return 0x00110000U; +} +static inline u32 pgsp_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 pgsp_falcon_irqsclr_r(void) +{ + return 0x00110004U; +} +static inline u32 pgsp_falcon_irqstat_r(void) +{ + return 0x00110008U; +} +static inline u32 pgsp_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 pgsp_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 pgsp_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 pgsp_falcon_irqmode_r(void) +{ + return 0x0011000cU; +} +static inline u32 pgsp_falcon_irqmset_r(void) +{ + return 0x00110010U; +} +static inline u32 pgsp_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pgsp_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pgsp_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pgsp_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pgsp_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pgsp_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pgsp_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pgsp_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pgsp_falcon_irqmclr_r(void) +{ + return 0x00110014U; +} +static inline u32 pgsp_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pgsp_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pgsp_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pgsp_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pgsp_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pgsp_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pgsp_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pgsp_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pgsp_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pgsp_falcon_irqmask_r(void) +{ + return 0x00110018U; +} +static inline u32 pgsp_falcon_irqdest_r(void) +{ + return 0x0011001cU; +} +static inline u32 pgsp_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pgsp_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pgsp_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pgsp_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pgsp_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pgsp_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pgsp_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pgsp_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pgsp_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pgsp_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 pgsp_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 pgsp_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 pgsp_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 pgsp_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pgsp_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 pgsp_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 pgsp_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 pgsp_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 pgsp_falcon_curctx_r(void) +{ + return 0x00110050U; +} +static inline u32 pgsp_falcon_nxtctx_r(void) +{ + return 0x00110054U; +} +static inline u32 pgsp_falcon_nxtctx_ctxptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 pgsp_falcon_nxtctx_ctxtgt_fb_f(void) +{ + return 0x0U; +} +static inline u32 pgsp_falcon_nxtctx_ctxtgt_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 pgsp_falcon_nxtctx_ctxtgt_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 pgsp_falcon_nxtctx_ctxvalid_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 pgsp_falcon_mailbox0_r(void) +{ + return 0x00110040U; +} +static inline u32 pgsp_falcon_mailbox1_r(void) +{ + return 0x00110044U; +} +static inline u32 pgsp_falcon_itfen_r(void) +{ + return 0x00110048U; +} +static inline u32 pgsp_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 pgsp_falcon_idlestate_r(void) +{ + return 0x0011004cU; +} +static inline u32 pgsp_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pgsp_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 pgsp_falcon_os_r(void) +{ + return 0x00110080U; +} +static inline u32 pgsp_falcon_engctl_r(void) +{ + return 0x001100a4U; +} +static inline u32 pgsp_falcon_engctl_switch_context_true_f(void) +{ + return 0x8U; +} +static inline u32 pgsp_falcon_engctl_switch_context_false_f(void) +{ + return 0x0U; +} +static inline u32 pgsp_falcon_cpuctl_r(void) +{ + return 0x00110100U; +} +static inline u32 pgsp_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pgsp_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pgsp_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 pgsp_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pgsp_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pgsp_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 pgsp_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 pgsp_falcon_cpuctl_alias_r(void) +{ + return 0x00110130U; +} +static inline u32 pgsp_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pgsp_falcon_imemc_r(u32 i) +{ + return 0x00110180U + i*16U; +} +static inline u32 pgsp_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pgsp_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pgsp_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pgsp_falcon_imemd_r(u32 i) +{ + return 0x00110184U + i*16U; +} +static inline u32 pgsp_falcon_imemt_r(u32 i) +{ + return 0x00110188U + i*16U; +} +static inline u32 pgsp_falcon_sctl_r(void) +{ + return 0x00110240U; +} +static inline u32 pgsp_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 pgsp_falcon_bootvec_r(void) +{ + return 0x00110104U; +} +static inline u32 pgsp_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pgsp_falcon_dmactl_r(void) +{ + return 0x0011010cU; +} +static inline u32 pgsp_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 pgsp_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pgsp_falcon_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pgsp_falcon_hwcfg_r(void) +{ + return 0x00110108U; +} +static inline u32 pgsp_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 pgsp_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 pgsp_falcon_dmatrfbase_r(void) +{ + return 0x00110110U; +} +static inline u32 pgsp_falcon_dmatrfbase1_r(void) +{ + return 0x00110128U; +} +static inline u32 pgsp_falcon_dmatrfmoffs_r(void) +{ + return 0x00110114U; +} +static inline u32 pgsp_falcon_dmatrfcmd_r(void) +{ + return 0x00110118U; +} +static inline u32 pgsp_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pgsp_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pgsp_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 pgsp_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 pgsp_falcon_dmatrffboffs_r(void) +{ + return 0x0011011cU; +} +static inline u32 pgsp_falcon_exterraddr_r(void) +{ + return 0x00110168U; +} +static inline u32 pgsp_falcon_exterrstat_r(void) +{ + return 0x0011016cU; +} +static inline u32 pgsp_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 pgsp_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 pgsp_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 pgsp_sec2_falcon_icd_cmd_r(void) +{ + return 0x00110200U; +} +static inline u32 pgsp_sec2_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 pgsp_sec2_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 pgsp_sec2_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 pgsp_sec2_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 pgsp_sec2_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 pgsp_sec2_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 pgsp_sec2_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 pgsp_sec2_falcon_icd_rdata_r(void) +{ + return 0x0011020cU; +} +static inline u32 pgsp_falcon_dmemc_r(u32 i) +{ + return 0x001101c0U + i*8U; +} +static inline u32 pgsp_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pgsp_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 pgsp_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pgsp_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 pgsp_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pgsp_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 pgsp_falcon_dmemd_r(u32 i) +{ + return 0x001101c4U + i*8U; +} +static inline u32 pgsp_falcon_debug1_r(void) +{ + return 0x00110090U; +} +static inline u32 pgsp_falcon_debug1_ctxsw_mode_s(void) +{ + return 1U; +} +static inline u32 pgsp_falcon_debug1_ctxsw_mode_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 pgsp_falcon_debug1_ctxsw_mode_m(void) +{ + return 0x1U << 16U; +} +static inline u32 pgsp_falcon_debug1_ctxsw_mode_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 pgsp_falcon_debug1_ctxsw_mode_init_f(void) +{ + return 0x0U; +} +static inline u32 pgsp_fbif_transcfg_r(u32 i) +{ + return 0x00110600U + i*4U; +} +static inline u32 pgsp_fbif_transcfg_target_local_fb_f(void) +{ + return 0x0U; +} +static inline u32 pgsp_fbif_transcfg_target_coherent_sysmem_f(void) +{ + return 0x1U; +} +static inline u32 pgsp_fbif_transcfg_target_noncoherent_sysmem_f(void) +{ + return 0x2U; +} +static inline u32 pgsp_fbif_transcfg_mem_type_s(void) +{ + return 1U; +} +static inline u32 pgsp_fbif_transcfg_mem_type_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pgsp_fbif_transcfg_mem_type_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pgsp_fbif_transcfg_mem_type_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pgsp_fbif_transcfg_mem_type_virtual_f(void) +{ + return 0x0U; +} +static inline u32 pgsp_fbif_transcfg_mem_type_physical_f(void) +{ + return 0x4U; +} +static inline u32 pgsp_falcon_engine_r(void) +{ + return 0x001103c0U; +} +static inline u32 pgsp_falcon_engine_reset_true_f(void) +{ + return 0x1U; +} +static inline u32 pgsp_falcon_engine_reset_false_f(void) +{ + return 0x0U; +} +static inline u32 pgsp_fbif_ctl_r(void) +{ + return 0x00110624U; +} +static inline u32 pgsp_fbif_ctl_allow_phys_no_ctx_init_f(void) +{ + return 0x0U; +} +static inline u32 pgsp_fbif_ctl_allow_phys_no_ctx_disallow_f(void) +{ + return 0x0U; +} +static inline u32 pgsp_fbif_ctl_allow_phys_no_ctx_allow_f(void) +{ + return 0x80U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_pram_gv100.h b/include/nvgpu/hw/gv100/hw_pram_gv100.h new file mode 100644 index 0000000..8f005a2 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_pram_gv100.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pram_gv100_h_ +#define _hw_pram_gv100_h_ + +static inline u32 pram_data032_r(u32 i) +{ + return 0x00700000U + i*4U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_pri_ringmaster_gv100.h b/include/nvgpu/hw/gv100/hw_pri_ringmaster_gv100.h new file mode 100644 index 0000000..5eca93c --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_pri_ringmaster_gv100.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringmaster_gv100_h_ +#define _hw_pri_ringmaster_gv100_h_ + +static inline u32 pri_ringmaster_command_r(void) +{ + return 0x0012004cU; +} +static inline u32 pri_ringmaster_command_cmd_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 pri_ringmaster_command_cmd_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 pri_ringmaster_command_cmd_no_cmd_v(void) +{ + return 0x00000000U; +} +static inline u32 pri_ringmaster_command_cmd_start_ring_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_command_cmd_ack_interrupt_f(void) +{ + return 0x2U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_f(void) +{ + return 0x3U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_bc_grp_all_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_command_data_r(void) +{ + return 0x00120048U; +} +static inline u32 pri_ringmaster_start_results_r(void) +{ + return 0x00120050U; +} +static inline u32 pri_ringmaster_start_results_connectivity_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_start_results_connectivity_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 pri_ringmaster_intr_status0_r(void) +{ + return 0x00120058U; +} +static inline u32 pri_ringmaster_intr_status0_ring_start_conn_fault_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_disconnect_fault_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_overflow_fault_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_gbl_write_error_sys_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status1_r(void) +{ + return 0x0012005cU; +} +static inline u32 pri_ringmaster_global_ctl_r(void) +{ + return 0x00120060U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_asserted_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_deasserted_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_enum_fbp_r(void) +{ + return 0x00120074U; +} +static inline u32 pri_ringmaster_enum_fbp_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_gpc_r(void) +{ + return 0x00120078U; +} +static inline u32 pri_ringmaster_enum_gpc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_ltc_r(void) +{ + return 0x0012006cU; +} +static inline u32 pri_ringmaster_enum_ltc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_pri_ringstation_gpc_gv100.h b/include/nvgpu/hw/gv100/hw_pri_ringstation_gpc_gv100.h new file mode 100644 index 0000000..fc522d5 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_pri_ringstation_gpc_gv100.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_gpc_gv100_h_ +#define _hw_pri_ringstation_gpc_gv100_h_ + +static inline u32 pri_ringstation_gpc_master_config_r(u32 i) +{ + return 0x00128300U + i*4U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_adr_r(void) +{ + return 0x00128120U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_wrdat_r(void) +{ + return 0x00128124U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_info_r(void) +{ + return 0x00128128U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_code_r(void) +{ + return 0x0012812cU; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_pri_ringstation_sys_gv100.h b/include/nvgpu/hw/gv100/hw_pri_ringstation_sys_gv100.h new file mode 100644 index 0000000..885ea30 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_pri_ringstation_sys_gv100.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_sys_gv100_h_ +#define _hw_pri_ringstation_sys_gv100_h_ + +static inline u32 pri_ringstation_sys_master_config_r(u32 i) +{ + return 0x00122300U + i*4U; +} +static inline u32 pri_ringstation_sys_decode_config_r(void) +{ + return 0x00122204U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_m(void) +{ + return 0x7U << 0U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_drop_on_ring_not_started_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringstation_sys_priv_error_adr_r(void) +{ + return 0x00122120U; +} +static inline u32 pri_ringstation_sys_priv_error_wrdat_r(void) +{ + return 0x00122124U; +} +static inline u32 pri_ringstation_sys_priv_error_info_r(void) +{ + return 0x00122128U; +} +static inline u32 pri_ringstation_sys_priv_error_code_r(void) +{ + return 0x0012212cU; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_proj_gv100.h b/include/nvgpu/hw/gv100/hw_proj_gv100.h new file mode 100644 index 0000000..f46eaa0 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_proj_gv100.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_proj_gv100_h_ +#define _hw_proj_gv100_h_ + +static inline u32 proj_gpc_base_v(void) +{ + return 0x00500000U; +} +static inline u32 proj_gpc_shared_base_v(void) +{ + return 0x00418000U; +} +static inline u32 proj_gpc_stride_v(void) +{ + return 0x00008000U; +} +static inline u32 proj_gpc_priv_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_ltc_stride_v(void) +{ + return 0x00002000U; +} +static inline u32 proj_lts_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_fbpa_base_v(void) +{ + return 0x00900000U; +} +static inline u32 proj_fbpa_shared_base_v(void) +{ + return 0x009a0000U; +} +static inline u32 proj_fbpa_stride_v(void) +{ + return 0x00004000U; +} +static inline u32 proj_ppc_in_gpc_base_v(void) +{ + return 0x00003000U; +} +static inline u32 proj_ppc_in_gpc_shared_base_v(void) +{ + return 0x00003e00U; +} +static inline u32 proj_ppc_in_gpc_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_rop_base_v(void) +{ + return 0x00410000U; +} +static inline u32 proj_rop_shared_base_v(void) +{ + return 0x00408800U; +} +static inline u32 proj_rop_stride_v(void) +{ + return 0x00000400U; +} +static inline u32 proj_tpc_in_gpc_base_v(void) +{ + return 0x00004000U; +} +static inline u32 proj_tpc_in_gpc_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_tpc_in_gpc_shared_base_v(void) +{ + return 0x00001800U; +} +static inline u32 proj_smpc_base_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_smpc_shared_base_v(void) +{ + return 0x00000300U; +} +static inline u32 proj_smpc_unique_base_v(void) +{ + return 0x00000600U; +} +static inline u32 proj_smpc_stride_v(void) +{ + return 0x00000100U; +} +static inline u32 proj_host_num_engines_v(void) +{ + return 0x0000000fU; +} +static inline u32 proj_host_num_pbdma_v(void) +{ + return 0x0000000eU; +} +static inline u32 proj_scal_litter_num_tpc_per_gpc_v(void) +{ + return 0x00000007U; +} +static inline u32 proj_scal_litter_num_fbps_v(void) +{ + return 0x00000008U; +} +static inline u32 proj_scal_litter_num_fbpas_v(void) +{ + return 0x00000010U; +} +static inline u32 proj_scal_litter_num_gpcs_v(void) +{ + return 0x00000006U; +} +static inline u32 proj_scal_litter_num_pes_per_gpc_v(void) +{ + return 0x00000003U; +} +static inline u32 proj_scal_litter_num_tpcs_per_pes_v(void) +{ + return 0x00000003U; +} +static inline u32 proj_scal_litter_num_zcull_banks_v(void) +{ + return 0x00000004U; +} +static inline u32 proj_scal_litter_num_sm_per_tpc_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_scal_max_gpcs_v(void) +{ + return 0x00000020U; +} +static inline u32 proj_scal_max_tpc_per_gpc_v(void) +{ + return 0x00000008U; +} +static inline u32 proj_sm_stride_v(void) +{ + return 0x00000080U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_pwr_gv100.h b/include/nvgpu/hw/gv100/hw_pwr_gv100.h new file mode 100644 index 0000000..c719226 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_pwr_gv100.h @@ -0,0 +1,983 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pwr_gv100_h_ +#define _hw_pwr_gv100_h_ + +static inline u32 pwr_falcon_irqsset_r(void) +{ + return 0x0010a000U; +} +static inline u32 pwr_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqsclr_r(void) +{ + return 0x0010a004U; +} +static inline u32 pwr_falcon_irqstat_r(void) +{ + return 0x0010a008U; +} +static inline u32 pwr_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 pwr_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 pwr_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqstat_ext_second_true_f(void) +{ + return 0x800U; +} +static inline u32 pwr_falcon_irqmode_r(void) +{ + return 0x0010a00cU; +} +static inline u32 pwr_falcon_irqmset_r(void) +{ + return 0x0010a010U; +} +static inline u32 pwr_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmset_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqmset_ext_ctxe_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 pwr_falcon_irqmset_ext_limitv_f(u32 v) +{ + return (v & 0x1U) << 9U; +} +static inline u32 pwr_falcon_irqmset_ext_second_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 pwr_falcon_irqmset_ext_therm_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 pwr_falcon_irqmset_ext_miscio_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 pwr_falcon_irqmset_ext_rttimer_f(u32 v) +{ + return (v & 0x1U) << 14U; +} +static inline u32 pwr_falcon_irqmclr_r(void) +{ + return 0x0010a014U; +} +static inline u32 pwr_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqmclr_ext_ctxe_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 pwr_falcon_irqmclr_ext_limitv_f(u32 v) +{ + return (v & 0x1U) << 9U; +} +static inline u32 pwr_falcon_irqmclr_ext_second_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 pwr_falcon_irqmclr_ext_therm_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 pwr_falcon_irqmclr_ext_miscio_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 pwr_falcon_irqmclr_ext_rttimer_f(u32 v) +{ + return (v & 0x1U) << 14U; +} +static inline u32 pwr_falcon_irqmask_r(void) +{ + return 0x0010a018U; +} +static inline u32 pwr_falcon_irqdest_r(void) +{ + return 0x0010a01cU; +} +static inline u32 pwr_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqdest_host_ext_ctxe_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 pwr_falcon_irqdest_host_ext_limitv_f(u32 v) +{ + return (v & 0x1U) << 9U; +} +static inline u32 pwr_falcon_irqdest_host_ext_second_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 pwr_falcon_irqdest_host_ext_therm_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 pwr_falcon_irqdest_host_ext_miscio_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 pwr_falcon_irqdest_host_ext_rttimer_f(u32 v) +{ + return (v & 0x1U) << 14U; +} +static inline u32 pwr_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 pwr_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 pwr_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 pwr_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 pwr_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 pwr_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 pwr_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 pwr_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 pwr_falcon_irqdest_target_ext_ctxe_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_irqdest_target_ext_limitv_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 pwr_falcon_irqdest_target_ext_second_f(u32 v) +{ + return (v & 0x1U) << 27U; +} +static inline u32 pwr_falcon_irqdest_target_ext_therm_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 pwr_falcon_irqdest_target_ext_miscio_f(u32 v) +{ + return (v & 0x1U) << 29U; +} +static inline u32 pwr_falcon_irqdest_target_ext_rttimer_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 pwr_falcon_curctx_r(void) +{ + return 0x0010a050U; +} +static inline u32 pwr_falcon_nxtctx_r(void) +{ + return 0x0010a054U; +} +static inline u32 pwr_falcon_mailbox0_r(void) +{ + return 0x0010a040U; +} +static inline u32 pwr_falcon_mailbox1_r(void) +{ + return 0x0010a044U; +} +static inline u32 pwr_falcon_itfen_r(void) +{ + return 0x0010a048U; +} +static inline u32 pwr_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 pwr_falcon_idlestate_r(void) +{ + return 0x0010a04cU; +} +static inline u32 pwr_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 pwr_falcon_os_r(void) +{ + return 0x0010a080U; +} +static inline u32 pwr_falcon_engctl_r(void) +{ + return 0x0010a0a4U; +} +static inline u32 pwr_falcon_cpuctl_r(void) +{ + return 0x0010a100U; +} +static inline u32 pwr_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 pwr_falcon_cpuctl_alias_r(void) +{ + return 0x0010a130U; +} +static inline u32 pwr_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_pmu_scpctl_stat_r(void) +{ + return 0x0010ac08U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_m(void) +{ + return 0x1U << 20U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 pwr_falcon_imemc_r(u32 i) +{ + return 0x0010a180U + i*16U; +} +static inline u32 pwr_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_imemd_r(u32 i) +{ + return 0x0010a184U + i*16U; +} +static inline u32 pwr_falcon_imemt_r(u32 i) +{ + return 0x0010a188U + i*16U; +} +static inline u32 pwr_falcon_sctl_r(void) +{ + return 0x0010a240U; +} +static inline u32 pwr_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 pwr_falcon_bootvec_r(void) +{ + return 0x0010a104U; +} +static inline u32 pwr_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_falcon_dmactl_r(void) +{ + return 0x0010a10cU; +} +static inline u32 pwr_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 pwr_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_falcon_hwcfg_r(void) +{ + return 0x0010a108U; +} +static inline u32 pwr_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 pwr_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 pwr_falcon_dmatrfbase_r(void) +{ + return 0x0010a110U; +} +static inline u32 pwr_falcon_dmatrfbase1_r(void) +{ + return 0x0010a128U; +} +static inline u32 pwr_falcon_dmatrfmoffs_r(void) +{ + return 0x0010a114U; +} +static inline u32 pwr_falcon_dmatrfcmd_r(void) +{ + return 0x0010a118U; +} +static inline u32 pwr_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 pwr_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 pwr_falcon_dmatrffboffs_r(void) +{ + return 0x0010a11cU; +} +static inline u32 pwr_falcon_exterraddr_r(void) +{ + return 0x0010a168U; +} +static inline u32 pwr_falcon_exterrstat_r(void) +{ + return 0x0010a16cU; +} +static inline u32 pwr_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 pwr_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 pwr_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_r(void) +{ + return 0x0010a200U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 pwr_pmu_falcon_icd_rdata_r(void) +{ + return 0x0010a20cU; +} +static inline u32 pwr_falcon_dmemc_r(u32 i) +{ + return 0x0010a1c0U + i*8U; +} +static inline u32 pwr_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 pwr_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 pwr_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 pwr_falcon_dmemd_r(u32 i) +{ + return 0x0010a1c4U + i*8U; +} +static inline u32 pwr_pmu_new_instblk_r(void) +{ + return 0x0010a480U; +} +static inline u32 pwr_pmu_new_instblk_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 pwr_pmu_new_instblk_target_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 pwr_pmu_new_instblk_valid_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 pwr_pmu_mutex_id_r(void) +{ + return 0x0010a488U; +} +static inline u32 pwr_pmu_mutex_id_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_id_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_value_not_avail_v(void) +{ + return 0x000000ffU; +} +static inline u32 pwr_pmu_mutex_id_release_r(void) +{ + return 0x0010a48cU; +} +static inline u32 pwr_pmu_mutex_id_release_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_m(void) +{ + return 0xffU << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_mutex_r(u32 i) +{ + return 0x0010a580U + i*4U; +} +static inline u32 pwr_pmu_mutex__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 pwr_pmu_mutex_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_value_initial_lock_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_queue_head_r(u32 i) +{ + return 0x0010a800U + i*4U; +} +static inline u32 pwr_pmu_queue_head__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 pwr_pmu_queue_head_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_head_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_queue_tail_r(u32 i) +{ + return 0x0010a820U + i*4U; +} +static inline u32 pwr_pmu_queue_tail__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 pwr_pmu_queue_tail_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_tail_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_head_r(void) +{ + return 0x0010a4c8U; +} +static inline u32 pwr_pmu_msgq_head_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_head_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_tail_r(void) +{ + return 0x0010a4ccU; +} +static inline u32 pwr_pmu_msgq_tail_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_tail_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_idle_mask_r(u32 i) +{ + return 0x0010a504U + i*16U; +} +static inline u32 pwr_pmu_idle_mask_gr_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pwr_pmu_idle_mask_ce_2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 pwr_pmu_idle_count_r(u32 i) +{ + return 0x0010a508U + i*16U; +} +static inline u32 pwr_pmu_idle_count_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_count_value_v(u32 r) +{ + return (r >> 0U) & 0x7fffffffU; +} +static inline u32 pwr_pmu_idle_count_reset_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 pwr_pmu_idle_ctrl_r(u32 i) +{ + return 0x0010a50cU + i*16U; +} +static inline u32 pwr_pmu_idle_ctrl_value_m(void) +{ + return 0x3U << 0U; +} +static inline u32 pwr_pmu_idle_ctrl_value_busy_f(void) +{ + return 0x2U; +} +static inline u32 pwr_pmu_idle_ctrl_value_always_f(void) +{ + return 0x3U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_disabled_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_idle_threshold_r(u32 i) +{ + return 0x0010a8a0U + i*4U; +} +static inline u32 pwr_pmu_idle_threshold_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_intr_r(void) +{ + return 0x0010a9e8U; +} +static inline u32 pwr_pmu_idle_intr_en_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_en_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_idle_intr_en_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_r(void) +{ + return 0x0010a9ecU; +} +static inline u32 pwr_pmu_idle_intr_status_intr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_m(void) +{ + return U32(0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_mask_supp_r(u32 i) +{ + return 0x0010a9f0U + i*8U; +} +static inline u32 pwr_pmu_idle_mask_1_supp_r(u32 i) +{ + return 0x0010a9f4U + i*8U; +} +static inline u32 pwr_pmu_idle_ctrl_supp_r(u32 i) +{ + return 0x0010aa30U + i*8U; +} +static inline u32 pwr_pmu_debug_r(u32 i) +{ + return 0x0010a5c0U + i*4U; +} +static inline u32 pwr_pmu_debug__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_mailbox_r(u32 i) +{ + return 0x0010a450U + i*4U; +} +static inline u32 pwr_pmu_mailbox__size_1_v(void) +{ + return 0x0000000cU; +} +static inline u32 pwr_pmu_bar0_addr_r(void) +{ + return 0x0010a7a0U; +} +static inline u32 pwr_pmu_bar0_data_r(void) +{ + return 0x0010a7a4U; +} +static inline u32 pwr_pmu_bar0_ctl_r(void) +{ + return 0x0010a7acU; +} +static inline u32 pwr_pmu_bar0_timeout_r(void) +{ + return 0x0010a7a8U; +} +static inline u32 pwr_pmu_bar0_fecs_error_r(void) +{ + return 0x0010a988U; +} +static inline u32 pwr_pmu_bar0_error_status_r(void) +{ + return 0x0010a7b0U; +} +static inline u32 pwr_pmu_pg_idlefilth_r(u32 i) +{ + return 0x0010a6c0U + i*4U; +} +static inline u32 pwr_pmu_pg_ppuidlefilth_r(u32 i) +{ + return 0x0010a6e8U + i*4U; +} +static inline u32 pwr_pmu_pg_idle_cnt_r(u32 i) +{ + return 0x0010a710U + i*4U; +} +static inline u32 pwr_pmu_pg_intren_r(u32 i) +{ + return 0x0010a760U + i*4U; +} +static inline u32 pwr_fbif_transcfg_r(u32 i) +{ + return 0x0010ae00U + i*4U; +} +static inline u32 pwr_fbif_transcfg_target_local_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_target_coherent_sysmem_f(void) +{ + return 0x1U; +} +static inline u32 pwr_fbif_transcfg_target_noncoherent_sysmem_f(void) +{ + return 0x2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_s(void) +{ + return 1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_virtual_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_mem_type_physical_f(void) +{ + return 0x4U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_ram_gv100.h b/include/nvgpu/hw/gv100/hw_ram_gv100.h new file mode 100644 index 0000000..55aa25f --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_ram_gv100.h @@ -0,0 +1,791 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ram_gv100_h_ +#define _hw_ram_gv100_h_ + +static inline u32 ram_in_ramfc_s(void) +{ + return 4096U; +} +static inline u32 ram_in_ramfc_w(void) +{ + return 0U; +} +static inline u32 ram_in_page_dir_base_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ram_in_page_dir_base_target_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 ram_in_page_dir_base_vol_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_page_dir_base_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_m(void) +{ + return 0x1U << 4U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_true_f(void) +{ + return 0x10U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_m(void) +{ + return 0x1U << 5U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_true_f(void) +{ + return 0x20U; +} +static inline u32 ram_in_use_ver2_pt_format_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ram_in_use_ver2_pt_format_m(void) +{ + return 0x1U << 10U; +} +static inline u32 ram_in_use_ver2_pt_format_w(void) +{ + return 128U; +} +static inline u32 ram_in_use_ver2_pt_format_true_f(void) +{ + return 0x400U; +} +static inline u32 ram_in_use_ver2_pt_format_false_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_big_page_size_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 ram_in_big_page_size_m(void) +{ + return 0x1U << 11U; +} +static inline u32 ram_in_big_page_size_w(void) +{ + return 128U; +} +static inline u32 ram_in_big_page_size_128kb_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_big_page_size_64kb_f(void) +{ + return 0x800U; +} +static inline u32 ram_in_page_dir_base_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_page_dir_base_lo_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_hi_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_in_page_dir_base_hi_w(void) +{ + return 129U; +} +static inline u32 ram_in_engine_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_cs_wfi_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_engine_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_engine_cs_fg_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_engine_cs_fg_f(void) +{ + return 0x8U; +} +static inline u32 ram_in_engine_wfi_mode_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 ram_in_engine_wfi_mode_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_wfi_mode_physical_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_engine_wfi_mode_virtual_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_engine_wfi_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ram_in_engine_wfi_target_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_wfi_target_sys_mem_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 ram_in_engine_wfi_target_sys_mem_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 ram_in_engine_wfi_target_local_mem_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_engine_wfi_ptr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_engine_wfi_ptr_lo_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_wfi_ptr_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_engine_wfi_ptr_hi_w(void) +{ + return 133U; +} +static inline u32 ram_in_engine_wfi_veid_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 ram_in_engine_wfi_veid_w(void) +{ + return 134U; +} +static inline u32 ram_in_eng_method_buffer_addr_lo_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_in_eng_method_buffer_addr_lo_w(void) +{ + return 136U; +} +static inline u32 ram_in_eng_method_buffer_addr_hi_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ram_in_eng_method_buffer_addr_hi_w(void) +{ + return 137U; +} +static inline u32 ram_in_sc_page_dir_base_target_f(u32 v, u32 i) +{ + return (v & 0x3U) << (0U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_target__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_target_vid_mem_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_sc_page_dir_base_target_invalid_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_page_dir_base_target_sys_mem_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 ram_in_sc_page_dir_base_target_sys_mem_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 ram_in_sc_page_dir_base_vol_f(u32 v, u32 i) +{ + return (v & 0x1U) << (2U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_vol__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_vol_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_page_dir_base_vol_false_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex_f(u32 v, u32 i) +{ + return (v & 0x1U) << (4U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc_f(u32 v, u32 i) +{ + return (v & 0x1U) << (5U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_sc_use_ver2_pt_format_f(u32 v, u32 i) +{ + return (v & 0x1U) << (10U + i*0U); +} +static inline u32 ram_in_sc_use_ver2_pt_format__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_use_ver2_pt_format_false_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_sc_use_ver2_pt_format_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_big_page_size_f(u32 v, u32 i) +{ + return (v & 0x1U) << (11U + i*0U); +} +static inline u32 ram_in_sc_big_page_size__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_big_page_size_64kb_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_page_dir_base_lo_f(u32 v, u32 i) +{ + return (v & 0xfffffU) << (12U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_lo__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_hi_f(u32 v, u32 i) +{ + return (v & 0xffffffffU) << (0U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_hi__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_target_0_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ram_in_sc_page_dir_base_target_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_page_dir_base_vol_0_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 ram_in_sc_page_dir_base_vol_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex_0_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc_0_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_use_ver2_pt_format_0_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ram_in_sc_use_ver2_pt_format_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_big_page_size_0_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 ram_in_sc_big_page_size_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_page_dir_base_lo_0_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_sc_page_dir_base_lo_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_page_dir_base_hi_0_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_in_sc_page_dir_base_hi_0_w(void) +{ + return 169U; +} +static inline u32 ram_in_base_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 ram_in_alloc_size_v(void) +{ + return 0x00001000U; +} +static inline u32 ram_fc_size_val_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_fc_gp_put_w(void) +{ + return 0U; +} +static inline u32 ram_fc_userd_w(void) +{ + return 2U; +} +static inline u32 ram_fc_userd_hi_w(void) +{ + return 3U; +} +static inline u32 ram_fc_signature_w(void) +{ + return 4U; +} +static inline u32 ram_fc_gp_get_w(void) +{ + return 5U; +} +static inline u32 ram_fc_pb_get_w(void) +{ + return 6U; +} +static inline u32 ram_fc_pb_get_hi_w(void) +{ + return 7U; +} +static inline u32 ram_fc_pb_top_level_get_w(void) +{ + return 8U; +} +static inline u32 ram_fc_pb_top_level_get_hi_w(void) +{ + return 9U; +} +static inline u32 ram_fc_acquire_w(void) +{ + return 12U; +} +static inline u32 ram_fc_sem_addr_hi_w(void) +{ + return 14U; +} +static inline u32 ram_fc_sem_addr_lo_w(void) +{ + return 15U; +} +static inline u32 ram_fc_sem_payload_lo_w(void) +{ + return 16U; +} +static inline u32 ram_fc_sem_payload_hi_w(void) +{ + return 39U; +} +static inline u32 ram_fc_sem_execute_w(void) +{ + return 17U; +} +static inline u32 ram_fc_gp_base_w(void) +{ + return 18U; +} +static inline u32 ram_fc_gp_base_hi_w(void) +{ + return 19U; +} +static inline u32 ram_fc_gp_fetch_w(void) +{ + return 20U; +} +static inline u32 ram_fc_pb_fetch_w(void) +{ + return 21U; +} +static inline u32 ram_fc_pb_fetch_hi_w(void) +{ + return 22U; +} +static inline u32 ram_fc_pb_put_w(void) +{ + return 23U; +} +static inline u32 ram_fc_pb_put_hi_w(void) +{ + return 24U; +} +static inline u32 ram_fc_pb_header_w(void) +{ + return 33U; +} +static inline u32 ram_fc_pb_count_w(void) +{ + return 34U; +} +static inline u32 ram_fc_subdevice_w(void) +{ + return 37U; +} +static inline u32 ram_fc_target_w(void) +{ + return 43U; +} +static inline u32 ram_fc_hce_ctrl_w(void) +{ + return 57U; +} +static inline u32 ram_fc_chid_w(void) +{ + return 58U; +} +static inline u32 ram_fc_chid_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_fc_chid_id_w(void) +{ + return 0U; +} +static inline u32 ram_fc_config_w(void) +{ + return 61U; +} +static inline u32 ram_fc_runlist_timeslice_w(void) +{ + return 62U; +} +static inline u32 ram_fc_set_channel_info_w(void) +{ + return 63U; +} +static inline u32 ram_userd_base_shift_v(void) +{ + return 0x00000009U; +} +static inline u32 ram_userd_chan_size_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_userd_put_w(void) +{ + return 16U; +} +static inline u32 ram_userd_get_w(void) +{ + return 17U; +} +static inline u32 ram_userd_ref_w(void) +{ + return 18U; +} +static inline u32 ram_userd_put_hi_w(void) +{ + return 19U; +} +static inline u32 ram_userd_ref_threshold_w(void) +{ + return 20U; +} +static inline u32 ram_userd_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_userd_get_hi_w(void) +{ + return 24U; +} +static inline u32 ram_userd_gp_get_w(void) +{ + return 34U; +} +static inline u32 ram_userd_gp_put_w(void) +{ + return 35U; +} +static inline u32 ram_userd_gp_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_gp_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_rl_entry_size_v(void) +{ + return 0x00000010U; +} +static inline u32 ram_rl_entry_type_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ram_rl_entry_type_channel_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_rl_entry_type_tsg_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_rl_entry_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_chan_runqueue_selector_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 ram_rl_entry_chan_inst_target_f(u32 v) +{ + return (v & 0x3U) << 4U; +} +static inline u32 ram_rl_entry_chan_inst_target_sys_mem_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 ram_rl_entry_chan_inst_target_sys_mem_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 ram_rl_entry_chan_inst_target_vid_mem_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_rl_entry_chan_userd_target_f(u32 v) +{ + return (v & 0x3U) << 6U; +} +static inline u32 ram_rl_entry_chan_userd_target_vid_mem_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_rl_entry_chan_userd_target_vid_mem_nvlink_coh_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_rl_entry_chan_userd_target_sys_mem_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 ram_rl_entry_chan_userd_target_sys_mem_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 ram_rl_entry_chan_userd_ptr_lo_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 ram_rl_entry_chan_userd_ptr_hi_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_rl_entry_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_chan_inst_ptr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_rl_entry_chan_inst_ptr_hi_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_rl_entry_tsg_timeslice_scale_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 ram_rl_entry_tsg_timeslice_scale_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ram_rl_entry_tsg_timeslice_timeout_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 ram_rl_entry_tsg_timeslice_timeout_128_v(void) +{ + return 0x00000080U; +} +static inline u32 ram_rl_entry_tsg_length_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_rl_entry_tsg_length_init_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_rl_entry_tsg_length_min_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_rl_entry_tsg_length_max_v(void) +{ + return 0x00000080U; +} +static inline u32 ram_rl_entry_tsg_tsgid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_chan_userd_ptr_align_shift_v(void) +{ + return 0x00000008U; +} +static inline u32 ram_rl_entry_chan_userd_align_shift_v(void) +{ + return 0x00000008U; +} +static inline u32 ram_rl_entry_chan_inst_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_therm_gv100.h b/include/nvgpu/hw/gv100/hw_therm_gv100.h new file mode 100644 index 0000000..2ea71ef --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_therm_gv100.h @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_therm_gv100_h_ +#define _hw_therm_gv100_h_ + +static inline u32 therm_weight_1_r(void) +{ + return 0x00020024U; +} +static inline u32 therm_config1_r(void) +{ + return 0x00020050U; +} +static inline u32 therm_config2_r(void) +{ + return 0x00020130U; +} +static inline u32 therm_config2_slowdown_factor_extended_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 therm_config2_grad_enable_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 therm_gate_ctrl_r(u32 i) +{ + return 0x00020200U + i*4U; +} +static inline u32 therm_gate_ctrl_eng_clk_m(void) +{ + return 0x3U << 0U; +} +static inline u32 therm_gate_ctrl_eng_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_eng_clk_auto_f(void) +{ + return 0x1U; +} +static inline u32 therm_gate_ctrl_eng_clk_stop_f(void) +{ + return 0x2U; +} +static inline u32 therm_gate_ctrl_blk_clk_m(void) +{ + return 0x3U << 2U; +} +static inline u32 therm_gate_ctrl_blk_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_blk_clk_auto_f(void) +{ + return 0x4U; +} +static inline u32 therm_gate_ctrl_idle_holdoff_m(void) +{ + return 0x1U << 4U; +} +static inline u32 therm_gate_ctrl_idle_holdoff_off_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_idle_holdoff_on_f(void) +{ + return 0x10U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_m(void) +{ + return 0x1fU << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_f(u32 v) +{ + return (v & 0x7U) << 13U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_m(void) +{ + return 0x7U << 13U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_m(void) +{ + return 0xfU << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_m(void) +{ + return 0xfU << 20U; +} +static inline u32 therm_fecs_idle_filter_r(void) +{ + return 0x00020288U; +} +static inline u32 therm_fecs_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_hubmmu_idle_filter_r(void) +{ + return 0x0002028cU; +} +static inline u32 therm_hubmmu_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_clk_slowdown_r(u32 i) +{ + return 0x00020160U + i*4U; +} +static inline u32 therm_clk_slowdown_idle_factor_f(u32 v) +{ + return (v & 0x3fU) << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_m(void) +{ + return 0x3fU << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_v(u32 r) +{ + return (r >> 16U) & 0x3fU; +} +static inline u32 therm_clk_slowdown_idle_factor_disabled_f(void) +{ + return 0x0U; +} +static inline u32 therm_grad_stepping_table_r(u32 i) +{ + return 0x000202c8U + i*4U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by1p5_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by2_f(void) +{ + return 0x2U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by4_f(void) +{ + return 0x6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f(void) +{ + return 0xeU; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_f(u32 v) +{ + return (v & 0x3fU) << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_m(void) +{ + return 0x3fU << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_f(u32 v) +{ + return (v & 0x3fU) << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_m(void) +{ + return 0x3fU << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_m(void) +{ + return 0x3fU << 24U; +} +static inline u32 therm_grad_stepping0_r(void) +{ + return 0x000202c0U; +} +static inline u32 therm_grad_stepping0_feature_s(void) +{ + return 1U; +} +static inline u32 therm_grad_stepping0_feature_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 therm_grad_stepping0_feature_m(void) +{ + return 0x1U << 0U; +} +static inline u32 therm_grad_stepping0_feature_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 therm_grad_stepping0_feature_enable_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping1_r(void) +{ + return 0x000202c4U; +} +static inline u32 therm_grad_stepping1_pdiv_duration_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 therm_clk_timing_r(u32 i) +{ + return 0x000203c0U + i*4U; +} +static inline u32 therm_clk_timing_grad_slowdown_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_m(void) +{ + return 0x1U << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_enabled_f(void) +{ + return 0x10000U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_timer_gv100.h b/include/nvgpu/hw/gv100/hw_timer_gv100.h new file mode 100644 index 0000000..9d76e24 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_timer_gv100.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_timer_gv100_h_ +#define _hw_timer_gv100_h_ + +static inline u32 timer_pri_timeout_r(void) +{ + return 0x00009080U; +} +static inline u32 timer_pri_timeout_period_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 timer_pri_timeout_period_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 timer_pri_timeout_period_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 timer_pri_timeout_en_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 timer_pri_timeout_en_m(void) +{ + return 0x1U << 31U; +} +static inline u32 timer_pri_timeout_en_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_en_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 timer_pri_timeout_en_en_disabled_f(void) +{ + return 0x0U; +} +static inline u32 timer_pri_timeout_save_0_r(void) +{ + return 0x00009084U; +} +static inline u32 timer_pri_timeout_save_1_r(void) +{ + return 0x00009088U; +} +static inline u32 timer_pri_timeout_fecs_errcode_r(void) +{ + return 0x0000908cU; +} +static inline u32 timer_time_0_r(void) +{ + return 0x00009400U; +} +static inline u32 timer_time_1_r(void) +{ + return 0x00009410U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_top_gv100.h b/include/nvgpu/hw/gv100/hw_top_gv100.h new file mode 100644 index 0000000..506a818 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_top_gv100.h @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_top_gv100_h_ +#define _hw_top_gv100_h_ + +static inline u32 top_num_gpcs_r(void) +{ + return 0x00022430U; +} +static inline u32 top_num_gpcs_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_tpc_per_gpc_r(void) +{ + return 0x00022434U; +} +static inline u32 top_tpc_per_gpc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_fbps_r(void) +{ + return 0x00022438U; +} +static inline u32 top_num_fbps_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_fbpas_r(void) +{ + return 0x0002243cU; +} +static inline u32 top_num_fbpas_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_ltc_per_fbp_r(void) +{ + return 0x00022450U; +} +static inline u32 top_ltc_per_fbp_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_slices_per_ltc_r(void) +{ + return 0x0002245cU; +} +static inline u32 top_slices_per_ltc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_ltcs_r(void) +{ + return 0x00022454U; +} +static inline u32 top_num_ces_r(void) +{ + return 0x00022444U; +} +static inline u32 top_num_ces_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_device_info_r(u32 i) +{ + return 0x00022700U + i*4U; +} +static inline u32 top_device_info__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 top_device_info_chain_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 top_device_info_chain_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_engine_enum_v(u32 r) +{ + return (r >> 26U) & 0xfU; +} +static inline u32 top_device_info_runlist_enum_v(u32 r) +{ + return (r >> 21U) & 0xfU; +} +static inline u32 top_device_info_intr_enum_v(u32 r) +{ + return (r >> 15U) & 0x1fU; +} +static inline u32 top_device_info_reset_enum_v(u32 r) +{ + return (r >> 9U) & 0x1fU; +} +static inline u32 top_device_info_type_enum_v(u32 r) +{ + return (r >> 2U) & 0x1fffffffU; +} +static inline u32 top_device_info_type_enum_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_type_enum_graphics_f(void) +{ + return 0x0U; +} +static inline u32 top_device_info_type_enum_copy2_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_type_enum_copy2_f(void) +{ + return 0xcU; +} +static inline u32 top_device_info_type_enum_lce_v(void) +{ + return 0x00000013U; +} +static inline u32 top_device_info_type_enum_lce_f(void) +{ + return 0x4cU; +} +static inline u32 top_device_info_type_enum_ioctrl_v(void) +{ + return 0x00000012U; +} +static inline u32 top_device_info_type_enum_ioctrl_f(void) +{ + return 0x48U; +} +static inline u32 top_device_info_engine_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 top_device_info_runlist_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 top_device_info_intr_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 top_device_info_reset_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_entry_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 top_device_info_entry_not_valid_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_entry_enum_v(void) +{ + return 0x00000002U; +} +static inline u32 top_device_info_entry_data_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_entry_engine_type_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_data_type_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 top_device_info_data_type_enum2_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_data_inst_id_v(u32 r) +{ + return (r >> 26U) & 0xfU; +} +static inline u32 top_device_info_data_pri_base_v(u32 r) +{ + return (r >> 12U) & 0xfffU; +} +static inline u32 top_device_info_data_pri_base_align_v(void) +{ + return 0x0000000cU; +} +static inline u32 top_device_info_data_fault_id_enum_v(u32 r) +{ + return (r >> 3U) & 0x7fU; +} +static inline u32 top_device_info_data_fault_id_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_data_fault_id_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 top_nvhsclk_ctrl_r(void) +{ + return 0x00022424U; +} +static inline u32 top_nvhsclk_ctrl_e_clk_nvl_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 top_nvhsclk_ctrl_e_clk_nvl_m(void) +{ + return 0x7U << 0U; +} +static inline u32 top_nvhsclk_ctrl_e_clk_nvl_v(u32 r) +{ + return (r >> 0U) & 0x7U; +} +static inline u32 top_nvhsclk_ctrl_e_clk_pcie_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 top_nvhsclk_ctrl_e_clk_pcie_m(void) +{ + return 0x1U << 3U; +} +static inline u32 top_nvhsclk_ctrl_e_clk_pcie_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 top_nvhsclk_ctrl_e_clk_core_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 top_nvhsclk_ctrl_e_clk_core_m(void) +{ + return 0x1U << 4U; +} +static inline u32 top_nvhsclk_ctrl_e_clk_core_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 top_nvhsclk_ctrl_rfu_f(u32 v) +{ + return (v & 0xfU) << 5U; +} +static inline u32 top_nvhsclk_ctrl_rfu_m(void) +{ + return 0xfU << 5U; +} +static inline u32 top_nvhsclk_ctrl_rfu_v(u32 r) +{ + return (r >> 5U) & 0xfU; +} +static inline u32 top_nvhsclk_ctrl_swap_clk_nvl_f(u32 v) +{ + return (v & 0x7U) << 10U; +} +static inline u32 top_nvhsclk_ctrl_swap_clk_nvl_m(void) +{ + return 0x7U << 10U; +} +static inline u32 top_nvhsclk_ctrl_swap_clk_nvl_v(u32 r) +{ + return (r >> 10U) & 0x7U; +} +static inline u32 top_nvhsclk_ctrl_swap_clk_pcie_f(u32 v) +{ + return (v & 0x1U) << 9U; +} +static inline u32 top_nvhsclk_ctrl_swap_clk_pcie_m(void) +{ + return 0x1U << 9U; +} +static inline u32 top_nvhsclk_ctrl_swap_clk_pcie_v(u32 r) +{ + return (r >> 9U) & 0x1U; +} +static inline u32 top_nvhsclk_ctrl_swap_clk_core_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 top_nvhsclk_ctrl_swap_clk_core_m(void) +{ + return 0x1U << 13U; +} +static inline u32 top_nvhsclk_ctrl_swap_clk_core_v(u32 r) +{ + return (r >> 13U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_trim_gv100.h b/include/nvgpu/hw/gv100/hw_trim_gv100.h new file mode 100644 index 0000000..f1b6da2 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_trim_gv100.h @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_trim_gv100_h_ +#define _hw_trim_gv100_h_ + +static inline u32 trim_sys_nvlink_uphy_cfg_r(void) +{ + return 0x00132410U; +} +static inline u32 trim_sys_nvlink_uphy_cfg_lockdect_wait_dly_length_f(u32 v) +{ + return (v & 0x3ffU) << 0U; +} +static inline u32 trim_sys_nvlink_uphy_cfg_lockdect_wait_dly_length_m(void) +{ + return 0x3ffU << 0U; +} +static inline u32 trim_sys_nvlink_uphy_cfg_lockdect_wait_dly_length_v(u32 r) +{ + return (r >> 0U) & 0x3ffU; +} +static inline u32 trim_sys_nvlink_uphy_cfg_phy2clks_use_lockdet_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 trim_sys_nvlink_uphy_cfg_phy2clks_use_lockdet_m(void) +{ + return 0x1U << 12U; +} +static inline u32 trim_sys_nvlink_uphy_cfg_phy2clks_use_lockdet_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 trim_sys_nvlink_uphy_cfg_nvlink_wait_dly_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 trim_sys_nvlink_uphy_cfg_nvlink_wait_dly_m(void) +{ + return 0xffU << 16U; +} +static inline u32 trim_sys_nvlink_uphy_cfg_nvlink_wait_dly_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 trim_sys_nvlink0_ctrl_r(void) +{ + return 0x00132420U; +} +static inline u32 trim_sys_nvlink0_ctrl_unit2clks_pll_turn_off_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 trim_sys_nvlink0_ctrl_unit2clks_pll_turn_off_m(void) +{ + return 0x1U << 0U; +} +static inline u32 trim_sys_nvlink0_ctrl_unit2clks_pll_turn_off_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 trim_sys_nvlink0_status_r(void) +{ + return 0x00132424U; +} +static inline u32 trim_sys_nvlink0_status_pll_off_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 trim_sys_nvlink0_status_pll_off_m(void) +{ + return 0x1U << 5U; +} +static inline u32 trim_sys_nvlink0_status_pll_off_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_r(void) +{ + return 0x001371c4U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_slowclk_f(u32 v) +{ + return (v & 0x3U) << 16U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_slowclk_m(void) +{ + return 0x3U << 16U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_slowclk_v(u32 r) +{ + return (r >> 16U) & 0x3U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_slowclk_xtal4x_v(void) +{ + return 0x00000003U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_slowclk_xtal4x_f(void) +{ + return 0x30000U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_slowclk_xtal_in_v(void) +{ + return 0x00000000U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_slowclk_xtal_in_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_finalsel_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_finalsel_m(void) +{ + return 0x3U << 0U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_finalsel_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_finalsel_slowclk_v(void) +{ + return 0x00000000U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_finalsel_slowclk_f(void) +{ + return 0x0U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_finalsel_miscclk_v(void) +{ + return 0x00000002U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_finalsel_miscclk_f(void) +{ + return 0x2U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_finalsel_onesrcclk_v(void) +{ + return 0x00000003U; +} +static inline u32 trim_sys_nvl_common_clk_alt_switch_finalsel_onesrcclk_f(void) +{ + return 0x3U; +} +static inline u32 trim_gpc_bcast_fr_clk_cntr_ncgpcclk_cfg_r(void) +{ + return 0x00132a70U; +} +static inline u32 trim_gpc_bcast_fr_clk_cntr_ncgpcclk_cfg_source_gpcclk_f(void) +{ + return 0x10000000U; +} +static inline u32 trim_gpc_bcast_fr_clk_cntr_ncgpcclk_cnt0_r(void) +{ + return 0x00132a74U; +} +static inline u32 trim_gpc_bcast_fr_clk_cntr_ncgpcclk_cnt1_r(void) +{ + return 0x00132a78U; +} +static inline u32 trim_sys_nafll_fr_clk_cntr_xbarclk_cfg_r(void) +{ + return 0x00136470U; +} +static inline u32 trim_sys_nafll_fr_clk_cntr_xbarclk_cfg_source_xbarclk_f(void) +{ + return 0x10000000U; +} +static inline u32 trim_sys_nafll_fr_clk_cntr_xbarclk_cntr0_r(void) +{ + return 0x00136474U; +} +static inline u32 trim_sys_nafll_fr_clk_cntr_xbarclk_cntr1_r(void) +{ + return 0x00136478U; +} +static inline u32 trim_sys_fr_clk_cntr_sysclk_cfg_r(void) +{ + return 0x0013762cU; +} +static inline u32 trim_sys_fr_clk_cntr_sysclk_cfg_source_sysclk_f(void) +{ + return 0x20000000U; +} +static inline u32 trim_sys_fr_clk_cntr_sysclk_cntr0_r(void) +{ + return 0x00137630U; +} +static inline u32 trim_sys_fr_clk_cntr_sysclk_cntr1_r(void) +{ + return 0x00137634U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_usermode_gv100.h b/include/nvgpu/hw/gv100/hw_usermode_gv100.h new file mode 100644 index 0000000..7b1d861 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_usermode_gv100.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_usermode_gv100_h_ +#define _hw_usermode_gv100_h_ + +static inline u32 usermode_cfg0_r(void) +{ + return 0x00810000U; +} +static inline u32 usermode_cfg0_class_id_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 usermode_cfg0_class_id_value_v(void) +{ + return 0x0000c361U; +} +static inline u32 usermode_time_0_r(void) +{ + return 0x00810080U; +} +static inline u32 usermode_time_0_nsec_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 usermode_time_1_r(void) +{ + return 0x00810084U; +} +static inline u32 usermode_time_1_nsec_f(u32 v) +{ + return (v & 0x1fffffffU) << 0U; +} +static inline u32 usermode_notify_channel_pending_r(void) +{ + return 0x00810090U; +} +static inline u32 usermode_notify_channel_pending_id_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_xp_gv100.h b/include/nvgpu/hw/gv100/hw_xp_gv100.h new file mode 100644 index 0000000..4296e04 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_xp_gv100.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_xp_gv100_h_ +#define _hw_xp_gv100_h_ + +static inline u32 xp_dl_mgr_r(u32 i) +{ + return 0x0008b8c0U + i*4U; +} +static inline u32 xp_dl_mgr_safe_timing_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 xp_pl_link_config_r(u32 i) +{ + return 0x0008c040U + i*4U; +} +static inline u32 xp_pl_link_config_ltssm_status_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 xp_pl_link_config_ltssm_status_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 xp_pl_link_config_ltssm_directive_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 xp_pl_link_config_ltssm_directive_m(void) +{ + return 0xfU << 0U; +} +static inline u32 xp_pl_link_config_ltssm_directive_normal_operations_v(void) +{ + return 0x00000000U; +} +static inline u32 xp_pl_link_config_ltssm_directive_change_speed_v(void) +{ + return 0x00000001U; +} +static inline u32 xp_pl_link_config_max_link_rate_f(u32 v) +{ + return (v & 0x3U) << 18U; +} +static inline u32 xp_pl_link_config_max_link_rate_m(void) +{ + return 0x3U << 18U; +} +static inline u32 xp_pl_link_config_max_link_rate_2500_mtps_v(void) +{ + return 0x00000002U; +} +static inline u32 xp_pl_link_config_max_link_rate_5000_mtps_v(void) +{ + return 0x00000001U; +} +static inline u32 xp_pl_link_config_max_link_rate_8000_mtps_v(void) +{ + return 0x00000000U; +} +static inline u32 xp_pl_link_config_target_tx_width_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 xp_pl_link_config_target_tx_width_m(void) +{ + return 0x7U << 20U; +} +static inline u32 xp_pl_link_config_target_tx_width_x1_v(void) +{ + return 0x00000007U; +} +static inline u32 xp_pl_link_config_target_tx_width_x2_v(void) +{ + return 0x00000006U; +} +static inline u32 xp_pl_link_config_target_tx_width_x4_v(void) +{ + return 0x00000005U; +} +static inline u32 xp_pl_link_config_target_tx_width_x8_v(void) +{ + return 0x00000004U; +} +static inline u32 xp_pl_link_config_target_tx_width_x16_v(void) +{ + return 0x00000000U; +} +#endif diff --git a/include/nvgpu/hw/gv100/hw_xve_gv100.h b/include/nvgpu/hw/gv100/hw_xve_gv100.h new file mode 100644 index 0000000..fc7aa72 --- /dev/null +++ b/include/nvgpu/hw/gv100/hw_xve_gv100.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_xve_gv100_h_ +#define _hw_xve_gv100_h_ + +static inline u32 xve_rom_ctrl_r(void) +{ + return 0x00000050U; +} +static inline u32 xve_rom_ctrl_rom_shadow_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 xve_rom_ctrl_rom_shadow_disabled_f(void) +{ + return 0x0U; +} +static inline u32 xve_rom_ctrl_rom_shadow_enabled_f(void) +{ + return 0x1U; +} +static inline u32 xve_link_control_status_r(void) +{ + return 0x00000088U; +} +static inline u32 xve_link_control_status_link_speed_m(void) +{ + return 0xfU << 16U; +} +static inline u32 xve_link_control_status_link_speed_v(u32 r) +{ + return (r >> 16U) & 0xfU; +} +static inline u32 xve_link_control_status_link_speed_link_speed_2p5_v(void) +{ + return 0x00000001U; +} +static inline u32 xve_link_control_status_link_speed_link_speed_5p0_v(void) +{ + return 0x00000002U; +} +static inline u32 xve_link_control_status_link_speed_link_speed_8p0_v(void) +{ + return 0x00000003U; +} +static inline u32 xve_link_control_status_link_width_m(void) +{ + return 0x3fU << 20U; +} +static inline u32 xve_link_control_status_link_width_v(u32 r) +{ + return (r >> 20U) & 0x3fU; +} +static inline u32 xve_link_control_status_link_width_x1_v(void) +{ + return 0x00000001U; +} +static inline u32 xve_link_control_status_link_width_x2_v(void) +{ + return 0x00000002U; +} +static inline u32 xve_link_control_status_link_width_x4_v(void) +{ + return 0x00000004U; +} +static inline u32 xve_link_control_status_link_width_x8_v(void) +{ + return 0x00000008U; +} +static inline u32 xve_link_control_status_link_width_x16_v(void) +{ + return 0x00000010U; +} +static inline u32 xve_priv_xv_r(void) +{ + return 0x00000150U; +} +static inline u32 xve_priv_xv_cya_l0s_enable_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 xve_priv_xv_cya_l0s_enable_m(void) +{ + return 0x1U << 7U; +} +static inline u32 xve_priv_xv_cya_l0s_enable_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 xve_priv_xv_cya_l1_enable_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 xve_priv_xv_cya_l1_enable_m(void) +{ + return 0x1U << 8U; +} +static inline u32 xve_priv_xv_cya_l1_enable_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 xve_cya_2_r(void) +{ + return 0x00000704U; +} +static inline u32 xve_reset_r(void) +{ + return 0x00000718U; +} +static inline u32 xve_reset_reset_m(void) +{ + return 0x1U << 0U; +} +static inline u32 xve_reset_gpu_on_sw_reset_m(void) +{ + return 0x1U << 1U; +} +static inline u32 xve_reset_counter_en_m(void) +{ + return 0x1U << 2U; +} +static inline u32 xve_reset_counter_val_f(u32 v) +{ + return (v & 0x7ffU) << 4U; +} +static inline u32 xve_reset_counter_val_m(void) +{ + return 0x7ffU << 4U; +} +static inline u32 xve_reset_counter_val_v(u32 r) +{ + return (r >> 4U) & 0x7ffU; +} +static inline u32 xve_reset_clock_on_sw_reset_m(void) +{ + return 0x1U << 15U; +} +static inline u32 xve_reset_clock_counter_en_m(void) +{ + return 0x1U << 16U; +} +static inline u32 xve_reset_clock_counter_val_f(u32 v) +{ + return (v & 0x7ffU) << 17U; +} +static inline u32 xve_reset_clock_counter_val_m(void) +{ + return 0x7ffU << 17U; +} +static inline u32 xve_reset_clock_counter_val_v(u32 r) +{ + return (r >> 17U) & 0x7ffU; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_bus_gv11b.h b/include/nvgpu/hw/gv11b/hw_bus_gv11b.h new file mode 100644 index 0000000..d1d9b34 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_bus_gv11b.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_bus_gv11b_h_ +#define _hw_bus_gv11b_h_ + +static inline u32 bus_bar0_window_r(void) +{ + return 0x00001700U; +} +static inline u32 bus_bar0_window_base_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 bus_bar0_window_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar0_window_target_sys_mem_coherent_f(void) +{ + return 0x2000000U; +} +static inline u32 bus_bar0_window_target_sys_mem_noncoherent_f(void) +{ + return 0x3000000U; +} +static inline u32 bus_bar0_window_target_bar0_window_base_shift_v(void) +{ + return 0x00000010U; +} +static inline u32 bus_bar1_block_r(void) +{ + return 0x00001704U; +} +static inline u32 bus_bar1_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar1_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar1_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar1_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar1_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar2_block_r(void) +{ + return 0x00001714U; +} +static inline u32 bus_bar2_block_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 bus_bar2_block_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 bus_bar2_block_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 bus_bar2_block_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 bus_bar2_block_mode_virtual_f(void) +{ + return 0x80000000U; +} +static inline u32 bus_bar1_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bar2_block_ptr_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 bus_bind_status_r(void) +{ + return 0x00001710U; +} +static inline u32 bus_bind_status_bar1_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 bus_bind_status_bar1_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar1_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 bus_bind_status_bar1_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 bus_bind_status_bar1_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar1_outstanding_true_f(void) +{ + return 0x2U; +} +static inline u32 bus_bind_status_bar2_pending_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 bus_bind_status_bar2_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar2_pending_busy_f(void) +{ + return 0x4U; +} +static inline u32 bus_bind_status_bar2_outstanding_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 bus_bind_status_bar2_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 bus_bind_status_bar2_outstanding_true_f(void) +{ + return 0x8U; +} +static inline u32 bus_intr_0_r(void) +{ + return 0x00001100U; +} +static inline u32 bus_intr_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +static inline u32 bus_intr_en_0_r(void) +{ + return 0x00001140U; +} +static inline u32 bus_intr_en_0_pri_squash_m(void) +{ + return 0x1U << 1U; +} +static inline u32 bus_intr_en_0_pri_fecserr_m(void) +{ + return 0x1U << 2U; +} +static inline u32 bus_intr_en_0_pri_timeout_m(void) +{ + return 0x1U << 3U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_ccsr_gv11b.h b/include/nvgpu/hw/gv11b/hw_ccsr_gv11b.h new file mode 100644 index 0000000..e21a473 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_ccsr_gv11b.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ccsr_gv11b_h_ +#define _hw_ccsr_gv11b_h_ + +static inline u32 ccsr_channel_inst_r(u32 i) +{ + return 0x00800000U + i*8U; +} +static inline u32 ccsr_channel_inst__size_1_v(void) +{ + return 0x00000200U; +} +static inline u32 ccsr_channel_inst_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 ccsr_channel_inst_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 ccsr_channel_inst_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 ccsr_channel_inst_bind_false_f(void) +{ + return 0x0U; +} +static inline u32 ccsr_channel_inst_bind_true_f(void) +{ + return 0x80000000U; +} +static inline u32 ccsr_channel_r(u32 i) +{ + return 0x00800004U + i*8U; +} +static inline u32 ccsr_channel__size_1_v(void) +{ + return 0x00000200U; +} +static inline u32 ccsr_channel_enable_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ccsr_channel_enable_set_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ccsr_channel_enable_set_true_f(void) +{ + return 0x400U; +} +static inline u32 ccsr_channel_enable_clr_true_f(void) +{ + return 0x800U; +} +static inline u32 ccsr_channel_status_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ccsr_channel_status_pending_ctx_reload_v(void) +{ + return 0x00000002U; +} +static inline u32 ccsr_channel_status_pending_acq_ctx_reload_v(void) +{ + return 0x00000004U; +} +static inline u32 ccsr_channel_status_on_pbdma_ctx_reload_v(void) +{ + return 0x0000000aU; +} +static inline u32 ccsr_channel_status_on_pbdma_and_eng_ctx_reload_v(void) +{ + return 0x0000000bU; +} +static inline u32 ccsr_channel_status_on_eng_ctx_reload_v(void) +{ + return 0x0000000cU; +} +static inline u32 ccsr_channel_status_on_eng_pending_ctx_reload_v(void) +{ + return 0x0000000dU; +} +static inline u32 ccsr_channel_status_on_eng_pending_acq_ctx_reload_v(void) +{ + return 0x0000000eU; +} +static inline u32 ccsr_channel_next_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 ccsr_channel_next_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ccsr_channel_force_ctx_reload_true_f(void) +{ + return 0x100U; +} +static inline u32 ccsr_channel_pbdma_faulted_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 ccsr_channel_pbdma_faulted_reset_f(void) +{ + return 0x400000U; +} +static inline u32 ccsr_channel_eng_faulted_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 ccsr_channel_eng_faulted_v(u32 r) +{ + return (r >> 23U) & 0x1U; +} +static inline u32 ccsr_channel_eng_faulted_reset_f(void) +{ + return 0x800000U; +} +static inline u32 ccsr_channel_eng_faulted_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ccsr_channel_busy_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_ce_gv11b.h b/include/nvgpu/hw/gv11b/hw_ce_gv11b.h new file mode 100644 index 0000000..57a76e6 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_ce_gv11b.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016-2019, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ce_gv11b_h_ +#define _hw_ce_gv11b_h_ + +static inline u32 ce_intr_status_r(u32 i) +{ + return 0x00104410U + i*128U; +} +static inline u32 ce_intr_status_blockpipe_pending_f(void) +{ + return 0x1U; +} +static inline u32 ce_intr_status_blockpipe_reset_f(void) +{ + return 0x1U; +} +static inline u32 ce_intr_status_nonblockpipe_pending_f(void) +{ + return 0x2U; +} +static inline u32 ce_intr_status_nonblockpipe_reset_f(void) +{ + return 0x2U; +} +static inline u32 ce_intr_status_launcherr_pending_f(void) +{ + return 0x4U; +} +static inline u32 ce_intr_status_launcherr_reset_f(void) +{ + return 0x4U; +} +static inline u32 ce_intr_status_invalid_config_pending_f(void) +{ + return 0x8U; +} +static inline u32 ce_intr_status_invalid_config_reset_f(void) +{ + return 0x8U; +} +static inline u32 ce_intr_status_mthd_buffer_fault_pending_f(void) +{ + return 0x10U; +} +static inline u32 ce_intr_status_mthd_buffer_fault_reset_f(void) +{ + return 0x10U; +} +static inline u32 ce_pce_map_r(void) +{ + return 0x00104028U; +} +static inline u32 ce_lce_opt_r(u32 i) +{ + return 0x00104414U + i*128U; +} +static inline u32 ce_lce_opt_force_barriers_npl__prod_f(void) +{ + return 0x8U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_ctxsw_prog_gv11b.h b/include/nvgpu/hw/gv11b/hw_ctxsw_prog_gv11b.h new file mode 100644 index 0000000..8b095b1 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_ctxsw_prog_gv11b.h @@ -0,0 +1,463 @@ +/* + * 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ctxsw_prog_gv11b_h_ +#define _hw_ctxsw_prog_gv11b_h_ + +static inline u32 ctxsw_prog_fecs_header_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_main_image_num_gpcs_o(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_main_image_ctl_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_main_image_ctl_type_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_undefined_v(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_opengl_v(void) +{ + return 0x00000008U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_dx9_v(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_dx10_v(void) +{ + return 0x00000011U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_dx11_v(void) +{ + return 0x00000012U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_compute_v(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_main_image_ctl_type_per_veid_header_v(void) +{ + return 0x00000021U; +} +static inline u32 ctxsw_prog_main_image_patch_count_o(void) +{ + return 0x00000010U; +} +static inline u32 ctxsw_prog_main_image_context_id_o(void) +{ + return 0x000000f0U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_lo_o(void) +{ + return 0x00000014U; +} +static inline u32 ctxsw_prog_main_image_patch_adr_hi_o(void) +{ + return 0x00000018U; +} +static inline u32 ctxsw_prog_main_image_zcull_o(void) +{ + return 0x0000001cU; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_no_ctxsw_v(void) +{ + return 0x00000001U; +} +static inline u32 ctxsw_prog_main_image_zcull_mode_separate_buffer_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_zcull_ptr_o(void) +{ + return 0x00000020U; +} +static inline u32 ctxsw_prog_main_image_pm_o(void) +{ + return 0x00000028U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_m(void) +{ + return 0x7U << 0U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_ctxsw_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_mode_stream_out_ctxsw_f(void) +{ + return 0x2U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_m(void) +{ + return 0x7U << 3U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_ctxsw_f(void) +{ + return 0x8U; +} +static inline u32 ctxsw_prog_main_image_pm_smpc_mode_no_ctxsw_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_pm_ptr_o(void) +{ + return 0x0000002cU; +} +static inline u32 ctxsw_prog_main_image_num_save_ops_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_main_image_num_wfi_save_ops_o(void) +{ + return 0x000000d0U; +} +static inline u32 ctxsw_prog_main_image_num_cta_save_ops_o(void) +{ + return 0x000000d4U; +} +static inline u32 ctxsw_prog_main_image_num_gfxp_save_ops_o(void) +{ + return 0x000000d8U; +} +static inline u32 ctxsw_prog_main_image_num_cilp_save_ops_o(void) +{ + return 0x000000dcU; +} +static inline u32 ctxsw_prog_main_image_num_restore_ops_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_main_image_zcull_ptr_hi_o(void) +{ + return 0x00000060U; +} +static inline u32 ctxsw_prog_main_image_zcull_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_pm_ptr_hi_o(void) +{ + return 0x00000094U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_hi_o(void) +{ + return 0x00000064U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_o(void) +{ + return 0x00000068U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_veid0_hi_o(void) +{ + return 0x00000070U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_veid0_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_veid0_o(void) +{ + return 0x00000074U; +} +static inline u32 ctxsw_prog_main_image_full_preemption_ptr_veid0_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_buffer_ptr_hi_o(void) +{ + return 0x00000078U; +} +static inline u32 ctxsw_prog_main_image_context_buffer_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_buffer_ptr_o(void) +{ + return 0x0000007cU; +} +static inline u32 ctxsw_prog_main_image_context_buffer_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_main_image_magic_value_v_value_v(void) +{ + return 0x600dc0deU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_o(void) +{ + return 0x0000000cU; +} +static inline u32 ctxsw_prog_local_priv_register_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_main_image_global_cb_ptr_o(void) +{ + return 0x000000b8U; +} +static inline u32 ctxsw_prog_main_image_global_cb_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_global_cb_ptr_hi_o(void) +{ + return 0x000000bcU; +} +static inline u32 ctxsw_prog_main_image_global_cb_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_global_pagepool_ptr_o(void) +{ + return 0x000000c0U; +} +static inline u32 ctxsw_prog_main_image_global_pagepool_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_global_pagepool_ptr_hi_o(void) +{ + return 0x000000c4U; +} +static inline u32 ctxsw_prog_main_image_global_pagepool_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_control_block_ptr_o(void) +{ + return 0x000000c8U; +} +static inline u32 ctxsw_prog_main_image_control_block_ptr_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_control_block_ptr_hi_o(void) +{ + return 0x000000ccU; +} +static inline u32 ctxsw_prog_main_image_control_block_ptr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_ramchain_buffer_addr_lo_o(void) +{ + return 0x000000e0U; +} +static inline u32 ctxsw_prog_main_image_context_ramchain_buffer_addr_lo_v_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ctxsw_prog_main_image_context_ramchain_buffer_addr_hi_o(void) +{ + return 0x000000e4U; +} +static inline u32 ctxsw_prog_main_image_context_ramchain_buffer_addr_hi_v_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ctxsw_prog_local_image_ppc_info_o(void) +{ + return 0x000000f4U; +} +static inline u32 ctxsw_prog_local_image_ppc_info_num_ppcs_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_ppc_info_ppc_mask_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 ctxsw_prog_local_image_num_tpcs_o(void) +{ + return 0x000000f8U; +} +static inline u32 ctxsw_prog_local_magic_value_o(void) +{ + return 0x000000fcU; +} +static inline u32 ctxsw_prog_local_magic_value_v_value_v(void) +{ + return 0xad0becabU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_o(void) +{ + return 0x000000ecU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_offset_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ctxsw_prog_main_extended_buffer_ctl_size_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 ctxsw_prog_extended_buffer_segments_size_in_bytes_v(void) +{ + return 0x00000100U; +} +static inline u32 ctxsw_prog_extended_marker_size_in_bytes_v(void) +{ + return 0x00000004U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_register_stride_v(void) +{ + return 0x00000000U; +} +static inline u32 ctxsw_prog_extended_sm_dsm_perf_counter_control_register_stride_v(void) +{ + return 0x00000002U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_o(void) +{ + return 0x000000a0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_s(void) +{ + return 2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_m(void) +{ + return 0x3U << 0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_allow_all_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_config_mode_use_map_f(void) +{ + return 0x2U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_lo_o(void) +{ + return 0x000000a4U; +} +static inline u32 ctxsw_prog_main_image_priv_access_map_addr_hi_o(void) +{ + return 0x000000a8U; +} +static inline u32 ctxsw_prog_main_image_misc_options_o(void) +{ + return 0x0000003cU; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ctxsw_prog_main_image_misc_options_verif_features_disabled_f(void) +{ + return 0x0U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_o(void) +{ + return 0x00000080U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_control_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_graphics_preemption_options_control_gfxp_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_o(void) +{ + return 0x00000084U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_cta_f(void) +{ + return 0x1U; +} +static inline u32 ctxsw_prog_main_image_compute_preemption_options_control_cilp_f(void) +{ + return 0x2U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_falcon_gv11b.h b/include/nvgpu/hw/gv11b/hw_falcon_gv11b.h new file mode 100644 index 0000000..31e883e --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_falcon_gv11b.h @@ -0,0 +1,603 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_falcon_gv11b_h_ +#define _hw_falcon_gv11b_h_ + +static inline u32 falcon_falcon_irqsset_r(void) +{ + return 0x00000000U; +} +static inline u32 falcon_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqsclr_r(void) +{ + return 0x00000004U; +} +static inline u32 falcon_falcon_irqstat_r(void) +{ + return 0x00000008U; +} +static inline u32 falcon_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 falcon_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 falcon_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 falcon_falcon_irqmode_r(void) +{ + return 0x0000000cU; +} +static inline u32 falcon_falcon_irqmset_r(void) +{ + return 0x00000010U; +} +static inline u32 falcon_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_r(void) +{ + return 0x00000014U; +} +static inline u32 falcon_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqmask_r(void) +{ + return 0x00000018U; +} +static inline u32 falcon_falcon_irqdest_r(void) +{ + return 0x0000001cU; +} +static inline u32 falcon_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 falcon_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 falcon_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 falcon_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 falcon_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 falcon_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 falcon_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 falcon_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 falcon_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 falcon_falcon_curctx_r(void) +{ + return 0x00000050U; +} +static inline u32 falcon_falcon_nxtctx_r(void) +{ + return 0x00000054U; +} +static inline u32 falcon_falcon_mailbox0_r(void) +{ + return 0x00000040U; +} +static inline u32 falcon_falcon_mailbox1_r(void) +{ + return 0x00000044U; +} +static inline u32 falcon_falcon_itfen_r(void) +{ + return 0x00000048U; +} +static inline u32 falcon_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 falcon_falcon_idlestate_r(void) +{ + return 0x0000004cU; +} +static inline u32 falcon_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 falcon_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 falcon_falcon_os_r(void) +{ + return 0x00000080U; +} +static inline u32 falcon_falcon_engctl_r(void) +{ + return 0x000000a4U; +} +static inline u32 falcon_falcon_cpuctl_r(void) +{ + return 0x00000100U; +} +static inline u32 falcon_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_cpuctl_sreset_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 falcon_falcon_cpuctl_hreset_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 falcon_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_stopped_m(void) +{ + return 0x1U << 5U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 falcon_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 falcon_falcon_cpuctl_alias_r(void) +{ + return 0x00000130U; +} +static inline u32 falcon_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 falcon_falcon_imemc_r(u32 i) +{ + return 0x00000180U + i*16U; +} +static inline u32 falcon_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_imemc_secure_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 falcon_falcon_imemd_r(u32 i) +{ + return 0x00000184U + i*16U; +} +static inline u32 falcon_falcon_imemt_r(u32 i) +{ + return 0x00000188U + i*16U; +} +static inline u32 falcon_falcon_sctl_r(void) +{ + return 0x00000240U; +} +static inline u32 falcon_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 falcon_falcon_bootvec_r(void) +{ + return 0x00000104U; +} +static inline u32 falcon_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 falcon_falcon_dmactl_r(void) +{ + return 0x0000010cU; +} +static inline u32 falcon_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 falcon_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 falcon_falcon_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 falcon_falcon_hwcfg_r(void) +{ + return 0x00000108U; +} +static inline u32 falcon_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 falcon_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 falcon_falcon_dmatrfbase_r(void) +{ + return 0x00000110U; +} +static inline u32 falcon_falcon_dmatrfbase1_r(void) +{ + return 0x00000128U; +} +static inline u32 falcon_falcon_dmatrfmoffs_r(void) +{ + return 0x00000114U; +} +static inline u32 falcon_falcon_dmatrfcmd_r(void) +{ + return 0x00000118U; +} +static inline u32 falcon_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 falcon_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 falcon_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 falcon_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 falcon_falcon_dmatrffboffs_r(void) +{ + return 0x0000011cU; +} +static inline u32 falcon_falcon_imctl_debug_r(void) +{ + return 0x0000015cU; +} +static inline u32 falcon_falcon_imctl_debug_addr_blk_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 falcon_falcon_imctl_debug_cmd_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 falcon_falcon_imstat_r(void) +{ + return 0x00000144U; +} +static inline u32 falcon_falcon_traceidx_r(void) +{ + return 0x00000148U; +} +static inline u32 falcon_falcon_traceidx_maxidx_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 falcon_falcon_traceidx_idx_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 falcon_falcon_tracepc_r(void) +{ + return 0x0000014cU; +} +static inline u32 falcon_falcon_tracepc_pc_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 falcon_falcon_exterraddr_r(void) +{ + return 0x00000168U; +} +static inline u32 falcon_falcon_exterrstat_r(void) +{ + return 0x0000016cU; +} +static inline u32 falcon_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 falcon_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 falcon_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 falcon_falcon_icd_cmd_r(void) +{ + return 0x00000200U; +} +static inline u32 falcon_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 falcon_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 falcon_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 falcon_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 falcon_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 falcon_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 falcon_falcon_icd_rdata_r(void) +{ + return 0x0000020cU; +} +static inline u32 falcon_falcon_dmemc_r(u32 i) +{ + return 0x000001c0U + i*8U; +} +static inline u32 falcon_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 falcon_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 falcon_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 falcon_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 falcon_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 falcon_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 falcon_falcon_dmemd_r(u32 i) +{ + return 0x000001c4U + i*8U; +} +static inline u32 falcon_falcon_debug1_r(void) +{ + return 0x00000090U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_s(void) +{ + return 1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_m(void) +{ + return 0x1U << 16U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 falcon_falcon_debug1_ctxsw_mode_init_f(void) +{ + return 0x0U; +} +static inline u32 falcon_falcon_debuginfo_r(void) +{ + return 0x00000094U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_fb_gv11b.h b/include/nvgpu/hw/gv11b/hw_fb_gv11b.h new file mode 100644 index 0000000..767fc5a --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_fb_gv11b.h @@ -0,0 +1,1867 @@ +/* + * 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fb_gv11b_h_ +#define _hw_fb_gv11b_h_ + +static inline u32 fb_fbhub_num_active_ltcs_r(void) +{ + return 0x00100800U; +} +static inline u32 fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_m(void) +{ + return 0x1U << 25U; +} +static inline u32 fb_fbhub_num_active_ltcs_hub_sys_atomic_mode_use_rmw_f(void) +{ + return 0x2000000U; +} +static inline u32 fb_fbhub_num_active_ltcs_hub_sys_ncoh_atomic_mode_m(void) +{ + return 0x1U << 26U; +} +static inline u32 fb_fbhub_num_active_ltcs_hub_sys_ncoh_atomic_mode_use_read_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_r(void) +{ + return 0x00100c80U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_empty_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_pri_fifo_space_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_m(void) +{ + return 0x3U << 24U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_l2_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_mode_rmw_f(void) +{ + return 0x2000000U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_sys_ncoh_mode_m(void) +{ + return 0x1U << 27U; +} +static inline u32 fb_mmu_ctrl_atomic_capability_sys_ncoh_mode_l2_f(void) +{ + return 0x0U; +} +static inline u32 fb_hshub_num_active_ltcs_r(void) +{ + return 0x001fbc20U; +} +static inline u32 fb_hshub_num_active_ltcs_hub_sys_atomic_mode_m(void) +{ + return 0x1U << 25U; +} +static inline u32 fb_hshub_num_active_ltcs_hub_sys_atomic_mode_use_read_f(void) +{ + return 0x0U; +} +static inline u32 fb_hshub_num_active_ltcs_hub_sys_atomic_mode_use_rmw_f(void) +{ + return 0x2000000U; +} +static inline u32 fb_priv_mmu_phy_secure_r(void) +{ + return 0x00100ce4U; +} +static inline u32 fb_mmu_invalidate_pdb_r(void) +{ + return 0x00100cb8U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_pdb_aperture_sys_mem_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_pdb_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_invalidate_r(void) +{ + return 0x00100cbcU; +} +static inline u32 fb_mmu_invalidate_all_va_true_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_invalidate_all_pdb_true_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_m(void) +{ + return 0x1U << 2U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_hubtlb_only_true_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_invalidate_replay_s(void) +{ + return 3U; +} +static inline u32 fb_mmu_invalidate_replay_f(u32 v) +{ + return (v & 0x7U) << 3U; +} +static inline u32 fb_mmu_invalidate_replay_m(void) +{ + return 0x7U << 3U; +} +static inline u32 fb_mmu_invalidate_replay_v(u32 r) +{ + return (r >> 3U) & 0x7U; +} +static inline u32 fb_mmu_invalidate_replay_none_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_replay_start_f(void) +{ + return 0x8U; +} +static inline u32 fb_mmu_invalidate_replay_start_ack_all_f(void) +{ + return 0x10U; +} +static inline u32 fb_mmu_invalidate_replay_cancel_global_f(void) +{ + return 0x20U; +} +static inline u32 fb_mmu_invalidate_sys_membar_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_sys_membar_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 fb_mmu_invalidate_sys_membar_m(void) +{ + return 0x1U << 6U; +} +static inline u32 fb_mmu_invalidate_sys_membar_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_sys_membar_true_f(void) +{ + return 0x40U; +} +static inline u32 fb_mmu_invalidate_ack_s(void) +{ + return 2U; +} +static inline u32 fb_mmu_invalidate_ack_f(u32 v) +{ + return (v & 0x3U) << 7U; +} +static inline u32 fb_mmu_invalidate_ack_m(void) +{ + return 0x3U << 7U; +} +static inline u32 fb_mmu_invalidate_ack_v(u32 r) +{ + return (r >> 7U) & 0x3U; +} +static inline u32 fb_mmu_invalidate_ack_ack_none_required_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_ack_ack_intranode_f(void) +{ + return 0x100U; +} +static inline u32 fb_mmu_invalidate_ack_ack_globally_f(void) +{ + return 0x80U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_s(void) +{ + return 6U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_f(u32 v) +{ + return (v & 0x3fU) << 9U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_m(void) +{ + return 0x3fU << 9U; +} +static inline u32 fb_mmu_invalidate_cancel_client_id_v(u32 r) +{ + return (r >> 9U) & 0x3fU; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_s(void) +{ + return 5U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_f(u32 v) +{ + return (v & 0x1fU) << 15U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_m(void) +{ + return 0x1fU << 15U; +} +static inline u32 fb_mmu_invalidate_cancel_gpc_id_v(u32 r) +{ + return (r >> 15U) & 0x1fU; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_m(void) +{ + return 0x1U << 20U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_gpc_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_cancel_client_type_hub_f(void) +{ + return 0x100000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_s(void) +{ + return 3U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_m(void) +{ + return 0x7U << 24U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_v(u32 r) +{ + return (r >> 24U) & 0x7U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_all_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_pte_only_f(void) +{ + return 0x1000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde0_f(void) +{ + return 0x2000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde1_f(void) +{ + return 0x3000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde2_f(void) +{ + return 0x4000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde3_f(void) +{ + return 0x5000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde4_f(void) +{ + return 0x6000000U; +} +static inline u32 fb_mmu_invalidate_cancel_cache_level_up_to_pde5_f(void) +{ + return 0x7000000U; +} +static inline u32 fb_mmu_invalidate_trigger_s(void) +{ + return 1U; +} +static inline u32 fb_mmu_invalidate_trigger_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_invalidate_trigger_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_invalidate_trigger_true_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_debug_wr_r(void) +{ + return 0x00100cc8U; +} +static inline u32 fb_mmu_debug_wr_aperture_s(void) +{ + return 2U; +} +static inline u32 fb_mmu_debug_wr_aperture_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_m(void) +{ + return 0x3U << 0U; +} +static inline u32 fb_mmu_debug_wr_aperture_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fb_mmu_debug_wr_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_wr_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_wr_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_wr_vol_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_wr_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_debug_wr_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_wr_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_rd_r(void) +{ + return 0x00100cccU; +} +static inline u32 fb_mmu_debug_rd_aperture_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_debug_rd_aperture_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_debug_rd_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_debug_rd_addr_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 fb_mmu_debug_rd_addr_alignment_v(void) +{ + return 0x0000000cU; +} +static inline u32 fb_mmu_debug_ctrl_r(void) +{ + return 0x00100cc4U; +} +static inline u32 fb_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 fb_mmu_debug_ctrl_debug_m(void) +{ + return 0x1U << 16U; +} +static inline u32 fb_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_debug_ctrl_debug_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_vpr_info_r(void) +{ + return 0x00100cd0U; +} +static inline u32 fb_mmu_vpr_info_fetch_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 fb_mmu_vpr_info_fetch_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_vpr_info_fetch_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_l2tlb_ecc_status_r(void) +{ + return 0x00100e70U; +} +static inline u32 fb_mmu_l2tlb_ecc_status_corrected_err_l2tlb_sa_data_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fb_mmu_l2tlb_ecc_status_uncorrected_err_l2tlb_sa_data_m(void) +{ + return 0x1U << 1U; +} +static inline u32 fb_mmu_l2tlb_ecc_status_corrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 16U; +} +static inline u32 fb_mmu_l2tlb_ecc_status_uncorrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 18U; +} +static inline u32 fb_mmu_l2tlb_ecc_status_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_mmu_l2tlb_ecc_status_reset_clear_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_mmu_l2tlb_ecc_corrected_err_count_r(void) +{ + return 0x00100e74U; +} +static inline u32 fb_mmu_l2tlb_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 fb_mmu_l2tlb_ecc_corrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fb_mmu_l2tlb_ecc_corrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fb_mmu_l2tlb_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fb_mmu_l2tlb_ecc_uncorrected_err_count_r(void) +{ + return 0x00100e78U; +} +static inline u32 fb_mmu_l2tlb_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 fb_mmu_l2tlb_ecc_uncorrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fb_mmu_l2tlb_ecc_uncorrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fb_mmu_l2tlb_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fb_mmu_l2tlb_ecc_address_r(void) +{ + return 0x00100e7cU; +} +static inline u32 fb_mmu_l2tlb_ecc_address_index_s(void) +{ + return 32U; +} +static inline u32 fb_mmu_l2tlb_ecc_address_index_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 fb_mmu_l2tlb_ecc_address_index_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 fb_mmu_l2tlb_ecc_address_index_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 fb_mmu_hubtlb_ecc_status_r(void) +{ + return 0x00100e84U; +} +static inline u32 fb_mmu_hubtlb_ecc_status_corrected_err_sa_data_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fb_mmu_hubtlb_ecc_status_uncorrected_err_sa_data_m(void) +{ + return 0x1U << 1U; +} +static inline u32 fb_mmu_hubtlb_ecc_status_corrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 16U; +} +static inline u32 fb_mmu_hubtlb_ecc_status_uncorrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 18U; +} +static inline u32 fb_mmu_hubtlb_ecc_status_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_mmu_hubtlb_ecc_status_reset_clear_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_mmu_hubtlb_ecc_corrected_err_count_r(void) +{ + return 0x00100e88U; +} +static inline u32 fb_mmu_hubtlb_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 fb_mmu_hubtlb_ecc_corrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fb_mmu_hubtlb_ecc_corrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fb_mmu_hubtlb_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fb_mmu_hubtlb_ecc_uncorrected_err_count_r(void) +{ + return 0x00100e8cU; +} +static inline u32 fb_mmu_hubtlb_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 fb_mmu_hubtlb_ecc_uncorrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fb_mmu_hubtlb_ecc_uncorrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fb_mmu_hubtlb_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fb_mmu_hubtlb_ecc_address_r(void) +{ + return 0x00100e90U; +} +static inline u32 fb_mmu_hubtlb_ecc_address_index_s(void) +{ + return 32U; +} +static inline u32 fb_mmu_hubtlb_ecc_address_index_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 fb_mmu_hubtlb_ecc_address_index_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 fb_mmu_hubtlb_ecc_address_index_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 fb_mmu_fillunit_ecc_status_r(void) +{ + return 0x00100e98U; +} +static inline u32 fb_mmu_fillunit_ecc_status_corrected_err_pte_data_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fb_mmu_fillunit_ecc_status_uncorrected_err_pte_data_m(void) +{ + return 0x1U << 1U; +} +static inline u32 fb_mmu_fillunit_ecc_status_corrected_err_pde0_data_m(void) +{ + return 0x1U << 2U; +} +static inline u32 fb_mmu_fillunit_ecc_status_uncorrected_err_pde0_data_m(void) +{ + return 0x1U << 3U; +} +static inline u32 fb_mmu_fillunit_ecc_status_corrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 16U; +} +static inline u32 fb_mmu_fillunit_ecc_status_uncorrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 18U; +} +static inline u32 fb_mmu_fillunit_ecc_status_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_mmu_fillunit_ecc_status_reset_clear_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_mmu_fillunit_ecc_corrected_err_count_r(void) +{ + return 0x00100e9cU; +} +static inline u32 fb_mmu_fillunit_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 fb_mmu_fillunit_ecc_corrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fb_mmu_fillunit_ecc_corrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fb_mmu_fillunit_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fb_mmu_fillunit_ecc_uncorrected_err_count_r(void) +{ + return 0x00100ea0U; +} +static inline u32 fb_mmu_fillunit_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 fb_mmu_fillunit_ecc_uncorrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fb_mmu_fillunit_ecc_uncorrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fb_mmu_fillunit_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fb_mmu_fillunit_ecc_address_r(void) +{ + return 0x00100ea4U; +} +static inline u32 fb_mmu_fillunit_ecc_address_index_s(void) +{ + return 32U; +} +static inline u32 fb_mmu_fillunit_ecc_address_index_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 fb_mmu_fillunit_ecc_address_index_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 fb_mmu_fillunit_ecc_address_index_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 fb_niso_flush_sysmem_addr_r(void) +{ + return 0x00100c10U; +} +static inline u32 fb_niso_intr_r(void) +{ + return 0x00100a20U; +} +static inline u32 fb_niso_intr_hub_access_counter_notify_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fb_niso_intr_hub_access_counter_notify_pending_f(void) +{ + return 0x1U; +} +static inline u32 fb_niso_intr_hub_access_counter_error_m(void) +{ + return 0x1U << 1U; +} +static inline u32 fb_niso_intr_hub_access_counter_error_pending_f(void) +{ + return 0x2U; +} +static inline u32 fb_niso_intr_mmu_replayable_fault_notify_m(void) +{ + return 0x1U << 27U; +} +static inline u32 fb_niso_intr_mmu_replayable_fault_notify_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 fb_niso_intr_mmu_replayable_fault_overflow_m(void) +{ + return 0x1U << 28U; +} +static inline u32 fb_niso_intr_mmu_replayable_fault_overflow_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 fb_niso_intr_mmu_nonreplayable_fault_notify_m(void) +{ + return 0x1U << 29U; +} +static inline u32 fb_niso_intr_mmu_nonreplayable_fault_notify_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 fb_niso_intr_mmu_nonreplayable_fault_overflow_m(void) +{ + return 0x1U << 30U; +} +static inline u32 fb_niso_intr_mmu_nonreplayable_fault_overflow_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_niso_intr_mmu_other_fault_notify_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_niso_intr_mmu_other_fault_notify_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_niso_intr_mmu_ecc_uncorrected_error_notify_m(void) +{ + return 0x1U << 26U; +} +static inline u32 fb_niso_intr_mmu_ecc_uncorrected_error_notify_pending_f(void) +{ + return 0x4000000U; +} +static inline u32 fb_niso_intr_en_r(u32 i) +{ + return 0x00100a24U + i*4U; +} +static inline u32 fb_niso_intr_en__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_niso_intr_en_hub_access_counter_notify_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fb_niso_intr_en_hub_access_counter_notify_enabled_f(void) +{ + return 0x1U; +} +static inline u32 fb_niso_intr_en_hub_access_counter_error_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 fb_niso_intr_en_hub_access_counter_error_enabled_f(void) +{ + return 0x2U; +} +static inline u32 fb_niso_intr_en_mmu_replayable_fault_notify_f(u32 v) +{ + return (v & 0x1U) << 27U; +} +static inline u32 fb_niso_intr_en_mmu_replayable_fault_notify_enabled_f(void) +{ + return 0x8000000U; +} +static inline u32 fb_niso_intr_en_mmu_replayable_fault_overflow_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 fb_niso_intr_en_mmu_replayable_fault_overflow_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 fb_niso_intr_en_mmu_nonreplayable_fault_notify_f(u32 v) +{ + return (v & 0x1U) << 29U; +} +static inline u32 fb_niso_intr_en_mmu_nonreplayable_fault_notify_enabled_f(void) +{ + return 0x20000000U; +} +static inline u32 fb_niso_intr_en_mmu_nonreplayable_fault_overflow_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_niso_intr_en_mmu_nonreplayable_fault_overflow_enabled_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_niso_intr_en_mmu_other_fault_notify_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_niso_intr_en_mmu_other_fault_notify_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_niso_intr_en_mmu_ecc_uncorrected_error_notify_f(u32 v) +{ + return (v & 0x1U) << 26U; +} +static inline u32 fb_niso_intr_en_mmu_ecc_uncorrected_error_notify_enabled_f(void) +{ + return 0x4000000U; +} +static inline u32 fb_niso_intr_en_set_r(u32 i) +{ + return 0x00100a2cU + i*4U; +} +static inline u32 fb_niso_intr_en_set__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_niso_intr_en_set_hub_access_counter_notify_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fb_niso_intr_en_set_hub_access_counter_notify_set_f(void) +{ + return 0x1U; +} +static inline u32 fb_niso_intr_en_set_hub_access_counter_error_m(void) +{ + return 0x1U << 1U; +} +static inline u32 fb_niso_intr_en_set_hub_access_counter_error_set_f(void) +{ + return 0x2U; +} +static inline u32 fb_niso_intr_en_set_mmu_replayable_fault_notify_m(void) +{ + return 0x1U << 27U; +} +static inline u32 fb_niso_intr_en_set_mmu_replayable_fault_notify_set_f(void) +{ + return 0x8000000U; +} +static inline u32 fb_niso_intr_en_set_mmu_replayable_fault_overflow_m(void) +{ + return 0x1U << 28U; +} +static inline u32 fb_niso_intr_en_set_mmu_replayable_fault_overflow_set_f(void) +{ + return 0x10000000U; +} +static inline u32 fb_niso_intr_en_set_mmu_nonreplayable_fault_notify_m(void) +{ + return 0x1U << 29U; +} +static inline u32 fb_niso_intr_en_set_mmu_nonreplayable_fault_notify_set_f(void) +{ + return 0x20000000U; +} +static inline u32 fb_niso_intr_en_set_mmu_nonreplayable_fault_overflow_m(void) +{ + return 0x1U << 30U; +} +static inline u32 fb_niso_intr_en_set_mmu_nonreplayable_fault_overflow_set_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_niso_intr_en_set_mmu_other_fault_notify_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_niso_intr_en_set_mmu_other_fault_notify_set_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_niso_intr_en_set_mmu_ecc_uncorrected_error_notify_m(void) +{ + return 0x1U << 26U; +} +static inline u32 fb_niso_intr_en_set_mmu_ecc_uncorrected_error_notify_set_f(void) +{ + return 0x4000000U; +} +static inline u32 fb_niso_intr_en_clr_r(u32 i) +{ + return 0x00100a34U + i*4U; +} +static inline u32 fb_niso_intr_en_clr__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_niso_intr_en_clr_hub_access_counter_notify_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fb_niso_intr_en_clr_hub_access_counter_notify_set_f(void) +{ + return 0x1U; +} +static inline u32 fb_niso_intr_en_clr_hub_access_counter_error_m(void) +{ + return 0x1U << 1U; +} +static inline u32 fb_niso_intr_en_clr_hub_access_counter_error_set_f(void) +{ + return 0x2U; +} +static inline u32 fb_niso_intr_en_clr_mmu_replayable_fault_notify_m(void) +{ + return 0x1U << 27U; +} +static inline u32 fb_niso_intr_en_clr_mmu_replayable_fault_notify_set_f(void) +{ + return 0x8000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_replayable_fault_overflow_m(void) +{ + return 0x1U << 28U; +} +static inline u32 fb_niso_intr_en_clr_mmu_replayable_fault_overflow_set_f(void) +{ + return 0x10000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_nonreplayable_fault_notify_m(void) +{ + return 0x1U << 29U; +} +static inline u32 fb_niso_intr_en_clr_mmu_nonreplayable_fault_notify_set_f(void) +{ + return 0x20000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_nonreplayable_fault_overflow_m(void) +{ + return 0x1U << 30U; +} +static inline u32 fb_niso_intr_en_clr_mmu_nonreplayable_fault_overflow_set_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_other_fault_notify_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_niso_intr_en_clr_mmu_other_fault_notify_set_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_ecc_uncorrected_error_notify_m(void) +{ + return 0x1U << 26U; +} +static inline u32 fb_niso_intr_en_clr_mmu_ecc_uncorrected_error_notify_set_f(void) +{ + return 0x4000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_non_replay_fault_buffer_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_niso_intr_en_clr_mmu_replay_fault_buffer_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_lo_r(u32 i) +{ + return 0x00100e24U + i*20U; +} +static inline u32 fb_mmu_fault_buffer_lo__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_virtual_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_virtual_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_physical_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_mode_physical_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_f(u32 v) +{ + return (v & 0x3U) << 1U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_v(u32 r) +{ + return (r >> 1U) & 0x3U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_sys_coh_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_sys_nocoh_v(void) +{ + return 0x00000003U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_aperture_sys_nocoh_f(void) +{ + return 0x6U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_vol_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 fb_mmu_fault_buffer_lo_phys_vol_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_buffer_lo_addr_b(void) +{ + return 12U; +} +static inline u32 fb_mmu_fault_buffer_hi_r(u32 i) +{ + return 0x00100e28U + i*20U; +} +static inline u32 fb_mmu_fault_buffer_hi__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_hi_addr_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 fb_mmu_fault_buffer_hi_addr_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 fb_mmu_fault_buffer_get_r(u32 i) +{ + return 0x00100e2cU + i*20U; +} +static inline u32 fb_mmu_fault_buffer_get__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_get_ptr_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 fb_mmu_fault_buffer_get_ptr_m(void) +{ + return 0xfffffU << 0U; +} +static inline u32 fb_mmu_fault_buffer_get_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_buffer_get_getptr_corrupted_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_mmu_fault_buffer_get_getptr_corrupted_m(void) +{ + return 0x1U << 30U; +} +static inline u32 fb_mmu_fault_buffer_get_getptr_corrupted_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_get_getptr_corrupted_clear_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_mmu_fault_buffer_get_overflow_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_fault_buffer_get_overflow_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_fault_buffer_get_overflow_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_get_overflow_clear_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_fault_buffer_put_r(u32 i) +{ + return 0x00100e30U + i*20U; +} +static inline u32 fb_mmu_fault_buffer_put__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_put_ptr_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 fb_mmu_fault_buffer_put_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_yes_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_yes_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_no_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_fault_buffer_put_getptr_corrupted_no_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_buffer_put_overflow_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_fault_buffer_put_overflow_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_put_overflow_yes_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_put_overflow_yes_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_fault_buffer_size_r(u32 i) +{ + return 0x00100e34U + i*20U; +} +static inline u32 fb_mmu_fault_buffer_size__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_buffer_size_val_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 fb_mmu_fault_buffer_size_val_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_buffer_size_overflow_intr_f(u32 v) +{ + return (v & 0x1U) << 29U; +} +static inline u32 fb_mmu_fault_buffer_size_overflow_intr_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_size_overflow_intr_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_size_overflow_intr_enable_f(void) +{ + return 0x20000000U; +} +static inline u32 fb_mmu_fault_buffer_size_set_default_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_mmu_fault_buffer_size_set_default_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_size_set_default_yes_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_size_set_default_yes_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_mmu_fault_buffer_size_enable_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_fault_buffer_size_enable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_fault_buffer_size_enable_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_fault_buffer_size_enable_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_buffer_size_enable_true_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_fault_addr_lo_r(void) +{ + return 0x00100e4cU; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_sys_coh_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_sys_nocoh_v(void) +{ + return 0x00000003U; +} +static inline u32 fb_mmu_fault_addr_lo_phys_aperture_sys_nocoh_f(void) +{ + return 0x3U; +} +static inline u32 fb_mmu_fault_addr_lo_addr_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 fb_mmu_fault_addr_lo_addr_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_addr_lo_addr_b(void) +{ + return 12U; +} +static inline u32 fb_mmu_fault_addr_hi_r(void) +{ + return 0x00100e50U; +} +static inline u32 fb_mmu_fault_addr_hi_addr_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 fb_mmu_fault_addr_hi_addr_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 fb_mmu_fault_inst_lo_r(void) +{ + return 0x00100e54U; +} +static inline u32 fb_mmu_fault_inst_lo_engine_id_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 fb_mmu_fault_inst_lo_aperture_v(u32 r) +{ + return (r >> 10U) & 0x3U; +} +static inline u32 fb_mmu_fault_inst_lo_aperture_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 fb_mmu_fault_inst_lo_aperture_sys_nocoh_v(void) +{ + return 0x00000003U; +} +static inline u32 fb_mmu_fault_inst_lo_addr_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 fb_mmu_fault_inst_lo_addr_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 fb_mmu_fault_inst_lo_addr_b(void) +{ + return 12U; +} +static inline u32 fb_mmu_fault_inst_hi_r(void) +{ + return 0x00100e58U; +} +static inline u32 fb_mmu_fault_inst_hi_addr_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 fb_mmu_fault_info_r(void) +{ + return 0x00100e5cU; +} +static inline u32 fb_mmu_fault_info_fault_type_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 fb_mmu_fault_info_replayable_fault_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 fb_mmu_fault_info_client_v(u32 r) +{ + return (r >> 8U) & 0x7fU; +} +static inline u32 fb_mmu_fault_info_access_type_v(u32 r) +{ + return (r >> 16U) & 0xfU; +} +static inline u32 fb_mmu_fault_info_client_type_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 fb_mmu_fault_info_gpc_id_v(u32 r) +{ + return (r >> 24U) & 0x1fU; +} +static inline u32 fb_mmu_fault_info_protected_mode_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 fb_mmu_fault_info_replayable_fault_en_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fb_mmu_fault_info_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fb_mmu_fault_status_r(void) +{ + return 0x00100e60U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_phys_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_phys_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_phys_set_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_phys_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_phys_clear_f(void) +{ + return 0x1U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_virt_m(void) +{ + return 0x1U << 1U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_virt_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_virt_set_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_virt_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar1_virt_clear_f(void) +{ + return 0x2U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_phys_m(void) +{ + return 0x1U << 2U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_phys_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_phys_set_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_phys_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_phys_clear_f(void) +{ + return 0x4U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_virt_m(void) +{ + return 0x1U << 3U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_virt_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_virt_set_f(void) +{ + return 0x8U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_virt_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_bar2_virt_clear_f(void) +{ + return 0x8U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_phys_m(void) +{ + return 0x1U << 4U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_phys_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_phys_set_f(void) +{ + return 0x10U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_phys_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_phys_clear_f(void) +{ + return 0x10U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_virt_m(void) +{ + return 0x1U << 5U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_virt_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_virt_set_f(void) +{ + return 0x20U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_virt_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_ifb_virt_clear_f(void) +{ + return 0x20U; +} +static inline u32 fb_mmu_fault_status_dropped_other_phys_m(void) +{ + return 0x1U << 6U; +} +static inline u32 fb_mmu_fault_status_dropped_other_phys_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_other_phys_set_f(void) +{ + return 0x40U; +} +static inline u32 fb_mmu_fault_status_dropped_other_phys_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_other_phys_clear_f(void) +{ + return 0x40U; +} +static inline u32 fb_mmu_fault_status_dropped_other_virt_m(void) +{ + return 0x1U << 7U; +} +static inline u32 fb_mmu_fault_status_dropped_other_virt_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_other_virt_set_f(void) +{ + return 0x80U; +} +static inline u32 fb_mmu_fault_status_dropped_other_virt_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_dropped_other_virt_clear_f(void) +{ + return 0x80U; +} +static inline u32 fb_mmu_fault_status_replayable_m(void) +{ + return 0x1U << 8U; +} +static inline u32 fb_mmu_fault_status_replayable_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_replayable_set_f(void) +{ + return 0x100U; +} +static inline u32 fb_mmu_fault_status_replayable_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_non_replayable_m(void) +{ + return 0x1U << 9U; +} +static inline u32 fb_mmu_fault_status_non_replayable_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_non_replayable_set_f(void) +{ + return 0x200U; +} +static inline u32 fb_mmu_fault_status_non_replayable_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_replayable_error_m(void) +{ + return 0x1U << 10U; +} +static inline u32 fb_mmu_fault_status_replayable_error_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_replayable_error_set_f(void) +{ + return 0x400U; +} +static inline u32 fb_mmu_fault_status_replayable_error_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_non_replayable_error_m(void) +{ + return 0x1U << 11U; +} +static inline u32 fb_mmu_fault_status_non_replayable_error_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_non_replayable_error_set_f(void) +{ + return 0x800U; +} +static inline u32 fb_mmu_fault_status_non_replayable_error_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_replayable_overflow_m(void) +{ + return 0x1U << 12U; +} +static inline u32 fb_mmu_fault_status_replayable_overflow_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_replayable_overflow_set_f(void) +{ + return 0x1000U; +} +static inline u32 fb_mmu_fault_status_replayable_overflow_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_non_replayable_overflow_m(void) +{ + return 0x1U << 13U; +} +static inline u32 fb_mmu_fault_status_non_replayable_overflow_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_non_replayable_overflow_set_f(void) +{ + return 0x2000U; +} +static inline u32 fb_mmu_fault_status_non_replayable_overflow_reset_f(void) +{ + return 0x0U; +} +static inline u32 fb_mmu_fault_status_replayable_getptr_corrupted_m(void) +{ + return 0x1U << 14U; +} +static inline u32 fb_mmu_fault_status_replayable_getptr_corrupted_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_replayable_getptr_corrupted_set_f(void) +{ + return 0x4000U; +} +static inline u32 fb_mmu_fault_status_non_replayable_getptr_corrupted_m(void) +{ + return 0x1U << 15U; +} +static inline u32 fb_mmu_fault_status_non_replayable_getptr_corrupted_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_non_replayable_getptr_corrupted_set_f(void) +{ + return 0x8000U; +} +static inline u32 fb_mmu_fault_status_busy_m(void) +{ + return 0x1U << 30U; +} +static inline u32 fb_mmu_fault_status_busy_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_busy_true_f(void) +{ + return 0x40000000U; +} +static inline u32 fb_mmu_fault_status_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fb_mmu_fault_status_valid_set_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_valid_set_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_fault_status_valid_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_fault_status_valid_clear_f(void) +{ + return 0x80000000U; +} +static inline u32 fb_mmu_num_active_ltcs_r(void) +{ + return 0x00100ec0U; +} +static inline u32 fb_mmu_num_active_ltcs_count_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 fb_mmu_num_active_ltcs_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 fb_mmu_cbc_base_r(void) +{ + return 0x00100ec4U; +} +static inline u32 fb_mmu_cbc_base_address_f(u32 v) +{ + return (v & 0x3ffffffU) << 0U; +} +static inline u32 fb_mmu_cbc_base_address_v(u32 r) +{ + return (r >> 0U) & 0x3ffffffU; +} +static inline u32 fb_mmu_cbc_base_address_alignment_shift_v(void) +{ + return 0x0000000bU; +} +static inline u32 fb_mmu_cbc_top_r(void) +{ + return 0x00100ec8U; +} +static inline u32 fb_mmu_cbc_top_size_f(u32 v) +{ + return (v & 0x7fffU) << 0U; +} +static inline u32 fb_mmu_cbc_top_size_v(u32 r) +{ + return (r >> 0U) & 0x7fffU; +} +static inline u32 fb_mmu_cbc_top_size_alignment_shift_v(void) +{ + return 0x0000000bU; +} +static inline u32 fb_mmu_cbc_max_r(void) +{ + return 0x00100eccU; +} +static inline u32 fb_mmu_cbc_max_comptagline_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 fb_mmu_cbc_max_comptagline_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 fb_mmu_cbc_max_safe_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 fb_mmu_cbc_max_safe_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fb_mmu_cbc_max_safe_false_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_cbc_max_unsafe_fault_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fb_mmu_cbc_max_unsafe_fault_enabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fb_mmu_cbc_max_unsafe_fault_disabled_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_fifo_gv11b.h b/include/nvgpu/hw/gv11b/hw_fifo_gv11b.h new file mode 100644 index 0000000..9ec30bf --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_fifo_gv11b.h @@ -0,0 +1,667 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fifo_gv11b_h_ +#define _hw_fifo_gv11b_h_ + +static inline u32 fifo_bar1_base_r(void) +{ + return 0x00002254U; +} +static inline u32 fifo_bar1_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_bar1_base_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 fifo_bar1_base_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 fifo_bar1_base_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_userd_writeback_r(void) +{ + return 0x0000225cU; +} +static inline u32 fifo_userd_writeback_timer_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fifo_userd_writeback_timer_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_userd_writeback_timer_shorter_v(void) +{ + return 0x00000003U; +} +static inline u32 fifo_userd_writeback_timer_100us_v(void) +{ + return 0x00000064U; +} +static inline u32 fifo_userd_writeback_timescale_f(u32 v) +{ + return (v & 0xfU) << 12U; +} +static inline u32 fifo_userd_writeback_timescale_0_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_runlist_base_r(void) +{ + return 0x00002270U; +} +static inline u32 fifo_runlist_base_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 fifo_runlist_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 fifo_runlist_base_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_runlist_base_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 fifo_runlist_r(void) +{ + return 0x00002274U; +} +static inline u32 fifo_runlist_engine_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 fifo_eng_runlist_base_r(u32 i) +{ + return 0x00002280U + i*8U; +} +static inline u32 fifo_eng_runlist_base__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fifo_eng_runlist_r(u32 i) +{ + return 0x00002284U + i*8U; +} +static inline u32 fifo_eng_runlist__size_1_v(void) +{ + return 0x00000002U; +} +static inline u32 fifo_eng_runlist_length_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fifo_eng_runlist_length_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 fifo_eng_runlist_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_pb_timeslice_r(u32 i) +{ + return 0x00002350U + i*4U; +} +static inline u32 fifo_pb_timeslice_timeout_16_f(void) +{ + return 0x10U; +} +static inline u32 fifo_pb_timeslice_timescale_0_f(void) +{ + return 0x0U; +} +static inline u32 fifo_pb_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +static inline u32 fifo_pbdma_map_r(u32 i) +{ + return 0x00002390U + i*4U; +} +static inline u32 fifo_intr_0_r(void) +{ + return 0x00002100U; +} +static inline u32 fifo_intr_0_bind_error_pending_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_bind_error_reset_f(void) +{ + return 0x1U; +} +static inline u32 fifo_intr_0_sched_error_pending_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_sched_error_reset_f(void) +{ + return 0x100U; +} +static inline u32 fifo_intr_0_chsw_error_pending_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_chsw_error_reset_f(void) +{ + return 0x10000U; +} +static inline u32 fifo_intr_0_memop_timeout_pending_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_memop_timeout_reset_f(void) +{ + return 0x800000U; +} +static inline u32 fifo_intr_0_lb_error_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_lb_error_reset_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_intr_0_pbdma_intr_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 fifo_intr_0_runlist_event_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 fifo_intr_0_channel_intr_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_intr_0_ctxsw_timeout_pending_f(void) +{ + return 0x2U; +} +static inline u32 fifo_intr_en_0_r(void) +{ + return 0x00002140U; +} +static inline u32 fifo_intr_en_0_sched_error_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 fifo_intr_en_0_sched_error_m(void) +{ + return 0x1U << 8U; +} +static inline u32 fifo_intr_en_0_ctxsw_timeout_pending_f(void) +{ + return 0x2U; +} +static inline u32 fifo_intr_en_1_r(void) +{ + return 0x00002528U; +} +static inline u32 fifo_intr_bind_error_r(void) +{ + return 0x0000252cU; +} +static inline u32 fifo_intr_sched_error_r(void) +{ + return 0x0000254cU; +} +static inline u32 fifo_intr_sched_error_code_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fifo_intr_chsw_error_r(void) +{ + return 0x0000256cU; +} +static inline u32 fifo_intr_ctxsw_timeout_r(void) +{ + return 0x00002a30U; +} +static inline u32 fifo_intr_ctxsw_timeout_engine_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_intr_ctxsw_timeout_engine_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fifo_intr_ctxsw_timeout_engine__size_1_v(void) +{ + return 0x00000020U; +} +static inline u32 fifo_intr_ctxsw_timeout_engine_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_ctxsw_timeout_engine_pending_f(u32 i) +{ + return 0x1U << (0U + i*1U); +} +static inline u32 fifo_intr_ctxsw_timeout_info_r(u32 i) +{ + return 0x00003200U + i*4U; +} +static inline u32 fifo_intr_ctxsw_timeout_info__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 fifo_intr_ctxsw_timeout_info_ctxsw_state_v(u32 r) +{ + return (r >> 14U) & 0x3U; +} +static inline u32 fifo_intr_ctxsw_timeout_info_ctxsw_state_load_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_ctxsw_timeout_info_ctxsw_state_save_v(void) +{ + return 0x00000002U; +} +static inline u32 fifo_intr_ctxsw_timeout_info_ctxsw_state_switch_v(void) +{ + return 0x00000003U; +} +static inline u32 fifo_intr_ctxsw_timeout_info_prev_tsgid_v(u32 r) +{ + return (r >> 0U) & 0x3fffU; +} +static inline u32 fifo_intr_ctxsw_timeout_info_next_tsgid_v(u32 r) +{ + return (r >> 16U) & 0x3fffU; +} +static inline u32 fifo_intr_ctxsw_timeout_info_status_v(u32 r) +{ + return (r >> 30U) & 0x3U; +} +static inline u32 fifo_intr_ctxsw_timeout_info_status_awaiting_ack_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_intr_ctxsw_timeout_info_status_eng_was_reset_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_intr_ctxsw_timeout_info_status_ack_received_v(void) +{ + return 0x00000002U; +} +static inline u32 fifo_intr_ctxsw_timeout_info_status_dropped_timeout_v(void) +{ + return 0x00000003U; +} +static inline u32 fifo_intr_pbdma_id_r(void) +{ + return 0x000025a0U; +} +static inline u32 fifo_intr_pbdma_id_status_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_intr_pbdma_id_status_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fifo_intr_pbdma_id_status__size_1_v(void) +{ + return 0x00000003U; +} +static inline u32 fifo_intr_runlist_r(void) +{ + return 0x00002a00U; +} +static inline u32 fifo_fb_timeout_r(void) +{ + return 0x00002a04U; +} +static inline u32 fifo_fb_timeout_period_m(void) +{ + return 0x3fffffffU << 0U; +} +static inline u32 fifo_fb_timeout_period_max_f(void) +{ + return 0x3fffffffU; +} +static inline u32 fifo_fb_timeout_period_init_f(void) +{ + return 0x3c00U; +} +static inline u32 fifo_fb_timeout_detection_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fifo_fb_timeout_detection_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_fb_timeout_detection_disabled_f(void) +{ + return 0x0U; +} +static inline u32 fifo_sched_disable_r(void) +{ + return 0x00002630U; +} +static inline u32 fifo_sched_disable_runlist_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_sched_disable_runlist_m(u32 i) +{ + return 0x1U << (0U + i*1U); +} +static inline u32 fifo_sched_disable_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_runlist_preempt_r(void) +{ + return 0x00002638U; +} +static inline u32 fifo_runlist_preempt_runlist_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +static inline u32 fifo_runlist_preempt_runlist_m(u32 i) +{ + return 0x1U << (0U + i*1U); +} +static inline u32 fifo_runlist_preempt_runlist_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_preempt_r(void) +{ + return 0x00002634U; +} +static inline u32 fifo_preempt_pending_true_f(void) +{ + return 0x100000U; +} +static inline u32 fifo_preempt_type_channel_f(void) +{ + return 0x0U; +} +static inline u32 fifo_preempt_type_tsg_f(void) +{ + return 0x1000000U; +} +static inline u32 fifo_preempt_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_preempt_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 fifo_engine_status_r(u32 i) +{ + return 0x00002640U + i*8U; +} +static inline u32 fifo_engine_status__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 fifo_engine_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_engine_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_engine_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_engine_status_ctx_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_engine_status_ctx_status_ctxsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_engine_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_engine_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_engine_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_eng_reload_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 fifo_engine_status_faulted_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 fifo_engine_status_faulted_true_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_engine_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 fifo_engine_status_engine_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_engine_status_engine_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_engine_status_ctxsw_in_progress_f(void) +{ + return 0x8000U; +} +static inline u32 fifo_eng_ctxsw_timeout_r(void) +{ + return 0x00002a0cU; +} +static inline u32 fifo_eng_ctxsw_timeout_period_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 fifo_eng_ctxsw_timeout_period_m(void) +{ + return 0x7fffffffU << 0U; +} +static inline u32 fifo_eng_ctxsw_timeout_period_v(u32 r) +{ + return (r >> 0U) & 0x7fffffffU; +} +static inline u32 fifo_eng_ctxsw_timeout_period_init_f(void) +{ + return 0x3fffffU; +} +static inline u32 fifo_eng_ctxsw_timeout_period_max_f(void) +{ + return 0x7fffffffU; +} +static inline u32 fifo_eng_ctxsw_timeout_detection_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 fifo_eng_ctxsw_timeout_detection_m(void) +{ + return 0x1U << 31U; +} +static inline u32 fifo_eng_ctxsw_timeout_detection_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 fifo_eng_ctxsw_timeout_detection_disabled_f(void) +{ + return 0x0U; +} +static inline u32 fifo_pbdma_status_r(u32 i) +{ + return 0x00003080U + i*4U; +} +static inline u32 fifo_pbdma_status__size_1_v(void) +{ + return 0x00000003U; +} +static inline u32 fifo_pbdma_status_id_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_id_type_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 fifo_pbdma_status_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_id_type_tsgid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_v(u32 r) +{ + return (r >> 13U) & 0x7U; +} +static inline u32 fifo_pbdma_status_chan_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_load_v(void) +{ + return 0x00000005U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_save_v(void) +{ + return 0x00000006U; +} +static inline u32 fifo_pbdma_status_chan_status_chsw_switch_v(void) +{ + return 0x00000007U; +} +static inline u32 fifo_pbdma_status_next_id_v(u32 r) +{ + return (r >> 16U) & 0xfffU; +} +static inline u32 fifo_pbdma_status_next_id_type_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 fifo_pbdma_status_next_id_type_chid_v(void) +{ + return 0x00000000U; +} +static inline u32 fifo_pbdma_status_chsw_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 fifo_pbdma_status_chsw_in_progress_v(void) +{ + return 0x00000001U; +} +static inline u32 fifo_cfg0_r(void) +{ + return 0x00002004U; +} +static inline u32 fifo_cfg0_num_pbdma_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 fifo_cfg0_pbdma_fault_id_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_flush_gv11b.h b/include/nvgpu/hw/gv11b/hw_flush_gv11b.h new file mode 100644 index 0000000..45c01de --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_flush_gv11b.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_flush_gv11b_h_ +#define _hw_flush_gv11b_h_ + +static inline u32 flush_l2_system_invalidate_r(void) +{ + return 0x00070004U; +} +static inline u32 flush_l2_system_invalidate_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_system_invalidate_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_system_invalidate_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_r(void) +{ + return 0x00070010U; +} +static inline u32 flush_l2_flush_dirty_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_flush_dirty_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_flush_dirty_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_flush_dirty_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_r(void) +{ + return 0x0007000cU; +} +static inline u32 flush_l2_clean_comptags_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_pending_empty_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_l2_clean_comptags_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_v(void) +{ + return 0x00000000U; +} +static inline u32 flush_l2_clean_comptags_outstanding_false_f(void) +{ + return 0x0U; +} +static inline u32 flush_l2_clean_comptags_outstanding_true_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_r(void) +{ + return 0x00070000U; +} +static inline u32 flush_fb_flush_pending_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 flush_fb_flush_pending_busy_v(void) +{ + return 0x00000001U; +} +static inline u32 flush_fb_flush_pending_busy_f(void) +{ + return 0x1U; +} +static inline u32 flush_fb_flush_outstanding_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 flush_fb_flush_outstanding_true_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_fuse_gv11b.h b/include/nvgpu/hw/gv11b/hw_fuse_gv11b.h new file mode 100644 index 0000000..9395da3 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_fuse_gv11b.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_fuse_gv11b_h_ +#define _hw_fuse_gv11b_h_ + +static inline u32 fuse_status_opt_gpc_r(void) +{ + return 0x00021c1cU; +} +static inline u32 fuse_status_opt_tpc_gpc_r(u32 i) +{ + return 0x00021c38U + i*4U; +} +static inline u32 fuse_ctrl_opt_tpc_gpc_r(u32 i) +{ + return 0x00021838U + i*4U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_r(void) +{ + return 0x00021944U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_m(void) +{ + return 0xffU << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_data_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_r(void) +{ + return 0x00021948U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_m(void) +{ + return 0x1U << 0U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_yes_f(void) +{ + return 0x1U; +} +static inline u32 fuse_ctrl_opt_ram_svop_pdp_override_data_no_f(void) +{ + return 0x0U; +} +static inline u32 fuse_status_opt_fbio_r(void) +{ + return 0x00021c14U; +} +static inline u32 fuse_status_opt_fbio_data_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 fuse_status_opt_fbio_data_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 fuse_status_opt_fbio_data_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 fuse_status_opt_rop_l2_fbp_r(u32 i) +{ + return 0x00021d70U + i*4U; +} +static inline u32 fuse_status_opt_fbp_r(void) +{ + return 0x00021d38U; +} +static inline u32 fuse_status_opt_fbp_idx_v(u32 r, u32 i) +{ + return (r >> (0U + i*1U)) & 0x1U; +} +static inline u32 fuse_opt_ecc_en_r(void) +{ + return 0x00021228U; +} +static inline u32 fuse_opt_feature_fuses_override_disable_r(void) +{ + return 0x000213f0U; +} +static inline u32 fuse_opt_sec_debug_en_r(void) +{ + return 0x00021218U; +} +static inline u32 fuse_opt_priv_sec_en_r(void) +{ + return 0x00021434U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_gmmu_gv11b.h b/include/nvgpu/hw/gv11b/hw_gmmu_gv11b.h new file mode 100644 index 0000000..922dd68 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_gmmu_gv11b.h @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gmmu_gv11b_h_ +#define _hw_gmmu_gv11b_h_ + +static inline u32 gmmu_new_pde_is_pte_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_is_pte_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_aperture_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_aperture_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_aperture_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_pde_aperture_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_pde_aperture_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_pde_address_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pde_address_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_vol_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pde_vol_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_pde_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pde_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_new_pde__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_dual_pde_is_pte_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_is_pte_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_dual_pde_aperture_big_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_dual_pde_address_big_sys_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 gmmu_new_dual_pde_address_big_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_video_memory_f(void) +{ + return 0x2U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_dual_pde_aperture_small_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_dual_pde_vol_small_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_vol_small_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_dual_pde_vol_small_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_vol_big_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_dual_pde_vol_big_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_dual_pde_vol_big_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_dual_pde_address_small_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_dual_pde_address_small_sys_w(void) +{ + return 2U; +} +static inline u32 gmmu_new_dual_pde_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_new_dual_pde_address_big_shift_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_dual_pde__size_v(void) +{ + return 0x00000010U; +} +static inline u32 gmmu_new_pte__size_v(void) +{ + return 0x00000008U; +} +static inline u32 gmmu_new_pte_valid_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_valid_true_f(void) +{ + return 0x1U; +} +static inline u32 gmmu_new_pte_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_privilege_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_privilege_true_f(void) +{ + return 0x20U; +} +static inline u32 gmmu_new_pte_privilege_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_address_sys_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pte_address_sys_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_address_vid_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 gmmu_new_pte_address_vid_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_vol_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_vol_true_f(void) +{ + return 0x8U; +} +static inline u32 gmmu_new_pte_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_aperture_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_aperture_video_memory_f(void) +{ + return 0x0U; +} +static inline u32 gmmu_new_pte_aperture_sys_mem_coh_f(void) +{ + return 0x4U; +} +static inline u32 gmmu_new_pte_aperture_sys_mem_ncoh_f(void) +{ + return 0x6U; +} +static inline u32 gmmu_new_pte_read_only_w(void) +{ + return 0U; +} +static inline u32 gmmu_new_pte_read_only_true_f(void) +{ + return 0x40U; +} +static inline u32 gmmu_new_pte_comptagline_f(u32 v) +{ + return (v & 0x3ffffU) << 4U; +} +static inline u32 gmmu_new_pte_comptagline_w(void) +{ + return 1U; +} +static inline u32 gmmu_new_pte_kind_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gmmu_new_pte_kind_w(void) +{ + return 1U; +} +static inline u32 gmmu_new_pte_address_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 gmmu_pte_kind_f(u32 v) +{ + return (v & 0xffU) << 4U; +} +static inline u32 gmmu_pte_kind_w(void) +{ + return 1U; +} +static inline u32 gmmu_pte_kind_invalid_v(void) +{ + return 0x000000ffU; +} +static inline u32 gmmu_pte_kind_pitch_v(void) +{ + return 0x00000000U; +} +static inline u32 gmmu_fault_client_type_gpc_v(void) +{ + return 0x00000000U; +} +static inline u32 gmmu_fault_client_type_hub_v(void) +{ + return 0x00000001U; +} +static inline u32 gmmu_fault_type_unbound_inst_block_v(void) +{ + return 0x00000004U; +} +static inline u32 gmmu_fault_type_pte_v(void) +{ + return 0x00000002U; +} +static inline u32 gmmu_fault_mmu_eng_id_bar2_v(void) +{ + return 0x00000005U; +} +static inline u32 gmmu_fault_mmu_eng_id_physical_v(void) +{ + return 0x0000001fU; +} +static inline u32 gmmu_fault_mmu_eng_id_ce0_v(void) +{ + return 0x0000000fU; +} +static inline u32 gmmu_fault_buf_size_v(void) +{ + return 0x00000020U; +} +static inline u32 gmmu_fault_buf_entry_inst_aperture_v(u32 r) +{ + return (r >> 8U) & 0x3U; +} +static inline u32 gmmu_fault_buf_entry_inst_aperture_w(void) +{ + return 0U; +} +static inline u32 gmmu_fault_buf_entry_inst_aperture_vid_mem_v(void) +{ + return 0x00000000U; +} +static inline u32 gmmu_fault_buf_entry_inst_aperture_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 gmmu_fault_buf_entry_inst_aperture_sys_nocoh_v(void) +{ + return 0x00000003U; +} +static inline u32 gmmu_fault_buf_entry_inst_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 gmmu_fault_buf_entry_inst_lo_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 gmmu_fault_buf_entry_inst_lo_b(void) +{ + return 12U; +} +static inline u32 gmmu_fault_buf_entry_inst_lo_w(void) +{ + return 0U; +} +static inline u32 gmmu_fault_buf_entry_inst_hi_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gmmu_fault_buf_entry_inst_hi_w(void) +{ + return 1U; +} +static inline u32 gmmu_fault_buf_entry_addr_phys_aperture_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 gmmu_fault_buf_entry_addr_phys_aperture_w(void) +{ + return 2U; +} +static inline u32 gmmu_fault_buf_entry_addr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 gmmu_fault_buf_entry_addr_lo_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 gmmu_fault_buf_entry_addr_lo_b(void) +{ + return 12U; +} +static inline u32 gmmu_fault_buf_entry_addr_lo_w(void) +{ + return 2U; +} +static inline u32 gmmu_fault_buf_entry_addr_hi_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gmmu_fault_buf_entry_addr_hi_w(void) +{ + return 3U; +} +static inline u32 gmmu_fault_buf_entry_timestamp_lo_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gmmu_fault_buf_entry_timestamp_lo_w(void) +{ + return 4U; +} +static inline u32 gmmu_fault_buf_entry_timestamp_hi_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gmmu_fault_buf_entry_timestamp_hi_w(void) +{ + return 5U; +} +static inline u32 gmmu_fault_buf_entry_engine_id_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 gmmu_fault_buf_entry_engine_id_w(void) +{ + return 6U; +} +static inline u32 gmmu_fault_buf_entry_fault_type_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gmmu_fault_buf_entry_fault_type_w(void) +{ + return 7U; +} +static inline u32 gmmu_fault_buf_entry_replayable_fault_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 gmmu_fault_buf_entry_replayable_fault_w(void) +{ + return 7U; +} +static inline u32 gmmu_fault_buf_entry_replayable_fault_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gmmu_fault_buf_entry_replayable_fault_true_f(void) +{ + return 0x80U; +} +static inline u32 gmmu_fault_buf_entry_client_v(u32 r) +{ + return (r >> 8U) & 0x7fU; +} +static inline u32 gmmu_fault_buf_entry_client_w(void) +{ + return 7U; +} +static inline u32 gmmu_fault_buf_entry_access_type_v(u32 r) +{ + return (r >> 16U) & 0xfU; +} +static inline u32 gmmu_fault_buf_entry_access_type_w(void) +{ + return 7U; +} +static inline u32 gmmu_fault_buf_entry_mmu_client_type_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 gmmu_fault_buf_entry_mmu_client_type_w(void) +{ + return 7U; +} +static inline u32 gmmu_fault_buf_entry_gpc_id_v(u32 r) +{ + return (r >> 24U) & 0x1fU; +} +static inline u32 gmmu_fault_buf_entry_gpc_id_w(void) +{ + return 7U; +} +static inline u32 gmmu_fault_buf_entry_protected_mode_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 gmmu_fault_buf_entry_protected_mode_w(void) +{ + return 7U; +} +static inline u32 gmmu_fault_buf_entry_protected_mode_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gmmu_fault_buf_entry_protected_mode_true_f(void) +{ + return 0x20000000U; +} +static inline u32 gmmu_fault_buf_entry_replayable_fault_en_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gmmu_fault_buf_entry_replayable_fault_en_w(void) +{ + return 7U; +} +static inline u32 gmmu_fault_buf_entry_replayable_fault_en_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gmmu_fault_buf_entry_replayable_fault_en_true_f(void) +{ + return 0x40000000U; +} +static inline u32 gmmu_fault_buf_entry_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gmmu_fault_buf_entry_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gmmu_fault_buf_entry_valid_w(void) +{ + return 7U; +} +static inline u32 gmmu_fault_buf_entry_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gmmu_fault_buf_entry_valid_true_f(void) +{ + return 0x80000000U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_gr_gv11b.h b/include/nvgpu/hw/gv11b/hw_gr_gv11b.h new file mode 100644 index 0000000..f7d8089 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_gr_gv11b.h @@ -0,0 +1,5699 @@ +/* + * 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gr_gv11b_h_ +#define _hw_gr_gv11b_h_ + +static inline u32 gr_intr_r(void) +{ + return 0x00400100U; +} +static inline u32 gr_intr_notify_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_notify_reset_f(void) +{ + return 0x1U; +} +static inline u32 gr_intr_semaphore_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_semaphore_reset_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_illegal_method_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_method_reset_f(void) +{ + return 0x10U; +} +static inline u32 gr_intr_illegal_notify_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_illegal_notify_reset_f(void) +{ + return 0x40U; +} +static inline u32 gr_intr_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 gr_intr_firmware_method_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_firmware_method_reset_f(void) +{ + return 0x100U; +} +static inline u32 gr_intr_illegal_class_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_illegal_class_reset_f(void) +{ + return 0x20U; +} +static inline u32 gr_intr_fecs_error_pending_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_fecs_error_reset_f(void) +{ + return 0x80000U; +} +static inline u32 gr_intr_class_error_pending_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_class_error_reset_f(void) +{ + return 0x100000U; +} +static inline u32 gr_intr_exception_pending_f(void) +{ + return 0x200000U; +} +static inline u32 gr_intr_exception_reset_f(void) +{ + return 0x200000U; +} +static inline u32 gr_fecs_intr_r(void) +{ + return 0x00400144U; +} +static inline u32 gr_class_error_r(void) +{ + return 0x00400110U; +} +static inline u32 gr_class_error_code_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_intr_nonstall_r(void) +{ + return 0x00400120U; +} +static inline u32 gr_intr_nonstall_trap_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_intr_en_r(void) +{ + return 0x0040013cU; +} +static inline u32 gr_exception_r(void) +{ + return 0x00400108U; +} +static inline u32 gr_exception_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception_gpc_m(void) +{ + return 0x1U << 24U; +} +static inline u32 gr_exception_memfmt_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_exception_ds_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_exception_sked_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_exception_pd_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_exception_scc_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_exception_ssync_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_exception_mme_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_exception1_r(void) +{ + return 0x00400118U; +} +static inline u32 gr_exception1_gpc_0_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_exception2_r(void) +{ + return 0x0040011cU; +} +static inline u32 gr_exception_en_r(void) +{ + return 0x00400138U; +} +static inline u32 gr_exception_en_fe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_exception_en_fe_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_exception_en_gpc_m(void) +{ + return 0x1U << 24U; +} +static inline u32 gr_exception_en_gpc_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 gr_exception_en_memfmt_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_exception_en_memfmt_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_exception_en_ds_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_exception_en_ds_enabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_exception_en_pd_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_exception_en_pd_enabled_f(void) +{ + return 0x4U; +} +static inline u32 gr_exception_en_scc_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_exception_en_scc_enabled_f(void) +{ + return 0x8U; +} +static inline u32 gr_exception_en_ssync_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_exception_en_ssync_enabled_f(void) +{ + return 0x20U; +} +static inline u32 gr_exception_en_mme_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_exception_en_mme_enabled_f(void) +{ + return 0x80U; +} +static inline u32 gr_exception_en_sked_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_exception_en_sked_enabled_f(void) +{ + return 0x100U; +} +static inline u32 gr_exception1_en_r(void) +{ + return 0x00400130U; +} +static inline u32 gr_exception2_en_r(void) +{ + return 0x00400134U; +} +static inline u32 gr_gpfifo_ctl_r(void) +{ + return 0x00400500U; +} +static inline u32 gr_gpfifo_ctl_access_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpfifo_ctl_access_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpfifo_ctl_access_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpfifo_ctl_semaphore_access_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpfifo_status_r(void) +{ + return 0x00400504U; +} +static inline u32 gr_trapped_addr_r(void) +{ + return 0x00400704U; +} +static inline u32 gr_trapped_addr_mthd_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 gr_trapped_addr_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 gr_trapped_addr_mme_generated_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 gr_trapped_addr_datahigh_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 gr_trapped_addr_priv_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 gr_trapped_addr_status_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_trapped_data_lo_r(void) +{ + return 0x00400708U; +} +static inline u32 gr_trapped_data_hi_r(void) +{ + return 0x0040070cU; +} +static inline u32 gr_trapped_data_mme_r(void) +{ + return 0x00400710U; +} +static inline u32 gr_trapped_data_mme_pc_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_status_r(void) +{ + return 0x00400700U; +} +static inline u32 gr_status_fe_method_upper_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_status_fe_method_lower_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_status_fe_gi_v(u32 r) +{ + return (r >> 21U) & 0x1U; +} +static inline u32 gr_status_mask_r(void) +{ + return 0x00400610U; +} +static inline u32 gr_status_1_r(void) +{ + return 0x00400604U; +} +static inline u32 gr_status_2_r(void) +{ + return 0x00400608U; +} +static inline u32 gr_engine_status_r(void) +{ + return 0x0040060cU; +} +static inline u32 gr_engine_status_value_busy_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_be0_becs_be_exception_r(void) +{ + return 0x00410204U; +} +static inline u32 gr_pri_be0_becs_be_exception_en_r(void) +{ + return 0x00410208U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_exception_en_r(void) +{ + return 0x00502c94U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_activity_0_r(void) +{ + return 0x00400380U; +} +static inline u32 gr_activity_1_r(void) +{ + return 0x00400384U; +} +static inline u32 gr_activity_2_r(void) +{ + return 0x00400388U; +} +static inline u32 gr_activity_4_r(void) +{ + return 0x00400390U; +} +static inline u32 gr_activity_4_gpc0_s(void) +{ + return 3U; +} +static inline u32 gr_activity_4_gpc0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_activity_4_gpc0_m(void) +{ + return 0x7U << 0U; +} +static inline u32 gr_activity_4_gpc0_v(u32 r) +{ + return (r >> 0U) & 0x7U; +} +static inline u32 gr_activity_4_gpc0_empty_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_activity_4_gpc0_preempted_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_pri_gpc0_gcc_dbg_r(void) +{ + return 0x00501000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_r(void) +{ + return 0x00419000U; +} +static inline u32 gr_pri_gpcs_gcc_dbg_invalidate_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cache_control_r(void) +{ + return 0x0050433cU; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_r(void) +{ + return 0x00419b3cU; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cache_control_invalidate_cache_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_sked_activity_r(void) +{ + return 0x00407054U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity0_r(void) +{ + return 0x00502c80U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity1_r(void) +{ + return 0x00502c84U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity2_r(void) +{ + return 0x00502c88U; +} +static inline u32 gr_pri_gpc0_gpccs_gpc_activity3_r(void) +{ + return 0x00502c8cU; +} +static inline u32 gr_pri_gpc0_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x00504500U; +} +static inline u32 gr_pri_gpc0_tpc1_tpccs_tpc_activity_0_r(void) +{ + return 0x00504d00U; +} +static inline u32 gr_pri_gpc0_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00501d00U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_0_r(void) +{ + return 0x0041ac80U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_1_r(void) +{ + return 0x0041ac84U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_2_r(void) +{ + return 0x0041ac88U; +} +static inline u32 gr_pri_gpcs_gpccs_gpc_activity_3_r(void) +{ + return 0x0041ac8cU; +} +static inline u32 gr_pri_gpcs_tpc0_tpccs_tpc_activity_0_r(void) +{ + return 0x0041c500U; +} +static inline u32 gr_pri_gpcs_tpc1_tpccs_tpc_activity_0_r(void) +{ + return 0x0041cd00U; +} +static inline u32 gr_pri_gpcs_tpcs_tpccs_tpc_activity_0_r(void) +{ + return 0x00419d00U; +} +static inline u32 gr_pri_be0_becs_be_activity0_r(void) +{ + return 0x00410200U; +} +static inline u32 gr_pri_be1_becs_be_activity0_r(void) +{ + return 0x00410600U; +} +static inline u32 gr_pri_bes_becs_be_activity0_r(void) +{ + return 0x00408a00U; +} +static inline u32 gr_pri_ds_mpipe_status_r(void) +{ + return 0x00405858U; +} +static inline u32 gr_pri_fe_go_idle_info_r(void) +{ + return 0x00404194U; +} +static inline u32 gr_pri_fe_chip_def_info_r(void) +{ + return 0x00404030U; +} +static inline u32 gr_pri_fe_chip_def_info_max_veid_count_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_pri_fe_chip_def_info_max_veid_count_init_v(void) +{ + return 0x00000040U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_tex_subunits_status_r(void) +{ + return 0x00504238U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_r(void) +{ + return 0x00504358U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp1_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp2_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp3_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp4_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp5_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp6_m(void) +{ + return 0x1U << 6U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_qrfdp7_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp0_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp1_m(void) +{ + return 0x1U << 9U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp2_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp3_m(void) +{ + return 0x1U << 11U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp4_m(void) +{ + return 0x1U << 12U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp5_m(void) +{ + return 0x1U << 13U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp6_m(void) +{ + return 0x1U << 14U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_qrfdp7_m(void) +{ + return 0x1U << 15U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_corrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_uncorrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 26U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_corrected_err_count_r(void) +{ + return 0x0050435cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_uncorrected_err_count_r(void) +{ + return 0x00504360U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_r(void) +{ + return 0x0050436cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_corrected_err_el1_0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_corrected_err_el1_1_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_uncorrected_err_el1_0_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_uncorrected_err_el1_1_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_corrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_uncorrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_status_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_corrected_err_count_r(void) +{ + return 0x00504370U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_uncorrected_err_count_r(void) +{ + return 0x00504374U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_r(void) +{ + return 0x0050464cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_corrected_err_l0_data_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_corrected_err_l0_predecode_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_corrected_err_l1_data_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_corrected_err_l1_predecode_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_uncorrected_err_l0_data_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_uncorrected_err_l0_predecode_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_uncorrected_err_l1_data_m(void) +{ + return 0x1U << 6U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_uncorrected_err_l1_predecode_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_corrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_uncorrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 18U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_status_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_corrected_err_count_r(void) +{ + return 0x00504650U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_uncorrected_err_count_r(void) +{ + return 0x00504654U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_r(void) +{ + return 0x00504624U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_el1_0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_el1_1_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_el1_0_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_el1_1_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_pixrpf_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_miss_fifo_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_pixrpf_m(void) +{ + return 0x1U << 6U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_miss_fifo_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_corrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_uncorrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_status_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_corrected_err_count_r(void) +{ + return 0x00504628U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_uncorrected_err_count_r(void) +{ + return 0x0050462cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_r(void) +{ + return 0x00504638U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_corrected_err_warp_sm0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_corrected_err_warp_sm1_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_corrected_err_barrier_sm0_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_corrected_err_barrier_sm1_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_uncorrected_err_warp_sm0_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_uncorrected_err_warp_sm1_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_uncorrected_err_barrier_sm0_m(void) +{ + return 0x1U << 6U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_uncorrected_err_barrier_sm1_m(void) +{ + return 0x1U << 7U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_corrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_uncorrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 18U) & 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_status_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_corrected_err_count_r(void) +{ + return 0x0050463cU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_uncorrected_err_count_r(void) +{ + return 0x00504640U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_r(void) +{ + return 0x00419b54U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp0_task_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp1_task_f(void) +{ + return 0x2U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp2_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp2_task_f(void) +{ + return 0x4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp3_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp3_task_f(void) +{ + return 0x8U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp4_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp4_task_f(void) +{ + return 0x10U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp5_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp5_task_f(void) +{ + return 0x20U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp6_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp6_task_f(void) +{ + return 0x40U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp7_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp7_task_f(void) +{ + return 0x80U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_r(void) +{ + return 0x00504354U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp0_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp1_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp2_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp2_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp3_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp3_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp4_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp4_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp5_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp5_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp6_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp6_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp7_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp7_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_data_ecc_control_r(void) +{ + return 0x00419b68U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_data_ecc_control_scrub_el1_0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_data_ecc_control_scrub_el1_0_task_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_data_ecc_control_scrub_el1_1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_data_ecc_control_scrub_el1_1_task_f(void) +{ + return 0x2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_control_r(void) +{ + return 0x00504368U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_control_scrub_el1_0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_control_scrub_el1_0_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_control_scrub_el1_1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_data_ecc_control_scrub_el1_1_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_r(void) +{ + return 0x00419e20U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_scrub_el1_0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_scrub_el1_0_task_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_scrub_el1_1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_scrub_el1_1_task_f(void) +{ + return 0x2U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_scrub_pixprf_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_scrub_pixprf_task_f(void) +{ + return 0x10U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_scrub_miss_fifo_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_scrub_miss_fifo_task_f(void) +{ + return 0x20U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_r(void) +{ + return 0x00504620U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_scrub_el1_0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_scrub_el1_0_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_scrub_el1_1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_scrub_el1_1_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_scrub_pixprf_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_scrub_pixprf_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_scrub_miss_fifo_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_scrub_miss_fifo_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cbu_ecc_control_r(void) +{ + return 0x00419e34U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_warp_sm0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_warp_sm0_task_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_warp_sm1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_warp_sm1_task_f(void) +{ + return 0x2U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_barrier_sm0_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_barrier_sm0_task_f(void) +{ + return 0x4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_barrier_sm1_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_barrier_sm1_task_f(void) +{ + return 0x8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_control_r(void) +{ + return 0x00504634U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_warp_sm0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_warp_sm0_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_warp_sm1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_warp_sm1_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_barrier_sm0_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_barrier_sm0_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_barrier_sm1_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_barrier_sm1_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_icache_ecc_control_r(void) +{ + return 0x00419e48U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l0_data_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l0_data_task_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l0_predecode_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l0_predecode_task_f(void) +{ + return 0x2U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l1_data_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l1_data_task_f(void) +{ + return 0x4U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l1_predecode_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l1_predecode_task_f(void) +{ + return 0x8U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_control_r(void) +{ + return 0x00504648U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l0_data_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l0_data_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l0_predecode_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l0_predecode_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l1_data_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l1_data_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l1_predecode_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l1_predecode_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_r(void) +{ + return 0x005042c4U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_default_f(void) +{ + return 0x0U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe0_f(void) +{ + return 0x1U; +} +static inline u32 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe1_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_mpc_hww_esr_r(void) +{ + return 0x00504430U; +} +static inline u32 gr_gpc0_tpc0_mpc_hww_esr_reset_trigger_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_mpc_hww_esr_info_r(void) +{ + return 0x00504434U; +} +static inline u32 gr_gpc0_tpc0_mpc_hww_esr_info_veid_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_pri_be0_crop_status1_r(void) +{ + return 0x00410134U; +} +static inline u32 gr_pri_bes_crop_status1_r(void) +{ + return 0x00408934U; +} +static inline u32 gr_pri_be0_zrop_status_r(void) +{ + return 0x00410048U; +} +static inline u32 gr_pri_be0_zrop_status2_r(void) +{ + return 0x0041004cU; +} +static inline u32 gr_pri_bes_zrop_status_r(void) +{ + return 0x00408848U; +} +static inline u32 gr_pri_bes_zrop_status2_r(void) +{ + return 0x0040884cU; +} +static inline u32 gr_pipe_bundle_address_r(void) +{ + return 0x00400200U; +} +static inline u32 gr_pipe_bundle_address_value_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pipe_bundle_address_veid_f(u32 v) +{ + return (v & 0x3fU) << 20U; +} +static inline u32 gr_pipe_bundle_address_veid_w(void) +{ + return 0U; +} +static inline u32 gr_pipe_bundle_data_r(void) +{ + return 0x00400204U; +} +static inline u32 gr_pipe_bundle_config_r(void) +{ + return 0x00400208U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_pipe_bundle_config_override_pipe_mode_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_r(void) +{ + return 0x00404000U; +} +static inline u32 gr_fe_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_fe_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_hww_esr_info_r(void) +{ + return 0x004041b0U; +} +static inline u32 gr_gpcs_tpcs_sms_hww_global_esr_report_mask_r(void) +{ + return 0x00419eacU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_r(void) +{ + return 0x0050472cU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_multiple_warp_errors_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_bpt_int_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_bpt_pause_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_single_step_complete_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_report_mask_error_in_trap_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpcs_tpcs_sms_hww_global_esr_r(void) +{ + return 0x00419eb4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_r(void) +{ + return 0x00504734U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_bpt_int_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_bpt_int_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_bpt_pause_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_bpt_pause_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_single_step_complete_m(void) +{ + return 0x1U << 6U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_single_step_complete_pending_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_multiple_warp_errors_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_multiple_warp_errors_pending_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_error_in_trap_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_global_esr_error_in_trap_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_fe_go_idle_timeout_r(void) +{ + return 0x00404154U; +} +static inline u32 gr_fe_go_idle_timeout_count_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fe_go_idle_timeout_count_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_go_idle_timeout_count_prod_f(void) +{ + return 0x1800U; +} +static inline u32 gr_fe_object_table_r(u32 i) +{ + return 0x00404200U + i*4U; +} +static inline u32 gr_fe_object_table_nvclass_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_fe_tpc_fs_r(u32 i) +{ + return 0x0040a200U + i*4U; +} +static inline u32 gr_fe_tpc_pesmask_r(void) +{ + return 0x0040a260U; +} +static inline u32 gr_fe_tpc_pesmask_pesid_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 gr_fe_tpc_pesmask_gpcid_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_fe_tpc_pesmask_action_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_fe_tpc_pesmask_action_write_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_fe_tpc_pesmask_action_read_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_tpc_pesmask_req_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fe_tpc_pesmask_req_send_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fe_tpc_pesmask_mask_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_pri_mme_shadow_raw_index_r(void) +{ + return 0x00404488U; +} +static inline u32 gr_pri_mme_shadow_raw_index_write_trigger_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pri_mme_shadow_raw_data_r(void) +{ + return 0x0040448cU; +} +static inline u32 gr_mme_hww_esr_r(void) +{ + return 0x00404490U; +} +static inline u32 gr_mme_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_mme_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_mme_hww_esr_info_r(void) +{ + return 0x00404494U; +} +static inline u32 gr_memfmt_hww_esr_r(void) +{ + return 0x00404600U; +} +static inline u32 gr_memfmt_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_memfmt_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fecs_cpuctl_r(void) +{ + return 0x00409100U; +} +static inline u32 gr_fecs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_cpuctl_alias_r(void) +{ + return 0x00409130U; +} +static inline u32 gr_fecs_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_dmactl_r(void) +{ + return 0x0040910cU; +} +static inline u32 gr_fecs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_fecs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_fecs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_fecs_os_r(void) +{ + return 0x00409080U; +} +static inline u32 gr_fecs_idlestate_r(void) +{ + return 0x0040904cU; +} +static inline u32 gr_fecs_mailbox0_r(void) +{ + return 0x00409040U; +} +static inline u32 gr_fecs_mailbox1_r(void) +{ + return 0x00409044U; +} +static inline u32 gr_fecs_irqstat_r(void) +{ + return 0x00409008U; +} +static inline u32 gr_fecs_irqmode_r(void) +{ + return 0x0040900cU; +} +static inline u32 gr_fecs_irqmask_r(void) +{ + return 0x00409018U; +} +static inline u32 gr_fecs_irqdest_r(void) +{ + return 0x0040901cU; +} +static inline u32 gr_fecs_curctx_r(void) +{ + return 0x00409050U; +} +static inline u32 gr_fecs_nxtctx_r(void) +{ + return 0x00409054U; +} +static inline u32 gr_fecs_engctl_r(void) +{ + return 0x004090a4U; +} +static inline u32 gr_fecs_debug1_r(void) +{ + return 0x00409090U; +} +static inline u32 gr_fecs_debuginfo_r(void) +{ + return 0x00409094U; +} +static inline u32 gr_fecs_icd_cmd_r(void) +{ + return 0x00409200U; +} +static inline u32 gr_fecs_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 gr_fecs_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 gr_fecs_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 gr_fecs_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 gr_fecs_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 gr_fecs_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 gr_fecs_icd_rdata_r(void) +{ + return 0x0040920cU; +} +static inline u32 gr_fecs_imemc_r(u32 i) +{ + return 0x00409180U + i*16U; +} +static inline u32 gr_fecs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_imemd_r(u32 i) +{ + return 0x00409184U + i*16U; +} +static inline u32 gr_fecs_imemt_r(u32 i) +{ + return 0x00409188U + i*16U; +} +static inline u32 gr_fecs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_dmemc_r(u32 i) +{ + return 0x004091c0U + i*8U; +} +static inline u32 gr_fecs_dmemc_offs_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_fecs_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 gr_fecs_dmemc_offs_v(u32 r) +{ + return (r >> 2U) & 0x3fU; +} +static inline u32 gr_fecs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_fecs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_fecs_dmemd_r(u32 i) +{ + return 0x004091c4U + i*8U; +} +static inline u32 gr_fecs_dmatrfbase_r(void) +{ + return 0x00409110U; +} +static inline u32 gr_fecs_dmatrfmoffs_r(void) +{ + return 0x00409114U; +} +static inline u32 gr_fecs_dmatrffboffs_r(void) +{ + return 0x0040911cU; +} +static inline u32 gr_fecs_dmatrfcmd_r(void) +{ + return 0x00409118U; +} +static inline u32 gr_fecs_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_fecs_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_fecs_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_fecs_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_fecs_bootvec_r(void) +{ + return 0x00409104U; +} +static inline u32 gr_fecs_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_falcon_hwcfg_r(void) +{ + return 0x00409108U; +} +static inline u32 gr_gpcs_gpccs_falcon_hwcfg_r(void) +{ + return 0x0041a108U; +} +static inline u32 gr_fecs_falcon_rm_r(void) +{ + return 0x00409084U; +} +static inline u32 gr_fecs_current_ctx_r(void) +{ + return 0x00409b00U; +} +static inline u32 gr_fecs_current_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_current_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_current_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_current_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_current_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_current_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_current_ctx_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 gr_fecs_current_ctx_target_sys_mem_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 gr_fecs_current_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_current_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_current_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_current_ctx_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_method_data_r(void) +{ + return 0x00409500U; +} +static inline u32 gr_fecs_method_push_r(void) +{ + return 0x00409504U; +} +static inline u32 gr_fecs_method_push_adr_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_v(void) +{ + return 0x00000003U; +} +static inline u32 gr_fecs_method_push_adr_bind_pointer_f(void) +{ + return 0x3U; +} +static inline u32 gr_fecs_method_push_adr_discover_image_size_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_method_push_adr_wfi_golden_save_v(void) +{ + return 0x00000009U; +} +static inline u32 gr_fecs_method_push_adr_restore_golden_v(void) +{ + return 0x00000015U; +} +static inline u32 gr_fecs_method_push_adr_discover_zcull_image_size_v(void) +{ + return 0x00000016U; +} +static inline u32 gr_fecs_method_push_adr_discover_pm_image_size_v(void) +{ + return 0x00000025U; +} +static inline u32 gr_fecs_method_push_adr_discover_reglist_image_size_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_bind_instance_v(void) +{ + return 0x00000031U; +} +static inline u32 gr_fecs_method_push_adr_set_reglist_virtual_address_v(void) +{ + return 0x00000032U; +} +static inline u32 gr_fecs_method_push_adr_stop_ctxsw_v(void) +{ + return 0x00000038U; +} +static inline u32 gr_fecs_method_push_adr_start_ctxsw_v(void) +{ + return 0x00000039U; +} +static inline u32 gr_fecs_method_push_adr_set_watchdog_timeout_f(void) +{ + return 0x21U; +} +static inline u32 gr_fecs_method_push_adr_discover_preemption_image_size_v(void) +{ + return 0x0000001aU; +} +static inline u32 gr_fecs_method_push_adr_halt_pipeline_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_fecs_method_push_adr_configure_interrupt_completion_option_v(void) +{ + return 0x0000003aU; +} +static inline u32 gr_fecs_host_int_status_r(void) +{ + return 0x00409c18U; +} +static inline u32 gr_fecs_host_int_status_fault_during_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_fecs_host_int_status_umimp_firmware_method_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 gr_fecs_host_int_status_umimp_illegal_method_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 gr_fecs_host_int_status_watchdog_active_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_host_int_status_ctxsw_intr_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_host_int_status_ecc_corrected_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 gr_fecs_host_int_status_ecc_corrected_m(void) +{ + return 0x1U << 21U; +} +static inline u32 gr_fecs_host_int_status_ecc_uncorrected_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 gr_fecs_host_int_status_ecc_uncorrected_m(void) +{ + return 0x1U << 22U; +} +static inline u32 gr_fecs_host_int_clear_r(void) +{ + return 0x00409c20U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_host_int_clear_ctxsw_intr1_clear_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_r(void) +{ + return 0x00409c24U; +} +static inline u32 gr_fecs_host_int_enable_ctxsw_intr1_enable_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_host_int_enable_fault_during_ctxsw_enable_f(void) +{ + return 0x10000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_firmware_method_enable_f(void) +{ + return 0x20000U; +} +static inline u32 gr_fecs_host_int_enable_umimp_illegal_method_enable_f(void) +{ + return 0x40000U; +} +static inline u32 gr_fecs_host_int_enable_watchdog_enable_f(void) +{ + return 0x80000U; +} +static inline u32 gr_fecs_host_int_enable_flush_when_busy_enable_f(void) +{ + return 0x100000U; +} +static inline u32 gr_fecs_host_int_enable_ecc_corrected_enable_f(void) +{ + return 0x200000U; +} +static inline u32 gr_fecs_host_int_enable_ecc_uncorrected_enable_f(void) +{ + return 0x400000U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_r(void) +{ + return 0x00409614U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_halt_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_engine_reset_disabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_engine_reset_disabled_f(void) +{ + return 0x20U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_engine_reset_disabled_f(void) +{ + return 0x40U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_sys_context_reset_disabled_f(void) +{ + return 0x100U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_gpc_context_reset_disabled_f(void) +{ + return 0x200U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_enabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fecs_ctxsw_reset_ctl_be_context_reset_disabled_f(void) +{ + return 0x400U; +} +static inline u32 gr_fecs_ctx_state_store_major_rev_id_r(void) +{ + return 0x0040960cU; +} +static inline u32 gr_fecs_ctxsw_mailbox_r(u32 i) +{ + return 0x00409800U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_fecs_ctxsw_mailbox_value_fail_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_r(u32 i) +{ + return 0x004098c0U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_set_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_r(u32 i) +{ + return 0x00409840U + i*4U; +} +static inline u32 gr_fecs_ctxsw_mailbox_clear_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fecs_fs_r(void) +{ + return 0x00409604U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_fs_num_available_gpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_fs_num_available_fbps_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_fs_num_available_fbps_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_m(void) +{ + return 0x1fU << 16U; +} +static inline u32 gr_fecs_fs_num_available_fbps_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_fecs_cfg_r(void) +{ + return 0x00409620U; +} +static inline u32 gr_fecs_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_fecs_rc_lanes_r(void) +{ + return 0x00409880U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_fecs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_fecs_ctxsw_status_1_r(void) +{ + return 0x00409400U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_m(void) +{ + return 0x1U << 12U; +} +static inline u32 gr_fecs_ctxsw_status_1_arb_busy_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_adr_r(void) +{ + return 0x00409a24U; +} +static inline u32 gr_fecs_new_ctx_r(void) +{ + return 0x00409b04U; +} +static inline u32 gr_fecs_new_ctx_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_new_ctx_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_new_ctx_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_new_ctx_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_new_ctx_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_new_ctx_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_new_ctx_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_new_ctx_valid_s(void) +{ + return 1U; +} +static inline u32 gr_fecs_new_ctx_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_fecs_new_ctx_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_fecs_arb_ctx_ptr_r(void) +{ + return 0x00409a0cU; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_s(void) +{ + return 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_m(void) +{ + return 0xfffffffU << 0U; +} +static inline u32 gr_fecs_arb_ctx_ptr_ptr_v(u32 r) +{ + return (r >> 0U) & 0xfffffffU; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_s(void) +{ + return 2U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_fecs_arb_ctx_ptr_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 gr_fecs_arb_ctx_cmd_r(void) +{ + return 0x00409a10U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_s(void) +{ + return 5U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_m(void) +{ + return 0x1fU << 0U; +} +static inline u32 gr_fecs_arb_ctx_cmd_cmd_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_fecs_ctxsw_status_fe_0_r(void) +{ + return 0x00409c00U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_gpc_0_r(void) +{ + return 0x00502c04U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_status_1_r(void) +{ + return 0x00502400U; +} +static inline u32 gr_fecs_ctxsw_idlestate_r(void) +{ + return 0x00409420U; +} +static inline u32 gr_fecs_feature_override_ecc_r(void) +{ + return 0x00409658U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_lrf_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_lrf_override_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_l1_data_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_l1_data_override_v(u32 r) +{ + return (r >> 7U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_l1_tag_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_l1_tag_override_v(u32 r) +{ + return (r >> 11U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_ltc_v(u32 r) +{ + return (r >> 12U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_ltc_override_v(u32 r) +{ + return (r >> 15U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_cbu_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_sm_cbu_override_v(u32 r) +{ + return (r >> 23U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_1_r(void) +{ + return 0x0040965cU; +} +static inline u32 gr_fecs_feature_override_ecc_1_sm_l0_icache_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_1_sm_l0_icache_override_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_1_sm_l1_icache_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_fecs_feature_override_ecc_1_sm_l1_icache_override_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 gr_gpc0_gpccs_ctxsw_idlestate_r(void) +{ + return 0x00502420U; +} +static inline u32 gr_rstr2d_gpc_map_r(u32 i) +{ + return 0x0040780cU + i*4U; +} +static inline u32 gr_rstr2d_map_table_cfg_r(void) +{ + return 0x004078bcU; +} +static inline u32 gr_rstr2d_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_rstr2d_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_hww_esr_r(void) +{ + return 0x00406018U; +} +static inline u32 gr_pd_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pd_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_num_tpc_per_gpc_r(u32 i) +{ + return 0x00406028U + i*4U; +} +static inline u32 gr_pd_num_tpc_per_gpc__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count1_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count2_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count3_f(u32 v) +{ + return (v & 0xfU) << 12U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count4_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count5_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count6_f(u32 v) +{ + return (v & 0xfU) << 24U; +} +static inline u32 gr_pd_num_tpc_per_gpc_count7_f(u32 v) +{ + return (v & 0xfU) << 28U; +} +static inline u32 gr_pd_ab_dist_cfg0_r(void) +{ + return 0x004064c0U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_en_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_pd_ab_dist_cfg0_timeslice_enable_dis_f(void) +{ + return 0x0U; +} +static inline u32 gr_pd_ab_dist_cfg1_r(void) +{ + return 0x004064c4U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_batches_init_f(void) +{ + return 0xffffU; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg1_max_output_granularity_v(void) +{ + return 0x00000080U; +} +static inline u32 gr_pd_ab_dist_cfg2_r(void) +{ + return 0x004064c8U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_f(u32 v) +{ + return (v & 0x1fffU) << 0U; +} +static inline u32 gr_pd_ab_dist_cfg2_token_limit_init_v(void) +{ + return 0x00000380U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_f(u32 v) +{ + return (v & 0x1fffU) << 16U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_scc_bundle_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_pd_ab_dist_cfg2_state_limit_min_gpm_fifo_depths_v(void) +{ + return 0x00000302U; +} +static inline u32 gr_pd_dist_skip_table_r(u32 i) +{ + return 0x004064d0U + i*4U; +} +static inline u32 gr_pd_dist_skip_table__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n0_mask_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n1_mask_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n2_mask_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_pd_dist_skip_table_gpc_4n3_mask_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_ds_debug_r(void) +{ + return 0x00405800U; +} +static inline u32 gr_ds_debug_timeslice_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_debug_timeslice_mode_enable_f(void) +{ + return 0x8000000U; +} +static inline u32 gr_ds_zbc_color_r_r(void) +{ + return 0x00405804U; +} +static inline u32 gr_ds_zbc_color_r_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_g_r(void) +{ + return 0x00405808U; +} +static inline u32 gr_ds_zbc_color_g_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_b_r(void) +{ + return 0x0040580cU; +} +static inline u32 gr_ds_zbc_color_b_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_a_r(void) +{ + return 0x00405810U; +} +static inline u32 gr_ds_zbc_color_a_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_r(void) +{ + return 0x00405814U; +} +static inline u32 gr_ds_zbc_color_fmt_val_f(u32 v) +{ + return (v & 0x7fU) << 0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_color_fmt_val_zero_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_color_fmt_val_unorm_one_v(void) +{ + return 0x00000002U; +} +static inline u32 gr_ds_zbc_color_fmt_val_rf32_gf32_bf32_af32_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_ds_zbc_color_fmt_val_a8_b8_g8_r8_v(void) +{ + return 0x00000028U; +} +static inline u32 gr_ds_zbc_z_r(void) +{ + return 0x00405818U; +} +static inline u32 gr_ds_zbc_z_val_s(void) +{ + return 32U; +} +static inline u32 gr_ds_zbc_z_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_ds_zbc_z_val_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_ds_zbc_z_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_ds_zbc_z_val__init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_ds_zbc_z_val__init_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_r(void) +{ + return 0x0040581cU; +} +static inline u32 gr_ds_zbc_z_fmt_val_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_invalid_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_z_fmt_val_fp32_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_zbc_tbl_index_r(void) +{ + return 0x00405820U; +} +static inline u32 gr_ds_zbc_tbl_index_val_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_ds_zbc_tbl_ld_r(void) +{ + return 0x00405824U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_c_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_select_z_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_zbc_tbl_ld_action_write_f(void) +{ + return 0x0U; +} +static inline u32 gr_ds_zbc_tbl_ld_trigger_active_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_tga_constraintlogic_beta_r(void) +{ + return 0x00405830U; +} +static inline u32 gr_ds_tga_constraintlogic_beta_cbsize_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_ds_tga_constraintlogic_alpha_r(void) +{ + return 0x0040585cU; +} +static inline u32 gr_ds_tga_constraintlogic_alpha_cbsize_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_ds_hww_esr_r(void) +{ + return 0x00405840U; +} +static inline u32 gr_ds_hww_esr_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_esr_2_r(void) +{ + return 0x00405848U; +} +static inline u32 gr_ds_hww_esr_2_reset_s(void) +{ + return 1U; +} +static inline u32 gr_ds_hww_esr_2_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_ds_hww_esr_2_reset_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_ds_hww_esr_2_reset_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 gr_ds_hww_esr_2_reset_task_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_ds_hww_esr_2_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ds_hww_esr_2_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ds_hww_report_mask_r(void) +{ + return 0x00405844U; +} +static inline u32 gr_ds_hww_report_mask_sph0_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_hww_report_mask_sph1_err_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_ds_hww_report_mask_sph2_err_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_ds_hww_report_mask_sph3_err_report_f(void) +{ + return 0x8U; +} +static inline u32 gr_ds_hww_report_mask_sph4_err_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_ds_hww_report_mask_sph5_err_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_ds_hww_report_mask_sph6_err_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_ds_hww_report_mask_sph7_err_report_f(void) +{ + return 0x80U; +} +static inline u32 gr_ds_hww_report_mask_sph8_err_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_ds_hww_report_mask_sph9_err_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_ds_hww_report_mask_sph10_err_report_f(void) +{ + return 0x400U; +} +static inline u32 gr_ds_hww_report_mask_sph11_err_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_ds_hww_report_mask_sph12_err_report_f(void) +{ + return 0x1000U; +} +static inline u32 gr_ds_hww_report_mask_sph13_err_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_ds_hww_report_mask_sph14_err_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_ds_hww_report_mask_sph15_err_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_ds_hww_report_mask_sph16_err_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_ds_hww_report_mask_sph17_err_report_f(void) +{ + return 0x20000U; +} +static inline u32 gr_ds_hww_report_mask_sph18_err_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_ds_hww_report_mask_sph19_err_report_f(void) +{ + return 0x80000U; +} +static inline u32 gr_ds_hww_report_mask_sph20_err_report_f(void) +{ + return 0x100000U; +} +static inline u32 gr_ds_hww_report_mask_sph21_err_report_f(void) +{ + return 0x200000U; +} +static inline u32 gr_ds_hww_report_mask_sph22_err_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_ds_hww_report_mask_sph23_err_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_ds_hww_report_mask_2_r(void) +{ + return 0x0040584cU; +} +static inline u32 gr_ds_hww_report_mask_2_sph24_err_report_f(void) +{ + return 0x1U; +} +static inline u32 gr_ds_num_tpc_per_gpc_r(u32 i) +{ + return 0x00405870U + i*4U; +} +static inline u32 gr_scc_debug_r(void) +{ + return 0x00408000U; +} +static inline u32 gr_scc_debug_pagepool_invalidates_m(void) +{ + return 0x1U << 9U; +} +static inline u32 gr_scc_debug_pagepool_invalidates_disable_f(void) +{ + return 0x200U; +} +static inline u32 gr_scc_debug_pagepool_invalidates_enable_f(void) +{ + return 0x0U; +} +static inline u32 gr_scc_bundle_cb_base_r(void) +{ + return 0x00408004U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_bundle_cb_size_r(void) +{ + return 0x00408008U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b__prod_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_scc_bundle_cb_size_div_256b_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_scc_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_pagepool_base_r(void) +{ + return 0x0040800cU; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_scc_pagepool_base_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_scc_pagepool_r(void) +{ + return 0x00408010U; +} +static inline u32 gr_scc_pagepool_total_pages_f(u32 v) +{ + return (v & 0x3ffU) << 0U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_scc_pagepool_total_pages_hwmax_value_v(void) +{ + return 0x00000200U; +} +static inline u32 gr_scc_pagepool_total_pages_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_s(void) +{ + return 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_f(u32 v) +{ + return (v & 0x3ffU) << 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_m(void) +{ + return 0x3ffU << 10U; +} +static inline u32 gr_scc_pagepool_max_valid_pages_v(u32 r) +{ + return (r >> 10U) & 0x3ffU; +} +static inline u32 gr_scc_pagepool_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_scc_init_r(void) +{ + return 0x0040802cU; +} +static inline u32 gr_scc_init_ram_trigger_f(void) +{ + return 0x1U; +} +static inline u32 gr_scc_hww_esr_r(void) +{ + return 0x00408030U; +} +static inline u32 gr_scc_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_scc_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_ssync_hww_esr_r(void) +{ + return 0x00405a14U; +} +static inline u32 gr_ssync_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_ssync_hww_esr_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_sked_hww_esr_r(void) +{ + return 0x00407020U; +} +static inline u32 gr_sked_hww_esr_reset_active_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_sked_hww_esr_en_r(void) +{ + return 0x00407024U; +} +static inline u32 gr_sked_hww_esr_en_skedcheck18_l1_config_too_small_m(void) +{ + return 0x1U << 25U; +} +static inline u32 gr_sked_hww_esr_en_skedcheck18_l1_config_too_small_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_sked_hww_esr_en_skedcheck18_l1_config_too_small_enabled_f(void) +{ + return 0x2000000U; +} +static inline u32 gr_cwd_fs_r(void) +{ + return 0x00405b00U; +} +static inline u32 gr_cwd_fs_num_gpcs_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_fs_num_tpcs_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_cwd_gpc_tpc_id_r(u32 i) +{ + return 0x00405b60U + i*4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc0_s(void) +{ + return 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc0_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_cwd_gpc_tpc_id_gpc0_s(void) +{ + return 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_gpc0_f(u32 v) +{ + return (v & 0xfU) << 4U; +} +static inline u32 gr_cwd_gpc_tpc_id_tpc1_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_cwd_sm_id_r(u32 i) +{ + return 0x00405ba0U + i*4U; +} +static inline u32 gr_cwd_sm_id__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_cwd_sm_id_tpc0_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_cwd_sm_id_tpc1_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpc0_fs_gpc_r(void) +{ + return 0x00502608U; +} +static inline u32 gr_gpc0_fs_gpc_num_available_tpcs_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 gr_gpc0_fs_gpc_num_available_zculls_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +static inline u32 gr_gpc0_cfg_r(void) +{ + return 0x00502620U; +} +static inline u32 gr_gpc0_cfg_imem_sz_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpccs_rc_lanes_r(void) +{ + return 0x00502880U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_rc_lanes_num_chains_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_rc_lane_size_r(void) +{ + return 0x00502910U; +} +static inline u32 gr_gpccs_rc_lane_size_v_s(void) +{ + return 24U; +} +static inline u32 gr_gpccs_rc_lane_size_v_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 gr_gpccs_rc_lane_size_v_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_rc_lane_size_v_0_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_zcull_fs_r(void) +{ + return 0x00500910U; +} +static inline u32 gr_gpc0_zcull_fs_num_sms_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 gr_gpc0_zcull_fs_num_active_banks_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 gr_gpc0_zcull_ram_addr_r(void) +{ + return 0x00500914U; +} +static inline u32 gr_gpc0_zcull_ram_addr_tiles_per_hypertile_row_per_gpc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_gpc0_zcull_ram_addr_row_offset_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_r(void) +{ + return 0x00500918U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_sm_num_rcp_conservative__max_v(void) +{ + return 0x00800000U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_r(void) +{ + return 0x00500920U; +} +static inline u32 gr_gpc0_zcull_total_ram_size_num_aliquots_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_zcull_zcsize_r(u32 i) +{ + return 0x00500a04U + i*32U; +} +static inline u32 gr_gpc0_zcull_zcsize_height_subregion__multiple_v(void) +{ + return 0x00000040U; +} +static inline u32 gr_gpc0_zcull_zcsize_width_subregion__multiple_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_r(u32 i) +{ + return 0x00500c10U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_sm_id_id_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_r(u32 i) +{ + return 0x00500c30U + i*4U; +} +static inline u32 gr_gpc0_gpm_pd_pes_tpc_id_mask_mask_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_r(void) +{ + return 0x00504088U; +} +static inline u32 gr_gpc0_tpc0_pe_cfg_smid_value_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_r(void) +{ + return 0x00504608U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_tpc_id_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_tpc0_sm_cfg_tpc_id_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_r(void) +{ + return 0x00504330U; +} +static inline u32 gr_gpc0_tpc0_sm_arch_warp_count_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_spa_version_v(u32 r) +{ + return (r >> 8U) & 0xfffU; +} +static inline u32 gr_gpc0_tpc0_sm_arch_sm_version_v(u32 r) +{ + return (r >> 20U) & 0xfffU; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_r(void) +{ + return 0x00503018U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_ppc0_pes_vsc_strem_master_pe_true_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_r(void) +{ + return 0x005030c0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_m(void) +{ + return 0x3fffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_default_v(void) +{ + return 0x00000800U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_gfxp_v(void) +{ + return 0x00001100U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_size_v_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_cb_offset_r(void) +{ + return 0x005030f4U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_r(void) +{ + return 0x005030e4U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_default_v(void) +{ + return 0x00000800U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_size_v_granularity_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_gpc0_ppc0_cbm_alpha_cb_offset_r(void) +{ + return 0x005030f8U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_r(void) +{ + return 0x005030f0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_v_default_v(void) +{ + return 0x00000800U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_0_r(void) +{ + return 0x00419e00U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_0_base_addr_43_12_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_r(void) +{ + return 0x00419e04U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_s(void) +{ + return 21U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_f(u32 v) +{ + return (v & 0x1fffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_m(void) +{ + return 0x1fffffU << 0U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_v(u32 r) +{ + return (r >> 0U) & 0x1fffffU; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_granularity_f(void) +{ + return 0x80U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_s(void) +{ + return 1U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_tpcs_tex_rm_cb_1_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpccs_falcon_addr_r(void) +{ + return 0x0041a0acU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_lsb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_msb_s(void) +{ + return 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 gr_gpccs_falcon_addr_msb_v(u32 r) +{ + return (r >> 6U) & 0x3fU; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpccs_falcon_addr_msb_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_s(void) +{ + return 12U; +} +static inline u32 gr_gpccs_falcon_addr_ext_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_m(void) +{ + return 0xfffU << 0U; +} +static inline u32 gr_gpccs_falcon_addr_ext_v(u32 r) +{ + return (r >> 0U) & 0xfffU; +} +static inline u32 gr_gpccs_cpuctl_r(void) +{ + return 0x0041a100U; +} +static inline u32 gr_gpccs_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_gpccs_dmactl_r(void) +{ + return 0x0041a10cU; +} +static inline u32 gr_gpccs_dmactl_require_ctx_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpccs_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpccs_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpccs_imemc_r(u32 i) +{ + return 0x0041a180U + i*16U; +} +static inline u32 gr_gpccs_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_imemd_r(u32 i) +{ + return 0x0041a184U + i*16U; +} +static inline u32 gr_gpccs_imemt_r(u32 i) +{ + return 0x0041a188U + i*16U; +} +static inline u32 gr_gpccs_imemt__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 gr_gpccs_imemt_tag_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpccs_dmemc_r(u32 i) +{ + return 0x0041a1c0U + i*8U; +} +static inline u32 gr_gpccs_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 gr_gpccs_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpccs_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 gr_gpccs_dmemd_r(u32 i) +{ + return 0x0041a1c4U + i*8U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_r(u32 i) +{ + return 0x0041a800U + i*4U; +} +static inline u32 gr_gpccs_ctxsw_mailbox_value_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_r(void) +{ + return 0x00418e24U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_s(void) +{ + return 32U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_init_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_base_addr_39_8_init_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_r(void) +{ + return 0x00418e28U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_s(void) +{ + return 11U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_f(u32 v) +{ + return (v & 0x7ffU) << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_m(void) +{ + return 0x7ffU << 0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_v(u32 r) +{ + return (r >> 0U) & 0x7ffU; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_init_v(void) +{ + return 0x00000030U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_div_256b_init_f(void) +{ + return 0x30U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_s(void) +{ + return 1U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_swdx_bundle_cb_size_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_r(void) +{ + return 0x005001dcU; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_default_v(void) +{ + return 0x00000170U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_size_256b_byte_granularity_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_r(void) +{ + return 0x005001d8U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpc0_swdx_rm_spill_buffer_addr_39_8_align_bits_v(void) +{ + return 0x00000008U; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_r(void) +{ + return 0x004181e4U; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_cbes_reserve_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpcs_swdx_beta_cb_ctrl_cbes_reserve_gfxp_v(void) +{ + return 0x00000100U; +} +static inline u32 gr_gpcs_ppcs_cbm_beta_cb_ctrl_r(void) +{ + return 0x0041befcU; +} +static inline u32 gr_gpcs_ppcs_cbm_beta_cb_ctrl_cbes_reserve_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 gr_gpcs_ppcs_cbm_debug_r(void) +{ + return 0x0041bec4U; +} +static inline u32 gr_gpcs_ppcs_cbm_debug_invalidate_alpha_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_ppcs_cbm_debug_invalidate_alpha_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_ppcs_cbm_debug_invalidate_alpha_enable_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_ppcs_cbm_debug_invalidate_beta_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpcs_ppcs_cbm_debug_invalidate_beta_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_ppcs_cbm_debug_invalidate_beta_enable_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_r(u32 i) +{ + return 0x00418ea0U + i*4U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_v_f(u32 v) +{ + return (v & 0x3fffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_tc_beta_cb_size_v_m(void) +{ + return 0x3fffffU << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_r_r(u32 i) +{ + return 0x00418010U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_r_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_g_r(u32 i) +{ + return 0x0041804cU + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_g_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_b_r(u32 i) +{ + return 0x00418088U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_b_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_a_r(u32 i) +{ + return 0x004180c4U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_color_a_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_c_01_to_04_format_r(void) +{ + return 0x00418100U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_r(u32 i) +{ + return 0x00418110U + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_z_01_to_04_format_r(void) +{ + return 0x0041814cU; +} +static inline u32 gr_gpcs_swdx_dss_zbc_s_r(u32 i) +{ + return 0x0041815cU + i*4U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_s_val_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_gpcs_swdx_dss_zbc_s_01_to_04_format_r(void) +{ + return 0x00418198U; +} +static inline u32 gr_gpcs_swdx_spill_unit_r(void) +{ + return 0x00418e9cU; +} +static inline u32 gr_gpcs_swdx_spill_unit_spill_buffer_cache_mgmt_mode_m(void) +{ + return 0x1U << 16U; +} +static inline u32 gr_gpcs_swdx_spill_unit_spill_buffer_cache_mgmt_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_swdx_spill_unit_spill_buffer_cache_mgmt_mode_enabled_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_r(void) +{ + return 0x00418810U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_addr_39_12_align_bits_v(void) +{ + return 0x0000000cU; +} +static inline u32 gr_gpcs_setup_attrib_cb_base_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_crstr_gpc_map_r(u32 i) +{ + return 0x00418b08U + i*4U; +} +static inline u32 gr_crstr_gpc_map_tile0_f(u32 v) +{ + return (v & 0x1fU) << 0U; +} +static inline u32 gr_crstr_gpc_map_tile1_f(u32 v) +{ + return (v & 0x1fU) << 5U; +} +static inline u32 gr_crstr_gpc_map_tile2_f(u32 v) +{ + return (v & 0x1fU) << 10U; +} +static inline u32 gr_crstr_gpc_map_tile3_f(u32 v) +{ + return (v & 0x1fU) << 15U; +} +static inline u32 gr_crstr_gpc_map_tile4_f(u32 v) +{ + return (v & 0x1fU) << 20U; +} +static inline u32 gr_crstr_gpc_map_tile5_f(u32 v) +{ + return (v & 0x1fU) << 25U; +} +static inline u32 gr_crstr_map_table_cfg_r(void) +{ + return 0x00418bb8U; +} +static inline u32 gr_crstr_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_crstr_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_r(u32 i) +{ + return 0x00418980U + i*4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_0_f(u32 v) +{ + return (v & 0x7U) << 0U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_1_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_2_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_3_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_4_f(u32 v) +{ + return (v & 0x7U) << 16U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_5_f(u32 v) +{ + return (v & 0x7U) << 20U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_6_f(u32 v) +{ + return (v & 0x7U) << 24U; +} +static inline u32 gr_gpcs_zcull_sm_in_gpc_number_map_tile_7_f(u32 v) +{ + return (v & 0x7U) << 28U; +} +static inline u32 gr_gpcs_gpm_pd_cfg_r(void) +{ + return 0x00418c6cU; +} +static inline u32 gr_gpcs_gcc_pagepool_base_r(void) +{ + return 0x00419004U; +} +static inline u32 gr_gpcs_gcc_pagepool_base_addr_39_8_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpcs_gcc_pagepool_r(void) +{ + return 0x00419008U; +} +static inline u32 gr_gpcs_gcc_pagepool_total_pages_f(u32 v) +{ + return (v & 0x3ffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_r(void) +{ + return 0x0041980cU; +} +static inline u32 gr_gpcs_tpcs_pe_vaf_fast_mode_switch_true_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_r(void) +{ + return 0x00419848U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_pe_pin_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_r(void) +{ + return 0x00419c00U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_debug_timeslice_mode_enabled_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_r(void) +{ + return 0x00419c2cU; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_v_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_valid_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_valid_true_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_gpcs_tpcs_sms_hww_warp_esr_report_mask_r(void) +{ + return 0x00419ea8U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_r(void) +{ + return 0x00504728U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_stack_error_report_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_api_stack_error_report_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_pc_wrap_report_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_misaligned_pc_report_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_pc_overflow_report_f(void) +{ + return 0x40U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_misaligned_reg_report_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_illegal_instr_encoding_report_f(void) +{ + return 0x200U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_illegal_instr_param_report_f(void) +{ + return 0x800U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_oor_reg_report_f(void) +{ + return 0x2000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_oor_addr_report_f(void) +{ + return 0x4000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_misaligned_addr_report_f(void) +{ + return 0x8000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_invalid_addr_space_report_f(void) +{ + return 0x10000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_invalid_const_addr_ldc_report_f(void) +{ + return 0x40000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_mmu_fault_report_f(void) +{ + return 0x800000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_stack_overflow_report_f(void) +{ + return 0x400000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_report_mask_mmu_nack_report_f(void) +{ + return 0x4000000U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_r(void) +{ + return 0x00419d0cU; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_tex_enabled_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpcs_tpcs_tpccs_tpc_exception_en_mpc_enabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_r(void) +{ + return 0x0050450cU; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_sm_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_en_mpc_enabled_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_r(void) +{ + return 0x0041ac94U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_gcc_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_tpc_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_gpccs_f(u32 v) +{ + return (v & 0x1U) << 14U; +} +static inline u32 gr_gpcs_gpccs_gpc_exception_en_gpcmmu_f(u32 v) +{ + return (v & 0x1U) << 15U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_r(void) +{ + return 0x00502c90U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gcc_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_tpc_0_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gpccs_f(u32 v) +{ + return (v & 0x1U) << 14U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gpccs_m(void) +{ + return 0x1U << 14U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gpccs_pending_f(void) +{ + return 0x4000U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gpcmmu_f(u32 v) +{ + return (v & 0x1U) << 15U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gpcmmu_m(void) +{ + return 0x1U << 15U; +} +static inline u32 gr_gpc0_gpccs_gpc_exception_gpcmmu_pending_f(void) +{ + return 0x8000U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_status_r(void) +{ + return 0x00501048U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_status_corrected_err_bank0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_status_corrected_err_bank1_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_status_uncorrected_err_bank0_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_status_uncorrected_err_bank1_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_status_corrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_status_uncorrected_err_total_counter_overflow_v(u32 r) +{ + return (r >> 10U) & 0x1U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_status_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_corrected_err_count_r(void) +{ + return 0x0050104cU; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_uncorrected_err_count_r(void) +{ + return 0x00501054U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_pri_gpc0_gcc_l15_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_r(void) +{ + return 0x00504508U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_tex_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_sm_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_mpc_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpc0_tpc0_tpccs_tpc_exception_mpc_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_r(void) +{ + return 0x00504704U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_on_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_on_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_off_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_off_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_stop_trigger_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_stop_trigger_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_stop_trigger_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_single_step_mode_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_single_step_mode_enable_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_single_step_mode_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_control0_run_trigger_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_tpc0_sm0_warp_valid_mask_0_r(void) +{ + return 0x00504708U; +} +static inline u32 gr_gpc0_tpc0_sm0_warp_valid_mask_1_r(void) +{ + return 0x0050470cU; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_bpt_pause_mask_0_r(void) +{ + return 0x00504710U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_bpt_pause_mask_1_r(void) +{ + return 0x00504714U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_bpt_trap_mask_0_r(void) +{ + return 0x00504718U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_bpt_trap_mask_1_r(void) +{ + return 0x0050471cU; +} +static inline u32 gr_gpcs_tpcs_sms_dbgr_bpt_pause_mask_0_r(void) +{ + return 0x00419e90U; +} +static inline u32 gr_gpcs_tpcs_sms_dbgr_bpt_pause_mask_1_r(void) +{ + return 0x00419e94U; +} +static inline u32 gr_gpcs_tpcs_sms_dbgr_status0_r(void) +{ + return 0x00419e80U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_status0_r(void) +{ + return 0x00504700U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_status0_sm_in_trap_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_status0_locked_down_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_dbgr_status0_locked_down_true_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_r(void) +{ + return 0x00504730U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_none_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_none_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_stack_error_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_api_stack_error_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_pc_wrap_f(void) +{ + return 0x4U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_misaligned_pc_f(void) +{ + return 0x5U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_pc_overflow_f(void) +{ + return 0x6U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_misaligned_reg_f(void) +{ + return 0x8U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_illegal_instr_encoding_f(void) +{ + return 0x9U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_illegal_instr_param_f(void) +{ + return 0xbU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_oor_reg_f(void) +{ + return 0xdU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_oor_addr_f(void) +{ + return 0xeU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_misaligned_addr_f(void) +{ + return 0xfU; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_invalid_addr_space_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_invalid_const_addr_ldc_f(void) +{ + return 0x12U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_stack_overflow_f(void) +{ + return 0x16U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_mmu_fault_f(void) +{ + return 0x17U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_tex_format_f(void) +{ + return 0x18U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_tex_layout_f(void) +{ + return 0x19U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_error_mmu_nack_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_wrap_id_m(void) +{ + return 0xffU << 16U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_addr_error_type_m(void) +{ + return 0xfU << 24U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_addr_error_type_none_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpc0_tpc0_sm_tpc_esr_sm_sel_r(void) +{ + return 0x0050460cU; +} +static inline u32 gr_gpc0_tpc0_sm_tpc_esr_sm_sel_sm0_error_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm_tpc_esr_sm_sel_sm1_error_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_pc_r(void) +{ + return 0x00504738U; +} +static inline u32 gr_gpc0_tpc0_sm0_hww_warp_esr_pc_hi_r(void) +{ + return 0x0050473cU; +} +static inline u32 gr_gpc0_tpc0_sm_halfctl_ctrl_r(void) +{ + return 0x005043a0U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_r(void) +{ + return 0x00419ba0U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpcs_tpcs_sm_halfctl_ctrl_sctl_read_quad_ctl_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_gpc0_tpc0_sm_debug_sfe_control_r(void) +{ + return 0x005043b0U; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_r(void) +{ + return 0x00419bb0U; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_tpcs_sm_debug_sfe_control_read_half_ctl_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_r(void) +{ + return 0x0041be08U; +} +static inline u32 gr_gpcs_tpcs_pes_vsc_vpc_fast_mode_switch_true_f(void) +{ + return 0x4U; +} +static inline u32 gr_ppcs_wwdx_map_gpc_map_r(u32 i) +{ + return 0x0041bf00U + i*4U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_r(void) +{ + return 0x0041bfd0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_row_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_num_entries_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_num_entries_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_normalized_shift_value_f(u32 v) +{ + return (v & 0x7U) << 21U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_r(void) +{ + return 0x0041bfd4U; +} +static inline u32 gr_gpcs_ppcs_wwdx_sm_num_rcp_conservative_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff_r(u32 i) +{ + return 0x0041bfb0U + i*4U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff__size_1_v(void) +{ + return 0x00000005U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff_0_mod_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff_1_mod_value_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff_2_mod_value_f(u32 v) +{ + return (v & 0xffU) << 16U; +} +static inline u32 gr_ppcs_wwdx_map_table_cfg_coeff_3_mod_value_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 gr_bes_zrop_settings_r(void) +{ + return 0x00408850U; +} +static inline u32 gr_bes_zrop_settings_num_active_ltcs_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_be0_crop_debug3_r(void) +{ + return 0x00410108U; +} +static inline u32 gr_bes_crop_debug3_r(void) +{ + return 0x00408908U; +} +static inline u32 gr_bes_crop_debug3_comp_vdc_4to2_disable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug3_blendopt_read_suppress_enabled_f(void) +{ + return 0x2U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug3_blendopt_fill_override_enabled_f(void) +{ + return 0x4U; +} +static inline u32 gr_bes_crop_debug4_r(void) +{ + return 0x0040894cU; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_m(void) +{ + return 0x1U << 18U; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_to_inf_f(void) +{ + return 0x0U; +} +static inline u32 gr_bes_crop_debug4_clamp_fp_blend_to_maxval_f(void) +{ + return 0x40000U; +} +static inline u32 gr_bes_crop_settings_r(void) +{ + return 0x00408958U; +} +static inline u32 gr_bes_crop_settings_num_active_ltcs_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 gr_zcull_bytes_per_aliquot_per_gpu_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_header_bytes_per_gpc_v(void) +{ + return 0x00000020U; +} +static inline u32 gr_zcull_save_restore_subregion_header_bytes_per_gpc_v(void) +{ + return 0x000000c0U; +} +static inline u32 gr_zcull_subregion_qty_v(void) +{ + return 0x00000010U; +} +static inline u32 gr_gpcs_tpcs_tex_in_dbg_r(void) +{ + return 0x00419a00U; +} +static inline u32 gr_gpcs_tpcs_tex_in_dbg_tsl1_rvch_invalidate_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 gr_gpcs_tpcs_tex_in_dbg_tsl1_rvch_invalidate_m(void) +{ + return 0x1U << 19U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_r(void) +{ + return 0x00419bf0U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_cache_surface_ld_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_cache_surface_ld_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_cache_surface_st_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_cache_surface_st_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_always_cut_collector_m(void) +{ + return 0x1U << 28U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_always_cut_collector_disable_f(void) +{ + return 0x0U; +} +static inline u32 gr_gpcs_tpcs_sm_l1tag_ctrl_always_cut_collector_enable_f(void) +{ + return 0x10000000U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter_control_sel0_r(void) +{ + return 0x00584200U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter_control_sel1_r(void) +{ + return 0x00584204U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter_control0_r(void) +{ + return 0x00584208U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter_control1_r(void) +{ + return 0x00584210U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter_control2_r(void) +{ + return 0x00584214U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter_control3_r(void) +{ + return 0x00584218U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter_control4_r(void) +{ + return 0x0058421cU; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter_control5_r(void) +{ + return 0x0058420cU; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter0_control_r(void) +{ + return 0x00584220U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter1_control_r(void) +{ + return 0x00584224U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter2_control_r(void) +{ + return 0x00584228U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter3_control_r(void) +{ + return 0x0058422cU; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter4_control_r(void) +{ + return 0x00584230U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter5_control_r(void) +{ + return 0x00584234U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter6_control_r(void) +{ + return 0x00584238U; +} +static inline u32 gr_egpc0_etpc0_sm_dsm_perf_counter7_control_r(void) +{ + return 0x0058423cU; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter_status_s0_r(void) +{ + return 0x00584600U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter_status_s1_r(void) +{ + return 0x00584604U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter0_s0_r(void) +{ + return 0x00584624U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter1_s0_r(void) +{ + return 0x00584628U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter2_s0_r(void) +{ + return 0x0058462cU; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter3_s0_r(void) +{ + return 0x00584630U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter0_s1_r(void) +{ + return 0x00584634U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter1_s1_r(void) +{ + return 0x00584638U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter2_s1_r(void) +{ + return 0x0058463cU; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter3_s1_r(void) +{ + return 0x00584640U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter0_s2_r(void) +{ + return 0x00584644U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter1_s2_r(void) +{ + return 0x00584648U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter2_s2_r(void) +{ + return 0x0058464cU; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter3_s2_r(void) +{ + return 0x00584650U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter0_s3_r(void) +{ + return 0x00584654U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter1_s3_r(void) +{ + return 0x00584658U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter2_s3_r(void) +{ + return 0x0058465cU; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter3_s3_r(void) +{ + return 0x00584660U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter4_r(void) +{ + return 0x00584614U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter5_r(void) +{ + return 0x00584618U; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter6_r(void) +{ + return 0x0058461cU; +} +static inline u32 gr_egpc0_etpc0_sm0_dsm_perf_counter7_r(void) +{ + return 0x00584620U; +} +static inline u32 gr_fe_pwr_mode_r(void) +{ + return 0x00404170U; +} +static inline u32 gr_fe_pwr_mode_mode_auto_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_pwr_mode_mode_force_on_f(void) +{ + return 0x2U; +} +static inline u32 gr_fe_pwr_mode_req_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 gr_fe_pwr_mode_req_send_f(void) +{ + return 0x10U; +} +static inline u32 gr_fe_pwr_mode_req_done_v(void) +{ + return 0x00000000U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_r(void) +{ + return 0x00418880U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_vm_pg_size_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_use_pdb_big_page_size_m(void) +{ + return 0x1U << 11U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_vol_fault_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_comp_fault_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_miss_gran_m(void) +{ + return 0x3U << 3U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_cache_mode_m(void) +{ + return 0x3U << 5U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_aperture_m(void) +{ + return 0x3U << 28U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_vol_m(void) +{ + return 0x1U << 30U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_mmu_disable_m(void) +{ + return 0x1U << 31U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_atomic_capability_mode_m(void) +{ + return 0x3U << 24U; +} +static inline u32 gr_gpcs_pri_mmu_ctrl_atomic_capability_sys_ncoh_mode_m(void) +{ + return 0x1U << 27U; +} +static inline u32 gr_gpcs_pri_mmu_pm_unit_mask_r(void) +{ + return 0x00418890U; +} +static inline u32 gr_gpcs_pri_mmu_pm_req_mask_r(void) +{ + return 0x00418894U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_r(void) +{ + return 0x004188b0U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 gr_gpcs_pri_mmu_debug_ctrl_debug_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 gr_gpcs_pri_mmu_debug_wr_r(void) +{ + return 0x004188b4U; +} +static inline u32 gr_gpcs_pri_mmu_debug_rd_r(void) +{ + return 0x004188b8U; +} +static inline u32 gr_gpcs_mmu_num_active_ltcs_r(void) +{ + return 0x004188acU; +} +static inline u32 gr_gpcs_tpcs_sms_dbgr_control0_r(void) +{ + return 0x00419e84U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_r(void) +{ + return 0x004041c0U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_count_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_count_disabled_f(void) +{ + return 0x0U; +} +static inline u32 gr_fe_gfxp_wfi_timeout_count_init_f(void) +{ + return 0x800U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_r(void) +{ + return 0x00419bd8U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_m(void) +{ + return 0x7U << 8U; +} +static inline u32 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_arm_63_48_match_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_r(void) +{ + return 0x00419ba4U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_re_suppress_m(void) +{ + return 0x3U << 11U; +} +static inline u32 gr_gpcs_tpcs_sm_disp_ctrl_re_suppress_disable_f(void) +{ + return 0x1000U; +} +static inline u32 gr_gpcs_tc_debug0_r(void) +{ + return 0x00418708U; +} +static inline u32 gr_gpcs_tc_debug0_limit_coalesce_buffer_size_f(u32 v) +{ + return (v & 0x1ffU) << 0U; +} +static inline u32 gr_gpcs_tc_debug0_limit_coalesce_buffer_size_m(void) +{ + return 0x1ffU << 0U; +} +static inline u32 gr_gpc0_mmu_gpcmmu_global_esr_r(void) +{ + return 0x00500324U; +} +static inline u32 gr_gpc0_mmu_gpcmmu_global_esr_ecc_corrected_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpc0_mmu_gpcmmu_global_esr_ecc_corrected_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_mmu_gpcmmu_global_esr_ecc_uncorrected_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_gpc0_mmu_gpcmmu_global_esr_ecc_uncorrected_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_r(void) +{ + return 0x00500314U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_corrected_err_l1tlb_sa_data_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_corrected_err_l1tlb_sa_data_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_corrected_err_l1tlb_fa_data_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_corrected_err_l1tlb_fa_data_m(void) +{ + return 0x1U << 2U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_uncorrected_err_l1tlb_sa_data_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_uncorrected_err_l1tlb_sa_data_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_uncorrected_err_l1tlb_fa_data_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_uncorrected_err_l1tlb_fa_data_m(void) +{ + return 0x1U << 3U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_uncorrected_err_total_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_uncorrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 18U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_corrected_err_total_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_corrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 16U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_uncorrected_err_unique_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_uncorrected_err_unique_counter_overflow_m(void) +{ + return 0x1U << 19U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_corrected_err_unique_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_corrected_err_unique_counter_overflow_m(void) +{ + return 0x1U << 17U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_status_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_address_r(void) +{ + return 0x00500320U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_address_index_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_corrected_err_count_r(void) +{ + return 0x00500318U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_corrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_corrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_corrected_err_count_unique_total_s(void) +{ + return 16U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_corrected_err_count_unique_total_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_corrected_err_count_unique_total_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_corrected_err_count_unique_total_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_uncorrected_err_count_r(void) +{ + return 0x0050031cU; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_uncorrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_uncorrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_uncorrected_err_count_unique_total_s(void) +{ + return 16U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_uncorrected_err_count_unique_total_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_uncorrected_err_count_unique_total_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 gr_gpc0_mmu_l1tlb_ecc_uncorrected_err_count_unique_total_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 gr_gpc0_gpccs_hww_esr_r(void) +{ + return 0x00502c98U; +} +static inline u32 gr_gpc0_gpccs_hww_esr_ecc_corrected_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpc0_gpccs_hww_esr_ecc_corrected_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_gpccs_hww_esr_ecc_corrected_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_gpccs_hww_esr_ecc_uncorrected_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_gpc0_gpccs_hww_esr_ecc_uncorrected_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpc0_gpccs_hww_esr_ecc_uncorrected_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_r(void) +{ + return 0x00502678U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_imem_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_imem_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_imem_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_dmem_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_dmem_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_dmem_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_imem_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_imem_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_dmem_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_dmem_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_dmem_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_total_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_total_counter_overflow_pending_f(void) +{ + return 0x400U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_total_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_total_counter_overflow_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_unique_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_unique_counter_overflow_m(void) +{ + return 0x1U << 11U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_uncorrected_err_unique_counter_overflow_pending_f(void) +{ + return 0x800U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_unique_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 9U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_unique_counter_overflow_m(void) +{ + return 0x1U << 9U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_corrected_err_unique_counter_overflow_pending_f(void) +{ + return 0x200U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_reset_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_status_reset_task_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_address_r(void) +{ + return 0x00502684U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_address_index_f(u32 v) +{ + return (v & 0x7fffffU) << 0U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_address_row_address_s(void) +{ + return 20U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_address_row_address_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_address_row_address_m(void) +{ + return 0xfffffU << 0U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_address_row_address_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_corrected_err_count_r(void) +{ + return 0x0050267cU; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_corrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_corrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_corrected_err_count_unique_total_s(void) +{ + return 16U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_corrected_err_count_unique_total_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_corrected_err_count_unique_total_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_corrected_err_count_unique_total_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_uncorrected_err_count_r(void) +{ + return 0x00502680U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_uncorrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_uncorrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_uncorrected_err_count_unique_total_s(void) +{ + return 16U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_uncorrected_err_count_unique_total_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_uncorrected_err_count_unique_total_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 gr_gpc0_gpccs_falcon_ecc_uncorrected_err_count_unique_total_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 gr_fecs_falcon_ecc_status_r(void) +{ + return 0x00409678U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_imem_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_imem_m(void) +{ + return 0x1U << 0U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_imem_pending_f(void) +{ + return 0x1U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_dmem_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_dmem_m(void) +{ + return 0x1U << 1U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_dmem_pending_f(void) +{ + return 0x2U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_imem_m(void) +{ + return 0x1U << 4U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_imem_pending_f(void) +{ + return 0x10U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_dmem_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_dmem_m(void) +{ + return 0x1U << 5U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_dmem_pending_f(void) +{ + return 0x20U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_total_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 10U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_total_counter_overflow_pending_f(void) +{ + return 0x400U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_total_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 8U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_total_counter_overflow_pending_f(void) +{ + return 0x100U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_unique_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_unique_counter_overflow_m(void) +{ + return 0x1U << 11U; +} +static inline u32 gr_fecs_falcon_ecc_status_uncorrected_err_unique_counter_overflow_pending_f(void) +{ + return 0x800U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_unique_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 9U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_unique_counter_overflow_m(void) +{ + return 0x1U << 9U; +} +static inline u32 gr_fecs_falcon_ecc_status_corrected_err_unique_counter_overflow_pending_f(void) +{ + return 0x200U; +} +static inline u32 gr_fecs_falcon_ecc_status_reset_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 gr_fecs_falcon_ecc_status_reset_task_f(void) +{ + return 0x80000000U; +} +static inline u32 gr_fecs_falcon_ecc_address_r(void) +{ + return 0x00409684U; +} +static inline u32 gr_fecs_falcon_ecc_address_index_f(u32 v) +{ + return (v & 0x7fffffU) << 0U; +} +static inline u32 gr_fecs_falcon_ecc_address_row_address_s(void) +{ + return 20U; +} +static inline u32 gr_fecs_falcon_ecc_address_row_address_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 gr_fecs_falcon_ecc_address_row_address_m(void) +{ + return 0xfffffU << 0U; +} +static inline u32 gr_fecs_falcon_ecc_address_row_address_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 gr_fecs_falcon_ecc_corrected_err_count_r(void) +{ + return 0x0040967cU; +} +static inline u32 gr_fecs_falcon_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 gr_fecs_falcon_ecc_corrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_falcon_ecc_corrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_fecs_falcon_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_fecs_falcon_ecc_corrected_err_count_unique_total_s(void) +{ + return 16U; +} +static inline u32 gr_fecs_falcon_ecc_corrected_err_count_unique_total_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_fecs_falcon_ecc_corrected_err_count_unique_total_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 gr_fecs_falcon_ecc_corrected_err_count_unique_total_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 gr_fecs_falcon_ecc_uncorrected_err_count_r(void) +{ + return 0x00409680U; +} +static inline u32 gr_fecs_falcon_ecc_uncorrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 gr_fecs_falcon_ecc_uncorrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 gr_fecs_falcon_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 gr_fecs_falcon_ecc_uncorrected_err_count_unique_total_s(void) +{ + return 16U; +} +static inline u32 gr_fecs_falcon_ecc_uncorrected_err_count_unique_total_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 gr_fecs_falcon_ecc_uncorrected_err_count_unique_total_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 gr_fecs_falcon_ecc_uncorrected_err_count_unique_total_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 gr_debug_2_r(void) +{ + return 0x00400088U; +} +static inline u32 gr_debug_2_gfxp_wfi_timeout_unit_m(void) +{ + return 0x1U << 27U; +} +static inline u32 gr_debug_2_gfxp_wfi_timeout_unit_usec_f(void) +{ + return 0x0U; +} +static inline u32 gr_debug_2_gfxp_wfi_timeout_unit_sysclk_f(void) +{ + return 0x8000000U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_ltc_gv11b.h b/include/nvgpu/hw/gv11b/hw_ltc_gv11b.h new file mode 100644 index 0000000..342f90d --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_ltc_gv11b.h @@ -0,0 +1,815 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ltc_gv11b_h_ +#define _hw_ltc_gv11b_h_ + +static inline u32 ltc_pltcg_base_v(void) +{ + return 0x00140000U; +} +static inline u32 ltc_pltcg_extent_v(void) +{ + return 0x0017ffffU; +} +static inline u32 ltc_ltc0_ltss_v(void) +{ + return 0x00140200U; +} +static inline u32 ltc_ltc0_lts0_v(void) +{ + return 0x00140400U; +} +static inline u32 ltc_ltcs_ltss_v(void) +{ + return 0x0017e200U; +} +static inline u32 ltc_ltcs_lts0_cbc_ctrl1_r(void) +{ + return 0x0014046cU; +} +static inline u32 ltc_ltc0_lts0_dstg_cfg0_r(void) +{ + return 0x00140518U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_r(void) +{ + return 0x0017e318U; +} +static inline u32 ltc_ltcs_ltss_dstg_cfg0_vdc_4to2_disable_m(void) +{ + return 0x1U << 15U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_r(void) +{ + return 0x00140494U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_ways_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_v(u32 r) +{ + return (r >> 16U) & 0x3U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_all_v(void) +{ + return 0x00000000U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_half_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_quarter_v(void) +{ + return 0x00000002U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void) +{ + return 0x0017e26cU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(void) +{ + return 0x2U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_active_f(void) +{ + return 0x4U; +} +static inline u32 ltc_ltc0_lts0_cbc_ctrl1_r(void) +{ + return 0x0014046cU; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_r(void) +{ + return 0x0017e270U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(u32 v) +{ + return (v & 0x3ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_r(void) +{ + return 0x0017e274U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(u32 v) +{ + return (v & 0x3ffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_init_v(void) +{ + return 0x0003ffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_r(void) +{ + return 0x0017e278U; +} +static inline u32 ltc_ltcs_ltss_cbc_base_alignment_shift_v(void) +{ + return 0x0000000bU; +} +static inline u32 ltc_ltcs_ltss_cbc_base_address_v(u32 r) +{ + return (r >> 0U) & 0x3ffffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_r(void) +{ + return 0x0017e27cU; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs__v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_nvlink_peer_through_l2_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_nvlink_peer_through_l2_v(u32 r) +{ + return (r >> 24U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_serialize_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 ltc_ltcs_ltss_cbc_num_active_ltcs_serialize_v(u32 r) +{ + return (r >> 25U) & 0x1U; +} +static inline u32 ltc_ltcs_misc_ltc_num_active_ltcs_r(void) +{ + return 0x0017e000U; +} +static inline u32 ltc_ltcs_ltss_cbc_param_r(void) +{ + return 0x0017e280U; +} +static inline u32 ltc_ltcs_ltss_cbc_param_comptags_per_cache_line_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_cache_line_size_v(u32 r) +{ + return (r >> 24U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_cbc_param_slices_per_ltc_v(u32 r) +{ + return (r >> 28U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_cbc_param2_r(void) +{ + return 0x0017e3f4U; +} +static inline u32 ltc_ltcs_ltss_cbc_param2_gobs_per_comptagline_per_slice_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_r(void) +{ + return 0x0017e2acU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_max_ways_evict_last_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_r(void) +{ + return 0x0017e338U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_index_address_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value_r(u32 i) +{ + return 0x0017e33cU + i*4U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_color_clear_value__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_r(void) +{ + return 0x0017e34cU; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_s(void) +{ + return 32U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_depth_clear_value_field_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_stencil_clear_value_r(void) +{ + return 0x0017e204U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_stencil_clear_value_field_s(void) +{ + return 8U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_stencil_clear_value_field_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_stencil_clear_value_field_m(void) +{ + return 0xffU << 0U; +} +static inline u32 ltc_ltcs_ltss_dstg_zbc_stencil_clear_value_field_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_r(void) +{ + return 0x0017e2b0U; +} +static inline u32 ltc_ltcs_ltss_tstg_set_mgmt_2_l2_bypass_mode_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_r(void) +{ + return 0x0017e214U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_r(void) +{ + return 0x00140214U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_r(void) +{ + return 0x00142214U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_g_elpg_flush_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_intr_r(void) +{ + return 0x0017e20cU; +} +static inline u32 ltc_ltcs_ltss_intr_ecc_sec_error_pending_f(void) +{ + return 0x100U; +} +static inline u32 ltc_ltcs_ltss_intr_ecc_ded_error_pending_f(void) +{ + return 0x200U; +} +static inline u32 ltc_ltcs_ltss_intr_en_evicted_cb_m(void) +{ + return 0x1U << 20U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_m(void) +{ + return 0x1U << 21U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_disabled_f(void) +{ + return 0x0U; +} +static inline u32 ltc_ltcs_ltss_intr_en_illegal_compstat_access_m(void) +{ + return 0x1U << 30U; +} +static inline u32 ltc_ltcs_ltss_intr_en_ecc_sec_error_enabled_f(void) +{ + return 0x1000000U; +} +static inline u32 ltc_ltcs_ltss_intr_en_ecc_ded_error_enabled_f(void) +{ + return 0x2000000U; +} +static inline u32 ltc_ltc0_lts0_intr_r(void) +{ + return 0x0014040cU; +} +static inline u32 ltc_ltcs_ltss_intr3_r(void) +{ + return 0x0017e388U; +} +static inline u32 ltc_ltcs_ltss_intr3_ecc_corrected_m(void) +{ + return 0x1U << 7U; +} +static inline u32 ltc_ltcs_ltss_intr3_ecc_uncorrected_m(void) +{ + return 0x1U << 8U; +} +static inline u32 ltc_ltc0_lts0_intr3_r(void) +{ + return 0x00140588U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_r(void) +{ + return 0x001404f0U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_corrected_err_rstg_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_corrected_err_rstg_m(void) +{ + return 0x1U << 1U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_corrected_err_tstg_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_corrected_err_tstg_m(void) +{ + return 0x1U << 3U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_corrected_err_dstg_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_corrected_err_dstg_m(void) +{ + return 0x1U << 5U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_uncorrected_err_rstg_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_uncorrected_err_rstg_m(void) +{ + return 0x1U << 0U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_uncorrected_err_tstg_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_uncorrected_err_tstg_m(void) +{ + return 0x1U << 2U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_uncorrected_err_dstg_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_uncorrected_err_dstg_m(void) +{ + return 0x1U << 4U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_uncorrected_err_total_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_uncorrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 18U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_corrected_err_total_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_corrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 16U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_uncorrected_err_unique_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_uncorrected_err_unique_counter_overflow_m(void) +{ + return 0x1U << 19U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_corrected_err_unique_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_corrected_err_unique_counter_overflow_m(void) +{ + return 0x1U << 17U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_reset_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_status_reset_task_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_address_r(void) +{ + return 0x001404fcU; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_corrected_err_count_r(void) +{ + return 0x001404f4U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_corrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_corrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_corrected_err_count_unique_total_s(void) +{ + return 16U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_corrected_err_count_unique_total_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_corrected_err_count_unique_total_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_corrected_err_count_unique_total_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_r(void) +{ + return 0x001404f8U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_unique_total_s(void) +{ + return 16U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_unique_total_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_unique_total_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 ltc_ltc0_lts0_l2_cache_ecc_uncorrected_err_count_unique_total_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_r(void) +{ + return 0x0014051cU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_sec_count_m(void) +{ + return 0xffU << 0U; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_sec_count_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_ded_count_m(void) +{ + return 0xffU << 16U; +} +static inline u32 ltc_ltc0_lts0_dstg_ecc_report_ded_count_v(u32 r) +{ + return (r >> 16U) & 0xffU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_r(void) +{ + return 0x0017e2a0U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_r(void) +{ + return 0x0017e2a4U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_v(u32 r) +{ + return (r >> 8U) & 0xfU; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_f(void) +{ + return 0x300U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_v(u32 r) +{ + return (r >> 16U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_f(void) +{ + return 0x10000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_v(u32 r) +{ + return (r >> 28U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_f(void) +{ + return 0x10000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_v(u32 r) +{ + return (r >> 29U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_f(void) +{ + return 0x20000000U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f(void) +{ + return 0x40000000U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_r(void) +{ + return 0x001402a0U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_r(void) +{ + return 0x001402a4U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_r(void) +{ + return 0x001422a0U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_r(void) +{ + return 0x001422a4U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_f(void) +{ + return 0x1U; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_r(void) +{ + return 0x0014058cU; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_slice_size_in_kb_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 ltc_ltc0_lts0_tstg_info_1_slices_per_l2_v(u32 r) +{ + return (r >> 16U) & 0x1fU; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_mc_gv11b.h b/include/nvgpu/hw/gv11b/hw_mc_gv11b.h new file mode 100644 index 0000000..a1bf15b --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_mc_gv11b.h @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_mc_gv11b_h_ +#define _hw_mc_gv11b_h_ + +static inline u32 mc_boot_0_r(void) +{ + return 0x00000000U; +} +static inline u32 mc_boot_0_architecture_v(u32 r) +{ + return (r >> 24U) & 0x1fU; +} +static inline u32 mc_boot_0_implementation_v(u32 r) +{ + return (r >> 20U) & 0xfU; +} +static inline u32 mc_boot_0_major_revision_v(u32 r) +{ + return (r >> 4U) & 0xfU; +} +static inline u32 mc_boot_0_minor_revision_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 mc_intr_r(u32 i) +{ + return 0x00000100U + i*4U; +} +static inline u32 mc_intr_pfifo_pending_f(void) +{ + return 0x100U; +} +static inline u32 mc_intr_hub_pending_f(void) +{ + return 0x200U; +} +static inline u32 mc_intr_pgraph_pending_f(void) +{ + return 0x1000U; +} +static inline u32 mc_intr_pmu_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 mc_intr_ltc_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 mc_intr_priv_ring_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 mc_intr_pbus_pending_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_intr_en_r(u32 i) +{ + return 0x00000140U + i*4U; +} +static inline u32 mc_intr_en_set_r(u32 i) +{ + return 0x00000160U + i*4U; +} +static inline u32 mc_intr_en_clear_r(u32 i) +{ + return 0x00000180U + i*4U; +} +static inline u32 mc_enable_r(void) +{ + return 0x00000200U; +} +static inline u32 mc_enable_xbar_enabled_f(void) +{ + return 0x4U; +} +static inline u32 mc_enable_l2_enabled_f(void) +{ + return 0x8U; +} +static inline u32 mc_enable_pmedia_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pmedia_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 mc_enable_pmedia_m(void) +{ + return 0x1U << 4U; +} +static inline u32 mc_enable_pmedia_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 mc_enable_ce0_m(void) +{ + return 0x1U << 6U; +} +static inline u32 mc_enable_pfifo_enabled_f(void) +{ + return 0x100U; +} +static inline u32 mc_enable_pgraph_enabled_f(void) +{ + return 0x1000U; +} +static inline u32 mc_enable_pwr_v(u32 r) +{ + return (r >> 13U) & 0x1U; +} +static inline u32 mc_enable_pwr_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 mc_enable_pwr_enabled_f(void) +{ + return 0x2000U; +} +static inline u32 mc_enable_pfb_enabled_f(void) +{ + return 0x100000U; +} +static inline u32 mc_enable_ce2_m(void) +{ + return 0x1U << 21U; +} +static inline u32 mc_enable_ce2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 mc_enable_blg_enabled_f(void) +{ + return 0x8000000U; +} +static inline u32 mc_enable_perfmon_enabled_f(void) +{ + return 0x10000000U; +} +static inline u32 mc_enable_hub_enabled_f(void) +{ + return 0x20000000U; +} +static inline u32 mc_intr_ltc_r(void) +{ + return 0x000001c0U; +} +static inline u32 mc_enable_pb_r(void) +{ + return 0x00000204U; +} +static inline u32 mc_enable_pb_0_s(void) +{ + return 1U; +} +static inline u32 mc_enable_pb_0_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 mc_enable_pb_0_m(void) +{ + return 0x1U << 0U; +} +static inline u32 mc_enable_pb_0_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 mc_enable_pb_0_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 mc_enable_pb_sel_f(u32 v, u32 i) +{ + return (v & 0x1U) << (0U + i*1U); +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_pbdma_gv11b.h b/include/nvgpu/hw/gv11b/hw_pbdma_gv11b.h new file mode 100644 index 0000000..c04d30a --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_pbdma_gv11b.h @@ -0,0 +1,651 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pbdma_gv11b_h_ +#define _hw_pbdma_gv11b_h_ + +static inline u32 pbdma_gp_entry1_r(void) +{ + return 0x10000004U; +} +static inline u32 pbdma_gp_entry1_get_hi_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pbdma_gp_entry1_length_f(u32 v) +{ + return (v & 0x1fffffU) << 10U; +} +static inline u32 pbdma_gp_entry1_length_v(u32 r) +{ + return (r >> 10U) & 0x1fffffU; +} +static inline u32 pbdma_gp_base_r(u32 i) +{ + return 0x00040048U + i*8192U; +} +static inline u32 pbdma_gp_base__size_1_v(void) +{ + return 0x00000003U; +} +static inline u32 pbdma_gp_base_offset_f(u32 v) +{ + return (v & 0x1fffffffU) << 3U; +} +static inline u32 pbdma_gp_base_rsvd_s(void) +{ + return 3U; +} +static inline u32 pbdma_gp_base_hi_r(u32 i) +{ + return 0x0004004cU + i*8192U; +} +static inline u32 pbdma_gp_base_hi_offset_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_gp_base_hi_limit2_f(u32 v) +{ + return (v & 0x1fU) << 16U; +} +static inline u32 pbdma_gp_fetch_r(u32 i) +{ + return 0x00040050U + i*8192U; +} +static inline u32 pbdma_gp_get_r(u32 i) +{ + return 0x00040014U + i*8192U; +} +static inline u32 pbdma_gp_put_r(u32 i) +{ + return 0x00040000U + i*8192U; +} +static inline u32 pbdma_pb_fetch_r(u32 i) +{ + return 0x00040054U + i*8192U; +} +static inline u32 pbdma_pb_fetch_hi_r(u32 i) +{ + return 0x00040058U + i*8192U; +} +static inline u32 pbdma_get_r(u32 i) +{ + return 0x00040018U + i*8192U; +} +static inline u32 pbdma_get_hi_r(u32 i) +{ + return 0x0004001cU + i*8192U; +} +static inline u32 pbdma_put_r(u32 i) +{ + return 0x0004005cU + i*8192U; +} +static inline u32 pbdma_put_hi_r(u32 i) +{ + return 0x00040060U + i*8192U; +} +static inline u32 pbdma_pb_header_r(u32 i) +{ + return 0x00040084U + i*8192U; +} +static inline u32 pbdma_pb_header_priv_user_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_method_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_subchannel_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_level_main_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_pb_header_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_pb_header_type_inc_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_pb_header_type_non_inc_f(void) +{ + return 0x60000000U; +} +static inline u32 pbdma_hdr_shadow_r(u32 i) +{ + return 0x00040118U + i*8192U; +} +static inline u32 pbdma_gp_shadow_0_r(u32 i) +{ + return 0x00040110U + i*8192U; +} +static inline u32 pbdma_gp_shadow_1_r(u32 i) +{ + return 0x00040114U + i*8192U; +} +static inline u32 pbdma_subdevice_r(u32 i) +{ + return 0x00040094U + i*8192U; +} +static inline u32 pbdma_subdevice_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 pbdma_subdevice_status_active_f(void) +{ + return 0x10000000U; +} +static inline u32 pbdma_subdevice_channel_dma_enable_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_method0_r(u32 i) +{ + return 0x000400c0U + i*8192U; +} +static inline u32 pbdma_method0_fifo_size_v(void) +{ + return 0x00000004U; +} +static inline u32 pbdma_method0_addr_f(u32 v) +{ + return (v & 0xfffU) << 2U; +} +static inline u32 pbdma_method0_addr_v(u32 r) +{ + return (r >> 2U) & 0xfffU; +} +static inline u32 pbdma_method0_subch_v(u32 r) +{ + return (r >> 16U) & 0x7U; +} +static inline u32 pbdma_method0_first_true_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_method0_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_method1_r(u32 i) +{ + return 0x000400c8U + i*8192U; +} +static inline u32 pbdma_method2_r(u32 i) +{ + return 0x000400d0U + i*8192U; +} +static inline u32 pbdma_method3_r(u32 i) +{ + return 0x000400d8U + i*8192U; +} +static inline u32 pbdma_data0_r(u32 i) +{ + return 0x000400c4U + i*8192U; +} +static inline u32 pbdma_acquire_r(u32 i) +{ + return 0x00040030U + i*8192U; +} +static inline u32 pbdma_acquire_retry_man_2_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_acquire_retry_exp_2_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_acquire_timeout_exp_f(u32 v) +{ + return (v & 0xfU) << 11U; +} +static inline u32 pbdma_acquire_timeout_exp_max_v(void) +{ + return 0x0000000fU; +} +static inline u32 pbdma_acquire_timeout_exp_max_f(void) +{ + return 0x7800U; +} +static inline u32 pbdma_acquire_timeout_man_f(u32 v) +{ + return (v & 0xffffU) << 15U; +} +static inline u32 pbdma_acquire_timeout_man_max_v(void) +{ + return 0x0000ffffU; +} +static inline u32 pbdma_acquire_timeout_man_max_f(void) +{ + return 0x7fff8000U; +} +static inline u32 pbdma_acquire_timeout_en_enable_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_acquire_timeout_en_disable_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_status_r(u32 i) +{ + return 0x00040100U + i*8192U; +} +static inline u32 pbdma_channel_r(u32 i) +{ + return 0x00040120U + i*8192U; +} +static inline u32 pbdma_signature_r(u32 i) +{ + return 0x00040010U + i*8192U; +} +static inline u32 pbdma_signature_hw_valid_f(void) +{ + return 0xfaceU; +} +static inline u32 pbdma_signature_sw_zero_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_r(u32 i) +{ + return 0x00040008U + i*8192U; +} +static inline u32 pbdma_userd_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_userd_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_userd_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 pbdma_userd_addr_f(u32 v) +{ + return (v & 0x7fffffU) << 9U; +} +static inline u32 pbdma_config_r(u32 i) +{ + return 0x000400f4U + i*8192U; +} +static inline u32 pbdma_config_l2_evict_first_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_config_l2_evict_normal_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_config_ce_split_enable_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_config_ce_split_disable_f(void) +{ + return 0x10U; +} +static inline u32 pbdma_config_auth_level_non_privileged_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_config_auth_level_privileged_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_config_userd_writeback_disable_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_config_userd_writeback_enable_f(void) +{ + return 0x1000U; +} +static inline u32 pbdma_userd_hi_r(u32 i) +{ + return 0x0004000cU + i*8192U; +} +static inline u32 pbdma_userd_hi_addr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pbdma_hce_ctrl_r(u32 i) +{ + return 0x000400e4U + i*8192U; +} +static inline u32 pbdma_hce_ctrl_hce_priv_mode_yes_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_r(u32 i) +{ + return 0x00040108U + i*8192U; +} +static inline u32 pbdma_intr_0_memreq_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pbdma_intr_0_memreq_pending_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_intr_0_memack_timeout_pending_f(void) +{ + return 0x2U; +} +static inline u32 pbdma_intr_0_memack_extra_pending_f(void) +{ + return 0x4U; +} +static inline u32 pbdma_intr_0_memdat_timeout_pending_f(void) +{ + return 0x8U; +} +static inline u32 pbdma_intr_0_memdat_extra_pending_f(void) +{ + return 0x10U; +} +static inline u32 pbdma_intr_0_memflush_pending_f(void) +{ + return 0x20U; +} +static inline u32 pbdma_intr_0_memop_pending_f(void) +{ + return 0x40U; +} +static inline u32 pbdma_intr_0_lbconnect_pending_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_intr_0_lbreq_pending_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_0_lback_timeout_pending_f(void) +{ + return 0x200U; +} +static inline u32 pbdma_intr_0_lback_extra_pending_f(void) +{ + return 0x400U; +} +static inline u32 pbdma_intr_0_lbdat_timeout_pending_f(void) +{ + return 0x800U; +} +static inline u32 pbdma_intr_0_lbdat_extra_pending_f(void) +{ + return 0x1000U; +} +static inline u32 pbdma_intr_0_gpfifo_pending_f(void) +{ + return 0x2000U; +} +static inline u32 pbdma_intr_0_gpptr_pending_f(void) +{ + return 0x4000U; +} +static inline u32 pbdma_intr_0_gpentry_pending_f(void) +{ + return 0x8000U; +} +static inline u32 pbdma_intr_0_gpcrc_pending_f(void) +{ + return 0x10000U; +} +static inline u32 pbdma_intr_0_pbptr_pending_f(void) +{ + return 0x20000U; +} +static inline u32 pbdma_intr_0_pbentry_pending_f(void) +{ + return 0x40000U; +} +static inline u32 pbdma_intr_0_pbcrc_pending_f(void) +{ + return 0x80000U; +} +static inline u32 pbdma_intr_0_clear_faulted_error_pending_f(void) +{ + return 0x100000U; +} +static inline u32 pbdma_intr_0_method_pending_f(void) +{ + return 0x200000U; +} +static inline u32 pbdma_intr_0_methodcrc_pending_f(void) +{ + return 0x400000U; +} +static inline u32 pbdma_intr_0_device_pending_f(void) +{ + return 0x800000U; +} +static inline u32 pbdma_intr_0_eng_reset_pending_f(void) +{ + return 0x1000000U; +} +static inline u32 pbdma_intr_0_semaphore_pending_f(void) +{ + return 0x2000000U; +} +static inline u32 pbdma_intr_0_acquire_pending_f(void) +{ + return 0x4000000U; +} +static inline u32 pbdma_intr_0_pri_pending_f(void) +{ + return 0x8000000U; +} +static inline u32 pbdma_intr_0_no_ctxsw_seg_pending_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_intr_0_pbseg_pending_f(void) +{ + return 0x40000000U; +} +static inline u32 pbdma_intr_0_signature_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_intr_1_r(u32 i) +{ + return 0x00040148U + i*8192U; +} +static inline u32 pbdma_intr_1_ctxnotvalid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 pbdma_intr_1_ctxnotvalid_pending_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_intr_en_0_r(u32 i) +{ + return 0x0004010cU + i*8192U; +} +static inline u32 pbdma_intr_en_0_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_en_1_r(u32 i) +{ + return 0x0004014cU + i*8192U; +} +static inline u32 pbdma_intr_stall_r(u32 i) +{ + return 0x0004013cU + i*8192U; +} +static inline u32 pbdma_intr_stall_lbreq_enabled_f(void) +{ + return 0x100U; +} +static inline u32 pbdma_intr_stall_1_r(u32 i) +{ + return 0x00040140U + i*8192U; +} +static inline u32 pbdma_intr_stall_1_hce_illegal_op_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pbdma_udma_nop_r(void) +{ + return 0x00000008U; +} +static inline u32 pbdma_runlist_timeslice_r(u32 i) +{ + return 0x000400f8U + i*8192U; +} +static inline u32 pbdma_runlist_timeslice_timeout_128_f(void) +{ + return 0x80U; +} +static inline u32 pbdma_runlist_timeslice_timescale_3_f(void) +{ + return 0x3000U; +} +static inline u32 pbdma_runlist_timeslice_enable_true_f(void) +{ + return 0x10000000U; +} +static inline u32 pbdma_target_r(u32 i) +{ + return 0x000400acU + i*8192U; +} +static inline u32 pbdma_target_engine_sw_f(void) +{ + return 0x1fU; +} +static inline u32 pbdma_target_eng_ctx_valid_true_f(void) +{ + return 0x10000U; +} +static inline u32 pbdma_target_eng_ctx_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_target_ce_ctx_valid_true_f(void) +{ + return 0x20000U; +} +static inline u32 pbdma_target_ce_ctx_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_target_host_tsg_event_reason_pbdma_idle_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_target_host_tsg_event_reason_semaphore_acquire_failure_f(void) +{ + return 0x1000000U; +} +static inline u32 pbdma_target_host_tsg_event_reason_tsg_yield_f(void) +{ + return 0x2000000U; +} +static inline u32 pbdma_target_host_tsg_event_reason_host_subchannel_switch_f(void) +{ + return 0x3000000U; +} +static inline u32 pbdma_target_should_send_tsg_event_true_f(void) +{ + return 0x20000000U; +} +static inline u32 pbdma_target_should_send_tsg_event_false_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_target_needs_host_tsg_event_true_f(void) +{ + return 0x80000000U; +} +static inline u32 pbdma_target_needs_host_tsg_event_false_f(void) +{ + return 0x0U; +} +static inline u32 pbdma_set_channel_info_r(u32 i) +{ + return 0x000400fcU + i*8192U; +} +static inline u32 pbdma_set_channel_info_veid_f(u32 v) +{ + return (v & 0x3fU) << 8U; +} +static inline u32 pbdma_timeout_r(u32 i) +{ + return 0x0004012cU + i*8192U; +} +static inline u32 pbdma_timeout_period_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 pbdma_timeout_period_max_f(void) +{ + return 0xffffffffU; +} +static inline u32 pbdma_timeout_period_init_f(void) +{ + return 0x10000U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_perf_gv11b.h b/include/nvgpu/hw/gv11b/hw_perf_gv11b.h new file mode 100644 index 0000000..a3341df --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_perf_gv11b.h @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_perf_gv11b_h_ +#define _hw_perf_gv11b_h_ + +static inline u32 perf_pmmgpc_perdomain_offset_v(void) +{ + return 0x00000200U; +} +static inline u32 perf_pmmsys_perdomain_offset_v(void) +{ + return 0x00000200U; +} +static inline u32 perf_pmmgpc_base_v(void) +{ + return 0x00180000U; +} +static inline u32 perf_pmmgpc_extent_v(void) +{ + return 0x00183fffU; +} +static inline u32 perf_pmmsys_base_v(void) +{ + return 0x00240000U; +} +static inline u32 perf_pmmsys_extent_v(void) +{ + return 0x00243fffU; +} +static inline u32 perf_pmmfbp_base_v(void) +{ + return 0x00200000U; +} +static inline u32 perf_pmasys_control_r(void) +{ + return 0x0024a000U; +} +static inline u32 perf_pmasys_control_membuf_status_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_status_overflowed_f(void) +{ + return 0x10U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_control_membuf_clear_status_doit_f(void) +{ + return 0x20U; +} +static inline u32 perf_pmasys_mem_block_r(void) +{ + return 0x0024a070U; +} +static inline u32 perf_pmasys_mem_block_base_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 perf_pmasys_mem_block_target_f(u32 v) +{ + return (v & 0x3U) << 28U; +} +static inline u32 perf_pmasys_mem_block_target_v(u32 r) +{ + return (r >> 28U) & 0x3U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_target_lfb_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 perf_pmasys_mem_block_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 perf_pmasys_mem_block_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 perf_pmasys_mem_block_valid_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 perf_pmasys_mem_block_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 perf_pmasys_mem_block_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_mem_block_valid_true_f(void) +{ + return 0x80000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_v(void) +{ + return 0x00000000U; +} +static inline u32 perf_pmasys_mem_block_valid_false_f(void) +{ + return 0x0U; +} +static inline u32 perf_pmasys_outbase_r(void) +{ + return 0x0024a074U; +} +static inline u32 perf_pmasys_outbase_ptr_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_outbaseupper_r(void) +{ + return 0x0024a078U; +} +static inline u32 perf_pmasys_outbaseupper_ptr_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 perf_pmasys_outsize_r(void) +{ + return 0x0024a07cU; +} +static inline u32 perf_pmasys_outsize_numbytes_f(u32 v) +{ + return (v & 0x7ffffffU) << 5U; +} +static inline u32 perf_pmasys_mem_bytes_r(void) +{ + return 0x0024a084U; +} +static inline u32 perf_pmasys_mem_bytes_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_mem_bump_r(void) +{ + return 0x0024a088U; +} +static inline u32 perf_pmasys_mem_bump_numbytes_f(u32 v) +{ + return (v & 0xfffffffU) << 4U; +} +static inline u32 perf_pmasys_enginestatus_r(void) +{ + return 0x0024a0a4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_v(void) +{ + return 0x00000001U; +} +static inline u32 perf_pmasys_enginestatus_rbufempty_empty_f(void) +{ + return 0x10U; +} +static inline u32 perf_pmmsys_engine_sel_r(u32 i) +{ + return 0x0024006cU + i*512U; +} +static inline u32 perf_pmmsys_engine_sel__size_1_v(void) +{ + return 0x00000020U; +} +static inline u32 perf_pmmfbp_engine_sel_r(u32 i) +{ + return 0x0020006cU + i*512U; +} +static inline u32 perf_pmmfbp_engine_sel__size_1_v(void) +{ + return 0x00000020U; +} +static inline u32 perf_pmmgpc_engine_sel_r(u32 i) +{ + return 0x0018006cU + i*512U; +} +static inline u32 perf_pmmgpc_engine_sel__size_1_v(void) +{ + return 0x00000020U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_pram_gv11b.h b/include/nvgpu/hw/gv11b/hw_pram_gv11b.h new file mode 100644 index 0000000..456d631 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_pram_gv11b.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pram_gv11b_h_ +#define _hw_pram_gv11b_h_ + +static inline u32 pram_data032_r(u32 i) +{ + return 0x00700000U + i*4U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_pri_ringmaster_gv11b.h b/include/nvgpu/hw/gv11b/hw_pri_ringmaster_gv11b.h new file mode 100644 index 0000000..a653681 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_pri_ringmaster_gv11b.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringmaster_gv11b_h_ +#define _hw_pri_ringmaster_gv11b_h_ + +static inline u32 pri_ringmaster_command_r(void) +{ + return 0x0012004cU; +} +static inline u32 pri_ringmaster_command_cmd_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 pri_ringmaster_command_cmd_v(u32 r) +{ + return (r >> 0U) & 0x3fU; +} +static inline u32 pri_ringmaster_command_cmd_no_cmd_v(void) +{ + return 0x00000000U; +} +static inline u32 pri_ringmaster_command_cmd_start_ring_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_command_cmd_ack_interrupt_f(void) +{ + return 0x2U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_f(void) +{ + return 0x3U; +} +static inline u32 pri_ringmaster_command_cmd_enumerate_stations_bc_grp_all_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_command_data_r(void) +{ + return 0x00120048U; +} +static inline u32 pri_ringmaster_start_results_r(void) +{ + return 0x00120050U; +} +static inline u32 pri_ringmaster_start_results_connectivity_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_start_results_connectivity_pass_v(void) +{ + return 0x00000001U; +} +static inline u32 pri_ringmaster_intr_status0_r(void) +{ + return 0x00120058U; +} +static inline u32 pri_ringmaster_intr_status0_ring_start_conn_fault_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_disconnect_fault_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_overflow_fault_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status0_gbl_write_error_sys_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 pri_ringmaster_intr_status1_r(void) +{ + return 0x0012005cU; +} +static inline u32 pri_ringmaster_global_ctl_r(void) +{ + return 0x00120060U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_asserted_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringmaster_global_ctl_ring_reset_deasserted_f(void) +{ + return 0x0U; +} +static inline u32 pri_ringmaster_enum_fbp_r(void) +{ + return 0x00120074U; +} +static inline u32 pri_ringmaster_enum_fbp_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_gpc_r(void) +{ + return 0x00120078U; +} +static inline u32 pri_ringmaster_enum_gpc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 pri_ringmaster_enum_ltc_r(void) +{ + return 0x0012006cU; +} +static inline u32 pri_ringmaster_enum_ltc_count_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_pri_ringstation_gpc_gv11b.h b/include/nvgpu/hw/gv11b/hw_pri_ringstation_gpc_gv11b.h new file mode 100644 index 0000000..47da22c --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_pri_ringstation_gpc_gv11b.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_gpc_gv11b_h_ +#define _hw_pri_ringstation_gpc_gv11b_h_ + +static inline u32 pri_ringstation_gpc_master_config_r(u32 i) +{ + return 0x00128300U + i*4U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_adr_r(void) +{ + return 0x00128120U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_wrdat_r(void) +{ + return 0x00128124U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_info_r(void) +{ + return 0x00128128U; +} +static inline u32 pri_ringstation_gpc_gpc0_priv_error_code_r(void) +{ + return 0x0012812cU; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_pri_ringstation_sys_gv11b.h b/include/nvgpu/hw/gv11b/hw_pri_ringstation_sys_gv11b.h new file mode 100644 index 0000000..622b6d7 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_pri_ringstation_sys_gv11b.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pri_ringstation_sys_gv11b_h_ +#define _hw_pri_ringstation_sys_gv11b_h_ + +static inline u32 pri_ringstation_sys_master_config_r(u32 i) +{ + return 0x00122300U + i*4U; +} +static inline u32 pri_ringstation_sys_decode_config_r(void) +{ + return 0x00122204U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_m(void) +{ + return 0x7U << 0U; +} +static inline u32 pri_ringstation_sys_decode_config_ring_drop_on_ring_not_started_f(void) +{ + return 0x1U; +} +static inline u32 pri_ringstation_sys_priv_error_adr_r(void) +{ + return 0x00122120U; +} +static inline u32 pri_ringstation_sys_priv_error_wrdat_r(void) +{ + return 0x00122124U; +} +static inline u32 pri_ringstation_sys_priv_error_info_r(void) +{ + return 0x00122128U; +} +static inline u32 pri_ringstation_sys_priv_error_code_r(void) +{ + return 0x0012212cU; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_proj_gv11b.h b/include/nvgpu/hw/gv11b/hw_proj_gv11b.h new file mode 100644 index 0000000..7283237 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_proj_gv11b.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_proj_gv11b_h_ +#define _hw_proj_gv11b_h_ + +static inline u32 proj_gpc_base_v(void) +{ + return 0x00500000U; +} +static inline u32 proj_gpc_shared_base_v(void) +{ + return 0x00418000U; +} +static inline u32 proj_gpc_stride_v(void) +{ + return 0x00008000U; +} +static inline u32 proj_gpc_priv_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_ltc_stride_v(void) +{ + return 0x00002000U; +} +static inline u32 proj_lts_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_fbpa_stride_v(void) +{ + return 0x00004000U; +} +static inline u32 proj_ppc_in_gpc_base_v(void) +{ + return 0x00003000U; +} +static inline u32 proj_ppc_in_gpc_shared_base_v(void) +{ + return 0x00003e00U; +} +static inline u32 proj_ppc_in_gpc_stride_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_rop_base_v(void) +{ + return 0x00410000U; +} +static inline u32 proj_rop_shared_base_v(void) +{ + return 0x00408800U; +} +static inline u32 proj_rop_stride_v(void) +{ + return 0x00000400U; +} +static inline u32 proj_tpc_in_gpc_base_v(void) +{ + return 0x00004000U; +} +static inline u32 proj_tpc_in_gpc_stride_v(void) +{ + return 0x00000800U; +} +static inline u32 proj_tpc_in_gpc_shared_base_v(void) +{ + return 0x00001800U; +} +static inline u32 proj_smpc_base_v(void) +{ + return 0x00000200U; +} +static inline u32 proj_smpc_shared_base_v(void) +{ + return 0x00000300U; +} +static inline u32 proj_smpc_unique_base_v(void) +{ + return 0x00000600U; +} +static inline u32 proj_smpc_stride_v(void) +{ + return 0x00000100U; +} +static inline u32 proj_host_num_engines_v(void) +{ + return 0x00000004U; +} +static inline u32 proj_host_num_pbdma_v(void) +{ + return 0x00000003U; +} +static inline u32 proj_scal_litter_num_tpc_per_gpc_v(void) +{ + return 0x00000004U; +} +static inline u32 proj_scal_litter_num_fbps_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_fbpas_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_gpcs_v(void) +{ + return 0x00000001U; +} +static inline u32 proj_scal_litter_num_pes_per_gpc_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_scal_litter_num_tpcs_per_pes_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_scal_litter_num_zcull_banks_v(void) +{ + return 0x00000004U; +} +static inline u32 proj_scal_litter_num_sm_per_tpc_v(void) +{ + return 0x00000002U; +} +static inline u32 proj_scal_max_gpcs_v(void) +{ + return 0x00000020U; +} +static inline u32 proj_scal_max_tpc_per_gpc_v(void) +{ + return 0x00000008U; +} +static inline u32 proj_sm_stride_v(void) +{ + return 0x00000080U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_pwr_gv11b.h b/include/nvgpu/hw/gv11b/hw_pwr_gv11b.h new file mode 100644 index 0000000..1cda12d --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_pwr_gv11b.h @@ -0,0 +1,1219 @@ +/* + * 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_pwr_gv11b_h_ +#define _hw_pwr_gv11b_h_ + +static inline u32 pwr_falcon_irqsset_r(void) +{ + return 0x0010a000U; +} +static inline u32 pwr_falcon_irqsset_swgen0_set_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqsclr_r(void) +{ + return 0x0010a004U; +} +static inline u32 pwr_falcon_irqstat_r(void) +{ + return 0x0010a008U; +} +static inline u32 pwr_falcon_irqstat_halt_true_f(void) +{ + return 0x10U; +} +static inline u32 pwr_falcon_irqstat_exterr_true_f(void) +{ + return 0x20U; +} +static inline u32 pwr_falcon_irqstat_swgen0_true_f(void) +{ + return 0x40U; +} +static inline u32 pwr_falcon_irqstat_ext_second_true_f(void) +{ + return 0x800U; +} +static inline u32 pwr_falcon_irqstat_ext_ecc_parity_true_f(void) +{ + return 0x400U; +} +static inline u32 pwr_pmu_ecc_intr_status_r(void) +{ + return 0x0010abfcU; +} +static inline u32 pwr_pmu_ecc_intr_status_corrected_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_ecc_intr_status_corrected_m(void) +{ + return 0x1U << 0U; +} +static inline u32 pwr_pmu_ecc_intr_status_uncorrected_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_pmu_ecc_intr_status_uncorrected_m(void) +{ + return 0x1U << 1U; +} +static inline u32 pwr_falcon_irqmode_r(void) +{ + return 0x0010a00cU; +} +static inline u32 pwr_falcon_irqmset_r(void) +{ + return 0x0010a010U; +} +static inline u32 pwr_falcon_irqmset_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmset_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmset_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmset_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmset_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmset_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmset_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmset_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmset_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqmset_ext_ctxe_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 pwr_falcon_irqmset_ext_limitv_f(u32 v) +{ + return (v & 0x1U) << 9U; +} +static inline u32 pwr_falcon_irqmset_ext_second_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 pwr_falcon_irqmset_ext_therm_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 pwr_falcon_irqmset_ext_miscio_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 pwr_falcon_irqmset_ext_rttimer_f(u32 v) +{ + return (v & 0x1U) << 14U; +} +static inline u32 pwr_falcon_irqmset_ext_rsvd8_f(u32 v) +{ + return (v & 0x1U) << 15U; +} +static inline u32 pwr_falcon_irqmset_ext_ecc_parity_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 pwr_falcon_irqmclr_r(void) +{ + return 0x0010a014U; +} +static inline u32 pwr_falcon_irqmclr_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqmclr_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqmclr_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqmclr_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqmclr_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqmclr_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqmclr_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqmclr_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqmclr_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqmclr_ext_ctxe_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 pwr_falcon_irqmclr_ext_limitv_f(u32 v) +{ + return (v & 0x1U) << 9U; +} +static inline u32 pwr_falcon_irqmclr_ext_second_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 pwr_falcon_irqmclr_ext_therm_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 pwr_falcon_irqmclr_ext_miscio_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 pwr_falcon_irqmclr_ext_rttimer_f(u32 v) +{ + return (v & 0x1U) << 14U; +} +static inline u32 pwr_falcon_irqmclr_ext_rsvd8_f(u32 v) +{ + return (v & 0x1U) << 15U; +} +static inline u32 pwr_falcon_irqmclr_ext_ecc_parity_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 pwr_falcon_irqmask_r(void) +{ + return 0x0010a018U; +} +static inline u32 pwr_falcon_irqdest_r(void) +{ + return 0x0010a01cU; +} +static inline u32 pwr_falcon_irqdest_host_gptmr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_falcon_irqdest_host_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_irqdest_host_mthd_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_falcon_irqdest_host_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 pwr_falcon_irqdest_host_halt_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_irqdest_host_exterr_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_irqdest_host_swgen0_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_irqdest_host_swgen1_f(u32 v) +{ + return (v & 0x1U) << 7U; +} +static inline u32 pwr_falcon_irqdest_host_ext_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_irqdest_host_ext_ctxe_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 pwr_falcon_irqdest_host_ext_limitv_f(u32 v) +{ + return (v & 0x1U) << 9U; +} +static inline u32 pwr_falcon_irqdest_host_ext_second_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 pwr_falcon_irqdest_host_ext_therm_f(u32 v) +{ + return (v & 0x1U) << 12U; +} +static inline u32 pwr_falcon_irqdest_host_ext_miscio_f(u32 v) +{ + return (v & 0x1U) << 13U; +} +static inline u32 pwr_falcon_irqdest_host_ext_rttimer_f(u32 v) +{ + return (v & 0x1U) << 14U; +} +static inline u32 pwr_falcon_irqdest_host_ext_rsvd8_f(u32 v) +{ + return (v & 0x1U) << 15U; +} +static inline u32 pwr_falcon_irqdest_host_ext_ecc_parity_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 pwr_falcon_irqdest_target_gptmr_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 pwr_falcon_irqdest_target_wdtmr_f(u32 v) +{ + return (v & 0x1U) << 17U; +} +static inline u32 pwr_falcon_irqdest_target_mthd_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 pwr_falcon_irqdest_target_ctxsw_f(u32 v) +{ + return (v & 0x1U) << 19U; +} +static inline u32 pwr_falcon_irqdest_target_halt_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_falcon_irqdest_target_exterr_f(u32 v) +{ + return (v & 0x1U) << 21U; +} +static inline u32 pwr_falcon_irqdest_target_swgen0_f(u32 v) +{ + return (v & 0x1U) << 22U; +} +static inline u32 pwr_falcon_irqdest_target_swgen1_f(u32 v) +{ + return (v & 0x1U) << 23U; +} +static inline u32 pwr_falcon_irqdest_target_ext_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 pwr_falcon_irqdest_target_ext_ctxe_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_irqdest_target_ext_limitv_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 pwr_falcon_irqdest_target_ext_second_f(u32 v) +{ + return (v & 0x1U) << 27U; +} +static inline u32 pwr_falcon_irqdest_target_ext_therm_f(u32 v) +{ + return (v & 0x1U) << 28U; +} +static inline u32 pwr_falcon_irqdest_target_ext_miscio_f(u32 v) +{ + return (v & 0x1U) << 29U; +} +static inline u32 pwr_falcon_irqdest_target_ext_rttimer_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 pwr_falcon_irqdest_target_ext_rsvd8_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 pwr_falcon_irqdest_target_ext_ecc_parity_f(u32 v) +{ + return (v & 0x1U) << 26U; +} +static inline u32 pwr_falcon_curctx_r(void) +{ + return 0x0010a050U; +} +static inline u32 pwr_falcon_nxtctx_r(void) +{ + return 0x0010a054U; +} +static inline u32 pwr_falcon_mailbox0_r(void) +{ + return 0x0010a040U; +} +static inline u32 pwr_falcon_mailbox1_r(void) +{ + return 0x0010a044U; +} +static inline u32 pwr_falcon_itfen_r(void) +{ + return 0x0010a048U; +} +static inline u32 pwr_falcon_itfen_ctxen_enable_f(void) +{ + return 0x1U; +} +static inline u32 pwr_falcon_idlestate_r(void) +{ + return 0x0010a04cU; +} +static inline u32 pwr_falcon_idlestate_falcon_busy_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_falcon_idlestate_ext_busy_v(u32 r) +{ + return (r >> 1U) & 0x7fffU; +} +static inline u32 pwr_falcon_os_r(void) +{ + return 0x0010a080U; +} +static inline u32 pwr_falcon_engctl_r(void) +{ + return 0x0010a0a4U; +} +static inline u32 pwr_falcon_cpuctl_r(void) +{ + return 0x0010a100U; +} +static inline u32 pwr_falcon_cpuctl_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_m(void) +{ + return 0x1U << 4U; +} +static inline u32 pwr_falcon_cpuctl_halt_intr_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_f(u32 v) +{ + return (v & 0x1U) << 6U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_m(void) +{ + return 0x1U << 6U; +} +static inline u32 pwr_falcon_cpuctl_cpuctl_alias_en_v(u32 r) +{ + return (r >> 6U) & 0x1U; +} +static inline u32 pwr_falcon_cpuctl_alias_r(void) +{ + return 0x0010a130U; +} +static inline u32 pwr_falcon_cpuctl_alias_startcpu_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_pmu_scpctl_stat_r(void) +{ + return 0x0010ac08U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_f(u32 v) +{ + return (v & 0x1U) << 20U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_m(void) +{ + return 0x1U << 20U; +} +static inline u32 pwr_pmu_scpctl_stat_debug_mode_v(u32 r) +{ + return (r >> 20U) & 0x1U; +} +static inline u32 pwr_falcon_imemc_r(u32 i) +{ + return 0x0010a180U + i*16U; +} +static inline u32 pwr_falcon_imemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_imemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_imemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_imemd_r(u32 i) +{ + return 0x0010a184U + i*16U; +} +static inline u32 pwr_falcon_imemt_r(u32 i) +{ + return 0x0010a188U + i*16U; +} +static inline u32 pwr_falcon_sctl_r(void) +{ + return 0x0010a240U; +} +static inline u32 pwr_falcon_mmu_phys_sec_r(void) +{ + return 0x00100ce4U; +} +static inline u32 pwr_falcon_bootvec_r(void) +{ + return 0x0010a104U; +} +static inline u32 pwr_falcon_bootvec_vec_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_falcon_dmactl_r(void) +{ + return 0x0010a10cU; +} +static inline u32 pwr_falcon_dmactl_dmem_scrubbing_m(void) +{ + return 0x1U << 1U; +} +static inline u32 pwr_falcon_dmactl_imem_scrubbing_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_falcon_hwcfg_r(void) +{ + return 0x0010a108U; +} +static inline u32 pwr_falcon_hwcfg_imem_size_v(u32 r) +{ + return (r >> 0U) & 0x1ffU; +} +static inline u32 pwr_falcon_hwcfg_dmem_size_v(u32 r) +{ + return (r >> 9U) & 0x1ffU; +} +static inline u32 pwr_falcon_dmatrfbase_r(void) +{ + return 0x0010a110U; +} +static inline u32 pwr_falcon_dmatrfbase1_r(void) +{ + return 0x0010a128U; +} +static inline u32 pwr_falcon_dmatrfmoffs_r(void) +{ + return 0x0010a114U; +} +static inline u32 pwr_falcon_dmatrfcmd_r(void) +{ + return 0x0010a118U; +} +static inline u32 pwr_falcon_dmatrfcmd_imem_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 pwr_falcon_dmatrfcmd_write_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 pwr_falcon_dmatrfcmd_size_f(u32 v) +{ + return (v & 0x7U) << 8U; +} +static inline u32 pwr_falcon_dmatrfcmd_ctxdma_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 pwr_falcon_dmatrffboffs_r(void) +{ + return 0x0010a11cU; +} +static inline u32 pwr_falcon_exterraddr_r(void) +{ + return 0x0010a168U; +} +static inline u32 pwr_falcon_exterrstat_r(void) +{ + return 0x0010a16cU; +} +static inline u32 pwr_falcon_exterrstat_valid_m(void) +{ + return 0x1U << 31U; +} +static inline u32 pwr_falcon_exterrstat_valid_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 pwr_falcon_exterrstat_valid_true_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_r(void) +{ + return 0x0010a200U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_s(void) +{ + return 4U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_m(void) +{ + return 0xfU << 0U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_v(u32 r) +{ + return (r >> 0U) & 0xfU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rreg_f(void) +{ + return 0x8U; +} +static inline u32 pwr_pmu_falcon_icd_cmd_opc_rstat_f(void) +{ + return 0xeU; +} +static inline u32 pwr_pmu_falcon_icd_cmd_idx_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 pwr_pmu_falcon_icd_rdata_r(void) +{ + return 0x0010a20cU; +} +static inline u32 pwr_falcon_dmemc_r(u32 i) +{ + return 0x0010a1c0U + i*8U; +} +static inline u32 pwr_falcon_dmemc_offs_f(u32 v) +{ + return (v & 0x3fU) << 2U; +} +static inline u32 pwr_falcon_dmemc_offs_m(void) +{ + return 0x3fU << 2U; +} +static inline u32 pwr_falcon_dmemc_blk_f(u32 v) +{ + return (v & 0xffU) << 8U; +} +static inline u32 pwr_falcon_dmemc_blk_m(void) +{ + return 0xffU << 8U; +} +static inline u32 pwr_falcon_dmemc_aincw_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 pwr_falcon_dmemc_aincr_f(u32 v) +{ + return (v & 0x1U) << 25U; +} +static inline u32 pwr_falcon_dmemd_r(u32 i) +{ + return 0x0010a1c4U + i*8U; +} +static inline u32 pwr_pmu_new_instblk_r(void) +{ + return 0x0010a480U; +} +static inline u32 pwr_pmu_new_instblk_ptr_f(u32 v) +{ + return (v & 0xfffffffU) << 0U; +} +static inline u32 pwr_pmu_new_instblk_target_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_coh_f(void) +{ + return 0x20000000U; +} +static inline u32 pwr_pmu_new_instblk_target_sys_ncoh_f(void) +{ + return 0x30000000U; +} +static inline u32 pwr_pmu_new_instblk_valid_f(u32 v) +{ + return (v & 0x1U) << 30U; +} +static inline u32 pwr_pmu_mutex_id_r(void) +{ + return 0x0010a488U; +} +static inline u32 pwr_pmu_mutex_id_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_id_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_value_not_avail_v(void) +{ + return 0x000000ffU; +} +static inline u32 pwr_pmu_mutex_id_release_r(void) +{ + return 0x0010a48cU; +} +static inline u32 pwr_pmu_mutex_id_release_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_m(void) +{ + return 0xffU << 0U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_mutex_id_release_value_init_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_mutex_r(u32 i) +{ + return 0x0010a580U + i*4U; +} +static inline u32 pwr_pmu_mutex__size_1_v(void) +{ + return 0x00000010U; +} +static inline u32 pwr_pmu_mutex_value_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 pwr_pmu_mutex_value_v(u32 r) +{ + return (r >> 0U) & 0xffU; +} +static inline u32 pwr_pmu_mutex_value_initial_lock_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_queue_head_r(u32 i) +{ + return 0x0010a800U + i*4U; +} +static inline u32 pwr_pmu_queue_head__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 pwr_pmu_queue_head_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_head_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_queue_tail_r(u32 i) +{ + return 0x0010a820U + i*4U; +} +static inline u32 pwr_pmu_queue_tail__size_1_v(void) +{ + return 0x00000008U; +} +static inline u32 pwr_pmu_queue_tail_address_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_queue_tail_address_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_head_r(void) +{ + return 0x0010a4c8U; +} +static inline u32 pwr_pmu_msgq_head_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_head_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_msgq_tail_r(void) +{ + return 0x0010a4ccU; +} +static inline u32 pwr_pmu_msgq_tail_val_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 pwr_pmu_msgq_tail_val_v(u32 r) +{ + return (r >> 0U) & 0xffffffffU; +} +static inline u32 pwr_pmu_idle_mask_r(u32 i) +{ + return 0x0010a504U + i*16U; +} +static inline u32 pwr_pmu_idle_mask_gr_enabled_f(void) +{ + return 0x1U; +} +static inline u32 pwr_pmu_idle_mask_ce_2_enabled_f(void) +{ + return 0x200000U; +} +static inline u32 pwr_pmu_idle_mask_1_r(u32 i) +{ + return 0x0010aa34U + i*8U; +} +static inline u32 pwr_pmu_idle_mask_2_r(u32 i) +{ + return 0x0010a840U + i*4U; +} +static inline u32 pwr_pmu_idle_count_r(u32 i) +{ + return 0x0010a508U + i*16U; +} +static inline u32 pwr_pmu_idle_count_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_count_value_v(u32 r) +{ + return (r >> 0U) & 0x7fffffffU; +} +static inline u32 pwr_pmu_idle_count_reset_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 pwr_pmu_idle_ctrl_r(u32 i) +{ + return 0x0010a50cU + i*16U; +} +static inline u32 pwr_pmu_idle_ctrl_value_m(void) +{ + return 0x3U << 0U; +} +static inline u32 pwr_pmu_idle_ctrl_value_busy_f(void) +{ + return 0x2U; +} +static inline u32 pwr_pmu_idle_ctrl_value_always_f(void) +{ + return 0x3U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_pmu_idle_ctrl_filter_disabled_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_idle_threshold_r(u32 i) +{ + return 0x0010a8a0U + i*4U; +} +static inline u32 pwr_pmu_idle_threshold_value_f(u32 v) +{ + return (v & 0x7fffffffU) << 0U; +} +static inline u32 pwr_pmu_idle_intr_r(void) +{ + return 0x0010a9e8U; +} +static inline u32 pwr_pmu_idle_intr_en_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_en_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 pwr_pmu_idle_intr_en_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_r(void) +{ + return 0x0010a9ecU; +} +static inline u32 pwr_pmu_idle_intr_status_intr_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_m(void) +{ + return 0x1U << 0U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_intr_status_intr_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 pwr_pmu_idle_mask_supp_r(u32 i) +{ + return 0x0010a9f0U + i*8U; +} +static inline u32 pwr_pmu_idle_mask_1_supp_r(u32 i) +{ + return 0x0010a9f4U + i*8U; +} +static inline u32 pwr_pmu_idle_mask_2_supp_r(u32 i) +{ + return 0x0010a690U + i*4U; +} +static inline u32 pwr_pmu_idle_ctrl_supp_r(u32 i) +{ + return 0x0010aa30U + i*8U; +} +static inline u32 pwr_pmu_debug_r(u32 i) +{ + return 0x0010a5c0U + i*4U; +} +static inline u32 pwr_pmu_debug__size_1_v(void) +{ + return 0x00000004U; +} +static inline u32 pwr_pmu_mailbox_r(u32 i) +{ + return 0x0010a450U + i*4U; +} +static inline u32 pwr_pmu_mailbox__size_1_v(void) +{ + return 0x0000000cU; +} +static inline u32 pwr_pmu_bar0_addr_r(void) +{ + return 0x0010a7a0U; +} +static inline u32 pwr_pmu_bar0_data_r(void) +{ + return 0x0010a7a4U; +} +static inline u32 pwr_pmu_bar0_ctl_r(void) +{ + return 0x0010a7acU; +} +static inline u32 pwr_pmu_bar0_timeout_r(void) +{ + return 0x0010a7a8U; +} +static inline u32 pwr_pmu_bar0_fecs_error_r(void) +{ + return 0x0010a988U; +} +static inline u32 pwr_pmu_bar0_error_status_r(void) +{ + return 0x0010a7b0U; +} +static inline u32 pwr_pmu_pg_idlefilth_r(u32 i) +{ + return 0x0010a6c0U + i*4U; +} +static inline u32 pwr_pmu_pg_ppuidlefilth_r(u32 i) +{ + return 0x0010a6e8U + i*4U; +} +static inline u32 pwr_pmu_pg_idle_cnt_r(u32 i) +{ + return 0x0010a710U + i*4U; +} +static inline u32 pwr_pmu_pg_intren_r(u32 i) +{ + return 0x0010a760U + i*4U; +} +static inline u32 pwr_pmu_falcon_ecc_status_r(void) +{ + return 0x0010a6b0U; +} +static inline u32 pwr_pmu_falcon_ecc_status_corrected_err_imem_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 pwr_pmu_falcon_ecc_status_corrected_err_imem_m(void) +{ + return 0x1U << 0U; +} +static inline u32 pwr_pmu_falcon_ecc_status_corrected_err_dmem_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 pwr_pmu_falcon_ecc_status_corrected_err_dmem_m(void) +{ + return 0x1U << 1U; +} +static inline u32 pwr_pmu_falcon_ecc_status_uncorrected_err_imem_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 pwr_pmu_falcon_ecc_status_uncorrected_err_imem_m(void) +{ + return 0x1U << 8U; +} +static inline u32 pwr_pmu_falcon_ecc_status_uncorrected_err_dmem_f(u32 v) +{ + return (v & 0x1U) << 9U; +} +static inline u32 pwr_pmu_falcon_ecc_status_uncorrected_err_dmem_m(void) +{ + return 0x1U << 9U; +} +static inline u32 pwr_pmu_falcon_ecc_status_corrected_err_total_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 pwr_pmu_falcon_ecc_status_corrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 16U; +} +static inline u32 pwr_pmu_falcon_ecc_status_uncorrected_err_total_counter_overflow_f(u32 v) +{ + return (v & 0x1U) << 18U; +} +static inline u32 pwr_pmu_falcon_ecc_status_uncorrected_err_total_counter_overflow_m(void) +{ + return 0x1U << 18U; +} +static inline u32 pwr_pmu_falcon_ecc_status_reset_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 pwr_pmu_falcon_ecc_status_reset_task_f(void) +{ + return 0x80000000U; +} +static inline u32 pwr_pmu_falcon_ecc_address_r(void) +{ + return 0x0010a6b4U; +} +static inline u32 pwr_pmu_falcon_ecc_address_index_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 pwr_pmu_falcon_ecc_address_type_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 pwr_pmu_falcon_ecc_address_type_imem_f(void) +{ + return 0x0U; +} +static inline u32 pwr_pmu_falcon_ecc_address_type_dmem_f(void) +{ + return 0x100000U; +} +static inline u32 pwr_pmu_falcon_ecc_address_row_address_s(void) +{ + return 16U; +} +static inline u32 pwr_pmu_falcon_ecc_address_row_address_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 pwr_pmu_falcon_ecc_address_row_address_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 pwr_pmu_falcon_ecc_address_row_address_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 pwr_pmu_falcon_ecc_corrected_err_count_r(void) +{ + return 0x0010a6b8U; +} +static inline u32 pwr_pmu_falcon_ecc_corrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 pwr_pmu_falcon_ecc_corrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 pwr_pmu_falcon_ecc_corrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 pwr_pmu_falcon_ecc_corrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 pwr_pmu_falcon_ecc_corrected_err_count_unique_total_s(void) +{ + return 16U; +} +static inline u32 pwr_pmu_falcon_ecc_corrected_err_count_unique_total_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 pwr_pmu_falcon_ecc_corrected_err_count_unique_total_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 pwr_pmu_falcon_ecc_corrected_err_count_unique_total_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 pwr_pmu_falcon_ecc_uncorrected_err_count_r(void) +{ + return 0x0010a6bcU; +} +static inline u32 pwr_pmu_falcon_ecc_uncorrected_err_count_total_s(void) +{ + return 16U; +} +static inline u32 pwr_pmu_falcon_ecc_uncorrected_err_count_total_f(u32 v) +{ + return (v & 0xffffU) << 0U; +} +static inline u32 pwr_pmu_falcon_ecc_uncorrected_err_count_total_m(void) +{ + return 0xffffU << 0U; +} +static inline u32 pwr_pmu_falcon_ecc_uncorrected_err_count_total_v(u32 r) +{ + return (r >> 0U) & 0xffffU; +} +static inline u32 pwr_pmu_falcon_ecc_uncorrected_err_count_unique_total_s(void) +{ + return 16U; +} +static inline u32 pwr_pmu_falcon_ecc_uncorrected_err_count_unique_total_f(u32 v) +{ + return (v & 0xffffU) << 16U; +} +static inline u32 pwr_pmu_falcon_ecc_uncorrected_err_count_unique_total_m(void) +{ + return 0xffffU << 16U; +} +static inline u32 pwr_pmu_falcon_ecc_uncorrected_err_count_unique_total_v(u32 r) +{ + return (r >> 16U) & 0xffffU; +} +static inline u32 pwr_fbif_transcfg_r(u32 i) +{ + return 0x0010ae00U + i*4U; +} +static inline u32 pwr_fbif_transcfg_target_local_fb_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_target_coherent_sysmem_f(void) +{ + return 0x1U; +} +static inline u32 pwr_fbif_transcfg_target_noncoherent_sysmem_f(void) +{ + return 0x2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_s(void) +{ + return 1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_m(void) +{ + return 0x1U << 2U; +} +static inline u32 pwr_fbif_transcfg_mem_type_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 pwr_fbif_transcfg_mem_type_virtual_f(void) +{ + return 0x0U; +} +static inline u32 pwr_fbif_transcfg_mem_type_physical_f(void) +{ + return 0x4U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_ram_gv11b.h b/include/nvgpu/hw/gv11b/hw_ram_gv11b.h new file mode 100644 index 0000000..59c6d88 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_ram_gv11b.h @@ -0,0 +1,791 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ram_gv11b_h_ +#define _hw_ram_gv11b_h_ + +static inline u32 ram_in_ramfc_s(void) +{ + return 4096U; +} +static inline u32 ram_in_ramfc_w(void) +{ + return 0U; +} +static inline u32 ram_in_page_dir_base_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ram_in_page_dir_base_target_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_target_vid_mem_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_coh_f(void) +{ + return 0x2U; +} +static inline u32 ram_in_page_dir_base_target_sys_mem_ncoh_f(void) +{ + return 0x3U; +} +static inline u32 ram_in_page_dir_base_vol_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_vol_true_f(void) +{ + return 0x4U; +} +static inline u32 ram_in_page_dir_base_vol_false_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_m(void) +{ + return 0x1U << 4U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_fault_replay_tex_true_f(void) +{ + return 0x10U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_m(void) +{ + return 0x1U << 5U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_fault_replay_gcc_true_f(void) +{ + return 0x20U; +} +static inline u32 ram_in_use_ver2_pt_format_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ram_in_use_ver2_pt_format_m(void) +{ + return 0x1U << 10U; +} +static inline u32 ram_in_use_ver2_pt_format_w(void) +{ + return 128U; +} +static inline u32 ram_in_use_ver2_pt_format_true_f(void) +{ + return 0x400U; +} +static inline u32 ram_in_use_ver2_pt_format_false_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_big_page_size_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 ram_in_big_page_size_m(void) +{ + return 0x1U << 11U; +} +static inline u32 ram_in_big_page_size_w(void) +{ + return 128U; +} +static inline u32 ram_in_big_page_size_128kb_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_big_page_size_64kb_f(void) +{ + return 0x800U; +} +static inline u32 ram_in_page_dir_base_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_page_dir_base_lo_w(void) +{ + return 128U; +} +static inline u32 ram_in_page_dir_base_hi_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_in_page_dir_base_hi_w(void) +{ + return 129U; +} +static inline u32 ram_in_engine_cs_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_cs_wfi_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_engine_cs_wfi_f(void) +{ + return 0x0U; +} +static inline u32 ram_in_engine_cs_fg_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_engine_cs_fg_f(void) +{ + return 0x8U; +} +static inline u32 ram_in_engine_wfi_mode_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 ram_in_engine_wfi_mode_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_wfi_mode_physical_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_engine_wfi_mode_virtual_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_engine_wfi_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ram_in_engine_wfi_target_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_wfi_target_sys_mem_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 ram_in_engine_wfi_target_sys_mem_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 ram_in_engine_wfi_target_local_mem_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_engine_wfi_ptr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_engine_wfi_ptr_lo_w(void) +{ + return 132U; +} +static inline u32 ram_in_engine_wfi_ptr_hi_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_in_engine_wfi_ptr_hi_w(void) +{ + return 133U; +} +static inline u32 ram_in_engine_wfi_veid_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 ram_in_engine_wfi_veid_w(void) +{ + return 134U; +} +static inline u32 ram_in_eng_method_buffer_addr_lo_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_in_eng_method_buffer_addr_lo_w(void) +{ + return 136U; +} +static inline u32 ram_in_eng_method_buffer_addr_hi_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 ram_in_eng_method_buffer_addr_hi_w(void) +{ + return 137U; +} +static inline u32 ram_in_sc_page_dir_base_target_f(u32 v, u32 i) +{ + return (v & 0x3U) << (0U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_target__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_target_vid_mem_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_sc_page_dir_base_target_invalid_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_page_dir_base_target_sys_mem_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 ram_in_sc_page_dir_base_target_sys_mem_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 ram_in_sc_page_dir_base_vol_f(u32 v, u32 i) +{ + return (v & 0x1U) << (2U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_vol__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_vol_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_page_dir_base_vol_false_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex_f(u32 v, u32 i) +{ + return (v & 0x1U) << (4U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc_f(u32 v, u32 i) +{ + return (v & 0x1U) << (5U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_sc_use_ver2_pt_format_f(u32 v, u32 i) +{ + return (v & 0x1U) << (10U + i*0U); +} +static inline u32 ram_in_sc_use_ver2_pt_format__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_use_ver2_pt_format_false_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_in_sc_use_ver2_pt_format_true_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_big_page_size_f(u32 v, u32 i) +{ + return (v & 0x1U) << (11U + i*0U); +} +static inline u32 ram_in_sc_big_page_size__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_big_page_size_64kb_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_in_sc_page_dir_base_lo_f(u32 v, u32 i) +{ + return (v & 0xfffffU) << (12U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_lo__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_hi_f(u32 v, u32 i) +{ + return (v & 0xffffffffU) << (0U + i*0U); +} +static inline u32 ram_in_sc_page_dir_base_hi__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 ram_in_sc_page_dir_base_target_0_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 ram_in_sc_page_dir_base_target_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_page_dir_base_vol_0_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 ram_in_sc_page_dir_base_vol_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex_0_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_tex_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc_0_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 ram_in_sc_page_dir_base_fault_replay_gcc_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_use_ver2_pt_format_0_f(u32 v) +{ + return (v & 0x1U) << 10U; +} +static inline u32 ram_in_sc_use_ver2_pt_format_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_big_page_size_0_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 ram_in_sc_big_page_size_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_page_dir_base_lo_0_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_in_sc_page_dir_base_lo_0_w(void) +{ + return 168U; +} +static inline u32 ram_in_sc_page_dir_base_hi_0_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_in_sc_page_dir_base_hi_0_w(void) +{ + return 169U; +} +static inline u32 ram_in_base_shift_v(void) +{ + return 0x0000000cU; +} +static inline u32 ram_in_alloc_size_v(void) +{ + return 0x00001000U; +} +static inline u32 ram_fc_size_val_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_fc_gp_put_w(void) +{ + return 0U; +} +static inline u32 ram_fc_userd_w(void) +{ + return 2U; +} +static inline u32 ram_fc_userd_hi_w(void) +{ + return 3U; +} +static inline u32 ram_fc_signature_w(void) +{ + return 4U; +} +static inline u32 ram_fc_gp_get_w(void) +{ + return 5U; +} +static inline u32 ram_fc_pb_get_w(void) +{ + return 6U; +} +static inline u32 ram_fc_pb_get_hi_w(void) +{ + return 7U; +} +static inline u32 ram_fc_pb_top_level_get_w(void) +{ + return 8U; +} +static inline u32 ram_fc_pb_top_level_get_hi_w(void) +{ + return 9U; +} +static inline u32 ram_fc_acquire_w(void) +{ + return 12U; +} +static inline u32 ram_fc_sem_addr_hi_w(void) +{ + return 14U; +} +static inline u32 ram_fc_sem_addr_lo_w(void) +{ + return 15U; +} +static inline u32 ram_fc_sem_payload_lo_w(void) +{ + return 16U; +} +static inline u32 ram_fc_sem_payload_hi_w(void) +{ + return 39U; +} +static inline u32 ram_fc_sem_execute_w(void) +{ + return 17U; +} +static inline u32 ram_fc_gp_base_w(void) +{ + return 18U; +} +static inline u32 ram_fc_gp_base_hi_w(void) +{ + return 19U; +} +static inline u32 ram_fc_gp_fetch_w(void) +{ + return 20U; +} +static inline u32 ram_fc_pb_fetch_w(void) +{ + return 21U; +} +static inline u32 ram_fc_pb_fetch_hi_w(void) +{ + return 22U; +} +static inline u32 ram_fc_pb_put_w(void) +{ + return 23U; +} +static inline u32 ram_fc_pb_put_hi_w(void) +{ + return 24U; +} +static inline u32 ram_fc_pb_header_w(void) +{ + return 33U; +} +static inline u32 ram_fc_pb_count_w(void) +{ + return 34U; +} +static inline u32 ram_fc_subdevice_w(void) +{ + return 37U; +} +static inline u32 ram_fc_target_w(void) +{ + return 43U; +} +static inline u32 ram_fc_hce_ctrl_w(void) +{ + return 57U; +} +static inline u32 ram_fc_chid_w(void) +{ + return 58U; +} +static inline u32 ram_fc_chid_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_fc_chid_id_w(void) +{ + return 0U; +} +static inline u32 ram_fc_config_w(void) +{ + return 61U; +} +static inline u32 ram_fc_runlist_timeslice_w(void) +{ + return 62U; +} +static inline u32 ram_fc_set_channel_info_w(void) +{ + return 63U; +} +static inline u32 ram_userd_base_shift_v(void) +{ + return 0x00000009U; +} +static inline u32 ram_userd_chan_size_v(void) +{ + return 0x00000200U; +} +static inline u32 ram_userd_put_w(void) +{ + return 16U; +} +static inline u32 ram_userd_get_w(void) +{ + return 17U; +} +static inline u32 ram_userd_ref_w(void) +{ + return 18U; +} +static inline u32 ram_userd_put_hi_w(void) +{ + return 19U; +} +static inline u32 ram_userd_ref_threshold_w(void) +{ + return 20U; +} +static inline u32 ram_userd_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_userd_get_hi_w(void) +{ + return 24U; +} +static inline u32 ram_userd_gp_get_w(void) +{ + return 34U; +} +static inline u32 ram_userd_gp_put_w(void) +{ + return 35U; +} +static inline u32 ram_userd_gp_top_level_get_w(void) +{ + return 22U; +} +static inline u32 ram_userd_gp_top_level_get_hi_w(void) +{ + return 23U; +} +static inline u32 ram_rl_entry_size_v(void) +{ + return 0x00000010U; +} +static inline u32 ram_rl_entry_type_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 ram_rl_entry_type_channel_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_rl_entry_type_tsg_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_rl_entry_id_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_chan_runqueue_selector_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 ram_rl_entry_chan_inst_target_f(u32 v) +{ + return (v & 0x3U) << 4U; +} +static inline u32 ram_rl_entry_chan_inst_target_sys_mem_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 ram_rl_entry_chan_inst_target_sys_mem_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 ram_rl_entry_chan_inst_target_vid_mem_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_rl_entry_chan_userd_target_f(u32 v) +{ + return (v & 0x3U) << 6U; +} +static inline u32 ram_rl_entry_chan_userd_target_vid_mem_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_rl_entry_chan_userd_target_vid_mem_nvlink_coh_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_rl_entry_chan_userd_target_sys_mem_coh_v(void) +{ + return 0x00000002U; +} +static inline u32 ram_rl_entry_chan_userd_target_sys_mem_ncoh_v(void) +{ + return 0x00000003U; +} +static inline u32 ram_rl_entry_chan_userd_ptr_lo_f(u32 v) +{ + return (v & 0xffffffU) << 8U; +} +static inline u32 ram_rl_entry_chan_userd_ptr_hi_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_rl_entry_chid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_chan_inst_ptr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 ram_rl_entry_chan_inst_ptr_hi_f(u32 v) +{ + return (v & 0xffffffffU) << 0U; +} +static inline u32 ram_rl_entry_tsg_timeslice_scale_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 ram_rl_entry_tsg_timeslice_scale_3_v(void) +{ + return 0x00000003U; +} +static inline u32 ram_rl_entry_tsg_timeslice_timeout_f(u32 v) +{ + return (v & 0xffU) << 24U; +} +static inline u32 ram_rl_entry_tsg_timeslice_timeout_128_v(void) +{ + return 0x00000080U; +} +static inline u32 ram_rl_entry_tsg_length_f(u32 v) +{ + return (v & 0xffU) << 0U; +} +static inline u32 ram_rl_entry_tsg_length_init_v(void) +{ + return 0x00000000U; +} +static inline u32 ram_rl_entry_tsg_length_min_v(void) +{ + return 0x00000001U; +} +static inline u32 ram_rl_entry_tsg_length_max_v(void) +{ + return 0x00000080U; +} +static inline u32 ram_rl_entry_tsg_tsgid_f(u32 v) +{ + return (v & 0xfffU) << 0U; +} +static inline u32 ram_rl_entry_chan_userd_ptr_align_shift_v(void) +{ + return 0x00000008U; +} +static inline u32 ram_rl_entry_chan_userd_align_shift_v(void) +{ + return 0x00000008U; +} +static inline u32 ram_rl_entry_chan_inst_ptr_align_shift_v(void) +{ + return 0x0000000cU; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_therm_gv11b.h b/include/nvgpu/hw/gv11b/hw_therm_gv11b.h new file mode 100644 index 0000000..0050083 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_therm_gv11b.h @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_therm_gv11b_h_ +#define _hw_therm_gv11b_h_ + +static inline u32 therm_use_a_r(void) +{ + return 0x00020798U; +} +static inline u32 therm_use_a_ext_therm_0_enable_f(void) +{ + return 0x1U; +} +static inline u32 therm_use_a_ext_therm_1_enable_f(void) +{ + return 0x2U; +} +static inline u32 therm_use_a_ext_therm_2_enable_f(void) +{ + return 0x4U; +} +static inline u32 therm_evt_ext_therm_0_r(void) +{ + return 0x00020700U; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_init_v(void) +{ + return 0x00000001U; +} +static inline u32 therm_evt_ext_therm_0_mode_f(u32 v) +{ + return (v & 0x3U) << 30U; +} +static inline u32 therm_evt_ext_therm_0_mode_normal_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_0_mode_inverted_v(void) +{ + return 0x00000001U; +} +static inline u32 therm_evt_ext_therm_0_mode_forced_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_evt_ext_therm_0_mode_cleared_v(void) +{ + return 0x00000003U; +} +static inline u32 therm_evt_ext_therm_1_r(void) +{ + return 0x00020704U; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_init_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_evt_ext_therm_1_mode_f(u32 v) +{ + return (v & 0x3U) << 30U; +} +static inline u32 therm_evt_ext_therm_1_mode_normal_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_1_mode_inverted_v(void) +{ + return 0x00000001U; +} +static inline u32 therm_evt_ext_therm_1_mode_forced_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_evt_ext_therm_1_mode_cleared_v(void) +{ + return 0x00000003U; +} +static inline u32 therm_evt_ext_therm_2_r(void) +{ + return 0x00020708U; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_init_v(void) +{ + return 0x00000003U; +} +static inline u32 therm_evt_ext_therm_2_mode_f(u32 v) +{ + return (v & 0x3U) << 30U; +} +static inline u32 therm_evt_ext_therm_2_mode_normal_v(void) +{ + return 0x00000000U; +} +static inline u32 therm_evt_ext_therm_2_mode_inverted_v(void) +{ + return 0x00000001U; +} +static inline u32 therm_evt_ext_therm_2_mode_forced_v(void) +{ + return 0x00000002U; +} +static inline u32 therm_evt_ext_therm_2_mode_cleared_v(void) +{ + return 0x00000003U; +} +static inline u32 therm_weight_1_r(void) +{ + return 0x00020024U; +} +static inline u32 therm_config1_r(void) +{ + return 0x00020050U; +} +static inline u32 therm_config2_r(void) +{ + return 0x00020130U; +} +static inline u32 therm_config2_grad_step_duration_f(u32 v) +{ + return (v & 0xfU) << 8U; +} +static inline u32 therm_config2_grad_step_duration_m(void) +{ + return 0xfU << 8U; +} +static inline u32 therm_config2_slowdown_factor_extended_f(u32 v) +{ + return (v & 0x1U) << 24U; +} +static inline u32 therm_config2_grad_enable_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 therm_gate_ctrl_r(u32 i) +{ + return 0x00020200U + i*4U; +} +static inline u32 therm_gate_ctrl_eng_clk_m(void) +{ + return 0x3U << 0U; +} +static inline u32 therm_gate_ctrl_eng_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_eng_clk_auto_f(void) +{ + return 0x1U; +} +static inline u32 therm_gate_ctrl_eng_clk_stop_f(void) +{ + return 0x2U; +} +static inline u32 therm_gate_ctrl_blk_clk_m(void) +{ + return 0x3U << 2U; +} +static inline u32 therm_gate_ctrl_blk_clk_run_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_blk_clk_auto_f(void) +{ + return 0x4U; +} +static inline u32 therm_gate_ctrl_idle_holdoff_m(void) +{ + return 0x1U << 4U; +} +static inline u32 therm_gate_ctrl_idle_holdoff_off_f(void) +{ + return 0x0U; +} +static inline u32 therm_gate_ctrl_idle_holdoff_on_f(void) +{ + return 0x10U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_f(u32 v) +{ + return (v & 0x1fU) << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp_m(void) +{ + return 0x1fU << 8U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_exp__prod_f(void) +{ + return 0x200U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_f(u32 v) +{ + return (v & 0x7U) << 13U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant_m(void) +{ + return 0x7U << 13U; +} +static inline u32 therm_gate_ctrl_eng_idle_filt_mant__prod_f(void) +{ + return 0x2000U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_f(u32 v) +{ + return (v & 0xfU) << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_before_m(void) +{ + return 0xfU << 16U; +} +static inline u32 therm_gate_ctrl_eng_delay_before__prod_f(void) +{ + return 0x40000U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_f(u32 v) +{ + return (v & 0xfU) << 20U; +} +static inline u32 therm_gate_ctrl_eng_delay_after_m(void) +{ + return 0xfU << 20U; +} +static inline u32 therm_gate_ctrl_eng_delay_after__prod_f(void) +{ + return 0x0U; +} +static inline u32 therm_fecs_idle_filter_r(void) +{ + return 0x00020288U; +} +static inline u32 therm_fecs_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_fecs_idle_filter_value__prod_f(void) +{ + return 0x0U; +} +static inline u32 therm_hubmmu_idle_filter_r(void) +{ + return 0x0002028cU; +} +static inline u32 therm_hubmmu_idle_filter_value_m(void) +{ + return 0xffffffffU << 0U; +} +static inline u32 therm_hubmmu_idle_filter_value__prod_f(void) +{ + return 0x0U; +} +static inline u32 therm_clk_slowdown_r(u32 i) +{ + return 0x00020160U + i*4U; +} +static inline u32 therm_clk_slowdown_idle_factor_f(u32 v) +{ + return (v & 0x3fU) << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_m(void) +{ + return 0x3fU << 16U; +} +static inline u32 therm_clk_slowdown_idle_factor_v(u32 r) +{ + return (r >> 16U) & 0x3fU; +} +static inline u32 therm_clk_slowdown_idle_factor_disabled_f(void) +{ + return 0x0U; +} +static inline u32 therm_clk_slowdown_2_r(u32 i) +{ + return 0x000201a0U + i*4U; +} +static inline u32 therm_clk_slowdown_2_idle_condition_a_select_f(u32 v) +{ + return (v & 0xfU) << 0U; +} +static inline u32 therm_clk_slowdown_2_idle_condition_a_type_f(u32 v) +{ + return (v & 0x7U) << 4U; +} +static inline u32 therm_clk_slowdown_2_idle_condition_a_type_v(u32 r) +{ + return (r >> 4U) & 0x7U; +} +static inline u32 therm_clk_slowdown_2_idle_condition_a_type_never_f(void) +{ + return 0x40U; +} +static inline u32 therm_clk_slowdown_2_idle_condition_b_type_f(u32 v) +{ + return (v & 0x7U) << 12U; +} +static inline u32 therm_clk_slowdown_2_idle_condition_b_type_v(u32 r) +{ + return (r >> 12U) & 0x7U; +} +static inline u32 therm_clk_slowdown_2_idle_condition_b_type_never_f(void) +{ + return 0x4000U; +} +static inline u32 therm_grad_stepping_table_r(u32 i) +{ + return 0x000202c8U + i*4U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_f(u32 v) +{ + return (v & 0x3fU) << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_m(void) +{ + return 0x3fU << 0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by1_f(void) +{ + return 0x0U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by1p5_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by2_f(void) +{ + return 0x2U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by4_f(void) +{ + return 0x6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f(void) +{ + return 0xeU; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by16_f(void) +{ + return 0x1eU; +} +static inline u32 therm_grad_stepping_table_slowdown_factor0_fpdiv_by32_f(void) +{ + return 0x3eU; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_f(u32 v) +{ + return (v & 0x3fU) << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor1_m(void) +{ + return 0x3fU << 6U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_f(u32 v) +{ + return (v & 0x3fU) << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor2_m(void) +{ + return 0x3fU << 12U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_f(u32 v) +{ + return (v & 0x3fU) << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor3_m(void) +{ + return 0x3fU << 18U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_f(u32 v) +{ + return (v & 0x3fU) << 24U; +} +static inline u32 therm_grad_stepping_table_slowdown_factor4_m(void) +{ + return 0x3fU << 24U; +} +static inline u32 therm_grad_stepping0_r(void) +{ + return 0x000202c0U; +} +static inline u32 therm_grad_stepping0_feature_s(void) +{ + return 1U; +} +static inline u32 therm_grad_stepping0_feature_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 therm_grad_stepping0_feature_m(void) +{ + return 0x1U << 0U; +} +static inline u32 therm_grad_stepping0_feature_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 therm_grad_stepping0_feature_enable_f(void) +{ + return 0x1U; +} +static inline u32 therm_grad_stepping1_r(void) +{ + return 0x000202c4U; +} +static inline u32 therm_grad_stepping1_pdiv_duration_f(u32 v) +{ + return (v & 0x1ffffU) << 0U; +} +static inline u32 therm_clk_timing_r(u32 i) +{ + return 0x000203c0U + i*4U; +} +static inline u32 therm_clk_timing_grad_slowdown_f(u32 v) +{ + return (v & 0x1U) << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_m(void) +{ + return 0x1U << 16U; +} +static inline u32 therm_clk_timing_grad_slowdown_enabled_f(void) +{ + return 0x10000U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_timer_gv11b.h b/include/nvgpu/hw/gv11b/hw_timer_gv11b.h new file mode 100644 index 0000000..34285b3 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_timer_gv11b.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_timer_gv11b_h_ +#define _hw_timer_gv11b_h_ + +static inline u32 timer_pri_timeout_r(void) +{ + return 0x00009080U; +} +static inline u32 timer_pri_timeout_period_f(u32 v) +{ + return (v & 0xffffffU) << 0U; +} +static inline u32 timer_pri_timeout_period_m(void) +{ + return 0xffffffU << 0U; +} +static inline u32 timer_pri_timeout_period_v(u32 r) +{ + return (r >> 0U) & 0xffffffU; +} +static inline u32 timer_pri_timeout_en_f(u32 v) +{ + return (v & 0x1U) << 31U; +} +static inline u32 timer_pri_timeout_en_m(void) +{ + return 0x1U << 31U; +} +static inline u32 timer_pri_timeout_en_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_en_en_enabled_f(void) +{ + return 0x80000000U; +} +static inline u32 timer_pri_timeout_en_en_disabled_f(void) +{ + return 0x0U; +} +static inline u32 timer_pri_timeout_save_0_r(void) +{ + return 0x00009084U; +} +static inline u32 timer_pri_timeout_save_0_fecs_tgt_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 timer_pri_timeout_save_0_addr_v(u32 r) +{ + return (r >> 2U) & 0x3fffffU; +} +static inline u32 timer_pri_timeout_save_0_write_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 timer_pri_timeout_save_1_r(void) +{ + return 0x00009088U; +} +static inline u32 timer_pri_timeout_fecs_errcode_r(void) +{ + return 0x0000908cU; +} +static inline u32 timer_time_0_r(void) +{ + return 0x00009400U; +} +static inline u32 timer_time_1_r(void) +{ + return 0x00009410U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_top_gv11b.h b/include/nvgpu/hw/gv11b/hw_top_gv11b.h new file mode 100644 index 0000000..89e4aeb --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_top_gv11b.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2016-2017, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_top_gv11b_h_ +#define _hw_top_gv11b_h_ + +static inline u32 top_num_gpcs_r(void) +{ + return 0x00022430U; +} +static inline u32 top_num_gpcs_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_tpc_per_gpc_r(void) +{ + return 0x00022434U; +} +static inline u32 top_tpc_per_gpc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_fbps_r(void) +{ + return 0x00022438U; +} +static inline u32 top_num_fbps_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_ltc_per_fbp_r(void) +{ + return 0x00022450U; +} +static inline u32 top_ltc_per_fbp_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_slices_per_ltc_r(void) +{ + return 0x0002245cU; +} +static inline u32 top_slices_per_ltc_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_num_ltcs_r(void) +{ + return 0x00022454U; +} +static inline u32 top_num_ces_r(void) +{ + return 0x00022444U; +} +static inline u32 top_num_ces_value_v(u32 r) +{ + return (r >> 0U) & 0x1fU; +} +static inline u32 top_device_info_r(u32 i) +{ + return 0x00022700U + i*4U; +} +static inline u32 top_device_info__size_1_v(void) +{ + return 0x00000040U; +} +static inline u32 top_device_info_chain_v(u32 r) +{ + return (r >> 31U) & 0x1U; +} +static inline u32 top_device_info_chain_enable_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_engine_enum_v(u32 r) +{ + return (r >> 26U) & 0xfU; +} +static inline u32 top_device_info_runlist_enum_v(u32 r) +{ + return (r >> 21U) & 0xfU; +} +static inline u32 top_device_info_intr_enum_v(u32 r) +{ + return (r >> 15U) & 0x1fU; +} +static inline u32 top_device_info_reset_enum_v(u32 r) +{ + return (r >> 9U) & 0x1fU; +} +static inline u32 top_device_info_type_enum_v(u32 r) +{ + return (r >> 2U) & 0x1fffffffU; +} +static inline u32 top_device_info_type_enum_graphics_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_type_enum_graphics_f(void) +{ + return 0x0U; +} +static inline u32 top_device_info_type_enum_copy2_v(void) +{ + return 0x00000003U; +} +static inline u32 top_device_info_type_enum_copy2_f(void) +{ + return 0xcU; +} +static inline u32 top_device_info_type_enum_lce_v(void) +{ + return 0x00000013U; +} +static inline u32 top_device_info_type_enum_lce_f(void) +{ + return 0x4cU; +} +static inline u32 top_device_info_engine_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 top_device_info_runlist_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 top_device_info_intr_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 top_device_info_reset_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_entry_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 top_device_info_entry_not_valid_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_entry_enum_v(void) +{ + return 0x00000002U; +} +static inline u32 top_device_info_entry_data_v(void) +{ + return 0x00000001U; +} +static inline u32 top_device_info_data_type_v(u32 r) +{ + return (r >> 30U) & 0x1U; +} +static inline u32 top_device_info_data_type_enum2_v(void) +{ + return 0x00000000U; +} +static inline u32 top_device_info_data_inst_id_v(u32 r) +{ + return (r >> 26U) & 0xfU; +} +static inline u32 top_device_info_data_pri_base_v(u32 r) +{ + return (r >> 12U) & 0xfffU; +} +static inline u32 top_device_info_data_pri_base_align_v(void) +{ + return 0x0000000cU; +} +static inline u32 top_device_info_data_fault_id_enum_v(u32 r) +{ + return (r >> 3U) & 0x7fU; +} +static inline u32 top_device_info_data_fault_id_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 top_device_info_data_fault_id_valid_v(void) +{ + return 0x00000001U; +} +#endif diff --git a/include/nvgpu/hw/gv11b/hw_usermode_gv11b.h b/include/nvgpu/hw/gv11b/hw_usermode_gv11b.h new file mode 100644 index 0000000..e374969 --- /dev/null +++ b/include/nvgpu/hw/gv11b/hw_usermode_gv11b.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016, 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. + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_usermode_gv11b_h_ +#define _hw_usermode_gv11b_h_ + +static inline u32 usermode_cfg0_r(void) +{ + return 0x00810000; +} +static inline u32 usermode_cfg0_usermode_class_id_f(u32 v) +{ + return (v & 0xffff) << 0; +} +static inline u32 usermode_cfg0_usermode_class_id_value_v(void) +{ + return 0x0000c361; +} +static inline u32 usermode_time_0_r(void) +{ + return 0x00810080; +} +static inline u32 usermode_time_0_nsec_f(u32 v) +{ + return (v & 0x7ffffff) << 5; +} +static inline u32 usermode_time_1_r(void) +{ + return 0x00810084; +} +static inline u32 usermode_time_1_nsec_f(u32 v) +{ + return (v & 0x1fffffff) << 0; +} +static inline u32 usermode_notify_channel_pending_r(void) +{ + return 0x00810090; +} +static inline u32 usermode_notify_channel_pending_id_f(u32 v) +{ + return (v & 0xffffffff) << 0; +} +#endif diff --git a/include/nvgpu/hw_sim.h b/include/nvgpu/hw_sim.h new file mode 100644 index 0000000..89ce6da --- /dev/null +++ b/include/nvgpu/hw_sim.h @@ -0,0 +1,2153 @@ +/* + * Copyright (c) 2012-2018, NVIDIA Corporation. + * + * 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. + */ + + /* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ + +#ifndef __hw_sim_h__ +#define __hw_sim_h__ +/*This file is autogenerated. Do not edit. */ + +static inline u32 sim_send_ring_r(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_target_s(void) +{ + return 2; +} +static inline u32 sim_send_ring_target_f(u32 v) +{ + return (v & 0x3) << 0; +} +static inline u32 sim_send_ring_target_m(void) +{ + return 0x3 << 0; +} +static inline u32 sim_send_ring_target_v(u32 r) +{ + return (r >> 0) & 0x3; +} +static inline u32 sim_send_ring_target_phys_init_v(void) +{ + return 0x00000001; +} +static inline u32 sim_send_ring_target_phys_init_f(void) +{ + return 0x1; +} +static inline u32 sim_send_ring_target_phys__init_v(void) +{ + return 0x00000001; +} +static inline u32 sim_send_ring_target_phys__init_f(void) +{ + return 0x1; +} +static inline u32 sim_send_ring_target_phys__prod_v(void) +{ + return 0x00000001; +} +static inline u32 sim_send_ring_target_phys__prod_f(void) +{ + return 0x1; +} +static inline u32 sim_send_ring_target_phys_nvm_v(void) +{ + return 0x00000001; +} +static inline u32 sim_send_ring_target_phys_nvm_f(void) +{ + return 0x1; +} +static inline u32 sim_send_ring_target_phys_pci_v(void) +{ + return 0x00000002; +} +static inline u32 sim_send_ring_target_phys_pci_f(void) +{ + return 0x2; +} +static inline u32 sim_send_ring_target_phys_pci_coherent_v(void) +{ + return 0x00000003; +} +static inline u32 sim_send_ring_target_phys_pci_coherent_f(void) +{ + return 0x3; +} +static inline u32 sim_send_ring_status_s(void) +{ + return 1; +} +static inline u32 sim_send_ring_status_f(u32 v) +{ + return (v & 0x1) << 3; +} +static inline u32 sim_send_ring_status_m(void) +{ + return 0x1 << 3; +} +static inline u32 sim_send_ring_status_v(u32 r) +{ + return (r >> 3) & 0x1; +} +static inline u32 sim_send_ring_status_init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_status_init_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_status__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_status__init_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_status__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_status__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_status_invalid_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_status_invalid_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_status_valid_v(void) +{ + return 0x00000001; +} +static inline u32 sim_send_ring_status_valid_f(void) +{ + return 0x8; +} +static inline u32 sim_send_ring_size_s(void) +{ + return 2; +} +static inline u32 sim_send_ring_size_f(u32 v) +{ + return (v & 0x3) << 4; +} +static inline u32 sim_send_ring_size_m(void) +{ + return 0x3 << 4; +} +static inline u32 sim_send_ring_size_v(u32 r) +{ + return (r >> 4) & 0x3; +} +static inline u32 sim_send_ring_size_init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_size_init_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_size__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_size__init_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_size__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_size__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_size_4kb_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_size_4kb_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_size_8kb_v(void) +{ + return 0x00000001; +} +static inline u32 sim_send_ring_size_8kb_f(void) +{ + return 0x10; +} +static inline u32 sim_send_ring_size_12kb_v(void) +{ + return 0x00000002; +} +static inline u32 sim_send_ring_size_12kb_f(void) +{ + return 0x20; +} +static inline u32 sim_send_ring_size_16kb_v(void) +{ + return 0x00000003; +} +static inline u32 sim_send_ring_size_16kb_f(void) +{ + return 0x30; +} +static inline u32 sim_send_ring_gp_in_ring_s(void) +{ + return 1; +} +static inline u32 sim_send_ring_gp_in_ring_f(u32 v) +{ + return (v & 0x1) << 11; +} +static inline u32 sim_send_ring_gp_in_ring_m(void) +{ + return 0x1 << 11; +} +static inline u32 sim_send_ring_gp_in_ring_v(u32 r) +{ + return (r >> 11) & 0x1; +} +static inline u32 sim_send_ring_gp_in_ring__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_gp_in_ring__init_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_gp_in_ring__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_gp_in_ring__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_gp_in_ring_no_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_gp_in_ring_no_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_gp_in_ring_yes_v(void) +{ + return 0x00000001; +} +static inline u32 sim_send_ring_gp_in_ring_yes_f(void) +{ + return 0x800; +} +static inline u32 sim_send_ring_addr_lo_s(void) +{ + return 20; +} +static inline u32 sim_send_ring_addr_lo_f(u32 v) +{ + return (v & 0xfffff) << 12; +} +static inline u32 sim_send_ring_addr_lo_m(void) +{ + return 0xfffff << 12; +} +static inline u32 sim_send_ring_addr_lo_v(u32 r) +{ + return (r >> 12) & 0xfffff; +} +static inline u32 sim_send_ring_addr_lo__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_addr_lo__init_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_addr_lo__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_addr_lo__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_hi_r(void) +{ + return 0x00000004; +} +static inline u32 sim_send_ring_hi_addr_s(void) +{ + return 20; +} +static inline u32 sim_send_ring_hi_addr_f(u32 v) +{ + return (v & 0xfffff) << 0; +} +static inline u32 sim_send_ring_hi_addr_m(void) +{ + return 0xfffff << 0; +} +static inline u32 sim_send_ring_hi_addr_v(u32 r) +{ + return (r >> 0) & 0xfffff; +} +static inline u32 sim_send_ring_hi_addr__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_hi_addr__init_f(void) +{ + return 0x0; +} +static inline u32 sim_send_ring_hi_addr__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_send_ring_hi_addr__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_send_put_r(void) +{ + return 0x00000008; +} +static inline u32 sim_send_put_pointer_s(void) +{ + return 29; +} +static inline u32 sim_send_put_pointer_f(u32 v) +{ + return (v & 0x1fffffff) << 3; +} +static inline u32 sim_send_put_pointer_m(void) +{ + return 0x1fffffff << 3; +} +static inline u32 sim_send_put_pointer_v(u32 r) +{ + return (r >> 3) & 0x1fffffff; +} +static inline u32 sim_send_get_r(void) +{ + return 0x0000000c; +} +static inline u32 sim_send_get_pointer_s(void) +{ + return 29; +} +static inline u32 sim_send_get_pointer_f(u32 v) +{ + return (v & 0x1fffffff) << 3; +} +static inline u32 sim_send_get_pointer_m(void) +{ + return 0x1fffffff << 3; +} +static inline u32 sim_send_get_pointer_v(u32 r) +{ + return (r >> 3) & 0x1fffffff; +} +static inline u32 sim_recv_ring_r(void) +{ + return 0x00000010; +} +static inline u32 sim_recv_ring_target_s(void) +{ + return 2; +} +static inline u32 sim_recv_ring_target_f(u32 v) +{ + return (v & 0x3) << 0; +} +static inline u32 sim_recv_ring_target_m(void) +{ + return 0x3 << 0; +} +static inline u32 sim_recv_ring_target_v(u32 r) +{ + return (r >> 0) & 0x3; +} +static inline u32 sim_recv_ring_target_phys_init_v(void) +{ + return 0x00000001; +} +static inline u32 sim_recv_ring_target_phys_init_f(void) +{ + return 0x1; +} +static inline u32 sim_recv_ring_target_phys__init_v(void) +{ + return 0x00000001; +} +static inline u32 sim_recv_ring_target_phys__init_f(void) +{ + return 0x1; +} +static inline u32 sim_recv_ring_target_phys__prod_v(void) +{ + return 0x00000001; +} +static inline u32 sim_recv_ring_target_phys__prod_f(void) +{ + return 0x1; +} +static inline u32 sim_recv_ring_target_phys_nvm_v(void) +{ + return 0x00000001; +} +static inline u32 sim_recv_ring_target_phys_nvm_f(void) +{ + return 0x1; +} +static inline u32 sim_recv_ring_target_phys_pci_v(void) +{ + return 0x00000002; +} +static inline u32 sim_recv_ring_target_phys_pci_f(void) +{ + return 0x2; +} +static inline u32 sim_recv_ring_target_phys_pci_coherent_v(void) +{ + return 0x00000003; +} +static inline u32 sim_recv_ring_target_phys_pci_coherent_f(void) +{ + return 0x3; +} +static inline u32 sim_recv_ring_status_s(void) +{ + return 1; +} +static inline u32 sim_recv_ring_status_f(u32 v) +{ + return (v & 0x1) << 3; +} +static inline u32 sim_recv_ring_status_m(void) +{ + return 0x1 << 3; +} +static inline u32 sim_recv_ring_status_v(u32 r) +{ + return (r >> 3) & 0x1; +} +static inline u32 sim_recv_ring_status_init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_status_init_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_status__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_status__init_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_status__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_status__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_status_invalid_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_status_invalid_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_status_valid_v(void) +{ + return 0x00000001; +} +static inline u32 sim_recv_ring_status_valid_f(void) +{ + return 0x8; +} +static inline u32 sim_recv_ring_size_s(void) +{ + return 2; +} +static inline u32 sim_recv_ring_size_f(u32 v) +{ + return (v & 0x3) << 4; +} +static inline u32 sim_recv_ring_size_m(void) +{ + return 0x3 << 4; +} +static inline u32 sim_recv_ring_size_v(u32 r) +{ + return (r >> 4) & 0x3; +} +static inline u32 sim_recv_ring_size_init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_size_init_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_size__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_size__init_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_size__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_size__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_size_4kb_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_size_4kb_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_size_8kb_v(void) +{ + return 0x00000001; +} +static inline u32 sim_recv_ring_size_8kb_f(void) +{ + return 0x10; +} +static inline u32 sim_recv_ring_size_12kb_v(void) +{ + return 0x00000002; +} +static inline u32 sim_recv_ring_size_12kb_f(void) +{ + return 0x20; +} +static inline u32 sim_recv_ring_size_16kb_v(void) +{ + return 0x00000003; +} +static inline u32 sim_recv_ring_size_16kb_f(void) +{ + return 0x30; +} +static inline u32 sim_recv_ring_gp_in_ring_s(void) +{ + return 1; +} +static inline u32 sim_recv_ring_gp_in_ring_f(u32 v) +{ + return (v & 0x1) << 11; +} +static inline u32 sim_recv_ring_gp_in_ring_m(void) +{ + return 0x1 << 11; +} +static inline u32 sim_recv_ring_gp_in_ring_v(u32 r) +{ + return (r >> 11) & 0x1; +} +static inline u32 sim_recv_ring_gp_in_ring__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_gp_in_ring__init_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_gp_in_ring__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_gp_in_ring__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_gp_in_ring_no_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_gp_in_ring_no_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_gp_in_ring_yes_v(void) +{ + return 0x00000001; +} +static inline u32 sim_recv_ring_gp_in_ring_yes_f(void) +{ + return 0x800; +} +static inline u32 sim_recv_ring_addr_lo_s(void) +{ + return 20; +} +static inline u32 sim_recv_ring_addr_lo_f(u32 v) +{ + return (v & 0xfffff) << 12; +} +static inline u32 sim_recv_ring_addr_lo_m(void) +{ + return 0xfffff << 12; +} +static inline u32 sim_recv_ring_addr_lo_v(u32 r) +{ + return (r >> 12) & 0xfffff; +} +static inline u32 sim_recv_ring_addr_lo__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_addr_lo__init_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_addr_lo__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_addr_lo__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_hi_r(void) +{ + return 0x00000014; +} +static inline u32 sim_recv_ring_hi_addr_s(void) +{ + return 20; +} +static inline u32 sim_recv_ring_hi_addr_f(u32 v) +{ + return (v & 0xfffff) << 0; +} +static inline u32 sim_recv_ring_hi_addr_m(void) +{ + return 0xfffff << 0; +} +static inline u32 sim_recv_ring_hi_addr_v(u32 r) +{ + return (r >> 0) & 0xfffff; +} +static inline u32 sim_recv_ring_hi_addr__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_hi_addr__init_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_ring_hi_addr__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_recv_ring_hi_addr__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_recv_put_r(void) +{ + return 0x00000018; +} +static inline u32 sim_recv_put_pointer_s(void) +{ + return 11; +} +static inline u32 sim_recv_put_pointer_f(u32 v) +{ + return (v & 0x7ff) << 3; +} +static inline u32 sim_recv_put_pointer_m(void) +{ + return 0x7ff << 3; +} +static inline u32 sim_recv_put_pointer_v(u32 r) +{ + return (r >> 3) & 0x7ff; +} +static inline u32 sim_recv_get_r(void) +{ + return 0x0000001c; +} +static inline u32 sim_recv_get_pointer_s(void) +{ + return 11; +} +static inline u32 sim_recv_get_pointer_f(u32 v) +{ + return (v & 0x7ff) << 3; +} +static inline u32 sim_recv_get_pointer_m(void) +{ + return 0x7ff << 3; +} +static inline u32 sim_recv_get_pointer_v(u32 r) +{ + return (r >> 3) & 0x7ff; +} +static inline u32 sim_config_r(void) +{ + return 0x00000020; +} +static inline u32 sim_config_mode_s(void) +{ + return 1; +} +static inline u32 sim_config_mode_f(u32 v) +{ + return (v & 0x1) << 0; +} +static inline u32 sim_config_mode_m(void) +{ + return 0x1 << 0; +} +static inline u32 sim_config_mode_v(u32 r) +{ + return (r >> 0) & 0x1; +} +static inline u32 sim_config_mode_disabled_v(void) +{ + return 0x00000000; +} +static inline u32 sim_config_mode_disabled_f(void) +{ + return 0x0; +} +static inline u32 sim_config_mode_enabled_v(void) +{ + return 0x00000001; +} +static inline u32 sim_config_mode_enabled_f(void) +{ + return 0x1; +} +static inline u32 sim_config_channels_s(void) +{ + return 7; +} +static inline u32 sim_config_channels_f(u32 v) +{ + return (v & 0x7f) << 1; +} +static inline u32 sim_config_channels_m(void) +{ + return 0x7f << 1; +} +static inline u32 sim_config_channels_v(u32 r) +{ + return (r >> 1) & 0x7f; +} +static inline u32 sim_config_channels_none_v(void) +{ + return 0x00000000; +} +static inline u32 sim_config_channels_none_f(void) +{ + return 0x0; +} +static inline u32 sim_config_cached_only_s(void) +{ + return 1; +} +static inline u32 sim_config_cached_only_f(u32 v) +{ + return (v & 0x1) << 8; +} +static inline u32 sim_config_cached_only_m(void) +{ + return 0x1 << 8; +} +static inline u32 sim_config_cached_only_v(u32 r) +{ + return (r >> 8) & 0x1; +} +static inline u32 sim_config_cached_only_disabled_v(void) +{ + return 0x00000000; +} +static inline u32 sim_config_cached_only_disabled_f(void) +{ + return 0x0; +} +static inline u32 sim_config_cached_only_enabled_v(void) +{ + return 0x00000001; +} +static inline u32 sim_config_cached_only_enabled_f(void) +{ + return 0x100; +} +static inline u32 sim_config_validity_s(void) +{ + return 2; +} +static inline u32 sim_config_validity_f(u32 v) +{ + return (v & 0x3) << 9; +} +static inline u32 sim_config_validity_m(void) +{ + return 0x3 << 9; +} +static inline u32 sim_config_validity_v(u32 r) +{ + return (r >> 9) & 0x3; +} +static inline u32 sim_config_validity__init_v(void) +{ + return 0x00000001; +} +static inline u32 sim_config_validity__init_f(void) +{ + return 0x200; +} +static inline u32 sim_config_validity_valid_v(void) +{ + return 0x00000001; +} +static inline u32 sim_config_validity_valid_f(void) +{ + return 0x200; +} +static inline u32 sim_config_simulation_s(void) +{ + return 2; +} +static inline u32 sim_config_simulation_f(u32 v) +{ + return (v & 0x3) << 12; +} +static inline u32 sim_config_simulation_m(void) +{ + return 0x3 << 12; +} +static inline u32 sim_config_simulation_v(u32 r) +{ + return (r >> 12) & 0x3; +} +static inline u32 sim_config_simulation_disabled_v(void) +{ + return 0x00000000; +} +static inline u32 sim_config_simulation_disabled_f(void) +{ + return 0x0; +} +static inline u32 sim_config_simulation_fmodel_v(void) +{ + return 0x00000001; +} +static inline u32 sim_config_simulation_fmodel_f(void) +{ + return 0x1000; +} +static inline u32 sim_config_simulation_rtlsim_v(void) +{ + return 0x00000002; +} +static inline u32 sim_config_simulation_rtlsim_f(void) +{ + return 0x2000; +} +static inline u32 sim_config_secondary_display_s(void) +{ + return 1; +} +static inline u32 sim_config_secondary_display_f(u32 v) +{ + return (v & 0x1) << 14; +} +static inline u32 sim_config_secondary_display_m(void) +{ + return 0x1 << 14; +} +static inline u32 sim_config_secondary_display_v(u32 r) +{ + return (r >> 14) & 0x1; +} +static inline u32 sim_config_secondary_display_disabled_v(void) +{ + return 0x00000000; +} +static inline u32 sim_config_secondary_display_disabled_f(void) +{ + return 0x0; +} +static inline u32 sim_config_secondary_display_enabled_v(void) +{ + return 0x00000001; +} +static inline u32 sim_config_secondary_display_enabled_f(void) +{ + return 0x4000; +} +static inline u32 sim_config_num_heads_s(void) +{ + return 8; +} +static inline u32 sim_config_num_heads_f(u32 v) +{ + return (v & 0xff) << 17; +} +static inline u32 sim_config_num_heads_m(void) +{ + return 0xff << 17; +} +static inline u32 sim_config_num_heads_v(u32 r) +{ + return (r >> 17) & 0xff; +} +static inline u32 sim_event_ring_r(void) +{ + return 0x00000030; +} +static inline u32 sim_event_ring_target_s(void) +{ + return 2; +} +static inline u32 sim_event_ring_target_f(u32 v) +{ + return (v & 0x3) << 0; +} +static inline u32 sim_event_ring_target_m(void) +{ + return 0x3 << 0; +} +static inline u32 sim_event_ring_target_v(u32 r) +{ + return (r >> 0) & 0x3; +} +static inline u32 sim_event_ring_target_phys_init_v(void) +{ + return 0x00000001; +} +static inline u32 sim_event_ring_target_phys_init_f(void) +{ + return 0x1; +} +static inline u32 sim_event_ring_target_phys__init_v(void) +{ + return 0x00000001; +} +static inline u32 sim_event_ring_target_phys__init_f(void) +{ + return 0x1; +} +static inline u32 sim_event_ring_target_phys__prod_v(void) +{ + return 0x00000001; +} +static inline u32 sim_event_ring_target_phys__prod_f(void) +{ + return 0x1; +} +static inline u32 sim_event_ring_target_phys_nvm_v(void) +{ + return 0x00000001; +} +static inline u32 sim_event_ring_target_phys_nvm_f(void) +{ + return 0x1; +} +static inline u32 sim_event_ring_target_phys_pci_v(void) +{ + return 0x00000002; +} +static inline u32 sim_event_ring_target_phys_pci_f(void) +{ + return 0x2; +} +static inline u32 sim_event_ring_target_phys_pci_coherent_v(void) +{ + return 0x00000003; +} +static inline u32 sim_event_ring_target_phys_pci_coherent_f(void) +{ + return 0x3; +} +static inline u32 sim_event_ring_status_s(void) +{ + return 1; +} +static inline u32 sim_event_ring_status_f(u32 v) +{ + return (v & 0x1) << 3; +} +static inline u32 sim_event_ring_status_m(void) +{ + return 0x1 << 3; +} +static inline u32 sim_event_ring_status_v(u32 r) +{ + return (r >> 3) & 0x1; +} +static inline u32 sim_event_ring_status_init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_status_init_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_status__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_status__init_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_status__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_status__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_status_invalid_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_status_invalid_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_status_valid_v(void) +{ + return 0x00000001; +} +static inline u32 sim_event_ring_status_valid_f(void) +{ + return 0x8; +} +static inline u32 sim_event_ring_size_s(void) +{ + return 2; +} +static inline u32 sim_event_ring_size_f(u32 v) +{ + return (v & 0x3) << 4; +} +static inline u32 sim_event_ring_size_m(void) +{ + return 0x3 << 4; +} +static inline u32 sim_event_ring_size_v(u32 r) +{ + return (r >> 4) & 0x3; +} +static inline u32 sim_event_ring_size_init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_size_init_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_size__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_size__init_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_size__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_size__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_size_4kb_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_size_4kb_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_size_8kb_v(void) +{ + return 0x00000001; +} +static inline u32 sim_event_ring_size_8kb_f(void) +{ + return 0x10; +} +static inline u32 sim_event_ring_size_12kb_v(void) +{ + return 0x00000002; +} +static inline u32 sim_event_ring_size_12kb_f(void) +{ + return 0x20; +} +static inline u32 sim_event_ring_size_16kb_v(void) +{ + return 0x00000003; +} +static inline u32 sim_event_ring_size_16kb_f(void) +{ + return 0x30; +} +static inline u32 sim_event_ring_gp_in_ring_s(void) +{ + return 1; +} +static inline u32 sim_event_ring_gp_in_ring_f(u32 v) +{ + return (v & 0x1) << 11; +} +static inline u32 sim_event_ring_gp_in_ring_m(void) +{ + return 0x1 << 11; +} +static inline u32 sim_event_ring_gp_in_ring_v(u32 r) +{ + return (r >> 11) & 0x1; +} +static inline u32 sim_event_ring_gp_in_ring__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_gp_in_ring__init_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_gp_in_ring__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_gp_in_ring__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_gp_in_ring_no_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_gp_in_ring_no_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_gp_in_ring_yes_v(void) +{ + return 0x00000001; +} +static inline u32 sim_event_ring_gp_in_ring_yes_f(void) +{ + return 0x800; +} +static inline u32 sim_event_ring_addr_lo_s(void) +{ + return 20; +} +static inline u32 sim_event_ring_addr_lo_f(u32 v) +{ + return (v & 0xfffff) << 12; +} +static inline u32 sim_event_ring_addr_lo_m(void) +{ + return 0xfffff << 12; +} +static inline u32 sim_event_ring_addr_lo_v(u32 r) +{ + return (r >> 12) & 0xfffff; +} +static inline u32 sim_event_ring_addr_lo__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_addr_lo__init_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_addr_lo__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_addr_lo__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_hi_v(void) +{ + return 0x00000034; +} +static inline u32 sim_event_ring_hi_addr_s(void) +{ + return 20; +} +static inline u32 sim_event_ring_hi_addr_f(u32 v) +{ + return (v & 0xfffff) << 0; +} +static inline u32 sim_event_ring_hi_addr_m(void) +{ + return 0xfffff << 0; +} +static inline u32 sim_event_ring_hi_addr_v(u32 r) +{ + return (r >> 0) & 0xfffff; +} +static inline u32 sim_event_ring_hi_addr__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_hi_addr__init_f(void) +{ + return 0x0; +} +static inline u32 sim_event_ring_hi_addr__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_event_ring_hi_addr__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_event_put_r(void) +{ + return 0x00000038; +} +static inline u32 sim_event_put_pointer_s(void) +{ + return 30; +} +static inline u32 sim_event_put_pointer_f(u32 v) +{ + return (v & 0x3fffffff) << 2; +} +static inline u32 sim_event_put_pointer_m(void) +{ + return 0x3fffffff << 2; +} +static inline u32 sim_event_put_pointer_v(u32 r) +{ + return (r >> 2) & 0x3fffffff; +} +static inline u32 sim_event_get_r(void) +{ + return 0x0000003c; +} +static inline u32 sim_event_get_pointer_s(void) +{ + return 30; +} +static inline u32 sim_event_get_pointer_f(u32 v) +{ + return (v & 0x3fffffff) << 2; +} +static inline u32 sim_event_get_pointer_m(void) +{ + return 0x3fffffff << 2; +} +static inline u32 sim_event_get_pointer_v(u32 r) +{ + return (r >> 2) & 0x3fffffff; +} +static inline u32 sim_status_r(void) +{ + return 0x00000028; +} +static inline u32 sim_status_send_put_s(void) +{ + return 1; +} +static inline u32 sim_status_send_put_f(u32 v) +{ + return (v & 0x1) << 0; +} +static inline u32 sim_status_send_put_m(void) +{ + return 0x1 << 0; +} +static inline u32 sim_status_send_put_v(u32 r) +{ + return (r >> 0) & 0x1; +} +static inline u32 sim_status_send_put__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_send_put__init_f(void) +{ + return 0x0; +} +static inline u32 sim_status_send_put_idle_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_send_put_idle_f(void) +{ + return 0x0; +} +static inline u32 sim_status_send_put_pending_v(void) +{ + return 0x00000001; +} +static inline u32 sim_status_send_put_pending_f(void) +{ + return 0x1; +} +static inline u32 sim_status_send_get_s(void) +{ + return 1; +} +static inline u32 sim_status_send_get_f(u32 v) +{ + return (v & 0x1) << 1; +} +static inline u32 sim_status_send_get_m(void) +{ + return 0x1 << 1; +} +static inline u32 sim_status_send_get_v(u32 r) +{ + return (r >> 1) & 0x1; +} +static inline u32 sim_status_send_get__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_send_get__init_f(void) +{ + return 0x0; +} +static inline u32 sim_status_send_get_idle_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_send_get_idle_f(void) +{ + return 0x0; +} +static inline u32 sim_status_send_get_pending_v(void) +{ + return 0x00000001; +} +static inline u32 sim_status_send_get_pending_f(void) +{ + return 0x2; +} +static inline u32 sim_status_send_get_clear_v(void) +{ + return 0x00000001; +} +static inline u32 sim_status_send_get_clear_f(void) +{ + return 0x2; +} +static inline u32 sim_status_recv_put_s(void) +{ + return 1; +} +static inline u32 sim_status_recv_put_f(u32 v) +{ + return (v & 0x1) << 2; +} +static inline u32 sim_status_recv_put_m(void) +{ + return 0x1 << 2; +} +static inline u32 sim_status_recv_put_v(u32 r) +{ + return (r >> 2) & 0x1; +} +static inline u32 sim_status_recv_put__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_recv_put__init_f(void) +{ + return 0x0; +} +static inline u32 sim_status_recv_put_idle_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_recv_put_idle_f(void) +{ + return 0x0; +} +static inline u32 sim_status_recv_put_pending_v(void) +{ + return 0x00000001; +} +static inline u32 sim_status_recv_put_pending_f(void) +{ + return 0x4; +} +static inline u32 sim_status_recv_put_clear_v(void) +{ + return 0x00000001; +} +static inline u32 sim_status_recv_put_clear_f(void) +{ + return 0x4; +} +static inline u32 sim_status_recv_get_s(void) +{ + return 1; +} +static inline u32 sim_status_recv_get_f(u32 v) +{ + return (v & 0x1) << 3; +} +static inline u32 sim_status_recv_get_m(void) +{ + return 0x1 << 3; +} +static inline u32 sim_status_recv_get_v(u32 r) +{ + return (r >> 3) & 0x1; +} +static inline u32 sim_status_recv_get__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_recv_get__init_f(void) +{ + return 0x0; +} +static inline u32 sim_status_recv_get_idle_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_recv_get_idle_f(void) +{ + return 0x0; +} +static inline u32 sim_status_recv_get_pending_v(void) +{ + return 0x00000001; +} +static inline u32 sim_status_recv_get_pending_f(void) +{ + return 0x8; +} +static inline u32 sim_status_event_put_s(void) +{ + return 1; +} +static inline u32 sim_status_event_put_f(u32 v) +{ + return (v & 0x1) << 4; +} +static inline u32 sim_status_event_put_m(void) +{ + return 0x1 << 4; +} +static inline u32 sim_status_event_put_v(u32 r) +{ + return (r >> 4) & 0x1; +} +static inline u32 sim_status_event_put__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_event_put__init_f(void) +{ + return 0x0; +} +static inline u32 sim_status_event_put_idle_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_event_put_idle_f(void) +{ + return 0x0; +} +static inline u32 sim_status_event_put_pending_v(void) +{ + return 0x00000001; +} +static inline u32 sim_status_event_put_pending_f(void) +{ + return 0x10; +} +static inline u32 sim_status_event_put_clear_v(void) +{ + return 0x00000001; +} +static inline u32 sim_status_event_put_clear_f(void) +{ + return 0x10; +} +static inline u32 sim_status_event_get_s(void) +{ + return 1; +} +static inline u32 sim_status_event_get_f(u32 v) +{ + return (v & 0x1) << 5; +} +static inline u32 sim_status_event_get_m(void) +{ + return 0x1 << 5; +} +static inline u32 sim_status_event_get_v(u32 r) +{ + return (r >> 5) & 0x1; +} +static inline u32 sim_status_event_get__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_event_get__init_f(void) +{ + return 0x0; +} +static inline u32 sim_status_event_get_idle_v(void) +{ + return 0x00000000; +} +static inline u32 sim_status_event_get_idle_f(void) +{ + return 0x0; +} +static inline u32 sim_status_event_get_pending_v(void) +{ + return 0x00000001; +} +static inline u32 sim_status_event_get_pending_f(void) +{ + return 0x20; +} +static inline u32 sim_control_r(void) +{ + return 0x0000002c; +} +static inline u32 sim_control_send_put_s(void) +{ + return 1; +} +static inline u32 sim_control_send_put_f(u32 v) +{ + return (v & 0x1) << 0; +} +static inline u32 sim_control_send_put_m(void) +{ + return 0x1 << 0; +} +static inline u32 sim_control_send_put_v(u32 r) +{ + return (r >> 0) & 0x1; +} +static inline u32 sim_control_send_put__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_send_put__init_f(void) +{ + return 0x0; +} +static inline u32 sim_control_send_put_disabled_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_send_put_disabled_f(void) +{ + return 0x0; +} +static inline u32 sim_control_send_put_enabled_v(void) +{ + return 0x00000001; +} +static inline u32 sim_control_send_put_enabled_f(void) +{ + return 0x1; +} +static inline u32 sim_control_send_get_s(void) +{ + return 1; +} +static inline u32 sim_control_send_get_f(u32 v) +{ + return (v & 0x1) << 1; +} +static inline u32 sim_control_send_get_m(void) +{ + return 0x1 << 1; +} +static inline u32 sim_control_send_get_v(u32 r) +{ + return (r >> 1) & 0x1; +} +static inline u32 sim_control_send_get__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_send_get__init_f(void) +{ + return 0x0; +} +static inline u32 sim_control_send_get_disabled_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_send_get_disabled_f(void) +{ + return 0x0; +} +static inline u32 sim_control_send_get_enabled_v(void) +{ + return 0x00000001; +} +static inline u32 sim_control_send_get_enabled_f(void) +{ + return 0x2; +} +static inline u32 sim_control_recv_put_s(void) +{ + return 1; +} +static inline u32 sim_control_recv_put_f(u32 v) +{ + return (v & 0x1) << 2; +} +static inline u32 sim_control_recv_put_m(void) +{ + return 0x1 << 2; +} +static inline u32 sim_control_recv_put_v(u32 r) +{ + return (r >> 2) & 0x1; +} +static inline u32 sim_control_recv_put__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_recv_put__init_f(void) +{ + return 0x0; +} +static inline u32 sim_control_recv_put_disabled_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_recv_put_disabled_f(void) +{ + return 0x0; +} +static inline u32 sim_control_recv_put_enabled_v(void) +{ + return 0x00000001; +} +static inline u32 sim_control_recv_put_enabled_f(void) +{ + return 0x4; +} +static inline u32 sim_control_recv_get_s(void) +{ + return 1; +} +static inline u32 sim_control_recv_get_f(u32 v) +{ + return (v & 0x1) << 3; +} +static inline u32 sim_control_recv_get_m(void) +{ + return 0x1 << 3; +} +static inline u32 sim_control_recv_get_v(u32 r) +{ + return (r >> 3) & 0x1; +} +static inline u32 sim_control_recv_get__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_recv_get__init_f(void) +{ + return 0x0; +} +static inline u32 sim_control_recv_get_disabled_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_recv_get_disabled_f(void) +{ + return 0x0; +} +static inline u32 sim_control_recv_get_enabled_v(void) +{ + return 0x00000001; +} +static inline u32 sim_control_recv_get_enabled_f(void) +{ + return 0x8; +} +static inline u32 sim_control_event_put_s(void) +{ + return 1; +} +static inline u32 sim_control_event_put_f(u32 v) +{ + return (v & 0x1) << 4; +} +static inline u32 sim_control_event_put_m(void) +{ + return 0x1 << 4; +} +static inline u32 sim_control_event_put_v(u32 r) +{ + return (r >> 4) & 0x1; +} +static inline u32 sim_control_event_put__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_event_put__init_f(void) +{ + return 0x0; +} +static inline u32 sim_control_event_put_disabled_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_event_put_disabled_f(void) +{ + return 0x0; +} +static inline u32 sim_control_event_put_enabled_v(void) +{ + return 0x00000001; +} +static inline u32 sim_control_event_put_enabled_f(void) +{ + return 0x10; +} +static inline u32 sim_control_event_get_s(void) +{ + return 1; +} +static inline u32 sim_control_event_get_f(u32 v) +{ + return (v & 0x1) << 5; +} +static inline u32 sim_control_event_get_m(void) +{ + return 0x1 << 5; +} +static inline u32 sim_control_event_get_v(u32 r) +{ + return (r >> 5) & 0x1; +} +static inline u32 sim_control_event_get__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_event_get__init_f(void) +{ + return 0x0; +} +static inline u32 sim_control_event_get_disabled_v(void) +{ + return 0x00000000; +} +static inline u32 sim_control_event_get_disabled_f(void) +{ + return 0x0; +} +static inline u32 sim_control_event_get_enabled_v(void) +{ + return 0x00000001; +} +static inline u32 sim_control_event_get_enabled_f(void) +{ + return 0x20; +} +static inline u32 sim_dma_r(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_target_s(void) +{ + return 2; +} +static inline u32 sim_dma_target_f(u32 v) +{ + return (v & 0x3) << 0; +} +static inline u32 sim_dma_target_m(void) +{ + return 0x3 << 0; +} +static inline u32 sim_dma_target_v(u32 r) +{ + return (r >> 0) & 0x3; +} +static inline u32 sim_dma_target_phys_init_v(void) +{ + return 0x00000001; +} +static inline u32 sim_dma_target_phys_init_f(void) +{ + return 0x1; +} +static inline u32 sim_dma_target_phys__init_v(void) +{ + return 0x00000001; +} +static inline u32 sim_dma_target_phys__init_f(void) +{ + return 0x1; +} +static inline u32 sim_dma_target_phys__prod_v(void) +{ + return 0x00000001; +} +static inline u32 sim_dma_target_phys__prod_f(void) +{ + return 0x1; +} +static inline u32 sim_dma_target_phys_nvm_v(void) +{ + return 0x00000001; +} +static inline u32 sim_dma_target_phys_nvm_f(void) +{ + return 0x1; +} +static inline u32 sim_dma_target_phys_pci_v(void) +{ + return 0x00000002; +} +static inline u32 sim_dma_target_phys_pci_f(void) +{ + return 0x2; +} +static inline u32 sim_dma_target_phys_pci_coherent_v(void) +{ + return 0x00000003; +} +static inline u32 sim_dma_target_phys_pci_coherent_f(void) +{ + return 0x3; +} +static inline u32 sim_dma_status_s(void) +{ + return 1; +} +static inline u32 sim_dma_status_f(u32 v) +{ + return (v & 0x1) << 3; +} +static inline u32 sim_dma_status_m(void) +{ + return 0x1 << 3; +} +static inline u32 sim_dma_status_v(u32 r) +{ + return (r >> 3) & 0x1; +} +static inline u32 sim_dma_status_init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_status_init_f(void) +{ + return 0x0; +} +static inline u32 sim_dma_status__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_status__init_f(void) +{ + return 0x0; +} +static inline u32 sim_dma_status__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_status__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_dma_status_invalid_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_status_invalid_f(void) +{ + return 0x0; +} +static inline u32 sim_dma_status_valid_v(void) +{ + return 0x00000001; +} +static inline u32 sim_dma_status_valid_f(void) +{ + return 0x8; +} +static inline u32 sim_dma_size_s(void) +{ + return 2; +} +static inline u32 sim_dma_size_f(u32 v) +{ + return (v & 0x3) << 4; +} +static inline u32 sim_dma_size_m(void) +{ + return 0x3 << 4; +} +static inline u32 sim_dma_size_v(u32 r) +{ + return (r >> 4) & 0x3; +} +static inline u32 sim_dma_size_init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_size_init_f(void) +{ + return 0x0; +} +static inline u32 sim_dma_size__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_size__init_f(void) +{ + return 0x0; +} +static inline u32 sim_dma_size__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_size__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_dma_size_4kb_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_size_4kb_f(void) +{ + return 0x0; +} +static inline u32 sim_dma_size_8kb_v(void) +{ + return 0x00000001; +} +static inline u32 sim_dma_size_8kb_f(void) +{ + return 0x10; +} +static inline u32 sim_dma_size_12kb_v(void) +{ + return 0x00000002; +} +static inline u32 sim_dma_size_12kb_f(void) +{ + return 0x20; +} +static inline u32 sim_dma_size_16kb_v(void) +{ + return 0x00000003; +} +static inline u32 sim_dma_size_16kb_f(void) +{ + return 0x30; +} +static inline u32 sim_dma_addr_lo_s(void) +{ + return 20; +} +static inline u32 sim_dma_addr_lo_f(u32 v) +{ + return (v & 0xfffff) << 12; +} +static inline u32 sim_dma_addr_lo_m(void) +{ + return 0xfffff << 12; +} +static inline u32 sim_dma_addr_lo_v(u32 r) +{ + return (r >> 12) & 0xfffff; +} +static inline u32 sim_dma_addr_lo__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_addr_lo__init_f(void) +{ + return 0x0; +} +static inline u32 sim_dma_addr_lo__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_addr_lo__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_dma_hi_r(void) +{ + return 0x00000004; +} +static inline u32 sim_dma_hi_addr_s(void) +{ + return 20; +} +static inline u32 sim_dma_hi_addr_f(u32 v) +{ + return (v & 0xfffff) << 0; +} +static inline u32 sim_dma_hi_addr_m(void) +{ + return 0xfffff << 0; +} +static inline u32 sim_dma_hi_addr_v(u32 r) +{ + return (r >> 0) & 0xfffff; +} +static inline u32 sim_dma_hi_addr__init_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_hi_addr__init_f(void) +{ + return 0x0; +} +static inline u32 sim_dma_hi_addr__prod_v(void) +{ + return 0x00000000; +} +static inline u32 sim_dma_hi_addr__prod_f(void) +{ + return 0x0; +} +static inline u32 sim_msg_signature_r(void) +{ + return 0x00000000; +} +static inline u32 sim_msg_signature_valid_v(void) +{ + return 0x43505256; +} +static inline u32 sim_msg_length_r(void) +{ + return 0x00000004; +} +static inline u32 sim_msg_function_r(void) +{ + return 0x00000008; +} +static inline u32 sim_msg_function_sim_escape_read_v(void) +{ + return 0x00000023; +} +static inline u32 sim_msg_function_sim_escape_write_v(void) +{ + return 0x00000024; +} +static inline u32 sim_msg_result_r(void) +{ + return 0x0000000c; +} +static inline u32 sim_msg_result_success_v(void) +{ + return 0x00000000; +} +static inline u32 sim_msg_result_rpc_pending_v(void) +{ + return 0xFFFFFFFF; +} +static inline u32 sim_msg_sequence_r(void) +{ + return 0x00000010; +} +static inline u32 sim_msg_spare_r(void) +{ + return 0x00000014; +} +static inline u32 sim_msg_spare__init_v(void) +{ + return 0x00000000; +} + +#endif /* __hw_sim__ */ diff --git a/include/nvgpu/hw_sim_pci.h b/include/nvgpu/hw_sim_pci.h new file mode 100644 index 0000000..32dbeb4 --- /dev/null +++ b/include/nvgpu/hw_sim_pci.h @@ -0,0 +1,2169 @@ +/* + * Copyright (c) 2012-2018, NVIDIA Corporation. + * + * 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. + */ + + /* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ + +#ifndef __hw_sim_pci_h__ +#define __hw_sim_pci_h__ +/*This file is autogenerated. Do not edit. */ + +static inline u32 sim_r(void) +{ + return 0x0008f000U; +} +static inline u32 sim_send_ring_r(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_target_s(void) +{ + return 2U; +} +static inline u32 sim_send_ring_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 sim_send_ring_target_m(void) +{ + return 0x3U << 0U; +} +static inline u32 sim_send_ring_target_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 sim_send_ring_target_phys_init_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_send_ring_target_phys_init_f(void) +{ + return 0x1U; +} +static inline u32 sim_send_ring_target_phys__init_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_send_ring_target_phys__init_f(void) +{ + return 0x1U; +} +static inline u32 sim_send_ring_target_phys__prod_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_send_ring_target_phys__prod_f(void) +{ + return 0x1U; +} +static inline u32 sim_send_ring_target_phys_nvm_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_send_ring_target_phys_nvm_f(void) +{ + return 0x1U; +} +static inline u32 sim_send_ring_target_phys_pci_v(void) +{ + return 0x00000002U; +} +static inline u32 sim_send_ring_target_phys_pci_f(void) +{ + return 0x2U; +} +static inline u32 sim_send_ring_target_phys_pci_coherent_v(void) +{ + return 0x00000003U; +} +static inline u32 sim_send_ring_target_phys_pci_coherent_f(void) +{ + return 0x3U; +} +static inline u32 sim_send_ring_status_s(void) +{ + return 1U; +} +static inline u32 sim_send_ring_status_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 sim_send_ring_status_m(void) +{ + return 0x1U << 3U; +} +static inline u32 sim_send_ring_status_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 sim_send_ring_status_init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_status_init_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_status__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_status__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_status__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_status__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_status_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_status_invalid_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_send_ring_status_valid_f(void) +{ + return 0x8U; +} +static inline u32 sim_send_ring_size_s(void) +{ + return 2U; +} +static inline u32 sim_send_ring_size_f(u32 v) +{ + return (v & 0x3U) << 4U; +} +static inline u32 sim_send_ring_size_m(void) +{ + return 0x3U << 4U; +} +static inline u32 sim_send_ring_size_v(u32 r) +{ + return (r >> 4U) & 0x3U; +} +static inline u32 sim_send_ring_size_init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_size_init_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_size__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_size__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_size__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_size__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_size_4kb_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_size_4kb_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_size_8kb_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_send_ring_size_8kb_f(void) +{ + return 0x10U; +} +static inline u32 sim_send_ring_size_12kb_v(void) +{ + return 0x00000002U; +} +static inline u32 sim_send_ring_size_12kb_f(void) +{ + return 0x20U; +} +static inline u32 sim_send_ring_size_16kb_v(void) +{ + return 0x00000003U; +} +static inline u32 sim_send_ring_size_16kb_f(void) +{ + return 0x30U; +} +static inline u32 sim_send_ring_gp_in_ring_s(void) +{ + return 1U; +} +static inline u32 sim_send_ring_gp_in_ring_f(u32 v) +{ + return (v & 0x1) << 11U; +} +static inline u32 sim_send_ring_gp_in_ring_m(void) +{ + return 0x1 << 11U; +} +static inline u32 sim_send_ring_gp_in_ring_v(u32 r) +{ + return (r >> 11) & 0x1U; +} +static inline u32 sim_send_ring_gp_in_ring__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_gp_in_ring__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_gp_in_ring__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_gp_in_ring__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_gp_in_ring_no_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_gp_in_ring_no_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_gp_in_ring_yes_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_send_ring_gp_in_ring_yes_f(void) +{ + return 0x800U; +} +static inline u32 sim_send_ring_addr_lo_s(void) +{ + return 20U; +} +static inline u32 sim_send_ring_addr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 sim_send_ring_addr_lo_m(void) +{ + return 0xfffffU << 12U; +} +static inline u32 sim_send_ring_addr_lo_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 sim_send_ring_addr_lo__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_addr_lo__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_addr_lo__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_addr_lo__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_hi_r(void) +{ + return 0x00000004U; +} +static inline u32 sim_send_ring_hi_addr_s(void) +{ + return 20U; +} +static inline u32 sim_send_ring_hi_addr_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 sim_send_ring_hi_addr_m(void) +{ + return 0xfffffU << 0U; +} +static inline u32 sim_send_ring_hi_addr_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 sim_send_ring_hi_addr__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_hi_addr__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_ring_hi_addr__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_send_ring_hi_addr__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_send_put_r(void) +{ + return 0x00000008U; +} +static inline u32 sim_send_put_pointer_s(void) +{ + return 29U; +} +static inline u32 sim_send_put_pointer_f(u32 v) +{ + return (v & 0x1fffffffU) << 3U; +} +static inline u32 sim_send_put_pointer_m(void) +{ + return 0x1fffffffU << 3U; +} +static inline u32 sim_send_put_pointer_v(u32 r) +{ + return (r >> 3U) & 0x1fffffffU; +} +static inline u32 sim_send_get_r(void) +{ + return 0x0000000cU; +} +static inline u32 sim_send_get_pointer_s(void) +{ + return 29U; +} +static inline u32 sim_send_get_pointer_f(u32 v) +{ + return (v & 0x1fffffffU) << 3U; +} +static inline u32 sim_send_get_pointer_m(void) +{ + return 0x1fffffffU << 3U; +} +static inline u32 sim_send_get_pointer_v(u32 r) +{ + return (r >> 3U) & 0x1fffffffU; +} +static inline u32 sim_recv_ring_r(void) +{ + return 0x00000010U; +} +static inline u32 sim_recv_ring_target_s(void) +{ + return 2U; +} +static inline u32 sim_recv_ring_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 sim_recv_ring_target_m(void) +{ + return 0x3U << 0U; +} +static inline u32 sim_recv_ring_target_v(u32 r) +{ + return (r >> 0) & 0x3U; +} +static inline u32 sim_recv_ring_target_phys_init_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_recv_ring_target_phys_init_f(void) +{ + return 0x1U; +} +static inline u32 sim_recv_ring_target_phys__init_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_recv_ring_target_phys__init_f(void) +{ + return 0x1U; +} +static inline u32 sim_recv_ring_target_phys__prod_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_recv_ring_target_phys__prod_f(void) +{ + return 0x1U; +} +static inline u32 sim_recv_ring_target_phys_nvm_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_recv_ring_target_phys_nvm_f(void) +{ + return 0x1U; +} +static inline u32 sim_recv_ring_target_phys_pci_v(void) +{ + return 0x00000002U; +} +static inline u32 sim_recv_ring_target_phys_pci_f(void) +{ + return 0x2U; +} +static inline u32 sim_recv_ring_target_phys_pci_coherent_v(void) +{ + return 0x00000003U; +} +static inline u32 sim_recv_ring_target_phys_pci_coherent_f(void) +{ + return 0x3U; +} +static inline u32 sim_recv_ring_status_s(void) +{ + return 1U; +} +static inline u32 sim_recv_ring_status_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 sim_recv_ring_status_m(void) +{ + return 0x1U << 3U; +} +static inline u32 sim_recv_ring_status_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 sim_recv_ring_status_init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_status_init_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_status__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_status__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_status__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_status__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_status_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_status_invalid_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_recv_ring_status_valid_f(void) +{ + return 0x8U; +} +static inline u32 sim_recv_ring_size_s(void) +{ + return 2U; +} +static inline u32 sim_recv_ring_size_f(u32 v) +{ + return (v & 0x3U) << 4U; +} +static inline u32 sim_recv_ring_size_m(void) +{ + return 0x3U << 4U; +} +static inline u32 sim_recv_ring_size_v(u32 r) +{ + return (r >> 4U) & 0x3U; +} +static inline u32 sim_recv_ring_size_init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_size_init_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_size__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_size__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_size__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_size__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_size_4kb_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_size_4kb_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_size_8kb_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_recv_ring_size_8kb_f(void) +{ + return 0x10U; +} +static inline u32 sim_recv_ring_size_12kb_v(void) +{ + return 0x00000002U; +} +static inline u32 sim_recv_ring_size_12kb_f(void) +{ + return 0x20U; +} +static inline u32 sim_recv_ring_size_16kb_v(void) +{ + return 0x00000003U; +} +static inline u32 sim_recv_ring_size_16kb_f(void) +{ + return 0x30U; +} +static inline u32 sim_recv_ring_gp_in_ring_s(void) +{ + return 1U; +} +static inline u32 sim_recv_ring_gp_in_ring_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 sim_recv_ring_gp_in_ring_m(void) +{ + return 0x1U << 11U; +} +static inline u32 sim_recv_ring_gp_in_ring_v(u32 r) +{ + return (r >> 11U) & 0x1U; +} +static inline u32 sim_recv_ring_gp_in_ring__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_gp_in_ring__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_gp_in_ring__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_gp_in_ring__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_gp_in_ring_no_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_gp_in_ring_no_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_gp_in_ring_yes_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_recv_ring_gp_in_ring_yes_f(void) +{ + return 0x800U; +} +static inline u32 sim_recv_ring_addr_lo_s(void) +{ + return 20U; +} +static inline u32 sim_recv_ring_addr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 sim_recv_ring_addr_lo_m(void) +{ + return 0xfffffU << 12U; +} +static inline u32 sim_recv_ring_addr_lo_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 sim_recv_ring_addr_lo__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_addr_lo__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_addr_lo__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_addr_lo__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_hi_r(void) +{ + return 0x00000014U; +} +static inline u32 sim_recv_ring_hi_addr_s(void) +{ + return 20U; +} +static inline u32 sim_recv_ring_hi_addr_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 sim_recv_ring_hi_addr_m(void) +{ + return 0xfffffU << 0U; +} +static inline u32 sim_recv_ring_hi_addr_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 sim_recv_ring_hi_addr__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_hi_addr__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_ring_hi_addr__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_recv_ring_hi_addr__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_recv_put_r(void) +{ + return 0x00000018U; +} +static inline u32 sim_recv_put_pointer_s(void) +{ + return 11U; +} +static inline u32 sim_recv_put_pointer_f(u32 v) +{ + return (v & 0x7ffU) << 3U; +} +static inline u32 sim_recv_put_pointer_m(void) +{ + return 0x7ffU << 3U; +} +static inline u32 sim_recv_put_pointer_v(u32 r) +{ + return (r >> 3U) & 0x7ffU; +} +static inline u32 sim_recv_get_r(void) +{ + return 0x0000001cU; +} +static inline u32 sim_recv_get_pointer_s(void) +{ + return 11U; +} +static inline u32 sim_recv_get_pointer_f(u32 v) +{ + return (v & 0x7ffU) << 3U; +} +static inline u32 sim_recv_get_pointer_m(void) +{ + return 0x7ffU << 3U; +} +static inline u32 sim_recv_get_pointer_v(u32 r) +{ + return (r >> 3U) & 0x7ffU; +} +static inline u32 sim_config_r(void) +{ + return 0x00000020U; +} +static inline u32 sim_config_mode_s(void) +{ + return 1U; +} +static inline u32 sim_config_mode_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 sim_config_mode_m(void) +{ + return 0x1U << 0U; +} +static inline u32 sim_config_mode_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 sim_config_mode_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_config_mode_disabled_f(void) +{ + return 0x0U; +} +static inline u32 sim_config_mode_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_config_mode_enabled_f(void) +{ + return 0x1U; +} +static inline u32 sim_config_channels_s(void) +{ + return 7U; +} +static inline u32 sim_config_channels_f(u32 v) +{ + return (v & 0x7fU) << 1U; +} +static inline u32 sim_config_channels_m(void) +{ + return 0x7fU << 1U; +} +static inline u32 sim_config_channels_v(u32 r) +{ + return (r >> 1U) & 0x7fU; +} +static inline u32 sim_config_channels_none_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_config_channels_none_f(void) +{ + return 0x0U; +} +static inline u32 sim_config_cached_only_s(void) +{ + return 1U; +} +static inline u32 sim_config_cached_only_f(u32 v) +{ + return (v & 0x1U) << 8U; +} +static inline u32 sim_config_cached_only_m(void) +{ + return 0x1U << 8U; +} +static inline u32 sim_config_cached_only_v(u32 r) +{ + return (r >> 8U) & 0x1U; +} +static inline u32 sim_config_cached_only_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_config_cached_only_disabled_f(void) +{ + return 0x0U; +} +static inline u32 sim_config_cached_only_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_config_cached_only_enabled_f(void) +{ + return 0x100U; +} +static inline u32 sim_config_validity_s(void) +{ + return 2U; +} +static inline u32 sim_config_validity_f(u32 v) +{ + return (v & 0x3U) << 9U; +} +static inline u32 sim_config_validity_m(void) +{ + return 0x3U << 9U; +} +static inline u32 sim_config_validity_v(u32 r) +{ + return (r >> 9U) & 0x3U; +} +static inline u32 sim_config_validity__init_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_config_validity__init_f(void) +{ + return 0x200U; +} +static inline u32 sim_config_validity_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_config_validity_valid_f(void) +{ + return 0x200U; +} +static inline u32 sim_config_simulation_s(void) +{ + return 2U; +} +static inline u32 sim_config_simulation_f(u32 v) +{ + return (v & 0x3U) << 12U; +} +static inline u32 sim_config_simulation_m(void) +{ + return 0x3U << 12U; +} +static inline u32 sim_config_simulation_v(u32 r) +{ + return (r >> 12U) & 0x3U; +} +static inline u32 sim_config_simulation_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_config_simulation_disabled_f(void) +{ + return 0x0U; +} +static inline u32 sim_config_simulation_fmodel_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_config_simulation_fmodel_f(void) +{ + return 0x1000U; +} +static inline u32 sim_config_simulation_rtlsim_v(void) +{ + return 0x00000002U; +} +static inline u32 sim_config_simulation_rtlsim_f(void) +{ + return 0x2000U; +} +static inline u32 sim_config_secondary_display_s(void) +{ + return 1U; +} +static inline u32 sim_config_secondary_display_f(u32 v) +{ + return (v & 0x1U) << 14U; +} +static inline u32 sim_config_secondary_display_m(void) +{ + return 0x1U << 14U; +} +static inline u32 sim_config_secondary_display_v(u32 r) +{ + return (r >> 14U) & 0x1U; +} +static inline u32 sim_config_secondary_display_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_config_secondary_display_disabled_f(void) +{ + return 0x0U; +} +static inline u32 sim_config_secondary_display_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_config_secondary_display_enabled_f(void) +{ + return 0x4000U; +} +static inline u32 sim_config_num_heads_s(void) +{ + return 8U; +} +static inline u32 sim_config_num_heads_f(u32 v) +{ + return (v & 0xffU) << 17U; +} +static inline u32 sim_config_num_heads_m(void) +{ + return 0xffU << 17U; +} +static inline u32 sim_config_num_heads_v(u32 r) +{ + return (r >> 17U) & 0xffU; +} +static inline u32 sim_event_ring_r(void) +{ + return 0x00000030U; +} +static inline u32 sim_event_ring_target_s(void) +{ + return 2U; +} +static inline u32 sim_event_ring_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 sim_event_ring_target_m(void) +{ + return 0x3U << 0U; +} +static inline u32 sim_event_ring_target_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 sim_event_ring_target_phys_init_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_event_ring_target_phys_init_f(void) +{ + return 0x1U; +} +static inline u32 sim_event_ring_target_phys__init_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_event_ring_target_phys__init_f(void) +{ + return 0x1U; +} +static inline u32 sim_event_ring_target_phys__prod_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_event_ring_target_phys__prod_f(void) +{ + return 0x1U; +} +static inline u32 sim_event_ring_target_phys_nvm_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_event_ring_target_phys_nvm_f(void) +{ + return 0x1U; +} +static inline u32 sim_event_ring_target_phys_pci_v(void) +{ + return 0x00000002U; +} +static inline u32 sim_event_ring_target_phys_pci_f(void) +{ + return 0x2U; +} +static inline u32 sim_event_ring_target_phys_pci_coherent_v(void) +{ + return 0x00000003U; +} +static inline u32 sim_event_ring_target_phys_pci_coherent_f(void) +{ + return 0x3U; +} +static inline u32 sim_event_ring_status_s(void) +{ + return 1U; +} +static inline u32 sim_event_ring_status_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 sim_event_ring_status_m(void) +{ + return 0x1U << 3U; +} +static inline u32 sim_event_ring_status_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 sim_event_ring_status_init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_status_init_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_status__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_status__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_status__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_status__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_status_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_status_invalid_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_event_ring_status_valid_f(void) +{ + return 0x8U; +} +static inline u32 sim_event_ring_size_s(void) +{ + return 2U; +} +static inline u32 sim_event_ring_size_f(u32 v) +{ + return (v & 0x3U) << 4U; +} +static inline u32 sim_event_ring_size_m(void) +{ + return 0x3U << 4U; +} +static inline u32 sim_event_ring_size_v(u32 r) +{ + return (r >> 4U) & 0x3U; +} +static inline u32 sim_event_ring_size_init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_size_init_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_size__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_size__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_size__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_size__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_size_4kb_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_size_4kb_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_size_8kb_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_event_ring_size_8kb_f(void) +{ + return 0x10U; +} +static inline u32 sim_event_ring_size_12kb_v(void) +{ + return 0x00000002U; +} +static inline u32 sim_event_ring_size_12kb_f(void) +{ + return 0x20U; +} +static inline u32 sim_event_ring_size_16kb_v(void) +{ + return 0x00000003U; +} +static inline u32 sim_event_ring_size_16kb_f(void) +{ + return 0x30U; +} +static inline u32 sim_event_ring_gp_in_ring_s(void) +{ + return 1U; +} +static inline u32 sim_event_ring_gp_in_ring_f(u32 v) +{ + return (v & 0x1U) << 11U; +} +static inline u32 sim_event_ring_gp_in_ring_m(void) +{ + return 0x1U << 11U; +} +static inline u32 sim_event_ring_gp_in_ring_v(u32 r) +{ + return (r >> 11U) & 0x1U; +} +static inline u32 sim_event_ring_gp_in_ring__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_gp_in_ring__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_gp_in_ring__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_gp_in_ring__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_gp_in_ring_no_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_gp_in_ring_no_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_gp_in_ring_yes_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_event_ring_gp_in_ring_yes_f(void) +{ + return 0x800U; +} +static inline u32 sim_event_ring_addr_lo_s(void) +{ + return 20U; +} +static inline u32 sim_event_ring_addr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 sim_event_ring_addr_lo_m(void) +{ + return 0xfffffU << 12U; +} +static inline u32 sim_event_ring_addr_lo_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 sim_event_ring_addr_lo__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_addr_lo__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_addr_lo__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_addr_lo__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_hi_v(void) +{ + return 0x00000034U; +} +static inline u32 sim_event_ring_hi_addr_s(void) +{ + return 20U; +} +static inline u32 sim_event_ring_hi_addr_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 sim_event_ring_hi_addr_m(void) +{ + return 0xfffffU << 0U; +} +static inline u32 sim_event_ring_hi_addr_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 sim_event_ring_hi_addr__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_hi_addr__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_ring_hi_addr__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_event_ring_hi_addr__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_event_put_r(void) +{ + return 0x00000038U; +} +static inline u32 sim_event_put_pointer_s(void) +{ + return 30U; +} +static inline u32 sim_event_put_pointer_f(u32 v) +{ + return (v & 0x3fffffffU) << 2U; +} +static inline u32 sim_event_put_pointer_m(void) +{ + return 0x3fffffffU << 2U; +} +static inline u32 sim_event_put_pointer_v(u32 r) +{ + return (r >> 2U) & 0x3fffffffU; +} +static inline u32 sim_event_get_r(void) +{ + return 0x0000003cU; +} +static inline u32 sim_event_get_pointer_s(void) +{ + return 30U; +} +static inline u32 sim_event_get_pointer_f(u32 v) +{ + return (v & 0x3fffffffU) << 2U; +} +static inline u32 sim_event_get_pointer_m(void) +{ + return 0x3fffffffU << 2U; +} +static inline u32 sim_event_get_pointer_v(u32 r) +{ + return (r >> 2U) & 0x3fffffffU; +} +static inline u32 sim_status_r(void) +{ + return 0x00000028U; +} +static inline u32 sim_status_send_put_s(void) +{ + return 1U; +} +static inline u32 sim_status_send_put_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 sim_status_send_put_m(void) +{ + return 0x1 << 0U; +} +static inline u32 sim_status_send_put_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 sim_status_send_put__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_send_put__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_send_put_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_send_put_idle_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_send_put_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_status_send_put_pending_f(void) +{ + return 0x1U; +} +static inline u32 sim_status_send_get_s(void) +{ + return 1U; +} +static inline u32 sim_status_send_get_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 sim_status_send_get_m(void) +{ + return 0x1U << 1U; +} +static inline u32 sim_status_send_get_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 sim_status_send_get__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_send_get__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_send_get_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_send_get_idle_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_send_get_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_status_send_get_pending_f(void) +{ + return 0x2U; +} +static inline u32 sim_status_send_get_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_status_send_get_clear_f(void) +{ + return 0x2U; +} +static inline u32 sim_status_recv_put_s(void) +{ + return 1U; +} +static inline u32 sim_status_recv_put_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 sim_status_recv_put_m(void) +{ + return 0x1U << 2U; +} +static inline u32 sim_status_recv_put_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 sim_status_recv_put__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_recv_put__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_recv_put_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_recv_put_idle_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_recv_put_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_status_recv_put_pending_f(void) +{ + return 0x4U; +} +static inline u32 sim_status_recv_put_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_status_recv_put_clear_f(void) +{ + return 0x4U; +} +static inline u32 sim_status_recv_get_s(void) +{ + return 1U; +} +static inline u32 sim_status_recv_get_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 sim_status_recv_get_m(void) +{ + return 0x1U << 3U; +} +static inline u32 sim_status_recv_get_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 sim_status_recv_get__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_recv_get__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_recv_get_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_recv_get_idle_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_recv_get_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_status_recv_get_pending_f(void) +{ + return 0x8U; +} +static inline u32 sim_status_event_put_s(void) +{ + return 1U; +} +static inline u32 sim_status_event_put_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 sim_status_event_put_m(void) +{ + return 0x1U << 4U; +} +static inline u32 sim_status_event_put_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 sim_status_event_put__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_event_put__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_event_put_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_event_put_idle_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_event_put_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_status_event_put_pending_f(void) +{ + return 0x10U; +} +static inline u32 sim_status_event_put_clear_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_status_event_put_clear_f(void) +{ + return 0x10U; +} +static inline u32 sim_status_event_get_s(void) +{ + return 1U; +} +static inline u32 sim_status_event_get_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 sim_status_event_get_m(void) +{ + return 0x1U << 5U; +} +static inline u32 sim_status_event_get_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 sim_status_event_get__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_event_get__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_event_get_idle_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_status_event_get_idle_f(void) +{ + return 0x0U; +} +static inline u32 sim_status_event_get_pending_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_status_event_get_pending_f(void) +{ + return 0x20U; +} +static inline u32 sim_control_r(void) +{ + return 0x0000002cU; +} +static inline u32 sim_control_send_put_s(void) +{ + return 1U; +} +static inline u32 sim_control_send_put_f(u32 v) +{ + return (v & 0x1U) << 0U; +} +static inline u32 sim_control_send_put_m(void) +{ + return 0x1U << 0U; +} +static inline u32 sim_control_send_put_v(u32 r) +{ + return (r >> 0U) & 0x1U; +} +static inline u32 sim_control_send_put__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_send_put__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_send_put_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_send_put_disabled_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_send_put_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_control_send_put_enabled_f(void) +{ + return 0x1U; +} +static inline u32 sim_control_send_get_s(void) +{ + return 1U; +} +static inline u32 sim_control_send_get_f(u32 v) +{ + return (v & 0x1U) << 1U; +} +static inline u32 sim_control_send_get_m(void) +{ + return 0x1U << 1U; +} +static inline u32 sim_control_send_get_v(u32 r) +{ + return (r >> 1U) & 0x1U; +} +static inline u32 sim_control_send_get__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_send_get__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_send_get_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_send_get_disabled_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_send_get_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_control_send_get_enabled_f(void) +{ + return 0x2U; +} +static inline u32 sim_control_recv_put_s(void) +{ + return 1U; +} +static inline u32 sim_control_recv_put_f(u32 v) +{ + return (v & 0x1U) << 2U; +} +static inline u32 sim_control_recv_put_m(void) +{ + return 0x1U << 2U; +} +static inline u32 sim_control_recv_put_v(u32 r) +{ + return (r >> 2U) & 0x1U; +} +static inline u32 sim_control_recv_put__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_recv_put__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_recv_put_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_recv_put_disabled_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_recv_put_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_control_recv_put_enabled_f(void) +{ + return 0x4U; +} +static inline u32 sim_control_recv_get_s(void) +{ + return 1U; +} +static inline u32 sim_control_recv_get_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 sim_control_recv_get_m(void) +{ + return 0x1U << 3U; +} +static inline u32 sim_control_recv_get_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 sim_control_recv_get__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_recv_get__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_recv_get_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_recv_get_disabled_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_recv_get_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_control_recv_get_enabled_f(void) +{ + return 0x8U; +} +static inline u32 sim_control_event_put_s(void) +{ + return 1U; +} +static inline u32 sim_control_event_put_f(u32 v) +{ + return (v & 0x1U) << 4U; +} +static inline u32 sim_control_event_put_m(void) +{ + return 0x1U << 4U; +} +static inline u32 sim_control_event_put_v(u32 r) +{ + return (r >> 4U) & 0x1U; +} +static inline u32 sim_control_event_put__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_event_put__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_event_put_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_event_put_disabled_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_event_put_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_control_event_put_enabled_f(void) +{ + return 0x10U; +} +static inline u32 sim_control_event_get_s(void) +{ + return 1U; +} +static inline u32 sim_control_event_get_f(u32 v) +{ + return (v & 0x1U) << 5U; +} +static inline u32 sim_control_event_get_m(void) +{ + return 0x1U << 5U; +} +static inline u32 sim_control_event_get_v(u32 r) +{ + return (r >> 5U) & 0x1U; +} +static inline u32 sim_control_event_get__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_event_get__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_event_get_disabled_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_control_event_get_disabled_f(void) +{ + return 0x0U; +} +static inline u32 sim_control_event_get_enabled_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_control_event_get_enabled_f(void) +{ + return 0x20U; +} +static inline u32 sim_dma_r(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_target_s(void) +{ + return 2U; +} +static inline u32 sim_dma_target_f(u32 v) +{ + return (v & 0x3U) << 0U; +} +static inline u32 sim_dma_target_m(void) +{ + return 0x3U << 0U; +} +static inline u32 sim_dma_target_v(u32 r) +{ + return (r >> 0U) & 0x3U; +} +static inline u32 sim_dma_target_phys_init_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_dma_target_phys_init_f(void) +{ + return 0x1U; +} +static inline u32 sim_dma_target_phys__init_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_dma_target_phys__init_f(void) +{ + return 0x1U; +} +static inline u32 sim_dma_target_phys__prod_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_dma_target_phys__prod_f(void) +{ + return 0x1U; +} +static inline u32 sim_dma_target_phys_nvm_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_dma_target_phys_nvm_f(void) +{ + return 0x1U; +} +static inline u32 sim_dma_target_phys_pci_v(void) +{ + return 0x00000002U; +} +static inline u32 sim_dma_target_phys_pci_f(void) +{ + return 0x2U; +} +static inline u32 sim_dma_target_phys_pci_coherent_v(void) +{ + return 0x00000003U; +} +static inline u32 sim_dma_target_phys_pci_coherent_f(void) +{ + return 0x3U; +} +static inline u32 sim_dma_status_s(void) +{ + return 1U; +} +static inline u32 sim_dma_status_f(u32 v) +{ + return (v & 0x1U) << 3U; +} +static inline u32 sim_dma_status_m(void) +{ + return 0x1U << 3U; +} +static inline u32 sim_dma_status_v(u32 r) +{ + return (r >> 3U) & 0x1U; +} +static inline u32 sim_dma_status_init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_status_init_f(void) +{ + return 0x0U; +} +static inline u32 sim_dma_status__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_status__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_dma_status__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_status__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_dma_status_invalid_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_status_invalid_f(void) +{ + return 0x0U; +} +static inline u32 sim_dma_status_valid_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_dma_status_valid_f(void) +{ + return 0x8U; +} +static inline u32 sim_dma_size_s(void) +{ + return 2U; +} +static inline u32 sim_dma_size_f(u32 v) +{ + return (v & 0x3U) << 4U; +} +static inline u32 sim_dma_size_m(void) +{ + return 0x3U << 4U; +} +static inline u32 sim_dma_size_v(u32 r) +{ + return (r >> 4U) & 0x3U; +} +static inline u32 sim_dma_size_init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_size_init_f(void) +{ + return 0x0U; +} +static inline u32 sim_dma_size__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_size__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_dma_size__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_size__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_dma_size_4kb_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_size_4kb_f(void) +{ + return 0x0U; +} +static inline u32 sim_dma_size_8kb_v(void) +{ + return 0x00000001U; +} +static inline u32 sim_dma_size_8kb_f(void) +{ + return 0x10U; +} +static inline u32 sim_dma_size_12kb_v(void) +{ + return 0x00000002U; +} +static inline u32 sim_dma_size_12kb_f(void) +{ + return 0x20U; +} +static inline u32 sim_dma_size_16kb_v(void) +{ + return 0x00000003U; +} +static inline u32 sim_dma_size_16kb_f(void) +{ + return 0x30U; +} +static inline u32 sim_dma_addr_lo_s(void) +{ + return 20U; +} +static inline u32 sim_dma_addr_lo_f(u32 v) +{ + return (v & 0xfffffU) << 12U; +} +static inline u32 sim_dma_addr_lo_m(void) +{ + return 0xfffffU << 12U; +} +static inline u32 sim_dma_addr_lo_v(u32 r) +{ + return (r >> 12U) & 0xfffffU; +} +static inline u32 sim_dma_addr_lo__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_addr_lo__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_dma_addr_lo__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_addr_lo__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_dma_hi_r(void) +{ + return 0x00000004U; +} +static inline u32 sim_dma_hi_addr_s(void) +{ + return 20U; +} +static inline u32 sim_dma_hi_addr_f(u32 v) +{ + return (v & 0xfffffU) << 0U; +} +static inline u32 sim_dma_hi_addr_m(void) +{ + return 0xfffffU << 0U; +} +static inline u32 sim_dma_hi_addr_v(u32 r) +{ + return (r >> 0U) & 0xfffffU; +} +static inline u32 sim_dma_hi_addr__init_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_hi_addr__init_f(void) +{ + return 0x0U; +} +static inline u32 sim_dma_hi_addr__prod_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_dma_hi_addr__prod_f(void) +{ + return 0x0U; +} +static inline u32 sim_msg_header_version_r(void) +{ + return 0x00000000U; +} +static inline u32 sim_msg_header_version_major_tot_v(void) +{ + return 0x03000000U; +} +static inline u32 sim_msg_header_version_minor_tot_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_msg_signature_r(void) +{ + return 0x00000004U; +} +static inline u32 sim_msg_signature_valid_v(void) +{ + return 0x43505256U; +} +static inline u32 sim_msg_length_r(void) +{ + return 0x00000008U; +} +static inline u32 sim_msg_function_r(void) +{ + return 0x0000000cU; +} +static inline u32 sim_msg_function_sim_escape_read_v(void) +{ + return 0x00000023U; +} +static inline u32 sim_msg_function_sim_escape_write_v(void) +{ + return 0x00000024U; +} +static inline u32 sim_msg_result_r(void) +{ + return 0x00000010U; +} +static inline u32 sim_msg_result_success_v(void) +{ + return 0x00000000U; +} +static inline u32 sim_msg_result_rpc_pending_v(void) +{ + return 0xFFFFFFFFU; +} +static inline u32 sim_msg_sequence_r(void) +{ + return 0x00000018U; +} +static inline u32 sim_msg_spare_r(void) +{ + return 0x0000001cU; +} +static inline u32 sim_msg_spare__init_v(void) +{ + return 0x00000000U; +} + +#endif /* __hw_sim_pci_h__ */ diff --git a/include/nvgpu/io.h b/include/nvgpu/io.h new file mode 100644 index 0000000..d6cc16e --- /dev/null +++ b/include/nvgpu/io.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_IO_H +#define NVGPU_IO_H + +#include + +/* Legacy defines - should be removed once everybody uses nvgpu_* */ +#define gk20a_writel nvgpu_writel +#define gk20a_readl nvgpu_readl +#define gk20a_writel_check nvgpu_writel_check +#define gk20a_bar1_writel nvgpu_bar1_writel +#define gk20a_bar1_readl nvgpu_bar1_readl +#define gk20a_io_exists nvgpu_io_exists +#define gk20a_io_valid_reg nvgpu_io_valid_reg + +struct gk20a; + +void nvgpu_writel(struct gk20a *g, u32 r, u32 v); +void nvgpu_writel_relaxed(struct gk20a *g, u32 r, u32 v); +u32 nvgpu_readl(struct gk20a *g, u32 r); +u32 __nvgpu_readl(struct gk20a *g, u32 r); +void nvgpu_writel_check(struct gk20a *g, u32 r, u32 v); +void nvgpu_writel_loop(struct gk20a *g, u32 r, u32 v); +void nvgpu_bar1_writel(struct gk20a *g, u32 b, u32 v); +u32 nvgpu_bar1_readl(struct gk20a *g, u32 b); +bool nvgpu_io_exists(struct gk20a *g); +bool nvgpu_io_valid_reg(struct gk20a *g, u32 r); + +#endif /* NVGPU_IO_H */ diff --git a/include/nvgpu/io_usermode.h b/include/nvgpu/io_usermode.h new file mode 100644 index 0000000..f56062b --- /dev/null +++ b/include/nvgpu/io_usermode.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_IO_USERMODE_H +#define NVGPU_IO_USERMODE_H + +void nvgpu_usermode_writel(struct gk20a *g, u32 r, u32 v); + +#endif /* NVGPU_IO_USERMODE_H */ diff --git a/include/nvgpu/kmem.h b/include/nvgpu/kmem.h new file mode 100644 index 0000000..61f90bf --- /dev/null +++ b/include/nvgpu/kmem.h @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_KMEM_H +#define NVGPU_KMEM_H + +#include +#include + +struct gk20a; + +/* + * When there's other implementations make sure they are included instead of + * Linux when not compiling on Linux! + */ +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +/** + * DOC: Kmem cache support + * + * In Linux there is support for the notion of a kmem_cache. It gives better + * memory usage characteristics for lots of allocations of the same size. Think + * structs that get allocated over and over. Normal kmalloc() type routines + * typically round to the next power-of-2 since that's easy. + * + * But if we know the size ahead of time the packing for the allocations can be + * much better. This is the benefit of a slab allocator. This type hides the + * underlying kmem_cache (or absense thereof). + */ +struct nvgpu_kmem_cache; + +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE +/* + * Uncomment this if you want to enable stack traces in the memory profiling. + * Since this is a fairly high overhead operation and is only necessary for + * debugging actual bugs it's left here for developers to enable. + */ +/* #define __NVGPU_SAVE_KALLOC_STACK_TRACES */ + +/* + * Defined per-OS. + */ +struct nvgpu_mem_alloc_tracker; +#endif + + +/** + * nvgpu_kmem_cache_create - create an nvgpu kernel memory cache. + * + * @g The GPU driver struct using this cache. + * @size Size of the object allocated by the cache. + * + * This cache can be used to allocate objects of size @size. Common usage would + * be for a struct that gets allocated a lot. In that case @size should be + * sizeof(struct my_struct). + * + * A given implementation of this need not do anything special. The allocation + * routines can simply be passed on to nvgpu_kzalloc() if desired so packing + * and alignment of the structs cannot be assumed. + */ +struct nvgpu_kmem_cache *nvgpu_kmem_cache_create(struct gk20a *g, size_t size); + +/** + * nvgpu_kmem_cache_destroy - destroy a cache created by + * nvgpu_kmem_cache_create(). + * + * @cache The cache to destroy. + */ +void nvgpu_kmem_cache_destroy(struct nvgpu_kmem_cache *cache); + +/** + * nvgpu_kmem_cache_alloc - Allocate an object from the cache + * + * @cache The cache to alloc from. + */ +void *nvgpu_kmem_cache_alloc(struct nvgpu_kmem_cache *cache); + +/** + * nvgpu_kmem_cache_free - Free an object back to a cache + * + * @cache The cache to return the object to. + * @ptr Pointer to the object to free. + */ +void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr); + +/** + * nvgpu_kmalloc - Allocate from the kernel's allocator. + * + * @g: Current GPU. + * @size: Size of the allocation. + * + * Allocate a chunk of system memory from the kernel. Allocations larger than 1 + * page may fail even when there may appear to be enough memory. + * + * This function may sleep so cannot be used in IRQs. + */ +#define nvgpu_kmalloc(g, size) __nvgpu_kmalloc(g, size, _NVGPU_GET_IP_) + +/** + * nvgpu_kzalloc - Allocate from the kernel's allocator. + * + * @g: Current GPU. + * @size: Size of the allocation. + * + * Identical to nvgpu_kalloc() except the memory will be zeroed before being + * returned. + */ +#define nvgpu_kzalloc(g, size) __nvgpu_kzalloc(g, size, _NVGPU_GET_IP_) + +/** + * nvgpu_kcalloc - Allocate from the kernel's allocator. + * + * @g: Current GPU. + * @n: Number of objects. + * @size: Size of each object. + * + * Identical to nvgpu_kalloc() except the size of the memory chunk returned is + * @n * @size. + */ +#define nvgpu_kcalloc(g, n, size) \ + __nvgpu_kcalloc(g, n, size, _NVGPU_GET_IP_) + +/** + * nvgpu_vmalloc - Allocate memory and return a map to it. + * + * @g: Current GPU. + * @size: Size of the allocation. + * + * Allocate some memory and return a pointer to a virtual memory mapping of + * that memory in the kernel's virtual address space. The underlying physical + * memory is not guaranteed to be contiguous (and indeed likely isn't). This + * allows for much larger allocations to be done without worrying about as much + * about physical memory fragmentation. + * + * This function may sleep. + */ +#define nvgpu_vmalloc(g, size) __nvgpu_vmalloc(g, size, _NVGPU_GET_IP_) + +/** + * nvgpu_vzalloc - Allocate memory and return a map to it. + * + * @g: Current GPU. + * @size: Size of the allocation. + * + * Identical to nvgpu_vmalloc() except this will return zero'ed memory. + */ +#define nvgpu_vzalloc(g, size) __nvgpu_vzalloc(g, size, _NVGPU_GET_IP_) + +/** + * nvgpu_kfree - Frees an alloc from nvgpu_kmalloc, nvgpu_kzalloc, + * nvgpu_kcalloc. + * + * @g: Current GPU. + * @addr: Address of object to free. + */ +#define nvgpu_kfree(g, addr) __nvgpu_kfree(g, addr) + +/** + * nvgpu_vfree - Frees an alloc from nvgpu_vmalloc, nvgpu_vzalloc. + * + * @g: Current GPU. + * @addr: Address of object to free. + */ +#define nvgpu_vfree(g, addr) __nvgpu_vfree(g, addr) + +#define kmem_dbg(g, fmt, args...) \ + nvgpu_log(g, gpu_dbg_kmem, fmt, ##args) + +/** + * nvgpu_kmem_init - Initialize the kmem tracking stuff. + * + *@g: The driver to init. + * + * Returns non-zero on failure. + */ +int nvgpu_kmem_init(struct gk20a *g); + +/** + * nvgpu_kmem_fini - Finalize the kmem tracking code + * + * @g - The GPU. + * @flags - Flags that control operation of this finalization. + * + * Cleanup resources used by nvgpu_kmem. Available flags for cleanup are: + * + * %NVGPU_KMEM_FINI_DO_NOTHING + * %NVGPU_KMEM_FINI_FORCE_CLEANUP + * %NVGPU_KMEM_FINI_DUMP_ALLOCS + * %NVGPU_KMEM_FINI_WARN + * %NVGPU_KMEM_FINI_BUG + * + * %NVGPU_KMEM_FINI_DO_NOTHING will be overridden by anything else specified. + * Put another way don't just add %NVGPU_KMEM_FINI_DO_NOTHING and expect that + * to suppress other flags from doing anything. + */ +void nvgpu_kmem_fini(struct gk20a *g, int flags); + +/* + * These will simply be ignored if CONFIG_NVGPU_TRACK_MEM_USAGE is not defined. + */ +#define NVGPU_KMEM_FINI_DO_NOTHING 0 +#define NVGPU_KMEM_FINI_FORCE_CLEANUP (1 << 0) +#define NVGPU_KMEM_FINI_DUMP_ALLOCS (1 << 1) +#define NVGPU_KMEM_FINI_WARN (1 << 2) +#define NVGPU_KMEM_FINI_BUG (1 << 3) + +/* + * Implemented by the OS interface. + */ +void *__nvgpu_big_alloc(struct gk20a *g, size_t size, bool clear); + +/** + * nvgpu_big_malloc - Pick virtual or physical alloc based on @size + * + * @g - The GPU. + * @size - Size of the allocation. + * + * On some platforms (i.e Linux) it is possible to allocate memory directly + * mapped into the kernel's address space (kmalloc) or allocate discontiguous + * pages which are then mapped into a special kernel address range. Each type + * of allocation has pros and cons. kmalloc() for instance lets you allocate + * small buffers more space efficiently but vmalloc() allows you to successfully + * allocate much larger buffers without worrying about fragmentation as much + * (but will allocate in multiples of page size). + * + * This function aims to provide the right allocation for when buffers are of + * variable size. In some cases the code doesn't know ahead of time if the + * buffer is going to be big or small so this does the check for you and + * provides the right type of memory allocation. + * + * Returns a pointer to a virtual address range that the kernel can access or + * %NULL on failure. + */ +static inline void *nvgpu_big_malloc(struct gk20a *g, size_t size) +{ + return __nvgpu_big_alloc(g, size, false); +} + +/** + * nvgpu_big_malloc - Pick virtual or physical alloc based on @size + * + * @g - The GPU. + * @size - Size of the allocation. + * + * Zeroed memory version of nvgpu_big_malloc(). + */ +static inline void *nvgpu_big_zalloc(struct gk20a *g, size_t size) +{ + return __nvgpu_big_alloc(g, size, true); +} + +/** + * nvgpu_big_free - Free and alloc from nvgpu_big_zalloc() or + * nvgpu_big_malloc(). + * @g - The GPU. + * @p - A pointer allocated by nvgpu_big_zalloc() or nvgpu_big_malloc(). + */ +void nvgpu_big_free(struct gk20a *g, void *p); + +#endif /* NVGPU_KMEM_H */ diff --git a/include/nvgpu/kref.h b/include/nvgpu/kref.h new file mode 100644 index 0000000..486040e --- /dev/null +++ b/include/nvgpu/kref.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* + * The following structure is used for reference counting of objects in nvgpu. + */ +#ifndef NVGPU_KREF_H +#define NVGPU_KREF_H + +#include + +struct nvgpu_ref { + nvgpu_atomic_t refcount; +}; + +/* + * Initialize object. + * @ref: the nvgpu_ref object to initialize + */ +static inline void nvgpu_ref_init(struct nvgpu_ref *ref) +{ + nvgpu_atomic_set(&ref->refcount, 1); +} + +/* + * Increment reference count for the object + * @ref: the nvgpu_ref object + */ +static inline void nvgpu_ref_get(struct nvgpu_ref *ref) +{ + nvgpu_atomic_inc(&ref->refcount); +} + +/* + * Decrement reference count for the object and call release() if it becomes + * zero. + * @ref: the nvgpu_ref object + * @release: pointer to the function that would be invoked to clean up the + * object when the reference count becomes zero, i.e. the last + * reference corresponding to this object is removed. + * Return 1 if object was removed, otherwise return 0. The user should not + * make any assumptions about the status of the object in the memory when + * the function returns 0 and should only use it to know that there are no + * further references to this object. + */ +static inline int nvgpu_ref_put(struct nvgpu_ref *ref, + void (*release)(struct nvgpu_ref *r)) +{ + if (nvgpu_atomic_sub_and_test(1, &ref->refcount)) { + if (release != NULL) { + release(ref); + } + return 1; + } + return 0; +} + +/* + * Increment reference count for the object unless it is zero. + * @ref: the nvgpu_ref object + * Return non-zero if the increment succeeds, Otherwise return 0. + */ +static inline int __must_check nvgpu_ref_get_unless_zero(struct nvgpu_ref *ref) +{ + return nvgpu_atomic_add_unless(&ref->refcount, 1, 0); +} + +#endif /* NVGPU_KREF_H */ diff --git a/include/nvgpu/linux/atomic.h b/include/nvgpu/linux/atomic.h new file mode 100644 index 0000000..0734672 --- /dev/null +++ b/include/nvgpu/linux/atomic.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __NVGPU_ATOMIC_LINUX_H__ +#define __NVGPU_ATOMIC_LINUX_H__ + +#ifdef __KERNEL__ +#include +#endif + +typedef struct nvgpu_atomic { + atomic_t atomic_var; +} nvgpu_atomic_t; + +typedef struct nvgpu_atomic64 { + atomic64_t atomic_var; +} nvgpu_atomic64_t; + +#define __nvgpu_atomic_init(i) { ATOMIC_INIT(i) } +#define __nvgpu_atomic64_init(i) { ATOMIC64_INIT(i) } + +static inline void __nvgpu_atomic_set(nvgpu_atomic_t *v, int i) +{ + atomic_set(&v->atomic_var, i); +} + +static inline int __nvgpu_atomic_read(nvgpu_atomic_t *v) +{ + return atomic_read(&v->atomic_var); +} + +static inline void __nvgpu_atomic_inc(nvgpu_atomic_t *v) +{ + atomic_inc(&v->atomic_var); +} + +static inline int __nvgpu_atomic_inc_return(nvgpu_atomic_t *v) +{ + return atomic_inc_return(&v->atomic_var); +} + +static inline void __nvgpu_atomic_dec(nvgpu_atomic_t *v) +{ + atomic_dec(&v->atomic_var); +} + +static inline int __nvgpu_atomic_dec_return(nvgpu_atomic_t *v) +{ + return atomic_dec_return(&v->atomic_var); +} + +static inline int __nvgpu_atomic_cmpxchg(nvgpu_atomic_t *v, int old, int new) +{ + return atomic_cmpxchg(&v->atomic_var, old, new); +} + +static inline int __nvgpu_atomic_xchg(nvgpu_atomic_t *v, int new) +{ + return atomic_xchg(&v->atomic_var, new); +} + +static inline bool __nvgpu_atomic_inc_and_test(nvgpu_atomic_t *v) +{ + return atomic_inc_and_test(&v->atomic_var); +} + +static inline bool __nvgpu_atomic_dec_and_test(nvgpu_atomic_t *v) +{ + return atomic_dec_and_test(&v->atomic_var); +} + +static inline bool __nvgpu_atomic_sub_and_test(int i, nvgpu_atomic_t *v) +{ + return atomic_sub_and_test(i, &v->atomic_var); +} + +static inline int __nvgpu_atomic_add_return(int i, nvgpu_atomic_t *v) +{ + return atomic_add_return(i, &v->atomic_var); +} + +static inline int __nvgpu_atomic_add_unless(nvgpu_atomic_t *v, int a, int u) +{ + return atomic_add_unless(&v->atomic_var, a, u); +} + +static inline void __nvgpu_atomic64_set(nvgpu_atomic64_t *v, long i) +{ + atomic64_set(&v->atomic_var, i); +} + +static inline long __nvgpu_atomic64_read(nvgpu_atomic64_t *v) +{ + return atomic64_read(&v->atomic_var); +} + +static inline void __nvgpu_atomic64_add(long x, nvgpu_atomic64_t *v) +{ + atomic64_add(x, &v->atomic_var); +} + +static inline void __nvgpu_atomic64_inc(nvgpu_atomic64_t *v) +{ + atomic64_inc(&v->atomic_var); +} + +static inline long __nvgpu_atomic64_inc_return(nvgpu_atomic64_t *v) +{ + return atomic64_inc_return(&v->atomic_var); +} + +static inline void __nvgpu_atomic64_dec(nvgpu_atomic64_t *v) +{ + atomic64_dec(&v->atomic_var); +} + +static inline void __nvgpu_atomic64_dec_return(nvgpu_atomic64_t *v) +{ + atomic64_dec_return(&v->atomic_var); +} + +static inline long __nvgpu_atomic64_cmpxchg(nvgpu_atomic64_t *v, + long old, long new) +{ + return atomic64_cmpxchg(&v->atomic_var, old, new); +} + +static inline void __nvgpu_atomic64_sub(long x, nvgpu_atomic64_t *v) +{ + atomic64_sub(x, &v->atomic_var); +} + +static inline long __nvgpu_atomic64_sub_return(long x, nvgpu_atomic64_t *v) +{ + return atomic64_sub_return(x, &v->atomic_var); +} +#endif /*__NVGPU_ATOMIC_LINUX_H__ */ diff --git a/include/nvgpu/linux/barrier.h b/include/nvgpu/linux/barrier.h new file mode 100644 index 0000000..ef867c4 --- /dev/null +++ b/include/nvgpu/linux/barrier.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NVGPU_BARRIER_LINUX_H__ +#define __NVGPU_BARRIER_LINUX_H__ + +#include + +#define __nvgpu_mb() mb() +#define __nvgpu_rmb() rmb() +#define __nvgpu_wmb() wmb() + +#define __nvgpu_smp_mb() smp_mb() +#define __nvgpu_smp_rmb() smp_rmb() +#define __nvgpu_smp_wmb() smp_wmb() + +#define __nvgpu_read_barrier_depends() read_barrier_depends() +#define __nvgpu_smp_read_barrier_depends() smp_read_barrier_depends() + +#define __NV_ACCESS_ONCE(x) ACCESS_ONCE(x) + +#define __nvgpu_speculation_barrier() speculation_barrier() + +#endif /* __NVGPU_BARRIER_LINUX_H__ */ diff --git a/include/nvgpu/linux/cond.h b/include/nvgpu/linux/cond.h new file mode 100644 index 0000000..b53ada3 --- /dev/null +++ b/include/nvgpu/linux/cond.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NVGPU_COND_LINUX_H__ +#define __NVGPU_COND_LINUX_H__ + +#include +#include + +struct nvgpu_cond { + bool initialized; + wait_queue_head_t wq; +}; + +/** + * NVGPU_COND_WAIT - Wait for a condition to be true + * + * @c - The condition variable to sleep on + * @condition - The condition that needs to be true + * @timeout_ms - Timeout in milliseconds, or 0 for infinite wait + * + * Wait for a condition to become true. Returns -ETIMEOUT if + * the wait timed out with condition false. + */ +#define NVGPU_COND_WAIT(c, condition, timeout_ms) \ +({\ + int ret = 0; \ + long _timeout_ms = timeout_ms;\ + if (_timeout_ms > 0) { \ + long _ret = wait_event_timeout((c)->wq, condition, \ + msecs_to_jiffies(_timeout_ms)); \ + if (_ret == 0) \ + ret = -ETIMEDOUT; \ + } else { \ + wait_event((c)->wq, condition); \ + } \ + ret;\ +}) + +/** + * NVGPU_COND_WAIT_INTERRUPTIBLE - Wait for a condition to be true + * + * @c - The condition variable to sleep on + * @condition - The condition that needs to be true + * @timeout_ms - Timeout in milliseconds, or 0 for infinite wait + * + * Wait for a condition to become true. Returns -ETIMEOUT if + * the wait timed out with condition false or -ERESTARTSYS on + * signal. + */ +#define NVGPU_COND_WAIT_INTERRUPTIBLE(c, condition, timeout_ms) \ +({ \ + int ret = 0; \ + long _timeout_ms = timeout_ms;\ + if (_timeout_ms > 0) { \ + long _ret = wait_event_interruptible_timeout((c)->wq, condition, \ + msecs_to_jiffies(_timeout_ms)); \ + if (_ret == 0) \ + ret = -ETIMEDOUT; \ + else if (_ret == -ERESTARTSYS) \ + ret = -ERESTARTSYS; \ + } else { \ + ret = wait_event_interruptible((c)->wq, condition); \ + } \ + ret; \ +}) + +#endif /* __NVGPU_LOCK_LINUX_H__ */ diff --git a/include/nvgpu/linux/dma.h b/include/nvgpu/linux/dma.h new file mode 100644 index 0000000..342b278 --- /dev/null +++ b/include/nvgpu/linux/dma.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NVGPU_LINUX_DMA_H__ +#define __NVGPU_LINUX_DMA_H__ + +/** + * Functions used internally for building the backing SGTs for nvgpu_mems. + */ + + +int nvgpu_get_sgtable_attrs(struct gk20a *g, struct sg_table **sgt, + void *cpuva, u64 iova, + size_t size, unsigned long flags); + +int nvgpu_get_sgtable(struct gk20a *g, struct sg_table **sgt, + void *cpuva, u64 iova, size_t size); + +int nvgpu_get_sgtable_from_pages(struct gk20a *g, struct sg_table **sgt, + struct page **pages, u64 iova, + size_t size); + +void nvgpu_free_sgtable(struct gk20a *g, struct sg_table **sgt); + +#endif diff --git a/include/nvgpu/linux/kmem.h b/include/nvgpu/linux/kmem.h new file mode 100644 index 0000000..660aac9 --- /dev/null +++ b/include/nvgpu/linux/kmem.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NVGPU_KMEM_LINUX_H__ +#define __NVGPU_KMEM_LINUX_H__ + +struct gk20a; +struct device; + +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE +void *__nvgpu_track_vmalloc(struct gk20a *g, unsigned long size, void *ip); +void *__nvgpu_track_vzalloc(struct gk20a *g, unsigned long size, void *ip); +void *__nvgpu_track_kmalloc(struct gk20a *g, size_t size, void *ip); +void *__nvgpu_track_kzalloc(struct gk20a *g, size_t size, void *ip); +void *__nvgpu_track_kcalloc(struct gk20a *g, size_t n, size_t size, void *ip); +void __nvgpu_track_vfree(struct gk20a *g, void *addr); +void __nvgpu_track_kfree(struct gk20a *g, void *addr); +#endif + +/** + * DOC: Linux pass through kmem implementation. + * + * These are the Linux implementations of the various kmem functions defined by + * nvgpu. This should not be included directly - instead include . + */ +void *__nvgpu_kmalloc(struct gk20a *g, size_t size, void *ip); +void *__nvgpu_kzalloc(struct gk20a *g, size_t size, void *ip); +void *__nvgpu_kcalloc(struct gk20a *g, size_t n, size_t size, void *ip); +void *__nvgpu_vmalloc(struct gk20a *g, unsigned long size, void *ip); +void *__nvgpu_vzalloc(struct gk20a *g, unsigned long size, void *ip); +void __nvgpu_kfree(struct gk20a *g, void *addr); +void __nvgpu_vfree(struct gk20a *g, void *addr); + +#endif diff --git a/include/nvgpu/linux/lock.h b/include/nvgpu/linux/lock.h new file mode 100644 index 0000000..fbf26e9 --- /dev/null +++ b/include/nvgpu/linux/lock.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NVGPU_LOCK_LINUX_H +#define NVGPU_LOCK_LINUX_H + +#include +#include + +struct nvgpu_mutex { + struct mutex mutex; +}; +struct nvgpu_spinlock { + spinlock_t spinlock; +}; +struct nvgpu_raw_spinlock { + raw_spinlock_t spinlock; +}; + +static inline int nvgpu_mutex_init(struct nvgpu_mutex *mutex) +{ + mutex_init(&mutex->mutex); + return 0; +}; +static inline void nvgpu_mutex_acquire(struct nvgpu_mutex *mutex) +{ + mutex_lock(&mutex->mutex); +}; +static inline void nvgpu_mutex_release(struct nvgpu_mutex *mutex) +{ + mutex_unlock(&mutex->mutex); +}; +static inline int nvgpu_mutex_tryacquire(struct nvgpu_mutex *mutex) +{ + return mutex_trylock(&mutex->mutex); +}; +static inline void nvgpu_mutex_destroy(struct nvgpu_mutex *mutex) +{ + mutex_destroy(&mutex->mutex); +}; + +static inline void nvgpu_spinlock_init(struct nvgpu_spinlock *spinlock) +{ + spin_lock_init(&spinlock->spinlock); +}; +static inline void nvgpu_spinlock_acquire(struct nvgpu_spinlock *spinlock) +{ + spin_lock(&spinlock->spinlock); +}; +static inline void nvgpu_spinlock_release(struct nvgpu_spinlock *spinlock) +{ + spin_unlock(&spinlock->spinlock); +}; + +static inline void nvgpu_raw_spinlock_init(struct nvgpu_raw_spinlock *spinlock) +{ + raw_spin_lock_init(&spinlock->spinlock); +}; +static inline void nvgpu_raw_spinlock_acquire(struct nvgpu_raw_spinlock *spinlock) +{ + raw_spin_lock(&spinlock->spinlock); +}; +static inline void nvgpu_raw_spinlock_release(struct nvgpu_raw_spinlock *spinlock) +{ + raw_spin_unlock(&spinlock->spinlock); +}; + +#endif /* NVGPU_LOCK_LINUX_H */ diff --git a/include/nvgpu/linux/nvgpu_mem.h b/include/nvgpu/linux/nvgpu_mem.h new file mode 100644 index 0000000..e5f5031 --- /dev/null +++ b/include/nvgpu/linux/nvgpu_mem.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NVGPU_LINUX_NVGPU_MEM_H__ +#define __NVGPU_LINUX_NVGPU_MEM_H__ + +struct page; +struct sg_table; +struct scatterlist; +struct nvgpu_sgt; + +struct gk20a; +struct nvgpu_mem; +struct nvgpu_gmmu_attrs; + +struct nvgpu_mem_priv { + struct page **pages; + struct sg_table *sgt; + unsigned long flags; +}; + +u64 nvgpu_mem_get_addr_sgl(struct gk20a *g, struct scatterlist *sgl); +struct nvgpu_sgt *nvgpu_mem_linux_sgt_create(struct gk20a *g, + struct sg_table *sgt); +void nvgpu_mem_linux_sgt_free(struct gk20a *g, struct nvgpu_sgt *sgt); +struct nvgpu_sgt *nvgpu_linux_sgt_create(struct gk20a *g, + struct sg_table *sgt); +/** + * __nvgpu_mem_create_from_pages - Create an nvgpu_mem from physical pages. + * + * @g - The GPU. + * @dest - nvgpu_mem to initialize. + * @pages - A list of page pointers. + * @nr_pages - The number of pages in @pages. + * + * Create a new nvgpu_mem struct from a pre-existing list of physical pages. The + * pages need not be contiguous (the underlying scatter gather list will help + * with that). However, note, this API will explicitly make it so that the GMMU + * mapping code bypasses SMMU access for the passed pages. This allows one to + * make mem_descs that describe MMIO regions or other non-DRAM things. + * + * This only works for SYSMEM (or other things like SYSMEM - basically just not + * VIDMEM). Also, this API is only available for Linux as it heavily depends on + * the notion of struct %page. + * + * The resulting nvgpu_mem should be released with the nvgpu_dma_free() or the + * nvgpu_dma_unmap_free() function depending on whether or not the resulting + * nvgpu_mem has been mapped. The underlying pages themselves must be cleaned up + * by the caller of this API. + * + * Returns 0 on success, or a relevant error otherwise. + */ +int __nvgpu_mem_create_from_pages(struct gk20a *g, struct nvgpu_mem *dest, + struct page **pages, int nr_pages); + +/** + * __nvgpu_mem_create_from_phys - Create an nvgpu_mem from physical mem. + * + * @g - The GPU. + * @dest - nvgpu_mem to initialize. + * @src_phys - start address of physical mem + * @nr_pages - The number of pages in phys. + * + * Create a new nvgpu_mem struct from a physical memory aperure. The physical + * memory aperture needs to be contiguous for requested @nr_pages. This API + * only works for SYSMEM. + * + * The resulting nvgpu_mem should be released with the nvgpu_dma_free() or the + * nvgpu_dma_unmap_free() function depending on whether or not the resulting + * nvgpu_mem has been mapped. + * + * Returns 0 on success, or a relevant error otherwise. + */ +int __nvgpu_mem_create_from_phys(struct gk20a *g, struct nvgpu_mem *dest, + u64 src_phys, int nr_pages); +#endif diff --git a/include/nvgpu/linux/nvlink.h b/include/nvgpu/linux/nvlink.h new file mode 100644 index 0000000..550a897 --- /dev/null +++ b/include/nvgpu/linux/nvlink.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_LINUX_NVLINK_H__ +#define __NVGPU_LINUX_NVLINK_H__ + +#ifdef CONFIG_TEGRA_NVLINK +#include +#include +#endif + +#endif diff --git a/include/nvgpu/linux/os_fence_android.h b/include/nvgpu/linux/os_fence_android.h new file mode 100644 index 0000000..201b530 --- /dev/null +++ b/include/nvgpu/linux/os_fence_android.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_OS_FENCE_ANDROID_H__ +#define __NVGPU_OS_FENCE_ANDROID_H__ + +struct gk20a; +struct nvgpu_os_fence; +struct sync_fence; +struct channel_gk20a; + +struct sync_fence *nvgpu_get_sync_fence(struct nvgpu_os_fence *s); + +void nvgpu_os_fence_android_drop_ref(struct nvgpu_os_fence *s); + +int nvgpu_os_fence_sema_fdget(struct nvgpu_os_fence *fence_out, + struct channel_gk20a *c, int fd); + +void nvgpu_os_fence_init(struct nvgpu_os_fence *fence_out, + struct gk20a *g, const struct nvgpu_os_fence_ops *fops, + struct sync_fence *fence); + +void nvgpu_os_fence_android_install_fd(struct nvgpu_os_fence *s, int fd); + +int nvgpu_os_fence_syncpt_fdget( + struct nvgpu_os_fence *fence_out, + struct channel_gk20a *c, int fd); + +#endif /* __NVGPU_OS_FENCE_ANDROID_H__ */ \ No newline at end of file diff --git a/include/nvgpu/linux/rwsem.h b/include/nvgpu/linux/rwsem.h new file mode 100644 index 0000000..7d073d3 --- /dev/null +++ b/include/nvgpu/linux/rwsem.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NVGPU_RWSEM_LINUX_H__ +#define __NVGPU_RWSEM_LINUX_H__ + +#include + +struct nvgpu_rwsem { + struct rw_semaphore rwsem; +}; + +#endif diff --git a/include/nvgpu/linux/sim.h b/include/nvgpu/linux/sim.h new file mode 100644 index 0000000..99c6348 --- /dev/null +++ b/include/nvgpu/linux/sim.h @@ -0,0 +1,38 @@ +/* + * + * nvgpu sim support + * + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __SIM_LINUX_H__ +#define __SIM_LINUX_H__ + +struct platform_device; + +struct sim_nvgpu_linux { + struct sim_nvgpu sim; + struct resource *reg_mem; + void __iomem *regs; + void (*remove_support_linux)(struct gk20a *g); +}; + +void sim_writel(struct sim_nvgpu *sim, u32 r, u32 v); +u32 sim_readl(struct sim_nvgpu *sim, u32 r); + +int nvgpu_init_sim_support_linux(struct gk20a *g, + struct platform_device *dev); +void nvgpu_remove_sim_support_linux(struct gk20a *g); +#endif diff --git a/include/nvgpu/linux/sim_pci.h b/include/nvgpu/linux/sim_pci.h new file mode 100644 index 0000000..b248f07 --- /dev/null +++ b/include/nvgpu/linux/sim_pci.h @@ -0,0 +1,26 @@ +/* + * + * nvgpu sim support pci + * + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __SIM_PCI_LINUX_H__ +#define __SIM_PCI_LINUX_H__ + +int nvgpu_init_sim_support_linux_pci(struct gk20a *g); +void nvgpu_remove_sim_support_linux_pci(struct gk20a *g); + +#endif diff --git a/include/nvgpu/linux/thread.h b/include/nvgpu/linux/thread.h new file mode 100644 index 0000000..1355319 --- /dev/null +++ b/include/nvgpu/linux/thread.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NVGPU_THREAD_LINUX_H__ +#define __NVGPU_THREAD_LINUX_H__ + +struct task_struct; + +struct nvgpu_thread { + struct task_struct *task; + bool running; + int (*fn)(void *); + void *data; +}; + +#endif /* __NVGPU_THREAD_LINUX_H__ */ diff --git a/include/nvgpu/linux/vm.h b/include/nvgpu/linux/vm.h new file mode 100644 index 0000000..6f3beaa --- /dev/null +++ b/include/nvgpu/linux/vm.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __COMMON_LINUX_VM_PRIV_H__ +#define __COMMON_LINUX_VM_PRIV_H__ + +#include + +#include + +/* + * Couple of places explicitly flush caches still. Any DMA buffer we allocate + * from within the GPU is writecombine and as a result does not need this but + * there seem to be exceptions. + */ +#ifdef CONFIG_ARM64 +#define outer_flush_range(a, b) +#define __cpuc_flush_dcache_area __flush_dcache_area +#endif + +struct sg_table; +struct dma_buf; +struct device; + +struct vm_gk20a; +struct vm_gk20a_mapping_batch; +struct nvgpu_vm_area; + +struct nvgpu_os_buffer { + struct dma_buf *dmabuf; + struct dma_buf_attachment *attachment; + struct device *dev; +}; + +struct nvgpu_mapped_buf_priv { + struct dma_buf *dmabuf; + struct dma_buf_attachment *attachment; + struct sg_table *sgt; +}; + +/* NVGPU_AS_MAP_BUFFER_FLAGS_DIRECT_KIND_CTRL must be set */ +int nvgpu_vm_map_linux(struct vm_gk20a *vm, + struct dma_buf *dmabuf, + u64 map_addr, + u32 flags, + u32 page_size, + s16 compr_kind, + s16 incompr_kind, + int rw_flag, + u64 buffer_offset, + u64 mapping_size, + struct vm_gk20a_mapping_batch *mapping_batch, + u64 *gpu_va); + +/* + * Notes: + * - Batch may be NULL if map op is not part of a batch. + * - NVGPU_AS_MAP_BUFFER_FLAGS_DIRECT_KIND_CTRL must be set + */ +int nvgpu_vm_map_buffer(struct vm_gk20a *vm, + int dmabuf_fd, + u64 *map_addr, + u32 flags, /* NVGPU_AS_MAP_BUFFER_FLAGS_ */ + u32 page_size, + s16 compr_kind, + s16 incompr_kind, + u64 buffer_offset, + u64 mapping_size, + struct vm_gk20a_mapping_batch *batch); + +/* find buffer corresponding to va */ +int nvgpu_vm_find_buf(struct vm_gk20a *vm, u64 gpu_va, + struct dma_buf **dmabuf, + u64 *offset); + +enum nvgpu_aperture gk20a_dmabuf_aperture(struct gk20a *g, + struct dma_buf *dmabuf); + +#endif diff --git a/include/nvgpu/list.h b/include/nvgpu/list.h new file mode 100644 index 0000000..1608035 --- /dev/null +++ b/include/nvgpu/list.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2017, 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_LIST_H +#define NVGPU_LIST_H +#include + +struct nvgpu_list_node { + struct nvgpu_list_node *prev; + struct nvgpu_list_node *next; +}; + +static inline void nvgpu_init_list_node(struct nvgpu_list_node *node) +{ + node->prev = node; + node->next = node; +} + +static inline void nvgpu_list_add(struct nvgpu_list_node *new_node, struct nvgpu_list_node *head) +{ + new_node->next = head->next; + new_node->next->prev = new_node; + new_node->prev = head; + head->next = new_node; +} + +static inline void nvgpu_list_add_tail(struct nvgpu_list_node *new_node, struct nvgpu_list_node *head) +{ + new_node->prev = head->prev; + new_node->prev->next = new_node; + new_node->next = head; + head->prev = new_node; +} + +static inline void nvgpu_list_del(struct nvgpu_list_node *node) +{ + node->prev->next = node->next; + node->next->prev = node->prev; + nvgpu_init_list_node(node); +} + +static inline bool nvgpu_list_empty(struct nvgpu_list_node *head) +{ + return head->next == head; +} + +static inline void nvgpu_list_move(struct nvgpu_list_node *node, struct nvgpu_list_node *head) +{ + nvgpu_list_del(node); + nvgpu_list_add(node, head); +} + +static inline void nvgpu_list_replace_init(struct nvgpu_list_node *old_node, struct nvgpu_list_node *new_node) +{ + new_node->next = old_node->next; + new_node->next->prev = new_node; + new_node->prev = old_node->prev; + new_node->prev->next = new_node; + nvgpu_init_list_node(old_node); +} + +#define nvgpu_list_entry(ptr, type, member) \ + type ## _from_ ## member(ptr) + +#define nvgpu_list_next_entry(pos, type, member) \ + nvgpu_list_entry((pos)->member.next, type, member) + +#define nvgpu_list_first_entry(ptr, type, member) \ + nvgpu_list_entry((ptr)->next, type, member) + +#define nvgpu_list_last_entry(ptr, type, member) \ + nvgpu_list_entry((ptr)->prev, type, member) + +#define nvgpu_list_for_each_entry(pos, head, type, member) \ + for (pos = nvgpu_list_first_entry(head, type, member); \ + &pos->member != (head); \ + pos = nvgpu_list_next_entry(pos, type, member)) + +#define nvgpu_list_for_each_entry_safe(pos, n, head, type, member) \ + for (pos = nvgpu_list_first_entry(head, type, member), \ + n = nvgpu_list_next_entry(pos, type, member); \ + &pos->member != (head); \ + pos = n, n = nvgpu_list_next_entry(n, type, member)) + +#endif /* NVGPU_LIST_H */ diff --git a/include/nvgpu/lock.h b/include/nvgpu/lock.h new file mode 100644 index 0000000..7e4b2ac --- /dev/null +++ b/include/nvgpu/lock.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_LOCK_H +#define NVGPU_LOCK_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +/* + * struct nvgpu_mutex + * + * Should be implemented per-OS in a separate library + * But implementation should adhere to mutex implementation + * as specified in Linux Documentation + */ +struct nvgpu_mutex; + +/* + * struct nvgpu_spinlock + * + * Should be implemented per-OS in a separate library + * But implementation should adhere to spinlock implementation + * as specified in Linux Documentation + */ +struct nvgpu_spinlock; + +/* + * struct nvgpu_raw_spinlock + * + * Should be implemented per-OS in a separate library + * But implementation should adhere to raw_spinlock implementation + * as specified in Linux Documentation + */ +struct nvgpu_raw_spinlock; + +int nvgpu_mutex_init(struct nvgpu_mutex *mutex); +void nvgpu_mutex_acquire(struct nvgpu_mutex *mutex); +void nvgpu_mutex_release(struct nvgpu_mutex *mutex); +int nvgpu_mutex_tryacquire(struct nvgpu_mutex *mutex); +void nvgpu_mutex_destroy(struct nvgpu_mutex *mutex); + +void nvgpu_spinlock_init(struct nvgpu_spinlock *spinlock); +void nvgpu_spinlock_acquire(struct nvgpu_spinlock *spinlock); +void nvgpu_spinlock_release(struct nvgpu_spinlock *spinlock); + +void nvgpu_raw_spinlock_init(struct nvgpu_raw_spinlock *spinlock); +void nvgpu_raw_spinlock_acquire(struct nvgpu_raw_spinlock *spinlock); +void nvgpu_raw_spinlock_release(struct nvgpu_raw_spinlock *spinlock); + +#endif /* NVGPU_LOCK_H */ diff --git a/include/nvgpu/log.h b/include/nvgpu/log.h new file mode 100644 index 0000000..70a1676 --- /dev/null +++ b/include/nvgpu/log.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_LOG_H +#define NVGPU_LOG_H + +#include +#include + +struct gk20a; + +enum nvgpu_log_type { + NVGPU_ERROR, + NVGPU_WARNING, + NVGPU_DEBUG, + NVGPU_INFO, +}; + +/* + * Each OS must implement these functions. They handle the OS specific nuances + * of printing data to a UART, log, whatever. + */ +__attribute__((format (printf, 5, 6))) +void __nvgpu_log_msg(struct gk20a *g, const char *func_name, int line, + enum nvgpu_log_type type, const char *fmt, ...); + +__attribute__((format (printf, 5, 6))) +void __nvgpu_log_dbg(struct gk20a *g, u64 log_mask, + const char *func_name, int line, + const char *fmt, ...); + +/* + * Use this define to set a default mask. + */ +#define NVGPU_DEFAULT_DBG_MASK (0) + +#define gpu_dbg_info BIT(0) /* Lightly verbose info. */ +#define gpu_dbg_fn BIT(1) /* Function name tracing. */ +#define gpu_dbg_reg BIT(2) /* Register accesses; very verbose. */ +#define gpu_dbg_pte BIT(3) /* GMMU PTEs. */ +#define gpu_dbg_intr BIT(4) /* Interrupts. */ +#define gpu_dbg_pmu BIT(5) /* gk20a pmu. */ +#define gpu_dbg_clk BIT(6) /* gk20a clk. */ +#define gpu_dbg_map BIT(7) /* Memory mappings. */ +#define gpu_dbg_map_v BIT(8) /* Verbose mem mappings. */ +#define gpu_dbg_gpu_dbg BIT(9) /* GPU debugger/profiler. */ +#define gpu_dbg_cde BIT(10) /* cde info messages. */ +#define gpu_dbg_cde_ctx BIT(11) /* cde context usage messages. */ +#define gpu_dbg_ctxsw BIT(12) /* ctxsw tracing. */ +#define gpu_dbg_sched BIT(13) /* Sched control tracing. */ +#define gpu_dbg_sema BIT(14) /* Semaphore debugging. */ +#define gpu_dbg_sema_v BIT(15) /* Verbose semaphore debugging. */ +#define gpu_dbg_pmu_pstate BIT(16) /* p state controlled by pmu. */ +#define gpu_dbg_xv BIT(17) /* XVE debugging. */ +#define gpu_dbg_shutdown BIT(18) /* GPU shutdown tracing. */ +#define gpu_dbg_kmem BIT(19) /* Kmem tracking debugging. */ +#define gpu_dbg_pd_cache BIT(20) /* PD cache traces. */ +#define gpu_dbg_alloc BIT(21) /* Allocator debugging. */ +#define gpu_dbg_dma BIT(22) /* DMA allocation prints. */ +#define gpu_dbg_sgl BIT(23) /* SGL related traces. */ +#define gpu_dbg_vidmem BIT(24) /* VIDMEM tracing. */ +#define gpu_dbg_nvlink BIT(25) /* nvlink Operation tracing. */ +#define gpu_dbg_clk_arb BIT(26) /* Clk arbiter debugging. */ +#define gpu_dbg_mem BIT(31) /* memory accesses; very verbose. */ + +/** + * nvgpu_log_mask_enabled - Check if logging is enabled + * + * @g - The GPU. + * @log_mask - The mask the check against. + * + * Check if, given the passed mask, logging would actually happen. This is + * useful for avoiding calling the logging function many times when we know that + * said prints would not happen. For example for-loops of log statements in + * critical paths. + */ +int nvgpu_log_mask_enabled(struct gk20a *g, u64 log_mask); + +/** + * nvgpu_log - Print a debug message + * + * @g - The GPU. + * @log_mask - A mask defining when the print should happen. See enum + * %nvgpu_log_categories. + * @fmt - A format string (printf style). + * @arg... - Arguments for the format string. + * + * Print a message if the log_mask matches the enabled debugging. + */ +#define nvgpu_log(g, log_mask, fmt, arg...) \ + __nvgpu_log_dbg(g, (u32)log_mask, __func__, __LINE__, fmt, ##arg) + +/** + * nvgpu_err - Print an error + * + * @g - The GPU. + * @fmt - A format string (printf style). + * @arg... - Arguments for the format string. + * + * Uncondtionally print an error message. + */ +#define nvgpu_err(g, fmt, arg...) \ + __nvgpu_log_msg(g, __func__, __LINE__, NVGPU_ERROR, fmt, ##arg) + +/** + * nvgpu_err - Print a warning + * + * @g - The GPU. + * @fmt - A format string (printf style). + * @arg... - Arguments for the format string. + * + * Uncondtionally print a warming message. + */ +#define nvgpu_warn(g, fmt, arg...) \ + __nvgpu_log_msg(g, __func__, __LINE__, NVGPU_WARNING, fmt, ##arg) + +/** + * nvgpu_info - Print an info message + * + * @g - The GPU. + * @fmt - A format string (printf style). + * @arg... - Arguments for the format string. + * + * Unconditionally print an information message. + */ +#define nvgpu_info(g, fmt, arg...) \ + __nvgpu_log_msg(g, __func__, __LINE__, NVGPU_INFO, fmt, ##arg) + +/* + * Some convenience macros. + */ +#define nvgpu_log_fn(g, fmt, arg...) nvgpu_log(g, gpu_dbg_fn, fmt, ##arg) +#define nvgpu_log_info(g, fmt, arg...) nvgpu_log(g, gpu_dbg_info, fmt, ##arg) + +/****************************************************************************** + * The old legacy debugging API minus some parts that are unnecessary. * + * Please, please, please do not use this!!! This is still around to aid * + * transitioning to the new API. * + * * + * This changes up the print formats to be closer to the new APIs formats. * + * Also it removes the dev_warn() and dev_err() usage. Those arguments are * + * ignored now. * + ******************************************************************************/ + +/* + * This exist for backwards compatibility with the old debug/logging API. If you + * want ftrace support use the new API! + */ +extern u64 nvgpu_dbg_mask; + +#define gk20a_dbg(log_mask, fmt, arg...) \ + do { \ + if (((log_mask) & nvgpu_dbg_mask) != 0) \ + __nvgpu_log_msg(NULL, __func__, __LINE__, \ + NVGPU_DEBUG, fmt "\n", ##arg); \ + } while (0) + +/* + * Some convenience macros. + */ +#define gk20a_dbg_fn(fmt, arg...) gk20a_dbg(gpu_dbg_fn, fmt, ##arg) +#define gk20a_dbg_info(fmt, arg...) gk20a_dbg(gpu_dbg_info, fmt, ##arg) + +#endif /* NVGPU_LOG_H */ diff --git a/include/nvgpu/log2.h b/include/nvgpu/log2.h new file mode 100644 index 0000000..98db1ec --- /dev/null +++ b/include/nvgpu/log2.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_LOG2_H +#define NVGPU_LOG2_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#endif + +#endif /* NVGPU_LOG2_H */ diff --git a/include/nvgpu/ltc.h b/include/nvgpu/ltc.h new file mode 100644 index 0000000..a674a29 --- /dev/null +++ b/include/nvgpu/ltc.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_LTC_H +#define NVGPU_LTC_H + +#include + +struct gk20a; + +int nvgpu_init_ltc_support(struct gk20a *g); +void nvgpu_ltc_sync_enabled(struct gk20a *g); +int nvgpu_ltc_alloc_cbc(struct gk20a *g, size_t compbit_backing_size, + bool vidmem_alloc); + +#endif /* NVGPU_LTC_H */ diff --git a/include/nvgpu/mc.h b/include/nvgpu/mc.h new file mode 100644 index 0000000..3c012f9 --- /dev/null +++ b/include/nvgpu/mc.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_MC_H +#define NVGPU_MC_H + +#include + +struct gk20a; + +#define NVGPU_MC_INTR_STALLING 0U +#define NVGPU_MC_INTR_NONSTALLING 1U + +u32 nvgpu_mc_boot_0(struct gk20a *g, u32 *arch, u32 *impl, u32 *rev); + +#endif diff --git a/include/nvgpu/mm.h b/include/nvgpu/mm.h new file mode 100644 index 0000000..01063bc --- /dev/null +++ b/include/nvgpu/mm.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_MM_H +#define NVGPU_MM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct gk20a; +struct vm_gk20a; +struct nvgpu_mem; +struct nvgpu_pd_cache; + +#define NVGPU_MM_MMU_FAULT_TYPE_OTHER_AND_NONREPLAY 0 +#define NVGPU_MM_MMU_FAULT_TYPE_REPLAY 1 + +#define FAULT_TYPE_NUM 2 /* replay and nonreplay faults */ + +struct mmu_fault_info { + u64 inst_ptr; + u32 inst_aperture; + u64 fault_addr; + u32 fault_addr_aperture; + u32 timestamp_lo; + u32 timestamp_hi; + u32 mmu_engine_id; + u32 gpc_id; + u32 client_type; + u32 client_id; + u32 fault_type; + u32 access_type; + u32 protected_mode; + u32 replayable_fault; + u32 replay_fault_en; + u32 valid; + u32 faulted_pbdma; + u32 faulted_engine; + u32 faulted_subid; + u32 chid; + struct channel_gk20a *refch; + const char *client_type_desc; + const char *fault_type_desc; + const char *client_id_desc; +}; + +enum nvgpu_flush_op { + NVGPU_FLUSH_DEFAULT, + NVGPU_FLUSH_FB, + NVGPU_FLUSH_L2_INV, + NVGPU_FLUSH_L2_FLUSH, + NVGPU_FLUSH_CBC_CLEAN, +}; + +struct mm_gk20a { + struct gk20a *g; + + /* GPU VA default sizes address spaces for channels */ + struct { + u64 user_size; /* userspace-visible GPU VA region */ + u64 kernel_size; /* kernel-only GPU VA region */ + } channel; + + struct { + u32 aperture_size; + struct vm_gk20a *vm; + struct nvgpu_mem inst_block; + } bar1; + + struct { + u32 aperture_size; + struct vm_gk20a *vm; + struct nvgpu_mem inst_block; + } bar2; + + struct { + u32 aperture_size; + struct vm_gk20a *vm; + struct nvgpu_mem inst_block; + } pmu; + + struct { + /* using pmu vm currently */ + struct nvgpu_mem inst_block; + } hwpm; + + struct { + struct vm_gk20a *vm; + struct nvgpu_mem inst_block; + } perfbuf; + + struct { + struct vm_gk20a *vm; + } cde; + + struct { + struct vm_gk20a *vm; + } ce; + + struct nvgpu_pd_cache *pd_cache; + + struct nvgpu_mutex l2_op_lock; + struct nvgpu_mutex tlb_lock; + struct nvgpu_mutex priv_lock; + + struct nvgpu_mem bar2_desc; + + struct nvgpu_mem hw_fault_buf[FAULT_TYPE_NUM]; + struct mmu_fault_info fault_info[FAULT_TYPE_NUM]; + struct nvgpu_mutex hub_isr_mutex; + + /* + * Separate function to cleanup the CE since it requires a channel to + * be closed which must happen before fifo cleanup. + */ + void (*remove_ce_support)(struct mm_gk20a *mm); + void (*remove_support)(struct mm_gk20a *mm); + bool sw_ready; + int physical_bits; + bool use_full_comp_tag_line; + bool ltc_enabled_current; + bool ltc_enabled_target; + bool disable_bigpage; + + struct nvgpu_mem sysmem_flush; + + u32 pramin_window; + struct nvgpu_spinlock pramin_window_lock; + + struct { + size_t size; + u64 base; + size_t bootstrap_size; + u64 bootstrap_base; + + struct nvgpu_allocator allocator; + struct nvgpu_allocator bootstrap_allocator; + + u32 ce_ctx_id; + volatile bool cleared; + struct nvgpu_mutex first_clear_mutex; + + struct nvgpu_list_node clear_list_head; + struct nvgpu_mutex clear_list_mutex; + + struct nvgpu_cond clearing_thread_cond; + struct nvgpu_thread clearing_thread; + struct nvgpu_mutex clearing_thread_lock; + nvgpu_atomic_t pause_count; + + nvgpu_atomic64_t bytes_pending; + } vidmem; + + struct nvgpu_mem mmu_wr_mem; + struct nvgpu_mem mmu_rd_mem; +}; + +#define gk20a_from_mm(mm) ((mm)->g) +#define gk20a_from_vm(vm) ((vm)->mm->g) + +static inline int bar1_aperture_size_mb_gk20a(void) +{ + return 16; /* 16MB is more than enough atm. */ +} + +/* The maximum GPU VA range supported */ +#define NV_GMMU_VA_RANGE 38 + +/* The default userspace-visible GPU VA size */ +#define NV_MM_DEFAULT_USER_SIZE (1ULL << 37) + +/* The default kernel-reserved GPU VA size */ +#define NV_MM_DEFAULT_KERNEL_SIZE (1ULL << 32) + +/* + * When not using unified address spaces, the bottom 56GB of the space are used + * for small pages, and the remaining high memory is used for large pages. + */ +static inline u64 nvgpu_gmmu_va_small_page_limit(void) +{ + return ((u64)SZ_1G * 56U); +} + +u32 nvgpu_vm_get_pte_size(struct vm_gk20a *vm, u64 base, u64 size); + +void nvgpu_init_mm_ce_context(struct gk20a *g); +int nvgpu_init_mm_support(struct gk20a *g); +int nvgpu_init_mm_setup_hw(struct gk20a *g); + +u64 nvgpu_inst_block_addr(struct gk20a *g, struct nvgpu_mem *mem); +void nvgpu_free_inst_block(struct gk20a *g, struct nvgpu_mem *inst_block); + +int nvgpu_mm_suspend(struct gk20a *g); +u32 nvgpu_mm_get_default_big_page_size(struct gk20a *g); +u32 nvgpu_mm_get_available_big_page_sizes(struct gk20a *g); + +#endif /* NVGPU_MM_H */ diff --git a/include/nvgpu/nvgpu_common.h b/include/nvgpu/nvgpu_common.h new file mode 100644 index 0000000..3466051 --- /dev/null +++ b/include/nvgpu/nvgpu_common.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016-2017, 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_COMMON_H +#define NVGPU_COMMON_H + +struct gk20a; +struct class; + +int nvgpu_probe(struct gk20a *g, + const char *debugfs_symlink, + const char *interface_name, + struct class *class); + +void nvgpu_kernel_restart(void *cmd); + +#endif diff --git a/include/nvgpu/nvgpu_mem.h b/include/nvgpu/nvgpu_mem.h new file mode 100644 index 0000000..4e84f2a --- /dev/null +++ b/include/nvgpu/nvgpu_mem.h @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2017-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_MEM_H +#define NVGPU_MEM_H + +#include +#include +#include + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +struct page; +struct sg_table; +struct nvgpu_sgt; + +struct gk20a; +struct nvgpu_allocator; +struct nvgpu_gmmu_attrs; +struct nvgpu_page_alloc; + +#define NVGPU_MEM_DMA_ERROR (~0ULL) + +/* + * Real location of a buffer - nvgpu_aperture_mask() will deduce what will be + * told to the gpu about the aperture, but this flag designates where the + * memory actually was allocated from. + */ +enum nvgpu_aperture { + APERTURE_INVALID = 0, /* unallocated or N/A */ + APERTURE_SYSMEM, + + /* Don't use directly. Use APERTURE_SYSMEM, this is used internally. */ + APERTURE_SYSMEM_COH, + + APERTURE_VIDMEM +}; + +/* + * Forward declared opaque placeholder type that does not really exist, but + * helps the compiler help us about getting types right. In reality, + * implementors of nvgpu_sgt_ops will have some concrete type in place of this. + */ +struct nvgpu_sgl; + +struct nvgpu_sgt_ops { + struct nvgpu_sgl *(*sgl_next)(struct nvgpu_sgl *sgl); + u64 (*sgl_phys)(struct gk20a *g, struct nvgpu_sgl *sgl); + u64 (*sgl_dma)(struct nvgpu_sgl *sgl); + u64 (*sgl_length)(struct nvgpu_sgl *sgl); + u64 (*sgl_gpu_addr)(struct gk20a *g, struct nvgpu_sgl *sgl, + struct nvgpu_gmmu_attrs *attrs); + /* + * If left NULL then iommuable is assumed to be false. + */ + bool (*sgt_iommuable)(struct gk20a *g, struct nvgpu_sgt *sgt); + + /* + * Note: this operates on the whole SGT not a specific SGL entry. + */ + void (*sgt_free)(struct gk20a *g, struct nvgpu_sgt *sgt); +}; + +/* + * Scatter gather table: this is a list of scatter list entries and the ops for + * interacting with those entries. + */ +struct nvgpu_sgt { + /* + * Ops for interacting with the underlying scatter gather list entries. + */ + const struct nvgpu_sgt_ops *ops; + + /* + * The first node in the scatter gather list. + */ + struct nvgpu_sgl *sgl; +}; + +/* + * This struct holds the necessary information for describing a struct + * nvgpu_mem's scatter gather list. + * + * This is one underlying implementation for nvgpu_sgl. Not all nvgpu_sgt's use + * this particular implementation. Nor is a given OS required to use this at + * all. + */ +struct nvgpu_mem_sgl { + /* + * Internally this is implemented as a singly linked list. + */ + struct nvgpu_mem_sgl *next; + + /* + * There is both a phys address and a DMA address since some systems, + * for example ones with an IOMMU, may see these as different addresses. + */ + u64 phys; + u64 dma; + u64 length; +}; + +/* + * Iterate over the SGL entries in an SGT. + */ +#define nvgpu_sgt_for_each_sgl(__sgl__, __sgt__) \ + for ((__sgl__) = (__sgt__)->sgl; \ + (__sgl__) != NULL; \ + (__sgl__) = nvgpu_sgt_get_next(__sgt__, __sgl__)) + +struct nvgpu_mem { + /* + * Populated for all nvgpu_mem structs - vidmem or system. + */ + enum nvgpu_aperture aperture; + size_t size; + size_t aligned_size; + u64 gpu_va; + bool skip_wmb; + bool free_gpu_va; + + /* + * Set when a nvgpu_mem struct is not a "real" nvgpu_mem struct. Instead + * the struct is just a copy of another nvgpu_mem struct. + */ +#define NVGPU_MEM_FLAG_SHADOW_COPY (1 << 0) + + /* + * Specify that the GVA mapping is a fixed mapping - that is the caller + * chose the GPU VA, not the GMMU mapping function. Only relevant for + * VIDMEM. + */ +#define NVGPU_MEM_FLAG_FIXED (1 << 1) + + /* + * Set for user generated VIDMEM allocations. This triggers a special + * cleanup path that clears the vidmem on free. Given that the VIDMEM is + * zeroed on boot this means that all user vidmem allocations are + * therefor zeroed (to prevent leaking information in VIDMEM buffers). + */ +#define NVGPU_MEM_FLAG_USER_MEM (1 << 2) + + /* + * Internal flag that specifies this struct has not been made with DMA + * memory and as a result should not try to use the DMA routines for + * freeing the backing memory. + * + * However, this will not stop the DMA API from freeing other parts of + * nvgpu_mem in a system specific way. + */ +#define __NVGPU_MEM_FLAG_NO_DMA (1 << 3) + /* + * Some nvgpu_mem objects act as facades to memory buffers owned by + * someone else. This internal flag specifies that the sgt field is + * "borrowed", and it must not be freed by us. + * + * Of course the caller will have to make sure that the sgt owner + * outlives the nvgpu_mem. + */ +#define NVGPU_MEM_FLAG_FOREIGN_SGT (1 << 4) + unsigned long mem_flags; + + /* + * Only populated for a sysmem allocation. + */ + void *cpu_va; + + /* + * Fields only populated for vidmem allocations. + */ + struct nvgpu_page_alloc *vidmem_alloc; + struct nvgpu_allocator *allocator; + struct nvgpu_list_node clear_list_entry; + + /* + * This is defined by the system specific header. It can be empty if + * there's no system specific stuff for a given system. + */ + struct nvgpu_mem_priv priv; +}; + +static inline struct nvgpu_mem * +nvgpu_mem_from_clear_list_entry(struct nvgpu_list_node *node) +{ + return (struct nvgpu_mem *) + ((uintptr_t)node - offsetof(struct nvgpu_mem, + clear_list_entry)); +}; + +static inline const char *nvgpu_aperture_str(struct gk20a *g, + enum nvgpu_aperture aperture) +{ + switch (aperture) { + case APERTURE_INVALID: + return "INVAL"; + case APERTURE_SYSMEM: + return "SYSMEM"; + case APERTURE_SYSMEM_COH: + return "SYSCOH"; + case APERTURE_VIDMEM: + return "VIDMEM"; + }; + return "UNKNOWN"; +} + +bool nvgpu_aperture_is_sysmem(enum nvgpu_aperture ap); +bool nvgpu_mem_is_sysmem(struct nvgpu_mem *mem); + +/* + * Returns true if the passed nvgpu_mem has been allocated (i.e it's valid for + * subsequent use). + */ +static inline bool nvgpu_mem_is_valid(struct nvgpu_mem *mem) +{ + /* + * Internally the DMA APIs must set/unset the aperture flag when + * allocating/freeing the buffer. So check that to see if the *mem + * has been allocated or not. + * + * This relies on mem_descs being zeroed before being initialized since + * APERTURE_INVALID is equal to 0. + */ + return mem->aperture != APERTURE_INVALID; + +} + +/** + * nvgpu_mem_sgt_create_from_mem - Create a scatter list from an nvgpu_mem. + * + * @g - The GPU. + * @mem - The source memory allocation to use. + * + * Create a scatter gather table from the passed @mem struct. This list lets the + * calling code iterate across each chunk of a DMA allocation for when that DMA + * allocation is not completely contiguous. + */ +struct nvgpu_sgt *nvgpu_sgt_create_from_mem(struct gk20a *g, + struct nvgpu_mem *mem); + +struct nvgpu_sgl *nvgpu_sgt_get_next(struct nvgpu_sgt *sgt, + struct nvgpu_sgl *sgl); +u64 nvgpu_sgt_get_phys(struct gk20a *g, struct nvgpu_sgt *sgt, + struct nvgpu_sgl *sgl); +u64 nvgpu_sgt_get_dma(struct nvgpu_sgt *sgt, struct nvgpu_sgl *sgl); +u64 nvgpu_sgt_get_length(struct nvgpu_sgt *sgt, struct nvgpu_sgl *sgl); +u64 nvgpu_sgt_get_gpu_addr(struct gk20a *g, struct nvgpu_sgt *sgt, + struct nvgpu_sgl *sgl, + struct nvgpu_gmmu_attrs *attrs); +void nvgpu_sgt_free(struct gk20a *g, struct nvgpu_sgt *sgt); + +bool nvgpu_sgt_iommuable(struct gk20a *g, struct nvgpu_sgt *sgt); +u64 nvgpu_sgt_alignment(struct gk20a *g, struct nvgpu_sgt *sgt); + +/** + * nvgpu_mem_create_from_mem - Create a new nvgpu_mem struct from an old one. + * + * @g - The GPU. + * @dest - Destination nvgpu_mem to hold resulting memory description. + * @src - Source memory. Must be valid. + * @start_page - Starting page to use. + * @nr_pages - Number of pages to place in the new nvgpu_mem. + * + * Create a new nvgpu_mem struct describing a subsection of the @src nvgpu_mem. + * This will create an nvpgu_mem object starting at @start_page and is @nr_pages + * long. This currently only works on SYSMEM nvgpu_mems. If this is called on a + * VIDMEM nvgpu_mem then this will return an error. + * + * There is a _major_ caveat to this API: if the source buffer is freed before + * the copy is freed then the copy will become invalid. This is a result from + * how typical DMA APIs work: we can't call free on the buffer multiple times. + * Nor can we call free on parts of a buffer. Thus the only way to ensure that + * the entire buffer is actually freed is to call free once on the source + * buffer. Since these nvgpu_mem structs are not ref-counted in anyway it is up + * to the caller of this API to _ensure_ that the resulting nvgpu_mem buffer + * from this API is freed before the source buffer. Otherwise there can and will + * be memory corruption. + * + * The resulting nvgpu_mem should be released with the nvgpu_dma_free() or the + * nvgpu_dma_unmap_free() function depending on whether or not the resulting + * nvgpu_mem has been mapped. + * + * This will return 0 on success. An error is returned if the resulting + * nvgpu_mem would not make sense or if a new scatter gather table cannot be + * created. + */ +int nvgpu_mem_create_from_mem(struct gk20a *g, + struct nvgpu_mem *dest, struct nvgpu_mem *src, + u64 start_page, int nr_pages); + +/* + * Really free a vidmem buffer. There's a fair amount of work involved in + * freeing vidmem buffers in the DMA API. This handles none of that - it only + * frees the underlying vidmem specific structures used in vidmem buffers. + * + * This is implemented in the OS specific code. If it's not necessary it can + * be a noop. But the symbol must at least be present. + */ +void __nvgpu_mem_free_vidmem_alloc(struct gk20a *g, struct nvgpu_mem *vidmem); + +/* + * Buffer accessors. Sysmem buffers always have a CPU mapping and vidmem + * buffers are accessed via PRAMIN. + */ + +/* word-indexed offset */ +u32 nvgpu_mem_rd32(struct gk20a *g, struct nvgpu_mem *mem, u32 w); +/* byte offset (32b-aligned) */ +u32 nvgpu_mem_rd(struct gk20a *g, struct nvgpu_mem *mem, u32 offset); +/* memcpy to cpu, offset and size in bytes (32b-aligned) */ +void nvgpu_mem_rd_n(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, + void *dest, u32 size); + +/* word-indexed offset */ +void nvgpu_mem_wr32(struct gk20a *g, struct nvgpu_mem *mem, u32 w, u32 data); +/* byte offset (32b-aligned) */ +void nvgpu_mem_wr(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, u32 data); +/* memcpy from cpu, offset and size in bytes (32b-aligned) */ +void nvgpu_mem_wr_n(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, + void *src, u32 size); +/* size and offset in bytes (32b-aligned), filled with the constant byte c */ +void nvgpu_memset(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, + u32 c, u32 size); + +u64 nvgpu_mem_get_addr(struct gk20a *g, struct nvgpu_mem *mem); +u64 nvgpu_mem_get_phys_addr(struct gk20a *g, struct nvgpu_mem *mem); + +u32 nvgpu_aperture_mask_raw(struct gk20a *g, enum nvgpu_aperture aperture, + u32 sysmem_mask, u32 sysmem_coh_mask, u32 vidmem_mask); +u32 nvgpu_aperture_mask(struct gk20a *g, struct nvgpu_mem *mem, + u32 sysmem_mask, u32 sysmem_coh_mask, u32 vidmem_mask); + +u64 nvgpu_mem_iommu_translate(struct gk20a *g, u64 phys); + +#endif /* NVGPU_MEM_H */ diff --git a/include/nvgpu/nvhost.h b/include/nvgpu/nvhost.h new file mode 100644 index 0000000..74dc48b --- /dev/null +++ b/include/nvgpu/nvhost.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_NVHOST_H +#define NVGPU_NVHOST_H + +#ifdef CONFIG_TEGRA_GK20A_NVHOST + +#include + +struct nvgpu_nvhost_dev; +struct gk20a; +struct sync_pt; +struct sync_fence; +struct timespec; + +int nvgpu_get_nvhost_dev(struct gk20a *g); +void nvgpu_free_nvhost_dev(struct gk20a *g); + +int nvgpu_nvhost_module_busy_ext(struct nvgpu_nvhost_dev *nvhost_dev); +void nvgpu_nvhost_module_idle_ext(struct nvgpu_nvhost_dev *nvhost_dev); + +void nvgpu_nvhost_debug_dump_device(struct nvgpu_nvhost_dev *nvhost_dev); + +int nvgpu_nvhost_syncpt_is_expired_ext(struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 thresh); +int nvgpu_nvhost_syncpt_wait_timeout_ext(struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 thresh, u32 timeout, u32 *value, struct timespec *ts); + +u32 nvgpu_nvhost_syncpt_incr_max_ext(struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 incrs); +void nvgpu_nvhost_syncpt_set_min_eq_max_ext(struct nvgpu_nvhost_dev *nvhost_dev, + u32 id); +int nvgpu_nvhost_syncpt_read_ext_check(struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 *val); +u32 nvgpu_nvhost_syncpt_read_maxval(struct nvgpu_nvhost_dev *nvhost_dev, + u32 id); +void nvgpu_nvhost_syncpt_set_safe_state( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id); + +int nvgpu_nvhost_intr_register_notifier(struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 thresh, void (*callback)(void *, int), void *private_data); + +const char *nvgpu_nvhost_syncpt_get_name(struct nvgpu_nvhost_dev *nvhost_dev, + int id); +bool nvgpu_nvhost_syncpt_is_valid_pt_ext(struct nvgpu_nvhost_dev *nvhost_dev, + u32 id); +void nvgpu_nvhost_syncpt_put_ref_ext(struct nvgpu_nvhost_dev *nvhost_dev, + u32 id); +u32 nvgpu_nvhost_get_syncpt_host_managed(struct nvgpu_nvhost_dev *nvhost_dev, + u32 param, + const char *syncpt_name); +u32 nvgpu_nvhost_get_syncpt_client_managed(struct nvgpu_nvhost_dev *nvhost_dev, + const char *syncpt_name); + +int nvgpu_nvhost_create_symlink(struct gk20a *g); +void nvgpu_nvhost_remove_symlink(struct gk20a *g); + +#ifdef CONFIG_SYNC +u32 nvgpu_nvhost_sync_pt_id(struct sync_pt *pt); +u32 nvgpu_nvhost_sync_pt_thresh(struct sync_pt *pt); +int nvgpu_nvhost_sync_num_pts(struct sync_fence *fence); + +struct sync_fence *nvgpu_nvhost_sync_fdget(int fd); +struct sync_fence *nvgpu_nvhost_sync_create_fence( + struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 thresh, const char *name); +#endif /* CONFIG_SYNC */ + +#ifdef CONFIG_TEGRA_T19X_GRHOST +int nvgpu_nvhost_syncpt_unit_interface_get_aperture( + struct nvgpu_nvhost_dev *nvhost_dev, + u64 *base, size_t *size); +u32 nvgpu_nvhost_syncpt_unit_interface_get_byte_offset(u32 syncpt_id); +int nvgpu_nvhost_syncpt_init(struct gk20a *g); +#else +static inline int nvgpu_nvhost_syncpt_unit_interface_get_aperture( + struct nvgpu_nvhost_dev *nvhost_dev, + u64 *base, size_t *size) +{ + return -EINVAL; +} +static inline u32 nvgpu_nvhost_syncpt_unit_interface_get_byte_offset(u32 syncpt_id) +{ + return 0; +} +static inline int nvgpu_nvhost_syncpt_init(struct gk20a *g) +{ + return 0; +} +#endif +#endif /* CONFIG_TEGRA_GK20A_NVHOST */ +#endif /* NVGPU_NVHOST_H */ diff --git a/include/nvgpu/nvlink.h b/include/nvgpu/nvlink.h new file mode 100644 index 0000000..a74111c --- /dev/null +++ b/include/nvgpu/nvlink.h @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_NVLINK_H +#define NVGPU_NVLINK_H + +#include + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +#define NV_NVLINK_REG_POLL_TIMEOUT_MS 3000 +#define NV_NVLINK_TIMEOUT_DELAY_US 5 + +#define MINION_REG_RD32(g, off) gk20a_readl(g, g->nvlink.minion_base + (off)) +#define MINION_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.minion_base + (off), (v)) +#define IOCTRL_REG_RD32(g, off) gk20a_readl(g, g->nvlink.ioctrl_base + (off)) +#define IOCTRL_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.ioctrl_base + (off), (v)) +#define MIF_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].mif_base + (off)) +#define MIF_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].mif_base + (off), (v)) +#define IPT_REG_RD32(g, off) gk20a_readl(g, g->nvlink.ipt_base + (off)) +#define IPT_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.ipt_base + (off), (v)) +#define TLC_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].tl_base + (off)) +#define TLC_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].tl_base + (off), (v)) +#define DLPL_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].dlpl_base + (off)) +#define DLPL_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].dlpl_base + (off), (v)) + +struct gk20a; + +struct nvgpu_nvlink_ioctrl_list { + bool valid; + u32 pri_base_addr; + u8 intr_enum; + u8 reset_enum; +}; + +struct nvgpu_nvlink_device_list { + bool valid; + u8 device_type; + u8 device_id; + u8 device_version; + u32 pri_base_addr; + u8 intr_enum; + u8 reset_enum; + u8 num_tx; + u8 num_rx; + u8 pll_master; + u8 pll_master_id; +}; + +enum nvgpu_nvlink_endp { + nvgpu_nvlink_endp_gpu, + nvgpu_nvlink_endp_tegra, + nvgpu_nvlink_endp__last, +}; + +enum nvgpu_nvlink_link_mode { + nvgpu_nvlink_link_off, + nvgpu_nvlink_link_hs, + nvgpu_nvlink_link_safe, + nvgpu_nvlink_link_fault, + nvgpu_nvlink_link_rcvy_ac, + nvgpu_nvlink_link_rcvy_sw, + nvgpu_nvlink_link_rcvy_rx, + nvgpu_nvlink_link_detect, + nvgpu_nvlink_link_reset, + nvgpu_nvlink_link_enable_pm, + nvgpu_nvlink_link_disable_pm, + nvgpu_nvlink_link_disable_err_detect, + nvgpu_nvlink_link_lane_disable, + nvgpu_nvlink_link_lane_shutdown, + nvgpu_nvlink_link__last, +}; + +enum nvgpu_nvlink_sublink_mode { + nvgpu_nvlink_sublink_tx_hs, + nvgpu_nvlink_sublink_tx_enable_pm, + nvgpu_nvlink_sublink_tx_disable_pm, + nvgpu_nvlink_sublink_tx_single_lane, + nvgpu_nvlink_sublink_tx_safe, + nvgpu_nvlink_sublink_tx_off, + nvgpu_nvlink_sublink_tx_common, + nvgpu_nvlink_sublink_tx_common_disable, + nvgpu_nvlink_sublink_tx_data_ready, + nvgpu_nvlink_sublink_tx_prbs_en, + nvgpu_nvlink_sublink_tx__last, + /* RX */ + nvgpu_nvlink_sublink_rx_hs, + nvgpu_nvlink_sublink_rx_enable_pm, + nvgpu_nvlink_sublink_rx_disable_pm, + nvgpu_nvlink_sublink_rx_single_lane, + nvgpu_nvlink_sublink_rx_safe, + nvgpu_nvlink_sublink_rx_off, + nvgpu_nvlink_sublink_rx_rxcal, + nvgpu_nvlink_sublink_rx__last, +}; + +struct nvgpu_nvlink_conn_info { + enum nvgpu_nvlink_endp device_type; + u32 link_number; + bool is_connected; +}; + +struct nvgpu_nvlink_link { + bool valid; + struct gk20a *g; + u8 link_id; + + u32 dlpl_base; + u8 dlpl_version; + + u32 tl_base; + u8 tl_version; + + u32 mif_base; + u8 mif_version; + + u8 intr_enum; + u8 reset_enum; + + bool dl_init_done; + + u8 pll_master_link_id; + u8 pll_slave_link_id; + + struct nvgpu_nvlink_conn_info remote_info; + void *priv; +}; + +#define NVLINK_MAX_LINKS_SW 6 + +enum nvgpu_nvlink_speed { + nvgpu_nvlink_speed_25G, + nvgpu_nvlink_speed_20G, + nvgpu_nvlink_speed__last, +}; + +struct nvgpu_nvlink_dev { + struct nvgpu_nvlink_ioctrl_list *ioctrl_table; + u32 io_num_entries; + + struct nvgpu_nvlink_device_list *device_table; + u32 num_devices; + + struct nvgpu_nvlink_link links[NVLINK_MAX_LINKS_SW]; + + u8 dlpl_type; + u32 dlpl_base[NVLINK_MAX_LINKS_SW]; + + u8 tl_type; + u32 tl_base[NVLINK_MAX_LINKS_SW]; + + u8 mif_type; + u32 mif_base[NVLINK_MAX_LINKS_SW]; + + u8 ipt_type; + u32 ipt_base; + u8 ipt_version; + + u8 dlpl_multicast_type; + u8 dlpl_multicast_version; + u32 dlpl_multicast_base; + + u8 tl_multicast_type; + u8 tl_multicast_version; + u32 tl_multicast_base; + + u8 mif_multicast_type; + u8 mif_multicast_version; + u32 mif_multicast_base; + + u8 ioctrl_type; + u32 ioctrl_base; + + u8 minion_type; + u32 minion_base; + u8 minion_version; + + u32 discovered_links; + + /* VBIOS settings */ + u32 link_disable_mask; + u32 link_mode_mask; + u32 link_refclk_mask; + u8 train_at_boot; + u32 ac_coupling_mask; + + u32 connected_links; + u32 initialized_links; + u32 enabled_links; + u32 init_pll_done; + + enum nvgpu_nvlink_speed speed; + + /* tlc cached errors */ + u32 tlc_rx_err_status_0[NVLINK_MAX_LINKS_SW]; + u32 tlc_rx_err_status_1[NVLINK_MAX_LINKS_SW]; + u32 tlc_tx_err_status_0[NVLINK_MAX_LINKS_SW]; + + /* priv struct */ + void *priv; +}; + +int nvgpu_nvlink_enumerate(struct gk20a *g); +int nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off); +int nvgpu_nvlink_read_dt_props(struct gk20a *g); + +int nvgpu_nvlink_probe(struct gk20a *g); +int nvgpu_nvlink_remove(struct gk20a *g); + +void nvgpu_mss_nvlink_init_credits(struct gk20a *g); + +#endif /* NVGPU_NVLINK_H */ diff --git a/include/nvgpu/os_fence.h b/include/nvgpu/os_fence.h new file mode 100644 index 0000000..272b076 --- /dev/null +++ b/include/nvgpu/os_fence.h @@ -0,0 +1,138 @@ +/* + * nvgpu os fence + * + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_OS_FENCE_H +#define NVGPU_OS_FENCE_H + +#include + +struct nvgpu_semaphore; +struct channel_gk20a; +struct priv_cmd_entry; +struct nvgpu_nvhost_dev; + +/* + * struct nvgpu_os_fence adds an abstraction to the earlier Android Sync + * Framework, specifically the sync-fence mechanism and the newer DMA sync + * APIs from linux-4.9. This abstraction provides the high-level definition + * as well as APIs that can be used by other OSes in future to have their own + * alternatives for the sync-framework. + */ +struct nvgpu_os_fence; + +/* + * struct nvgpu_os_fence depends on the following ops structure + */ +struct nvgpu_os_fence_ops { + /* + * This API is used to iterate through multiple fence points within the + * fence and program the pushbuffer method for wait command. + */ + int (*program_waits)(struct nvgpu_os_fence *s, + struct priv_cmd_entry *wait_cmd, + struct channel_gk20a *c, + int max_wait_cmds); + + /* + * This should be the last operation on the OS fence. The + * OS fence acts as a place-holder for the underlying fence + * implementation e.g. sync_fences. For each construct/fdget call + * there needs to be a drop_ref call. This reduces a reference count + * for the underlying sync_fence. + */ + void (*drop_ref)(struct nvgpu_os_fence *s); + + /* + * Used to install the fd in the corresponding OS. The underlying + * implementation varies from OS to OS. + */ + void (*install_fence)(struct nvgpu_os_fence *s, int fd); +}; + +/* + * The priv structure here is used to contain the struct sync_fence + * for LINUX_VERSION <= 4.9 and dma_fence for LINUX_VERSION > 4.9 + */ +struct nvgpu_os_fence { + void *priv; + struct gk20a *g; + const struct nvgpu_os_fence_ops *ops; +}; + +/* + * This API is used to validate the nvgpu_os_fence + */ +static inline int nvgpu_os_fence_is_initialized(struct nvgpu_os_fence *fence) +{ + return (fence->ops != NULL); +} + +#ifdef CONFIG_SYNC + +int nvgpu_os_fence_sema_create( + struct nvgpu_os_fence *fence_out, + struct channel_gk20a *c, + struct nvgpu_semaphore *sema); + +int nvgpu_os_fence_fdget( + struct nvgpu_os_fence *fence_out, + struct channel_gk20a *c, int fd); + +#else + +static inline int nvgpu_os_fence_sema_create( + struct nvgpu_os_fence *fence_out, + struct channel_gk20a *c, + struct nvgpu_semaphore *sema) +{ + return -ENOSYS; +} +static inline int nvgpu_os_fence_fdget( + struct nvgpu_os_fence *fence_out, + struct channel_gk20a *c, int fd) +{ + return -ENOSYS; +} + +#endif /* CONFIG_SYNC */ + +#if defined(CONFIG_TEGRA_GK20A_NVHOST) && defined(CONFIG_SYNC) + +int nvgpu_os_fence_syncpt_create(struct nvgpu_os_fence *fence_out, + struct channel_gk20a *c, struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 thresh); + +#else + +static inline int nvgpu_os_fence_syncpt_create( + struct nvgpu_os_fence *fence_out, struct channel_gk20a *c, + struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 thresh) +{ + return -ENOSYS; +} + +#endif /* CONFIG_TEGRA_GK20A_NVHOST && CONFIG_SYNC */ + +#endif /* NVGPU_OS_FENCE_H */ diff --git a/include/nvgpu/os_sched.h b/include/nvgpu/os_sched.h new file mode 100644 index 0000000..c8843b1 --- /dev/null +++ b/include/nvgpu/os_sched.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_OS_SCHED_H +#define NVGPU_OS_SCHED_H + +#include + +struct gk20a; + +/** + * nvgpu_current_tid - Query the id of current thread + * + */ +int nvgpu_current_tid(struct gk20a *g); + +/** + * nvgpu_current_pid - Query the id of current process + * + */ +int nvgpu_current_pid(struct gk20a *g); + +void __nvgpu_print_current(struct gk20a *g, const char *func_name, int line, + void *ctx, enum nvgpu_log_type type); +/** + * nvgpu_print_current - print the name of current calling process + * + */ +#define nvgpu_print_current(g, ctx, type) \ + __nvgpu_print_current(g, __func__, __LINE__, ctx, type) + +#endif /* NVGPU_OS_SCHED_H */ diff --git a/include/nvgpu/page_allocator.h b/include/nvgpu/page_allocator.h new file mode 100644 index 0000000..a6e0205 --- /dev/null +++ b/include/nvgpu/page_allocator.h @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2016-2017, 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 PAGE_ALLOCATOR_PRIV_H +#define PAGE_ALLOCATOR_PRIV_H + +#include +#include +#include +#include +#include + +struct nvgpu_allocator; + +/* + * This allocator implements the ability to do SLAB style allocation since the + * GPU has two page sizes available - 4k and 64k/128k. When the default + * granularity is the large page size (64k/128k) small allocations become very + * space inefficient. This is most notable in PDE and PTE blocks which are 4k + * in size. + * + * Thus we need the ability to suballocate in 64k pages. The way we do this for + * the GPU is as follows. We have several buckets for sub-64K allocations: + * + * B0 - 4k + * B1 - 8k + * B3 - 16k + * B4 - 32k + * B5 - 64k (for when large pages are 128k) + * + * When an allocation comes in for less than the large page size (from now on + * assumed to be 64k) the allocation is satisfied by one of the buckets. + */ +struct page_alloc_slab { + struct nvgpu_list_node empty; + struct nvgpu_list_node partial; + struct nvgpu_list_node full; + + int nr_empty; + int nr_partial; + int nr_full; + + u32 slab_size; +}; + +enum slab_page_state { + SP_EMPTY, + SP_PARTIAL, + SP_FULL, + SP_NONE +}; + +struct page_alloc_slab_page { + unsigned long bitmap; + u64 page_addr; + u32 slab_size; + + u32 nr_objects; + u32 nr_objects_alloced; + + enum slab_page_state state; + + struct page_alloc_slab *owner; + struct nvgpu_list_node list_entry; +}; + +static inline struct page_alloc_slab_page * +page_alloc_slab_page_from_list_entry(struct nvgpu_list_node *node) +{ + return (struct page_alloc_slab_page *) + ((uintptr_t)node - offsetof(struct page_alloc_slab_page, list_entry)); +}; + +/* + * Struct to handle internal management of page allocation. It holds a list + * of the chunks of pages that make up the overall allocation - much like a + * scatter gather table. + */ +struct nvgpu_page_alloc { + /* + * nvgpu_sgt for describing the actual allocation. Convenient for + * GMMU mapping. + */ + struct nvgpu_sgt sgt; + + int nr_chunks; + u64 length; + + /* + * Only useful for the RB tree - since the alloc may have discontiguous + * pages the base is essentially irrelevant except for the fact that it + * is guarenteed to be unique. + */ + u64 base; + + struct nvgpu_rbtree_node tree_entry; + + /* + * Set if this is a slab alloc. Points back to the slab page that owns + * this particular allocation. nr_chunks will always be 1 if this is + * set. + */ + struct page_alloc_slab_page *slab_page; +}; + +static inline struct nvgpu_page_alloc * +nvgpu_page_alloc_from_rbtree_node(struct nvgpu_rbtree_node *node) +{ + return (struct nvgpu_page_alloc *) + ((uintptr_t)node - offsetof(struct nvgpu_page_alloc, tree_entry)); +}; + +struct nvgpu_page_allocator { + struct nvgpu_allocator *owner; /* Owner of this allocator. */ + + /* + * Use a buddy allocator to manage the allocation of the underlying + * pages. This lets us abstract the discontiguous allocation handling + * out of the annoyingly complicated buddy allocator. + */ + struct nvgpu_allocator source_allocator; + + /* + * Page params. + */ + u64 base; + u64 length; + u64 page_size; + u32 page_shift; + + struct nvgpu_rbtree_node *allocs; /* Outstanding allocations. */ + + struct page_alloc_slab *slabs; + int nr_slabs; + + struct nvgpu_kmem_cache *alloc_cache; + struct nvgpu_kmem_cache *slab_page_cache; + + u64 flags; + + /* + * Stat tracking. + */ + u64 nr_allocs; + u64 nr_frees; + u64 nr_fixed_allocs; + u64 nr_fixed_frees; + u64 nr_slab_allocs; + u64 nr_slab_frees; + u64 pages_alloced; + u64 pages_freed; +}; + +static inline struct nvgpu_page_allocator *page_allocator( + struct nvgpu_allocator *a) +{ + return (struct nvgpu_page_allocator *)(a)->priv; +} + +static inline struct nvgpu_allocator *palloc_owner( + struct nvgpu_page_allocator *a) +{ + return a->owner; +} + +#endif diff --git a/include/nvgpu/pci.h b/include/nvgpu/pci.h new file mode 100644 index 0000000..b38465a --- /dev/null +++ b/include/nvgpu/pci.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_PCI_H +#define NVGPU_PCI_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#elif defined(__QNX__) +#include +#else +/* + * In case someone tries to use this without implementing support! + */ +#error "Build bug: need PCI headers!" +#endif + +#endif /* NVGPU_PCI_H */ diff --git a/include/nvgpu/pmu.h b/include/nvgpu/pmu.h new file mode 100644 index 0000000..2b745c7 --- /dev/null +++ b/include/nvgpu/pmu.h @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2017-2019, 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_H +#define NVGPU_PMU_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define nvgpu_pmu_dbg(g, fmt, args...) \ + nvgpu_log(g, gpu_dbg_pmu, fmt, ##args) + +/* defined by pmu hw spec */ +#define GK20A_PMU_VA_SIZE (512 * 1024 * 1024) +#define GK20A_PMU_UCODE_SIZE_MAX (256 * 1024) +#define GK20A_PMU_SEQ_BUF_SIZE 4096 + +#define GK20A_PMU_TRACE_BUFSIZE 0x4000 /* 4K */ +#define GK20A_PMU_DMEM_BLKSIZE2 8 + +#define PMU_MODE_MISMATCH_STATUS_MAILBOX_R 6 +#define PMU_MODE_MISMATCH_STATUS_VAL 0xDEADDEAD + +/* Falcon Register index */ +#define PMU_FALCON_REG_R0 (0) +#define PMU_FALCON_REG_R1 (1) +#define PMU_FALCON_REG_R2 (2) +#define PMU_FALCON_REG_R3 (3) +#define PMU_FALCON_REG_R4 (4) +#define PMU_FALCON_REG_R5 (5) +#define PMU_FALCON_REG_R6 (6) +#define PMU_FALCON_REG_R7 (7) +#define PMU_FALCON_REG_R8 (8) +#define PMU_FALCON_REG_R9 (9) +#define PMU_FALCON_REG_R10 (10) +#define PMU_FALCON_REG_R11 (11) +#define PMU_FALCON_REG_R12 (12) +#define PMU_FALCON_REG_R13 (13) +#define PMU_FALCON_REG_R14 (14) +#define PMU_FALCON_REG_R15 (15) +#define PMU_FALCON_REG_IV0 (16) +#define PMU_FALCON_REG_IV1 (17) +#define PMU_FALCON_REG_UNDEFINED (18) +#define PMU_FALCON_REG_EV (19) +#define PMU_FALCON_REG_SP (20) +#define PMU_FALCON_REG_PC (21) +#define PMU_FALCON_REG_IMB (22) +#define PMU_FALCON_REG_DMB (23) +#define PMU_FALCON_REG_CSW (24) +#define PMU_FALCON_REG_CCR (25) +#define PMU_FALCON_REG_SEC (26) +#define PMU_FALCON_REG_CTX (27) +#define PMU_FALCON_REG_EXCI (28) +#define PMU_FALCON_REG_RSVD0 (29) +#define PMU_FALCON_REG_RSVD1 (30) +#define PMU_FALCON_REG_RSVD2 (31) +#define PMU_FALCON_REG_SIZE (32) + +/* Choices for pmu_state */ +#define PMU_STATE_OFF 0U /* PMU is off */ +#define PMU_STATE_STARTING 1U /* PMU is on, but not booted */ +#define PMU_STATE_INIT_RECEIVED 2U /* PMU init message received */ +#define PMU_STATE_ELPG_BOOTING 3U /* PMU is booting */ +#define PMU_STATE_ELPG_BOOTED 4U /* ELPG is initialized */ +#define PMU_STATE_LOADING_PG_BUF 5U /* Loading PG buf */ +#define PMU_STATE_LOADING_ZBC 6U /* Loading ZBC buf */ +#define PMU_STATE_STARTED 7U /* Fully unitialized */ +#define PMU_STATE_EXIT 8U /* Exit PMU state machine */ + +#define GK20A_PMU_UCODE_NB_MAX_OVERLAY 32U +#define GK20A_PMU_UCODE_NB_MAX_DATE_LENGTH 64U + +#define PMU_MAX_NUM_SEQUENCES (256U) +#define PMU_SEQ_BIT_SHIFT (5U) +#define PMU_SEQ_TBL_SIZE \ + (PMU_MAX_NUM_SEQUENCES >> PMU_SEQ_BIT_SHIFT) + +#define PMU_INVALID_SEQ_DESC (~0) + +enum { + GK20A_PMU_DMAIDX_UCODE = 0, + GK20A_PMU_DMAIDX_VIRT = 1, + GK20A_PMU_DMAIDX_PHYS_VID = 2, + GK20A_PMU_DMAIDX_PHYS_SYS_COH = 3, + GK20A_PMU_DMAIDX_PHYS_SYS_NCOH = 4, + GK20A_PMU_DMAIDX_RSVD = 5, + GK20A_PMU_DMAIDX_PELPG = 6, + GK20A_PMU_DMAIDX_END = 7 +}; + +enum { + PMU_SEQ_STATE_FREE = 0, + PMU_SEQ_STATE_PENDING, + PMU_SEQ_STATE_USED, + PMU_SEQ_STATE_CANCELLED +}; + +/*PG defines used by nvpgu-pmu*/ +#define PMU_PG_IDLE_THRESHOLD_SIM 1000 +#define PMU_PG_POST_POWERUP_IDLE_THRESHOLD_SIM 4000000 +/* TBD: QT or else ? */ +#define PMU_PG_IDLE_THRESHOLD 15000 +#define PMU_PG_POST_POWERUP_IDLE_THRESHOLD 1000000 + +#define PMU_PG_LPWR_FEATURE_RPPG 0x0 +#define PMU_PG_LPWR_FEATURE_MSCG 0x1 + +#define PMU_MSCG_DISABLED 0U +#define PMU_MSCG_ENABLED 1U + +/* Default Sampling Period of AELPG */ +#define APCTRL_SAMPLING_PERIOD_PG_DEFAULT_US (1000000) + +/* Default values of APCTRL parameters */ +#define APCTRL_MINIMUM_IDLE_FILTER_DEFAULT_US (100) +#define APCTRL_MINIMUM_TARGET_SAVING_DEFAULT_US (10000) +#define APCTRL_POWER_BREAKEVEN_DEFAULT_US (2000) +#define APCTRL_CYCLES_PER_SAMPLE_MAX_DEFAULT (200) + +/* pmu load const defines */ +#define PMU_BUSY_CYCLES_NORM_MAX (1000U) + +/* RPC */ +#define PMU_RPC_EXECUTE(_stat, _pmu, _unit, _func, _prpc, _size)\ + do { \ + memset(&((_prpc)->hdr), 0, sizeof((_prpc)->hdr));\ + \ + (_prpc)->hdr.unit_id = PMU_UNIT_##_unit; \ + (_prpc)->hdr.function = NV_PMU_RPC_ID_##_unit##_##_func;\ + (_prpc)->hdr.flags = 0x0; \ + \ + _stat = nvgpu_pmu_rpc_execute(_pmu, &((_prpc)->hdr), \ + (sizeof(*(_prpc)) - sizeof((_prpc)->scratch)),\ + (_size), NULL, NULL, false); \ + } while (0) + +/* RPC blocking call to copy back data from PMU to _prpc */ +#define PMU_RPC_EXECUTE_CPB(_stat, _pmu, _unit, _func, _prpc, _size)\ + do { \ + memset(&((_prpc)->hdr), 0, sizeof((_prpc)->hdr));\ + \ + (_prpc)->hdr.unit_id = PMU_UNIT_##_unit; \ + (_prpc)->hdr.function = NV_PMU_RPC_ID_##_unit##_##_func;\ + (_prpc)->hdr.flags = 0x0; \ + \ + _stat = nvgpu_pmu_rpc_execute(_pmu, &((_prpc)->hdr), \ + (sizeof(*(_prpc)) - sizeof((_prpc)->scratch)),\ + (_size), NULL, NULL, true); \ + } while (0) + +/* RPC non-blocking with call_back handler option */ +#define PMU_RPC_EXECUTE_CB(_stat, _pmu, _unit, _func, _prpc, _size, _cb, _cbp)\ + do { \ + memset(&((_prpc)->hdr), 0, sizeof((_prpc)->hdr));\ + \ + (_prpc)->hdr.unit_id = PMU_UNIT_##_unit; \ + (_prpc)->hdr.function = NV_PMU_RPC_ID_##_unit##_##_func;\ + (_prpc)->hdr.flags = 0x0; \ + \ + _stat = nvgpu_pmu_rpc_execute(_pmu, &((_prpc)->hdr), \ + (sizeof(*(_prpc)) - sizeof((_prpc)->scratch)),\ + (_size), _cb, _cbp, false); \ + } while (0) + +typedef void (*pmu_callback)(struct gk20a *, struct pmu_msg *, void *, u32, + u32); + +struct rpc_handler_payload { + void *rpc_buff; + bool is_mem_free_set; + bool complete; +}; + +struct pmu_rpc_desc { + void *prpc; + u16 size_rpc; + u16 size_scratch; +}; + +struct pmu_payload { + struct { + void *buf; + u32 offset; + u32 size; + u32 fb_size; + } in, out; + struct pmu_rpc_desc rpc; +}; + +struct pmu_ucode_desc { + u32 descriptor_size; + u32 image_size; + u32 tools_version; + u32 app_version; + char date[GK20A_PMU_UCODE_NB_MAX_DATE_LENGTH]; + u32 bootloader_start_offset; + u32 bootloader_size; + u32 bootloader_imem_offset; + u32 bootloader_entry_point; + u32 app_start_offset; + u32 app_size; + u32 app_imem_offset; + u32 app_imem_entry; + u32 app_dmem_offset; + /* Offset from appStartOffset */ + u32 app_resident_code_offset; + /* Exact size of the resident code + * ( potentially contains CRC inside at the end ) + */ + u32 app_resident_code_size; + /* Offset from appStartOffset */ + u32 app_resident_data_offset; + /* Exact size of the resident code + * ( potentially contains CRC inside at the end ) + */ + u32 app_resident_data_size; + u32 nb_overlays; + struct {u32 start; u32 size; } load_ovl[GK20A_PMU_UCODE_NB_MAX_OVERLAY]; + u32 compressed; +}; + +struct pmu_ucode_desc_v1 { + u32 descriptor_size; + u32 image_size; + u32 tools_version; + u32 app_version; + char date[GK20A_PMU_UCODE_NB_MAX_DATE_LENGTH]; + u32 bootloader_start_offset; + u32 bootloader_size; + u32 bootloader_imem_offset; + u32 bootloader_entry_point; + u32 app_start_offset; + u32 app_size; + u32 app_imem_offset; + u32 app_imem_entry; + u32 app_dmem_offset; + u32 app_resident_code_offset; + u32 app_resident_code_size; + u32 app_resident_data_offset; + u32 app_resident_data_size; + u32 nb_imem_overlays; + u32 nb_dmem_overlays; + struct {u32 start; u32 size; } load_ovl[64]; + u32 compressed; +}; + +struct pmu_mutex { + u32 id; + u32 index; + u32 ref_cnt; +}; + +struct pmu_sequence { + u8 id; + u32 state; + u32 desc; + struct pmu_msg *msg; + union { + struct pmu_allocation_v1 in_v1; + struct pmu_allocation_v2 in_v2; + struct pmu_allocation_v3 in_v3; + }; + struct nvgpu_mem *in_mem; + union { + struct pmu_allocation_v1 out_v1; + struct pmu_allocation_v2 out_v2; + struct pmu_allocation_v3 out_v3; + }; + struct nvgpu_mem *out_mem; + u8 *out_payload; + pmu_callback callback; + void *cb_params; +}; + +struct nvgpu_pg_init { + bool state_change; + bool state_destroy; + struct nvgpu_cond wq; + struct nvgpu_thread state_task; +}; + +struct nvgpu_pmu { + struct gk20a *g; + struct nvgpu_falcon *flcn; + + union { + struct pmu_ucode_desc *desc; + struct pmu_ucode_desc_v1 *desc_v1; + }; + struct nvgpu_mem ucode; + + struct nvgpu_mem pg_buf; + + /* TBD: remove this if ZBC seq is fixed */ + struct nvgpu_mem seq_buf; + struct nvgpu_mem trace_buf; + struct nvgpu_mem super_surface_buf; + + bool buf_loaded; + + struct pmu_sha1_gid gid_info; + + struct nvgpu_falcon_queue queue[PMU_QUEUE_COUNT]; + + struct pmu_sequence *seq; + unsigned long pmu_seq_tbl[PMU_SEQ_TBL_SIZE]; + u32 next_seq_desc; + + struct pmu_mutex *mutex; + u32 mutex_cnt; + + struct nvgpu_mutex pmu_copy_lock; + struct nvgpu_mutex pmu_seq_lock; + + struct nvgpu_allocator dmem; + + u32 *ucode_image; + bool pmu_ready; + + u32 perfmon_query; + + u32 zbc_save_done; + + u32 stat_dmem_offset[PMU_PG_ELPG_ENGINE_ID_INVALID_ENGINE]; + + u32 elpg_stat; + + u32 mscg_stat; + u32 mscg_transition_state; + + u32 pmu_state; + +#define PMU_ELPG_ENABLE_ALLOW_DELAY_MSEC 1 /* msec */ + struct nvgpu_pg_init pg_init; + struct nvgpu_mutex pg_mutex; /* protect pg-RPPG/MSCG enable/disable */ + struct nvgpu_mutex elpg_mutex; /* protect elpg enable/disable */ + /* disable -1, enable +1, <=0 elpg disabled, > 0 elpg enabled */ + int elpg_refcnt; + + union { + struct pmu_perfmon_counter_v2 perfmon_counter_v2; + }; + u32 perfmon_state_id[PMU_DOMAIN_GROUP_NUM]; + + bool initialized; + + void (*remove_support)(struct nvgpu_pmu *pmu); + bool sw_ready; + bool perfmon_ready; + + u32 sample_buffer; + u32 load_shadow; + u32 load_avg; + u32 load; + + struct nvgpu_mutex isr_mutex; + bool isr_enabled; + + bool zbc_ready; + union { + struct pmu_cmdline_args_v3 args_v3; + struct pmu_cmdline_args_v4 args_v4; + struct pmu_cmdline_args_v5 args_v5; + struct pmu_cmdline_args_v6 args_v6; + }; + unsigned long perfmon_events_cnt; + bool perfmon_sampling_enabled; + u8 pmu_mode; /*Added for GM20b, and ACR*/ + u32 falcon_id; + u32 aelpg_param[5]; + u32 override_done; + + struct nvgpu_firmware *fw; +}; + +struct pmu_surface { + struct nvgpu_mem vidmem_desc; + struct nvgpu_mem sysmem_desc; + struct flcn_mem_desc_v0 params; +}; + +/*PG defines used by nvpgu-pmu*/ +struct pmu_pg_stats_data { + u32 gating_cnt; + u32 ingating_time; + u32 ungating_time; + u32 avg_entry_latency_us; + u32 avg_exit_latency_us; +}; + +/*! + * Structure/object which single register write need to be done during PG init + * sequence to set PROD values. + */ +struct pg_init_sequence_list { + u32 regaddr; + u32 writeval; +}; + +/* PMU IPC Methods */ +void nvgpu_pmu_seq_init(struct nvgpu_pmu *pmu); + +int nvgpu_pmu_mutex_acquire(struct nvgpu_pmu *pmu, u32 id, u32 *token); +int nvgpu_pmu_mutex_release(struct nvgpu_pmu *pmu, u32 id, u32 *token); + +int nvgpu_pmu_queue_init(struct nvgpu_pmu *pmu, u32 id, + union pmu_init_msg_pmu *init); + +/* send a cmd to pmu */ +int nvgpu_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd, + struct pmu_msg *msg, struct pmu_payload *payload, + u32 queue_id, pmu_callback callback, void *cb_param, + u32 *seq_desc, unsigned long timeout); + +int nvgpu_pmu_process_message(struct nvgpu_pmu *pmu); + +/* perfmon */ +int nvgpu_pmu_init_perfmon(struct nvgpu_pmu *pmu); +int nvgpu_pmu_perfmon_start_sampling(struct nvgpu_pmu *pmu); +int nvgpu_pmu_perfmon_stop_sampling(struct nvgpu_pmu *pmu); +int nvgpu_pmu_perfmon_start_sampling_rpc(struct nvgpu_pmu *pmu); +int nvgpu_pmu_perfmon_stop_sampling_rpc(struct nvgpu_pmu *pmu); +int nvgpu_pmu_perfmon_get_samples_rpc(struct nvgpu_pmu *pmu); +int nvgpu_pmu_handle_perfmon_event(struct nvgpu_pmu *pmu, + struct pmu_perfmon_msg *msg); +int nvgpu_pmu_init_perfmon_rpc(struct nvgpu_pmu *pmu); +int nvgpu_pmu_load_norm(struct gk20a *g, u32 *load); +int nvgpu_pmu_load_update(struct gk20a *g); +int nvgpu_pmu_busy_cycles_norm(struct gk20a *g, u32 *norm); +void nvgpu_pmu_reset_load_counters(struct gk20a *g); +void nvgpu_pmu_get_load_counters(struct gk20a *g, u32 *busy_cycles, + u32 *total_cycles); + +int nvgpu_pmu_handle_therm_event(struct nvgpu_pmu *pmu, + struct nv_pmu_therm_msg *msg); + +/* PMU init */ +int nvgpu_init_pmu_support(struct gk20a *g); +int nvgpu_pmu_destroy(struct gk20a *g); +int nvgpu_pmu_process_init_msg(struct nvgpu_pmu *pmu, + struct pmu_msg *msg); +int nvgpu_pmu_super_surface_alloc(struct gk20a *g, + struct nvgpu_mem *mem_surface, u32 size); + +void nvgpu_pmu_state_change(struct gk20a *g, u32 pmu_state, + bool post_change_event); +void nvgpu_kill_task_pg_init(struct gk20a *g); + +/* NVGPU-PMU MEM alloc */ +void nvgpu_pmu_surface_free(struct gk20a *g, struct nvgpu_mem *mem); +void nvgpu_pmu_surface_describe(struct gk20a *g, struct nvgpu_mem *mem, + struct flcn_mem_desc_v0 *fb); +int nvgpu_pmu_vidmem_surface_alloc(struct gk20a *g, struct nvgpu_mem *mem, + u32 size); +int nvgpu_pmu_sysmem_surface_alloc(struct gk20a *g, struct nvgpu_mem *mem, + u32 size); + +/* PMU F/W support */ +int nvgpu_init_pmu_fw_support(struct nvgpu_pmu *pmu); +int nvgpu_pmu_prepare_ns_ucode_blob(struct gk20a *g); + +/* PG init*/ +int nvgpu_pmu_init_powergating(struct gk20a *g); +int nvgpu_pmu_init_bind_fecs(struct gk20a *g); +void nvgpu_pmu_setup_hw_load_zbc(struct gk20a *g); + +/* PMU reset */ +int nvgpu_pmu_reset(struct gk20a *g); + +/* PG enable/disable */ +int nvgpu_pmu_reenable_elpg(struct gk20a *g); +int nvgpu_pmu_enable_elpg(struct gk20a *g); +int nvgpu_pmu_disable_elpg(struct gk20a *g); +int nvgpu_pmu_pg_global_enable(struct gk20a *g, u32 enable_pg); + +int nvgpu_pmu_get_pg_stats(struct gk20a *g, u32 pg_engine_id, + struct pmu_pg_stats_data *pg_stat_data); + +/* AELPG */ +int nvgpu_aelpg_init(struct gk20a *g); +int nvgpu_aelpg_init_and_enable(struct gk20a *g, u8 ctrl_id); +int nvgpu_pmu_ap_send_command(struct gk20a *g, + union pmu_ap_cmd *p_ap_cmd, bool b_block); + +/* PMU debug */ +void nvgpu_pmu_dump_falcon_stats(struct nvgpu_pmu *pmu); +void nvgpu_pmu_dump_elpg_stats(struct nvgpu_pmu *pmu); +bool nvgpu_find_hex_in_string(char *strings, struct gk20a *g, u32 *hex_pos); + +/* PMU RPC */ +int nvgpu_pmu_rpc_execute(struct nvgpu_pmu *pmu, struct nv_pmu_rpc_header *rpc, + u16 size_rpc, u16 size_scratch, pmu_callback callback, void *cb_param, + bool is_copy_back); + +/* PMU wait*/ +int pmu_wait_message_cond(struct nvgpu_pmu *pmu, u32 timeout_ms, + void *var, u8 val); + +struct gk20a *gk20a_from_pmu(struct nvgpu_pmu *pmu); +#endif /* NVGPU_PMU_H */ diff --git a/include/nvgpu/pmuif/gpmu_super_surf_if.h b/include/nvgpu/pmuif/gpmu_super_surf_if.h new file mode 100644 index 0000000..b0f9e10 --- /dev/null +++ b/include/nvgpu/pmuif/gpmu_super_surf_if.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_GPMU_SUPER_SURF_IF_H +#define NVGPU_PMUIF_GPMU_SUPER_SURF_IF_H + +struct nv_pmu_super_surface_hdr { + u32 memberMask; + u16 dmemBufferSizeMax; +}; + +NV_PMU_MAKE_ALIGNED_STRUCT(nv_pmu_super_surface_hdr, + sizeof(struct nv_pmu_super_surface_hdr)); + +/* + * Global Super Surface structure for combined INIT data required by PMU. + * NOTE: Any new substructures or entries must be aligned. + */ +struct nv_pmu_super_surface { + union nv_pmu_super_surface_hdr_aligned hdr; + + struct { + struct nv_pmu_volt_volt_device_boardobj_grp_set volt_device_grp_set; + struct nv_pmu_volt_volt_policy_boardobj_grp_set volt_policy_grp_set; + struct nv_pmu_volt_volt_rail_boardobj_grp_set volt_rail_grp_set; + + struct nv_pmu_volt_volt_policy_boardobj_grp_get_status volt_policy_grp_get_status; + struct nv_pmu_volt_volt_rail_boardobj_grp_get_status volt_rail_grp_get_status; + struct nv_pmu_volt_volt_device_boardobj_grp_get_status volt_device_grp_get_status; + } volt; + struct { + struct nv_pmu_clk_clk_vin_device_boardobj_grp_set clk_vin_device_grp_set; + struct nv_pmu_clk_clk_domain_boardobj_grp_set clk_domain_grp_set; + struct nv_pmu_clk_clk_freq_controller_boardobj_grp_set clk_freq_controller_grp_set; + u8 clk_rsvd2[0x200]; + struct nv_pmu_clk_clk_fll_device_boardobj_grp_set clk_fll_device_grp_set; + struct nv_pmu_clk_clk_prog_boardobj_grp_set clk_prog_grp_set; + struct nv_pmu_clk_clk_vf_point_boardobj_grp_set clk_vf_point_grp_set; + struct nv_pmu_clk_clk_vin_device_boardobj_grp_get_status clk_vin_device_grp_get_status; + struct nv_pmu_clk_clk_fll_device_boardobj_grp_get_status clk_fll_device_grp_get_status; + struct nv_pmu_clk_clk_vf_point_boardobj_grp_get_status clk_vf_point_grp_get_status; + u8 clk_rsvd[0x4660]; + } clk; + struct { + struct nv_pmu_perf_vfe_equ_boardobj_grp_set vfe_equ_grp_set; + struct nv_pmu_perf_vfe_var_boardobj_grp_set vfe_var_grp_set; + + struct nv_pmu_perf_vfe_var_boardobj_grp_get_status vfe_var_grp_get_status; + u8 perf_rsvd[0x40790]; + u8 perfcf_rsvd[0x1eb0]; + } perf; + struct { + struct nv_pmu_therm_therm_channel_boardobj_grp_set therm_channel_grp_set; + struct nv_pmu_therm_therm_device_boardobj_grp_set therm_device_grp_set; + u8 therm_rsvd[0x1460]; + } therm; +}; + +#endif /* NVGPU_PMUIF_GPMU_SUPER_SURF_IF_H */ diff --git a/include/nvgpu/pmuif/gpmuif_acr.h b/include/nvgpu/pmuif/gpmuif_acr.h new file mode 100644 index 0000000..c305589 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuif_acr.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_GPMUIF_ACR_H +#define NVGPU_PMUIF_GPMUIF_ACR_H + +/* ACR Commands/Message structures */ + +enum { + PMU_ACR_CMD_ID_INIT_WPR_REGION = 0x0, + PMU_ACR_CMD_ID_BOOTSTRAP_FALCON, + PMU_ACR_CMD_ID_RESERVED, + PMU_ACR_CMD_ID_BOOTSTRAP_MULTIPLE_FALCONS, +}; + +/* + * Initializes the WPR region details + */ +struct pmu_acr_cmd_init_wpr_details { + u8 cmd_type; + u32 regionid; + u32 wproffset; + +}; + +/* + * falcon ID to bootstrap + */ +struct pmu_acr_cmd_bootstrap_falcon { + u8 cmd_type; + u32 flags; + u32 falconid; +}; + +/* + * falcon ID to bootstrap + */ +struct pmu_acr_cmd_bootstrap_multiple_falcons { + u8 cmd_type; + u32 flags; + u32 falconidmask; + u32 usevamask; + struct falc_u64 wprvirtualbase; +}; + +#define PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_NO 1 +#define PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES 0 + + +struct pmu_acr_cmd { + union { + u8 cmd_type; + struct pmu_acr_cmd_bootstrap_falcon bootstrap_falcon; + struct pmu_acr_cmd_init_wpr_details init_wpr; + struct pmu_acr_cmd_bootstrap_multiple_falcons boot_falcons; + }; +}; + +/* acr messages */ + +/* + * returns the WPR region init information + */ +#define PMU_ACR_MSG_ID_INIT_WPR_REGION 0 + +/* + * Returns the Bootstrapped falcon ID to RM + */ +#define PMU_ACR_MSG_ID_BOOTSTRAP_FALCON 1 + +/* + * Returns the WPR init status + */ +#define PMU_ACR_SUCCESS 0 +#define PMU_ACR_ERROR 1 + +/* + * PMU notifies about bootstrap status of falcon + */ +struct pmu_acr_msg_bootstrap_falcon { + u8 msg_type; + union { + u32 errorcode; + u32 falconid; + }; +}; + +struct pmu_acr_msg { + union { + u8 msg_type; + struct pmu_acr_msg_bootstrap_falcon acrmsg; + }; +}; + +/* ACR RPC */ +#define NV_PMU_RPC_ID_ACR_INIT_WPR_REGION 0x00 +#define NV_PMU_RPC_ID_ACR_WRITE_CBC_BASE 0x01 +#define NV_PMU_RPC_ID_ACR_BOOTSTRAP_FALCON 0x02 +#define NV_PMU_RPC_ID_ACR_BOOTSTRAP_GR_FALCONS 0x03 +#define NV_PMU_RPC_ID_ACR__COUNT 0x04 + +/* + * structure that holds data used + * to execute INIT_WPR_REGION RPC. + */ +struct nv_pmu_rpc_struct_acr_init_wpr_region { + /*[IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + /*[IN] ACR region ID of WPR region */ + u32 wpr_regionId; + /* [IN] WPR offset from startAddress */ + u32 wpr_offset; + u32 scratch[1]; +}; + +/* + * structure that holds data used to + * execute BOOTSTRAP_GR_FALCONS RPC. + */ +struct nv_pmu_rpc_struct_acr_bootstrap_gr_falcons { + /*[IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + /* [IN] Mask of falcon IDs @ref LSF_FALCON_ID_ */ + u32 falcon_id_mask; + /* + * [IN] Boostrapping flags @ref + * PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_ + */ + u32 flags; + /* [IN] Indicate whether the particular falon uses VA */ + u32 falcon_va_mask; + /* + * [IN] WPR Base Address in VA. The Inst Block containing + * this VA should be bound to both PMU and GR falcons + * during the falcon boot + */ + struct falc_u64 wpr_base_virtual; + u32 scratch[1]; +}; + +#endif /* NVGPU_PMUIF_GPMUIF_ACR_H */ diff --git a/include/nvgpu/pmuif/gpmuif_ap.h b/include/nvgpu/pmuif/gpmuif_ap.h new file mode 100644 index 0000000..776fce8 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuif_ap.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_GPMUIF_AP_H +#define NVGPU_PMUIF_GPMUIF_AP_H + +/* PMU Command/Message Interfaces for Adaptive Power */ +/* Macro to get Histogram index */ +#define PMU_AP_HISTOGRAM(idx) (idx) +#define PMU_AP_HISTOGRAM_CONT (4) + +/* Total number of histogram bins */ +#define PMU_AP_CFG_HISTOGRAM_BIN_N (16) + +/* Mapping between Idle counters and histograms */ +#define PMU_AP_IDLE_MASK_HIST_IDX_0 (2) +#define PMU_AP_IDLE_MASK_HIST_IDX_1 (3) +#define PMU_AP_IDLE_MASK_HIST_IDX_2 (5) +#define PMU_AP_IDLE_MASK_HIST_IDX_3 (6) + + +/* Mapping between AP_CTRLs and Histograms */ +#define PMU_AP_HISTOGRAM_IDX_GRAPHICS (PMU_AP_HISTOGRAM(1)) + +/* Mapping between AP_CTRLs and Idle counters */ +#define PMU_AP_IDLE_MASK_GRAPHICS (PMU_AP_IDLE_MASK_HIST_IDX_1) + +/* Adaptive Power Controls (AP_CTRL) */ +enum { + PMU_AP_CTRL_ID_GRAPHICS = 0x0, + PMU_AP_CTRL_ID_MAX, +}; + +/* AP_CTRL Statistics */ +struct pmu_ap_ctrl_stat { + /* + * Represents whether AP is active or not + */ + u8 b_active; + + /* Idle filter represented by histogram bin index */ + u8 idle_filter_x; + u8 rsvd[2]; + + /* Total predicted power saving cycles. */ + s32 power_saving_h_cycles; + + /* Counts how many times AP gave us -ve power benefits. */ + u32 bad_decision_count; + + /* + * Number of times ap structure needs to skip AP iterations + * KICK_CTRL from kernel updates this parameter. + */ + u32 skip_count; + u8 bin[PMU_AP_CFG_HISTOGRAM_BIN_N]; +}; + +/* Parameters initialized by INITn APCTRL command */ +struct pmu_ap_ctrl_init_params { + /* Minimum idle filter value in Us */ + u32 min_idle_filter_us; + + /* + * Minimum Targeted Saving in Us. AP will update idle thresholds only + * if power saving achieved by updating idle thresholds is greater than + * Minimum targeted saving. + */ + u32 min_target_saving_us; + + /* Minimum targeted residency of power feature in Us */ + u32 power_break_even_us; + + /* + * Maximum number of allowed power feature cycles per sample. + * + * We are allowing at max "pgPerSampleMax" cycles in one iteration of AP + * AKA pgPerSampleMax in original algorithm. + */ + u32 cycles_per_sample_max; +}; + +/* AP Commands/Message structures */ + +/* + * Structure for Generic AP Commands + */ +struct pmu_ap_cmd_common { + u8 cmd_type; + u16 cmd_id; +}; + +/* + * Structure for INIT AP command + */ +struct pmu_ap_cmd_init { + u8 cmd_type; + u16 cmd_id; + u8 rsvd; + u32 pg_sampling_period_us; +}; + +/* + * Structure for Enable/Disable ApCtrl Commands + */ +struct pmu_ap_cmd_enable_ctrl { + u8 cmd_type; + u16 cmd_id; + + u8 ctrl_id; +}; + +struct pmu_ap_cmd_disable_ctrl { + u8 cmd_type; + u16 cmd_id; + + u8 ctrl_id; +}; + +/* + * Structure for INIT command + */ +struct pmu_ap_cmd_init_ctrl { + u8 cmd_type; + u16 cmd_id; + u8 ctrl_id; + struct pmu_ap_ctrl_init_params params; +}; + +struct pmu_ap_cmd_init_and_enable_ctrl { + u8 cmd_type; + u16 cmd_id; + u8 ctrl_id; + struct pmu_ap_ctrl_init_params params; +}; + +/* + * Structure for KICK_CTRL command + */ +struct pmu_ap_cmd_kick_ctrl { + u8 cmd_type; + u16 cmd_id; + u8 ctrl_id; + + u32 skip_count; +}; + +/* + * Structure for PARAM command + */ +struct pmu_ap_cmd_param { + u8 cmd_type; + u16 cmd_id; + u8 ctrl_id; + + u32 data; +}; + +/* + * Defines for AP commands + */ +enum { + PMU_AP_CMD_ID_INIT = 0x0, + PMU_AP_CMD_ID_INIT_AND_ENABLE_CTRL, + PMU_AP_CMD_ID_ENABLE_CTRL, + PMU_AP_CMD_ID_DISABLE_CTRL, + PMU_AP_CMD_ID_KICK_CTRL, +}; + +/* + * AP Command + */ +union pmu_ap_cmd { + u8 cmd_type; + struct pmu_ap_cmd_common cmn; + struct pmu_ap_cmd_init init; + struct pmu_ap_cmd_init_and_enable_ctrl init_and_enable_ctrl; + struct pmu_ap_cmd_enable_ctrl enable_ctrl; + struct pmu_ap_cmd_disable_ctrl disable_ctrl; + struct pmu_ap_cmd_kick_ctrl kick_ctrl; +}; + +/* + * Structure for generic AP Message + */ +struct pmu_ap_msg_common { + u8 msg_type; + u16 msg_id; +}; + +/* + * Structure for INIT_ACK Message + */ +struct pmu_ap_msg_init_ack { + u8 msg_type; + u16 msg_id; + u8 ctrl_id; + u32 stats_dmem_offset; +}; + +/* + * Defines for AP messages + */ +enum { + PMU_AP_MSG_ID_INIT_ACK = 0x0, +}; + +/* + * AP Message + */ +union pmu_ap_msg { + u8 msg_type; + struct pmu_ap_msg_common cmn; + struct pmu_ap_msg_init_ack init_ack; +}; + +/* + * Adaptive Power Controller + */ +struct ap_ctrl { + u32 stats_dmem_offset; + u32 disable_reason_mask; + struct pmu_ap_ctrl_stat stat_cache; + u8 b_ready; +}; + +/* + * Adaptive Power structure + * + * ap structure provides generic infrastructure to make any power feature + * adaptive. + */ +struct pmu_ap { + u32 supported_mask; + struct ap_ctrl ap_ctrl[PMU_AP_CTRL_ID_MAX]; +}; + +#endif /* NVGPU_PMUIF_GPMUIF_AP_H*/ diff --git a/include/nvgpu/pmuif/gpmuif_cmn.h b/include/nvgpu/pmuif/gpmuif_cmn.h new file mode 100644 index 0000000..0989754 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuif_cmn.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_GPMUIF_CMN_H +#define NVGPU_PMUIF_GPMUIF_CMN_H + +/* + * Defines the logical queue IDs that must be used when submitting + * commands to the PMU + */ +/* write by sw, read by pmu, protected by sw mutex lock */ +#define PMU_COMMAND_QUEUE_HPQ 0U +/* write by sw, read by pmu, protected by sw mutex lock */ +#define PMU_COMMAND_QUEUE_LPQ 1U +/* write by pmu, read by sw, accessed by interrupt handler, no lock */ +#define PMU_MESSAGE_QUEUE 4U +#define PMU_QUEUE_COUNT 5U + +#define PMU_IS_COMMAND_QUEUE(id) \ + ((id) < PMU_MESSAGE_QUEUE) + +#define PMU_IS_SW_COMMAND_QUEUE(id) \ + (((id) == PMU_COMMAND_QUEUE_HPQ) || \ + ((id) == PMU_COMMAND_QUEUE_LPQ)) + +#define PMU_IS_MESSAGE_QUEUE(id) \ + ((id) == PMU_MESSAGE_QUEUE) + +#define OFLAG_READ 0U +#define OFLAG_WRITE 1U + +#define QUEUE_SET (true) +#define QUEUE_GET (false) + +#define QUEUE_ALIGNMENT (4U) + +/* An enumeration containing all valid logical mutex identifiers */ +enum { + PMU_MUTEX_ID_RSVD1 = 0, + PMU_MUTEX_ID_GPUSER, + PMU_MUTEX_ID_QUEUE_BIOS, + PMU_MUTEX_ID_QUEUE_SMI, + PMU_MUTEX_ID_GPMUTEX, + PMU_MUTEX_ID_I2C, + PMU_MUTEX_ID_RMLOCK, + PMU_MUTEX_ID_MSGBOX, + PMU_MUTEX_ID_FIFO, + PMU_MUTEX_ID_PG, + PMU_MUTEX_ID_GR, + PMU_MUTEX_ID_CLK, + PMU_MUTEX_ID_RSVD6, + PMU_MUTEX_ID_RSVD7, + PMU_MUTEX_ID_RSVD8, + PMU_MUTEX_ID_RSVD9, + PMU_MUTEX_ID_INVALID +}; + +#define PMU_MUTEX_ID_IS_VALID(id) \ + ((id) < PMU_MUTEX_ID_INVALID) + +#define PMU_INVALID_MUTEX_OWNER_ID (0) + +/* + * The PMU's frame-buffer interface block has several slots/indices + * which can be bound to support DMA to various surfaces in memory + */ +enum { + PMU_DMAIDX_UCODE = 0, + PMU_DMAIDX_VIRT = 1, + PMU_DMAIDX_PHYS_VID = 2, + PMU_DMAIDX_PHYS_SYS_COH = 3, + PMU_DMAIDX_PHYS_SYS_NCOH = 4, + PMU_DMAIDX_RSVD = 5, + PMU_DMAIDX_PELPG = 6, + PMU_DMAIDX_END = 7 +}; + +/* + * Falcon PMU DMA's minimum size in bytes. + */ +#define PMU_DMA_MIN_READ_SIZE_BYTES 16 +#define PMU_DMA_MIN_WRITE_SIZE_BYTES 4 + +#define PMU_FB_COPY_RW_ALIGNMENT \ + ((PMU_DMA_MIN_READ_SIZE_BYTES > PMU_DMA_MIN_WRITE_SIZE_BYTES) ? \ + PMU_DMA_MIN_READ_SIZE_BYTES : PMU_DMA_MIN_WRITE_SIZE_BYTES) + +/* + * Macros to make aligned versions of RM_PMU_XXX structures. PMU needs aligned + * data structures to issue DMA read/write operations. + */ +#define NV_PMU_MAKE_ALIGNED_STRUCT(name, size) \ +union name##_aligned { \ + struct name data; \ + u8 pad[ALIGN_UP(sizeof(struct name), \ + (PMU_FB_COPY_RW_ALIGNMENT))]; \ +} + +#define NV_PMU_MAKE_ALIGNED_UNION(name, size) \ +union name##_aligned { \ + union name data; \ + u8 pad[ALIGN_UP(sizeof(union name), \ + (PMU_FB_COPY_RW_ALIGNMENT))]; \ +} + +/* RPC (Remote Procedure Call) header structure */ +#define NV_PMU_RPC_FLAGS_TYPE_SYNC 0x00000000 + +struct nv_pmu_rpc_header { + /* Identifies the unit servicing requested RPC*/ + u8 unit_id; + /* Identifies the requested RPC (within the unit)*/ + u8 function; + /* RPC call flags (@see PMU_RPC_FLAGS) */ + u8 flags; + /* Falcon's status code to describe failures*/ + u8 flcn_status; + /* RPC's total exec. time (measured on nvgpu driver side)*/ + u32 exec_time_nv_ns; + /* RPC's actual exec. time (measured on PMU side)*/ + u32 exec_time_pmu_ns; +}; + +#endif /* NVGPU_PMUIF_GPMUIF_CMN_H*/ diff --git a/include/nvgpu/pmuif/gpmuif_perfmon.h b/include/nvgpu/pmuif/gpmuif_perfmon.h new file mode 100644 index 0000000..8324e36 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuif_perfmon.h @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_GPMUIF_PERFMON_H +#define NVGPU_PMUIF_GPMUIF_PERFMON_H + +/*perfmon task defines*/ + +#define PMU_DOMAIN_GROUP_PSTATE 0 +#define PMU_DOMAIN_GROUP_GPC2CLK 1 +#define PMU_DOMAIN_GROUP_NUM 2 + +#define PMU_PERFMON_FLAG_ENABLE_INCREASE (0x00000001) +#define PMU_PERFMON_FLAG_ENABLE_DECREASE (0x00000002) +#define PMU_PERFMON_FLAG_CLEAR_PREV (0x00000004) + +#define NV_PMU_PERFMON_MAX_COUNTERS 10U + +enum pmu_perfmon_cmd_start_fields { + COUNTER_ALLOC +}; + +enum { + PMU_PERFMON_CMD_ID_START = 0, + PMU_PERFMON_CMD_ID_STOP = 1, + PMU_PERFMON_CMD_ID_INIT = 2 +}; + +struct pmu_perfmon_counter_v2 { + u8 index; + u8 flags; + u8 group_id; + u8 valid; + u16 upper_threshold; /* units of 0.01% */ + u16 lower_threshold; /* units of 0.01% */ + u32 scale; +}; + +struct pmu_perfmon_counter_v3 { + u8 index; + u8 group_id; + u16 flags; + u16 upper_threshold; /* units of 0.01% */ + u16 lower_threshold; /* units of 0.01% */ + u32 scale; +}; + +struct pmu_perfmon_cmd_start_v3 { + u8 cmd_type; + u8 group_id; + u8 state_id; + u8 flags; + struct pmu_allocation_v3 counter_alloc; +}; + +struct pmu_perfmon_cmd_start_v2 { + u8 cmd_type; + u8 group_id; + u8 state_id; + u8 flags; + struct pmu_allocation_v2 counter_alloc; +}; + +struct pmu_perfmon_cmd_start_v1 { + u8 cmd_type; + u8 group_id; + u8 state_id; + u8 flags; + struct pmu_allocation_v1 counter_alloc; +}; + +struct pmu_perfmon_cmd_stop { + u8 cmd_type; +}; + +struct pmu_perfmon_cmd_init_v3 { + u8 cmd_type; + u8 to_decrease_count; + u8 base_counter_id; + u32 sample_period_us; + struct pmu_allocation_v3 counter_alloc; + u8 num_counters; + u8 samples_in_moving_avg; + u16 sample_buffer; +}; + +struct pmu_perfmon_cmd_init_v2 { + u8 cmd_type; + u8 to_decrease_count; + u8 base_counter_id; + u32 sample_period_us; + struct pmu_allocation_v2 counter_alloc; + u8 num_counters; + u8 samples_in_moving_avg; + u16 sample_buffer; +}; + +struct pmu_perfmon_cmd_init_v1 { + u8 cmd_type; + u8 to_decrease_count; + u8 base_counter_id; + u32 sample_period_us; + struct pmu_allocation_v1 counter_alloc; + u8 num_counters; + u8 samples_in_moving_avg; + u16 sample_buffer; +}; + +struct pmu_perfmon_cmd { + union { + u8 cmd_type; + struct pmu_perfmon_cmd_start_v1 start_v1; + struct pmu_perfmon_cmd_start_v2 start_v2; + struct pmu_perfmon_cmd_start_v3 start_v3; + struct pmu_perfmon_cmd_stop stop; + struct pmu_perfmon_cmd_init_v1 init_v1; + struct pmu_perfmon_cmd_init_v2 init_v2; + struct pmu_perfmon_cmd_init_v3 init_v3; + }; +}; + +struct pmu_zbc_cmd { + u8 cmd_type; + u8 pad; + u16 entry_mask; +}; + +/* PERFMON MSG */ +enum { + PMU_PERFMON_MSG_ID_INCREASE_EVENT = 0, + PMU_PERFMON_MSG_ID_DECREASE_EVENT = 1, + PMU_PERFMON_MSG_ID_INIT_EVENT = 2, + PMU_PERFMON_MSG_ID_ACK = 3 +}; + +struct pmu_perfmon_msg_generic { + u8 msg_type; + u8 state_id; + u8 group_id; + u8 data; +}; + +struct pmu_perfmon_msg { + union { + u8 msg_type; + struct pmu_perfmon_msg_generic gen; + }; +}; + +/* PFERMON RPC interface*/ +/* + * RPC calls serviced by PERFMON unit. + */ +#define NV_PMU_RPC_ID_PERFMON_T18X_INIT 0x00 +#define NV_PMU_RPC_ID_PERFMON_T18X_DEINIT 0x01 +#define NV_PMU_RPC_ID_PERFMON_T18X_START 0x02 +#define NV_PMU_RPC_ID_PERFMON_T18X_STOP 0x03 +#define NV_PMU_RPC_ID_PERFMON_T18X_QUERY 0x04 +#define NV_PMU_RPC_ID_PERFMON_T18X__COUNT 0x05 + +/* + * structure that holds data used to + * execute Perfmon INIT RPC. + * hdr - RPC header + * sample_periodus - Desired period in between samples. + * to_decrease_count - Consecutive samples before decrease event. + * base_counter_id - Index of the base counter. + * samples_in_moving_avg - Number of values in moving average. + * num_counters - Num of counters PMU should use. + * counter - Counters. + */ +struct nv_pmu_rpc_struct_perfmon_init { + struct nv_pmu_rpc_header hdr; + u32 sample_periodus; + u8 to_decrease_count; + u8 base_counter_id; + u8 samples_in_moving_avg; + u8 num_counters; + struct pmu_perfmon_counter_v3 counter[NV_PMU_PERFMON_MAX_COUNTERS]; + u32 scratch[1]; +}; + +/* + * structure that holds data used to + * execute Perfmon START RPC. + * hdr - RPC header + * group_id - NV group ID + * state_id - NV state ID + * flags - PMU_PERFON flags + * counters - Counters. + */ +struct nv_pmu_rpc_struct_perfmon_start { + struct nv_pmu_rpc_header hdr; + u8 group_id; + u8 state_id; + u8 flags; + struct pmu_perfmon_counter_v3 counter[NV_PMU_PERFMON_MAX_COUNTERS]; + u32 scratch[1]; +}; + +/* + * structure that holds data used to + * execute Perfmon STOP RPC. + * hdr - RPC header + */ +struct nv_pmu_rpc_struct_perfmon_stop { + struct nv_pmu_rpc_header hdr; + u32 scratch[1]; +}; + +/* + * structure that holds data used to + * execute QUERY RPC. + * hdr - RPC header + * sample_buffer - Output buffer from pmu containing utilization samples. + */ +struct nv_pmu_rpc_struct_perfmon_query { + struct nv_pmu_rpc_header hdr; + u16 sample_buffer[NV_PMU_PERFMON_MAX_COUNTERS]; + u32 scratch[1]; +}; + +#endif /* NVGPU_PMUIF_GPMUIF_PERFMON_H */ diff --git a/include/nvgpu/pmuif/gpmuif_pg.h b/include/nvgpu/pmuif/gpmuif_pg.h new file mode 100644 index 0000000..69a7ea4 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuif_pg.h @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_GPMUIF_PG_H +#define NVGPU_PMUIF_GPMUIF_PG_H + +#include "gpmuif_ap.h" +#include "gpmuif_pg_rppg.h" + +/*PG defines*/ + +/* Identifier for each PG */ +#define PMU_PG_ELPG_ENGINE_ID_GRAPHICS (0x00000000U) +#define PMU_PG_ELPG_ENGINE_ID_MS (0x00000004U) +#define PMU_PG_ELPG_ENGINE_ID_INVALID_ENGINE (0x00000005U) +#define PMU_PG_ELPG_ENGINE_MAX PMU_PG_ELPG_ENGINE_ID_INVALID_ENGINE + +/* PG message */ +enum { + PMU_PG_ELPG_MSG_INIT_ACK, + PMU_PG_ELPG_MSG_DISALLOW_ACK, + PMU_PG_ELPG_MSG_ALLOW_ACK, + PMU_PG_ELPG_MSG_FREEZE_ACK, + PMU_PG_ELPG_MSG_FREEZE_ABORT, + PMU_PG_ELPG_MSG_UNFREEZE_ACK, +}; + +struct pmu_pg_msg_elpg_msg { + u8 msg_type; + u8 engine_id; + u16 msg; +}; + +enum { + PMU_PG_STAT_MSG_RESP_DMEM_OFFSET = 0, +}; + +struct pmu_pg_msg_stat { + u8 msg_type; + u8 engine_id; + u16 sub_msg_id; + u32 data; +}; + +enum { + PMU_PG_MSG_ENG_BUF_LOADED, + PMU_PG_MSG_ENG_BUF_UNLOADED, + PMU_PG_MSG_ENG_BUF_FAILED, +}; + +struct pmu_pg_msg_eng_buf_stat { + u8 msg_type; + u8 engine_id; + u8 buf_idx; + u8 status; +}; + +struct pmu_pg_msg { + union { + u8 msg_type; + struct pmu_pg_msg_elpg_msg elpg_msg; + struct pmu_pg_msg_stat stat; + struct pmu_pg_msg_eng_buf_stat eng_buf_stat; + /* TBD: other pg messages */ + union pmu_ap_msg ap_msg; + struct nv_pmu_rppg_msg rppg_msg; + }; +}; + +/* PG commands */ +enum { + PMU_PG_ELPG_CMD_INIT, + PMU_PG_ELPG_CMD_DISALLOW, + PMU_PG_ELPG_CMD_ALLOW, + PMU_PG_ELPG_CMD_FREEZE, + PMU_PG_ELPG_CMD_UNFREEZE, +}; + +enum { + PMU_PG_CMD_ID_ELPG_CMD = 0, + PMU_PG_CMD_ID_ENG_BUF_LOAD, + PMU_PG_CMD_ID_ENG_BUF_UNLOAD, + PMU_PG_CMD_ID_PG_STAT, + PMU_PG_CMD_ID_PG_LOG_INIT, + PMU_PG_CMD_ID_PG_LOG_FLUSH, + PMU_PG_CMD_ID_PG_PARAM, + PMU_PG_CMD_ID_ELPG_INIT, + PMU_PG_CMD_ID_ELPG_POLL_CTXSAVE, + PMU_PG_CMD_ID_ELPG_ABORT_POLL, + PMU_PG_CMD_ID_ELPG_PWR_UP, + PMU_PG_CMD_ID_ELPG_DISALLOW, + PMU_PG_CMD_ID_ELPG_ALLOW, + PMU_PG_CMD_ID_AP, + RM_PMU_PG_CMD_ID_PSI, + RM_PMU_PG_CMD_ID_CG, + PMU_PG_CMD_ID_ZBC_TABLE_UPDATE, + PMU_PG_CMD_ID_PWR_RAIL_GATE_DISABLE = 0x20, + PMU_PG_CMD_ID_PWR_RAIL_GATE_ENABLE, + PMU_PG_CMD_ID_PWR_RAIL_SMU_MSG_DISABLE, + PMU_PMU_PG_CMD_ID_RPPG = 0x24, +}; + +enum { + PMU_PG_STAT_CMD_ALLOC_DMEM = 0, +}; + +enum { + SLOWDOWN_FACTOR_FPDIV_BY1 = 0, + SLOWDOWN_FACTOR_FPDIV_BY1P5, + SLOWDOWN_FACTOR_FPDIV_BY2, + SLOWDOWN_FACTOR_FPDIV_BY2P5, + SLOWDOWN_FACTOR_FPDIV_BY3, + SLOWDOWN_FACTOR_FPDIV_BY3P5, + SLOWDOWN_FACTOR_FPDIV_BY4, + SLOWDOWN_FACTOR_FPDIV_BY4P5, + SLOWDOWN_FACTOR_FPDIV_BY5, + SLOWDOWN_FACTOR_FPDIV_BY5P5, + SLOWDOWN_FACTOR_FPDIV_BY6, + SLOWDOWN_FACTOR_FPDIV_BY6P5, + SLOWDOWN_FACTOR_FPDIV_BY7, + SLOWDOWN_FACTOR_FPDIV_BY7P5, + SLOWDOWN_FACTOR_FPDIV_BY8, + SLOWDOWN_FACTOR_FPDIV_BY8P5, + SLOWDOWN_FACTOR_FPDIV_BY9, + SLOWDOWN_FACTOR_FPDIV_BY9P5, + SLOWDOWN_FACTOR_FPDIV_BY10, + SLOWDOWN_FACTOR_FPDIV_BY10P5, + SLOWDOWN_FACTOR_FPDIV_BY11, + SLOWDOWN_FACTOR_FPDIV_BY11P5, + SLOWDOWN_FACTOR_FPDIV_BY12, + SLOWDOWN_FACTOR_FPDIV_BY12P5, + SLOWDOWN_FACTOR_FPDIV_BY13, + SLOWDOWN_FACTOR_FPDIV_BY13P5, + SLOWDOWN_FACTOR_FPDIV_BY14, + SLOWDOWN_FACTOR_FPDIV_BY14P5, + SLOWDOWN_FACTOR_FPDIV_BY15, + SLOWDOWN_FACTOR_FPDIV_BY15P5, + SLOWDOWN_FACTOR_FPDIV_BY16, + SLOWDOWN_FACTOR_FPDIV_BY16P5, + SLOWDOWN_FACTOR_FPDIV_BY17 = 0x20, + SLOWDOWN_FACTOR_FPDIV_BY18 = 0x22, + SLOWDOWN_FACTOR_FPDIV_BY19 = 0x24, + SLOWDOWN_FACTOR_FPDIV_BY20 = 0x26, + SLOWDOWN_FACTOR_FPDIV_BY21 = 0x28, + SLOWDOWN_FACTOR_FPDIV_BY22 = 0x2a, + SLOWDOWN_FACTOR_FPDIV_BY23 = 0x2c, + SLOWDOWN_FACTOR_FPDIV_BY24 = 0x2e, + SLOWDOWN_FACTOR_FPDIV_BY25 = 0x30, + SLOWDOWN_FACTOR_FPDIV_BY26 = 0x32, + SLOWDOWN_FACTOR_FPDIV_BY27 = 0x34, + SLOWDOWN_FACTOR_FPDIV_BY28 = 0x36, + SLOWDOWN_FACTOR_FPDIV_BY29 = 0x38, + SLOWDOWN_FACTOR_FPDIV_BY30 = 0x3a, + SLOWDOWN_FACTOR_FPDIV_BY31 = 0x3c, + SLOWDOWN_FACTOR_FPDIV_BYMAX, +}; + +#define PMU_PG_PARAM_CMD_GR_INIT_PARAM 0x0U +#define PMU_PG_PARAM_CMD_MS_INIT_PARAM 0x01U +#define PMU_PG_PARAM_CMD_MCLK_CHANGE 0x04U +#define PMU_PG_PARAM_CMD_POST_INIT 0x06U +#define PMU_PG_PARAM_CMD_SUB_FEATURE_MASK_UPDATE 0x07U + +#define NVGPU_PMU_GR_FEATURE_MASK_SDIV_SLOWDOWN BIT32(0) +#define NVGPU_PMU_GR_FEATURE_MASK_POWER_GATING BIT32(2) +#define NVGPU_PMU_GR_FEATURE_MASK_RPPG BIT32(3) +#define NVGPU_PMU_GR_FEATURE_MASK_PRIV_RING BIT32(5) +#define NVGPU_PMU_GR_FEATURE_MASK_UNBIND BIT32(6) +#define NVGPU_PMU_GR_FEATURE_MASK_SAVE_GLOBAL_STATE BIT32(7) +#define NVGPU_PMU_GR_FEATURE_MASK_RESET_ENTRY BIT32(8) +#define NVGPU_PMU_GR_FEATURE_MASK_HW_SEQUENCE BIT32(9) +#define NVGPU_PMU_GR_FEATURE_MASK_ELPG_SRAM BIT32(10) +#define NVGPU_PMU_GR_FEATURE_MASK_ELPG_LOGIC BIT32(11) +#define NVGPU_PMU_GR_FEATURE_MASK_ELPG_L2RPPG BIT32(12) + +#define NVGPU_PMU_GR_FEATURE_MASK_ALL \ + ( \ + NVGPU_PMU_GR_FEATURE_MASK_SDIV_SLOWDOWN |\ + NVGPU_PMU_GR_FEATURE_MASK_POWER_GATING |\ + NVGPU_PMU_GR_FEATURE_MASK_RPPG |\ + NVGPU_PMU_GR_FEATURE_MASK_PRIV_RING |\ + NVGPU_PMU_GR_FEATURE_MASK_UNBIND |\ + NVGPU_PMU_GR_FEATURE_MASK_SAVE_GLOBAL_STATE |\ + NVGPU_PMU_GR_FEATURE_MASK_RESET_ENTRY |\ + NVGPU_PMU_GR_FEATURE_MASK_HW_SEQUENCE |\ + NVGPU_PMU_GR_FEATURE_MASK_ELPG_SRAM |\ + NVGPU_PMU_GR_FEATURE_MASK_ELPG_LOGIC |\ + NVGPU_PMU_GR_FEATURE_MASK_ELPG_L2RPPG \ + ) + +#define NVGPU_PMU_MS_FEATURE_MASK_CLOCK_GATING BIT32(0) +#define NVGPU_PMU_MS_FEATURE_MASK_SW_ASR BIT32(1) +#define NVGPU_PMU_MS_FEATURE_MASK_RPPG BIT32(8) +#define NVGPU_PMU_MS_FEATURE_MASK_FB_TRAINING BIT32(5) + +#define NVGPU_PMU_MS_FEATURE_MASK_ALL \ + ( \ + NVGPU_PMU_MS_FEATURE_MASK_CLOCK_GATING |\ + NVGPU_PMU_MS_FEATURE_MASK_SW_ASR |\ + NVGPU_PMU_MS_FEATURE_MASK_RPPG |\ + NVGPU_PMU_MS_FEATURE_MASK_FB_TRAINING \ + ) + + +struct pmu_pg_cmd_elpg_cmd { + u8 cmd_type; + u8 engine_id; + u16 cmd; +}; + +struct pmu_pg_cmd_eng_buf_load_v0 { + u8 cmd_type; + u8 engine_id; + u8 buf_idx; + u8 pad; + u16 buf_size; + u32 dma_base; + u8 dma_offset; + u8 dma_idx; +}; + +struct pmu_pg_cmd_eng_buf_load_v1 { + u8 cmd_type; + u8 engine_id; + u8 buf_idx; + u8 pad; + struct flcn_mem_desc { + struct falc_u64 dma_addr; + u16 dma_size; + u8 dma_idx; + } dma_desc; +}; + +struct pmu_pg_cmd_eng_buf_load_v2 { + u8 cmd_type; + u8 engine_id; + u8 buf_idx; + u8 pad; + struct flcn_mem_desc_v0 dma_desc; +}; + +struct pmu_pg_cmd_gr_init_param { + u8 cmd_type; + u16 sub_cmd_id; + u8 featuremask; +}; + +struct pmu_pg_cmd_gr_init_param_v2 { + u8 cmd_type; + u16 sub_cmd_id; + u8 featuremask; + u8 ldiv_slowdown_factor; +}; + +struct pmu_pg_cmd_gr_init_param_v1 { + u8 cmd_type; + u16 sub_cmd_id; + u32 featuremask; +}; + +struct pmu_pg_cmd_sub_feature_mask_update { + u8 cmd_type; + u16 sub_cmd_id; + u8 ctrl_id; + u32 enabled_mask; +}; + +struct pmu_pg_cmd_ms_init_param { + u8 cmd_type; + u16 cmd_id; + u8 psi; + u8 idle_flipped_test_enabled; + u16 psiSettleTimeUs; + u8 rsvd[2]; + u32 support_mask; + u32 abort_timeout_us; +}; + +struct pmu_pg_cmd_mclk_change { + u8 cmd_type; + u16 cmd_id; + u8 rsvd; + u32 data; +}; + +#define PG_VOLT_RAIL_IDX_MAX 2 + +struct pmu_pg_volt_rail { + u8 volt_rail_idx; + u8 sleep_volt_dev_idx; + u8 sleep_vfe_idx; + u32 sleep_voltage_uv; + u32 therm_vid0_cache; + u32 therm_vid1_cache; +}; + +struct pmu_pg_cmd_post_init_param { + u8 cmd_type; + u16 cmd_id; + struct pmu_pg_volt_rail pg_volt_rail[PG_VOLT_RAIL_IDX_MAX]; +}; + +struct pmu_pg_cmd_stat { + u8 cmd_type; + u8 engine_id; + u16 sub_cmd_id; + u32 data; +}; + +struct pmu_pg_cmd { + union { + u8 cmd_type; + struct pmu_pg_cmd_elpg_cmd elpg_cmd; + struct pmu_pg_cmd_eng_buf_load_v0 eng_buf_load_v0; + struct pmu_pg_cmd_eng_buf_load_v1 eng_buf_load_v1; + struct pmu_pg_cmd_eng_buf_load_v2 eng_buf_load_v2; + struct pmu_pg_cmd_stat stat; + struct pmu_pg_cmd_gr_init_param gr_init_param; + struct pmu_pg_cmd_gr_init_param_v1 gr_init_param_v1; + struct pmu_pg_cmd_gr_init_param_v2 gr_init_param_v2; + struct pmu_pg_cmd_ms_init_param ms_init_param; + struct pmu_pg_cmd_mclk_change mclk_change; + struct pmu_pg_cmd_post_init_param post_init; + /* TBD: other pg commands */ + union pmu_ap_cmd ap_cmd; + struct nv_pmu_rppg_cmd rppg_cmd; + struct pmu_pg_cmd_sub_feature_mask_update sf_mask_update; + }; +}; + +/* Statistics structure for PG features */ +struct pmu_pg_stats_v2 { + u32 entry_count; + u32 exit_count; + u32 abort_count; + u32 detection_count; + u32 prevention_activate_count; + u32 prevention_deactivate_count; + u32 powered_up_time_us; + u32 entry_latency_us; + u32 exit_latency_us; + u32 resident_time_us; + u32 entry_latency_avg_us; + u32 exit_latency_avg_us; + u32 entry_latency_max_us; + u32 exit_latency_max_us; + u32 total_sleep_time_us; + u32 total_non_sleep_time_us; +}; + +struct pmu_pg_stats_v1 { + /* 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; + /* + * Time for which GPU was neither in Sleep state not + * executing sleep sequence. + */ + u32 poweredup_timeus; + /* Entry and exit latency of current sleep cycle */ + u32 entry_latency_us; + u32 exitlatencyus; + /* Resident time for current sleep cycle. */ + u32 resident_timeus; + /* Rolling average entry and exit latencies */ + u32 entrylatency_avgus; + u32 exitlatency_avgus; + /* Max entry and exit latencies */ + u32 entrylatency_maxus; + u32 exitlatency_maxus; + /* Total time spent in sleep and non-sleep state */ + u32 total_sleep_timeus; + u32 total_nonsleep_timeus; +}; + +struct pmu_pg_stats { + u64 pg_entry_start_timestamp; + u64 pg_ingating_start_timestamp; + u64 pg_exit_start_timestamp; + u64 pg_ungating_start_timestamp; + u32 pg_avg_entry_time_us; + u32 pg_ingating_cnt; + u32 pg_ingating_time_us; + u32 pg_avg_exit_time_us; + u32 pg_ungating_count; + u32 pg_ungating_time_us; + u32 pg_gating_cnt; + u32 pg_gating_deny_cnt; +}; + +#endif /* NVGPU_PMUIF_GPMUIF_PG_H*/ diff --git a/include/nvgpu/pmuif/gpmuif_pg_rppg.h b/include/nvgpu/pmuif/gpmuif_pg_rppg.h new file mode 100644 index 0000000..05445f6 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuif_pg_rppg.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_GPMUIF_PG_RPPG_H +#define NVGPU_PMUIF_GPMUIF_PG_RPPG_H + +#define NV_PMU_RPPG_CTRL_ID_GR (0x0000) +#define NV_PMU_RPPG_CTRL_ID_MS (0x0001) +#define NV_PMU_RPPG_CTRL_ID_DI (0x0002) +#define NV_PMU_RPPG_CTRL_ID_MAX (0x0003) + +#define NV_PMU_RPPG_CTRL_MASK_ENABLE_ALL (BIT(NV_PMU_RPPG_CTRL_ID_GR) |\ + BIT(NV_PMU_RPPG_CTRL_ID_MS) |\ + BIT(NV_PMU_RPPG_CTRL_ID_DI)) + +#define NV_PMU_RPPG_CTRL_MASK_DISABLE_ALL 0 + +enum { + NV_PMU_RPPG_DOMAIN_ID_GFX = 0x0, + NV_PMU_RPPG_DOMAIN_ID_NON_GFX, +}; + +struct nv_pmu_rppg_ctrl_stats { + u32 entry_count; + u32 exit_count; +}; + +struct nv_pmu_rppg_cmd_common { + u8 cmd_type; + u8 cmd_id; +}; + +struct nv_pmu_rppg_cmd_init { + u8 cmd_type; + u8 cmd_id; +}; + +struct nv_pmu_rppg_cmd_init_ctrl { + u8 cmd_type; + u8 cmd_id; + u8 ctrl_id; + u8 domain_id; +}; + +struct nv_pmu_rppg_cmd_stats_reset { + u8 cmd_type; + u8 cmd_id; + u8 ctrl_id; +}; + +struct nv_pmu_rppg_cmd { + union { + u8 cmd_type; + struct nv_pmu_rppg_cmd_common cmn; + struct nv_pmu_rppg_cmd_init init; + struct nv_pmu_rppg_cmd_init_ctrl init_ctrl; + struct nv_pmu_rppg_cmd_stats_reset stats_reset; + }; +}; + +enum { + NV_PMU_RPPG_CMD_ID_INIT = 0x0, + NV_PMU_RPPG_CMD_ID_INIT_CTRL, + NV_PMU_RPPG_CMD_ID_STATS_RESET, +}; + + +struct nv_pmu_rppg_msg_common { + u8 msg_type; + u8 msg_id; +}; + +struct nv_pmu_rppg_msg_init_ctrl_ack { + u8 msg_type; + u8 msg_id; + u8 ctrl_id; + u32 stats_dmem_offset; +}; + +struct nv_pmu_rppg_msg { + union { + u8 msg_type; + struct nv_pmu_rppg_msg_common cmn; + struct nv_pmu_rppg_msg_init_ctrl_ack init_ctrl_ack; + }; +}; + +enum { + NV_PMU_RPPG_MSG_ID_INIT_CTRL_ACK = 0x0, +}; + +#endif /* NVGPU_PMUIF_GPMUIF_PG_RPPG_H */ diff --git a/include/nvgpu/pmuif/gpmuif_pmu.h b/include/nvgpu/pmuif/gpmuif_pmu.h new file mode 100644 index 0000000..0528bd6 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuif_pmu.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_GPMUIF_PMU_H +#define NVGPU_PMUIF_GPMUIF_PMU_H + +#include +#include "gpmuif_cmn.h" + +/* Make sure size of this structure is a multiple of 4 bytes */ +struct pmu_cmdline_args_v3 { + u32 reserved; + u32 cpu_freq_hz; + u32 falc_trace_size; + u32 falc_trace_dma_base; + u32 falc_trace_dma_idx; + u8 secure_mode; + u8 raise_priv_sec; + struct pmu_mem_v1 gc6_ctx; +}; + +struct pmu_cmdline_args_v4 { + u32 reserved; + u32 cpu_freq_hz; + u32 falc_trace_size; + struct falc_dma_addr dma_addr; + u32 falc_trace_dma_idx; + u8 secure_mode; + u8 raise_priv_sec; + struct pmu_mem_desc_v0 gc6_ctx; + u8 pad; +}; + +struct pmu_cmdline_args_v5 { + u32 cpu_freq_hz; + struct flcn_mem_desc_v0 trace_buf; + u8 secure_mode; + u8 raise_priv_sec; + struct flcn_mem_desc_v0 gc6_ctx; + struct flcn_mem_desc_v0 init_data_dma_info; + u32 dummy; +}; + +struct pmu_cmdline_args_v6 { + u32 cpu_freq_hz; + struct flcn_mem_desc_v0 trace_buf; + u8 secure_mode; + u8 raise_priv_sec; + struct flcn_mem_desc_v0 gc6_ctx; + struct flcn_mem_desc_v0 gc6_bsod_ctx; + struct flcn_mem_desc_v0 super_surface; + u32 flags; +}; + +/* GPU ID */ +#define PMU_SHA1_GID_SIGNATURE 0xA7C66AD2 +#define PMU_SHA1_GID_SIGNATURE_SIZE 4 + +#define PMU_SHA1_GID_SIZE 16 + +struct pmu_sha1_gid { + bool valid; + u8 gid[PMU_SHA1_GID_SIZE]; +}; + +struct pmu_sha1_gid_data { + u8 signature[PMU_SHA1_GID_SIGNATURE_SIZE]; + u8 gid[PMU_SHA1_GID_SIZE]; +}; + +/* PMU INIT MSG */ +enum { + PMU_INIT_MSG_TYPE_PMU_INIT = 0, +}; + +struct pmu_init_msg_pmu_v1 { + u8 msg_type; + u8 pad; + u16 os_debug_entry_point; + + struct { + u16 size; + u16 offset; + u8 index; + u8 pad; + } queue_info[PMU_QUEUE_COUNT]; + + u16 sw_managed_area_offset; + u16 sw_managed_area_size; +}; + +#define PMU_QUEUE_COUNT_FOR_V5 4 +#define PMU_QUEUE_COUNT_FOR_V4 5 +#define PMU_QUEUE_COUNT_FOR_V3 3 +#define PMU_QUEUE_HPQ_IDX_FOR_V3 0 +#define PMU_QUEUE_LPQ_IDX_FOR_V3 1 +#define PMU_QUEUE_MSG_IDX_FOR_V3 2 +#define PMU_QUEUE_MSG_IDX_FOR_V5 3 +struct pmu_init_msg_pmu_v3 { + u8 msg_type; + u8 queue_index[PMU_QUEUE_COUNT_FOR_V3]; + u16 queue_size[PMU_QUEUE_COUNT_FOR_V3]; + u16 queue_offset; + + u16 sw_managed_area_offset; + u16 sw_managed_area_size; + + u16 os_debug_entry_point; + + u8 dummy[18]; +}; + +struct pmu_init_msg_pmu_v4 { + u8 msg_type; + u8 queue_index[PMU_QUEUE_COUNT_FOR_V4]; + u16 queue_size[PMU_QUEUE_COUNT_FOR_V4]; + u16 queue_offset; + + u16 sw_managed_area_offset; + u16 sw_managed_area_size; + + u16 os_debug_entry_point; + + u8 dummy[18]; +}; + +struct pmu_init_msg_pmu_v5 { + u8 msg_type; + u8 flcn_status; + u8 queue_index[PMU_QUEUE_COUNT_FOR_V5]; + u16 queue_size[PMU_QUEUE_COUNT_FOR_V5]; + u16 queue_offset; + + u16 sw_managed_area_offset; + u16 sw_managed_area_size; + + u16 os_debug_entry_point; + + u8 dummy[18]; + u8 pad; +}; + +union pmu_init_msg_pmu { + struct pmu_init_msg_pmu_v1 v1; + struct pmu_init_msg_pmu_v3 v3; + struct pmu_init_msg_pmu_v4 v4; + struct pmu_init_msg_pmu_v5 v5; +}; + +struct pmu_init_msg { + union { + u8 msg_type; + struct pmu_init_msg_pmu_v1 pmu_init_v1; + struct pmu_init_msg_pmu_v3 pmu_init_v3; + struct pmu_init_msg_pmu_v4 pmu_init_v4; + struct pmu_init_msg_pmu_v5 pmu_init_v5; + }; +}; + +/* robust channel (RC) messages */ +enum { + PMU_RC_MSG_TYPE_UNHANDLED_CMD = 0, +}; + +struct pmu_rc_msg_unhandled_cmd { + u8 msg_type; + u8 unit_id; +}; + +struct pmu_rc_msg { + u8 msg_type; + struct pmu_rc_msg_unhandled_cmd unhandled_cmd; +}; + +#endif /* NVGPU_PMUIF_GPMUIF_PMU_H*/ diff --git a/include/nvgpu/pmuif/gpmuifbios.h b/include/nvgpu/pmuif/gpmuifbios.h new file mode 100644 index 0000000..e89fbc3 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuifbios.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_GPMUIFBIOS_H +#define NVGPU_PMUIF_GPMUIFBIOS_H + +struct nv_pmu_bios_vfield_register_segment_super { + u8 type; + u8 low_bit; + u8 high_bit; +}; + +struct nv_pmu_bios_vfield_register_segment_reg { + struct nv_pmu_bios_vfield_register_segment_super super; + u32 addr; +}; + +struct nv_pmu_bios_vfield_register_segment_index_reg { + struct nv_pmu_bios_vfield_register_segment_super super; + u32 addr; + u32 reg_index; + u32 index; +}; + +union nv_pmu_bios_vfield_register_segment { + struct nv_pmu_bios_vfield_register_segment_super super; + struct nv_pmu_bios_vfield_register_segment_reg reg; + struct nv_pmu_bios_vfield_register_segment_index_reg index_reg; +}; + + +#endif /* NVGPU_PMUIF_GPMUIFBIOS_H*/ diff --git a/include/nvgpu/pmuif/gpmuifboardobj.h b/include/nvgpu/pmuif/gpmuifboardobj.h new file mode 100644 index 0000000..47226aa --- /dev/null +++ b/include/nvgpu/pmuif/gpmuifboardobj.h @@ -0,0 +1,234 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ +#ifndef NVGPU_PMUIF_GPMUIFBOARDOBJ_H +#define NVGPU_PMUIF_GPMUIFBOARDOBJ_H + +#include +#include "ctrl/ctrlboardobj.h" + +/* board object group command id's. */ +#define NV_PMU_BOARDOBJGRP_CMD_SET 0x00U +#define NV_PMU_BOARDOBJGRP_CMD_GET_STATUS 0x01U + +#define NV_PMU_RPC_ID_CLK_BOARD_OBJ_GRP_CMD 0x00U +#define NV_PMU_RPC_ID_FAN_BOARD_OBJ_GRP_CMD 0x00U +#define NV_PMU_RPC_ID_PERF_BOARD_OBJ_GRP_CMD 0x00U +#define NV_PMU_RPC_ID_PERF_CF_BOARD_OBJ_GRP_CMD 0x00U +#define NV_PMU_RPC_ID_PMGR_BOARD_OBJ_GRP_CMD 0x00U +#define NV_PMU_RPC_ID_THERM_BOARD_OBJ_GRP_CMD 0x00U +#define NV_PMU_RPC_ID_VOLT_BOARD_OBJ_GRP_CMD 0x00U + +/* + * Base structure describing a BOARDOBJ for communication between Kernel and + * PMU. + */ +struct nv_pmu_boardobj { + u8 type; + u8 grp_idx; +}; + +/* + * Base structure describing a BOARDOBJ for Query interface between Kernel and + * PMU. + */ +struct nv_pmu_boardobj_query { + u8 type; + u8 grp_idx; +}; + +/* + * Virtual base structure describing a BOARDOBJGRP interface between Kernel and + * PMU. + */ +struct nv_pmu_boardobjgrp_super { + u8 type; + u8 class_id; + u8 obj_slots; + u8 flags; +}; + +struct nv_pmu_boardobjgrp { + struct nv_pmu_boardobjgrp_super super; + u32 obj_mask; +}; + +struct nv_pmu_boardobjgrp_e32 { + struct nv_pmu_boardobjgrp_super super; + struct ctrl_boardobjgrp_mask_e32 obj_mask; +}; + +struct nv_pmu_boardobjgrp_e255 { + struct nv_pmu_boardobjgrp_super super; + struct ctrl_boardobjgrp_mask_e255 obj_mask; +}; + +struct nv_pmu_boardobj_cmd_grp_payload { + struct pmu_allocation_v3 dmem_buf; + struct flcn_mem_desc_v0 fb; + u8 hdr_size; + u8 entry_size; +}; + +struct nv_pmu_boardobj_cmd_grp { + u8 cmd_type; + u8 pad[2]; + u8 class_id; + struct nv_pmu_boardobj_cmd_grp_payload grp; +}; + +#define NV_PMU_BOARDOBJ_GRP_ALLOC_OFFSET \ + (NV_OFFSETOF(NV_PMU_BOARDOBJ_CMD_GRP, grp)) + +struct nv_pmu_boardobj_cmd { + union { + u8 cmd_type; + struct nv_pmu_boardobj_cmd_grp grp; + struct nv_pmu_boardobj_cmd_grp grp_set; + struct nv_pmu_boardobj_cmd_grp grp_get_status; + }; +}; + +struct nv_pmu_boardobj_msg_grp { + u8 msg_type; + bool b_success; + flcn_status flcn_status; + u8 class_id; +}; + +struct nv_pmu_boardobj_msg { + union { + u8 msg_type; + struct nv_pmu_boardobj_msg_grp grp; + struct nv_pmu_boardobj_msg_grp grp_set; + struct nv_pmu_boardobj_msg_grp grp_get_status; + }; +}; + +/* +* Macro generating structures describing classes which implement +* NV_PMU_BOARDOBJGRP via the NV_PMU_BOARDBOBJ_CMD_GRP SET interface. +* +* @para _eng Name of implementing engine in which this structure is +* found. +* @param _class Class ID of Objects within Board Object Group. +* @param _slots Max number of elements this group can contain. +*/ +#define NV_PMU_BOARDOBJ_GRP_SET_MAKE(_eng, _class, _slots) \ + NV_PMU_MAKE_ALIGNED_STRUCT( \ + nv_pmu_##_eng##_##_class##_boardobjgrp_set_header, one_structure); \ + NV_PMU_MAKE_ALIGNED_UNION( \ + nv_pmu_##_eng##_##_class##_boardobj_set_union, one_union); \ + struct nv_pmu_##_eng##_##_class##_boardobj_grp_set { \ + union nv_pmu_##_eng##_##_class##_boardobjgrp_set_header_aligned hdr; \ + union nv_pmu_##_eng##_##_class##_boardobj_set_union_aligned objects[(_slots)];\ + } + +/* +* Macro generating structures describing classes which implement +* NV_PMU_BOARDOBJGRP_E32 via the NV_PMU_BOARDBOBJ_CMD_GRP SET interface. +* +* @para _eng Name of implementing engine in which this structure is +* found. +* @param _class Class ID of Objects within Board Object Group. +*/ +#define NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(_eng, _class) \ + NV_PMU_BOARDOBJ_GRP_SET_MAKE(_eng, _class, \ + CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) + +/* +* Macro generating structures describing classes which implement +* NV_PMU_BOARDOBJGRP_E255 via the NV_PMU_BOARDBOBJ_CMD_GRP SET interface. +* +* @para _eng Name of implementing engine in which this structure is +* found. +* @param _class Class ID of Objects within Board Object Group. +*/ +#define NV_PMU_BOARDOBJ_GRP_SET_MAKE_E255(_eng, _class) \ + NV_PMU_BOARDOBJ_GRP_SET_MAKE(_eng, _class, \ + CTRL_BOARDOBJGRP_E255_MAX_OBJECTS) + +/* +* Macro generating structures for querying dynamic state for classes which +* implement NV_PMU_BOARDOBJGRP via the NV_PMU_BOARDOBJ_CMD_GRP GET_STATUS +* interface. +* +* @para _eng Name of implementing engine in which this structure is +* found. +* @param _class Class ID of Objects within Board Object Group. +* @param _slots Max number of elements this group can contain. +*/ +#define NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE(_eng, _class, _slots) \ + NV_PMU_MAKE_ALIGNED_STRUCT( \ + nv_pmu_##_eng##_##_class##_boardobjgrp_get_status_header, struct); \ + NV_PMU_MAKE_ALIGNED_UNION( \ + nv_pmu_##_eng##_##_class##_boardobj_get_status_union, union); \ + struct nv_pmu_##_eng##_##_class##_boardobj_grp_get_status { \ + union nv_pmu_##_eng##_##_class##_boardobjgrp_get_status_header_aligned \ + hdr; \ + union nv_pmu_##_eng##_##_class##_boardobj_get_status_union_aligned \ + objects[(_slots)]; \ + } + +/* +* Macro generating structures for querying dynamic state for classes which +* implement NV_PMU_BOARDOBJGRP_E32 via the NV_PMU_BOARDOBJ_CMD_GRP GET_STATUS +* interface. +* +* @para _eng Name of implementing engine in which this structure is +* found. +* @param _class Class ID of Objects within Board Object Group. +*/ +#define NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(_eng, _class) \ + NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE(_eng, _class, \ + CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) + +/* +* Macro generating structures for querying dynamic state for classes which +* implement NV_PMU_BOARDOBJGRP_E255 via the NV_PMU_BOARDOBJ_CMD_GRP GET_STATUS +* interface. +* +* @para _eng Name of implementing engine in which this structure is +* found. +* @param _class Class ID of Objects within Board Object Group. +*/ +#define NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E255(_eng, _class) \ + NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE(_eng, _class, \ + CTRL_BOARDOBJGRP_E255_MAX_OBJECTS) + +/* RPC */ + +/* + * structure that holds data used to + * execute BOARD_OBJ_GRP_CMD RPC. + */ +struct nv_pmu_rpc_struct_board_obj_grp_cmd +{ + /* [IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + /* [IN] BOARDOBJGRP class IDs. */ + u8 class_id; + /* [IN] Requested command ID (@ref NV_PMU_BOARDOBJGRP_CMD_***)*/ + u8 command_id; + u32 scratch[1]; +}; + +#endif /* NVGPU_PMUIF_GPMUIFBOARDOBJ_H */ diff --git a/include/nvgpu/pmuif/gpmuifclk.h b/include/nvgpu/pmuif/gpmuifclk.h new file mode 100644 index 0000000..70a913b --- /dev/null +++ b/include/nvgpu/pmuif/gpmuifclk.h @@ -0,0 +1,573 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_PMUIF_GPMUIFCLK_H +#define NVGPU_PMUIF_GPMUIFCLK_H + +#include "ctrl/ctrlboardobj.h" +#include "ctrl/ctrlvolt.h" +#include "ctrl/ctrlperf.h" +#include "ctrl/ctrlclk.h" +#include "gpmuifboardobj.h" +#include "gpmuifvolt.h" +#include + + +/* + * Try to get gpc2clk, mclk, sys2clk, xbar2clk work for Pascal + * + * mclk is same for both + * gpc2clk is 17 for Pascal and 13 for Volta, making it 17 + * as volta uses gpcclk + * sys2clk is 20 in Pascal and 15 in Volta. + * Changing for Pascal would break nvdclk of Volta + * xbar2clk is 19 in Pascal and 14 in Volta + * Changing for Pascal would break pwrclk of Volta + */ +enum nv_pmu_clk_clkwhich { + clkwhich_gpcclk = 1, + clkwhich_xbarclk = 2, + clkwhich_sysclk = 3, + clkwhich_hubclk = 4, + clkwhich_mclk = 5, + clkwhich_hostclk = 6, + clkwhich_dispclk = 7, + clkwhich_xclk = 12, + clkwhich_gpc2clk = 17, + clkwhich_xbar2clk = 14, + clkwhich_sys2clk = 15, + clkwhich_hub2clk = 16, + clkwhich_pwrclk = 19, + clkwhich_nvdclk = 20, + clkwhich_pciegenclk = 26, +}; + +/* + * Enumeration of BOARDOBJGRP class IDs within OBJCLK. Used as "classId" + * argument for communications between Kernel and PMU via the various generic + * BOARDOBJGRP interfaces. + */ +#define NV_PMU_CLK_BOARDOBJGRP_CLASS_ID_CLK_DOMAIN 0x00 +#define NV_PMU_CLK_BOARDOBJGRP_CLASS_ID_CLK_PROG 0x01 +#define NV_PMU_CLK_BOARDOBJGRP_CLASS_ID_VIN_DEVICE 0x02 +#define NV_PMU_CLK_BOARDOBJGRP_CLASS_ID_FLL_DEVICE 0x03 +#define NV_PMU_CLK_BOARDOBJGRP_CLASS_ID_CLK_VF_POINT 0x04 +#define NV_PMU_CLK_BOARDOBJGRP_CLASS_ID_CLK_FREQ_CONTROLLER 0x05 + +/*! +* CLK_DOMAIN BOARDOBJGRP Header structure. Describes global state about the +* CLK_DOMAIN feature. +*/ +struct nv_pmu_clk_clk_domain_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e32 super; + u32 vbios_domains; + struct ctrl_boardobjgrp_mask_e32 prog_domains_mask; + struct ctrl_boardobjgrp_mask_e32 master_domains_mask; + u16 cntr_sampling_periodms; + u8 version; + bool b_override_o_v_o_c; + bool b_debug_mode; + bool b_enforce_vf_monotonicity; + bool b_enforce_vf_smoothening; + u8 volt_rails_max; + struct ctrl_clk_clk_delta deltas; +}; + +struct nv_pmu_clk_clk_domain_boardobj_set { + struct nv_pmu_boardobj super; + enum nv_pmu_clk_clkwhich domain; + u32 api_domain; + u8 perf_domain_grp_idx; +}; + +struct nv_pmu_clk_clk_domain_3x_boardobj_set { + struct nv_pmu_clk_clk_domain_boardobj_set super; + bool b_noise_aware_capable; +}; + +struct nv_pmu_clk_clk_domain_3x_fixed_boardobj_set { + struct nv_pmu_clk_clk_domain_3x_boardobj_set super; + u16 freq_mhz; +}; + +struct nv_pmu_clk_clk_domain_3x_prog_boardobj_set { + struct nv_pmu_clk_clk_domain_3x_boardobj_set super; + u8 clk_prog_idx_first; + u8 clk_prog_idx_last; + bool b_force_noise_unaware_ordering; + struct ctrl_clk_freq_delta factory_delta; + short freq_delta_min_mhz; + short freq_delta_max_mhz; + struct ctrl_clk_clk_delta deltas; +}; + +struct nv_pmu_clk_clk_domain_30_prog_boardobj_set { + struct nv_pmu_clk_clk_domain_3x_prog_boardobj_set super; + u8 noise_unaware_ordering_index; + u8 noise_aware_ordering_index; +}; + +struct nv_pmu_clk_clk_domain_3x_master_boardobj_set { + u8 rsvd; /* Stubbing for RM_PMU_BOARDOBJ_INTERFACE */ + u32 slave_idxs_mask; +}; + +struct nv_pmu_clk_clk_domain_30_master_boardobj_set { + struct nv_pmu_clk_clk_domain_30_prog_boardobj_set super; + struct nv_pmu_clk_clk_domain_3x_master_boardobj_set master; +}; + +struct nv_pmu_clk_clk_domain_3x_slave_boardobj_set { + u8 rsvd; /* Stubbing for RM_PMU_BOARDOBJ_INTERFACE */ + u8 master_idx; +}; + +struct nv_pmu_clk_clk_domain_30_slave_boardobj_set { + struct nv_pmu_clk_clk_domain_30_prog_boardobj_set super; + struct nv_pmu_clk_clk_domain_3x_slave_boardobj_set slave; +}; + +struct nv_pmu_clk_clk_domain_35_prog_boardobj_set { + struct nv_pmu_clk_clk_domain_3x_prog_boardobj_set super; + u8 pre_volt_ordering_index; + u8 post_volt_ordering_index; + u8 clk_pos; + u8 clk_vf_curve_count; +}; + +struct nv_pmu_clk_clk_domain_35_master_boardobj_set { + struct nv_pmu_clk_clk_domain_35_prog_boardobj_set super; + struct nv_pmu_clk_clk_domain_3x_master_boardobj_set master; + u32 master_slave_domains_grp_mask; +}; + + +struct nv_pmu_clk_clk_domain_35_slave_boardobj_set { + struct nv_pmu_clk_clk_domain_35_prog_boardobj_set super; + struct nv_pmu_clk_clk_domain_3x_slave_boardobj_set slave; +}; + +union nv_pmu_clk_clk_domain_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_clk_clk_domain_boardobj_set super; + struct nv_pmu_clk_clk_domain_3x_boardobj_set v3x; + struct nv_pmu_clk_clk_domain_3x_fixed_boardobj_set v3x_fixed; + struct nv_pmu_clk_clk_domain_3x_prog_boardobj_set v3x_prog; + struct nv_pmu_clk_clk_domain_30_prog_boardobj_set v30_prog; + struct nv_pmu_clk_clk_domain_30_master_boardobj_set v30_master; + struct nv_pmu_clk_clk_domain_30_slave_boardobj_set v30_slave; + struct nv_pmu_clk_clk_domain_35_prog_boardobj_set v35_prog; + struct nv_pmu_clk_clk_domain_35_master_boardobj_set v35_master; + struct nv_pmu_clk_clk_domain_35_slave_boardobj_set v35_slave; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_domain); + +struct nv_pmu_clk_clk_prog_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e255 super; + u8 slave_entry_count; + u8 vf_entry_count; +}; + +struct nv_pmu_clk_clk_prog_boardobj_set { + struct nv_pmu_boardobj super; +}; + +struct nv_pmu_clk_clk_prog_1x_boardobj_set { + struct nv_pmu_clk_clk_prog_boardobj_set super; + u8 source; + u16 freq_max_mhz; + union ctrl_clk_clk_prog_1x_source_data source_data; +}; + +struct nv_pmu_clk_clk_prog_1x_master_boardobj_set { + struct nv_pmu_clk_clk_prog_1x_boardobj_set super; + u8 rsvd; /* Stubbing for RM_PMU_BOARDOBJ_INTERFACE */ + bool b_o_c_o_v_enabled; + struct ctrl_clk_clk_prog_1x_master_vf_entry vf_entries[ + CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES]; + struct ctrl_clk_clk_delta deltas; + union ctrl_clk_clk_prog_1x_master_source_data source_data; +}; + +struct nv_pmu_clk_clk_prog_1x_master_ratio_boardobj_set { + struct nv_pmu_clk_clk_prog_1x_master_boardobj_set super; + u8 rsvd; /* Stubbing for RM_PMU_BOARDOBJ_INTERFACE */ + struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry slave_entries[ + CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES]; +}; + +struct nv_pmu_clk_clk_prog_1x_master_table_boardobj_set { + struct nv_pmu_clk_clk_prog_1x_master_boardobj_set super; + u8 rsvd; /* Stubbing for RM_PMU_BOARDOBJ_INTERFACE */ + struct ctrl_clk_clk_prog_1x_master_table_slave_entry + slave_entries[CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES]; +}; + +union nv_pmu_clk_clk_prog_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_clk_clk_prog_boardobj_set super; + struct nv_pmu_clk_clk_prog_1x_boardobj_set v1x; + struct nv_pmu_clk_clk_prog_1x_master_boardobj_set v1x_master; + struct nv_pmu_clk_clk_prog_1x_master_ratio_boardobj_set v1x_master_ratio; + struct nv_pmu_clk_clk_prog_1x_master_table_boardobj_set v1x_master_table; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E255(clk, clk_prog); + +struct nv_pmu_clk_lut_device_desc { + u8 vselect_mode; + u16 hysteresis_threshold; +}; + +struct nv_pmu_clk_regime_desc { + u8 regime_id; + u8 target_regime_id_override; + u16 fixed_freq_regime_limit_mhz; +}; + +struct nv_pmu_clk_clk_fll_device_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e32 super; + struct ctrl_boardobjgrp_mask_e32 lut_prog_master_mask; + u32 lut_step_size_uv; + u32 lut_min_voltage_uv; + u8 lut_num_entries; + u16 max_min_freq_mhz; +}; + +struct nv_pmu_clk_clk_fll_device_boardobj_set { + struct nv_pmu_boardobj super; + u8 id; + u8 mdiv; + u8 vin_idx_logic; + u8 vin_idx_sram; + u8 rail_idx_for_lut; + u16 input_freq_mhz; + u32 clk_domain; + struct nv_pmu_clk_lut_device_desc lut_device; + struct nv_pmu_clk_regime_desc regime_desc; + u8 min_freq_vfe_idx; + u8 freq_ctrl_idx; + bool b_skip_pldiv_below_dvco_min; + bool b_dvco_1x; + struct ctrl_boardobjgrp_mask_e32 lut_prog_broadcast_slave_mask; +}; + +union nv_pmu_clk_clk_fll_device_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_clk_clk_fll_device_boardobj_set super; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_fll_device); + +struct nv_pmu_clk_clk_vin_device_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e32 super; + bool b_vin_is_disable_allowed; +}; + +struct nv_pmu_clk_clk_vin_device_boardobj_set { + struct nv_pmu_boardobj super; + u8 id; + u8 volt_domain; + u32 flls_shared_mask; +}; + +struct nv_pmu_clk_clk_vin_device_v10_boardobj_set { + struct nv_pmu_clk_clk_vin_device_boardobj_set super; + struct ctrl_clk_vin_device_info_data_v10 data; +}; + +struct nv_pmu_clk_clk_vin_device_v20_boardobj_set { + struct nv_pmu_clk_clk_vin_device_boardobj_set super; + struct ctrl_clk_vin_device_info_data_v20 data; +}; + +union nv_pmu_clk_clk_vin_device_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_clk_clk_vin_device_boardobj_set super; + struct nv_pmu_clk_clk_vin_device_v10_boardobj_set v10; + struct nv_pmu_clk_clk_vin_device_v20_boardobj_set v20; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_vin_device); + +struct nv_pmu_clk_clk_vf_point_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e255 super; +}; + +struct nv_pmu_clk_clk_vf_point_boardobj_set { + struct nv_pmu_boardobj super; + u8 vfe_equ_idx; + u8 volt_rail_idx; +}; + +struct nv_pmu_clk_clk_vf_point_freq_boardobj_set { + struct nv_pmu_clk_clk_vf_point_boardobj_set super; + u16 freq_mhz; + int volt_delta_uv; +}; + +struct nv_pmu_clk_clk_vf_point_volt_boardobj_set { + struct nv_pmu_clk_clk_vf_point_boardobj_set super; + u32 source_voltage_uv; + struct ctrl_clk_freq_delta freq_delta; +}; + +union nv_pmu_clk_clk_vf_point_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_clk_clk_vf_point_boardobj_set super; + struct nv_pmu_clk_clk_vf_point_freq_boardobj_set freq; + struct nv_pmu_clk_clk_vf_point_volt_boardobj_set volt; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E255(clk, clk_vf_point); + +struct nv_pmu_clk_clk_vf_point_boardobjgrp_get_status_header { + struct nv_pmu_boardobjgrp_e255 super; + u32 vf_points_cahce_counter; +}; + +struct nv_pmu_clk_clk_vf_point_boardobj_get_status { + struct nv_pmu_boardobj super; + struct ctrl_clk_vf_pair pair; + u8 dummy[38]; +}; + +struct nv_pmu_clk_clk_vf_point_volt_boardobj_get_status { + struct nv_pmu_clk_clk_vf_point_boardobj_get_status super; + u16 vf_gain_value; +}; + +union nv_pmu_clk_clk_vf_point_boardobj_get_status_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_clk_clk_vf_point_boardobj_get_status super; + struct nv_pmu_clk_clk_vf_point_volt_boardobj_get_status volt; +}; + +NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E255(clk, clk_vf_point); + +#define NV_PMU_VF_INJECT_MAX_CLOCK_DOMAINS (12) + +struct nv_pmu_clk_clk_domain_list { + u8 num_domains; + struct ctrl_clk_clk_domain_list_item clk_domains[ + NV_PMU_VF_INJECT_MAX_CLOCK_DOMAINS]; +}; + +struct nv_pmu_clk_clk_domain_list_v1 { + u8 num_domains; + struct ctrl_clk_clk_domain_list_item_v1 clk_domains[ + NV_PMU_VF_INJECT_MAX_CLOCK_DOMAINS]; +}; + +struct nv_pmu_clk_vf_change_inject { + u8 flags; + struct nv_pmu_clk_clk_domain_list clk_list; + struct nv_pmu_volt_volt_rail_list volt_list; +}; + +struct nv_pmu_clk_vf_change_inject_v1 { + u8 flags; + struct nv_pmu_clk_clk_domain_list_v1 clk_list; + struct nv_pmu_volt_volt_rail_list_v1 volt_list; +}; + +#define NV_NV_PMU_CLK_LOAD_FEATURE_VIN (0x00000002) +#define NV_NV_PMU_CLK_LOAD_ACTION_MASK_VIN_HW_CAL_PROGRAM_YES (0x00000001) + +struct nv_pmu_clk_load_payload_freq_controllers { + struct ctrl_boardobjgrp_mask_e32 load_mask; +}; + +struct nv_pmu_clk_load { + u8 feature; + u32 action_mask; + union { + struct nv_pmu_clk_load_payload_freq_controllers freq_controllers; + } payload; +}; + +struct nv_pmu_clk_freq_effective_avg { + u32 clkDomainMask; + u32 freqkHz[CTRL_BOARDOBJ_MAX_BOARD_OBJECTS]; +}; + +/* CLK_FREQ_CONTROLLER */ +#define NV_NV_PMU_CLK_LOAD_FEATURE_FREQ_CONTROLLER (0x00000003) + +#define NV_NV_PMU_CLK_LOAD_ACTION_MASK_FREQ_CONTROLLER_CALLBACK_NO (0x00000000) +#define NV_NV_PMU_CLK_LOAD_ACTION_MASK_FREQ_CONTROLLER_CALLBACK_YES (0x00000002) + +struct nv_pmu_clk_clk_freq_controller_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e32 super; + u32 sampling_period_ms; + u8 volt_policy_idx; +}; + +struct nv_pmu_clk_clk_freq_controller_boardobj_set { + struct nv_pmu_boardobj super; + u8 controller_id; + u8 parts_freq_mode; + bool bdisable; + u32 clk_domain; + s16 freq_cap_noise_unaware_vmin_above; + s16 freq_cap_noise_unaware_vmin_below; + s16 freq_hyst_pos_mhz; + s16 freq_hyst_neg_mhz; +}; + +struct nv_pmu_clk_clk_freq_controller_pi_boardobj_set { + struct nv_pmu_clk_clk_freq_controller_boardobj_set super; + s32 prop_gain; + s32 integ_gain; + s32 integ_decay; + s32 volt_delta_min; + s32 volt_delta_max; + u8 slowdown_pct_min; + bool bpoison; +}; + +union nv_pmu_clk_clk_freq_controller_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_clk_clk_freq_controller_boardobj_set super; + struct nv_pmu_clk_clk_freq_controller_pi_boardobj_set pi; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_freq_controller); + +#define NV_NV_PMU_CLK_LOAD_FEATURE_FREQ_EFFECTIVE_AVG (0x00000004) +#define NV_NV_PMU_CLK_LOAD_ACTION_MASK_FREQ_EFFECTIVE_AVG_CALLBACK_NO (0x00000000) +#define NV_NV_PMU_CLK_LOAD_ACTION_MASK_FREQ_EFFECTIVE_AVG_CALLBACK_YES (0x00000004) + +/* CLK CMD ID definitions. */ +#define NV_PMU_CLK_CMD_ID_BOARDOBJ_GRP_SET (0x00000001) +#define NV_PMU_CLK_CMD_ID_RPC (0x00000000) +#define NV_PMU_CLK_CMD_ID_BOARDOBJ_GRP_GET_STATUS (0x00000002) + +#define NV_PMU_CLK_RPC_ID_LOAD (0x00000001) +#define NV_PMU_CLK_RPC_ID_CLK_VF_CHANGE_INJECT (0x00000000) +#define NV_PMU_CLK_RPC_ID_CLK_FREQ_EFF_AVG (0x00000002) + +struct nv_pmu_clk_cmd_rpc { + u8 cmd_type; + u8 pad[3]; + struct nv_pmu_allocation request; +}; + +struct nv_pmu_clk_cmd_generic { + u8 cmd_type; + bool b_perf_daemon_cmd; + u8 pad[2]; +}; + +#define NV_PMU_CLK_CMD_RPC_ALLOC_OFFSET \ + (offsetof(struct nv_pmu_clk_cmd_rpc, request)) + +struct nv_pmu_clk_cmd { + union { + u8 cmd_type; + struct nv_pmu_boardobj_cmd_grp grp_set; + struct nv_pmu_clk_cmd_generic generic; + struct nv_pmu_clk_cmd_rpc rpc; + struct nv_pmu_boardobj_cmd_grp grp_get_status; + }; +}; + +struct nv_pmu_clk_rpc { + u8 function; + bool b_supported; + bool b_success; + flcn_status flcn_status; + union { + struct nv_pmu_clk_vf_change_inject clk_vf_change_inject; + struct nv_pmu_clk_vf_change_inject_v1 clk_vf_change_inject_v1; + struct nv_pmu_clk_load clk_load; + struct nv_pmu_clk_freq_effective_avg clk_freq_effective_avg; + } params; +}; + +/* CLK MSG ID definitions */ +#define NV_PMU_CLK_MSG_ID_BOARDOBJ_GRP_SET (0x00000001) +#define NV_PMU_CLK_MSG_ID_RPC (0x00000000) +#define NV_PMU_CLK_MSG_ID_BOARDOBJ_GRP_GET_STATUS (0x00000002) + +struct nv_pmu_clk_msg_rpc { + u8 msg_type; + u8 rsvd[3]; + struct nv_pmu_allocation response; +}; + +#define NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET \ + offsetof(struct nv_pmu_clk_msg_rpc, response) + +struct nv_pmu_clk_msg { + union { + u8 msg_type; + struct nv_pmu_boardobj_msg_grp grp_set; + struct nv_pmu_clk_msg_rpc rpc; + struct nv_pmu_boardobj_msg_grp grp_get_status; + }; +}; + +struct nv_pmu_clk_clk_vin_device_boardobjgrp_get_status_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +struct nv_pmu_clk_clk_vin_device_boardobj_get_status { + struct nv_pmu_boardobj_query super; + u32 actual_voltage_uv; + u32 corrected_voltage_uv; + u8 sampled_code; + u8 override_code; +}; + +union nv_pmu_clk_clk_vin_device_boardobj_get_status_union { + struct nv_pmu_boardobj_query board_obj; + struct nv_pmu_clk_clk_vin_device_boardobj_get_status super; +}; + +NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(clk, clk_vin_device); + +struct nv_pmu_clk_lut_vf_entry { + u32 entry; +}; + +struct nv_pmu_clk_clk_fll_device_boardobjgrp_get_status_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +struct nv_pmu_clk_clk_fll_device_boardobj_get_status { + struct nv_pmu_boardobj_query super; + u8 current_regime_id; + bool b_dvco_min_reached; + u16 min_freq_mhz; + struct nv_pmu_clk_lut_vf_entry lut_vf_curve[NV_UNSIGNED_ROUNDED_DIV(CTRL_CLK_LUT_NUM_ENTRIES_MAX, 2)]; +}; + +union nv_pmu_clk_clk_fll_device_boardobj_get_status_union { + struct nv_pmu_boardobj_query board_obj; + struct nv_pmu_clk_clk_fll_device_boardobj_get_status super; +}; + +NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(clk, clk_fll_device); + +#endif /*NVGPU_PMUIF_GPMUIFCLK_H*/ diff --git a/include/nvgpu/pmuif/gpmuifperf.h b/include/nvgpu/pmuif/gpmuifperf.h new file mode 100644 index 0000000..70b93e1 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuifperf.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_GPMUIFPERF_H +#define NVGPU_PMUIF_GPMUIFPERF_H + +#include "gpmuifvolt.h" +#include "gpmuifperfvfe.h" + +/* +* Enumeration of BOARDOBJGRP class IDs within OBJPERF. Used as "classId" +* argument for communications between Kernel and PMU via the various generic +* BOARDOBJGRP interfaces. +*/ +#define NV_PMU_PERF_BOARDOBJGRP_CLASS_ID_VFE_VAR 0x00U +#define NV_PMU_PERF_BOARDOBJGRP_CLASS_ID_VFE_EQU 0x01U + +#define NV_PMU_PERF_CMD_ID_RPC (0x00000002U) +#define NV_PMU_PERF_CMD_ID_BOARDOBJ_GRP_SET (0x00000003U) +#define NV_PMU_PERF_CMD_ID_BOARDOBJ_GRP_GET_STATUS (0x00000004U) + +/*! + * RPC calls serviced by PERF unit. + */ +#define NV_PMU_RPC_ID_PERF_BOARD_OBJ_GRP_CMD 0x00U +#define NV_PMU_RPC_ID_PERF_LOAD 0x01U +#define NV_PMU_RPC_ID_PERF_CHANGE_SEQ_INFO_GET 0x02U +#define NV_PMU_RPC_ID_PERF_CHANGE_SEQ_INFO_SET 0x03U +#define NV_PMU_RPC_ID_PERF_CHANGE_SEQ_SET_CONTROL 0x04U +#define NV_PMU_RPC_ID_PERF_CHANGE_SEQ_QUEUE_CHANGE 0x05U +#define NV_PMU_RPC_ID_PERF_CHANGE_SEQ_LOCK 0x06U +#define NV_PMU_RPC_ID_PERF_CHANGE_SEQ_LOAD 0x07U +#define NV_PMU_RPC_ID_PERF_CHANGE_SEQ_QUERY 0x08U +#define NV_PMU_RPC_ID_PERF_PERF_LIMITS_INVALIDATE 0x09U +#define NV_PMU_RPC_ID_PERF_VFE_EQU_EVAL 0x0AU +#define NV_PMU_RPC_ID_PERF_VFE_INVALIDATE 0x0BU +#define NV_PMU_RPC_ID_PERF_VFE_EQU_MONITOR_SET 0x0CU +#define NV_PMU_RPC_ID_PERF_VFE_EQU_MONITOR_GET 0x0DU +#define NV_PMU_RPC_ID_PERF__COUNT 0x0EU +/* + * Defines the structure that holds data + * used to execute LOAD RPC. + */ +struct nv_pmu_rpc_struct_perf_load { + /*[IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + u32 scratch[1]; +}; + +struct nv_pmu_perf_cmd_set_object { + u8 cmd_type; + u8 pad[2]; + u8 object_type; + struct nv_pmu_allocation object; +}; + +#define NV_PMU_PERF_SET_OBJECT_ALLOC_OFFSET \ + (offsetof(struct nv_pmu_perf_cmd_set_object, object)) + +/* RPC IDs */ +#define NV_PMU_PERF_RPC_ID_VFE_LOAD (0x00000001U) + +/*! +* Command requesting execution of the perf RPC. +*/ +struct nv_pmu_perf_cmd_rpc { + u8 cmd_type; + u8 pad[3]; + struct nv_pmu_allocation request; +}; + +#define NV_PMU_PERF_CMD_RPC_ALLOC_OFFSET \ + offsetof(struct nv_pmu_perf_cmd_rpc, request) + +/*! +* Simply a union of all specific PERF commands. Forms the general packet +* exchanged between the Kernel and PMU when sending and receiving PERF commands +* (respectively). +*/ +struct nv_pmu_perf_cmd { + union { + u8 cmd_type; + struct nv_pmu_perf_cmd_set_object set_object; + struct nv_pmu_boardobj_cmd_grp grp_set; + struct nv_pmu_boardobj_cmd_grp grp_get_status; + }; +}; + +/*! +* Defines the data structure used to invoke PMU perf RPCs. Same structure is +* used to return the result of the RPC execution. +*/ +struct nv_pmu_perf_rpc { + u8 function; + bool b_supported; + bool b_success; + flcn_status flcn_status; + union { + struct nv_pmu_perf_rpc_vfe_equ_eval vfe_equ_eval; + struct nv_pmu_perf_rpc_vfe_load vfe_load; + } params; +}; + + +/* PERF Message-type Definitions */ +#define NV_PMU_PERF_MSG_ID_RPC (0x00000003U) +#define NV_PMU_PERF_MSG_ID_BOARDOBJ_GRP_SET (0x00000004U) +#define NV_PMU_PERF_MSG_ID_BOARDOBJ_GRP_GET_STATUS (0x00000006U) +#define NV_PMU_PERF_MSG_ID_VFE_CALLBACK (0x00000005U) + +/*! +* Message carrying the result of the perf RPC execution. +*/ +struct nv_pmu_perf_msg_rpc { + u8 msg_type; + u8 rsvd[3]; + struct nv_pmu_allocation response; +}; + +#define NV_PMU_PERF_MSG_RPC_ALLOC_OFFSET \ + (offsetof(struct nv_pmu_perf_msg_rpc, response)) + +/*! +* Simply a union of all specific PERF messages. Forms the general packet +* exchanged between the Kernel and PMU when sending and receiving PERF messages +* (respectively). +*/ +struct nv_pmu_perf_msg { + union { + u8 msg_type; + struct nv_pmu_perf_msg_rpc rpc; + struct nv_pmu_boardobj_msg_grp grp_set; + }; +}; + +#endif /* NVGPU_PMUIF_GPMUIFPERF_H*/ diff --git a/include/nvgpu/pmuif/gpmuifperfvfe.h b/include/nvgpu/pmuif/gpmuifperfvfe.h new file mode 100644 index 0000000..d128c32 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuifperfvfe.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_GPMUIFPERFVFE_H +#define NVGPU_PMUIF_GPMUIFPERFVFE_H + +#include "gpmuifbios.h" +#include "gpmuifboardobj.h" +#include "ctrl/ctrlperf.h" + +#define CTRL_PERF_VFE_EQU_QUADRATIC_COEFF_COUNT 0x03 +#define NV_PMU_PERF_RPC_VFE_EQU_EVAL_VAR_COUNT_MAX 2 +#define NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX 16 + +struct nv_pmu_perf_vfe_var_value { + u8 var_type; + u8 reserved[3]; + u32 var_value; +}; + +union nv_pmu_perf_vfe_equ_result { + u32 freq_m_hz; + u32 voltu_v; + u32 vf_gain; + int volt_deltau_v; +}; + +struct nv_pmu_perf_rpc_vfe_equ_eval { + u8 equ_idx; + u8 var_count; + u8 output_type; + struct nv_pmu_perf_vfe_var_value var_values[ + NV_PMU_PERF_RPC_VFE_EQU_EVAL_VAR_COUNT_MAX]; + union nv_pmu_perf_vfe_equ_result result; +}; + +struct nv_pmu_perf_rpc_vfe_load { + bool b_load; +}; + +struct nv_pmu_perf_vfe_var_boardobjgrp_get_status_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +struct nv_pmu_perf_vfe_var_get_status_super { + struct nv_pmu_boardobj_query board_obj; +}; + +struct nv_pmu_perf_vfe_var_single_sensed_fuse_get_status { + struct nv_pmu_perf_vfe_var_get_status_super super; + struct ctrl_perf_vfe_var_single_sensed_fuse_value fuse_value_integer; + struct ctrl_perf_vfe_var_single_sensed_fuse_value fuse_value_hw_integer; + u8 fuse_version; + bool b_version_check_failed; +}; + +union nv_pmu_perf_vfe_var_boardobj_get_status_union { + struct nv_pmu_boardobj_query board_obj; + struct nv_pmu_perf_vfe_var_get_status_super super; + struct nv_pmu_perf_vfe_var_single_sensed_fuse_get_status fuse_status; +}; + +NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(perf, vfe_var); + +struct nv_pmu_vfe_var { + struct nv_pmu_boardobj super; + u32 out_range_min; + u32 out_range_max; + struct ctrl_boardobjgrp_mask_e32 mask_dependent_vars; + struct ctrl_boardobjgrp_mask_e255 mask_dependent_equs; +}; + +struct nv_pmu_vfe_var_derived { + struct nv_pmu_vfe_var super; +}; + +struct nv_pmu_vfe_var_derived_product { + struct nv_pmu_vfe_var_derived super; + u8 var_idx0; + u8 var_idx1; +}; + +struct nv_pmu_vfe_var_derived_sum { + struct nv_pmu_vfe_var_derived super; + u8 var_idx0; + u8 var_idx1; +}; + +struct nv_pmu_vfe_var_single { + struct nv_pmu_vfe_var super; + u8 override_type; + u32 override_value; +}; + +struct nv_pmu_vfe_var_single_frequency { + struct nv_pmu_vfe_var_single super; +}; + +struct nv_pmu_vfe_var_single_sensed { + struct nv_pmu_vfe_var_single super; +}; + +struct nv_pmu_vfe_var_single_sensed_fuse { + struct nv_pmu_vfe_var_single_sensed super; + struct ctrl_perf_vfe_var_single_sensed_fuse_override_info override_info; + struct ctrl_perf_vfe_var_single_sensed_fuse_vfield_info vfield_info; + struct ctrl_perf_vfe_var_single_sensed_fuse_ver_vfield_info vfield_ver_info; + struct ctrl_perf_vfe_var_single_sensed_fuse_value fuse_val_default; + bool b_fuse_value_signed; +}; + +struct nv_pmu_vfe_var_single_sensed_temp { + struct nv_pmu_vfe_var_single_sensed super; + u8 therm_channel_index; + int temp_hysteresis_positive; + int temp_hysteresis_negative; + int temp_default; +}; + +struct nv_pmu_vfe_var_single_voltage { + struct nv_pmu_vfe_var_single super; +}; + +struct nv_pmu_perf_vfe_var_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e32 super; + u8 polling_periodms; +}; + +union nv_pmu_perf_vfe_var_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_vfe_var var; + struct nv_pmu_vfe_var_derived var_derived; + struct nv_pmu_vfe_var_derived_product var_derived_product; + struct nv_pmu_vfe_var_derived_sum var_derived_sum; + struct nv_pmu_vfe_var_single var_single; + struct nv_pmu_vfe_var_single_frequency var_single_frequiency; + struct nv_pmu_vfe_var_single_sensed var_single_sensed; + struct nv_pmu_vfe_var_single_sensed_fuse var_single_sensed_fuse; + struct nv_pmu_vfe_var_single_sensed_temp var_single_sensed_temp; + struct nv_pmu_vfe_var_single_voltage var_single_voltage; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(perf, vfe_var); + +struct nv_pmu_vfe_equ { + struct nv_pmu_boardobj super; + u8 var_idx; + u8 equ_idx_next; + u8 output_type; + u32 out_range_min; + u32 out_range_max; +}; + +struct nv_pmu_vfe_equ_compare { + struct nv_pmu_vfe_equ super; + u8 func_id; + u8 equ_idx_true; + u8 equ_idx_false; + u32 criteria; +}; + +struct nv_pmu_vfe_equ_minmax { + struct nv_pmu_vfe_equ super; + bool b_max; + u8 equ_idx0; + u8 equ_idx1; +}; + +struct nv_pmu_vfe_equ_quadratic { + struct nv_pmu_vfe_equ super; + u32 coeffs[CTRL_PERF_VFE_EQU_QUADRATIC_COEFF_COUNT]; +}; + +struct nv_pmu_perf_vfe_equ_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e255 super; +}; + +union nv_pmu_perf_vfe_equ_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_vfe_equ equ; + struct nv_pmu_vfe_equ_compare equ_comapre; + struct nv_pmu_vfe_equ_minmax equ_minmax; + struct nv_pmu_vfe_equ_quadratic equ_quadratic; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E255(perf, vfe_equ); + +#endif /* NVGPU_PMUIF_GPMUIFPERFVFE_H*/ diff --git a/include/nvgpu/pmuif/gpmuifpmgr.h b/include/nvgpu/pmuif/gpmuifpmgr.h new file mode 100644 index 0000000..a0e6c82 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuifpmgr.h @@ -0,0 +1,443 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_PMUIF_GPMUIFPMGR_H +#define NVGPU_PMUIF_GPMUIFPMGR_H + +#include "ctrl/ctrlpmgr.h" +#include "gpmuifboardobj.h" +#include + +struct nv_pmu_pmgr_i2c_device_desc { + struct nv_pmu_boardobj super; + u8 dcb_index; + u16 i2c_address; + u32 i2c_flags; + u8 i2c_port; +}; + +#define NV_PMU_PMGR_I2C_DEVICE_DESC_TABLE_MAX_DEVICES (32U) + +struct nv_pmu_pmgr_i2c_device_desc_table { + u32 dev_mask; + struct nv_pmu_pmgr_i2c_device_desc + devices[NV_PMU_PMGR_I2C_DEVICE_DESC_TABLE_MAX_DEVICES]; +}; + +struct nv_pmu_pmgr_pwr_device_desc { + struct nv_pmu_boardobj super; + u32 power_corr_factor; +}; + +#define NV_PMU_PMGR_PWR_DEVICE_INA3221_CH_NUM 0x03U + +struct nv_pmu_pmgr_pwr_device_desc_ina3221 { + struct nv_pmu_pmgr_pwr_device_desc super; + u8 i2c_dev_idx; + struct ctrl_pmgr_pwr_device_info_rshunt + r_shuntm_ohm[NV_PMU_PMGR_PWR_DEVICE_INA3221_CH_NUM]; + u16 configuration; + u16 mask_enable; + u32 event_mask; + u16 curr_correct_m; + s16 curr_correct_b; +}; + +union nv_pmu_pmgr_pwr_device_desc_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_pmgr_pwr_device_desc pwr_dev; + struct nv_pmu_pmgr_pwr_device_desc_ina3221 ina3221; +}; + +struct nv_pmu_pmgr_pwr_device_ba_info { + bool b_initialized_and_used; +}; + +struct nv_pmu_pmgr_pwr_device_desc_table_header { + struct nv_pmu_boardobjgrp_e32 super; + struct nv_pmu_pmgr_pwr_device_ba_info ba_info; +}; + +NV_PMU_MAKE_ALIGNED_STRUCT(nv_pmu_pmgr_pwr_device_desc_table_header, + sizeof(struct nv_pmu_pmgr_pwr_device_desc_table_header)); +NV_PMU_MAKE_ALIGNED_UNION(nv_pmu_pmgr_pwr_device_desc_union, + sizeof(union nv_pmu_pmgr_pwr_device_desc_union)); + +struct nv_pmu_pmgr_pwr_device_desc_table { + union nv_pmu_pmgr_pwr_device_desc_table_header_aligned hdr; + union nv_pmu_pmgr_pwr_device_desc_union_aligned + devices[CTRL_PMGR_PWR_DEVICES_MAX_DEVICES]; +}; + +union nv_pmu_pmgr_pwr_device_dmem_size { + union nv_pmu_pmgr_pwr_device_desc_table_header_aligned pwr_device_hdr; + union nv_pmu_pmgr_pwr_device_desc_union_aligned pwr_device; +}; + +struct nv_pmu_pmgr_pwr_channel { + struct nv_pmu_boardobj super; + u8 pwr_rail; + u8 ch_idx; + u32 volt_fixedu_v; + u32 pwr_corr_slope; + s32 pwr_corr_offsetm_w; + u32 curr_corr_slope; + s32 curr_corr_offsetm_a; + u32 dependent_ch_mask; +}; + +#define NV_PMU_PMGR_PWR_CHANNEL_MAX_CHANNELS 16U + +#define NV_PMU_PMGR_PWR_CHANNEL_MAX_CHRELATIONSHIPS 16U + +struct nv_pmu_pmgr_pwr_channel_sensor { + struct nv_pmu_pmgr_pwr_channel super; + u8 pwr_dev_idx; + u8 pwr_dev_prov_idx; +}; + +struct nv_pmu_pmgr_pwr_channel_pmu_compactible { + u8 pmu_compactible_data[56]; +}; + +union nv_pmu_pmgr_pwr_channel_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_pmgr_pwr_channel pwr_channel; + struct nv_pmu_pmgr_pwr_channel_sensor sensor; + struct nv_pmu_pmgr_pwr_channel_pmu_compactible pmu_pwr_channel; +}; + +#define NV_PMU_PMGR_PWR_MONITOR_TYPE_NO_POLLING 0x02U + +struct nv_pmu_pmgr_pwr_monitor_pstate { + u32 hw_channel_mask; +}; + +union nv_pmu_pmgr_pwr_monitor_type_specific { + struct nv_pmu_pmgr_pwr_monitor_pstate pstate; +}; + +struct nv_pmu_pmgr_pwr_chrelationship_pmu_compactible { + u8 pmu_compactible_data[28]; +}; + +union nv_pmu_pmgr_pwr_chrelationship_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_pmgr_pwr_chrelationship_pmu_compactible pmu_pwr_chrelationship; +}; + +struct nv_pmu_pmgr_pwr_channel_header { + struct nv_pmu_boardobjgrp_e32 super; + u8 type; + union nv_pmu_pmgr_pwr_monitor_type_specific type_specific; + u8 sample_count; + u16 sampling_periodms; + u16 sampling_period_low_powerms; + u32 total_gpu_power_channel_mask; + u32 physical_channel_mask; +}; + +struct nv_pmu_pmgr_pwr_chrelationship_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +NV_PMU_MAKE_ALIGNED_STRUCT(nv_pmu_pmgr_pwr_channel_header, + sizeof(struct nv_pmu_pmgr_pwr_channel_header)); +NV_PMU_MAKE_ALIGNED_STRUCT(nv_pmu_pmgr_pwr_chrelationship_header, + sizeof(struct nv_pmu_pmgr_pwr_chrelationship_header)); +NV_PMU_MAKE_ALIGNED_UNION(nv_pmu_pmgr_pwr_chrelationship_union, + sizeof(union nv_pmu_pmgr_pwr_chrelationship_union)); +NV_PMU_MAKE_ALIGNED_UNION(nv_pmu_pmgr_pwr_channel_union, + sizeof(union nv_pmu_pmgr_pwr_channel_union)); + +struct nv_pmu_pmgr_pwr_channel_desc { + union nv_pmu_pmgr_pwr_channel_header_aligned hdr; + union nv_pmu_pmgr_pwr_channel_union_aligned + channels[NV_PMU_PMGR_PWR_CHANNEL_MAX_CHANNELS]; +}; + +struct nv_pmu_pmgr_pwr_chrelationship_desc { + union nv_pmu_pmgr_pwr_chrelationship_header_aligned hdr; + union nv_pmu_pmgr_pwr_chrelationship_union_aligned + ch_rels[NV_PMU_PMGR_PWR_CHANNEL_MAX_CHRELATIONSHIPS]; +}; + +union nv_pmu_pmgr_pwr_monitor_dmem_size { + union nv_pmu_pmgr_pwr_channel_header_aligned channel_hdr; + union nv_pmu_pmgr_pwr_channel_union_aligned channel; + union nv_pmu_pmgr_pwr_chrelationship_header_aligned ch_rels_hdr; + union nv_pmu_pmgr_pwr_chrelationship_union_aligned ch_rels; +}; + +struct nv_pmu_pmgr_pwr_monitor_pack { + struct nv_pmu_pmgr_pwr_channel_desc channels; + struct nv_pmu_pmgr_pwr_chrelationship_desc ch_rels; +}; + +#define NV_PMU_PMGR_PWR_POLICY_MAX_POLICIES 32U + +#define NV_PMU_PMGR_PWR_POLICY_MAX_POLICY_RELATIONSHIPS 32U + +struct nv_pmu_pmgr_pwr_policy { + struct nv_pmu_boardobj super; + u8 ch_idx; + u8 num_limit_inputs; + u8 limit_unit; + u8 sample_mult; + u32 limit_curr; + u32 limit_min; + u32 limit_max; + struct ctrl_pmgr_pwr_policy_info_integral integral; + enum ctrl_pmgr_pwr_policy_filter_type filter_type; + union ctrl_pmgr_pwr_policy_filter_param filter_param; +}; + +struct nv_pmu_pmgr_pwr_policy_hw_threshold { + struct nv_pmu_pmgr_pwr_policy super; + u8 threshold_idx; + u8 low_threshold_idx; + bool b_use_low_threshold; + u16 low_threshold_value; +}; + +struct nv_pmu_pmgr_pwr_policy_sw_threshold { + struct nv_pmu_pmgr_pwr_policy super; + u8 threshold_idx; + u8 low_threshold_idx; + bool b_use_low_threshold; + u16 low_threshold_value; + u8 event_id; +}; + +struct nv_pmu_pmgr_pwr_policy_pmu_compactible { + u8 pmu_compactible_data[68]; +}; + +union nv_pmu_pmgr_pwr_policy_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_pmgr_pwr_policy pwr_policy; + struct nv_pmu_pmgr_pwr_policy_hw_threshold hw_threshold; + struct nv_pmu_pmgr_pwr_policy_sw_threshold sw_threshold; + struct nv_pmu_pmgr_pwr_policy_pmu_compactible pmu_pwr_policy; +}; + +struct nv_pmu_pmgr_pwr_policy_relationship_pmu_compactible { + u8 pmu_compactible_data[24]; +}; + +union nv_pmu_pmgr_pwr_policy_relationship_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_pmgr_pwr_policy_relationship_pmu_compactible pmu_pwr_relationship; +}; + +struct nv_pmu_pmgr_pwr_violation_pmu_compactible { + u8 pmu_compactible_data[16]; +}; + +union nv_pmu_pmgr_pwr_violation_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_pmgr_pwr_violation_pmu_compactible violation; +}; + +#define NV_PMU_PMGR_PWR_POLICY_DESC_TABLE_VERSION_3X 0x30U + +NV_PMU_MAKE_ALIGNED_UNION(nv_pmu_pmgr_pwr_policy_union, + sizeof(union nv_pmu_pmgr_pwr_policy_union)); +NV_PMU_MAKE_ALIGNED_UNION(nv_pmu_pmgr_pwr_policy_relationship_union, + sizeof(union nv_pmu_pmgr_pwr_policy_relationship_union)); + +#define NV_PMU_PERF_DOMAIN_GROUP_MAX_GROUPS 2U + +struct nv_pmu_perf_domain_group_limits +{ + u32 values[NV_PMU_PERF_DOMAIN_GROUP_MAX_GROUPS]; +} ; + +#define NV_PMU_PMGR_RESERVED_PWR_POLICY_MASK_COUNT 0x6U + +struct nv_pmu_pmgr_pwr_policy_desc_header { + struct nv_pmu_boardobjgrp_e32 super; + u8 version; + bool b_enabled; + u8 low_sampling_mult; + u8 semantic_policy_tbl[CTRL_PMGR_PWR_POLICY_IDX_NUM_INDEXES]; + u16 base_sample_period; + u16 min_client_sample_period; + u32 reserved_pmu_policy_mask[NV_PMU_PMGR_RESERVED_PWR_POLICY_MASK_COUNT]; + struct nv_pmu_perf_domain_group_limits global_ceiling; +}; + +NV_PMU_MAKE_ALIGNED_STRUCT(nv_pmu_pmgr_pwr_policy_desc_header , + sizeof(struct nv_pmu_pmgr_pwr_policy_desc_header )); + +struct nv_pmu_pmgr_pwr_policyrel_desc_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +NV_PMU_MAKE_ALIGNED_STRUCT(nv_pmu_pmgr_pwr_policyrel_desc_header, + sizeof(struct nv_pmu_pmgr_pwr_policyrel_desc_header)); + +struct nv_pmu_pmgr_pwr_violation_desc_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +NV_PMU_MAKE_ALIGNED_STRUCT(nv_pmu_pmgr_pwr_violation_desc_header, + sizeof(struct nv_pmu_pmgr_pwr_violation_desc_header)); +NV_PMU_MAKE_ALIGNED_UNION(nv_pmu_pmgr_pwr_violation_union, + sizeof(union nv_pmu_pmgr_pwr_violation_union)); + +struct nv_pmu_pmgr_pwr_policy_desc { + union nv_pmu_pmgr_pwr_policy_desc_header_aligned hdr; + union nv_pmu_pmgr_pwr_policy_union_aligned + policies[NV_PMU_PMGR_PWR_POLICY_MAX_POLICIES]; +}; + +struct nv_pmu_pmgr_pwr_policyrel_desc { + union nv_pmu_pmgr_pwr_policyrel_desc_header_aligned hdr; + union nv_pmu_pmgr_pwr_policy_relationship_union_aligned + policy_rels[NV_PMU_PMGR_PWR_POLICY_MAX_POLICY_RELATIONSHIPS]; +}; + +struct nv_pmu_pmgr_pwr_violation_desc { + union nv_pmu_pmgr_pwr_violation_desc_header_aligned hdr; + union nv_pmu_pmgr_pwr_violation_union_aligned + violations[CTRL_PMGR_PWR_VIOLATION_MAX]; +}; + +union nv_pmu_pmgr_pwr_policy_dmem_size { + union nv_pmu_pmgr_pwr_policy_desc_header_aligned policy_hdr; + union nv_pmu_pmgr_pwr_policy_union_aligned policy; + union nv_pmu_pmgr_pwr_policyrel_desc_header_aligned policy_rels_hdr; + union nv_pmu_pmgr_pwr_policy_relationship_union_aligned policy_rels; + union nv_pmu_pmgr_pwr_violation_desc_header_aligned violation_hdr; + union nv_pmu_pmgr_pwr_violation_union_aligned violation; +}; + +struct nv_pmu_pmgr_pwr_policy_pack { + struct nv_pmu_pmgr_pwr_policy_desc policies; + struct nv_pmu_pmgr_pwr_policyrel_desc policy_rels; + struct nv_pmu_pmgr_pwr_violation_desc violations; +}; + +#define NV_PMU_PMGR_CMD_ID_SET_OBJECT (0x00000000U) + +#define NV_PMU_PMGR_MSG_ID_QUERY (0x00000002U) + +#define NV_PMU_PMGR_CMD_ID_PWR_DEVICES_QUERY (0x00000001U) + +#define NV_PMU_PMGR_CMD_ID_LOAD (0x00000006U) + +#define NV_PMU_PMGR_CMD_ID_UNLOAD (0x00000007U) + +struct nv_pmu_pmgr_cmd_set_object { + u8 cmd_type; + u8 pad[2]; + u8 object_type; + struct nv_pmu_allocation object; +}; + +#define NV_PMU_PMGR_SET_OBJECT_ALLOC_OFFSET (0x04U) + +#define NV_PMU_PMGR_OBJECT_I2C_DEVICE_DESC_TABLE (0x00000000U) + +#define NV_PMU_PMGR_OBJECT_PWR_DEVICE_DESC_TABLE (0x00000001U) + +#define NV_PMU_PMGR_OBJECT_PWR_MONITOR (0x00000002U) + +#define NV_PMU_PMGR_OBJECT_PWR_POLICY (0x00000005U) + +struct nv_pmu_pmgr_pwr_devices_query_payload { + struct { + u32 powerm_w; + u32 voltageu_v; + u32 currentm_a; + } devices[CTRL_PMGR_PWR_DEVICES_MAX_DEVICES]; +}; + +struct nv_pmu_pmgr_cmd_pwr_devices_query { + u8 cmd_type; + u8 pad[3]; + u32 dev_mask; + struct nv_pmu_allocation payload; +}; + +#define NV_PMU_PMGR_PWR_DEVICES_QUERY_ALLOC_OFFSET (0x08U) + +struct nv_pmu_pmgr_cmd_load { + u8 cmd_type; +}; + +struct nv_pmu_pmgr_cmd_unload { + u8 cmd_type; +}; + +struct nv_pmu_pmgr_cmd { + union { + u8 cmd_type; + struct nv_pmu_pmgr_cmd_set_object set_object; + struct nv_pmu_pmgr_cmd_pwr_devices_query pwr_dev_query; + struct nv_pmu_pmgr_cmd_load load; + struct nv_pmu_pmgr_cmd_unload unload; + }; +}; + +#define NV_PMU_PMGR_MSG_ID_SET_OBJECT (0x00000000U) + +#define NV_PMU_PMGR_MSG_ID_LOAD (0x00000004U) + +#define NV_PMU_PMGR_MSG_ID_UNLOAD (0x00000005U) + +struct nv_pmu_pmgr_msg_set_object { + u8 msg_type; + bool b_success; + flcn_status flcnstatus; + u8 object_type; +}; + +struct nv_pmu_pmgr_msg_query { + u8 msg_type; + bool b_success; + flcn_status flcnstatus; + u8 cmd_type; +}; + +struct nv_pmu_pmgr_msg_load { + u8 msg_type; + bool b_success; + flcn_status flcnstatus; +}; + +struct nv_pmu_pmgr_msg_unload { + u8 msg_type; +}; + +struct nv_pmu_pmgr_msg { + union { + u8 msg_type; + struct nv_pmu_pmgr_msg_set_object set_object; + struct nv_pmu_pmgr_msg_query query; + struct nv_pmu_pmgr_msg_load load; + struct nv_pmu_pmgr_msg_unload unload; + }; +}; + +#endif /* NVGPU_PMUIF_GPMUIFPMGR_H */ diff --git a/include/nvgpu/pmuif/gpmuifseq.h b/include/nvgpu/pmuif/gpmuifseq.h new file mode 100644 index 0000000..af93a6e --- /dev/null +++ b/include/nvgpu/pmuif/gpmuifseq.h @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ +#ifndef NVGPU_PMUIF_GPMUIFSEQ_H +#define NVGPU_PMUIF_GPMUIFSEQ_H + +#include + +#define PMU_UNIT_SEQ (0x02) + +/*! +* @file gpmuifseq.h +* @brief PMU Command/Message Interfaces - Sequencer +*/ + +/*! +* Defines the identifiers various high-level types of sequencer commands. +* +* _RUN_SCRIPT @ref NV_PMU_SEQ_CMD_RUN_SCRIPT +*/ +enum { + NV_PMU_SEQ_CMD_ID_RUN_SCRIPT = 0, +}; + +struct nv_pmu_seq_cmd_run_script { + u8 cmd_type; + u8 pad[3]; + struct pmu_allocation_v3 script_alloc; + struct pmu_allocation_v3 reg_alloc; +}; + +#define NV_PMU_SEQ_CMD_ALLOC_OFFSET 4 + +#define NV_PMU_SEQ_MSG_ALLOC_OFFSET \ + (NV_PMU_SEQ_CMD_ALLOC_OFFSET + NV_PMU_CMD_ALLOC_SIZE) + +struct nv_pmu_seq_cmd { + struct pmu_hdr hdr; + union { + u8 cmd_type; + struct nv_pmu_seq_cmd_run_script run_script; + }; +}; + +enum { + NV_PMU_SEQ_MSG_ID_RUN_SCRIPT = 0, +}; + +struct nv_pmu_seq_msg_run_script { + u8 msg_type; + u8 error_code; + u16 error_pc; + u32 timeout_stat; +}; + +struct nv_pmu_seq_msg { + struct pmu_hdr hdr; + union { + u8 msg_type; + struct nv_pmu_seq_msg_run_script run_script; + }; +}; + +#endif /* NVGPU_PMUIF_GPMUIFSEQ_H */ diff --git a/include/nvgpu/pmuif/gpmuiftherm.h b/include/nvgpu/pmuif/gpmuiftherm.h new file mode 100644 index 0000000..115e7ab --- /dev/null +++ b/include/nvgpu/pmuif/gpmuiftherm.h @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_PMUIF_GPMUIFTHERM_H +#define NVGPU_PMUIF_GPMUIFTHERM_H + +#include + +#define NV_PMU_THERM_CMD_ID_RPC 0x00000002 +#define NV_PMU_THERM_MSG_ID_RPC 0x00000002 +#define NV_PMU_THERM_RPC_ID_SLCT 0x00000000 +#define NV_PMU_THERM_RPC_ID_SLCT_EVENT_TEMP_TH_SET 0x00000006 +#define NV_PMU_THERM_EVENT_THERMAL_1 0x00000004 +#define NV_PMU_THERM_CMD_ID_HW_SLOWDOWN_NOTIFICATION 0x00000001 +#define NV_RM_PMU_THERM_HW_SLOWDOWN_NOTIFICATION_REQUEST_ENABLE 0x00000001 +#define NV_PMU_THERM_MSG_ID_EVENT_HW_SLOWDOWN_NOTIFICATION 0x00000001 + +struct nv_pmu_therm_rpc_slct_event_temp_th_set { + s32 temp_threshold; + u8 event_id; + flcn_status flcn_stat; +}; + +struct nv_pmu_therm_rpc_slct { + u32 mask_enabled; + flcn_status flcn_stat; +}; + +struct nv_pmu_therm_rpc { + u8 function; + bool b_supported; + union { + struct nv_pmu_therm_rpc_slct slct; + struct nv_pmu_therm_rpc_slct_event_temp_th_set slct_event_temp_th_set; + } params; +}; + +struct nv_pmu_therm_cmd_rpc { + u8 cmd_type; + u8 pad[3]; + struct nv_pmu_allocation request; +}; + +struct nv_pmu_therm_cmd_hw_slowdown_notification { + u8 cmd_type; + u8 request; +}; + +#define NV_PMU_THERM_CMD_RPC_ALLOC_OFFSET \ + offsetof(struct nv_pmu_therm_cmd_rpc, request) + +struct nv_pmu_therm_cmd { + union { + u8 cmd_type; + struct nv_pmu_therm_cmd_rpc rpc; + struct nv_pmu_therm_cmd_hw_slowdown_notification hw_slct_notification; + }; +}; + +struct nv_pmu_therm_msg_rpc { + u8 msg_type; + u8 rsvd[3]; + struct nv_pmu_allocation response; +}; + +struct nv_pmu_therm_msg_event_hw_slowdown_notification { + u8 msg_type; + u32 mask; +}; + +#define NV_PMU_THERM_MSG_RPC_ALLOC_OFFSET \ + offsetof(struct nv_pmu_therm_msg_rpc, response) + +struct nv_pmu_therm_msg { + union { + u8 msg_type; + struct nv_pmu_therm_msg_rpc rpc; + struct nv_pmu_therm_msg_event_hw_slowdown_notification hw_slct_msg; + }; +}; + +#endif /* NVGPU_PMUIF_GPMUIFTHERM_H */ + diff --git a/include/nvgpu/pmuif/gpmuifthermsensor.h b/include/nvgpu/pmuif/gpmuifthermsensor.h new file mode 100644 index 0000000..47d35da --- /dev/null +++ b/include/nvgpu/pmuif/gpmuifthermsensor.h @@ -0,0 +1,105 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_PMUIF_GPMUIFTHERMSENSOR_H +#define NVGPU_PMUIF_GPMUIFTHERMSENSOR_H + +#include "ctrl/ctrltherm.h" +#include "gpmuifboardobj.h" +#include + +#define NV_PMU_THERM_BOARDOBJGRP_CLASS_ID_THERM_DEVICE 0x00 +#define NV_PMU_THERM_BOARDOBJGRP_CLASS_ID_THERM_CHANNEL 0x01 + +#define NV_PMU_THERM_CMD_ID_BOARDOBJ_GRP_SET 0x0000000B +#define NV_PMU_THERM_MSG_ID_BOARDOBJ_GRP_SET 0x00000008 + +struct nv_pmu_therm_therm_device_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +struct nv_pmu_therm_therm_device_boardobj_set { + struct nv_pmu_boardobj super; +}; + +struct nv_pmu_therm_therm_device_gpu_gpc_tsosc_boardobj_set { + struct nv_pmu_therm_therm_device_boardobj_set super; + u8 gpc_tsosc_idx; +}; + +struct nv_pmu_therm_therm_device_gpu_sci_boardobj_set { + struct nv_pmu_therm_therm_device_boardobj_set super; +}; + +struct nv_pmu_therm_therm_device_i2c_boardobj_set { + struct nv_pmu_therm_therm_device_boardobj_set super; + u8 i2c_dev_idx; +}; + +struct nv_pmu_therm_therm_device_hbm2_site_boardobj_set { + struct nv_pmu_therm_therm_device_boardobj_set super; + u8 site_idx; +}; + +struct nv_pmu_therm_therm_device_hbm2_combined_boardobj_set { + struct nv_pmu_therm_therm_device_boardobj_set super; +}; + +union nv_pmu_therm_therm_device_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_therm_therm_device_boardobj_set therm_device; + struct nv_pmu_therm_therm_device_gpu_gpc_tsosc_boardobj_set gpu_gpc_tsosc; + struct nv_pmu_therm_therm_device_gpu_sci_boardobj_set gpu_sci; + struct nv_pmu_therm_therm_device_i2c_boardobj_set i2c; + struct nv_pmu_therm_therm_device_hbm2_site_boardobj_set hbm2_site; + struct nv_pmu_therm_therm_device_hbm2_combined_boardobj_set hbm2_combined; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(therm, therm_device); + +struct nv_pmu_therm_therm_channel_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +struct nv_pmu_therm_therm_channel_boardobj_set { + struct nv_pmu_boardobj super; + s16 scaling; + s16 offset; + s32 temp_min; + s32 temp_max; +}; + +struct nv_pmu_therm_therm_channel_device_boardobj_set { + struct nv_pmu_therm_therm_channel_boardobj_set super; + u8 therm_dev_idx; + u8 therm_dev_prov_idx; +}; + +union nv_pmu_therm_therm_channel_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_therm_therm_channel_boardobj_set therm_channel; + struct nv_pmu_therm_therm_channel_device_boardobj_set device; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(therm, therm_channel); + +#endif /* NVGPU_PMUIF_GPMUIFTHERMSENSOR_H */ diff --git a/include/nvgpu/pmuif/gpmuifvolt.h b/include/nvgpu/pmuif/gpmuifvolt.h new file mode 100644 index 0000000..0161719 --- /dev/null +++ b/include/nvgpu/pmuif/gpmuifvolt.h @@ -0,0 +1,402 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ +#ifndef NVGPU_PMUIF_GPMUIFVOLT_H +#define NVGPU_PMUIF_GPMUIFVOLT_H + +#include "gpmuifboardobj.h" +#include +#include "ctrl/ctrlvolt.h" + +#define NV_PMU_VOLT_VALUE_0V_IN_UV (0U) + +/* ------------- VOLT_RAIL's GRP_SET defines and structures ------------- */ + +#define NV_PMU_VOLT_BOARDOBJGRP_CLASS_ID_VOLT_RAIL 0x00U +#define NV_PMU_VOLT_BOARDOBJGRP_CLASS_ID_VOLT_DEVICE 0x01U +#define NV_PMU_VOLT_BOARDOBJGRP_CLASS_ID_VOLT_POLICY 0x02U + + +struct nv_pmu_volt_volt_rail_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +struct nv_pmu_volt_volt_rail_boardobj_set { + + struct nv_pmu_boardobj super; + u8 rel_limit_vfe_equ_idx; + u8 alt_rel_limit_vfe_equ_idx; + u8 ov_limit_vfe_equ_idx; + u8 vmin_limit_vfe_equ_idx; + u8 volt_margin_limit_vfe_equ_idx; + u8 pwr_equ_idx; + u8 volt_dev_idx_default; + u8 volt_dev_idx_ipc_vmin; + u8 volt_scale_exp_pwr_equ_idx; + struct ctrl_boardobjgrp_mask_e32 volt_dev_mask; + s32 volt_delta_uv[CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES]; +}; + +union nv_pmu_volt_volt_rail_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_volt_volt_rail_boardobj_set super; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(volt, volt_rail); + +/* ------------ VOLT_DEVICE's GRP_SET defines and structures ------------ */ + +struct nv_pmu_volt_volt_device_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +struct nv_pmu_volt_volt_device_boardobj_set { + struct nv_pmu_boardobj super; + u32 switch_delay_us; + u32 voltage_min_uv; + u32 voltage_max_uv; + u32 volt_step_uv; +}; + +struct nv_pmu_volt_volt_device_vid_boardobj_set { + struct nv_pmu_volt_volt_device_boardobj_set super; + s32 voltage_base_uv; + s32 voltage_offset_scale_uv; + u8 gpio_pin[CTRL_VOLT_VOLT_DEV_VID_VSEL_MAX_ENTRIES]; + u8 vsel_mask; +}; + +struct nv_pmu_volt_volt_device_pwm_boardobj_set { + struct nv_pmu_volt_volt_device_boardobj_set super; + u32 raw_period; + s32 voltage_base_uv; + s32 voltage_offset_scale_uv; + enum nv_pmu_pmgr_pwm_source pwm_source; +}; + +union nv_pmu_volt_volt_device_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_volt_volt_device_boardobj_set super; + struct nv_pmu_volt_volt_device_vid_boardobj_set vid; + struct nv_pmu_volt_volt_device_pwm_boardobj_set pwm; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(volt, volt_device); + +/* ------------ VOLT_POLICY's GRP_SET defines and structures ------------ */ +struct nv_pmu_volt_volt_policy_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e32 super; + u8 perf_core_vf_seq_policy_idx; +}; + +struct nv_pmu_volt_volt_policy_boardobj_set { + struct nv_pmu_boardobj super; +}; +struct nv_pmu_volt_volt_policy_sr_boardobj_set { + struct nv_pmu_volt_volt_policy_boardobj_set super; + u8 rail_idx; +}; + +struct nv_pmu_volt_volt_policy_sr_multi_step_boardobj_set { + struct nv_pmu_volt_volt_policy_sr_boardobj_set super; + u16 inter_switch_delay_us; + u32 ramp_up_step_size_uv; + u32 ramp_down_step_size_uv; +}; + +struct nv_pmu_volt_volt_policy_splt_r_boardobj_set { + struct nv_pmu_volt_volt_policy_boardobj_set super; + u8 rail_idx_master; + u8 rail_idx_slave; + u8 delta_min_vfe_equ_idx; + u8 delta_max_vfe_equ_idx; + s32 offset_delta_min_uv; + s32 offset_delta_max_uv; +}; + +struct nv_pmu_volt_volt_policy_srms_boardobj_set { + struct nv_pmu_volt_volt_policy_splt_r_boardobj_set super; + u16 inter_switch_delayus; +}; + +/* sr - > single_rail */ +struct nv_pmu_volt_volt_policy_srss_boardobj_set { + struct nv_pmu_volt_volt_policy_splt_r_boardobj_set super; +}; + +union nv_pmu_volt_volt_policy_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_volt_volt_policy_boardobj_set super; + struct nv_pmu_volt_volt_policy_sr_boardobj_set single_rail; + struct nv_pmu_volt_volt_policy_sr_multi_step_boardobj_set + single_rail_ms; + struct nv_pmu_volt_volt_policy_splt_r_boardobj_set split_rail; + struct nv_pmu_volt_volt_policy_srms_boardobj_set + split_rail_m_s; + struct nv_pmu_volt_volt_policy_srss_boardobj_set + split_rail_s_s; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(volt, volt_policy); + +/* ----------- VOLT_RAIL's GRP_GET_STATUS defines and structures ----------- */ +struct nv_pmu_volt_volt_rail_boardobjgrp_get_status_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +struct nv_pmu_volt_volt_rail_boardobj_get_status { + struct nv_pmu_boardobj_query super; + u32 curr_volt_defaultu_v; + u32 rel_limitu_v; + u32 alt_rel_limitu_v; + u32 ov_limitu_v; + u32 max_limitu_v; + u32 vmin_limitu_v; + s32 volt_margin_limitu_v; + u32 rsvd; +}; + +union nv_pmu_volt_volt_rail_boardobj_get_status_union { + struct nv_pmu_boardobj_query board_obj; + struct nv_pmu_volt_volt_rail_boardobj_get_status super; +}; + +NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(volt, volt_rail); + +/* ---------- VOLT_DEVICE's GRP_GET_STATUS defines and structures ---------- */ +struct nv_pmu_volt_volt_device_boardobjgrp_get_status_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +struct nv_pmu_volt_volt_device_boardobj_get_status { + struct nv_pmu_boardobj_query super; +}; + +union nv_pmu_volt_volt_device_boardobj_get_status_union { + struct nv_pmu_boardobj_query board_obj; + struct nv_pmu_volt_volt_device_boardobj_get_status super; +}; + +NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(volt, volt_device); + +/* ---------- VOLT_POLICY's GRP_GET_STATUS defines and structures ---------- */ +struct nv_pmu_volt_volt_policy_boardobjgrp_get_status_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +struct nv_pmu_volt_volt_policy_boardobj_get_status { + struct nv_pmu_boardobj_query super; + u32 offset_volt_requ_v; + u32 offset_volt_curru_v; +}; + +struct nv_pmu_volt_volt_policy_sr_boardobj_get_status { + struct nv_pmu_volt_volt_policy_boardobj_get_status super; + u32 curr_voltu_v; +}; + +struct nv_pmu_volt_volt_policy_splt_r_boardobj_get_status { + struct nv_pmu_volt_volt_policy_boardobj_get_status super; + s32 delta_minu_v; + s32 delta_maxu_v; + s32 orig_delta_minu_v; + s32 orig_delta_maxu_v; + u32 curr_volt_masteru_v; + u32 curr_volt_slaveu_v; + bool b_violation; +}; + +/* srms -> split_rail_multi_step */ +struct nv_pmu_volt_volt_policy_srms_boardobj_get_status { + struct nv_pmu_volt_volt_policy_splt_r_boardobj_get_status super; +}; + +/* srss -> split_rail_single_step */ +struct nv_pmu_volt_volt_policy_srss_boardobj_get_status { + struct nv_pmu_volt_volt_policy_splt_r_boardobj_get_status super; +}; + +union nv_pmu_volt_volt_policy_boardobj_get_status_union { + struct nv_pmu_boardobj_query board_obj; + struct nv_pmu_volt_volt_policy_boardobj_get_status super; + struct nv_pmu_volt_volt_policy_sr_boardobj_get_status single_rail; + struct nv_pmu_volt_volt_policy_splt_r_boardobj_get_status split_rail; + struct nv_pmu_volt_volt_policy_srms_boardobj_get_status + split_rail_m_s; + struct nv_pmu_volt_volt_policy_srss_boardobj_get_status + split_rail_s_s; +}; + +NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(volt, volt_policy); + +struct nv_pmu_volt_policy_voltage_data { + u8 policy_idx; + struct ctrl_perf_volt_rail_list + rail_list; +}; + +struct nv_pmu_volt_rail_get_voltage { + u8 rail_idx; + u32 voltage_uv; +}; + +struct nv_pmu_volt_volt_rail_set_noise_unaware_vmin { + u8 num_rails; + struct ctrl_volt_volt_rail_list + rail_list; +}; + +#define NV_PMU_VOLT_CMD_ID_BOARDOBJ_GRP_SET (0x00000000U) +#define NV_PMU_VOLT_CMD_ID_RPC (0x00000001U) +#define NV_PMU_VOLT_CMD_ID_BOARDOBJ_GRP_GET_STATUS (0x00000002U) +#define NV_PMU_VOLT_RPC_ID_VOLT_RAIL_SET_NOISE_UNAWARE_VMIN (0x00000004U) + +/*! +* PMU VOLT RPC calls. +*/ +#define NV_PMU_VOLT_RPC_ID_LOAD (0x00000000U) +#define NV_PMU_VOLT_RPC_ID_VOLT_POLICY_SET_VOLTAGE (0x00000002U) +#define NV_PMU_VOLT_RPC_ID_VOLT_RAIL_GET_VOLTAGE (0x00000003U) + +struct nv_pmu_volt_cmd_rpc { + u8 cmd_type; + u8 pad[3]; + struct nv_pmu_allocation request; +}; + +#define NV_PMU_VOLT_CMD_RPC_ALLOC_OFFSET \ + offsetof(struct nv_pmu_volt_cmd_rpc, request) + +struct nv_pmu_volt_cmd { + union { + u8 cmd_type; + struct nv_pmu_boardobj_cmd_grp grp_set; + struct nv_pmu_volt_cmd_rpc rpc; + struct nv_pmu_boardobj_cmd_grp grp_get_status; + }; +}; + +struct nv_pmu_volt_rpc { + u8 function; + bool b_supported; + bool b_success; + flcn_status flcn_status; + union { + struct nv_pmu_volt_policy_voltage_data volt_policy_voltage_data; + struct nv_pmu_volt_rail_get_voltage volt_rail_get_voltage; + struct nv_pmu_volt_volt_rail_set_noise_unaware_vmin + volt_rail_set_noise_unaware_vmin; + } params; +}; + +/*! +* VOLT MSG ID definitions +*/ +#define NV_PMU_VOLT_MSG_ID_BOARDOBJ_GRP_SET (0x00000000U) +#define NV_PMU_VOLT_MSG_ID_RPC (0x00000001U) +#define NV_PMU_VOLT_MSG_ID_BOARDOBJ_GRP_GET_STATUS (0x00000002U) + +/*! +* Message carrying the result of the VOLT RPC execution. +*/ +struct nv_pmu_volt_msg_rpc { + u8 msg_type; + u8 rsvd[3]; + struct nv_pmu_allocation response; +}; + +#define NV_PMU_VOLT_MSG_RPC_ALLOC_OFFSET \ + offsetof(struct nv_pmu_volt_msg_rpc, response) + +struct nv_pmu_volt_msg { + union { + u8 msg_type; + struct nv_pmu_boardobj_msg_grp grp_set; + struct nv_pmu_volt_msg_rpc rpc; + struct nv_pmu_boardobj_msg_grp grp_get_status; + }; +}; + +#define NV_PMU_VF_INJECT_MAX_VOLT_RAILS (2U) + +struct nv_pmu_volt_volt_rail_list { + u8 num_rails; + struct ctrl_perf_volt_rail_list_item + rails[NV_PMU_VF_INJECT_MAX_VOLT_RAILS]; +}; + +struct nv_pmu_volt_volt_rail_list_v1 { + u8 num_rails; + struct ctrl_volt_volt_rail_list_item_v1 + rails[NV_PMU_VF_INJECT_MAX_VOLT_RAILS]; +}; + +/* VOLT RPC */ +#define NV_PMU_RPC_ID_VOLT_BOARD_OBJ_GRP_CMD 0x00U +#define NV_PMU_RPC_ID_VOLT_VOLT_SET_VOLTAGE 0x01U +#define NV_PMU_RPC_ID_VOLT_LOAD 0x02U +#define NV_PMU_RPC_ID_VOLT_VOLT_RAIL_GET_VOLTAGE 0x03U +#define NV_PMU_RPC_ID_VOLT_VOLT_POLICY_SANITY_CHECK 0x04U +#define NV_PMU_RPC_ID_VOLT_TEST_EXECUTE 0x05U +#define NV_PMU_RPC_ID_VOLT__COUNT 0x06U + +/* + * Defines the structure that holds data + * used to execute LOAD RPC. + */ +struct nv_pmu_rpc_struct_volt_load { + /*[IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + u32 scratch[1]; +}; + +/* + * Defines the structure that holds data + * used to execute VOLT_SET_VOLTAGE RPC. + */ +struct nv_pmu_rpc_struct_volt_volt_set_voltage { + /*[IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + /*[IN] ID of the client that wants to set the voltage */ + u8 client_id; + /* + * [IN] The list containing target voltage and + * noise-unaware Vmin value for the VOLT_RAILs. + */ + struct ctrl_volt_volt_rail_list_v1 rail_list; + u32 scratch[1]; +}; + +/* + * Defines the structure that holds data + * used to execute VOLT_RAIL_GET_VOLTAGE RPC. + */ +struct nv_pmu_rpc_struct_volt_volt_rail_get_voltage { + /*[IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + /* [OUT] Current voltage in uv */ + u32 voltage_uv; + /* [IN] Voltage Rail Table Index */ + u8 rail_idx; + u32 scratch[1]; +}; + +#endif /* NVGPU_PMUIF_GPMUIFVOLT_H*/ diff --git a/include/nvgpu/pmuif/nvgpu_gpmu_cmdif.h b/include/nvgpu/pmuif/nvgpu_gpmu_cmdif.h new file mode 100644 index 0000000..ce55f67 --- /dev/null +++ b/include/nvgpu/pmuif/nvgpu_gpmu_cmdif.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMUIF_NVGPU_GPMU_CMDIF_H +#define NVGPU_PMUIF_NVGPU_GPMU_CMDIF_H + +#include +#include "gpmuif_cmn.h" +#include "gpmuif_pmu.h" +#include "gpmuif_ap.h" +#include "gpmuif_pg.h" +#include "gpmuif_perfmon.h" +#include "gpmuif_acr.h" +#include "gpmuifboardobj.h" +#include "gpmuifclk.h" +#include "gpmuifperf.h" +#include "gpmuifperfvfe.h" +#include "gpmuifpmgr.h" +#include "gpmuifvolt.h" +#include "gpmuiftherm.h" +#include "gpmuifthermsensor.h" +#include "gpmuifseq.h" +#include "gpmu_super_surf_if.h" + +/* + * Command requesting execution of the RPC (Remote Procedure Call) + */ +struct nv_pmu_rpc_cmd { + /* Must be set to @ref NV_PMU_RPC_CMD_ID */ + u8 cmd_type; + /* RPC call flags (@see PMU_RPC_FLAGS) */ + u8 flags; + /* Size of RPC structure allocated + * within NV managed DMEM heap + */ + u16 rpc_dmem_size; + /* + * DMEM pointer of RPC structure allocated + * within RM managed DMEM heap. + */ + u32 rpc_dmem_ptr; +}; + +#define NV_PMU_RPC_CMD_ID 0x80U + +/* Message carrying the result of the RPC execution */ +struct nv_pmu_rpc_msg { + /* Must be set to @ref NV_PMU_RPC_MSG_ID */ + u8 msg_type; + /* RPC call flags (@see PMU_RPC_FLAGS)*/ + u8 flags; + /* + * Size of RPC structure allocated + * within NV managed DMEM heap. + */ + u16 rpc_dmem_size; + /* + * DMEM pointer of RPC structure allocated + * within NV managed DMEM heap. + */ + u32 rpc_dmem_ptr; +}; + +#define NV_PMU_RPC_MSG_ID 0x80U + +struct pmu_cmd { + struct pmu_hdr hdr; + union { + struct pmu_perfmon_cmd perfmon; + struct pmu_pg_cmd pg; + struct pmu_zbc_cmd zbc; + struct pmu_acr_cmd acr; + struct nv_pmu_boardobj_cmd boardobj; + struct nv_pmu_perf_cmd perf; + struct nv_pmu_volt_cmd volt; + struct nv_pmu_clk_cmd clk; + struct nv_pmu_pmgr_cmd pmgr; + struct nv_pmu_therm_cmd therm; + struct nv_pmu_rpc_cmd rpc; + } cmd; +}; + +struct pmu_msg { + struct pmu_hdr hdr; + union { + struct pmu_init_msg init; + struct pmu_perfmon_msg perfmon; + struct pmu_pg_msg pg; + struct pmu_rc_msg rc; + struct pmu_acr_msg acr; + struct nv_pmu_boardobj_msg boardobj; + struct nv_pmu_perf_msg perf; + struct nv_pmu_volt_msg volt; + struct nv_pmu_clk_msg clk; + struct nv_pmu_pmgr_msg pmgr; + struct nv_pmu_therm_msg therm; + struct nv_pmu_rpc_msg rpc; + } msg; +}; + +#define PMU_UNIT_REWIND (0x00U) +#define PMU_UNIT_PG (0x03U) +#define PMU_UNIT_INIT (0x07U) +#define PMU_UNIT_ACR (0x0AU) +#define PMU_UNIT_PERFMON_T18X (0x11U) +#define PMU_UNIT_PERFMON (0x12U) +#define PMU_UNIT_PERF (0x13U) +#define PMU_UNIT_RC (0x1FU) +#define PMU_UNIT_FECS_MEM_OVERRIDE (0x1EU) +#define PMU_UNIT_CLK (0x0DU) +#define PMU_UNIT_THERM (0x14U) +#define PMU_UNIT_PMGR (0x18U) +#define PMU_UNIT_VOLT (0x0EU) + +#define PMU_UNIT_END (0x23U) +#define PMU_UNIT_INVALID (0xFFU) + +#define PMU_UNIT_TEST_START (0xFEU) +#define PMU_UNIT_END_SIM (0xFFU) +#define PMU_UNIT_TEST_END (0xFFU) + +#define PMU_UNIT_ID_IS_VALID(id) \ + (((id) < PMU_UNIT_END) || ((id) >= PMU_UNIT_TEST_START)) + +#endif /* NVGPU_PMUIF_NVGPU_GPMU_CMDIF_H*/ diff --git a/include/nvgpu/posix/atomic.h b/include/nvgpu/posix/atomic.h new file mode 100644 index 0000000..c9d9212 --- /dev/null +++ b/include/nvgpu/posix/atomic.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2017, 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_POSIX_ATOMIC_H__ +#define __NVGPU_POSIX_ATOMIC_H__ + +#include + +/* + * Note: this code uses the GCC builtins to implement atomics. + */ + +#define __atomic_cmpxchg(p, v, c) __sync_val_compare_and_swap(p, v, c) +#define __atomic_and(p, v) __sync_fetch_and_and(p, v) +#define __atomic_or(p, v) __sync_fetch_and_or(p, v) + +#define cmpxchg __atomic_cmpxchg + +/* + * Place holders until real atomics can be implemented... Yay for GCC builtins! + * We can use those eventually to define all the Linux atomic ops. + * + * TODO: make these _actually_ atomic! + */ +typedef struct __nvgpu_posix_atomic { + int v; +} nvgpu_atomic_t; + +typedef struct __nvgpu_posix_atomic64 { + long v; +} nvgpu_atomic64_t; + +#define __nvgpu_atomic_init(i) { i } +#define __nvgpu_atomic64_init(i) { i } + +static inline void __nvgpu_atomic_set(nvgpu_atomic_t *v, int i) +{ + v->v = i; +} + +static inline int __nvgpu_atomic_read(nvgpu_atomic_t *v) +{ + return v->v; +} + +static inline void __nvgpu_atomic_inc(nvgpu_atomic_t *v) +{ + v->v++; +} + +static inline int __nvgpu_atomic_inc_return(nvgpu_atomic_t *v) +{ + v->v++; + return v->v; +} + +static inline void __nvgpu_atomic_dec(nvgpu_atomic_t *v) +{ + v->v--; +} + +static inline int __nvgpu_atomic_dec_return(nvgpu_atomic_t *v) +{ + v->v--; + return v->v; +} + +static inline int __nvgpu_atomic_cmpxchg(nvgpu_atomic_t *v, int old, int new) +{ + if (v->v == old) + v->v = new; + + return v->v; +} + +static inline int __nvgpu_atomic_xchg(nvgpu_atomic_t *v, int new) +{ + v->v = new; + return new; +} + +static inline bool __nvgpu_atomic_inc_and_test(nvgpu_atomic_t *v) +{ + v->v++; + return v->v ? true : false; +} + +static inline bool __nvgpu_atomic_dec_and_test(nvgpu_atomic_t *v) +{ + v->v--; + return v->v ? true : false; +} + +static inline bool __nvgpu_atomic_sub_and_test(int i, nvgpu_atomic_t *v) +{ + v->v -= i; + return v->v ? true : false; +} + +static inline int __nvgpu_atomic_add_return(int i, nvgpu_atomic_t *v) +{ + v->v += i; + return v->v; +} + +static inline int __nvgpu_atomic_add_unless(nvgpu_atomic_t *v, int a, int u) +{ + if (v->v != u) + v->v += a; + + return v->v; +} + +static inline void __nvgpu_atomic64_set(nvgpu_atomic64_t *v, long i) +{ + v->v = i; +} + +static inline long __nvgpu_atomic64_read(nvgpu_atomic64_t *v) +{ + return v->v; +} + +static inline void __nvgpu_atomic64_add(long x, nvgpu_atomic64_t *v) +{ + v->v += x; +} + +static inline void __nvgpu_atomic64_inc(nvgpu_atomic64_t *v) +{ + v->v++; +} + +static inline long __nvgpu_atomic64_inc_return(nvgpu_atomic64_t *v) +{ + v->v++; + return v->v; +} + +static inline void __nvgpu_atomic64_dec(nvgpu_atomic64_t *v) +{ + v->v--; +} + +static inline long __nvgpu_atomic64_dec_return(nvgpu_atomic64_t *v) +{ + v->v--; + return v->v; +} + +static inline long __nvgpu_atomic64_cmpxchg(nvgpu_atomic64_t *v, + long old, long new) +{ + + if (v->v == old) + v->v = new; + + return v->v; +} + +static inline void __nvgpu_atomic64_sub(long x, nvgpu_atomic64_t *v) +{ + v->v -= x; +} + +static inline long __nvgpu_atomic64_sub_return(long x, nvgpu_atomic64_t *v) +{ + v->v -= x; + return v->v; +} + +#endif diff --git a/include/nvgpu/posix/barrier.h b/include/nvgpu/posix/barrier.h new file mode 100644 index 0000000..edc7b12 --- /dev/null +++ b/include/nvgpu/posix/barrier.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017, 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_POSIX_BARRIER_H__ +#define __NVGPU_POSIX_BARRIER_H__ + +#define ACCESS_ONCE(x) (*(volatile __typeof__(x) *)&x) + +/* + * TODO: implement all these! + */ +#define __nvgpu_mb() +#define __nvgpu_rmb() +#define __nvgpu_wmb() + +#define __nvgpu_smp_mb() +#define __nvgpu_smp_rmb() +#define __nvgpu_smp_wmb() + +#define __nvgpu_read_barrier_depends() +#define __nvgpu_smp_read_barrier_depends() + +#define __NV_ACCESS_ONCE(x) ACCESS_ONCE(x) + +#endif diff --git a/include/nvgpu/posix/bitops.h b/include/nvgpu/posix/bitops.h new file mode 100644 index 0000000..e8c663b --- /dev/null +++ b/include/nvgpu/posix/bitops.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017, 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_POSIX_BITOPS_H__ +#define __NVGPU_POSIX_BITOPS_H__ + +#include + +/* + * Assume an 8 bit byte, of course. + */ +#define BITS_PER_BYTE 8UL +#define BITS_PER_LONG (__SIZEOF_LONG__ * BITS_PER_BYTE) +#define BITS_TO_LONGS(bits) \ + (bits + (BITS_PER_LONG - 1) / BITS_PER_LONG) + +/* + * Deprecated; use the explicit BITxx() macros instead. + */ +#define BIT(i) BIT64(i) + +#define GENMASK(h, l) \ + (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) + +#define DECLARE_BITMAP(bmap, bits) \ + unsigned long bmap[BITS_TO_LONGS(bits)] + +#define for_each_set_bit(bit, addr, size) \ + for ((bit) = find_first_bit((addr), (size)); \ + (bit) < (size); \ + (bit) = find_next_bit((addr), (size), (bit) + 1)) + +#define ffs(word) __ffs(word) +#define ffz(word) __ffs(~(word)) +#define fls(word) __fls(word) + +/* + * Clashes with symbols in libc it seems. + */ +#define __ffs(word) __nvgpu_posix_ffs(word) +#define __fls(word) __nvgpu_posix_fls(word) + +unsigned long __nvgpu_posix_ffs(unsigned long word); +unsigned long __nvgpu_posix_fls(unsigned long word); + +unsigned long find_first_bit(const unsigned long *addr, unsigned long size); +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, + unsigned long offset); +unsigned long find_first_zero_bit(const unsigned long *addr, + unsigned long size); + +bool test_bit(int nr, const volatile unsigned long *addr); +bool test_and_set_bit(int nr, volatile unsigned long *addr); +bool test_and_clear_bit(int nr, volatile unsigned long *addr); + +/* + * These two are atomic. + */ +void set_bit(int nr, volatile unsigned long *addr); +void clear_bit(int nr, volatile unsigned long *addr); + +void bitmap_set(unsigned long *map, unsigned int start, int len); +void bitmap_clear(unsigned long *map, unsigned int start, int len); +unsigned long bitmap_find_next_zero_area_off(unsigned long *map, + unsigned long size, + unsigned long start, + unsigned int nr, + unsigned long align_mask, + unsigned long align_offset); +unsigned long bitmap_find_next_zero_area(unsigned long *map, + unsigned long size, + unsigned long start, + unsigned int nr, + unsigned long align_mask); + +#endif diff --git a/include/nvgpu/posix/bug.h b/include/nvgpu/posix/bug.h new file mode 100644 index 0000000..04389a9 --- /dev/null +++ b/include/nvgpu/posix/bug.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_POSIX_BUG_H__ +#define __NVGPU_POSIX_BUG_H__ + +#include + +/* + * TODO: make these actually useful! + */ + +#define BUG() __bug("") +#define BUG_ON(cond) \ + do { \ + if (cond) \ + BUG(); \ + } while (0) + +#define WARN(cond, msg, arg...) __warn(cond, msg, ##arg) +#define WARN_ON(cond) __warn(cond, "") + +#define WARN_ONCE(cond, msg, arg...) \ + ({static int __warned__ = 0; \ + if (!__warned__) { \ + WARN(cond, msg, ##arg); \ + __warned__ = 1; \ + } \ + cond; }) + + +void dump_stack(void); + +void __bug(const char *fmt, ...) __attribute__ ((noreturn)); +bool __warn(bool cond, const char *fmt, ...); + +#endif diff --git a/include/nvgpu/posix/circ_buf.h b/include/nvgpu/posix/circ_buf.h new file mode 100644 index 0000000..8d9b5ea --- /dev/null +++ b/include/nvgpu/posix/circ_buf.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_POSIX_CIRC_BUF_H__ +#define __NVGPU_POSIX_CIRC_BUF_H__ + +#include + +/* TODO: implement. */ + +#define CIRC_CNT(head, tail, size) \ + ({(void)head; \ + (void)tail; \ + (void)size; \ + BUG(); \ + 1; }) + +#define CIRC_SPACE(head, tail, size) \ + ({(void)head; \ + (void)tail; \ + (void)size; \ + BUG(); \ + 1; }) + +#endif diff --git a/include/nvgpu/posix/cond.h b/include/nvgpu/posix/cond.h new file mode 100644 index 0000000..3528388 --- /dev/null +++ b/include/nvgpu/posix/cond.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_POSIX_COND_H__ +#define __NVGPU_POSIX_COND_H__ + +#include + +struct nvgpu_cond { + /* Place holder until this can be properly implemented. */ +}; + +/** + * NVGPU_COND_WAIT - Wait for a condition to be true + * + * @c - The condition variable to sleep on + * @condition - The condition that needs to be true + * @timeout_ms - Timeout in milliseconds, or 0 for infinite wait + * + * Wait for a condition to become true. Returns -ETIMEOUT if + * the wait timed out with condition false. + */ +#define NVGPU_COND_WAIT(c, condition, timeout_ms) \ + ({BUG(); 1; }) + +/** + * NVGPU_COND_WAIT_INTERRUPTIBLE - Wait for a condition to be true + * + * @c - The condition variable to sleep on + * @condition - The condition that needs to be true + * @timeout_ms - Timeout in milliseconds, or 0 for infinite wait + * + * Wait for a condition to become true. Returns -ETIMEOUT if + * the wait timed out with condition false or -ERESTARTSYS on + * signal. + */ +#define NVGPU_COND_WAIT_INTERRUPTIBLE(c, condition, timeout_ms) \ + ({BUG(); 1; }) + +#endif diff --git a/include/nvgpu/posix/io.h b/include/nvgpu/posix/io.h new file mode 100644 index 0000000..98be4d0 --- /dev/null +++ b/include/nvgpu/posix/io.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_POSIX_IO_H +#define NVGPU_POSIX_IO_H + +#include +#include + +struct gk20a; + +/** + * Here lies the interface for a unit test module to interact with the nvgpu IO + * accessors. This interface provides the ability for a module to react to nvgpu + * calling nvgpu IO accessors so that nvgpu can handle various HW sequences even + * when run in unit testing mode. + * + * The primary interface is simply callbacks to the unit test module which the + * module can handle how ever it wishes. + */ + +struct nvgpu_reg_access { + /* + * Address of the register write relative to the base of the register + * space. I.e you can compare this against values in the HW headers + * directly to check what register is being read/written to/from. + */ + u32 addr; + + /* + * Writes: this is the value being written. + * Reads: populate with the value to return. + */ + u32 value; +}; + +struct nvgpu_posix_io_callbacks { + void (*writel)(struct gk20a *g, struct nvgpu_reg_access *access); + void (*writel_check)(struct gk20a *g, struct nvgpu_reg_access *access); + void (*__readl)(struct gk20a *g, struct nvgpu_reg_access *access); + void (*readl)(struct gk20a *g, struct nvgpu_reg_access *access); + void (*bar1_writel)(struct gk20a *g, struct nvgpu_reg_access *access); + void (*bar1_readl)(struct gk20a *g, struct nvgpu_reg_access *access); + void (*usermode_writel)(struct gk20a *g, + struct nvgpu_reg_access *access); +}; + +struct nvgpu_posix_io_callbacks *nvgpu_posix_register_io( + struct gk20a *g, + struct nvgpu_posix_io_callbacks *io_callbacks); + +struct nvgpu_posix_io_reg_space { + u32 base; + u32 size; + u32 *data; + struct nvgpu_list_node link; +}; + +static inline struct nvgpu_posix_io_reg_space * +nvgpu_posix_io_reg_space_from_link(struct nvgpu_list_node *node) +{ + return (struct nvgpu_posix_io_reg_space *) + ((uintptr_t)node - offsetof(struct nvgpu_posix_io_reg_space, link)); +}; + +void nvgpu_posix_io_init_reg_space(struct gk20a *g); +int nvgpu_posix_io_get_error_code(struct gk20a *g); +void nvgpu_posix_io_reset_error_code(struct gk20a *g); +int nvgpu_posix_io_add_reg_space(struct gk20a *g, u32 base, u32 size); +struct nvgpu_posix_io_reg_space *nvgpu_posix_io_get_reg_space(struct gk20a *g, + u32 addr); +void nvgpu_posix_io_delete_reg_space(struct gk20a *g, u32 base); +void nvgpu_posix_io_writel_reg_space(struct gk20a *g, u32 addr, u32 data); +u32 nvgpu_posix_io_readl_reg_space(struct gk20a *g, u32 addr); + +struct nvgpu_posix_io_reg_access { + struct nvgpu_reg_access access; + struct nvgpu_list_node link; +}; + +static inline struct nvgpu_posix_io_reg_access * +nvgpu_posix_io_reg_access_from_link(struct nvgpu_list_node *node) +{ + return (struct nvgpu_posix_io_reg_access *) + ((uintptr_t)node - offsetof(struct nvgpu_posix_io_reg_access, link)); +}; + +void nvgpu_posix_io_start_recorder(struct gk20a *g); +void nvgpu_posix_io_reset_recorder(struct gk20a *g); +void nvgpu_posix_io_record_access(struct gk20a *g, + struct nvgpu_reg_access *access); +bool nvgpu_posix_io_check_sequence(struct gk20a *g, + struct nvgpu_reg_access *sequence, u32 size, bool strict); + +#endif diff --git a/include/nvgpu/posix/kmem.h b/include/nvgpu/posix/kmem.h new file mode 100644 index 0000000..efcdd3d --- /dev/null +++ b/include/nvgpu/posix/kmem.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017, 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_POSIX_KMEM_H__ +#define __NVGPU_POSIX_KMEM_H__ + +#include + +void *__nvgpu_kmalloc(struct gk20a *g, size_t size, void *ip); +void *__nvgpu_kzalloc(struct gk20a *g, size_t size, void *ip); +void *__nvgpu_kcalloc(struct gk20a *g, size_t n, size_t size, void *ip); +void *__nvgpu_vmalloc(struct gk20a *g, unsigned long size, void *ip); +void *__nvgpu_vzalloc(struct gk20a *g, unsigned long size, void *ip); +void __nvgpu_kfree(struct gk20a *g, void *addr); +void __nvgpu_vfree(struct gk20a *g, void *addr); + +#endif diff --git a/include/nvgpu/posix/lock.h b/include/nvgpu/posix/lock.h new file mode 100644 index 0000000..82eddd0 --- /dev/null +++ b/include/nvgpu/posix/lock.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017, 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_POSIX_LOCK_H__ +#define __NVGPU_POSIX_LOCK_H__ + +#include + +#include + +/* + * All locks for posix nvgpu are just pthread locks. There's not a lot of reason + * to have real spinlocks in userspace since we aren't using real HW or running + * perf critical code where a sleep could be devestating. + * + * This could be revisited later, though. + */ +struct __nvgpu_posix_lock { + pthread_mutex_t mutex; +}; + +static inline void __nvgpu_posix_lock_acquire(struct __nvgpu_posix_lock *lock) +{ + pthread_mutex_lock(&lock->mutex); +} + +static inline int __nvgpu_posix_lock_try_acquire( + struct __nvgpu_posix_lock *lock) +{ + return pthread_mutex_trylock(&lock->mutex); +} + +static inline void __nvgpu_posix_lock_release(struct __nvgpu_posix_lock *lock) +{ + pthread_mutex_unlock(&lock->mutex); +} + +struct nvgpu_mutex { + struct __nvgpu_posix_lock lock; +}; + +struct nvgpu_spinlock { + struct __nvgpu_posix_lock lock; +}; + +struct nvgpu_raw_spinlock { + struct __nvgpu_posix_lock lock; +}; + +#endif /* NVGPU_LOCK_LINUX_H */ diff --git a/include/nvgpu/posix/log2.h b/include/nvgpu/posix/log2.h new file mode 100644 index 0000000..ca95c10 --- /dev/null +++ b/include/nvgpu/posix/log2.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_POSIX_LOG2_H__ +#define __NVGPU_POSIX_LOG2_H__ + +#define ilog2(x) (fls(x) - 1) + +#define roundup_pow_of_two(x) (1UL << fls((x) - 1)) +#define rounddown_pow_of_two(x) (1UL << (fls(x) - 1)) + +#define is_power_of_2(x) \ + ({ \ + typeof(x) __x__ = (x); \ + (__x__ != 0 && ((__x__ & (__x__ - 1)) == 0)); \ + }) + +#endif diff --git a/include/nvgpu/posix/nvgpu_mem.h b/include/nvgpu/posix/nvgpu_mem.h new file mode 100644 index 0000000..30cdf60 --- /dev/null +++ b/include/nvgpu/posix/nvgpu_mem.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017, 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_POSIX_NVGPU_MEM_H__ +#define __NVGPU_POSIX_NVGPU_MEM_H__ + +struct nvgpu_mem_priv { + /* + * Eventually this will require an implementation using nvmap. + */ +}; + +#endif diff --git a/include/nvgpu/posix/nvlink.h b/include/nvgpu/posix/nvlink.h new file mode 100644 index 0000000..99cf837 --- /dev/null +++ b/include/nvgpu/posix/nvlink.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NVGPU_POSIX_NVLINK_H__ +#define __NVGPU_POSIX_NVLINK_H__ + +/* + * Empty... + */ + +#endif diff --git a/include/nvgpu/posix/pci.h b/include/nvgpu/posix/pci.h new file mode 100644 index 0000000..cd9fc14 --- /dev/null +++ b/include/nvgpu/posix/pci.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_POSIX_PCI_H__ +#define __NVGPU_POSIX_PCI_H__ + +#define PCI_VENDOR_ID_NVIDIA 0x10de + +#endif diff --git a/include/nvgpu/posix/probe.h b/include/nvgpu/posix/probe.h new file mode 100644 index 0000000..a9763aa --- /dev/null +++ b/include/nvgpu/posix/probe.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_POSIX_PROBE_H__ +#define __NVGPU_POSIX_PROBE_H__ + +struct gk20a; + +struct gk20a *nvgpu_posix_probe(void); +void nvgpu_posix_cleanup(struct gk20a *g); + +#endif diff --git a/include/nvgpu/posix/rwsem.h b/include/nvgpu/posix/rwsem.h new file mode 100644 index 0000000..65aa931 --- /dev/null +++ b/include/nvgpu/posix/rwsem.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_POSIX_RWSEM_H__ +#define __NVGPU_POSIX_RWSEM_H__ + +#include + +struct nvgpu_rwsem { + struct nvgpu_spinlock lock; + + int readers; + int writers; +}; + +#endif diff --git a/include/nvgpu/posix/sizes.h b/include/nvgpu/posix/sizes.h new file mode 100644 index 0000000..3fda757 --- /dev/null +++ b/include/nvgpu/posix/sizes.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017, 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_POSIX_SIZES_H__ +#define __NVGPU_POSIX_SIZES_H__ + +#define SZ_1K (1UL << 10) +#define SZ_4K (SZ_1K << 2) +#define SZ_64K (SZ_1K << 6) +#define SZ_128K (SZ_1K << 7) + +#define SZ_1M (1UL << 20) +#define SZ_16M (SZ_1M << 4) +#define SZ_256M (SZ_1M << 8) + +#define SZ_1G (1UL << 30) +#define SZ_4G (SZ_1G << 2) + +#endif diff --git a/include/nvgpu/posix/sort.h b/include/nvgpu/posix/sort.h new file mode 100644 index 0000000..6a6920e --- /dev/null +++ b/include/nvgpu/posix/sort.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017, 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_POSIX_SORT_H__ +#define __NVGPU_POSIX_SORT_H__ + +#include + +static void sort(void *base, size_t num, size_t size, + int (*cmp)(const void *, const void *), + void (*swap)(void *, void *, int)) +{ + __bug("sort() not implemented yet!"); +} + +#endif diff --git a/include/nvgpu/posix/thread.h b/include/nvgpu/posix/thread.h new file mode 100644 index 0000000..a312cc1 --- /dev/null +++ b/include/nvgpu/posix/thread.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_POSIX_THREAD_H__ +#define __NVGPU_POSIX_THREAD_H__ + +#include + +#include + +/* + * Handles passing an nvgpu thread function into a posix thread. + */ +struct nvgpu_posix_thread_data { + int (*fn)(void *data); + void *data; +}; + +/* + * For some reason POSIX only allows 16 bytes of name length. + */ +#define NVGPU_THREAD_POSIX_MAX_NAMELEN 16 + +struct nvgpu_thread { + bool running; + bool should_stop; + pthread_t thread; + struct nvgpu_posix_thread_data nvgpu; + char tname[16]; +}; + +#endif diff --git a/include/nvgpu/posix/types.h b/include/nvgpu/posix/types.h new file mode 100644 index 0000000..12078b9 --- /dev/null +++ b/include/nvgpu/posix/types.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2017, 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_POSIX_TYPES_H__ +#define __NVGPU_POSIX_TYPES_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * For endianness functions. + */ +#include + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; + +typedef signed char s8; +typedef signed short s16; +typedef signed int s32; +typedef signed long long s64; + +#define min_t(type, a, b) \ + ({ \ + type __a = (a); \ + type __b = (b); \ + __a < __b ? __a : __b; \ + }) + +#if defined(min) +#undef min +#endif +#if defined(max) +#undef max +#endif + +#define min(a, b) \ + ({ \ + (a) < (b) ? a : b; \ + }) +#define max(a, b) \ + ({ \ + (a) > (b) ? a : b; \ + }) +#define min3(a, b, c) min(min(a, b), c) + +#define PAGE_SIZE 4096U + +#define ARRAY_SIZE(array) \ + (sizeof(array) / sizeof((array)[0])) + +#define MAX_SCHEDULE_TIMEOUT LONG_MAX + +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) + +/* + * Only used in clk_gm20b.c which we will never unit test. Don't use! + */ +#define DIV_ROUND_CLOSEST(x, divisor) ({BUG(); 0; }) + +/* + * Joys of userspace: usually division just works since the compiler can link + * against external division functions implicitly. + */ +#define do_div(a, b) ((a) /= (b)) +#define div64_u64(a, b) ((a) / (b)) + +#define __round_mask(x, y) ((__typeof__(x))((y) - 1)) +#define round_up(x, y) ((((x) - 1) | __round_mask(x, y)) + 1) +#define roundup(x, y) round_up(x, y) +#define round_down(x, y) ((x) & ~__round_mask(x, y)) + +#define ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) +#define ALIGN(x, a) ALIGN_MASK(x, (typeof(x))(a) - 1) +#define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE) + +/* + * Caps return at the size of the buffer not what would have been written if buf + * were arbitrarily sized. + */ +static inline int scnprintf(char *buf, size_t size, const char *format, ...) +{ + size_t ret; + va_list args; + + va_start(args, format); + ret = vsnprintf(buf, size, format, args); + va_end(args); + + return ret <= size ? ret : size; +} + +static inline u32 be32_to_cpu(u32 x) +{ + /* + * Conveniently big-endian happens to be network byte order as well so + * we can use ntohl() for this. + */ + return ntohl(x); +} + +/* + * Hamming weights. + */ +static inline unsigned long __hweight8(uint8_t x) +{ + return (unsigned long)(!!(x & (1 << 0)) + + !!(x & (1 << 1)) + + !!(x & (1 << 2)) + + !!(x & (1 << 3)) + + !!(x & (1 << 4)) + + !!(x & (1 << 5)) + + !!(x & (1 << 6)) + + !!(x & (1 << 7))); +} + +static inline unsigned long __hweight16(uint16_t x) +{ + return __hweight8((uint8_t)x) + + __hweight8((uint8_t)((x & 0xff00) >> 8)); +} + +static inline unsigned long __hweight32(uint32_t x) +{ + return __hweight16((uint16_t)x) + + __hweight16((uint16_t)((x & 0xffff0000) >> 16)); +} + +static inline unsigned long __hweight64(uint64_t x) +{ + return __hweight32((uint32_t)x) + + __hweight32((uint32_t)((x & 0xffffffff00000000) >> 32)); +} + +#define hweight32 __hweight32 +#define hweight_long __hweight64 + +/* + * Better suited under a compiler.h type header file, but for now these can live + * here. + */ +#define __must_check +#define __maybe_unused __attribute__((unused)) +#define __iomem +#define __user +#define unlikely +#define likely + +#define __stringify(x) #x + +/* + * Prevent compiler optimizations from mangling writes. But likely most uses of + * this in nvgpu are incorrect (i.e unnecessary). + */ +#define WRITE_ONCE(p, v) \ + ({ \ + volatile typeof(p) *__p__ = &(p); \ + *__p__ = v; \ + }) + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#define __packed __attribute__((packed)) + +#define IS_ENABLED(config) 0 + +#define MAX_ERRNO 4095 + +#define IS_ERR_VALUE(x) ((x) >= (unsigned long)-MAX_ERRNO) + +static inline void *ERR_PTR(long error) +{ + return (void *) error; +} + +static inline long PTR_ERR(void *error) +{ + return (long)(uintptr_t)error; +} + +static inline bool IS_ERR(const void *ptr) +{ + return IS_ERR_VALUE((unsigned long)ptr); +} + +static inline bool IS_ERR_OR_NULL(const void *ptr) +{ + return (ptr == NULL) || IS_ERR_VALUE((unsigned long)ptr); +} + +#endif diff --git a/include/nvgpu/posix/vm.h b/include/nvgpu/posix/vm.h new file mode 100644 index 0000000..ae997d3 --- /dev/null +++ b/include/nvgpu/posix/vm.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017, 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_POSIX_VM_H__ +#define __NVGPU_POSIX_VM_H__ + +#include + +struct nvgpu_os_buffer { + /* + * We just use malloc() buffers in userspace. + */ + void *buf; + size_t size; +}; + +struct nvgpu_mapped_buf_priv { + void *buf; + size_t size; +}; + +#endif diff --git a/include/nvgpu/power_features/cg.h b/include/nvgpu/power_features/cg.h new file mode 100644 index 0000000..d447d9b --- /dev/null +++ b/include/nvgpu/power_features/cg.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019-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_POWER_FEATURES_CG_H +#define NVGPU_POWER_FEATURES_CG_H + +#include + +struct gk20a; +struct fifo_gk20a; + +void nvgpu_cg_init_gr_load_gating_prod(struct gk20a *g); +void nvgpu_cg_elcg_enable(struct gk20a *g); +void nvgpu_cg_elcg_disable(struct gk20a *g); +void nvgpu_cg_elcg_enable_no_wait(struct gk20a *g); +void nvgpu_cg_elcg_disable_no_wait(struct gk20a *g); +void nvgpu_cg_elcg_set_elcg_enabled(struct gk20a *g, bool enable); + +void nvgpu_cg_blcg_mode_enable(struct gk20a *g); +void nvgpu_cg_blcg_mode_disable(struct gk20a *g); +void nvgpu_cg_blcg_fb_ltc_load_enable(struct gk20a *g); +void nvgpu_cg_blcg_fifo_load_enable(struct gk20a *g); +void nvgpu_cg_blcg_pmu_load_enable(struct gk20a *g); +void nvgpu_cg_blcg_ce_load_enable(struct gk20a *g); +void nvgpu_cg_blcg_gr_load_enable(struct gk20a *g); +void nvgpu_cg_blcg_set_blcg_enabled(struct gk20a *g, bool enable); + +void nvgpu_cg_slcg_gr_perf_ltc_load_enable(struct gk20a *g); +void nvgpu_cg_slcg_gr_perf_ltc_load_disable(struct gk20a *g); +void nvgpu_cg_slcg_fb_ltc_load_enable(struct gk20a *g); +void nvgpu_cg_slcg_priring_load_enable(struct gk20a *g); +void nvgpu_cg_slcg_fifo_load_enable(struct gk20a *g); +void nvgpu_cg_slcg_pmu_load_enable(struct gk20a *g); +void nvgpu_cg_slcg_ce2_load_enable(struct gk20a *g); +void nvgpu_cg_slcg_set_slcg_enabled(struct gk20a *g, bool enable); + +#endif /*NVGPU_POWER_FEATURES_CG_H*/ diff --git a/include/nvgpu/power_features/pg.h b/include/nvgpu/power_features/pg.h new file mode 100644 index 0000000..d735780 --- /dev/null +++ b/include/nvgpu/power_features/pg.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019, 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_POWER_FEATURES_PG_H +#define NVGPU_POWER_FEATURES_PG_H + +#include + +struct gk20a; + +int nvgpu_pg_elpg_disable(struct gk20a *g); +int nvgpu_pg_elpg_enable(struct gk20a *g); +bool nvgpu_pg_elpg_is_enabled(struct gk20a *g); +int nvgpu_pg_elpg_set_elpg_enabled(struct gk20a *g, bool enable); + +#endif /*NVGPU_POWER_FEATURES_PG_H*/ diff --git a/include/nvgpu/power_features/power_features.h b/include/nvgpu/power_features/power_features.h new file mode 100644 index 0000000..f6ffccf --- /dev/null +++ b/include/nvgpu/power_features/power_features.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019, 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_POWER_FEATURES_H +#define NVGPU_POWER_FEATURES_H + +#include + +struct gk20a; + +int nvgpu_cg_pg_disable(struct gk20a *g); +int nvgpu_cg_pg_enable(struct gk20a *g); + +#endif /*NVGPU_POWER_FEATURES_H*/ diff --git a/include/nvgpu/pramin.h b/include/nvgpu/pramin.h new file mode 100644 index 0000000..b0914bc --- /dev/null +++ b/include/nvgpu/pramin.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_PRAMIN_H +#define NVGPU_PRAMIN_H + +#include + +struct gk20a; +struct mm_gk20a; +struct nvgpu_mem; + + +void nvgpu_pramin_rd_n(struct gk20a *g, struct nvgpu_mem *mem, u32 start, u32 words, void *dest); +void nvgpu_pramin_wr_n(struct gk20a *g, struct nvgpu_mem *mem, u32 start, u32 words, void *src); +void nvgpu_pramin_memset(struct gk20a *g, struct nvgpu_mem *mem, u32 start, u32 words, u32 w); + +void nvgpu_init_pramin(struct mm_gk20a *mm); + +#endif /* NVGPU_PRAMIN_H */ diff --git a/include/nvgpu/ptimer.h b/include/nvgpu/ptimer.h new file mode 100644 index 0000000..3369eb2 --- /dev/null +++ b/include/nvgpu/ptimer.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PTIMER_H +#define NVGPU_PTIMER_H + +#include + +struct gk20a; + +struct nvgpu_cpu_time_correlation_sample { + u64 cpu_timestamp; + u64 gpu_timestamp; +}; + +/* PTIMER_REF_FREQ_HZ corresponds to a period of 32 nanoseconds. + 32 ns is the resolution of ptimer. */ +#define PTIMER_REF_FREQ_HZ 31250000 + +static inline u32 ptimer_scalingfactor10x(u32 ptimer_src_freq) +{ + return (u32)(((u64)(PTIMER_REF_FREQ_HZ * 10)) / ptimer_src_freq); +} + +static inline u32 scale_ptimer(u32 timeout , u32 scale10x) +{ + if (((timeout*10) % scale10x) >= (scale10x/2)) { + return ((timeout * 10) / scale10x) + 1; + } else { + return (timeout * 10) / scale10x; + } +} + +int nvgpu_get_timestamps_zipper(struct gk20a *g, + u32 source_id, u32 count, + struct nvgpu_cpu_time_correlation_sample *samples); +#endif diff --git a/include/nvgpu/rbtree.h b/include/nvgpu/rbtree.h new file mode 100644 index 0000000..bcbbabb --- /dev/null +++ b/include/nvgpu/rbtree.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_RBTREE_H +#define NVGPU_RBTREE_H + +#include + +struct nvgpu_rbtree_node { + u64 key_start; + u64 key_end; + + bool is_red; /* !IsRed == IsBlack */ + + struct nvgpu_rbtree_node *parent; + struct nvgpu_rbtree_node *left; + struct nvgpu_rbtree_node *right; +}; + +/** + * nvgpu_rbtree_insert - insert a new node into rbtree + * + * @new_node Pointer to new node. + * @root Pointer to root of tree + * + * Nodes with duplicate key_start and overlapping ranges + * are not allowed + */ +void nvgpu_rbtree_insert(struct nvgpu_rbtree_node *new_node, + struct nvgpu_rbtree_node **root); + +/** + * nvgpu_rbtree_unlink - delete a node from rbtree + * + * @node Pointer to node to be deleted + * @root Pointer to root of tree + */ +void nvgpu_rbtree_unlink(struct nvgpu_rbtree_node *node, + struct nvgpu_rbtree_node **root); + +/** + * nvgpu_rbtree_search - search a given key in rbtree + * + * @key_start Key to be searched in rbtree + * @node Node pointer to be returned + * @root Pointer to root of tree + * + * This API will match given key against key_start of each node + * In case of a hit, node points to a node with given key + * In case of a miss, node is NULL + */ +void nvgpu_rbtree_search(u64 key_start, struct nvgpu_rbtree_node **node, + struct nvgpu_rbtree_node *root); + +/** + * nvgpu_rbtree_range_search - search a node with key falling in range + * + * @key Key to be searched in rbtree + * @node Node pointer to be returned + * @root Pointer to root of tree + * + * This API will match given key and find a node where key value + * falls within range of {start, end} keys + * In case of a hit, node points to a node with given key + * In case of a miss, node is NULL + */ +void nvgpu_rbtree_range_search(u64 key, + struct nvgpu_rbtree_node **node, + struct nvgpu_rbtree_node *root); + +/** + * nvgpu_rbtree_less_than_search - search a node with key lesser than given key + * + * @key_start Key to be searched in rbtree + * @node Node pointer to be returned + * @root Pointer to root of tree + * + * This API will match given key and find a node with highest + * key value lesser than given key + * In case of a hit, node points to a node with given key + * In case of a miss, node is NULL + */ +void nvgpu_rbtree_less_than_search(u64 key_start, + struct nvgpu_rbtree_node **node, + struct nvgpu_rbtree_node *root); + +/** + * nvgpu_rbtree_enum_start - enumerate tree starting at the node with specified value + * + * @key_start Key value to begin enumeration from + * @node Pointer to first node in the tree + * @root Pointer to root of tree + * + * This API returns node pointer pointing to first node in the rbtree + */ +void nvgpu_rbtree_enum_start(u64 key_start, + struct nvgpu_rbtree_node **node, + struct nvgpu_rbtree_node *root); + +/** + * nvgpu_rbtree_enum_next - find next node in enumeration + * + * @node Pointer to next node in the tree + * @root Pointer to root of tree + * + * This API returns node pointer pointing to next node in the rbtree + */ +void nvgpu_rbtree_enum_next(struct nvgpu_rbtree_node **node, + struct nvgpu_rbtree_node *root); + +#endif /* NVGPU_RBTREE_H */ diff --git a/include/nvgpu/rwsem.h b/include/nvgpu/rwsem.h new file mode 100644 index 0000000..3cca9c5 --- /dev/null +++ b/include/nvgpu/rwsem.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_RWSEM_H +#define NVGPU_RWSEM_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +/* + * struct nvgpu_rwsem + * + * Should be implemented per-OS in a separate library + * But implementation should adhere to rw_semaphore implementation + * as specified in Linux Documentation + */ +struct nvgpu_rwsem; + +void nvgpu_rwsem_init(struct nvgpu_rwsem *rwsem); +void nvgpu_rwsem_up_read(struct nvgpu_rwsem *rwsem); +void nvgpu_rwsem_down_read(struct nvgpu_rwsem *rwsem); +void nvgpu_rwsem_up_write(struct nvgpu_rwsem *rwsem); +void nvgpu_rwsem_down_write(struct nvgpu_rwsem *rwsem); + +#endif /* NVGPU_RWSEM_H */ diff --git a/include/nvgpu/sched.h b/include/nvgpu/sched.h new file mode 100644 index 0000000..c49b7d1 --- /dev/null +++ b/include/nvgpu/sched.h @@ -0,0 +1,42 @@ +/* + * 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_SCHED_COMMON_H +#define __NVGPU_SCHED_COMMON_H + +struct nvgpu_sched_ctrl { + struct nvgpu_mutex control_lock; + bool control_locked; + bool sw_ready; + struct nvgpu_mutex status_lock; + struct nvgpu_mutex busy_lock; + + u64 status; + + size_t bitmap_size; + u64 *active_tsg_bitmap; + u64 *recent_tsg_bitmap; + u64 *ref_tsg_bitmap; + + struct nvgpu_cond readout_wq; +}; + +#endif /* __NVGPU_SCHED_COMMON_H */ diff --git a/include/nvgpu/sec2.h b/include/nvgpu/sec2.h new file mode 100644 index 0000000..7c75584 --- /dev/null +++ b/include/nvgpu/sec2.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_SEC2_H +#define NVGPU_SEC2_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define NVGPU_SEC2_TRACE_BUFSIZE (32U*1024U) + +#define SEC2_MAX_NUM_SEQUENCES (256U) +#define SEC2_SEQ_BIT_SHIFT (5U) +#define SEC2_SEQ_TBL_SIZE \ + (SEC2_MAX_NUM_SEQUENCES >> SEC2_SEQ_BIT_SHIFT) + +#define SEC2_INVALID_SEQ_DESC (~0U) + +enum { + SEC2_SEQ_STATE_FREE = 0U, + SEC2_SEQ_STATE_PENDING, + SEC2_SEQ_STATE_USED, + SEC2_SEQ_STATE_CANCELLED +}; + +typedef void (*sec2_callback)(struct gk20a *, struct nv_flcn_msg_sec2 *, + void *, u32, u32); + +struct sec2_sequence { + u8 id; + u32 state; + u32 desc; + struct nv_flcn_msg_sec2 *msg; + u8 *out_payload; + sec2_callback callback; + void *cb_params; +}; + +struct nvgpu_sec2 { + struct gk20a *g; + struct nvgpu_falcon *flcn; + u32 falcon_id; + + struct nvgpu_falcon_queue queue[SEC2_QUEUE_NUM]; + + struct sec2_sequence *seq; + unsigned long sec2_seq_tbl[SEC2_SEQ_TBL_SIZE]; + u32 next_seq_desc; + struct nvgpu_mutex sec2_seq_lock; + + bool isr_enabled; + struct nvgpu_mutex isr_mutex; + + struct nvgpu_allocator dmem; + + /* set to true once init received */ + bool sec2_ready; + + struct nvgpu_mem trace_buf; + + void (*remove_support)(struct nvgpu_sec2 *sec2); + + u32 command_ack; +}; + +/* sec2 init */ +int nvgpu_init_sec2_support(struct gk20a *g); +int nvgpu_sec2_destroy(struct gk20a *g); + +#endif /* NVGPU_SEC2_H */ diff --git a/include/nvgpu/sec2if/sec2_cmd_if.h b/include/nvgpu/sec2if/sec2_cmd_if.h new file mode 100644 index 0000000..839743f --- /dev/null +++ b/include/nvgpu/sec2if/sec2_cmd_if.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_SEC2_CMD_IF_H +#define NVGPU_SEC2_CMD_IF_H + +#include +#include + +struct nv_flcn_cmd_sec2 { + struct pmu_hdr hdr; + union { + union nv_sec2_acr_cmd acr; + } cmd; +}; + +struct nv_flcn_msg_sec2 { + struct pmu_hdr hdr; + + union { + union nv_flcn_msg_sec2_init init; + union nv_sec2_acr_msg acr; + } msg; +}; + +#define NV_SEC2_UNIT_REWIND NV_FLCN_UNIT_ID_REWIND +#define NV_SEC2_UNIT_INIT (0x01U) +#define NV_SEC2_UNIT_ACR (0x07U) +#define NV_SEC2_UNIT_END (0x0AU) + +#endif /* NVGPU_SEC2_CMD_IF_H */ diff --git a/include/nvgpu/sec2if/sec2_if_acr.h b/include/nvgpu/sec2if/sec2_if_acr.h new file mode 100644 index 0000000..5b41958 --- /dev/null +++ b/include/nvgpu/sec2if/sec2_if_acr.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_SEC2_IF_ACR_H +#define NVGPU_SEC2_IF_ACR_H + +#include + +/* + * ACR Command Types + * _BOOT_FALCON + * NVGPU sends a Falcon ID and LSB offset to SEC2 to boot + * the falcon in LS mode. + * SEC2 needs to hanlde the case since UCODE of falcons are + * stored in secured location on FB. + */ +#define NV_SEC2_ACR_CMD_ID_BOOTSTRAP_FALCON 0U + +/* nvgpu provides the Falcon ID to bootstrap */ +struct nv_sec2_acr_cmd_bootstrap_falcon { + /* Command must be first as this struct is the part of union */ + u8 cmd_type; + + /* Additional bootstrapping flags */ + u32 flags; + + /* ID to identify Falcon, ref LSF_FALCON_ID_ */ + u32 falcon_id; +}; + +#define NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET 0U +#define NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_NO 1U +#define NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES 0U + +/* A union of all ACR Commands */ +union nv_sec2_acr_cmd { + /* Command type */ + u8 cmd_type; + + /* Bootstrap Falcon */ + struct nv_sec2_acr_cmd_bootstrap_falcon bootstrap_falcon; +}; + +/* ACR Message Status */ + +/* Returns the Bootstrapped falcon ID to RM */ +#define NV_SEC2_ACR_MSG_ID_BOOTSTRAP_FALCON 0U + +/* Returns the Error Status for Invalid Command */ +#define NV_SEC2_ACR_MSG_ID_INVALID_COMMAND 2U + +/* + * SEC2 notifies nvgpu about bootstrap status of falcon + */ +struct nv_sec2_acr_msg_bootstrap_falcon { + /* Message must be at start */ + u8 msg_type; + + /* Falcon Error Code returned by message */ + u32 error_code; + + /* Bootstrapped falcon ID by ACR */ + u32 falcon_id; +} ; + +/* + * A union of all ACR Messages. + */ +union nv_sec2_acr_msg { + /* Message type */ + u8 msg_type; + + /* Bootstrap details of falcon and status code */ + struct nv_sec2_acr_msg_bootstrap_falcon msg_flcn; +}; + +#endif /* NVGPU_SEC2_IF_ACR_H */ diff --git a/include/nvgpu/sec2if/sec2_if_cmn.h b/include/nvgpu/sec2if/sec2_if_cmn.h new file mode 100644 index 0000000..a40f8f9 --- /dev/null +++ b/include/nvgpu/sec2if/sec2_if_cmn.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_SEC2_IF_CMN_H +#define NVGPU_SEC2_IF_CMN_H + +/* + * Define the maximum number of command sequences that can be in flight at + * any given time. This is dictated by the width of the sequence number + * id ('seqNumId') stored in each sequence packet (currently 8-bits). + */ +#define NV_SEC2_MAX_NUM_SEQUENCES 256U + +/* + * Compares an unit id against the values in the unit_id enumeration and + * verifies that the id is valid. It is expected that the id is specified + * as an unsigned integer. + */ +#define NV_SEC2_UNITID_IS_VALID(id) (((id) < NV_SEC2_UNIT_END)) + +/* + * Defines the size of the surface/buffer that will be allocated to store + * debug spew from the SEC2 ucode application when falcon-trace is enabled. + */ +#define NV_SEC2_DEBUG_SURFACE_SIZE (32U*1024U) + +/* + * SEC2's frame-buffer interface block has several slots/indices which can + * be bound to support DMA to various surfaces in memory. This is an + * enumeration that gives name to each index based on type of memory-aperture + * the index is used to access. + * + * Pre-Turing, NV_SEC2_DMAIDX_PHYS_VID_FN0 == NV_SEC2_DMAIDX_GUEST_PHYS_VID_BOUND. + * From Turing, engine context is stored in GPA, requiring a separate aperture. + * + * Traditionally, video falcons have used the 6th index for ucode, and we will + * continue to use that to allow legacy ucode to work seamlessly. + * + * Note: DO NOT CHANGE THE VALUE OF NV_SEC2_DMAIDX_UCODE. That value is used by + * both the legacy SEC2 ucode, which assumes that it will use index 6, and by + * SEC2 RTOS. Changing it will break legacy SEC2 ucode, unless it is updated to + * reflect the new value. + */ + +#define NV_SEC2_DMAIDX_GUEST_PHYS_VID_BOUND 0U +#define NV_SEC2_DMAIDX_VIRT 1U +#define NV_SEC2_DMAIDX_PHYS_VID_FN0 2U +#define NV_SEC2_DMAIDX_PHYS_SYS_COH_FN0 3U +#define NV_SEC2_DMAIDX_PHYS_SYS_NCOH_FN0 4U +#define NV_SEC2_DMAIDX_GUEST_PHYS_SYS_COH_BOUND 5U +#define NV_SEC2_DMAIDX_UCODE 6U +#define NV_SEC2_DMAIDX_GUEST_PHYS_SYS_NCOH_BOUND 7U + +#endif /* NVGPU_SEC2_IF_CMN_H */ diff --git a/include/nvgpu/sec2if/sec2_if_sec2.h b/include/nvgpu/sec2if/sec2_if_sec2.h new file mode 100644 index 0000000..c895c41 --- /dev/null +++ b/include/nvgpu/sec2if/sec2_if_sec2.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_SEC2_IF_SEC2_H +#define NVGPU_SEC2_IF_SEC2_H + +/* + * SEC2 Command/Message Interfaces - SEC2 Management + */ + +/* + * Defines the identifiers various high-level types of sequencer commands and + * messages. + * _SEC2_INIT - sec2_init_msg_sec2_init + */ +enum +{ + NV_SEC2_INIT_MSG_ID_SEC2_INIT = 0U, +}; + +/* + * Defines the logical queue IDs that must be used when submitting commands + * to or reading messages from SEC2. The identifiers must begin with zero and + * should increment sequentially. _CMDQ_LOG_ID__LAST must always be set to the + * last command queue identifier. _NUM must always be set to the last + * identifier plus one. + */ +#define SEC2_NV_CMDQ_LOG_ID 0U +#define SEC2_NV_CMDQ_LOG_ID__LAST 0U +#define SEC2_NV_MSGQ_LOG_ID 1U +#define SEC2_QUEUE_NUM 2U + +struct sec2_init_msg_sec2_init { + u8 msg_type; + u8 num_queues; + + u16 os_debug_entry_point; + + struct + { + u32 queue_offset; + u16 queue_size; + u8 queue_phy_id; + u8 queue_log_id; + } q_info[SEC2_QUEUE_NUM]; + + u32 nv_managed_area_offset; + u16 nv_managed_area_size; +}; + +union nv_flcn_msg_sec2_init { + u8 msg_type; + struct sec2_init_msg_sec2_init sec2_init; +}; + +#endif /* NVGPU_SEC2_IF_SEC2_H */ diff --git a/include/nvgpu/semaphore.h b/include/nvgpu/semaphore.h new file mode 100644 index 0000000..94e3be0 --- /dev/null +++ b/include/nvgpu/semaphore.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef SEMAPHORE_GK20A_H +#define SEMAPHORE_GK20A_H + +#include +#include +#include +#include +#include + +#include "gk20a/mm_gk20a.h" + +struct gk20a; + +#define gpu_sema_dbg(g, fmt, args...) \ + nvgpu_log(g, gpu_dbg_sema, fmt, ##args) +#define gpu_sema_verbose_dbg(g, fmt, args...) \ + nvgpu_log(g, gpu_dbg_sema_v, fmt, ##args) + +/* + * Max number of channels that can be used is 512. This of course needs to be + * fixed to be dynamic but still fast. + */ +#define SEMAPHORE_POOL_COUNT 512U +#define SEMAPHORE_SIZE 16U +#define SEMAPHORE_SEA_GROWTH_RATE 32U + +struct nvgpu_semaphore_sea; + +struct nvgpu_semaphore_loc { + struct nvgpu_semaphore_pool *pool; /* Pool that owns this sema. */ + u32 offset; /* Byte offset into the pool. */ +}; + +/* + * Underlying semaphore data structure. This semaphore can be shared amongst + * other semaphore instances. + */ +struct nvgpu_semaphore_int { + struct nvgpu_semaphore_loc location; + nvgpu_atomic_t next_value; /* Next available value. */ + struct channel_gk20a *ch; /* Channel that owns this sema. */ +}; + +/* + * A semaphore which the rest of the driver actually uses. This consists of a + * pointer to a real semaphore and a value to wait for. This allows one physical + * semaphore to be shared among an essentially infinite number of submits. + */ +struct nvgpu_semaphore { + struct gk20a *g; + struct nvgpu_semaphore_loc location; + + nvgpu_atomic_t value; + bool incremented; + + struct nvgpu_ref ref; +}; + +/* + * A semaphore pool. Each address space will own exactly one of these. + */ +struct nvgpu_semaphore_pool { + struct nvgpu_list_node pool_list_entry; /* Node for list of pools. */ + u64 gpu_va; /* GPU access to the pool. */ + u64 gpu_va_ro; /* GPU access to the pool. */ + u64 page_idx; /* Index into sea bitmap. */ + + DECLARE_BITMAP(semas_alloced, PAGE_SIZE / SEMAPHORE_SIZE); + + struct nvgpu_semaphore_sea *sema_sea; /* Sea that owns this pool. */ + + struct nvgpu_mutex pool_lock; + + /* + * This is the address spaces's personal RW table. Other channels will + * ultimately map this page as RO. This is a sub-nvgpu_mem from the + * sea's mem. + */ + struct nvgpu_mem rw_mem; + + bool mapped; + + /* + * Sometimes a channel can be released before other channels are + * done waiting on it. This ref count ensures that the pool doesn't + * go away until all semaphores using this pool are cleaned up first. + */ + struct nvgpu_ref ref; +}; + +static inline struct nvgpu_semaphore_pool * +nvgpu_semaphore_pool_from_pool_list_entry(struct nvgpu_list_node *node) +{ + return (struct nvgpu_semaphore_pool *) + ((uintptr_t)node - + offsetof(struct nvgpu_semaphore_pool, pool_list_entry)); +}; + +/* + * A sea of semaphores pools. Each pool is owned by a single VM. Since multiple + * channels can share a VM each channel gets it's own HW semaphore from the + * pool. Channels then allocate regular semaphores - basically just a value that + * signifies when a particular job is done. + */ +struct nvgpu_semaphore_sea { + struct nvgpu_list_node pool_list; /* List of pools in this sea. */ + struct gk20a *gk20a; + + size_t size; /* Number of pages available. */ + u64 gpu_va; /* GPU virtual address of sema sea. */ + u64 map_size; /* Size of the mapping. */ + + /* + * TODO: + * List of pages that we use to back the pools. The number of pages + * can grow dynamically since allocating 512 pages for all channels at + * once would be a tremendous waste. + */ + int page_count; /* Pages allocated to pools. */ + + /* + * The read-only memory for the entire semaphore sea. Each semaphore + * pool needs a sub-nvgpu_mem that will be mapped as RW in its address + * space. This sea_mem cannot be freed until all semaphore_pools have + * been freed. + */ + struct nvgpu_mem sea_mem; + + /* + * Can't use a regular allocator here since the full range of pools are + * not always allocated. Instead just use a bitmap. + */ + DECLARE_BITMAP(pools_alloced, SEMAPHORE_POOL_COUNT); + + struct nvgpu_mutex sea_lock; /* Lock alloc/free calls. */ +}; + +/* + * Semaphore sea functions. + */ +struct nvgpu_semaphore_sea *nvgpu_semaphore_sea_create(struct gk20a *gk20a); +void nvgpu_semaphore_sea_destroy(struct gk20a *g); +int nvgpu_semaphore_sea_map(struct nvgpu_semaphore_pool *sea, + struct vm_gk20a *vm); +void nvgpu_semaphore_sea_unmap(struct nvgpu_semaphore_pool *sea, + struct vm_gk20a *vm); +struct nvgpu_semaphore_sea *nvgpu_semaphore_get_sea(struct gk20a *g); + +/* + * Semaphore pool functions. + */ +int nvgpu_semaphore_pool_alloc(struct nvgpu_semaphore_sea *sea, + struct nvgpu_semaphore_pool **pool); +int nvgpu_semaphore_pool_map(struct nvgpu_semaphore_pool *pool, + struct vm_gk20a *vm); +void nvgpu_semaphore_pool_unmap(struct nvgpu_semaphore_pool *pool, + struct vm_gk20a *vm); +u64 __nvgpu_semaphore_pool_gpu_va(struct nvgpu_semaphore_pool *p, bool global); +void nvgpu_semaphore_pool_get(struct nvgpu_semaphore_pool *p); +void nvgpu_semaphore_pool_put(struct nvgpu_semaphore_pool *p); + +/* + * Semaphore functions. + */ +struct nvgpu_semaphore *nvgpu_semaphore_alloc(struct channel_gk20a *ch); +void nvgpu_semaphore_put(struct nvgpu_semaphore *s); +void nvgpu_semaphore_get(struct nvgpu_semaphore *s); +void nvgpu_semaphore_free_hw_sema(struct channel_gk20a *ch); + +u64 nvgpu_semaphore_gpu_rw_va(struct nvgpu_semaphore *s); +u64 nvgpu_semaphore_gpu_ro_va(struct nvgpu_semaphore *s); +u64 nvgpu_hw_sema_addr(struct nvgpu_semaphore_int *hw_sema); + +u32 __nvgpu_semaphore_read(struct nvgpu_semaphore_int *hw_sema); +u32 nvgpu_semaphore_read(struct nvgpu_semaphore *s); +u32 nvgpu_semaphore_get_value(struct nvgpu_semaphore *s); +bool nvgpu_semaphore_is_released(struct nvgpu_semaphore *s); +bool nvgpu_semaphore_is_acquired(struct nvgpu_semaphore *s); + +bool nvgpu_semaphore_reset(struct nvgpu_semaphore_int *hw_sema); +void nvgpu_semaphore_prepare(struct nvgpu_semaphore *s, + struct nvgpu_semaphore_int *hw_sema); + +#endif diff --git a/include/nvgpu/sim.h b/include/nvgpu/sim.h new file mode 100644 index 0000000..1d6b15d --- /dev/null +++ b/include/nvgpu/sim.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_SIM_H +#define NVGPU_SIM_H + +#include + +struct gk20a; +struct sim_nvgpu { + struct gk20a *g; + u32 send_ring_put; + u32 recv_ring_get; + u32 recv_ring_put; + u32 sequence_base; + struct nvgpu_mem send_bfr; + struct nvgpu_mem recv_bfr; + struct nvgpu_mem msg_bfr; + void (*sim_init_late)(struct gk20a *); + void (*remove_support)(struct gk20a *); + void (*esc_readl)( + struct gk20a *g, char *path, u32 index, u32 *data); +}; +#ifdef __KERNEL__ +#include "linux/sim.h" +#include "linux/sim_pci.h" +#elif defined(__NVGPU_POSIX__) +/* Nothing for POSIX-nvgpu. */ +#else +#include +#include +#endif +int nvgpu_init_sim_support(struct gk20a *g); +int nvgpu_init_sim_support_pci(struct gk20a *g); +int nvgpu_alloc_sim_buffer(struct gk20a *g, struct nvgpu_mem *mem); +void nvgpu_free_sim_buffer(struct gk20a *g, struct nvgpu_mem *mem); +void nvgpu_free_sim_support(struct gk20a *g); +void nvgpu_remove_sim_support(struct gk20a *g); + +#endif /* NVGPU_SIM_H */ diff --git a/include/nvgpu/sizes.h b/include/nvgpu/sizes.h new file mode 100644 index 0000000..af5e4b2 --- /dev/null +++ b/include/nvgpu/sizes.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_SIZES_H +#define NVGPU_SIZES_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +#endif /* NVGPU_SIZES_H */ diff --git a/include/nvgpu/soc.h b/include/nvgpu/soc.h new file mode 100644 index 0000000..729d8af --- /dev/null +++ b/include/nvgpu/soc.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_SOC_H +#define NVGPU_SOC_H + +#include + +struct gk20a; + +bool nvgpu_platform_is_silicon(struct gk20a *g); +bool nvgpu_platform_is_simulation(struct gk20a *g); +bool nvgpu_platform_is_fpga(struct gk20a *g); +bool nvgpu_is_hypervisor_mode(struct gk20a *g); +bool nvgpu_is_bpmp_running(struct gk20a *g); +bool nvgpu_is_soc_t194_a01(struct gk20a *g); +int nvgpu_init_soc_vars(struct gk20a *g); + +#endif /* NVGPU_SOC_H */ diff --git a/include/nvgpu/sort.h b/include/nvgpu/sort.h new file mode 100644 index 0000000..80bae4b --- /dev/null +++ b/include/nvgpu/sort.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_SORT_H +#define NVGPU_SORT_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +#endif /* NVGPU_SORT_H */ diff --git a/include/nvgpu/therm.h b/include/nvgpu/therm.h new file mode 100644 index 0000000..41808de --- /dev/null +++ b/include/nvgpu/therm.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011-2017, 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_THERM_H +#define NVGPU_THERM_H + +struct gk20a; + +int nvgpu_init_therm_support(struct gk20a *g); + +#endif diff --git a/include/nvgpu/thread.h b/include/nvgpu/thread.h new file mode 100644 index 0000000..eac06ef --- /dev/null +++ b/include/nvgpu/thread.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_THREAD_H +#define NVGPU_THREAD_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +#include + +/** + * nvgpu_thread_create - Create and run a new thread. + * + * @thread - thread structure to use + * @data - data to pass to threadfn + * @threadfn - Thread function + * @name - name of the thread + * + * Create a thread and run threadfn in it. The thread stays alive as long as + * threadfn is running. As soon as threadfn returns the thread is destroyed. + * + * threadfn needs to continuously poll nvgpu_thread_should_stop() to determine + * if it should exit. + */ +int nvgpu_thread_create(struct nvgpu_thread *thread, + void *data, + int (*threadfn)(void *data), const char *name); + +/** + * nvgpu_thread_stop - Destroy or request to destroy a thread + * + * @thread - thread to stop + * + * Request a thread to stop by setting nvgpu_thread_should_stop() to + * true and wait for thread to exit. + */ +void nvgpu_thread_stop(struct nvgpu_thread *thread); + +/** + * nvgpu_thread_should_stop - Query if thread should stop + * + * @thread + * + * Return true if thread should exit. Can be run only in the thread's own + * context and with the thread as parameter. + */ +bool nvgpu_thread_should_stop(struct nvgpu_thread *thread); + +/** + * nvgpu_thread_is_running - Query if thread is running + * + * @thread + * + * Return true if thread is started. + */ +bool nvgpu_thread_is_running(struct nvgpu_thread *thread); + +/** + * nvgpu_thread_join - join a thread to reclaim resources + * after it has exited + * + * @thread - thread to join + * + */ +void nvgpu_thread_join(struct nvgpu_thread *thread); + +#endif /* NVGPU_THREAD_H */ diff --git a/include/nvgpu/timers.h b/include/nvgpu/timers.h new file mode 100644 index 0000000..f69e234 --- /dev/null +++ b/include/nvgpu/timers.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_TIMERS_H +#define NVGPU_TIMERS_H + +#include +#include + +struct gk20a; + +/* + * struct nvgpu_timeout - define a timeout. + * + * There are two types of timer suported: + * + * o NVGPU_TIMER_CPU_TIMER + * Timer uses the CPU to measure the timeout. + * + * o NVGPU_TIMER_RETRY_TIMER + * Instead of measuring a time limit keep track of the number of times + * something has been attempted. After said limit, "expire" the timer. + * + * Available flags: + * + * o NVGPU_TIMER_NO_PRE_SI + * By default when the system is not running on silicon the timeout + * code will ignore the requested timeout. Specifying this flag will + * override that behavior and honor the timeout regardless of platform. + * + * o NVGPU_TIMER_SILENT_TIMEOUT + * Do not print any messages on timeout. Normally a simple message is + * printed that specifies where the timeout occurred. + */ +struct nvgpu_timeout { + struct gk20a *g; + + unsigned int flags; + + union { + s64 time; + struct { + u32 max; + u32 attempted; + } retries; + }; +}; + +/* + * Bit 0 specifies the type of timer: CPU or retry. + */ +#define NVGPU_TIMER_CPU_TIMER (0x0) +#define NVGPU_TIMER_RETRY_TIMER (0x1) + +/* + * Bits 1 through 7 are reserved; bits 8 and up are flags: + */ +#define NVGPU_TIMER_NO_PRE_SI (0x1 << 8) +#define NVGPU_TIMER_SILENT_TIMEOUT (0x1 << 9) + +#define NVGPU_TIMER_FLAG_MASK (NVGPU_TIMER_RETRY_TIMER | \ + NVGPU_TIMER_NO_PRE_SI | \ + NVGPU_TIMER_SILENT_TIMEOUT) + +int nvgpu_timeout_init(struct gk20a *g, struct nvgpu_timeout *timeout, + u32 duration, unsigned long flags); +int nvgpu_timeout_peek_expired(struct nvgpu_timeout *timeout); + +#define nvgpu_timeout_expired(__timeout) \ + __nvgpu_timeout_expired_msg(__timeout, _NVGPU_GET_IP_, "") + +#define nvgpu_timeout_expired_msg(__timeout, fmt, args...) \ + __nvgpu_timeout_expired_msg(__timeout, _NVGPU_GET_IP_, \ + fmt, ##args) + +/* + * Don't use this directly. + */ +int __nvgpu_timeout_expired_msg(struct nvgpu_timeout *timeout, + void *caller, const char *fmt, ...); + + +/* + * Waits and delays. + */ +void nvgpu_msleep(unsigned int msecs); +void nvgpu_usleep_range(unsigned int min_us, unsigned int max_us); +void nvgpu_udelay(unsigned int usecs); + +/* + * Timekeeping. + */ +s64 nvgpu_current_time_ms(void); +s64 nvgpu_current_time_ns(void); +u64 nvgpu_hr_timestamp(void); + +#endif /* NVGPU_TIMERS_H */ diff --git a/include/nvgpu/tsg.h b/include/nvgpu/tsg.h new file mode 100644 index 0000000..7cd97c9 --- /dev/null +++ b/include/nvgpu/tsg.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2014-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 TSG_GK20A_H +#define TSG_GK20A_H + +#include +#include +#include + +#include "gk20a/gr_gk20a.h" + +#define NVGPU_INVALID_TSG_ID (U32_MAX) + +struct channel_gk20a; + +struct tsg_gk20a *gk20a_tsg_open(struct gk20a *g, pid_t pid); +void gk20a_tsg_release(struct nvgpu_ref *ref); + +int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid); +struct tsg_gk20a *tsg_gk20a_from_ch(struct channel_gk20a *ch); + +struct nvgpu_tsg_sm_error_state { + u32 hww_global_esr; + u32 hww_warp_esr; + u64 hww_warp_esr_pc; + u32 hww_global_esr_report_mask; + u32 hww_warp_esr_report_mask; +}; + +struct tsg_gk20a { + struct gk20a *g; + + struct vm_gk20a *vm; + struct nvgpu_mem *eng_method_buffers; + + + struct nvgpu_gr_ctx gr_ctx; + struct nvgpu_ref refcount; + + struct nvgpu_list_node ch_list; + struct nvgpu_list_node event_id_list; + struct nvgpu_rwsem ch_list_lock; + struct nvgpu_mutex event_id_list_lock; + int num_active_channels; + + unsigned int timeslice_us; + unsigned int timeslice_timeout; + unsigned int timeslice_scale; + + u32 interleave_level; + u32 tsgid; + + u32 runlist_id; + pid_t tgid; + u32 num_active_tpcs; + u8 tpc_pg_enabled; + bool tpc_num_initialized; + bool in_use; + + /* MMU debug mode enabled if mmu_debug_mode_refcnt > 0 */ + u32 mmu_debug_mode_refcnt; + + struct nvgpu_tsg_sm_error_state *sm_error_states; + +#define NVGPU_SM_EXCEPTION_TYPE_MASK_NONE (0x0U) +#define NVGPU_SM_EXCEPTION_TYPE_MASK_FATAL (0x1U << 0) + u32 sm_exception_mask_type; +}; + +int gk20a_enable_tsg(struct tsg_gk20a *tsg); +int gk20a_disable_tsg(struct tsg_gk20a *tsg); +int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, + struct channel_gk20a *ch); +int gk20a_tsg_unbind_channel(struct channel_gk20a *ch); + +void gk20a_tsg_event_id_post_event(struct tsg_gk20a *tsg, + int event_id); +int gk20a_tsg_set_runlist_interleave(struct tsg_gk20a *tsg, u32 level); +int gk20a_tsg_set_timeslice(struct tsg_gk20a *tsg, u32 timeslice); +u32 gk20a_tsg_get_timeslice(struct tsg_gk20a *tsg); +int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg, + u32 priority); +int gk20a_tsg_alloc_sm_error_states_mem(struct gk20a *g, + struct tsg_gk20a *tsg, + u32 num_sm); +void gk20a_tsg_update_sm_error_state_locked(struct tsg_gk20a *tsg, + u32 sm_id, + struct nvgpu_tsg_sm_error_state *sm_error_state); + +struct gk20a_event_id_data { + struct gk20a *g; + + int id; /* ch or tsg */ + int pid; + u32 event_id; + + bool event_posted; + + struct nvgpu_cond event_id_wq; + struct nvgpu_mutex lock; + struct nvgpu_list_node event_id_node; +}; + +static inline struct gk20a_event_id_data * +gk20a_event_id_data_from_event_id_node(struct nvgpu_list_node *node) +{ + return (struct gk20a_event_id_data *) + ((uintptr_t)node - offsetof(struct gk20a_event_id_data, event_id_node)); +}; + +int nvgpu_tsg_set_mmu_debug_mode(struct channel_gk20a *ch, bool enable); + +#endif /* TSG_GK20A_H */ diff --git a/include/nvgpu/types.h b/include/nvgpu/types.h new file mode 100644 index 0000000..0cb847b --- /dev/null +++ b/include/nvgpu/types.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_TYPES_H +#define NVGPU_TYPES_H + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +#include +#endif + +/* + * These macros exist to make integer literals used in certain arithmetic + * operations explicitly large enough to hold the results of that operation. + * The following is an example of this. + * + * In MISRA the destination for a bitwise shift must be able to hold the number + * of bits shifted. Otherwise the results are undefined. For example: + * + * 256U << 20U + * + * This is valid C code but the results of this _may_ be undefined if the size + * of an unsigned by default is less than 24 bits (i.e 16 bits). The MISRA + * checker sees the 256U and determines that the 256U fits in a 16 bit data type + * (i.e a u16). Since a u16 has 16 bits, which is less than 20, this is an + * issue. + * + * Of course most compilers these days use 32 bits for the default unsigned type + * this is not a requirement. Moreover this same problem could exist like so: + * + * 0xfffffU << 40U + * + * The 0xfffffU is a 32 bit unsigned type; but we are shifting 40 bits which + * overflows the 32 bit data type. So in this case we need an explicit cast to + * 64 bits in order to prevent undefined behavior. + */ +#define U8(x) ((u8)(x)) +#define U16(x) ((u16)(x)) +#define U32(x) ((u32)(x)) +#define U64(x) ((u64)(x)) + +/* Linux uses U8_MAX instead of UCHAR_MAX. We define it here for non-Linux + * OSes + */ +#if !defined(__KERNEL__) && !defined(U8_MAX) +#define U8_MAX ((u8)255) +#define U32_MAX ((u32)~0U) +#endif + +#endif /* NVGPU_TYPES_H */ diff --git a/include/nvgpu/unit.h b/include/nvgpu/unit.h new file mode 100644 index 0000000..11df652 --- /dev/null +++ b/include/nvgpu/unit.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_UNIT_H +#define NVGPU_UNIT_H + +/* + * Enumeration of all units intended to be used by any HAL that requires + * unit as parameter. + * + * Units are added to the enumeration as needed, so it is not complete. + */ +enum nvgpu_unit { + NVGPU_UNIT_FIFO, + NVGPU_UNIT_PERFMON, + NVGPU_UNIT_GRAPH, + NVGPU_UNIT_BLG, + NVGPU_UNIT_PWR, + NVGPU_UNIT_NVDEC, +}; + +#endif /* NVGPU_UNIT_H */ diff --git a/include/nvgpu/utils.h b/include/nvgpu/utils.h new file mode 100644 index 0000000..6184608 --- /dev/null +++ b/include/nvgpu/utils.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_UTILS_H +#define NVGPU_UTILS_H + +#include + +static inline u32 u64_hi32(u64 n) +{ + return (u32)((n >> 32) & ~(u32)0); +} + +static inline u32 u64_lo32(u64 n) +{ + return (u32)(n & ~(u32)0); +} + +static inline u64 hi32_lo32_to_u64(u32 hi, u32 lo) +{ + return (((u64)hi) << 32) | (u64)lo; +} + +static inline u32 set_field(u32 val, u32 mask, u32 field) +{ + return ((val & ~mask) | field); +} + +static inline u32 get_field(u32 reg, u32 mask) +{ + return (reg & mask); +} + +/* + * MISRA Rule 11.6 compliant IP address generator. + */ +#define _NVGPU_GET_IP_ ({ __label__ __here; __here: &&__here; }) + +#endif /* NVGPU_UTILS_H */ diff --git a/include/nvgpu/vgpu/tegra_vgpu.h b/include/nvgpu/vgpu/tegra_vgpu.h new file mode 100644 index 0000000..e33dce9 --- /dev/null +++ b/include/nvgpu/vgpu/tegra_vgpu.h @@ -0,0 +1,817 @@ +/* + * Tegra GPU Virtualization Interfaces to Server + * + * Copyright (c) 2014-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 TEGRA_VGPU_H +#define TEGRA_VGPU_H + +#include +#include /* For NVGPU_ECC_STAT_NAME_MAX_SIZE */ + +enum { + TEGRA_VGPU_MODULE_GPU = 0, +}; + +enum { + /* Needs to follow last entry in TEGRA_VHOST_QUEUE_* list, + * in tegra_vhost.h + */ + TEGRA_VGPU_QUEUE_CMD = 3, + TEGRA_VGPU_QUEUE_INTR +}; + +enum { + TEGRA_VGPU_CMD_CONNECT = 0, + TEGRA_VGPU_CMD_DISCONNECT = 1, + TEGRA_VGPU_CMD_ABORT = 2, + TEGRA_VGPU_CMD_CHANNEL_ALLOC_HWCTX = 3, + TEGRA_VGPU_CMD_CHANNEL_FREE_HWCTX = 4, + TEGRA_VGPU_CMD_GET_ATTRIBUTE = 5, + TEGRA_VGPU_CMD_MAP_BAR1 = 6, + TEGRA_VGPU_CMD_AS_ALLOC_SHARE = 7, + TEGRA_VGPU_CMD_AS_BIND_SHARE = 8, + TEGRA_VGPU_CMD_AS_FREE_SHARE = 9, + TEGRA_VGPU_CMD_AS_UNMAP = 11, + TEGRA_VGPU_CMD_CHANNEL_BIND = 13, + TEGRA_VGPU_CMD_CHANNEL_UNBIND = 14, + TEGRA_VGPU_CMD_CHANNEL_DISABLE = 15, + TEGRA_VGPU_CMD_CHANNEL_PREEMPT = 16, + TEGRA_VGPU_CMD_CHANNEL_SETUP_RAMFC = 17, + TEGRA_VGPU_CMD_CHANNEL_COMMIT_GR_CTX = 20, + TEGRA_VGPU_CMD_CHANNEL_ALLOC_GR_PATCH_CTX = 21, + TEGRA_VGPU_CMD_CHANNEL_FREE_GR_PATCH_CTX = 22, + TEGRA_VGPU_CMD_CHANNEL_MAP_GR_GLOBAL_CTX = 23, + TEGRA_VGPU_CMD_CHANNEL_UNMAP_GR_GLOBAL_CTX = 24, + TEGRA_VGPU_CMD_CHANNEL_COMMIT_GR_GLOBAL_CTX = 25, + TEGRA_VGPU_CMD_CHANNEL_LOAD_GR_GOLDEN_CTX = 26, + TEGRA_VGPU_CMD_CHANNEL_BIND_ZCULL = 27, + TEGRA_VGPU_CMD_CACHE_MAINT = 28, + TEGRA_VGPU_CMD_SUBMIT_RUNLIST = 29, + TEGRA_VGPU_CMD_GET_ZCULL_INFO = 30, + TEGRA_VGPU_CMD_ZBC_SET_TABLE = 31, + TEGRA_VGPU_CMD_ZBC_QUERY_TABLE = 32, + TEGRA_VGPU_CMD_AS_MAP_EX = 33, + TEGRA_VGPU_CMD_CHANNEL_BIND_GR_CTXSW_BUFFERS = 34, + TEGRA_VGPU_CMD_SET_MMU_DEBUG_MODE = 35, + TEGRA_VGPU_CMD_SET_SM_DEBUG_MODE = 36, + TEGRA_VGPU_CMD_REG_OPS = 37, + TEGRA_VGPU_CMD_CHANNEL_SET_PRIORITY = 38, + TEGRA_VGPU_CMD_CHANNEL_SET_RUNLIST_INTERLEAVE = 39, + TEGRA_VGPU_CMD_CHANNEL_SET_TIMESLICE = 40, + TEGRA_VGPU_CMD_FECS_TRACE_ENABLE = 41, + TEGRA_VGPU_CMD_FECS_TRACE_DISABLE = 42, + TEGRA_VGPU_CMD_FECS_TRACE_POLL = 43, + TEGRA_VGPU_CMD_FECS_TRACE_SET_FILTER = 44, + TEGRA_VGPU_CMD_CHANNEL_SET_SMPC_CTXSW_MODE = 45, + TEGRA_VGPU_CMD_CHANNEL_SET_HWPM_CTXSW_MODE = 46, + TEGRA_VGPU_CMD_CHANNEL_FREE_HWPM_CTX = 47, + TEGRA_VGPU_CMD_GR_CTX_ALLOC = 48, + TEGRA_VGPU_CMD_GR_CTX_FREE = 49, + TEGRA_VGPU_CMD_CHANNEL_BIND_GR_CTX = 50, + TEGRA_VGPU_CMD_TSG_BIND_GR_CTX = 51, + TEGRA_VGPU_CMD_TSG_BIND_CHANNEL = 52, + TEGRA_VGPU_CMD_TSG_UNBIND_CHANNEL = 53, + TEGRA_VGPU_CMD_TSG_PREEMPT = 54, + TEGRA_VGPU_CMD_TSG_SET_TIMESLICE = 55, + TEGRA_VGPU_CMD_TSG_SET_RUNLIST_INTERLEAVE = 56, + TEGRA_VGPU_CMD_CHANNEL_FORCE_RESET = 57, + TEGRA_VGPU_CMD_CHANNEL_ENABLE = 58, + TEGRA_VGPU_CMD_READ_PTIMER = 59, + TEGRA_VGPU_CMD_SET_POWERGATE = 60, + TEGRA_VGPU_CMD_SET_GPU_CLK_RATE = 61, + TEGRA_VGPU_CMD_GET_CONSTANTS = 62, + TEGRA_VGPU_CMD_CHANNEL_CYCLESTATS_SNAPSHOT = 63, + TEGRA_VGPU_CMD_TSG_OPEN = 64, + TEGRA_VGPU_CMD_GET_GPU_LOAD = 65, + TEGRA_VGPU_CMD_SUSPEND_CONTEXTS = 66, + TEGRA_VGPU_CMD_RESUME_CONTEXTS = 67, + TEGRA_VGPU_CMD_CLEAR_SM_ERROR_STATE = 68, + TEGRA_VGPU_CMD_GET_GPU_CLK_RATE = 69, + TEGRA_VGPU_CMD_GET_GPU_FREQ_TABLE = 70, + TEGRA_VGPU_CMD_CAP_GPU_CLK_RATE = 71, + TEGRA_VGPU_CMD_PROF_MGT = 72, + TEGRA_VGPU_CMD_PERFBUF_MGT = 73, + TEGRA_VGPU_CMD_GET_TIMESTAMPS_ZIPPER = 74, + TEGRA_VGPU_CMD_TSG_RELEASE = 75, + TEGRA_VGPU_CMD_GET_VSMS_MAPPING = 76, + TEGRA_VGPU_CMD_ALLOC_CTX_HEADER = 77, + TEGRA_VGPU_CMD_FREE_CTX_HEADER = 78, + TEGRA_VGPU_CMD_MAP_SYNCPT = 79, + TEGRA_VGPU_CMD_TSG_BIND_CHANNEL_EX = 80, + TEGRA_VGPU_CMD_UPDATE_PC_SAMPLING = 81, + TEGRA_VGPU_CMD_SUSPEND = 82, + TEGRA_VGPU_CMD_RESUME = 83, + TEGRA_VGPU_CMD_GET_ECC_INFO = 84, + TEGRA_VGPU_CMD_GET_ECC_COUNTER_VALUE = 85, + TEGRA_VGPU_CMD_FB_SET_MMU_DEBUG_MODE = 88, + TEGRA_VGPU_CMD_GR_SET_MMU_DEBUG_MODE = 89, +}; + +struct tegra_vgpu_connect_params { + u32 module; + u64 handle; +}; + +struct tegra_vgpu_channel_hwctx_params { + u32 id; + u64 pid; + u64 handle; +}; + +struct tegra_vgpu_attrib_params { + u32 attrib; + u32 value; +}; + +struct tegra_vgpu_as_share_params { + u64 size; + u64 handle; + u32 big_page_size; +}; + +struct tegra_vgpu_as_bind_share_params { + u64 as_handle; + u64 chan_handle; +}; + +enum { + TEGRA_VGPU_MAP_PROT_NONE = 0, + TEGRA_VGPU_MAP_PROT_READ_ONLY, + TEGRA_VGPU_MAP_PROT_WRITE_ONLY +}; + +struct tegra_vgpu_as_map_params { + u64 handle; + u64 addr; + u64 gpu_va; + u64 size; + u8 pgsz_idx; + u8 iova; + u8 kind; + u8 cacheable; + u8 clear_ctags; + u8 prot; + u32 ctag_offset; +}; + +#define TEGRA_VGPU_MAP_CACHEABLE (1 << 0) +#define TEGRA_VGPU_MAP_IO_COHERENT (1 << 1) +#define TEGRA_VGPU_MAP_L3_ALLOC (1 << 2) +#define TEGRA_VGPU_MAP_PLATFORM_ATOMIC (1 << 3) + +struct tegra_vgpu_as_map_ex_params { + u64 handle; + u64 gpu_va; + u64 size; + u32 mem_desc_count; + u8 pgsz_idx; + u8 iova; + u8 kind; + u32 flags; + u8 clear_ctags; + u8 prot; + u32 ctag_offset; +}; + +struct tegra_vgpu_mem_desc { + u64 addr; + u64 length; +}; + +struct tegra_vgpu_channel_config_params { + u64 handle; +}; + +struct tegra_vgpu_ramfc_params { + u64 handle; + u64 gpfifo_va; + u32 num_entries; + u64 userd_addr; + u8 iova; +}; + +struct tegra_vgpu_ch_ctx_params { + u64 handle; + u64 gr_ctx_va; + u64 patch_ctx_va; + u64 cb_va; + u64 attr_va; + u64 page_pool_va; + u64 priv_access_map_va; + u64 fecs_trace_va; + u32 class_num; +}; + +struct tegra_vgpu_zcull_bind_params { + u64 handle; + u64 zcull_va; + u32 mode; +}; + +enum { + TEGRA_VGPU_L2_MAINT_FLUSH = 0, + TEGRA_VGPU_L2_MAINT_INV, + TEGRA_VGPU_L2_MAINT_FLUSH_INV, + TEGRA_VGPU_FB_FLUSH +}; + +struct tegra_vgpu_cache_maint_params { + u8 op; +}; + +struct tegra_vgpu_runlist_params { + u8 runlist_id; + u32 num_entries; +}; + +struct tegra_vgpu_golden_ctx_params { + u32 size; +}; + +struct tegra_vgpu_zcull_info_params { + u32 width_align_pixels; + u32 height_align_pixels; + u32 pixel_squares_by_aliquots; + u32 aliquot_total; + u32 region_byte_multiplier; + u32 region_header_size; + u32 subregion_header_size; + u32 subregion_width_align_pixels; + u32 subregion_height_align_pixels; + u32 subregion_count; +}; + +#define TEGRA_VGPU_ZBC_COLOR_VALUE_SIZE 4 +#define TEGRA_VGPU_ZBC_TYPE_INVALID 0 +#define TEGRA_VGPU_ZBC_TYPE_COLOR 1 +#define TEGRA_VGPU_ZBC_TYPE_DEPTH 2 + +struct tegra_vgpu_zbc_set_table_params { + u32 color_ds[TEGRA_VGPU_ZBC_COLOR_VALUE_SIZE]; + u32 color_l2[TEGRA_VGPU_ZBC_COLOR_VALUE_SIZE]; + u32 depth; + u32 format; + u32 type; /* color or depth */ +}; + +struct tegra_vgpu_zbc_query_table_params { + u32 color_ds[TEGRA_VGPU_ZBC_COLOR_VALUE_SIZE]; + u32 color_l2[TEGRA_VGPU_ZBC_COLOR_VALUE_SIZE]; + u32 depth; + u32 ref_cnt; + u32 format; + u32 type; /* color or depth */ + u32 index_size; /* [out] size, [in] index */ +}; + +enum { + TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_MAIN, + TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_SPILL, + TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_PAGEPOOL, + TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_BETACB, + TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_LAST +}; + +enum { + TEGRA_VGPU_GR_CTXSW_PREEMPTION_MODE_WFI, + TEGRA_VGPU_GR_CTXSW_PREEMPTION_MODE_GFX_GFXP, + TEGRA_VGPU_GR_CTXSW_PREEMPTION_MODE_COMPUTE_CTA, + TEGRA_VGPU_GR_CTXSW_PREEMPTION_MODE_COMPUTE_CILP, + TEGRA_VGPU_GR_CTXSW_PREEMPTION_MODE_LAST +}; + +struct tegra_vgpu_gr_bind_ctxsw_buffers_params { + u64 handle; /* deprecated */ + u64 gpu_va[TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_LAST]; + u64 size[TEGRA_VGPU_GR_BIND_CTXSW_BUFFER_LAST]; + u32 mode; + u64 gr_ctx_handle; +}; + +struct tegra_vgpu_mmu_debug_mode { + u32 enable; +}; + +struct tegra_vgpu_sm_debug_mode { + u64 handle; + u64 sms; + u32 enable; +}; + +struct tegra_vgpu_reg_op { + u8 op; + u8 type; + u8 status; + u8 quad; + u32 group_mask; + u32 sub_group_mask; + u32 offset; + u32 value_lo; + u32 value_hi; + u32 and_n_mask_lo; + u32 and_n_mask_hi; +}; + +struct tegra_vgpu_reg_ops_params { + u64 handle; + u64 num_ops; + u32 is_profiler; +}; + +struct tegra_vgpu_channel_priority_params { + u64 handle; + u32 priority; +}; + +/* level follows nvgpu.h definitions */ +struct tegra_vgpu_channel_runlist_interleave_params { + u64 handle; + u32 level; +}; + +struct tegra_vgpu_channel_timeslice_params { + u64 handle; + u32 timeslice_us; +}; + +#define TEGRA_VGPU_FECS_TRACE_FILTER_SIZE 256 +struct tegra_vgpu_fecs_trace_filter { + u64 tag_bits[(TEGRA_VGPU_FECS_TRACE_FILTER_SIZE + 63) / 64]; +}; + +enum { + TEGRA_VGPU_CTXSW_MODE_NO_CTXSW = 0, + TEGRA_VGPU_CTXSW_MODE_CTXSW, + TEGRA_VGPU_CTXSW_MODE_STREAM_OUT_CTXSW, +}; + +enum { + TEGRA_VGPU_DISABLE_SAMPLING = 0, + TEGRA_VGPU_ENABLE_SAMPLING, +}; +struct tegra_vgpu_channel_set_ctxsw_mode { + u64 handle; + u64 gpu_va; + u32 mode; +}; + +struct tegra_vgpu_channel_update_pc_sampling { + u64 handle; + u32 mode; +}; + +struct tegra_vgpu_channel_free_hwpm_ctx { + u64 handle; +}; + +struct tegra_vgpu_ecc_info_params { + u32 ecc_stats_count; +}; + +struct tegra_vgpu_ecc_info_entry { + u32 ecc_id; + char name[NVGPU_ECC_STAT_NAME_MAX_SIZE]; +}; + +struct tegra_vgpu_ecc_counter_params { + u32 ecc_id; + u32 value; +}; + +struct tegra_vgpu_gr_ctx_params { + u64 gr_ctx_handle; + u64 as_handle; + u64 gr_ctx_va; + u32 class_num; + u32 tsg_id; +}; + +struct tegra_vgpu_channel_bind_gr_ctx_params { + u64 ch_handle; + u64 gr_ctx_handle; +}; + +struct tegra_vgpu_tsg_bind_gr_ctx_params { + u32 tsg_id; + u64 gr_ctx_handle; +}; + +struct tegra_vgpu_tsg_bind_unbind_channel_params { + u32 tsg_id; + u64 ch_handle; +}; + +struct tegra_vgpu_tsg_preempt_params { + u32 tsg_id; +}; + +struct tegra_vgpu_tsg_timeslice_params { + u32 tsg_id; + u32 timeslice_us; +}; + +struct tegra_vgpu_tsg_open_rel_params { + u32 tsg_id; +}; + +/* level follows nvgpu.h definitions */ +struct tegra_vgpu_tsg_runlist_interleave_params { + u32 tsg_id; + u32 level; +}; + +struct tegra_vgpu_read_ptimer_params { + u64 time; +}; + +#define TEGRA_VGPU_GET_TIMESTAMPS_ZIPPER_MAX_COUNT 16 +#define TEGRA_VGPU_GET_TIMESTAMPS_ZIPPER_SRC_ID_TSC 1 +struct tegra_vgpu_get_timestamps_zipper_params { + /* timestamp pairs */ + struct { + /* gpu timestamp value */ + u64 cpu_timestamp; + /* raw GPU counter (PTIMER) value */ + u64 gpu_timestamp; + } samples[TEGRA_VGPU_GET_TIMESTAMPS_ZIPPER_MAX_COUNT]; + /* number of pairs to read */ + u32 count; + /* cpu clock source id */ + u32 source_id; +}; + +#define TEGRA_VGPU_POWERGATE_MODE_ENABLE 1 +#define TEGRA_VGPU_POWERGATE_MODE_DISABLE 2 +struct tegra_vgpu_set_powergate_params { + u32 mode; +}; + +struct tegra_vgpu_gpu_clk_rate_params { + u32 rate; /* in kHz */ +}; + +/* TEGRA_VGPU_MAX_ENGINES must be equal or greater than num_engines */ +#define TEGRA_VGPU_MAX_ENGINES 4 +struct tegra_vgpu_engines_info { + u32 num_engines; + struct engineinfo { + u32 engine_id; + u32 intr_mask; + u32 reset_mask; + u32 runlist_id; + u32 pbdma_id; + u32 inst_id; + u32 pri_base; + u32 engine_enum; + u32 fault_id; + } info[TEGRA_VGPU_MAX_ENGINES]; +}; + +#define TEGRA_VGPU_MAX_GPC_COUNT 16 +#define TEGRA_VGPU_MAX_TPC_COUNT_PER_GPC 16 +#define TEGRA_VGPU_L2_EN_MASK 32 + +struct tegra_vgpu_constants_params { + u32 arch; + u32 impl; + u32 rev; + u32 max_freq; + u32 num_channels; + u32 golden_ctx_size; + u32 zcull_ctx_size; + u32 l2_size; + u32 ltc_count; + u32 cacheline_size; + u32 slices_per_ltc; + u32 comptags_per_cacheline; + u32 comptag_lines; + u32 sm_arch_sm_version; + u32 sm_arch_spa_version; + u32 sm_arch_warp_count; + u32 max_gpc_count; + u32 gpc_count; + u32 max_tpc_per_gpc_count; + u32 num_fbps; + u32 fbp_en_mask; + u32 ltc_per_fbp; + u32 max_lts_per_ltc; + u8 gpc_tpc_count[TEGRA_VGPU_MAX_GPC_COUNT]; + /* mask bits should be equal or larger than + * TEGRA_VGPU_MAX_TPC_COUNT_PER_GPC + */ + u16 gpc_tpc_mask[TEGRA_VGPU_MAX_GPC_COUNT]; + u32 hwpm_ctx_size; + u8 force_preempt_mode; + u8 can_set_clkrate; + u32 default_timeslice_us; + u32 preempt_ctx_size; + u32 channel_base; + struct tegra_vgpu_engines_info engines_info; + u32 num_pce; + u32 sm_per_tpc; + u32 max_subctx_count; + u32 l2_en_mask[TEGRA_VGPU_L2_EN_MASK]; +}; + +enum { + TEGRA_VGPU_CYCLE_STATS_SNAPSHOT_CMD_FLUSH = 0, + TEGRA_VGPU_CYCLE_STATS_SNAPSHOT_CMD_ATTACH = 1, + TEGRA_VGPU_CYCLE_STATS_SNAPSHOT_CMD_DETACH = 2, +}; + +struct tegra_vgpu_channel_cyclestats_snapshot_params { + u64 handle; + u32 perfmon_start; + u32 perfmon_count; + u32 buf_info; /* client->srvr: get ptr; srvr->client: num pending */ + u8 subcmd; + u8 hw_overflow; +}; + +struct tegra_vgpu_gpu_load_params { + u32 load; +}; + +struct tegra_vgpu_suspend_resume_contexts { + u32 num_channels; + u16 resident_chid; +}; + +struct tegra_vgpu_clear_sm_error_state { + u64 handle; + u32 sm_id; +}; + +enum { + TEGRA_VGPU_PROF_GET_GLOBAL = 0, + TEGRA_VGPU_PROF_GET_CONTEXT, + TEGRA_VGPU_PROF_RELEASE +}; + +struct tegra_vgpu_prof_mgt_params { + u32 mode; +}; + +struct tegra_vgpu_perfbuf_mgt_params { + u64 vm_handle; + u64 offset; + u32 size; +}; + +#define TEGRA_VGPU_GPU_FREQ_TABLE_SIZE 25 + +struct tegra_vgpu_get_gpu_freq_table_params { + u32 num_freqs; +}; + +struct tegra_vgpu_vsms_mapping_params { + u32 num_sm; +}; + +struct tegra_vgpu_vsms_mapping_entry { + u32 gpc_index; + u32 tpc_index; + u32 sm_index; + u32 global_tpc_index; +}; + +struct tegra_vgpu_alloc_ctx_header_params { + u64 ch_handle; + u64 ctx_header_va; +}; + +struct tegra_vgpu_free_ctx_header_params { + u64 ch_handle; +}; + +struct tegra_vgpu_map_syncpt_params { + u64 as_handle; + u64 gpu_va; + u64 len; + u64 offset; + u8 prot; +}; + +struct tegra_vgpu_tsg_bind_channel_ex_params { + u32 tsg_id; + u64 ch_handle; + u32 subctx_id; + u32 runqueue_sel; +}; + +struct tegra_vgpu_fb_set_mmu_debug_mode_params { + u8 enable; +}; + +struct tegra_vgpu_gr_set_mmu_debug_mode_params { + u64 ch_handle; + u8 enable; +}; + +struct tegra_vgpu_cmd_msg { + u32 cmd; + int ret; + u64 handle; + union { + struct tegra_vgpu_connect_params connect; + struct tegra_vgpu_channel_hwctx_params channel_hwctx; + struct tegra_vgpu_attrib_params attrib; + struct tegra_vgpu_as_share_params as_share; + struct tegra_vgpu_as_bind_share_params as_bind_share; + struct tegra_vgpu_as_map_params as_map; + struct tegra_vgpu_as_map_ex_params as_map_ex; + struct tegra_vgpu_channel_config_params channel_config; + struct tegra_vgpu_ramfc_params ramfc; + struct tegra_vgpu_ch_ctx_params ch_ctx; + struct tegra_vgpu_zcull_bind_params zcull_bind; + struct tegra_vgpu_cache_maint_params cache_maint; + struct tegra_vgpu_runlist_params runlist; + struct tegra_vgpu_golden_ctx_params golden_ctx; + struct tegra_vgpu_zcull_info_params zcull_info; + struct tegra_vgpu_zbc_set_table_params zbc_set_table; + struct tegra_vgpu_zbc_query_table_params zbc_query_table; + struct tegra_vgpu_gr_bind_ctxsw_buffers_params gr_bind_ctxsw_buffers; + struct tegra_vgpu_mmu_debug_mode mmu_debug_mode; + struct tegra_vgpu_sm_debug_mode sm_debug_mode; + struct tegra_vgpu_reg_ops_params reg_ops; + struct tegra_vgpu_channel_priority_params channel_priority; + struct tegra_vgpu_channel_runlist_interleave_params channel_interleave; + struct tegra_vgpu_channel_timeslice_params channel_timeslice; + struct tegra_vgpu_fecs_trace_filter fecs_trace_filter; + struct tegra_vgpu_channel_set_ctxsw_mode set_ctxsw_mode; + struct tegra_vgpu_channel_free_hwpm_ctx free_hwpm_ctx; + struct tegra_vgpu_gr_ctx_params gr_ctx; + struct tegra_vgpu_channel_bind_gr_ctx_params ch_bind_gr_ctx; + struct tegra_vgpu_tsg_bind_gr_ctx_params tsg_bind_gr_ctx; + struct tegra_vgpu_tsg_bind_unbind_channel_params tsg_bind_unbind_channel; + struct tegra_vgpu_tsg_open_rel_params tsg_open; + struct tegra_vgpu_tsg_open_rel_params tsg_release; + struct tegra_vgpu_tsg_preempt_params tsg_preempt; + struct tegra_vgpu_tsg_timeslice_params tsg_timeslice; + struct tegra_vgpu_tsg_runlist_interleave_params tsg_interleave; + struct tegra_vgpu_read_ptimer_params read_ptimer; + struct tegra_vgpu_set_powergate_params set_powergate; + struct tegra_vgpu_gpu_clk_rate_params gpu_clk_rate; + struct tegra_vgpu_constants_params constants; + struct tegra_vgpu_channel_cyclestats_snapshot_params cyclestats_snapshot; + struct tegra_vgpu_gpu_load_params gpu_load; + struct tegra_vgpu_suspend_resume_contexts suspend_contexts; + struct tegra_vgpu_suspend_resume_contexts resume_contexts; + struct tegra_vgpu_clear_sm_error_state clear_sm_error_state; + struct tegra_vgpu_prof_mgt_params prof_management; + struct tegra_vgpu_perfbuf_mgt_params perfbuf_management; + struct tegra_vgpu_get_timestamps_zipper_params get_timestamps_zipper; + struct tegra_vgpu_get_gpu_freq_table_params get_gpu_freq_table; + struct tegra_vgpu_vsms_mapping_params vsms_mapping; + struct tegra_vgpu_alloc_ctx_header_params alloc_ctx_header; + struct tegra_vgpu_free_ctx_header_params free_ctx_header; + struct tegra_vgpu_map_syncpt_params map_syncpt; + struct tegra_vgpu_tsg_bind_channel_ex_params tsg_bind_channel_ex; + struct tegra_vgpu_channel_update_pc_sampling update_pc_sampling; + struct tegra_vgpu_ecc_info_params ecc_info; + struct tegra_vgpu_ecc_counter_params ecc_counter; + struct tegra_vgpu_fb_set_mmu_debug_mode_params fb_set_mmu_debug_mode; + struct tegra_vgpu_gr_set_mmu_debug_mode_params gr_set_mmu_debug_mode; + char padding[192]; + } params; +}; + +enum { + TEGRA_VGPU_GR_INTR_NOTIFY = 0, + TEGRA_VGPU_GR_INTR_SEMAPHORE_TIMEOUT = 1, + TEGRA_VGPU_GR_INTR_ILLEGAL_NOTIFY = 2, + TEGRA_VGPU_GR_INTR_ILLEGAL_METHOD = 3, + TEGRA_VGPU_GR_INTR_ILLEGAL_CLASS = 4, + TEGRA_VGPU_GR_INTR_FECS_ERROR = 5, + TEGRA_VGPU_GR_INTR_CLASS_ERROR = 6, + TEGRA_VGPU_GR_INTR_FIRMWARE_METHOD = 7, + TEGRA_VGPU_GR_INTR_EXCEPTION = 8, + TEGRA_VGPU_GR_INTR_SEMAPHORE = 9, + TEGRA_VGPU_FIFO_INTR_PBDMA = 10, + TEGRA_VGPU_FIFO_INTR_CTXSW_TIMEOUT = 11, + TEGRA_VGPU_FIFO_INTR_MMU_FAULT = 12, + TEGRA_VGPU_GR_INTR_SM_EXCEPTION = 16, +}; + +struct tegra_vgpu_gr_intr_info { + u32 type; + u32 chid; +}; + +struct tegra_vgpu_gr_nonstall_intr_info { + u32 type; +}; + +struct tegra_vgpu_fifo_intr_info { + u32 type; + u32 chid; +}; + +struct tegra_vgpu_fifo_nonstall_intr_info { + u32 type; +}; + +struct tegra_vgpu_ce2_nonstall_intr_info { + u32 type; +}; + +enum { + TEGRA_VGPU_FECS_TRACE_DATA_UPDATE = 0 +}; + +struct tegra_vgpu_fecs_trace_event_info { + u32 type; +}; + +#define TEGRA_VGPU_CHANNEL_EVENT_ID_MAX 6 +struct tegra_vgpu_channel_event_info { + u32 event_id; + u32 is_tsg; + u32 id; /* channel id or tsg id */ +}; + +struct tegra_vgpu_sm_esr_info { + u32 tsg_id; + u32 sm_id; + u32 hww_global_esr; + u32 hww_warp_esr; + u64 hww_warp_esr_pc; + u32 hww_global_esr_report_mask; + u32 hww_warp_esr_report_mask; +}; + +struct tegra_vgpu_semaphore_wakeup { + u32 post_events; +}; + +struct tegra_vgpu_channel_cleanup { + u32 chid; +}; + +struct tegra_vgpu_channel_set_error_notifier { + u32 chid; + u32 error; +}; + +enum { + + TEGRA_VGPU_INTR_GR = 0, + TEGRA_VGPU_INTR_FIFO = 1, + TEGRA_VGPU_INTR_CE2 = 2, +}; + +enum { + TEGRA_VGPU_EVENT_INTR = 0, + TEGRA_VGPU_EVENT_ABORT = 1, + TEGRA_VGPU_EVENT_FECS_TRACE = 2, + TEGRA_VGPU_EVENT_CHANNEL = 3, + TEGRA_VGPU_EVENT_SM_ESR = 4, + TEGRA_VGPU_EVENT_SEMAPHORE_WAKEUP = 5, + TEGRA_VGPU_EVENT_CHANNEL_CLEANUP = 6, + TEGRA_VGPU_EVENT_SET_ERROR_NOTIFIER = 7, +}; + +struct tegra_vgpu_intr_msg { + unsigned int event; + u32 unit; + union { + struct tegra_vgpu_gr_intr_info gr_intr; + struct tegra_vgpu_gr_nonstall_intr_info gr_nonstall_intr; + struct tegra_vgpu_fifo_intr_info fifo_intr; + struct tegra_vgpu_fifo_nonstall_intr_info fifo_nonstall_intr; + struct tegra_vgpu_ce2_nonstall_intr_info ce2_nonstall_intr; + struct tegra_vgpu_fecs_trace_event_info fecs_trace; + struct tegra_vgpu_channel_event_info channel_event; + struct tegra_vgpu_sm_esr_info sm_esr; + struct tegra_vgpu_semaphore_wakeup sem_wakeup; + struct tegra_vgpu_channel_cleanup ch_cleanup; + struct tegra_vgpu_channel_set_error_notifier set_error_notifier; + char padding[32]; + } info; +}; + +#define TEGRA_VGPU_QUEUE_SIZES \ + 512, \ + sizeof(struct tegra_vgpu_intr_msg) + +#endif diff --git a/include/nvgpu/vgpu/vgpu.h b/include/nvgpu/vgpu/vgpu.h new file mode 100644 index 0000000..ecdb896 --- /dev/null +++ b/include/nvgpu/vgpu/vgpu.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2014-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 __VGPU_COMMON_H__ +#define __VGPU_COMMON_H__ + +#include +#include +#include +#include +#include + +struct device; +struct tegra_vgpu_gr_intr_info; +struct tegra_vgpu_fifo_intr_info; +struct tegra_vgpu_cmd_msg; +struct nvgpu_mem; +struct gk20a; +struct vm_gk20a; +struct nvgpu_gr_ctx; +struct nvgpu_cpu_time_correlation_sample; +struct vgpu_ecc_stat; +struct channel_gk20a; + +struct vgpu_priv_data { + u64 virt_handle; + struct nvgpu_thread intr_handler; + struct tegra_vgpu_constants_params constants; + struct vgpu_ecc_stat *ecc_stats; + int ecc_stats_count; + u32 num_freqs; + unsigned long *freqs; + struct nvgpu_mutex vgpu_clk_get_freq_lock; +}; + +struct vgpu_priv_data *vgpu_get_priv_data(struct gk20a *g); + +static inline u64 vgpu_get_handle(struct gk20a *g) +{ + struct vgpu_priv_data *priv = vgpu_get_priv_data(g); + + if (unlikely(!priv)) { + nvgpu_err(g, "invalid vgpu_priv_data in %s", __func__); + return INT_MAX; + } + + return priv->virt_handle; +} + +int vgpu_comm_init(struct gk20a *g); +void vgpu_comm_deinit(void); +int vgpu_comm_sendrecv(struct tegra_vgpu_cmd_msg *msg, size_t size_in, + size_t size_out); +u64 vgpu_connect(void); +int vgpu_get_attribute(u64 handle, u32 attrib, u32 *value); +int vgpu_intr_thread(void *dev_id); +void vgpu_remove_support_common(struct gk20a *g); +void vgpu_detect_chip(struct gk20a *g); +int vgpu_init_gpu_characteristics(struct gk20a *g); +int vgpu_read_ptimer(struct gk20a *g, u64 *value); +int vgpu_get_timestamps_zipper(struct gk20a *g, + u32 source_id, u32 count, + struct nvgpu_cpu_time_correlation_sample *samples); +int vgpu_init_hal(struct gk20a *g); +int vgpu_get_constants(struct gk20a *g); +u64 vgpu_bar1_map(struct gk20a *g, struct nvgpu_mem *mem); +int vgpu_gr_isr(struct gk20a *g, struct tegra_vgpu_gr_intr_info *info); +int vgpu_gr_alloc_gr_ctx(struct gk20a *g, + struct nvgpu_gr_ctx *gr_ctx, + struct vm_gk20a *vm, + u32 class, + u32 flags); +void vgpu_gr_free_gr_ctx(struct gk20a *g, struct vm_gk20a *vm, + struct nvgpu_gr_ctx *gr_ctx); +void vgpu_gr_handle_sm_esr_event(struct gk20a *g, + struct tegra_vgpu_sm_esr_info *info); +int vgpu_gr_init_ctx_state(struct gk20a *g); +int vgpu_fifo_isr(struct gk20a *g, struct tegra_vgpu_fifo_intr_info *info); +u32 vgpu_ce_get_num_pce(struct gk20a *g); +int vgpu_init_mm_support(struct gk20a *g); +int vgpu_init_gr_support(struct gk20a *g); +int vgpu_init_fifo_support(struct gk20a *g); + +int vgpu_gp10b_init_hal(struct gk20a *g); +int vgpu_gv11b_init_hal(struct gk20a *g); + +bool vgpu_is_reduced_bar1(struct gk20a *g); + +int vgpu_gr_set_mmu_debug_mode(struct gk20a *g, + struct channel_gk20a *ch, bool enable); +#endif diff --git a/include/nvgpu/vgpu/vgpu_ivc.h b/include/nvgpu/vgpu/vgpu_ivc.h new file mode 100644 index 0000000..e7e4026 --- /dev/null +++ b/include/nvgpu/vgpu/vgpu_ivc.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __VGPU_IVC_H__ +#define __VGPU_IVC_H__ + +#include + +struct gk20a; + +int vgpu_ivc_init(struct gk20a *g, u32 elems, + const size_t *queue_sizes, u32 queue_start, u32 num_queues); +void vgpu_ivc_deinit(u32 queue_start, u32 num_queues); +void vgpu_ivc_release(void *handle); +u32 vgpu_ivc_get_server_vmid(void); +int vgpu_ivc_recv(u32 index, void **handle, void **data, + size_t *size, u32 *sender); +int vgpu_ivc_send(u32 peer, u32 index, void *data, size_t size); +int vgpu_ivc_sendrecv(u32 peer, u32 index, void **handle, + void **data, size_t *size); +u32 vgpu_ivc_get_peer_self(void); +void *vgpu_ivc_oob_get_ptr(u32 peer, u32 index, void **ptr, + size_t *size); +void vgpu_ivc_oob_put_ptr(void *handle); + +#endif diff --git a/include/nvgpu/vgpu/vgpu_ivm.h b/include/nvgpu/vgpu/vgpu_ivm.h new file mode 100644 index 0000000..cecdd51 --- /dev/null +++ b/include/nvgpu/vgpu/vgpu_ivm.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __VGPU_IVM_H__ +#define __VGPU_IVM_H__ + +#include + +struct tegra_hv_ivm_cookie; + +struct tegra_hv_ivm_cookie *vgpu_ivm_mempool_reserve(unsigned int id); +int vgpu_ivm_mempool_unreserve(struct tegra_hv_ivm_cookie *cookie); +u64 vgpu_ivm_get_ipa(struct tegra_hv_ivm_cookie *cookie); +u64 vgpu_ivm_get_size(struct tegra_hv_ivm_cookie *cookie); +void *vgpu_ivm_mempool_map(struct tegra_hv_ivm_cookie *cookie); +void vgpu_ivm_mempool_unmap(struct tegra_hv_ivm_cookie *cookie, + void *addr); +#endif diff --git a/include/nvgpu/vgpu/vm.h b/include/nvgpu/vgpu/vm.h new file mode 100644 index 0000000..fc0078d --- /dev/null +++ b/include/nvgpu/vgpu/vm.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_VGPU_VM_H +#define NVGPU_VGPU_VM_H + +#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION +int vgpu_vm_init(struct gk20a *g, struct vm_gk20a *vm); +void vgpu_vm_remove(struct vm_gk20a *vm); +#endif + +#endif /* NVGPU_VGPU_VM_H */ diff --git a/include/nvgpu/vidmem.h b/include/nvgpu/vidmem.h new file mode 100644 index 0000000..4470232 --- /dev/null +++ b/include/nvgpu/vidmem.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_VIDMEM_H +#define NVGPU_VIDMEM_H + +#include +#include + +struct gk20a; +struct mm_gk20a; +struct nvgpu_mem; + +struct nvgpu_vidmem_buf { + /* + * Must be a pointer since control of this mem is passed over to the + * vidmem background clearing thread when the vidmem buf is freed. + */ + struct nvgpu_mem *mem; + + struct gk20a *g; + + /* + * Filled in by each OS - this holds the necessary data to export this + * buffer to userspace. This will eventually be replaced by a struct + * which shall be defined in the OS specific vidmem.h header file. + */ + void *priv; +}; + +#if defined(CONFIG_GK20A_VIDMEM) + +/** + * nvgpu_vidmem_user_alloc - Allocates a vidmem buffer for userspace + * + * @g - The GPU. + * @bytes - Size of the buffer in bytes. + * + * Allocate a generic (OS agnostic) vidmem buffer. This does not allocate the OS + * specific interfacing for userspace sharing. Instead is is expected that the + * OS specific code will allocate that OS specific data and add it to this + * buffer. + * + * The buffer allocated here is intended to use used by userspace, hence the + * extra struct over nvgpu_mem. If a vidmem buffer is needed by the kernel + * driver only then a simple nvgpu_dma_alloc_vid() or the like is sufficient. + * + * Returns a pointer to a vidmem buffer on success, 0 otherwise. + */ +struct nvgpu_vidmem_buf *nvgpu_vidmem_user_alloc(struct gk20a *g, size_t bytes); + +void nvgpu_vidmem_buf_free(struct gk20a *g, struct nvgpu_vidmem_buf *buf); + +int nvgpu_vidmem_clear_list_enqueue(struct gk20a *g, struct nvgpu_mem *mem); + +bool nvgpu_addr_is_vidmem_page_alloc(u64 addr); +int nvgpu_vidmem_get_space(struct gk20a *g, u64 *space); + +void nvgpu_vidmem_destroy(struct gk20a *g); +int nvgpu_vidmem_init(struct mm_gk20a *mm); + +int nvgpu_vidmem_clear(struct gk20a *g, struct nvgpu_mem *mem); + +void nvgpu_vidmem_thread_pause_sync(struct mm_gk20a *mm); +void nvgpu_vidmem_thread_unpause(struct mm_gk20a *mm); + +#else /* !defined(CONFIG_GK20A_VIDMEM) */ + +/* + * When VIDMEM support is not present this interface is used. + */ + +static inline bool nvgpu_addr_is_vidmem_page_alloc(u64 addr) +{ + return false; +} + +static inline int nvgpu_vidmem_buf_alloc(struct gk20a *g, size_t bytes) +{ + return -ENOSYS; +} + +static inline void nvgpu_vidmem_buf_free(struct gk20a *g, + struct nvgpu_vidmem_buf *buf) +{ +} + +static inline int nvgpu_vidmem_get_space(struct gk20a *g, u64 *space) +{ + return -ENOSYS; +} + +static inline void nvgpu_vidmem_destroy(struct gk20a *g) +{ +} + +static inline int nvgpu_vidmem_init(struct mm_gk20a *mm) +{ + return 0; +} + +static inline int nvgpu_vidmem_clear_all(struct gk20a *g) +{ + return -ENOSYS; +} + +static inline int nvgpu_vidmem_clear(struct gk20a *g, + struct nvgpu_mem *mem) +{ + return -ENOSYS; +} + +static inline void nvgpu_vidmem_thread_pause_sync(struct mm_gk20a *mm) +{ +} + +static inline void nvgpu_vidmem_thread_unpause(struct mm_gk20a *mm) +{ +} + +#endif /* !defined(CONFIG_GK20A_VIDMEM) */ + +/* + * Simple macro for VIDMEM debugging. + */ +#define vidmem_dbg(g, fmt, args...) \ + nvgpu_log(g, gpu_dbg_vidmem, fmt, ##args); \ + +#endif /* NVGPU_VIDMEM_H */ diff --git a/include/nvgpu/vm.h b/include/nvgpu/vm.h new file mode 100644 index 0000000..3867c74 --- /dev/null +++ b/include/nvgpu/vm.h @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2017-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_VM_H +#define NVGPU_VM_H + +#include +#include +#include +#include +#include +#include +#include + +struct vm_gk20a; +struct nvgpu_vm_area; +struct gk20a_comptag_allocator; + +/* + * Defined by each OS. Allows the common VM code do things to the OS specific + * buffer structures. + */ +struct nvgpu_os_buffer; + +#ifdef __KERNEL__ +#include +#elif defined(__NVGPU_POSIX__) +#include +#else +/* QNX include goes here. */ +#include +#endif + +/** + * This header contains the OS agnostic APIs for dealing with VMs. Most of the + * VM implementation is system specific - it must translate from a platform's + * representation of DMA'able memory to our nvgpu_mem notion. + * + * However, some stuff is platform agnostic. VM ref-counting and the VM struct + * itself are platform agnostic. Also, the initialization and destruction of + * VMs is the same across all platforms (for now). + * + * VM Architecture: + * ---------------- + * + * The VM managment in nvgpu is split up as follows: a vm_gk20a struct which + * defines an address space. Each address space is a set of page tables and a + * GPU Virtual Address (GVA) allocator. Any number of channels may bind to a VM. + * + * +----+ +----+ +----+ +-----+ +-----+ + * | C1 | | C2 | ... | Cn | | VM1 | ... | VMn | + * +-+--+ +-+--+ +-+--+ +--+--+ +--+--+ + * | | | | | + * | | +----->-----+ | + * | +---------------->-----+ | + * +------------------------>-----------------+ + * + * Each VM also manages a set of mapped buffers (struct nvgpu_mapped_buf) + * which corresponds to _user space_ buffers which have been mapped into this VM. + * Kernel space mappings (created by nvgpu_gmmu_map()) are not tracked by VMs. + * This may be an architectural bug, but for now it seems to be OK. VMs can be + * closed in various ways - refs counts hitting zero, direct calls to the remove + * routine, etc. Note: this is going to change. VM cleanup is going to be + * homogonized around ref-counts. When a VM is closed all mapped buffers in the + * VM are unmapped from the GMMU. This means that those mappings will no longer + * be valid and any subsequent access by the GPU will fault. That means one must + * ensure the VM is not in use before closing it. + * + * VMs may also contain VM areas (struct nvgpu_vm_area) which are created for + * the purpose of sparse and/or fixed mappings. If userspace wishes to create a + * fixed mapping it must first create a VM area - either with a fixed address or + * not. VM areas are reserved - other mapping operations will not use the space. + * Userspace may then create fixed mappings within that VM area. + */ + +/* map/unmap batch state */ +struct vm_gk20a_mapping_batch { + bool gpu_l2_flushed; + bool need_tlb_invalidate; +}; + +struct nvgpu_mapped_buf { + struct vm_gk20a *vm; + struct nvgpu_vm_area *vm_area; + + struct nvgpu_ref ref; + + struct nvgpu_rbtree_node node; + struct nvgpu_list_node buffer_list; + u64 addr; + u64 size; + + u32 pgsz_idx; + + u32 flags; + u32 kind; + bool va_allocated; + + /* + * Separate from the nvgpu_os_buffer struct to clearly distinguish + * lifetime. A nvgpu_mapped_buf_priv will _always_ be wrapped by a + * struct nvgpu_mapped_buf; however, there are times when a struct + * nvgpu_os_buffer would be separate. This aims to prevent dangerous + * usage of container_of() or the like in OS code. + */ + struct nvgpu_mapped_buf_priv os_priv; +}; + +static inline struct nvgpu_mapped_buf * +nvgpu_mapped_buf_from_buffer_list(struct nvgpu_list_node *node) +{ + return (struct nvgpu_mapped_buf *) + ((uintptr_t)node - offsetof(struct nvgpu_mapped_buf, + buffer_list)); +} + +static inline struct nvgpu_mapped_buf * +mapped_buffer_from_rbtree_node(struct nvgpu_rbtree_node *node) +{ + return (struct nvgpu_mapped_buf *) + ((uintptr_t)node - offsetof(struct nvgpu_mapped_buf, node)); +} + +struct vm_gk20a { + struct mm_gk20a *mm; + struct gk20a_as_share *as_share; /* as_share this represents */ + char name[20]; + + u64 va_start; + u64 va_limit; + + int num_user_mapped_buffers; + + bool big_pages; /* enable large page support */ + bool enable_ctag; + bool guest_managed; /* whether the vm addr space is managed by guest */ + + u32 big_page_size; + + bool userspace_managed; + + const struct gk20a_mmu_level *mmu_levels; + + struct nvgpu_ref ref; + + struct nvgpu_mutex update_gmmu_lock; + + struct nvgpu_gmmu_pd pdb; + + /* + * These structs define the address spaces. In some cases it's possible + * to merge address spaces (user and user_lp) and in other cases it's + * not. vma[] allows the code to be agnostic to this by always using + * address spaces through this pointer array. + */ + struct nvgpu_allocator *vma[GMMU_NR_PAGE_SIZES]; + struct nvgpu_allocator kernel; + struct nvgpu_allocator user; + struct nvgpu_allocator user_lp; + + struct nvgpu_rbtree_node *mapped_buffers; + + struct nvgpu_list_node vm_area_list; + +#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION + u64 handle; +#endif + u32 gmmu_page_sizes[GMMU_NR_PAGE_SIZES]; + + /* if non-NULL, kref_put will use this batch when + unmapping. Must hold vm->update_gmmu_lock. */ + struct vm_gk20a_mapping_batch *kref_put_batch; + + /* + * Each address space needs to have a semaphore pool. + */ + struct nvgpu_semaphore_pool *sema_pool; + + /* + * Create sync point read only map for sync point range. + * Channels sharing same vm will also share same sync point ro map + */ + u64 syncpt_ro_map_gpu_va; + /* Protect allocation of sync point map */ + struct nvgpu_mutex syncpt_ro_map_lock; +}; + +/* + * Mapping flags. + */ +#define NVGPU_VM_MAP_FIXED_OFFSET BIT32(0) +#define NVGPU_VM_MAP_CACHEABLE BIT32(1) +#define NVGPU_VM_MAP_IO_COHERENT BIT32(2) +#define NVGPU_VM_MAP_UNMAPPED_PTE BIT32(3) +#define NVGPU_VM_MAP_DIRECT_KIND_CTRL BIT32(4) +#define NVGPU_VM_MAP_L3_ALLOC BIT32(5) +#define NVGPU_VM_MAP_PLATFORM_ATOMIC BIT32(6) + +#define NVGPU_KIND_INVALID -1 + +void nvgpu_vm_get(struct vm_gk20a *vm); +void nvgpu_vm_put(struct vm_gk20a *vm); + +int vm_aspace_id(struct vm_gk20a *vm); +bool nvgpu_big_pages_possible(struct vm_gk20a *vm, u64 base, u64 size); + +int nvgpu_vm_pde_coverage_bit_count(struct vm_gk20a *vm); + +/* batching eliminates redundant cache flushes and invalidates */ +void nvgpu_vm_mapping_batch_start(struct vm_gk20a_mapping_batch *batch); +void nvgpu_vm_mapping_batch_finish( + struct vm_gk20a *vm, struct vm_gk20a_mapping_batch *batch); +/* called when holding vm->update_gmmu_lock */ +void nvgpu_vm_mapping_batch_finish_locked( + struct vm_gk20a *vm, struct vm_gk20a_mapping_batch *batch); + +/* get reference to all currently mapped buffers */ +int nvgpu_vm_get_buffers(struct vm_gk20a *vm, + struct nvgpu_mapped_buf ***mapped_buffers, + int *num_buffers); +/* put references on the given buffers */ +void nvgpu_vm_put_buffers(struct vm_gk20a *vm, + struct nvgpu_mapped_buf **mapped_buffers, + int num_buffers); + +struct nvgpu_mapped_buf *nvgpu_vm_find_mapping(struct vm_gk20a *vm, + struct nvgpu_os_buffer *os_buf, + u64 map_addr, + u32 flags, + int kind); + +struct nvgpu_mapped_buf *nvgpu_vm_map(struct vm_gk20a *vm, + struct nvgpu_os_buffer *os_buf, + struct nvgpu_sgt *sgt, + u64 map_addr, + u64 map_size, + u64 phys_offset, + int rw, + u32 flags, + s16 compr_kind, + s16 incompr_kind, + struct vm_gk20a_mapping_batch *batch, + enum nvgpu_aperture aperture); + +void nvgpu_vm_unmap(struct vm_gk20a *vm, u64 offset, + struct vm_gk20a_mapping_batch *batch); + +/* + * Implemented by each OS. Called from within the core VM code to handle OS + * specific components of an nvgpu_mapped_buf. + */ +void nvgpu_vm_unmap_system(struct nvgpu_mapped_buf *mapped_buffer); + +/* + * Don't use this outside of the core VM code! + */ +void __nvgpu_vm_unmap_ref(struct nvgpu_ref *ref); + +u64 nvgpu_os_buf_get_size(struct nvgpu_os_buffer *os_buf); + +/* + * These all require the VM update lock to be held. + */ +struct nvgpu_mapped_buf *__nvgpu_vm_find_mapped_buf( + struct vm_gk20a *vm, u64 addr); +struct nvgpu_mapped_buf *__nvgpu_vm_find_mapped_buf_range( + struct vm_gk20a *vm, u64 addr); +struct nvgpu_mapped_buf *__nvgpu_vm_find_mapped_buf_less_than( + struct vm_gk20a *vm, u64 addr); + +int nvgpu_insert_mapped_buf(struct vm_gk20a *vm, + struct nvgpu_mapped_buf *mapped_buffer); +void nvgpu_remove_mapped_buf(struct vm_gk20a *vm, + struct nvgpu_mapped_buf *mapped_buffer); + +/* + * Initialize a preallocated vm + */ +int __nvgpu_vm_init(struct mm_gk20a *mm, + struct vm_gk20a *vm, + u32 big_page_size, + u64 low_hole, + u64 kernel_reserved, + u64 aperture_size, + bool big_pages, + bool userspace_managed, + char *name); + +struct vm_gk20a *nvgpu_vm_init(struct gk20a *g, + u32 big_page_size, + u64 low_hole, + u64 kernel_reserved, + u64 aperture_size, + bool big_pages, + bool userspace_managed, + char *name); + +/* + * These are private to the VM code but are unfortunately used by the vgpu code. + * It appears to be used for an optimization in reducing the number of server + * requests to the vgpu server. Basically the vgpu implementation of + * map_global_ctx_buffers() sends a bunch of VA ranges over to the RM server. + * Ideally the RM server can just batch mappings but until such a time this + * will be used by the vgpu code. + */ +u64 __nvgpu_vm_alloc_va(struct vm_gk20a *vm, u64 size, + u32 pgsz_idx); +int __nvgpu_vm_free_va(struct vm_gk20a *vm, u64 addr, + u32 pgsz_idx); + +#endif /* NVGPU_VM_H */ diff --git a/include/nvgpu/vm_area.h b/include/nvgpu/vm_area.h new file mode 100644 index 0000000..8778e42 --- /dev/null +++ b/include/nvgpu/vm_area.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_VM_AREA_H +#define NVGPU_VM_AREA_H + +#include +#include + +struct vm_gk20a; +struct gk20a_as_share; +struct nvgpu_as_alloc_space_args; +struct nvgpu_as_free_space_args; + +struct nvgpu_vm_area { + /* + * Entry into the list of VM areas owned by a VM. + */ + struct nvgpu_list_node vm_area_list; + + /* + * List of buffers mapped into this vm_area. + */ + struct nvgpu_list_node buffer_list_head; + + u32 flags; + u32 pgsz_idx; + u64 addr; + u64 size; + bool sparse; +}; + +static inline struct nvgpu_vm_area * +nvgpu_vm_area_from_vm_area_list(struct nvgpu_list_node *node) +{ + return (struct nvgpu_vm_area *) + ((uintptr_t)node - offsetof(struct nvgpu_vm_area, + vm_area_list)); +}; + +/* + * Alloc space flags. + */ +#define NVGPU_VM_AREA_ALLOC_FIXED_OFFSET BIT(0) +#define NVGPU_VM_AREA_ALLOC_SPARSE BIT(1) + +int nvgpu_vm_area_alloc(struct vm_gk20a *vm, u32 pages, u32 page_size, + u64 *addr, u32 flags); +int nvgpu_vm_area_free(struct vm_gk20a *vm, u64 addr); + +struct nvgpu_vm_area *nvgpu_vm_area_find(struct vm_gk20a *vm, u64 addr); +int nvgpu_vm_area_validate_buffer(struct vm_gk20a *vm, + u64 map_offset, u64 map_size, u32 pgsz_idx, + struct nvgpu_vm_area **pvm_area); + +#endif /* NVGPU_VM_AREA_H */ diff --git a/include/nvgpu/vpr.h b/include/nvgpu/vpr.h new file mode 100644 index 0000000..ae0ac1b --- /dev/null +++ b/include/nvgpu/vpr.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019, 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_VPR_H +#define NVGPU_VPR_H + +#include + +bool nvgpu_is_vpr_resize_enabled(void); + +#endif /* NVGPU_VPR_H */ diff --git a/include/nvgpu/xve.h b/include/nvgpu/xve.h new file mode 100644 index 0000000..2d0d698 --- /dev/null +++ b/include/nvgpu/xve.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_XVE_H +#define NVGPU_XVE_H + +#include +#include + +/* + * For the available speeds bitmap. + */ +#define GPU_XVE_SPEED_2P5 (1 << 0) +#define GPU_XVE_SPEED_5P0 (1 << 1) +#define GPU_XVE_SPEED_8P0 (1 << 2) +#define GPU_XVE_NR_SPEEDS 3 + +#define GPU_XVE_SPEED_MASK (GPU_XVE_SPEED_2P5 | \ + GPU_XVE_SPEED_5P0 | \ + GPU_XVE_SPEED_8P0) + +/* + * The HW uses a 2 bit field where speed is defined by a number: + * + * NV_XVE_LINK_CONTROL_STATUS_LINK_SPEED_2P5 = 1 + * NV_XVE_LINK_CONTROL_STATUS_LINK_SPEED_5P0 = 2 + * NV_XVE_LINK_CONTROL_STATUS_LINK_SPEED_8P0 = 3 + * + * This isn't ideal for a bitmap with available speeds. So the external + * APIs think about speeds as a bit in a bitmap and this function converts + * from those bits to the actual HW speed setting. + * + * @speed_bit must have only 1 bit set and must be one of the 3 available + * HW speeds. Not all chips support all speeds so use available_speeds() to + * determine what a given chip supports. + */ +static inline const char *xve_speed_to_str(u32 speed) +{ + if (!speed || !is_power_of_2(speed) || + !(speed & GPU_XVE_SPEED_MASK)) { + return "Unknown ???"; + } + + return speed & GPU_XVE_SPEED_2P5 ? "Gen1" : + speed & GPU_XVE_SPEED_5P0 ? "Gen2" : + speed & GPU_XVE_SPEED_8P0 ? "Gen3" : + "Unknown ???"; +} + +#endif /* NVGPU_XVE_H */ diff --git a/include/os/linux/cde.c b/include/os/linux/cde.c new file mode 100644 index 0000000..715513c --- /dev/null +++ b/include/os/linux/cde.c @@ -0,0 +1,1794 @@ +/* + * Color decompression engine support + * + * Copyright (c) 2014-2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "gk20a/mm_gk20a.h" +#include "gk20a/fence_gk20a.h" +#include "gk20a/gr_gk20a.h" + +#include "cde.h" +#include "os_linux.h" +#include "dmabuf.h" +#include "channel.h" +#include "cde_gm20b.h" +#include "cde_gp10b.h" + +#include +#include + +static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx); +static struct gk20a_cde_ctx *gk20a_cde_allocate_context(struct nvgpu_os_linux *l); + +#define CTX_DELETE_TIME 1000 + +#define MAX_CTX_USE_COUNT 42 +#define MAX_CTX_RETRY_TIME 2000 + +static dma_addr_t gpuva_to_iova_base(struct vm_gk20a *vm, u64 gpu_vaddr) +{ + struct nvgpu_mapped_buf *buffer; + dma_addr_t addr = 0; + struct gk20a *g = gk20a_from_vm(vm); + + nvgpu_mutex_acquire(&vm->update_gmmu_lock); + buffer = __nvgpu_vm_find_mapped_buf(vm, gpu_vaddr); + if (buffer) + addr = nvgpu_mem_get_addr_sgl(g, buffer->os_priv.sgt->sgl); + nvgpu_mutex_release(&vm->update_gmmu_lock); + + return addr; +} + +static void gk20a_deinit_cde_img(struct gk20a_cde_ctx *cde_ctx) +{ + unsigned int i; + + for (i = 0; i < cde_ctx->num_bufs; i++) { + struct nvgpu_mem *mem = cde_ctx->mem + i; + nvgpu_dma_unmap_free(cde_ctx->vm, mem); + } + + nvgpu_kfree(&cde_ctx->l->g, cde_ctx->init_convert_cmd); + + cde_ctx->convert_cmd = NULL; + cde_ctx->init_convert_cmd = NULL; + cde_ctx->num_bufs = 0; + cde_ctx->num_params = 0; + cde_ctx->init_cmd_num_entries = 0; + cde_ctx->convert_cmd_num_entries = 0; + cde_ctx->init_cmd_executed = false; +} + +static void gk20a_cde_remove_ctx(struct gk20a_cde_ctx *cde_ctx) +__must_hold(&cde_app->mutex) +{ + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + struct channel_gk20a *ch = cde_ctx->ch; + struct vm_gk20a *vm = ch->vm; + + trace_gk20a_cde_remove_ctx(cde_ctx); + + /* release mapped memory */ + gk20a_deinit_cde_img(cde_ctx); + nvgpu_gmmu_unmap(vm, &g->gr.compbit_store.mem, + cde_ctx->backing_store_vaddr); + + /* + * free the channel + * gk20a_channel_close() will also unbind the channel from TSG + */ + gk20a_channel_close(ch); + nvgpu_ref_put(&cde_ctx->tsg->refcount, gk20a_tsg_release); + + /* housekeeping on app */ + nvgpu_list_del(&cde_ctx->list); + l->cde_app.ctx_count--; + nvgpu_kfree(g, cde_ctx); +} + +static void gk20a_cde_cancel_deleter(struct gk20a_cde_ctx *cde_ctx, + bool wait_finish) +__releases(&cde_app->mutex) +__acquires(&cde_app->mutex) +{ + struct gk20a_cde_app *cde_app = &cde_ctx->l->cde_app; + + /* permanent contexts do not have deleter works */ + if (!cde_ctx->is_temporary) + return; + + if (wait_finish) { + nvgpu_mutex_release(&cde_app->mutex); + cancel_delayed_work_sync(&cde_ctx->ctx_deleter_work); + nvgpu_mutex_acquire(&cde_app->mutex); + } else { + cancel_delayed_work(&cde_ctx->ctx_deleter_work); + } +} + +static void gk20a_cde_remove_contexts(struct nvgpu_os_linux *l) +__must_hold(&l->cde_app->mutex) +{ + struct gk20a_cde_app *cde_app = &l->cde_app; + struct gk20a_cde_ctx *cde_ctx, *cde_ctx_save; + + /* safe to go off the mutex in cancel_deleter since app is + * deinitialised; no new jobs are started. deleter works may be only at + * waiting for the mutex or before, going to abort */ + + nvgpu_list_for_each_entry_safe(cde_ctx, cde_ctx_save, + &cde_app->free_contexts, gk20a_cde_ctx, list) { + gk20a_cde_cancel_deleter(cde_ctx, true); + gk20a_cde_remove_ctx(cde_ctx); + } + + nvgpu_list_for_each_entry_safe(cde_ctx, cde_ctx_save, + &cde_app->used_contexts, gk20a_cde_ctx, list) { + gk20a_cde_cancel_deleter(cde_ctx, true); + gk20a_cde_remove_ctx(cde_ctx); + } +} + +static void gk20a_cde_stop(struct nvgpu_os_linux *l) +__must_hold(&l->cde_app->mutex) +{ + struct gk20a_cde_app *cde_app = &l->cde_app; + + /* prevent further conversions and delayed works from working */ + cde_app->initialised = false; + /* free all data, empty the list */ + gk20a_cde_remove_contexts(l); +} + +void gk20a_cde_destroy(struct nvgpu_os_linux *l) +__acquires(&l->cde_app->mutex) +__releases(&l->cde_app->mutex) +{ + struct gk20a_cde_app *cde_app = &l->cde_app; + + if (!cde_app->initialised) + return; + + nvgpu_mutex_acquire(&cde_app->mutex); + gk20a_cde_stop(l); + nvgpu_mutex_release(&cde_app->mutex); + + nvgpu_mutex_destroy(&cde_app->mutex); +} + +void gk20a_cde_suspend(struct nvgpu_os_linux *l) +__acquires(&l->cde_app->mutex) +__releases(&l->cde_app->mutex) +{ + struct gk20a_cde_app *cde_app = &l->cde_app; + struct gk20a_cde_ctx *cde_ctx, *cde_ctx_save; + + if (!cde_app->initialised) + return; + + nvgpu_mutex_acquire(&cde_app->mutex); + + nvgpu_list_for_each_entry_safe(cde_ctx, cde_ctx_save, + &cde_app->free_contexts, gk20a_cde_ctx, list) { + gk20a_cde_cancel_deleter(cde_ctx, false); + } + + nvgpu_list_for_each_entry_safe(cde_ctx, cde_ctx_save, + &cde_app->used_contexts, gk20a_cde_ctx, list) { + gk20a_cde_cancel_deleter(cde_ctx, false); + } + + nvgpu_mutex_release(&cde_app->mutex); + +} + +static int gk20a_cde_create_context(struct nvgpu_os_linux *l) +__must_hold(&l->cde_app->mutex) +{ + struct gk20a_cde_app *cde_app = &l->cde_app; + struct gk20a_cde_ctx *cde_ctx; + + cde_ctx = gk20a_cde_allocate_context(l); + if (IS_ERR(cde_ctx)) + return PTR_ERR(cde_ctx); + + nvgpu_list_add(&cde_ctx->list, &cde_app->free_contexts); + cde_app->ctx_count++; + if (cde_app->ctx_count > cde_app->ctx_count_top) + cde_app->ctx_count_top = cde_app->ctx_count; + + return 0; +} + +static int gk20a_cde_create_contexts(struct nvgpu_os_linux *l) +__must_hold(&l->cde_app->mutex) +{ + int err; + int i; + + for (i = 0; i < NUM_CDE_CONTEXTS; i++) { + err = gk20a_cde_create_context(l); + if (err) + goto out; + } + + return 0; +out: + gk20a_cde_remove_contexts(l); + return err; +} + +static int gk20a_init_cde_buf(struct gk20a_cde_ctx *cde_ctx, + struct nvgpu_firmware *img, + struct gk20a_cde_hdr_buf *buf) +{ + struct nvgpu_mem *mem; + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + int err; + + /* check that the file can hold the buf */ + if (buf->data_byte_offset != 0 && + buf->data_byte_offset + buf->num_bytes > img->size) { + nvgpu_warn(g, "cde: invalid data section. buffer idx = %d", + cde_ctx->num_bufs); + return -EINVAL; + } + + /* check that we have enough buf elems available */ + if (cde_ctx->num_bufs >= MAX_CDE_BUFS) { + nvgpu_warn(g, "cde: invalid data section. buffer idx = %d", + cde_ctx->num_bufs); + return -ENOMEM; + } + + /* allocate buf */ + mem = cde_ctx->mem + cde_ctx->num_bufs; + err = nvgpu_dma_alloc_map_sys(cde_ctx->vm, buf->num_bytes, mem); + if (err) { + nvgpu_warn(g, "cde: could not allocate device memory. buffer idx = %d", + cde_ctx->num_bufs); + return -ENOMEM; + } + + /* copy the content */ + if (buf->data_byte_offset != 0) + memcpy(mem->cpu_va, img->data + buf->data_byte_offset, + buf->num_bytes); + + cde_ctx->num_bufs++; + + return 0; +} + +static int gk20a_replace_data(struct gk20a_cde_ctx *cde_ctx, void *target, + int type, s32 shift, u64 mask, u64 value) +{ + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + u32 *target_mem_ptr = target; + u64 *target_mem_ptr_u64 = target; + u64 current_value, new_value; + + value = (shift >= 0) ? value << shift : value >> -shift; + value &= mask; + + /* read current data from the location */ + current_value = 0; + if (type == TYPE_PARAM_TYPE_U32) { + if (mask != 0xfffffffful) + current_value = *target_mem_ptr; + } else if (type == TYPE_PARAM_TYPE_U64_LITTLE) { + if (mask != ~0ul) + current_value = *target_mem_ptr_u64; + } else if (type == TYPE_PARAM_TYPE_U64_BIG) { + current_value = *target_mem_ptr_u64; + current_value = (u64)(current_value >> 32) | + (u64)(current_value << 32); + } else { + nvgpu_warn(g, "cde: unknown type. type=%d", + type); + return -EINVAL; + } + + current_value &= ~mask; + new_value = current_value | value; + + /* store the element data back */ + if (type == TYPE_PARAM_TYPE_U32) + *target_mem_ptr = (u32)new_value; + else if (type == TYPE_PARAM_TYPE_U64_LITTLE) + *target_mem_ptr_u64 = new_value; + else { + new_value = (u64)(new_value >> 32) | + (u64)(new_value << 32); + *target_mem_ptr_u64 = new_value; + } + + return 0; +} + +static int gk20a_init_cde_replace(struct gk20a_cde_ctx *cde_ctx, + struct nvgpu_firmware *img, + struct gk20a_cde_hdr_replace *replace) +{ + struct nvgpu_mem *source_mem; + struct nvgpu_mem *target_mem; + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + u32 *target_mem_ptr; + u64 vaddr; + int err; + + if (replace->target_buf >= cde_ctx->num_bufs || + replace->source_buf >= cde_ctx->num_bufs) { + nvgpu_warn(g, "cde: invalid buffer. target_buf=%u, source_buf=%u, num_bufs=%d", + replace->target_buf, replace->source_buf, + cde_ctx->num_bufs); + return -EINVAL; + } + + source_mem = cde_ctx->mem + replace->source_buf; + target_mem = cde_ctx->mem + replace->target_buf; + target_mem_ptr = target_mem->cpu_va; + + if (source_mem->size < (replace->source_byte_offset + 3) || + target_mem->size < (replace->target_byte_offset + 3)) { + nvgpu_warn(g, "cde: invalid buffer offsets. target_buf_offs=%lld, source_buf_offs=%lld, source_buf_size=%zu, dest_buf_size=%zu", + replace->target_byte_offset, + replace->source_byte_offset, + source_mem->size, + target_mem->size); + return -EINVAL; + } + + /* calculate the target pointer */ + target_mem_ptr += (replace->target_byte_offset / sizeof(u32)); + + /* determine patch value */ + vaddr = source_mem->gpu_va + replace->source_byte_offset; + err = gk20a_replace_data(cde_ctx, target_mem_ptr, replace->type, + replace->shift, replace->mask, + vaddr); + if (err) { + nvgpu_warn(g, "cde: replace failed. err=%d, target_buf=%u, target_buf_offs=%lld, source_buf=%u, source_buf_offs=%lld", + err, replace->target_buf, + replace->target_byte_offset, + replace->source_buf, + replace->source_byte_offset); + } + + return err; +} + +static int gk20a_cde_patch_params(struct gk20a_cde_ctx *cde_ctx) +{ + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + struct nvgpu_mem *target_mem; + u32 *target_mem_ptr; + u64 new_data; + int user_id = 0, err; + unsigned int i; + + for (i = 0; i < cde_ctx->num_params; i++) { + struct gk20a_cde_hdr_param *param = cde_ctx->params + i; + target_mem = cde_ctx->mem + param->target_buf; + target_mem_ptr = target_mem->cpu_va; + target_mem_ptr += (param->target_byte_offset / sizeof(u32)); + + switch (param->id) { + case TYPE_PARAM_COMPTAGS_PER_CACHELINE: + new_data = g->gr.comptags_per_cacheline; + break; + case TYPE_PARAM_GPU_CONFIGURATION: + new_data = (u64)g->ltc_count * g->gr.slices_per_ltc * + g->gr.cacheline_size; + break; + case TYPE_PARAM_FIRSTPAGEOFFSET: + new_data = cde_ctx->surf_param_offset; + break; + case TYPE_PARAM_NUMPAGES: + new_data = cde_ctx->surf_param_lines; + break; + case TYPE_PARAM_BACKINGSTORE: + new_data = cde_ctx->backing_store_vaddr; + break; + case TYPE_PARAM_DESTINATION: + new_data = cde_ctx->compbit_vaddr; + break; + case TYPE_PARAM_DESTINATION_SIZE: + new_data = cde_ctx->compbit_size; + break; + case TYPE_PARAM_BACKINGSTORE_SIZE: + new_data = g->gr.compbit_store.mem.size; + break; + case TYPE_PARAM_SOURCE_SMMU_ADDR: + new_data = gpuva_to_iova_base(cde_ctx->vm, + cde_ctx->surf_vaddr); + if (new_data == 0) { + nvgpu_warn(g, "cde: failed to find 0x%llx", + cde_ctx->surf_vaddr); + return -EINVAL; + } + break; + case TYPE_PARAM_BACKINGSTORE_BASE_HW: + new_data = g->gr.compbit_store.base_hw; + break; + case TYPE_PARAM_GOBS_PER_COMPTAGLINE_PER_SLICE: + new_data = g->gr.gobs_per_comptagline_per_slice; + break; + case TYPE_PARAM_SCATTERBUFFER: + new_data = cde_ctx->scatterbuffer_vaddr; + break; + case TYPE_PARAM_SCATTERBUFFER_SIZE: + new_data = cde_ctx->scatterbuffer_size; + break; + default: + user_id = param->id - NUM_RESERVED_PARAMS; + if (user_id < 0 || user_id >= MAX_CDE_USER_PARAMS) + continue; + new_data = cde_ctx->user_param_values[user_id]; + } + + nvgpu_log(g, gpu_dbg_cde, "cde: patch: idx_in_file=%d param_id=%d target_buf=%u target_byte_offset=%lld data_value=0x%llx data_offset/data_diff=%lld data_type=%d data_shift=%d data_mask=0x%llx", + i, param->id, param->target_buf, + param->target_byte_offset, new_data, + param->data_offset, param->type, param->shift, + param->mask); + + new_data += param->data_offset; + + err = gk20a_replace_data(cde_ctx, target_mem_ptr, param->type, + param->shift, param->mask, new_data); + + if (err) { + nvgpu_warn(g, "cde: patch failed. err=%d, idx=%d, id=%d, target_buf=%u, target_buf_offs=%lld, patch_value=%llu", + err, i, param->id, param->target_buf, + param->target_byte_offset, new_data); + return err; + } + } + + return 0; +} + +static int gk20a_init_cde_param(struct gk20a_cde_ctx *cde_ctx, + struct nvgpu_firmware *img, + struct gk20a_cde_hdr_param *param) +{ + struct nvgpu_mem *target_mem; + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + + if (param->target_buf >= cde_ctx->num_bufs) { + nvgpu_warn(g, "cde: invalid buffer parameter. param idx = %d, target_buf=%u, num_bufs=%u", + cde_ctx->num_params, param->target_buf, + cde_ctx->num_bufs); + return -EINVAL; + } + + target_mem = cde_ctx->mem + param->target_buf; + if (target_mem->size < (param->target_byte_offset + 3)) { + nvgpu_warn(g, "cde: invalid buffer parameter. param idx = %d, target_buf_offs=%lld, target_buf_size=%zu", + cde_ctx->num_params, param->target_byte_offset, + target_mem->size); + return -EINVAL; + } + + /* does this parameter fit into our parameter structure */ + if (cde_ctx->num_params >= MAX_CDE_PARAMS) { + nvgpu_warn(g, "cde: no room for new parameters param idx = %d", + cde_ctx->num_params); + return -ENOMEM; + } + + /* is the given id valid? */ + if (param->id >= NUM_RESERVED_PARAMS + MAX_CDE_USER_PARAMS) { + nvgpu_warn(g, "cde: parameter id is not valid. param idx = %d, id=%u, max=%u", + param->id, cde_ctx->num_params, + NUM_RESERVED_PARAMS + MAX_CDE_USER_PARAMS); + return -EINVAL; + } + + cde_ctx->params[cde_ctx->num_params] = *param; + cde_ctx->num_params++; + + return 0; +} + +static int gk20a_init_cde_required_class(struct gk20a_cde_ctx *cde_ctx, + struct nvgpu_firmware *img, + u32 required_class) +{ + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + int err; + + /* CDE enabled */ + cde_ctx->ch->cde = true; + + err = gk20a_alloc_obj_ctx(cde_ctx->ch, required_class, 0); + if (err) { + nvgpu_warn(g, "cde: failed to allocate ctx. err=%d", + err); + return err; + } + + return 0; +} + +static int gk20a_init_cde_command(struct gk20a_cde_ctx *cde_ctx, + struct nvgpu_firmware *img, + u32 op, + struct gk20a_cde_cmd_elem *cmd_elem, + u32 num_elems) +{ + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + struct nvgpu_gpfifo_entry **gpfifo, *gpfifo_elem; + u32 *num_entries; + unsigned int i; + + /* check command type */ + if (op == TYPE_BUF_COMMAND_INIT) { + gpfifo = &cde_ctx->init_convert_cmd; + num_entries = &cde_ctx->init_cmd_num_entries; + } else if (op == TYPE_BUF_COMMAND_CONVERT) { + gpfifo = &cde_ctx->convert_cmd; + num_entries = &cde_ctx->convert_cmd_num_entries; + } else { + nvgpu_warn(g, "cde: unknown command. op=%u", + op); + return -EINVAL; + } + + /* allocate gpfifo entries to be pushed */ + *gpfifo = nvgpu_kzalloc(g, + sizeof(struct nvgpu_gpfifo_entry) * num_elems); + if (!*gpfifo) { + nvgpu_warn(g, "cde: could not allocate memory for gpfifo entries"); + return -ENOMEM; + } + + gpfifo_elem = *gpfifo; + for (i = 0; i < num_elems; i++, cmd_elem++, gpfifo_elem++) { + struct nvgpu_mem *target_mem; + + /* validate the current entry */ + if (cmd_elem->target_buf >= cde_ctx->num_bufs) { + nvgpu_warn(g, "cde: target buffer is not available (target=%u, num_bufs=%u)", + cmd_elem->target_buf, cde_ctx->num_bufs); + return -EINVAL; + } + + target_mem = cde_ctx->mem + cmd_elem->target_buf; + if (target_mem->size< + cmd_elem->target_byte_offset + cmd_elem->num_bytes) { + nvgpu_warn(g, "cde: target buffer cannot hold all entries (target_size=%zu, target_byte_offset=%lld, num_bytes=%llu)", + target_mem->size, + cmd_elem->target_byte_offset, + cmd_elem->num_bytes); + return -EINVAL; + } + + /* store the element into gpfifo */ + gpfifo_elem->entry0 = + u64_lo32(target_mem->gpu_va + + cmd_elem->target_byte_offset); + gpfifo_elem->entry1 = + u64_hi32(target_mem->gpu_va + + cmd_elem->target_byte_offset) | + pbdma_gp_entry1_length_f(cmd_elem->num_bytes / + sizeof(u32)); + } + + *num_entries = num_elems; + return 0; +} + +static int gk20a_cde_pack_cmdbufs(struct gk20a_cde_ctx *cde_ctx) +{ + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + unsigned long init_bytes = cde_ctx->init_cmd_num_entries * + sizeof(struct nvgpu_gpfifo_entry); + unsigned long conv_bytes = cde_ctx->convert_cmd_num_entries * + sizeof(struct nvgpu_gpfifo_entry); + unsigned long total_bytes = init_bytes + conv_bytes; + struct nvgpu_gpfifo_entry *combined_cmd; + + /* allocate buffer that has space for both */ + combined_cmd = nvgpu_kzalloc(g, total_bytes); + if (!combined_cmd) { + nvgpu_warn(g, + "cde: could not allocate memory for gpfifo entries"); + return -ENOMEM; + } + + /* move the original init here and append convert */ + memcpy(combined_cmd, cde_ctx->init_convert_cmd, init_bytes); + memcpy(combined_cmd + cde_ctx->init_cmd_num_entries, + cde_ctx->convert_cmd, conv_bytes); + + nvgpu_kfree(g, cde_ctx->init_convert_cmd); + nvgpu_kfree(g, cde_ctx->convert_cmd); + + cde_ctx->init_convert_cmd = combined_cmd; + cde_ctx->convert_cmd = combined_cmd + + cde_ctx->init_cmd_num_entries; + + return 0; +} + +static int gk20a_init_cde_img(struct gk20a_cde_ctx *cde_ctx, + struct nvgpu_firmware *img) +{ + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + struct gk20a_cde_app *cde_app = &l->cde_app; + u32 *data = (u32 *)img->data; + u32 num_of_elems; + struct gk20a_cde_hdr_elem *elem; + u32 min_size = 0; + int err = 0; + unsigned int i; + + min_size += 2 * sizeof(u32); + if (img->size < min_size) { + nvgpu_warn(g, "cde: invalid image header"); + return -EINVAL; + } + + cde_app->firmware_version = data[0]; + num_of_elems = data[1]; + + min_size += num_of_elems * sizeof(*elem); + if (img->size < min_size) { + nvgpu_warn(g, "cde: bad image"); + return -EINVAL; + } + + elem = (struct gk20a_cde_hdr_elem *)&data[2]; + for (i = 0; i < num_of_elems; i++) { + int err = 0; + switch (elem->type) { + case TYPE_BUF: + err = gk20a_init_cde_buf(cde_ctx, img, &elem->buf); + break; + case TYPE_REPLACE: + err = gk20a_init_cde_replace(cde_ctx, img, + &elem->replace); + break; + case TYPE_PARAM: + err = gk20a_init_cde_param(cde_ctx, img, &elem->param); + break; + case TYPE_REQUIRED_CLASS: + err = gk20a_init_cde_required_class(cde_ctx, img, + elem->required_class); + break; + case TYPE_COMMAND: + { + struct gk20a_cde_cmd_elem *cmd = (void *) + &img->data[elem->command.data_byte_offset]; + err = gk20a_init_cde_command(cde_ctx, img, + elem->command.op, cmd, + elem->command.num_entries); + break; + } + case TYPE_ARRAY: + memcpy(&cde_app->arrays[elem->array.id][0], + elem->array.data, + MAX_CDE_ARRAY_ENTRIES*sizeof(u32)); + break; + default: + nvgpu_warn(g, "cde: unknown header element"); + err = -EINVAL; + } + + if (err) + goto deinit_image; + + elem++; + } + + if (!cde_ctx->init_convert_cmd || !cde_ctx->init_cmd_num_entries) { + nvgpu_warn(g, "cde: convert command not defined"); + err = -EINVAL; + goto deinit_image; + } + + if (!cde_ctx->convert_cmd || !cde_ctx->convert_cmd_num_entries) { + nvgpu_warn(g, "cde: convert command not defined"); + err = -EINVAL; + goto deinit_image; + } + + err = gk20a_cde_pack_cmdbufs(cde_ctx); + if (err) + goto deinit_image; + + return 0; + +deinit_image: + gk20a_deinit_cde_img(cde_ctx); + return err; +} + +static int gk20a_cde_execute_buffer(struct gk20a_cde_ctx *cde_ctx, + u32 op, struct nvgpu_channel_fence *fence, + u32 flags, struct gk20a_fence **fence_out) +{ + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + struct nvgpu_gpfifo_entry *gpfifo = NULL; + int num_entries = 0; + + /* check command type */ + if (op == TYPE_BUF_COMMAND_INIT) { + /* both init and convert combined */ + gpfifo = cde_ctx->init_convert_cmd; + num_entries = cde_ctx->init_cmd_num_entries + + cde_ctx->convert_cmd_num_entries; + } else if (op == TYPE_BUF_COMMAND_CONVERT) { + gpfifo = cde_ctx->convert_cmd; + num_entries = cde_ctx->convert_cmd_num_entries; + } else if (op == TYPE_BUF_COMMAND_NOOP) { + /* Any non-null gpfifo will suffice with 0 num_entries */ + gpfifo = cde_ctx->init_convert_cmd; + num_entries = 0; + } else { + nvgpu_warn(g, "cde: unknown buffer"); + return -EINVAL; + } + + if (gpfifo == NULL) { + nvgpu_warn(g, "cde: buffer not available"); + return -ENOSYS; + } + + return nvgpu_submit_channel_gpfifo_kernel(cde_ctx->ch, gpfifo, + num_entries, flags, fence, fence_out); +} + +static void gk20a_cde_ctx_release(struct gk20a_cde_ctx *cde_ctx) +__acquires(&cde_app->mutex) +__releases(&cde_app->mutex) +{ + struct gk20a_cde_app *cde_app = &cde_ctx->l->cde_app; + struct gk20a *g = &cde_ctx->l->g; + + nvgpu_log(g, gpu_dbg_cde_ctx, "releasing use on %p", cde_ctx); + trace_gk20a_cde_release(cde_ctx); + + nvgpu_mutex_acquire(&cde_app->mutex); + + if (cde_ctx->in_use) { + cde_ctx->in_use = false; + nvgpu_list_move(&cde_ctx->list, &cde_app->free_contexts); + cde_app->ctx_usecount--; + } else { + nvgpu_log_info(g, "double release cde context %p", cde_ctx); + } + + nvgpu_mutex_release(&cde_app->mutex); +} + +static void gk20a_cde_ctx_deleter_fn(struct work_struct *work) +__acquires(&cde_app->mutex) +__releases(&cde_app->mutex) +{ + struct delayed_work *delay_work = to_delayed_work(work); + struct gk20a_cde_ctx *cde_ctx = container_of(delay_work, + struct gk20a_cde_ctx, ctx_deleter_work); + struct gk20a_cde_app *cde_app = &cde_ctx->l->cde_app; + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + int err; + + /* someone has just taken it? engine deletion started? */ + if (cde_ctx->in_use || !cde_app->initialised) + return; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_cde_ctx, + "cde: attempting to delete temporary %p", cde_ctx); + + err = gk20a_busy(g); + if (err) { + /* this context would find new use anyway later, so not freeing + * here does not leak anything */ + nvgpu_warn(g, "cde: cannot set gk20a on, postponing" + " temp ctx deletion"); + return; + } + + nvgpu_mutex_acquire(&cde_app->mutex); + if (cde_ctx->in_use || !cde_app->initialised) { + nvgpu_log(g, gpu_dbg_cde_ctx, + "cde: context use raced, not deleting %p", + cde_ctx); + goto out; + } + + WARN(delayed_work_pending(&cde_ctx->ctx_deleter_work), + "double pending %p", cde_ctx); + + gk20a_cde_remove_ctx(cde_ctx); + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_cde_ctx, + "cde: destroyed %p count=%d use=%d max=%d", + cde_ctx, cde_app->ctx_count, cde_app->ctx_usecount, + cde_app->ctx_count_top); + +out: + nvgpu_mutex_release(&cde_app->mutex); + gk20a_idle(g); +} + +static struct gk20a_cde_ctx *gk20a_cde_do_get_context(struct nvgpu_os_linux *l) +__must_hold(&cde_app->mutex) +{ + struct gk20a *g = &l->g; + struct gk20a_cde_app *cde_app = &l->cde_app; + struct gk20a_cde_ctx *cde_ctx; + + /* exhausted? */ + + if (cde_app->ctx_usecount >= MAX_CTX_USE_COUNT) + return ERR_PTR(-EAGAIN); + + /* idle context available? */ + + if (!nvgpu_list_empty(&cde_app->free_contexts)) { + cde_ctx = nvgpu_list_first_entry(&cde_app->free_contexts, + gk20a_cde_ctx, list); + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_cde_ctx, + "cde: got free %p count=%d use=%d max=%d", + cde_ctx, cde_app->ctx_count, + cde_app->ctx_usecount, + cde_app->ctx_count_top); + trace_gk20a_cde_get_context(cde_ctx); + + /* deleter work may be scheduled, but in_use prevents it */ + cde_ctx->in_use = true; + nvgpu_list_move(&cde_ctx->list, &cde_app->used_contexts); + cde_app->ctx_usecount++; + + /* cancel any deletions now that ctx is in use */ + gk20a_cde_cancel_deleter(cde_ctx, true); + return cde_ctx; + } + + /* no free contexts, get a temporary one */ + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_cde_ctx, + "cde: no free contexts, count=%d", + cde_app->ctx_count); + + cde_ctx = gk20a_cde_allocate_context(l); + if (IS_ERR(cde_ctx)) { + nvgpu_warn(g, "cde: cannot allocate context: %ld", + PTR_ERR(cde_ctx)); + return cde_ctx; + } + + trace_gk20a_cde_get_context(cde_ctx); + cde_ctx->in_use = true; + cde_ctx->is_temporary = true; + cde_app->ctx_usecount++; + cde_app->ctx_count++; + if (cde_app->ctx_count > cde_app->ctx_count_top) + cde_app->ctx_count_top = cde_app->ctx_count; + nvgpu_list_add(&cde_ctx->list, &cde_app->used_contexts); + + return cde_ctx; +} + +static struct gk20a_cde_ctx *gk20a_cde_get_context(struct nvgpu_os_linux *l) +__releases(&cde_app->mutex) +__acquires(&cde_app->mutex) +{ + struct gk20a *g = &l->g; + struct gk20a_cde_app *cde_app = &l->cde_app; + struct gk20a_cde_ctx *cde_ctx = NULL; + struct nvgpu_timeout timeout; + + nvgpu_timeout_init(g, &timeout, MAX_CTX_RETRY_TIME, + NVGPU_TIMER_CPU_TIMER); + + do { + cde_ctx = gk20a_cde_do_get_context(l); + if (PTR_ERR(cde_ctx) != -EAGAIN) + break; + + /* exhausted, retry */ + nvgpu_mutex_release(&cde_app->mutex); + cond_resched(); + nvgpu_mutex_acquire(&cde_app->mutex); + } while (!nvgpu_timeout_expired(&timeout)); + + return cde_ctx; +} + +static struct gk20a_cde_ctx *gk20a_cde_allocate_context(struct nvgpu_os_linux *l) +{ + struct gk20a *g = &l->g; + struct gk20a_cde_ctx *cde_ctx; + int ret; + + cde_ctx = nvgpu_kzalloc(g, sizeof(*cde_ctx)); + if (!cde_ctx) + return ERR_PTR(-ENOMEM); + + cde_ctx->l = l; + cde_ctx->dev = dev_from_gk20a(g); + + ret = gk20a_cde_load(cde_ctx); + if (ret) { + nvgpu_kfree(g, cde_ctx); + return ERR_PTR(ret); + } + + nvgpu_init_list_node(&cde_ctx->list); + cde_ctx->is_temporary = false; + cde_ctx->in_use = false; + INIT_DELAYED_WORK(&cde_ctx->ctx_deleter_work, + gk20a_cde_ctx_deleter_fn); + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_cde_ctx, "cde: allocated %p", cde_ctx); + trace_gk20a_cde_allocate_context(cde_ctx); + return cde_ctx; +} + +static u32 gk20a_cde_mapping_page_size(struct vm_gk20a *vm, + u32 map_offset, u32 map_size) +{ + struct gk20a *g = gk20a_from_vm(vm); + + /* + * To be simple we will just make the map size depend on the + * iommu'ability of the driver. If there's an IOMMU we can rely on + * buffers being contiguous. If not, then we'll use 4k pages since we + * know that will work for any buffer. + */ + if (!nvgpu_iommuable(g)) + return SZ_4K; + + /* + * If map size or offset is not 64K aligned then use small pages. + */ + if (map_size & (vm->big_page_size - 1) || + map_offset & (vm->big_page_size - 1)) + return SZ_4K; + + return vm->big_page_size; +} + +int gk20a_cde_convert(struct nvgpu_os_linux *l, + struct dma_buf *compbits_scatter_buf, + u64 compbits_byte_offset, + u64 scatterbuffer_byte_offset, + struct nvgpu_channel_fence *fence, + u32 __flags, struct gk20a_cde_param *params, + int num_params, struct gk20a_fence **fence_out) +__acquires(&l->cde_app->mutex) +__releases(&l->cde_app->mutex) +{ + struct gk20a *g = &l->g; + struct gk20a_cde_ctx *cde_ctx = NULL; + struct gk20a_comptags comptags; + struct nvgpu_os_buffer os_buf = { + compbits_scatter_buf, + NULL, + dev_from_gk20a(g) + }; + u64 mapped_compbits_offset = 0; + u64 compbits_size = 0; + u64 mapped_scatterbuffer_offset = 0; + u64 scatterbuffer_size = 0; + u64 map_vaddr = 0; + u64 map_offset = 0; + u64 map_size = 0; + u8 *surface = NULL; + u64 big_page_mask = 0; + u32 flags; + int err, i; + const s16 compbits_kind = 0; + u32 submit_op; + struct dma_buf_attachment *attachment; + + nvgpu_log(g, gpu_dbg_cde, "compbits_byte_offset=%llu scatterbuffer_byte_offset=%llu", + compbits_byte_offset, scatterbuffer_byte_offset); + + /* scatter buffer must be after compbits buffer */ + if (scatterbuffer_byte_offset && + scatterbuffer_byte_offset < compbits_byte_offset) + return -EINVAL; + + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_mutex_acquire(&l->cde_app.mutex); + cde_ctx = gk20a_cde_get_context(l); + nvgpu_mutex_release(&l->cde_app.mutex); + if (IS_ERR(cde_ctx)) { + err = PTR_ERR(cde_ctx); + goto exit_idle; + } + + /* First, map the buffer to local va */ + + /* ensure that the compbits buffer has drvdata */ + err = gk20a_dmabuf_alloc_drvdata(compbits_scatter_buf, + dev_from_gk20a(g)); + if (err) + goto exit_idle; + + /* compbits don't start at page aligned offset, so we need to align + the region to be mapped */ + big_page_mask = cde_ctx->vm->big_page_size - 1; + map_offset = compbits_byte_offset & ~big_page_mask; + map_size = compbits_scatter_buf->size - map_offset; + + + /* compute compbit start offset from the beginning of the mapped + area */ + mapped_compbits_offset = compbits_byte_offset - map_offset; + if (scatterbuffer_byte_offset) { + compbits_size = scatterbuffer_byte_offset - + compbits_byte_offset; + mapped_scatterbuffer_offset = scatterbuffer_byte_offset - + map_offset; + scatterbuffer_size = compbits_scatter_buf->size - + scatterbuffer_byte_offset; + } else { + compbits_size = compbits_scatter_buf->size - + compbits_byte_offset; + } + + nvgpu_log(g, gpu_dbg_cde, "map_offset=%llu map_size=%llu", + map_offset, map_size); + nvgpu_log(g, gpu_dbg_cde, "mapped_compbits_offset=%llu compbits_size=%llu", + mapped_compbits_offset, compbits_size); + nvgpu_log(g, gpu_dbg_cde, "mapped_scatterbuffer_offset=%llu scatterbuffer_size=%llu", + mapped_scatterbuffer_offset, scatterbuffer_size); + + + /* map the destination buffer */ + get_dma_buf(compbits_scatter_buf); /* a ref for nvgpu_vm_map_linux */ + err = nvgpu_vm_map_linux(cde_ctx->vm, compbits_scatter_buf, 0, + NVGPU_VM_MAP_CACHEABLE | + NVGPU_VM_MAP_DIRECT_KIND_CTRL, + gk20a_cde_mapping_page_size(cde_ctx->vm, + map_offset, + map_size), + NV_KIND_INVALID, + compbits_kind, /* incompressible kind */ + gk20a_mem_flag_none, + map_offset, map_size, + NULL, + &map_vaddr); + if (err) { + nvgpu_warn(g, "cde: failed to map compbits scatter buf at %lld size %lld", + map_offset, map_size); + dma_buf_put(compbits_scatter_buf); + err = -EINVAL; + goto exit_idle; + } + + if (scatterbuffer_byte_offset && + l->ops.cde.need_scatter_buffer && + l->ops.cde.need_scatter_buffer(g)) { + struct sg_table *sgt; + void *scatter_buffer; + + surface = dma_buf_vmap(compbits_scatter_buf); + if (IS_ERR(surface)) { + nvgpu_warn(g, + "dma_buf_vmap failed"); + err = -EINVAL; + goto exit_unmap_vaddr; + } + + scatter_buffer = surface + scatterbuffer_byte_offset; + + nvgpu_log(g, gpu_dbg_cde, "surface=0x%p scatterBuffer=0x%p", + surface, scatter_buffer); + sgt = gk20a_mm_pin(dev_from_gk20a(g), compbits_scatter_buf, + &attachment); + if (IS_ERR(sgt)) { + nvgpu_warn(g, + "mm_pin failed"); + err = -EINVAL; + goto exit_unmap_surface; + } else { + err = l->ops.cde.populate_scatter_buffer(g, sgt, + compbits_byte_offset, scatter_buffer, + scatterbuffer_size); + WARN_ON(err); + + gk20a_mm_unpin(dev_from_gk20a(g), compbits_scatter_buf, + attachment, sgt); + if (err) + goto exit_unmap_surface; + } + + __cpuc_flush_dcache_area(scatter_buffer, scatterbuffer_size); + dma_buf_vunmap(compbits_scatter_buf, surface); + surface = NULL; + } + + /* store source buffer compression tags */ + gk20a_get_comptags(&os_buf, &comptags); + cde_ctx->surf_param_offset = comptags.offset; + cde_ctx->surf_param_lines = comptags.lines; + + /* store surface vaddr. This is actually compbit vaddr, but since + compbits live in the same surface, and we can get the alloc base + address by using gpuva_to_iova_base, this will do */ + cde_ctx->surf_vaddr = map_vaddr; + + /* store information about destination */ + cde_ctx->compbit_vaddr = map_vaddr + mapped_compbits_offset; + cde_ctx->compbit_size = compbits_size; + + cde_ctx->scatterbuffer_vaddr = map_vaddr + mapped_scatterbuffer_offset; + cde_ctx->scatterbuffer_size = scatterbuffer_size; + + /* remove existing argument data */ + memset(cde_ctx->user_param_values, 0, + sizeof(cde_ctx->user_param_values)); + + /* read user space arguments for the conversion */ + for (i = 0; i < num_params; i++) { + struct gk20a_cde_param *param = params + i; + int id = param->id - NUM_RESERVED_PARAMS; + + if (id < 0 || id >= MAX_CDE_USER_PARAMS) { + nvgpu_warn(g, "cde: unknown user parameter"); + err = -EINVAL; + goto exit_unmap_surface; + } + cde_ctx->user_param_values[id] = param->value; + } + + /* patch data */ + err = gk20a_cde_patch_params(cde_ctx); + if (err) { + nvgpu_warn(g, "cde: failed to patch parameters"); + goto exit_unmap_surface; + } + + nvgpu_log(g, gpu_dbg_cde, "cde: buffer=cbc, size=%zu, gpuva=%llx\n", + g->gr.compbit_store.mem.size, cde_ctx->backing_store_vaddr); + nvgpu_log(g, gpu_dbg_cde, "cde: buffer=compbits, size=%llu, gpuva=%llx\n", + cde_ctx->compbit_size, cde_ctx->compbit_vaddr); + nvgpu_log(g, gpu_dbg_cde, "cde: buffer=scatterbuffer, size=%llu, gpuva=%llx\n", + cde_ctx->scatterbuffer_size, cde_ctx->scatterbuffer_vaddr); + + /* take always the postfence as it is needed for protecting the + * cde context */ + flags = __flags | NVGPU_SUBMIT_FLAGS_FENCE_GET; + + /* gk20a_cde_execute_buffer() will grab a power reference of it's own */ + gk20a_idle(g); + + if (comptags.lines == 0) { + /* + * Nothing to do on the buffer, but do a null kickoff for + * managing the pre and post fences. + */ + submit_op = TYPE_BUF_COMMAND_NOOP; + } else if (!cde_ctx->init_cmd_executed) { + /* + * First time, so include the init pushbuf too in addition to + * the conversion code. + */ + submit_op = TYPE_BUF_COMMAND_INIT; + } else { + /* + * The usual condition: execute just the conversion. + */ + submit_op = TYPE_BUF_COMMAND_CONVERT; + } + err = gk20a_cde_execute_buffer(cde_ctx, submit_op, + fence, flags, fence_out); + + if (comptags.lines != 0 && !err) + cde_ctx->init_cmd_executed = true; + + /* unmap the buffers - channel holds references to them now */ + nvgpu_vm_unmap(cde_ctx->vm, map_vaddr, NULL); + + return err; + +exit_unmap_surface: + if (surface) + dma_buf_vunmap(compbits_scatter_buf, surface); +exit_unmap_vaddr: + nvgpu_vm_unmap(cde_ctx->vm, map_vaddr, NULL); +exit_idle: + gk20a_idle(g); + return err; +} + +static void gk20a_cde_finished_ctx_cb(struct channel_gk20a *ch, void *data) +__acquires(&cde_app->mutex) +__releases(&cde_app->mutex) +{ + struct gk20a_cde_ctx *cde_ctx = data; + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + struct gk20a_cde_app *cde_app = &l->cde_app; + bool channel_idle; + + channel_gk20a_joblist_lock(ch); + channel_idle = channel_gk20a_joblist_is_empty(ch); + channel_gk20a_joblist_unlock(ch); + + if (!channel_idle) + return; + + trace_gk20a_cde_finished_ctx_cb(cde_ctx); + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_cde_ctx, "cde: finished %p", cde_ctx); + if (!cde_ctx->in_use) + nvgpu_log_info(g, "double finish cde context %p on channel %p", + cde_ctx, ch); + + if (gk20a_channel_check_timedout(ch)) { + if (cde_ctx->is_temporary) { + nvgpu_warn(g, + "cde: channel had timed out" + " (temporary channel)"); + /* going to be deleted anyway */ + } else { + nvgpu_warn(g, + "cde: channel had timed out" + ", reloading"); + /* mark it to be deleted, replace with a new one */ + nvgpu_mutex_acquire(&cde_app->mutex); + cde_ctx->is_temporary = true; + if (gk20a_cde_create_context(l)) { + nvgpu_err(g, "cde: can't replace context"); + } + nvgpu_mutex_release(&cde_app->mutex); + } + } + + /* delete temporary contexts later (watch for doubles) */ + if (cde_ctx->is_temporary && cde_ctx->in_use) { + WARN_ON(delayed_work_pending(&cde_ctx->ctx_deleter_work)); + schedule_delayed_work(&cde_ctx->ctx_deleter_work, + msecs_to_jiffies(CTX_DELETE_TIME)); + } + + if (!gk20a_channel_check_timedout(ch)) { + gk20a_cde_ctx_release(cde_ctx); + } +} + +static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx) +{ + struct nvgpu_os_linux *l = cde_ctx->l; + struct gk20a *g = &l->g; + struct nvgpu_firmware *img; + struct channel_gk20a *ch; + struct tsg_gk20a *tsg; + struct gr_gk20a *gr = &g->gr; + struct nvgpu_setup_bind_args setup_bind_args; + int err = 0; + u64 vaddr; + + img = nvgpu_request_firmware(g, "gpu2cde.bin", 0); + if (!img) { + nvgpu_err(g, "cde: could not fetch the firmware"); + return -ENOSYS; + } + + tsg = gk20a_tsg_open(g, nvgpu_current_pid(g)); + if (!tsg) { + nvgpu_err(g, "cde: could not create TSG"); + err = -ENOMEM; + goto err_get_gk20a_channel; + } + + ch = gk20a_open_new_channel_with_cb(g, gk20a_cde_finished_ctx_cb, + cde_ctx, + -1, + false); + if (!ch) { + nvgpu_warn(g, "cde: gk20a channel not available"); + err = -ENOMEM; + goto err_get_gk20a_channel; + } + + ch->timeout.enabled = false; + + /* bind the channel to the vm */ + err = g->ops.mm.vm_bind_channel(g->mm.cde.vm, ch); + if (err) { + nvgpu_warn(g, "cde: could not bind vm"); + goto err_commit_va; + } + + err = gk20a_tsg_bind_channel(tsg, ch); + if (err) { + nvgpu_err(g, "cde: unable to bind to tsg"); + goto err_setup_bind; + } + + setup_bind_args.num_gpfifo_entries = 1024; + setup_bind_args.num_inflight_jobs = 0; + setup_bind_args.flags = 0; + err = nvgpu_channel_setup_bind(ch, &setup_bind_args); + if (err) { + nvgpu_warn(g, "cde: unable to setup channel"); + goto err_setup_bind; + } + + /* map backing store to gpu virtual space */ + vaddr = nvgpu_gmmu_map(ch->vm, &gr->compbit_store.mem, + g->gr.compbit_store.mem.size, + NVGPU_VM_MAP_CACHEABLE, + gk20a_mem_flag_read_only, + false, + gr->compbit_store.mem.aperture); + + if (!vaddr) { + nvgpu_warn(g, "cde: cannot map compression bit backing store"); + err = -ENOMEM; + goto err_map_backingstore; + } + + /* store initialisation data */ + cde_ctx->ch = ch; + cde_ctx->tsg = tsg; + cde_ctx->vm = ch->vm; + cde_ctx->backing_store_vaddr = vaddr; + + /* initialise the firmware */ + err = gk20a_init_cde_img(cde_ctx, img); + if (err) { + nvgpu_warn(g, "cde: image initialisation failed"); + goto err_init_cde_img; + } + + /* initialisation done */ + nvgpu_release_firmware(g, img); + + return 0; + +err_init_cde_img: + nvgpu_gmmu_unmap(ch->vm, &g->gr.compbit_store.mem, vaddr); +err_map_backingstore: +err_setup_bind: + nvgpu_vm_put(ch->vm); +err_commit_va: +err_get_gk20a_channel: + nvgpu_release_firmware(g, img); + nvgpu_err(g, "cde: couldn't initialise buffer converter: %d", err); + return err; +} + +int gk20a_cde_reload(struct nvgpu_os_linux *l) +__acquires(&l->cde_app->mutex) +__releases(&l->cde_app->mutex) +{ + struct gk20a *g = &l->g; + struct gk20a_cde_app *cde_app = &l->cde_app; + int err; + + if (!cde_app->initialised) + return -ENOSYS; + + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_mutex_acquire(&cde_app->mutex); + + gk20a_cde_stop(l); + + err = gk20a_cde_create_contexts(l); + if (!err) + cde_app->initialised = true; + + nvgpu_mutex_release(&cde_app->mutex); + + gk20a_idle(g); + return err; +} + +int gk20a_init_cde_support(struct nvgpu_os_linux *l) +__acquires(&cde_app->mutex) +__releases(&cde_app->mutex) +{ + struct gk20a_cde_app *cde_app = &l->cde_app; + struct gk20a *g = &l->g; + int err; + + if (cde_app->initialised) + return 0; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_cde_ctx, "cde: init"); + + err = nvgpu_mutex_init(&cde_app->mutex); + if (err) + return err; + + nvgpu_mutex_acquire(&cde_app->mutex); + + nvgpu_init_list_node(&cde_app->free_contexts); + nvgpu_init_list_node(&cde_app->used_contexts); + cde_app->ctx_count = 0; + cde_app->ctx_count_top = 0; + cde_app->ctx_usecount = 0; + + err = gk20a_cde_create_contexts(l); + if (!err) + cde_app->initialised = true; + + nvgpu_mutex_release(&cde_app->mutex); + nvgpu_log(g, gpu_dbg_cde_ctx, "cde: init finished: %d", err); + + if (err) + nvgpu_mutex_destroy(&cde_app->mutex); + + return err; +} + +enum cde_launch_patch_id { + PATCH_H_QMD_CTA_RASTER_WIDTH_ID = 1024, + PATCH_H_QMD_CTA_RASTER_HEIGHT_ID = 1025, + PATCH_QMD_CTA_RASTER_DEPTH_ID = 1026, /* for firmware v0 only */ + PATCH_QMD_CTA_THREAD_DIMENSION0_ID = 1027, + PATCH_QMD_CTA_THREAD_DIMENSION1_ID = 1028, + PATCH_QMD_CTA_THREAD_DIMENSION2_ID = 1029, /* for firmware v0 only */ + PATCH_USER_CONST_XTILES_ID = 1030, /* for firmware v0 only */ + PATCH_USER_CONST_YTILES_ID = 1031, /* for firmware v0 only */ + PATCH_USER_CONST_BLOCKHEIGHTLOG2_ID = 1032, + PATCH_USER_CONST_DSTPITCH_ID = 1033, /* for firmware v0 only */ + PATCH_H_USER_CONST_FLAGS_ID = 1034, /* for firmware v0 only */ + PATCH_H_VPC_CURRENT_GRID_SIZE_X_ID = 1035, + PATCH_H_VPC_CURRENT_GRID_SIZE_Y_ID = 1036, + PATCH_H_VPC_CURRENT_GRID_SIZE_Z_ID = 1037, + PATCH_VPC_CURRENT_GROUP_SIZE_X_ID = 1038, + PATCH_VPC_CURRENT_GROUP_SIZE_Y_ID = 1039, + PATCH_VPC_CURRENT_GROUP_SIZE_Z_ID = 1040, + PATCH_USER_CONST_XBLOCKS_ID = 1041, + PATCH_H_USER_CONST_DSTOFFSET_ID = 1042, + PATCH_V_QMD_CTA_RASTER_WIDTH_ID = 1043, + PATCH_V_QMD_CTA_RASTER_HEIGHT_ID = 1044, + PATCH_V_USER_CONST_DSTOFFSET_ID = 1045, + PATCH_V_VPC_CURRENT_GRID_SIZE_X_ID = 1046, + PATCH_V_VPC_CURRENT_GRID_SIZE_Y_ID = 1047, + PATCH_V_VPC_CURRENT_GRID_SIZE_Z_ID = 1048, + PATCH_H_LAUNCH_WORD1_ID = 1049, + PATCH_H_LAUNCH_WORD2_ID = 1050, + PATCH_V_LAUNCH_WORD1_ID = 1051, + PATCH_V_LAUNCH_WORD2_ID = 1052, + PATCH_H_QMD_PROGRAM_OFFSET_ID = 1053, + PATCH_H_QMD_REGISTER_COUNT_ID = 1054, + PATCH_V_QMD_PROGRAM_OFFSET_ID = 1055, + PATCH_V_QMD_REGISTER_COUNT_ID = 1056, +}; + +/* maximum number of WRITE_PATCHes in the below function */ +#define MAX_CDE_LAUNCH_PATCHES 32 + +static int gk20a_buffer_convert_gpu_to_cde_v1( + struct nvgpu_os_linux *l, + struct dma_buf *dmabuf, u32 consumer, + u64 offset, u64 compbits_hoffset, u64 compbits_voffset, + u64 scatterbuffer_offset, + u32 width, u32 height, u32 block_height_log2, + u32 submit_flags, struct nvgpu_channel_fence *fence_in, + struct gk20a_buffer_state *state) +{ + struct gk20a *g = &l->g; + struct gk20a_cde_param params[MAX_CDE_LAUNCH_PATCHES]; + int param = 0; + int err = 0; + struct gk20a_fence *new_fence = NULL; + const int wgx = 8; + const int wgy = 8; + const int compbits_per_byte = 4; /* one byte stores 4 compbit pairs */ + const int xalign = compbits_per_byte * wgx; + const int yalign = wgy; + + /* Compute per launch parameters */ + const int xtiles = (width + 7) >> 3; + const int ytiles = (height + 7) >> 3; + const int gridw_h = roundup(xtiles, xalign) / xalign; + const int gridh_h = roundup(ytiles, yalign) / yalign; + const int gridw_v = roundup(ytiles, xalign) / xalign; + const int gridh_v = roundup(xtiles, yalign) / yalign; + const int xblocks = (xtiles + 1) >> 1; + const int voffset = compbits_voffset - compbits_hoffset; + + int hprog = -1; + int vprog = -1; + + if (l->ops.cde.get_program_numbers) + l->ops.cde.get_program_numbers(g, block_height_log2, + l->cde_app.shader_parameter, + &hprog, &vprog); + else { + nvgpu_warn(g, "cde: chip not supported"); + return -ENOSYS; + } + + if (hprog < 0 || vprog < 0) { + nvgpu_warn(g, "cde: could not determine programs"); + return -ENOSYS; + } + + if (xtiles > 8192 / 8 || ytiles > 8192 / 8) + nvgpu_warn(g, "cde: surface is exceptionally large (xtiles=%d, ytiles=%d)", + xtiles, ytiles); + + nvgpu_log(g, gpu_dbg_cde, "w=%d, h=%d, bh_log2=%d, compbits_hoffset=0x%llx, compbits_voffset=0x%llx, scatterbuffer_offset=0x%llx", + width, height, block_height_log2, + compbits_hoffset, compbits_voffset, scatterbuffer_offset); + nvgpu_log(g, gpu_dbg_cde, "resolution (%d, %d) tiles (%d, %d)", + width, height, xtiles, ytiles); + nvgpu_log(g, gpu_dbg_cde, "group (%d, %d) gridH (%d, %d) gridV (%d, %d)", + wgx, wgy, gridw_h, gridh_h, gridw_v, gridh_v); + nvgpu_log(g, gpu_dbg_cde, "hprog=%d, offset=0x%x, regs=%d, vprog=%d, offset=0x%x, regs=%d", + hprog, + l->cde_app.arrays[ARRAY_PROGRAM_OFFSET][hprog], + l->cde_app.arrays[ARRAY_REGISTER_COUNT][hprog], + vprog, + l->cde_app.arrays[ARRAY_PROGRAM_OFFSET][vprog], + l->cde_app.arrays[ARRAY_REGISTER_COUNT][vprog]); + + /* Write parameters */ +#define WRITE_PATCH(NAME, VALUE) \ + params[param++] = (struct gk20a_cde_param){NAME##_ID, 0, VALUE} + WRITE_PATCH(PATCH_USER_CONST_XBLOCKS, xblocks); + WRITE_PATCH(PATCH_USER_CONST_BLOCKHEIGHTLOG2, + block_height_log2); + WRITE_PATCH(PATCH_QMD_CTA_THREAD_DIMENSION0, wgx); + WRITE_PATCH(PATCH_QMD_CTA_THREAD_DIMENSION1, wgy); + WRITE_PATCH(PATCH_VPC_CURRENT_GROUP_SIZE_X, wgx); + WRITE_PATCH(PATCH_VPC_CURRENT_GROUP_SIZE_Y, wgy); + WRITE_PATCH(PATCH_VPC_CURRENT_GROUP_SIZE_Z, 1); + + WRITE_PATCH(PATCH_H_QMD_CTA_RASTER_WIDTH, gridw_h); + WRITE_PATCH(PATCH_H_QMD_CTA_RASTER_HEIGHT, gridh_h); + WRITE_PATCH(PATCH_H_USER_CONST_DSTOFFSET, 0); + WRITE_PATCH(PATCH_H_VPC_CURRENT_GRID_SIZE_X, gridw_h); + WRITE_PATCH(PATCH_H_VPC_CURRENT_GRID_SIZE_Y, gridh_h); + WRITE_PATCH(PATCH_H_VPC_CURRENT_GRID_SIZE_Z, 1); + + WRITE_PATCH(PATCH_V_QMD_CTA_RASTER_WIDTH, gridw_v); + WRITE_PATCH(PATCH_V_QMD_CTA_RASTER_HEIGHT, gridh_v); + WRITE_PATCH(PATCH_V_USER_CONST_DSTOFFSET, voffset); + WRITE_PATCH(PATCH_V_VPC_CURRENT_GRID_SIZE_X, gridw_v); + WRITE_PATCH(PATCH_V_VPC_CURRENT_GRID_SIZE_Y, gridh_v); + WRITE_PATCH(PATCH_V_VPC_CURRENT_GRID_SIZE_Z, 1); + + WRITE_PATCH(PATCH_H_QMD_PROGRAM_OFFSET, + l->cde_app.arrays[ARRAY_PROGRAM_OFFSET][hprog]); + WRITE_PATCH(PATCH_H_QMD_REGISTER_COUNT, + l->cde_app.arrays[ARRAY_REGISTER_COUNT][hprog]); + WRITE_PATCH(PATCH_V_QMD_PROGRAM_OFFSET, + l->cde_app.arrays[ARRAY_PROGRAM_OFFSET][vprog]); + WRITE_PATCH(PATCH_V_QMD_REGISTER_COUNT, + l->cde_app.arrays[ARRAY_REGISTER_COUNT][vprog]); + + if (consumer & NVGPU_GPU_COMPBITS_CDEH) { + WRITE_PATCH(PATCH_H_LAUNCH_WORD1, + l->cde_app.arrays[ARRAY_LAUNCH_COMMAND][0]); + WRITE_PATCH(PATCH_H_LAUNCH_WORD2, + l->cde_app.arrays[ARRAY_LAUNCH_COMMAND][1]); + } else { + WRITE_PATCH(PATCH_H_LAUNCH_WORD1, + l->cde_app.arrays[ARRAY_LAUNCH_COMMAND][2]); + WRITE_PATCH(PATCH_H_LAUNCH_WORD2, + l->cde_app.arrays[ARRAY_LAUNCH_COMMAND][3]); + } + + if (consumer & NVGPU_GPU_COMPBITS_CDEV) { + WRITE_PATCH(PATCH_V_LAUNCH_WORD1, + l->cde_app.arrays[ARRAY_LAUNCH_COMMAND][0]); + WRITE_PATCH(PATCH_V_LAUNCH_WORD2, + l->cde_app.arrays[ARRAY_LAUNCH_COMMAND][1]); + } else { + WRITE_PATCH(PATCH_V_LAUNCH_WORD1, + l->cde_app.arrays[ARRAY_LAUNCH_COMMAND][2]); + WRITE_PATCH(PATCH_V_LAUNCH_WORD2, + l->cde_app.arrays[ARRAY_LAUNCH_COMMAND][3]); + } +#undef WRITE_PATCH + + err = gk20a_cde_convert(l, dmabuf, + compbits_hoffset, + scatterbuffer_offset, + fence_in, submit_flags, + params, param, &new_fence); + if (err) + goto out; + + /* compbits generated, update state & fence */ + gk20a_fence_put(state->fence); + state->fence = new_fence; + state->valid_compbits |= consumer & + (NVGPU_GPU_COMPBITS_CDEH | NVGPU_GPU_COMPBITS_CDEV); +out: + return err; +} + +static int gk20a_buffer_convert_gpu_to_cde( + struct nvgpu_os_linux *l, struct dma_buf *dmabuf, u32 consumer, + u64 offset, u64 compbits_hoffset, u64 compbits_voffset, + u64 scatterbuffer_offset, + u32 width, u32 height, u32 block_height_log2, + u32 submit_flags, struct nvgpu_channel_fence *fence_in, + struct gk20a_buffer_state *state) +{ + struct gk20a *g = &l->g; + int err = 0; + + if (!l->cde_app.initialised) + return -ENOSYS; + + nvgpu_log(g, gpu_dbg_cde, "firmware version = %d\n", + l->cde_app.firmware_version); + + if (l->cde_app.firmware_version == 1) { + err = gk20a_buffer_convert_gpu_to_cde_v1( + l, dmabuf, consumer, offset, compbits_hoffset, + compbits_voffset, scatterbuffer_offset, + width, height, block_height_log2, + submit_flags, fence_in, state); + } else { + nvgpu_err(g, "unsupported CDE firmware version %d", + l->cde_app.firmware_version); + err = -EINVAL; + } + + return err; +} + +int gk20a_prepare_compressible_read( + struct nvgpu_os_linux *l, u32 buffer_fd, u32 request, u64 offset, + u64 compbits_hoffset, u64 compbits_voffset, + u64 scatterbuffer_offset, + u32 width, u32 height, u32 block_height_log2, + u32 submit_flags, struct nvgpu_channel_fence *fence, + u32 *valid_compbits, u32 *zbc_color, + struct gk20a_fence **fence_out) +{ + struct gk20a *g = &l->g; + int err = 0; + struct gk20a_buffer_state *state; + struct dma_buf *dmabuf; + u32 missing_bits; + + dmabuf = dma_buf_get(buffer_fd); + if (IS_ERR(dmabuf)) + return -EINVAL; + + err = gk20a_dmabuf_get_state(dmabuf, g, offset, &state); + if (err) { + dma_buf_put(dmabuf); + return err; + } + + missing_bits = (state->valid_compbits ^ request) & request; + + nvgpu_mutex_acquire(&state->lock); + + if (state->valid_compbits && request == NVGPU_GPU_COMPBITS_NONE) { + + gk20a_fence_put(state->fence); + state->fence = NULL; + /* state->fence = decompress(); + state->valid_compbits = 0; */ + err = -EINVAL; + goto out; + } else if (missing_bits) { + u32 missing_cde_bits = missing_bits & + (NVGPU_GPU_COMPBITS_CDEH | NVGPU_GPU_COMPBITS_CDEV); + if ((state->valid_compbits & NVGPU_GPU_COMPBITS_GPU) && + missing_cde_bits) { + err = gk20a_buffer_convert_gpu_to_cde( + l, dmabuf, + missing_cde_bits, + offset, compbits_hoffset, + compbits_voffset, scatterbuffer_offset, + width, height, block_height_log2, + submit_flags, fence, + state); + if (err) + goto out; + } + } + + if (state->fence && fence_out) + *fence_out = gk20a_fence_get(state->fence); + + if (valid_compbits) + *valid_compbits = state->valid_compbits; + + if (zbc_color) + *zbc_color = state->zbc_color; + +out: + nvgpu_mutex_release(&state->lock); + dma_buf_put(dmabuf); + return err; +} + +int gk20a_mark_compressible_write(struct gk20a *g, u32 buffer_fd, + u32 valid_compbits, u64 offset, u32 zbc_color) +{ + int err; + struct gk20a_buffer_state *state; + struct dma_buf *dmabuf; + + dmabuf = dma_buf_get(buffer_fd); + if (IS_ERR(dmabuf)) { + nvgpu_err(g, "invalid dmabuf"); + return -EINVAL; + } + + err = gk20a_dmabuf_get_state(dmabuf, g, offset, &state); + if (err) { + nvgpu_err(g, "could not get state from dmabuf"); + dma_buf_put(dmabuf); + return err; + } + + nvgpu_mutex_acquire(&state->lock); + + /* Update the compbits state. */ + state->valid_compbits = valid_compbits; + state->zbc_color = zbc_color; + + /* Discard previous compbit job fence. */ + gk20a_fence_put(state->fence); + state->fence = NULL; + + nvgpu_mutex_release(&state->lock); + dma_buf_put(dmabuf); + return 0; +} diff --git a/include/os/linux/cde.h b/include/os/linux/cde.h new file mode 100644 index 0000000..5928b62 --- /dev/null +++ b/include/os/linux/cde.h @@ -0,0 +1,326 @@ +/* + * GK20A color decompression engine support + * + * Copyright (c) 2014-2017, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _CDE_GK20A_H_ +#define _CDE_GK20A_H_ + +#include +#include +#include + +#include +#include + +#define MAX_CDE_BUFS 10 +#define MAX_CDE_PARAMS 64 +#define MAX_CDE_USER_PARAMS 40 +#define MAX_CDE_ARRAY_ENTRIES 9 + +/* + * The size of the context ring buffer that is dedicated for handling cde + * jobs. Re-using a context (=channel) for a differnt cde job forces a cpu + * wait on the previous job to that channel, so increasing this value + * reduces the likelihood of stalls. + */ +#define NUM_CDE_CONTEXTS 4 + +struct dma_buf; +struct device; +struct nvgpu_os_linux; +struct gk20a; +struct gk20a_fence; +struct nvgpu_channel_fence; +struct channel_gk20a; +struct vm_gk20a; +struct nvgpu_gpfifo_entry; + +/* + * this element defines a buffer that is allocated and mapped into gpu address + * space. data_byte_offset defines the beginning of the buffer inside the + * firmare. num_bytes defines how many bytes the firmware contains. + * + * If data_byte_offset is zero, we allocate an empty buffer. + */ + +struct gk20a_cde_hdr_buf { + u64 data_byte_offset; + u64 num_bytes; +}; + +/* + * this element defines a constant patching in buffers. It basically + * computes physical address to +source_byte_offset. The + * address is then modified into patch value as per: + * value = (current_value & ~mask) | (address << shift) & mask . + * + * The type field defines the register size as: + * 0=u32, + * 1=u64 (little endian), + * 2=u64 (big endian) + */ + +struct gk20a_cde_hdr_replace { + u32 target_buf; + u32 source_buf; + s32 shift; + u32 type; + u64 target_byte_offset; + u64 source_byte_offset; + u64 mask; +}; + +enum { + TYPE_PARAM_TYPE_U32 = 0, + TYPE_PARAM_TYPE_U64_LITTLE, + TYPE_PARAM_TYPE_U64_BIG +}; + +/* + * this element defines a runtime patching in buffers. Parameters with id from + * 0 to 1024 are reserved for special usage as follows: + * 0 = comptags_per_cacheline, + * 1 = slices_per_fbp, + * 2 = num_fbps + * 3 = source buffer first page offset + * 4 = source buffer block height log2 + * 5 = backing store memory address + * 6 = destination memory address + * 7 = destination size (bytes) + * 8 = backing store size (bytes) + * 9 = cache line size + * + * Parameters above id 1024 are user-specified. I.e. they determine where a + * parameters from user space should be placed in buffers, what is their + * type, etc. + * + * Once the value is available, we add data_offset to the value. + * + * The value address is then modified into patch value as per: + * value = (current_value & ~mask) | (address << shift) & mask . + * + * The type field defines the register size as: + * 0=u32, + * 1=u64 (little endian), + * 2=u64 (big endian) + */ + +struct gk20a_cde_hdr_param { + u32 id; + u32 target_buf; + s32 shift; + u32 type; + s64 data_offset; + u64 target_byte_offset; + u64 mask; +}; + +enum { + TYPE_PARAM_COMPTAGS_PER_CACHELINE = 0, + TYPE_PARAM_GPU_CONFIGURATION, + TYPE_PARAM_FIRSTPAGEOFFSET, + TYPE_PARAM_NUMPAGES, + TYPE_PARAM_BACKINGSTORE, + TYPE_PARAM_DESTINATION, + TYPE_PARAM_DESTINATION_SIZE, + TYPE_PARAM_BACKINGSTORE_SIZE, + TYPE_PARAM_SOURCE_SMMU_ADDR, + TYPE_PARAM_BACKINGSTORE_BASE_HW, + TYPE_PARAM_GOBS_PER_COMPTAGLINE_PER_SLICE, + TYPE_PARAM_SCATTERBUFFER, + TYPE_PARAM_SCATTERBUFFER_SIZE, + NUM_RESERVED_PARAMS = 1024, +}; + +/* + * This header element defines a command. The op field determines whether the + * element is defining an init (0) or convert command (1). data_byte_offset + * denotes the beginning address of command elements in the file. + */ + +struct gk20a_cde_hdr_command { + u32 op; + u32 num_entries; + u64 data_byte_offset; +}; + +enum { + TYPE_BUF_COMMAND_INIT = 0, + TYPE_BUF_COMMAND_CONVERT, + TYPE_BUF_COMMAND_NOOP +}; + +/* + * This is a command element defines one entry inside push buffer. target_buf + * defines the buffer including the pushbuffer entries, target_byte_offset the + * offset inside the buffer and num_bytes the number of words in the buffer. + */ + +struct gk20a_cde_cmd_elem { + u32 target_buf; + u32 padding; + u64 target_byte_offset; + u64 num_bytes; +}; + +/* + * This element is used for storing a small array of data. + */ + +enum { + ARRAY_PROGRAM_OFFSET = 0, + ARRAY_REGISTER_COUNT, + ARRAY_LAUNCH_COMMAND, + NUM_CDE_ARRAYS +}; + +struct gk20a_cde_hdr_array { + u32 id; + u32 data[MAX_CDE_ARRAY_ENTRIES]; +}; + +/* + * Following defines a single header element. Each element has a type and + * some of the data structures. + */ + +struct gk20a_cde_hdr_elem { + u32 type; + u32 padding; + union { + struct gk20a_cde_hdr_buf buf; + struct gk20a_cde_hdr_replace replace; + struct gk20a_cde_hdr_param param; + u32 required_class; + struct gk20a_cde_hdr_command command; + struct gk20a_cde_hdr_array array; + }; +}; + +enum { + TYPE_BUF = 0, + TYPE_REPLACE, + TYPE_PARAM, + TYPE_REQUIRED_CLASS, + TYPE_COMMAND, + TYPE_ARRAY +}; + +struct gk20a_cde_param { + u32 id; + u32 padding; + u64 value; +}; + +struct gk20a_cde_ctx { + struct nvgpu_os_linux *l; + struct device *dev; + + /* channel related data */ + struct channel_gk20a *ch; + struct tsg_gk20a *tsg; + struct vm_gk20a *vm; + + /* buf converter configuration */ + struct nvgpu_mem mem[MAX_CDE_BUFS]; + unsigned int num_bufs; + + /* buffer patching params (where should patching be done) */ + struct gk20a_cde_hdr_param params[MAX_CDE_PARAMS]; + unsigned int num_params; + + /* storage for user space parameter values */ + u32 user_param_values[MAX_CDE_USER_PARAMS]; + + u32 surf_param_offset; + u32 surf_param_lines; + u64 surf_vaddr; + + u64 compbit_vaddr; + u64 compbit_size; + + u64 scatterbuffer_vaddr; + u64 scatterbuffer_size; + + u64 backing_store_vaddr; + + struct nvgpu_gpfifo_entry *init_convert_cmd; + int init_cmd_num_entries; + + struct nvgpu_gpfifo_entry *convert_cmd; + int convert_cmd_num_entries; + + struct kobj_attribute attr; + + bool init_cmd_executed; + + struct nvgpu_list_node list; + bool is_temporary; + bool in_use; + struct delayed_work ctx_deleter_work; +}; + +static inline struct gk20a_cde_ctx * +gk20a_cde_ctx_from_list(struct nvgpu_list_node *node) +{ + return (struct gk20a_cde_ctx *) + ((uintptr_t)node - offsetof(struct gk20a_cde_ctx, list)); +}; + +struct gk20a_cde_app { + bool initialised; + struct nvgpu_mutex mutex; + + struct nvgpu_list_node free_contexts; + struct nvgpu_list_node used_contexts; + unsigned int ctx_count; + unsigned int ctx_usecount; + unsigned int ctx_count_top; + + u32 firmware_version; + + u32 arrays[NUM_CDE_ARRAYS][MAX_CDE_ARRAY_ENTRIES]; + + u32 shader_parameter; +}; + +void gk20a_cde_destroy(struct nvgpu_os_linux *l); +void gk20a_cde_suspend(struct nvgpu_os_linux *l); +int gk20a_init_cde_support(struct nvgpu_os_linux *l); +int gk20a_cde_reload(struct nvgpu_os_linux *l); +int gk20a_cde_convert(struct nvgpu_os_linux *l, + struct dma_buf *compbits_buf, + u64 compbits_byte_offset, + u64 scatterbuffer_byte_offset, + struct nvgpu_channel_fence *fence, + u32 __flags, struct gk20a_cde_param *params, + int num_params, struct gk20a_fence **fence_out); + +int gk20a_prepare_compressible_read( + struct nvgpu_os_linux *l, u32 buffer_fd, u32 request, u64 offset, + u64 compbits_hoffset, u64 compbits_voffset, + u64 scatterbuffer_offset, + u32 width, u32 height, u32 block_height_log2, + u32 submit_flags, struct nvgpu_channel_fence *fence, + u32 *valid_compbits, u32 *zbc_color, + struct gk20a_fence **fence_out); +int gk20a_mark_compressible_write( + struct gk20a *g, u32 buffer_fd, u32 valid_compbits, u64 offset, + u32 zbc_color); +int nvgpu_cde_init_ops(struct nvgpu_os_linux *l); + +#endif diff --git a/include/os/linux/cde_gm20b.c b/include/os/linux/cde_gm20b.c new file mode 100644 index 0000000..a9a4754 --- /dev/null +++ b/include/os/linux/cde_gm20b.c @@ -0,0 +1,59 @@ +/* + * GM20B CDE + * + * Copyright (c) 2015-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "cde_gm20b.h" + +enum programs { + PROG_HPASS = 0, + PROG_VPASS_LARGE = 1, + PROG_VPASS_SMALL = 2, + PROG_HPASS_DEBUG = 3, + PROG_VPASS_LARGE_DEBUG = 4, + PROG_VPASS_SMALL_DEBUG = 5, + PROG_PASSTHROUGH = 6, +}; + +void gm20b_cde_get_program_numbers(struct gk20a *g, + u32 block_height_log2, + u32 shader_parameter, + int *hprog_out, int *vprog_out) +{ + int hprog = PROG_HPASS; + int vprog = (block_height_log2 >= 2) ? + PROG_VPASS_LARGE : PROG_VPASS_SMALL; + if (shader_parameter == 1) { + hprog = PROG_PASSTHROUGH; + vprog = PROG_PASSTHROUGH; + } else if (shader_parameter == 2) { + hprog = PROG_HPASS_DEBUG; + vprog = (block_height_log2 >= 2) ? + PROG_VPASS_LARGE_DEBUG : + PROG_VPASS_SMALL_DEBUG; + } + + *hprog_out = hprog; + *vprog_out = vprog; +} diff --git a/include/os/linux/cde_gm20b.h b/include/os/linux/cde_gm20b.h new file mode 100644 index 0000000..fac8aaf --- /dev/null +++ b/include/os/linux/cde_gm20b.h @@ -0,0 +1,33 @@ +/* + * GM20B CDE + * + * Copyright (c) 2015-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _NVHOST_GM20B_CDE +#define _NVHOST_GM20B_CDE + +void gm20b_cde_get_program_numbers(struct gk20a *g, + u32 block_height_log2, + u32 shader_parameter, + int *hprog_out, int *vprog_out); + +#endif diff --git a/include/os/linux/cde_gp10b.c b/include/os/linux/cde_gp10b.c new file mode 100644 index 0000000..6356d33 --- /dev/null +++ b/include/os/linux/cde_gp10b.c @@ -0,0 +1,153 @@ +/* + * GP10B CDE + * + * Copyright (c) 2015-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "cde_gp10b.h" + +enum gp10b_programs { + GP10B_PROG_HPASS = 0, + GP10B_PROG_HPASS_4K = 1, + GP10B_PROG_VPASS = 2, + GP10B_PROG_VPASS_4K = 3, + GP10B_PROG_HPASS_DEBUG = 4, + GP10B_PROG_HPASS_4K_DEBUG = 5, + GP10B_PROG_VPASS_DEBUG = 6, + GP10B_PROG_VPASS_4K_DEBUG = 7, + GP10B_PROG_PASSTHROUGH = 8, +}; + +void gp10b_cde_get_program_numbers(struct gk20a *g, + u32 block_height_log2, + u32 shader_parameter, + int *hprog_out, int *vprog_out) +{ + int hprog, vprog; + + if (shader_parameter == 1) { + hprog = GP10B_PROG_PASSTHROUGH; + vprog = GP10B_PROG_PASSTHROUGH; + } else { + hprog = GP10B_PROG_HPASS; + vprog = GP10B_PROG_VPASS; + if (shader_parameter == 2) { + hprog = GP10B_PROG_HPASS_DEBUG; + vprog = GP10B_PROG_VPASS_DEBUG; + } + if (!nvgpu_iommuable(g)) { + if (!g->mm.disable_bigpage) { + nvgpu_warn(g, + "When no IOMMU big pages cannot be used"); + } + hprog |= 1; + vprog |= 1; + } + } + + *hprog_out = hprog; + *vprog_out = vprog; +} + +bool gp10b_need_scatter_buffer(struct gk20a *g) +{ + return !nvgpu_iommuable(g); +} + +static u8 parity(u32 a) +{ + a ^= a>>16u; + a ^= a>>8u; + a ^= a>>4u; + a &= 0xfu; + return (0x6996u >> a) & 1u; +} + +int gp10b_populate_scatter_buffer(struct gk20a *g, + struct sg_table *sgt, + size_t surface_size, + void *scatter_buffer_ptr, + size_t scatter_buffer_size) +{ + /* map scatter buffer to CPU VA and fill it */ + const u32 page_size_log2 = 12; + const u32 page_size = 1 << page_size_log2; + const u32 page_size_shift = page_size_log2 - 7u; + + /* 0011 1111 1111 1111 1111 1110 0100 1000 */ + const u32 getSliceMaskGP10B = 0x3ffffe48; + u8 *scatter_buffer = scatter_buffer_ptr; + + size_t i; + struct scatterlist *sg = NULL; + u8 d = 0; + size_t page = 0; + size_t pages_left; + + surface_size = round_up(surface_size, page_size); + + pages_left = surface_size >> page_size_log2; + if ((pages_left >> 3) > scatter_buffer_size) + return -ENOMEM; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) { + unsigned int j; + u64 surf_pa = sg_phys(sg); + unsigned int n = (int)(sg->length >> page_size_log2); + + nvgpu_log(g, gpu_dbg_cde, "surfPA=0x%llx + %d pages", surf_pa, n); + + for (j=0; j < n && pages_left > 0; j++, surf_pa += page_size) { + u32 addr = (((u32)(surf_pa>>7)) & getSliceMaskGP10B) >> page_size_shift; + u8 scatter_bit = parity(addr); + u8 bit = page & 7; + + d |= scatter_bit << bit; + if (bit == 7) { + scatter_buffer[page >> 3] = d; + d = 0; + } + + ++page; + --pages_left; + } + + if (pages_left == 0) + break; + } + + /* write the last byte in case the number of pages is not divisible by 8 */ + if ((page & 7) != 0) + scatter_buffer[page >> 3] = d; + + if (nvgpu_log_mask_enabled(g, gpu_dbg_cde)) { + nvgpu_log(g, gpu_dbg_cde, "scatterBuffer content:"); + for (i = 0; i < page >> 3; i++) { + nvgpu_log(g, gpu_dbg_cde, " %x", scatter_buffer[i]); + } + } + + return 0; +} diff --git a/include/os/linux/cde_gp10b.h b/include/os/linux/cde_gp10b.h new file mode 100644 index 0000000..3ecca2a --- /dev/null +++ b/include/os/linux/cde_gp10b.h @@ -0,0 +1,40 @@ +/* + * GP10B CDE + * + * Copyright (c) 2015-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _NVHOST_GP10B_CDE +#define _NVHOST_GP10B_CDE + +#include "os_linux.h" + +void gp10b_cde_get_program_numbers(struct gk20a *g, + u32 block_height_log2, + u32 shader_parameter, + int *hprog_out, int *vprog_out); +bool gp10b_need_scatter_buffer(struct gk20a *g); +int gp10b_populate_scatter_buffer(struct gk20a *g, + struct sg_table *sgt, + size_t surface_size, + void *scatter_buffer_ptr, + size_t scatter_buffer_size); +#endif diff --git a/include/os/linux/channel.h b/include/os/linux/channel.h new file mode 100644 index 0000000..e6326fa --- /dev/null +++ b/include/os/linux/channel.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef NVGPU_LINUX_CHANNEL_H +#define NVGPU_LINUX_CHANNEL_H + +#include +#include + +#include + +struct channel_gk20a; +struct nvgpu_gpfifo; +struct nvgpu_submit_gpfifo_args; +struct nvgpu_channel_fence; +struct gk20a_fence; +struct fifo_profile_gk20a; +struct nvgpu_os_linux; + +struct sync_fence; +struct sync_timeline; + +struct nvgpu_channel_completion_cb { + /* + * Signal channel owner via a callback, if set, in job cleanup with + * schedule_work. Means that something finished on the channel (perhaps + * more than one job). + */ + void (*fn)(struct channel_gk20a *, void *); + void *user_data; + /* Make access to the two above atomic */ + struct nvgpu_spinlock lock; + /* Per-channel async work task, cannot reschedule itself */ + struct work_struct work; +}; + +struct nvgpu_error_notifier { + struct dma_buf *dmabuf; + void *vaddr; + + struct nvgpu_notification *notification; + + struct nvgpu_mutex mutex; +}; + +/* + * This struct contains fence_related data. + * e.g. sync_timeline for sync_fences. + */ +struct nvgpu_os_fence_framework { + struct sync_timeline *timeline; +}; + +struct nvgpu_usermode_bufs_linux { + /* + * Common low level info of these is stored in nvgpu_mems in + * channel_gk20a; these hold lifetimes for the actual dmabuf and its + * dma mapping. + */ + struct nvgpu_usermode_buf_linux { + struct dma_buf *dmabuf; + struct dma_buf_attachment *attachment; + struct sg_table *sgt; + } gpfifo, userd; +}; + +struct nvgpu_channel_linux { + struct channel_gk20a *ch; + + struct nvgpu_os_fence_framework fence_framework; + + struct nvgpu_channel_completion_cb completion_cb; + struct nvgpu_error_notifier error_notifier; + + struct dma_buf *cyclestate_buffer_handler; + + struct nvgpu_usermode_bufs_linux usermode; +}; + +u32 nvgpu_submit_gpfifo_user_flags_to_common_flags(u32 user_flags); +int nvgpu_init_channel_support_linux(struct nvgpu_os_linux *l); +void nvgpu_remove_channel_support_linux(struct nvgpu_os_linux *l); + +struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g, + void (*update_fn)(struct channel_gk20a *, void *), + void *update_fn_data, + int runlist_id, + bool is_privileged_channel); + +#endif diff --git a/include/os/linux/clk.c b/include/os/linux/clk.c new file mode 100644 index 0000000..e9796ea --- /dev/null +++ b/include/os/linux/clk.c @@ -0,0 +1,286 @@ +/* + * Linux clock support + * + * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include "clk.h" +#include "os_linux.h" +#include "platform_gk20a.h" + +#include +#include + +#define HZ_TO_MHZ(x) ((x) / 1000000) + +static unsigned long nvgpu_linux_clk_get_rate(struct gk20a *g, u32 api_domain) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev_from_gk20a(g)); + unsigned long ret; + + switch (api_domain) { + case CTRL_CLK_DOMAIN_GPCCLK: + if (g->clk.tegra_clk) + ret = clk_get_rate(g->clk.tegra_clk); + else + ret = clk_get_rate(platform->clk[0]); + break; + case CTRL_CLK_DOMAIN_PWRCLK: + ret = clk_get_rate(platform->clk[1]); + break; + default: + nvgpu_err(g, "unknown clock: %u", api_domain); + ret = 0; + break; + } + + return ret; +} + +static int nvgpu_linux_clk_set_rate(struct gk20a *g, + u32 api_domain, unsigned long rate) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev_from_gk20a(g)); + int ret; + + switch (api_domain) { + case CTRL_CLK_DOMAIN_GPCCLK: + if (g->clk.tegra_clk) + ret = clk_set_rate(g->clk.tegra_clk, rate); + else + ret = clk_set_rate(platform->clk[0], rate); + break; + case CTRL_CLK_DOMAIN_PWRCLK: + ret = clk_set_rate(platform->clk[1], rate); + break; + default: + nvgpu_err(g, "unknown clock: %u", api_domain); + ret = -EINVAL; + break; + } + + return ret; +} + +static unsigned long nvgpu_linux_get_fmax_at_vmin_safe(struct gk20a *g) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev_from_gk20a(g)); + + /* + * On Tegra platforms with GPCPLL bus (gbus) GPU tegra_clk clock exposed + * to frequency governor is a shared user on the gbus. The latter can be + * accessed as GPU clock parent, and incorporate DVFS related data. + */ + if (g->clk.tegra_clk) + return tegra_dvfs_get_fmax_at_vmin_safe_t( + g->clk.tegra_clk_parent); + + if (platform->maxmin_clk_id) + return tegra_bpmp_dvfs_get_fmax_at_vmin( + platform->maxmin_clk_id); + + return 0; +} + +static u32 nvgpu_linux_get_ref_clock_rate(struct gk20a *g) +{ + struct clk *c; + + c = clk_get_sys("gpu_ref", "gpu_ref"); + if (IS_ERR(c)) { + nvgpu_err(g, "failed to get GPCPLL reference clock"); + return 0; + } + + return clk_get_rate(c); +} + +static int nvgpu_linux_predict_mv_at_hz_cur_tfloor(struct clk_gk20a *clk, + unsigned long rate) +{ + return tegra_dvfs_predict_mv_at_hz_cur_tfloor( + clk->tegra_clk_parent, rate); +} + +static unsigned long nvgpu_linux_get_maxrate(struct gk20a *g, u32 api_domain) +{ + int ret; + u16 min_mhz, max_mhz; + + switch (api_domain) { + case CTRL_CLK_DOMAIN_GPCCLK: + ret = tegra_dvfs_get_maxrate(g->clk.tegra_clk_parent); + /* If dvfs not supported */ + if (ret == 0) { + int err = nvgpu_clk_arb_get_arbiter_clk_range(g, + NVGPU_CLK_DOMAIN_GPCCLK, + &min_mhz, &max_mhz); + if (err == 0) { + ret = max_mhz * 1000000L; + } + } + break; + default: + nvgpu_err(g, "unknown clock: %u", api_domain); + ret = 0; + break; + } + + return ret; +} + +/* + * This API is used to return a list of supported frequencies by igpu. + * Set *num_points as 0 to get the size of the freqs list, returned + * by *num_points itself. freqs array must be provided by caller. + * If *num_points is non-zero, then freqs array size must atleast + * equal *num_points. + */ +static int nvgpu_linux_clk_get_f_points(struct gk20a *g, + u32 api_domain, u32 *num_points, u16 *freqs) +{ + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = gk20a_get_platform(dev); + unsigned long *gpu_freq_table; + int ret = 0; + int num_supported_freq = 0; + u32 i; + + switch (api_domain) { + case CTRL_CLK_DOMAIN_GPCCLK: + ret = platform->get_clk_freqs(dev, &gpu_freq_table, + &num_supported_freq); + + if (ret) { + return ret; + } + + if (num_points == NULL) { + return -EINVAL; + } + + if (*num_points != 0U) { + if (freqs == NULL || (*num_points > (u32)num_supported_freq)) { + return -EINVAL; + } + } + + if (*num_points == 0) { + *num_points = num_supported_freq; + } else { + for (i = 0; i < *num_points; i++) { + freqs[i] = HZ_TO_MHZ(gpu_freq_table[i]); + } + } + break; + default: + nvgpu_err(g, "unknown clock: %u", api_domain); + ret = -EINVAL; + break; + } + + return ret; +} + +static int nvgpu_clk_get_range(struct gk20a *g, u32 api_domain, + u16 *min_mhz, u16 *max_mhz) +{ + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = gk20a_get_platform(dev); + unsigned long *freqs; + int num_freqs; + int ret; + + switch (api_domain) { + case CTRL_CLK_DOMAIN_GPCCLK: + ret = platform->get_clk_freqs(dev, &freqs, &num_freqs); + + if (!ret) { + *min_mhz = HZ_TO_MHZ(freqs[0]); + *max_mhz = HZ_TO_MHZ(freqs[num_freqs - 1]); + } + break; + default: + nvgpu_err(g, "unknown clock: %u", api_domain); + ret = -EINVAL; + break; + } + + return ret; +} + +/* rate_target should be passed in as Hz + rounded_rate is returned in Hz */ +static int nvgpu_clk_get_round_rate(struct gk20a *g, + u32 api_domain, unsigned long rate_target, + unsigned long *rounded_rate) +{ + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = gk20a_get_platform(dev); + unsigned long *freqs; + int num_freqs; + int i, ret = 0; + + switch (api_domain) { + case CTRL_CLK_DOMAIN_GPCCLK: + ret = platform->get_clk_freqs(dev, &freqs, &num_freqs); + + for (i = 0; i < num_freqs; ++i) { + if (freqs[i] >= rate_target) { + *rounded_rate = freqs[i]; + return 0; + } + } + *rounded_rate = freqs[num_freqs - 1]; + break; + default: + nvgpu_err(g, "unknown clock: %u", api_domain); + ret = -EINVAL; + break; + } + + return ret; +} + +static int nvgpu_linux_prepare_enable(struct clk_gk20a *clk) +{ + return clk_prepare_enable(clk->tegra_clk); +} + +static void nvgpu_linux_disable_unprepare(struct clk_gk20a *clk) +{ + clk_disable_unprepare(clk->tegra_clk); +} + +void nvgpu_linux_init_clk_support(struct gk20a *g) +{ + g->ops.clk.get_rate = nvgpu_linux_clk_get_rate; + g->ops.clk.set_rate = nvgpu_linux_clk_set_rate; + g->ops.clk.get_fmax_at_vmin_safe = nvgpu_linux_get_fmax_at_vmin_safe; + g->ops.clk.get_ref_clock_rate = nvgpu_linux_get_ref_clock_rate; + g->ops.clk.predict_mv_at_hz_cur_tfloor = nvgpu_linux_predict_mv_at_hz_cur_tfloor; + g->ops.clk.get_maxrate = nvgpu_linux_get_maxrate; + g->ops.clk.prepare_enable = nvgpu_linux_prepare_enable; + g->ops.clk.disable_unprepare = nvgpu_linux_disable_unprepare; + g->ops.clk.clk_domain_get_f_points = nvgpu_linux_clk_get_f_points; + g->ops.clk.get_clk_range = nvgpu_clk_get_range; + g->ops.clk.clk_get_round_rate = nvgpu_clk_get_round_rate; + g->ops.clk.measure_freq = nvgpu_clk_measure_freq; +} diff --git a/include/os/linux/clk.h b/include/os/linux/clk.h new file mode 100644 index 0000000..614a7fd --- /dev/null +++ b/include/os/linux/clk.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NVGPU_COMMON_LINUX_CLK_H + +struct gk20a; +void nvgpu_linux_init_clk_support(struct gk20a *g); + +#endif diff --git a/include/os/linux/comptags.c b/include/os/linux/comptags.c new file mode 100644 index 0000000..ab37197 --- /dev/null +++ b/include/os/linux/comptags.c @@ -0,0 +1,140 @@ +/* +* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include + +#include "dmabuf.h" + +void gk20a_get_comptags(struct nvgpu_os_buffer *buf, + struct gk20a_comptags *comptags) +{ + struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(buf->dmabuf, + buf->dev); + + if (!comptags) + return; + + if (!priv) { + memset(comptags, 0, sizeof(*comptags)); + return; + } + + nvgpu_mutex_acquire(&priv->lock); + *comptags = priv->comptags; + nvgpu_mutex_release(&priv->lock); +} + +int gk20a_alloc_or_get_comptags(struct gk20a *g, + struct nvgpu_os_buffer *buf, + struct gk20a_comptag_allocator *allocator, + struct gk20a_comptags *comptags) +{ + struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(buf->dmabuf, + buf->dev); + u32 offset; + int err; + unsigned int ctag_granularity; + u32 lines; + + if (!priv) + return -ENOSYS; + + nvgpu_mutex_acquire(&priv->lock); + + if (priv->comptags.allocated) { + /* + * already allocated + */ + *comptags = priv->comptags; + + err = 0; + goto exit_locked; + } + + ctag_granularity = g->ops.fb.compression_page_size(g); + lines = DIV_ROUND_UP_ULL(buf->dmabuf->size, ctag_granularity); + + /* 0-sized buffer? Shouldn't occur, but let's check anyways. */ + if (lines < 1) { + err = -EINVAL; + goto exit_locked; + } + + /* store the allocator so we can use it when we free the ctags */ + priv->comptag_allocator = allocator; + err = gk20a_comptaglines_alloc(allocator, &offset, lines); + if (!err) { + priv->comptags.offset = offset; + priv->comptags.lines = lines; + priv->comptags.needs_clear = true; + } else { + priv->comptags.offset = 0; + priv->comptags.lines = 0; + priv->comptags.needs_clear = false; + } + + /* + * We don't report an error here if comptag alloc failed. The + * caller will simply fallback to incompressible kinds. It + * would not be safe to re-allocate comptags anyways on + * successive calls, as that would break map aliasing. + */ + err = 0; + priv->comptags.allocated = true; + + *comptags = priv->comptags; + +exit_locked: + nvgpu_mutex_release(&priv->lock); + + return err; +} + +bool gk20a_comptags_start_clear(struct nvgpu_os_buffer *buf) +{ + struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(buf->dmabuf, + buf->dev); + bool clear_started = false; + + if (priv) { + nvgpu_mutex_acquire(&priv->lock); + + clear_started = priv->comptags.needs_clear; + + if (!clear_started) + nvgpu_mutex_release(&priv->lock); + } + + return clear_started; +} + +void gk20a_comptags_finish_clear(struct nvgpu_os_buffer *buf, + bool clear_successful) +{ + struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(buf->dmabuf, + buf->dev); + if (priv) { + if (clear_successful) + priv->comptags.needs_clear = false; + + nvgpu_mutex_release(&priv->lock); + } +} diff --git a/include/os/linux/cond.c b/include/os/linux/cond.c new file mode 100644 index 0000000..633c34f --- /dev/null +++ b/include/os/linux/cond.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include + +int nvgpu_cond_init(struct nvgpu_cond *cond) +{ + init_waitqueue_head(&cond->wq); + cond->initialized = true; + + return 0; +} + +void nvgpu_cond_destroy(struct nvgpu_cond *cond) +{ + cond->initialized = false; +} + +int nvgpu_cond_signal(struct nvgpu_cond *cond) +{ + if (!cond->initialized) + return -EINVAL; + + wake_up(&cond->wq); + + return 0; +} + +int nvgpu_cond_signal_interruptible(struct nvgpu_cond *cond) +{ + if (!cond->initialized) + return -EINVAL; + + wake_up_interruptible(&cond->wq); + + return 0; +} + +int nvgpu_cond_broadcast(struct nvgpu_cond *cond) +{ + if (!cond->initialized) + return -EINVAL; + + wake_up_all(&cond->wq); + + return 0; +} + +int nvgpu_cond_broadcast_interruptible(struct nvgpu_cond *cond) +{ + if (!cond->initialized) + return -EINVAL; + + wake_up_interruptible_all(&cond->wq); + + return 0; +} diff --git a/include/os/linux/ctxsw_trace.c b/include/os/linux/ctxsw_trace.c new file mode 100644 index 0000000..2d36d9c --- /dev/null +++ b/include/os/linux/ctxsw_trace.c @@ -0,0 +1,792 @@ +/* + * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a/gr_gk20a.h" +#include "gk20a/fecs_trace_gk20a.h" + +#include "platform_gk20a.h" +#include "os_linux.h" +#include "ctxsw_trace.h" + +#include +#include + +#define GK20A_CTXSW_TRACE_MAX_VM_RING_SIZE (128*PAGE_SIZE) + +/* Userland-facing FIFO (one global + eventually one per VM) */ +struct gk20a_ctxsw_dev { + struct gk20a *g; + + struct nvgpu_ctxsw_ring_header *hdr; + struct nvgpu_gpu_ctxsw_trace_entry *ents; + struct nvgpu_gpu_ctxsw_trace_filter filter; + bool write_enabled; + struct nvgpu_cond readout_wq; + size_t size; + u32 num_ents; + + nvgpu_atomic_t vma_ref; + + struct nvgpu_mutex write_lock; +}; + + +struct gk20a_ctxsw_trace { + struct gk20a_ctxsw_dev devs[GK20A_CTXSW_TRACE_NUM_DEVS]; +}; + +static inline int ring_is_empty(struct nvgpu_ctxsw_ring_header *hdr) +{ + return (hdr->write_idx == hdr->read_idx); +} + +static inline int ring_is_full(struct nvgpu_ctxsw_ring_header *hdr) +{ + return ((hdr->write_idx + 1) % hdr->num_ents) == hdr->read_idx; +} + +static inline int ring_len(struct nvgpu_ctxsw_ring_header *hdr) +{ + return (hdr->write_idx - hdr->read_idx) % hdr->num_ents; +} + +static void nvgpu_set_ctxsw_trace_entry(struct nvgpu_ctxsw_trace_entry *entry_dst, + struct nvgpu_gpu_ctxsw_trace_entry *entry_src) +{ + entry_dst->tag = entry_src->tag; + entry_dst->vmid = entry_src->vmid; + entry_dst->seqno = entry_src->seqno; + entry_dst->context_id = entry_src->context_id; + entry_dst->pid = entry_src->pid; + entry_dst->timestamp = entry_src->timestamp; +} + +ssize_t gk20a_ctxsw_dev_read(struct file *filp, char __user *buf, size_t size, + loff_t *off) +{ + struct gk20a_ctxsw_dev *dev = filp->private_data; + struct gk20a *g = dev->g; + struct nvgpu_ctxsw_ring_header *hdr = dev->hdr; + struct nvgpu_ctxsw_trace_entry __user *entry = + (struct nvgpu_ctxsw_trace_entry *) buf; + struct nvgpu_ctxsw_trace_entry user_entry; + size_t copied = 0; + int err; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, + "filp=%p buf=%p size=%zu", filp, buf, size); + + nvgpu_mutex_acquire(&dev->write_lock); + while (ring_is_empty(hdr)) { + nvgpu_mutex_release(&dev->write_lock); + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + err = NVGPU_COND_WAIT_INTERRUPTIBLE(&dev->readout_wq, + !ring_is_empty(hdr), 0); + if (err) + return err; + nvgpu_mutex_acquire(&dev->write_lock); + } + + while (size >= sizeof(struct nvgpu_gpu_ctxsw_trace_entry)) { + if (ring_is_empty(hdr)) + break; + + nvgpu_set_ctxsw_trace_entry(&user_entry, &dev->ents[hdr->read_idx]); + if (copy_to_user(entry, &user_entry, + sizeof(*entry))) { + nvgpu_mutex_release(&dev->write_lock); + return -EFAULT; + } + + hdr->read_idx++; + if (hdr->read_idx >= hdr->num_ents) + hdr->read_idx = 0; + + entry++; + copied += sizeof(*entry); + size -= sizeof(*entry); + } + + nvgpu_log(g, gpu_dbg_ctxsw, "copied=%zu read_idx=%d", copied, + hdr->read_idx); + + *off = hdr->read_idx; + nvgpu_mutex_release(&dev->write_lock); + + return copied; +} + +static int gk20a_ctxsw_dev_ioctl_trace_enable(struct gk20a_ctxsw_dev *dev) +{ + struct gk20a *g = dev->g; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, "trace enabled"); + nvgpu_mutex_acquire(&dev->write_lock); + dev->write_enabled = true; + nvgpu_mutex_release(&dev->write_lock); + dev->g->ops.fecs_trace.enable(dev->g); + return 0; +} + +static int gk20a_ctxsw_dev_ioctl_trace_disable(struct gk20a_ctxsw_dev *dev) +{ + struct gk20a *g = dev->g; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, "trace disabled"); + dev->g->ops.fecs_trace.disable(dev->g); + nvgpu_mutex_acquire(&dev->write_lock); + dev->write_enabled = false; + nvgpu_mutex_release(&dev->write_lock); + return 0; +} + +static int gk20a_ctxsw_dev_alloc_buffer(struct gk20a_ctxsw_dev *dev, + size_t size) +{ + struct gk20a *g = dev->g; + void *buf; + int err; + + if ((dev->write_enabled) || (nvgpu_atomic_read(&dev->vma_ref))) + return -EBUSY; + + err = g->ops.fecs_trace.alloc_user_buffer(g, &buf, &size); + if (err) + return err; + + + dev->hdr = buf; + dev->ents = (struct nvgpu_gpu_ctxsw_trace_entry *) (dev->hdr + 1); + dev->size = size; + dev->num_ents = dev->hdr->num_ents; + + nvgpu_log(g, gpu_dbg_ctxsw, "size=%zu hdr=%p ents=%p num_ents=%d", + dev->size, dev->hdr, dev->ents, dev->hdr->num_ents); + return 0; +} + +int gk20a_ctxsw_dev_ring_alloc(struct gk20a *g, + void **buf, size_t *size) +{ + struct nvgpu_ctxsw_ring_header *hdr; + + *size = roundup(*size, PAGE_SIZE); + hdr = vmalloc_user(*size); + if (!hdr) + return -ENOMEM; + + hdr->magic = NVGPU_CTXSW_RING_HEADER_MAGIC; + hdr->version = NVGPU_CTXSW_RING_HEADER_VERSION; + hdr->num_ents = (*size - sizeof(struct nvgpu_ctxsw_ring_header)) + / sizeof(struct nvgpu_gpu_ctxsw_trace_entry); + hdr->ent_size = sizeof(struct nvgpu_gpu_ctxsw_trace_entry); + hdr->drop_count = 0; + hdr->read_idx = 0; + hdr->write_idx = 0; + hdr->write_seqno = 0; + + *buf = hdr; + return 0; +} + +int gk20a_ctxsw_dev_ring_free(struct gk20a *g) +{ + struct gk20a_ctxsw_dev *dev = &g->ctxsw_trace->devs[0]; + + nvgpu_vfree(g, dev->hdr); + return 0; +} + +static int gk20a_ctxsw_dev_ioctl_ring_setup(struct gk20a_ctxsw_dev *dev, + struct nvgpu_ctxsw_ring_setup_args *args) +{ + struct gk20a *g = dev->g; + size_t size = args->size; + int ret; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, "size=%zu", size); + + if (size > GK20A_CTXSW_TRACE_MAX_VM_RING_SIZE) + return -EINVAL; + + nvgpu_mutex_acquire(&dev->write_lock); + ret = gk20a_ctxsw_dev_alloc_buffer(dev, size); + nvgpu_mutex_release(&dev->write_lock); + + return ret; +} + +static void nvgpu_set_ctxsw_trace_filter_args(struct nvgpu_gpu_ctxsw_trace_filter *filter_dst, + struct nvgpu_ctxsw_trace_filter *filter_src) +{ + memcpy(filter_dst->tag_bits, filter_src->tag_bits, (NVGPU_CTXSW_FILTER_SIZE + 63) / 64); +} + +static void nvgpu_get_ctxsw_trace_filter_args(struct nvgpu_ctxsw_trace_filter *filter_dst, + struct nvgpu_gpu_ctxsw_trace_filter *filter_src) +{ + memcpy(filter_dst->tag_bits, filter_src->tag_bits, (NVGPU_CTXSW_FILTER_SIZE + 63) / 64); +} + +static int gk20a_ctxsw_dev_ioctl_set_filter(struct gk20a_ctxsw_dev *dev, + struct nvgpu_ctxsw_trace_filter_args *args) +{ + struct gk20a *g = dev->g; + + nvgpu_mutex_acquire(&dev->write_lock); + nvgpu_set_ctxsw_trace_filter_args(&dev->filter, &args->filter); + nvgpu_mutex_release(&dev->write_lock); + + if (g->ops.fecs_trace.set_filter) + g->ops.fecs_trace.set_filter(g, &dev->filter); + return 0; +} + +static int gk20a_ctxsw_dev_ioctl_get_filter(struct gk20a_ctxsw_dev *dev, + struct nvgpu_ctxsw_trace_filter_args *args) +{ + nvgpu_mutex_acquire(&dev->write_lock); + nvgpu_get_ctxsw_trace_filter_args(&args->filter, &dev->filter); + nvgpu_mutex_release(&dev->write_lock); + + return 0; +} + +static int gk20a_ctxsw_dev_ioctl_poll(struct gk20a_ctxsw_dev *dev) +{ + struct gk20a *g = dev->g; + int err; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, " "); + + err = gk20a_busy(g); + if (err) + return err; + + if (g->ops.fecs_trace.flush) + err = g->ops.fecs_trace.flush(g); + + if (likely(!err)) + err = g->ops.fecs_trace.poll(g); + + gk20a_idle(g); + return err; +} + +int gk20a_ctxsw_dev_open(struct inode *inode, struct file *filp) +{ + struct nvgpu_os_linux *l; + struct gk20a *g; + struct gk20a_ctxsw_trace *trace; + struct gk20a_ctxsw_dev *dev; + int err; + size_t size; + u32 n; + + /* only one VM for now */ + const int vmid = 0; + + l = container_of(inode->i_cdev, struct nvgpu_os_linux, ctxsw.cdev); + g = gk20a_get(&l->g); + if (!g) + return -ENODEV; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, "g=%p", g); + + err = gk20a_busy(g); + if (err) + goto free_ref; + + trace = g->ctxsw_trace; + if (!trace) { + err = -ENODEV; + goto idle; + } + + /* Allow only one user for this device */ + dev = &trace->devs[vmid]; + nvgpu_mutex_acquire(&dev->write_lock); + if (dev->hdr) { + err = -EBUSY; + goto done; + } + + /* By default, allocate ring buffer big enough to accommodate + * FECS records with default event filter */ + + /* enable all traces by default */ + NVGPU_CTXSW_FILTER_SET_ALL(&dev->filter); + + /* compute max number of entries generated with this filter */ + n = g->ops.fecs_trace.max_entries(g, &dev->filter); + + size = sizeof(struct nvgpu_ctxsw_ring_header) + + n * sizeof(struct nvgpu_gpu_ctxsw_trace_entry); + nvgpu_log(g, gpu_dbg_ctxsw, "size=%zu entries=%d ent_size=%zu", + size, n, sizeof(struct nvgpu_gpu_ctxsw_trace_entry)); + + err = gk20a_ctxsw_dev_alloc_buffer(dev, size); + if (!err) { + filp->private_data = dev; + nvgpu_log(g, gpu_dbg_ctxsw, "filp=%p dev=%p size=%zu", + filp, dev, size); + } + +done: + nvgpu_mutex_release(&dev->write_lock); + +idle: + gk20a_idle(g); +free_ref: + if (err) + gk20a_put(g); + return err; +} + +int gk20a_ctxsw_dev_release(struct inode *inode, struct file *filp) +{ + struct gk20a_ctxsw_dev *dev = filp->private_data; + struct gk20a *g = dev->g; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, "dev: %p", dev); + + g->ops.fecs_trace.disable(g); + + nvgpu_mutex_acquire(&dev->write_lock); + dev->write_enabled = false; + nvgpu_mutex_release(&dev->write_lock); + + if (dev->hdr) { + dev->g->ops.fecs_trace.free_user_buffer(dev->g); + dev->hdr = NULL; + } + gk20a_put(g); + return 0; +} + +long gk20a_ctxsw_dev_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct gk20a_ctxsw_dev *dev = filp->private_data; + struct gk20a *g = dev->g; + u8 buf[NVGPU_CTXSW_IOCTL_MAX_ARG_SIZE]; + int err = 0; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, "nr=%d", _IOC_NR(cmd)); + + if ((_IOC_TYPE(cmd) != NVGPU_CTXSW_IOCTL_MAGIC) || + (_IOC_NR(cmd) == 0) || + (_IOC_NR(cmd) > NVGPU_CTXSW_IOCTL_LAST) || + (_IOC_SIZE(cmd) > NVGPU_CTXSW_IOCTL_MAX_ARG_SIZE)) + return -EINVAL; + + memset(buf, 0, sizeof(buf)); + if (_IOC_DIR(cmd) & _IOC_WRITE) { + if (copy_from_user(buf, (void __user *) arg, _IOC_SIZE(cmd))) + return -EFAULT; + } + + switch (cmd) { + case NVGPU_CTXSW_IOCTL_TRACE_ENABLE: + err = gk20a_ctxsw_dev_ioctl_trace_enable(dev); + break; + case NVGPU_CTXSW_IOCTL_TRACE_DISABLE: + err = gk20a_ctxsw_dev_ioctl_trace_disable(dev); + break; + case NVGPU_CTXSW_IOCTL_RING_SETUP: + err = gk20a_ctxsw_dev_ioctl_ring_setup(dev, + (struct nvgpu_ctxsw_ring_setup_args *) buf); + break; + case NVGPU_CTXSW_IOCTL_SET_FILTER: + err = gk20a_ctxsw_dev_ioctl_set_filter(dev, + (struct nvgpu_ctxsw_trace_filter_args *) buf); + break; + case NVGPU_CTXSW_IOCTL_GET_FILTER: + err = gk20a_ctxsw_dev_ioctl_get_filter(dev, + (struct nvgpu_ctxsw_trace_filter_args *) buf); + break; + case NVGPU_CTXSW_IOCTL_POLL: + err = gk20a_ctxsw_dev_ioctl_poll(dev); + break; + default: + dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", + cmd); + err = -ENOTTY; + } + + if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ)) + err = copy_to_user((void __user *) arg, buf, _IOC_SIZE(cmd)); + + return err; +} + +unsigned int gk20a_ctxsw_dev_poll(struct file *filp, poll_table *wait) +{ + struct gk20a_ctxsw_dev *dev = filp->private_data; + struct gk20a *g = dev->g; + struct nvgpu_ctxsw_ring_header *hdr = dev->hdr; + unsigned int mask = 0; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, " "); + + nvgpu_mutex_acquire(&dev->write_lock); + poll_wait(filp, &dev->readout_wq.wq, wait); + if (!ring_is_empty(hdr)) + mask |= POLLIN | POLLRDNORM; + nvgpu_mutex_release(&dev->write_lock); + + return mask; +} + +static void gk20a_ctxsw_dev_vma_open(struct vm_area_struct *vma) +{ + struct gk20a_ctxsw_dev *dev = vma->vm_private_data; + struct gk20a *g = dev->g; + + nvgpu_atomic_inc(&dev->vma_ref); + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, "vma_ref=%d", + nvgpu_atomic_read(&dev->vma_ref)); +} + +static void gk20a_ctxsw_dev_vma_close(struct vm_area_struct *vma) +{ + struct gk20a_ctxsw_dev *dev = vma->vm_private_data; + struct gk20a *g = dev->g; + + nvgpu_atomic_dec(&dev->vma_ref); + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, "vma_ref=%d", + nvgpu_atomic_read(&dev->vma_ref)); +} + +static struct vm_operations_struct gk20a_ctxsw_dev_vma_ops = { + .open = gk20a_ctxsw_dev_vma_open, + .close = gk20a_ctxsw_dev_vma_close, +}; + +int gk20a_ctxsw_dev_mmap_buffer(struct gk20a *g, + struct vm_area_struct *vma) +{ + return remap_vmalloc_range(vma, g->ctxsw_trace->devs[0].hdr, 0); +} + +int gk20a_ctxsw_dev_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct gk20a_ctxsw_dev *dev = filp->private_data; + struct gk20a *g = dev->g; + int ret; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, "vm_start=%lx vm_end=%lx", + vma->vm_start, vma->vm_end); + + ret = dev->g->ops.fecs_trace.mmap_user_buffer(dev->g, vma); + if (likely(!ret)) { + vma->vm_private_data = dev; + vma->vm_ops = &gk20a_ctxsw_dev_vma_ops; + vma->vm_ops->open(vma); + } + + return ret; +} + +#ifdef CONFIG_GK20A_CTXSW_TRACE +static int gk20a_ctxsw_init_devs(struct gk20a *g) +{ + struct gk20a_ctxsw_trace *trace = g->ctxsw_trace; + struct gk20a_ctxsw_dev *dev = trace->devs; + int err; + int i; + + for (i = 0; i < GK20A_CTXSW_TRACE_NUM_DEVS; i++) { + dev->g = g; + dev->hdr = NULL; + dev->write_enabled = false; + nvgpu_cond_init(&dev->readout_wq); + err = nvgpu_mutex_init(&dev->write_lock); + if (err) + return err; + nvgpu_atomic_set(&dev->vma_ref, 0); + dev++; + } + return 0; +} +#endif + +int gk20a_ctxsw_trace_init(struct gk20a *g) +{ +#ifdef CONFIG_GK20A_CTXSW_TRACE + struct gk20a_ctxsw_trace *trace = g->ctxsw_trace; + int err; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_ctxsw, "g=%p trace=%p", g, trace); + + /* if tracing is not supported, skip this */ + if (!g->ops.fecs_trace.init) + return 0; + + if (likely(trace)) { + __nvgpu_set_enabled(g, NVGPU_SUPPORT_FECS_CTXSW_TRACE, true); + return 0; + } + + trace = nvgpu_kzalloc(g, sizeof(*trace)); + if (unlikely(!trace)) + return -ENOMEM; + g->ctxsw_trace = trace; + + err = gk20a_ctxsw_init_devs(g); + if (err) + goto fail; + + err = g->ops.fecs_trace.init(g); + if (unlikely(err)) + goto fail; + + return 0; + +fail: + memset(&g->ops.fecs_trace, 0, sizeof(g->ops.fecs_trace)); + nvgpu_kfree(g, trace); + g->ctxsw_trace = NULL; + return err; +#else + return 0; +#endif +} + +void gk20a_ctxsw_trace_cleanup(struct gk20a *g) +{ +#ifdef CONFIG_GK20A_CTXSW_TRACE + struct gk20a_ctxsw_trace *trace; + struct gk20a_ctxsw_dev *dev; + int i; + + if (!g->ctxsw_trace) + return; + + trace = g->ctxsw_trace; + dev = trace->devs; + + for (i = 0; i < GK20A_CTXSW_TRACE_NUM_DEVS; i++) { + nvgpu_mutex_destroy(&dev->write_lock); + dev++; + } + + nvgpu_kfree(g, g->ctxsw_trace); + g->ctxsw_trace = NULL; + + g->ops.fecs_trace.deinit(g); +#endif +} + +int gk20a_ctxsw_trace_write(struct gk20a *g, + struct nvgpu_gpu_ctxsw_trace_entry *entry) +{ + struct nvgpu_ctxsw_ring_header *hdr; + struct gk20a_ctxsw_dev *dev; + int ret = 0; + const char *reason; + u32 write_idx; + + if (!g->ctxsw_trace) + return 0; + + if (unlikely(entry->vmid >= GK20A_CTXSW_TRACE_NUM_DEVS)) + return -ENODEV; + + dev = &g->ctxsw_trace->devs[entry->vmid]; + hdr = dev->hdr; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_ctxsw, + "dev=%p hdr=%p", dev, hdr); + + nvgpu_mutex_acquire(&dev->write_lock); + + if (unlikely(!hdr)) { + /* device has been released */ + ret = -ENODEV; + goto done; + } + + write_idx = hdr->write_idx; + if (write_idx >= dev->num_ents) { + nvgpu_err(dev->g, + "write_idx=%u out of range [0..%u]", + write_idx, dev->num_ents); + ret = -ENOSPC; + reason = "write_idx out of range"; + goto disable; + } + + entry->seqno = hdr->write_seqno++; + + if (!dev->write_enabled) { + ret = -EBUSY; + reason = "write disabled"; + goto drop; + } + + if (unlikely(ring_is_full(hdr))) { + ret = -ENOSPC; + reason = "user fifo full"; + goto drop; + } + + if (!NVGPU_GPU_CTXSW_FILTER_ISSET(entry->tag, &dev->filter)) { + reason = "filtered out"; + goto filter; + } + + nvgpu_log(g, gpu_dbg_ctxsw, + "seqno=%d context_id=%08x pid=%lld tag=%x timestamp=%llx", + entry->seqno, entry->context_id, entry->pid, + entry->tag, entry->timestamp); + + dev->ents[write_idx] = *entry; + + /* ensure record is written before updating write index */ + nvgpu_smp_wmb(); + + write_idx++; + if (unlikely(write_idx >= hdr->num_ents)) + write_idx = 0; + hdr->write_idx = write_idx; + nvgpu_log(g, gpu_dbg_ctxsw, "added: read=%d write=%d len=%d", + hdr->read_idx, hdr->write_idx, ring_len(hdr)); + + nvgpu_mutex_release(&dev->write_lock); + return ret; + +disable: + g->ops.fecs_trace.disable(g); + +drop: + hdr->drop_count++; + +filter: + nvgpu_log(g, gpu_dbg_ctxsw, + "dropping seqno=%d context_id=%08x pid=%lld " + "tag=%x time=%llx (%s)", + entry->seqno, entry->context_id, entry->pid, + entry->tag, entry->timestamp, reason); + +done: + nvgpu_mutex_release(&dev->write_lock); + return ret; +} + +void gk20a_ctxsw_trace_wake_up(struct gk20a *g, int vmid) +{ + struct gk20a_ctxsw_dev *dev; + + if (!g->ctxsw_trace) + return; + + dev = &g->ctxsw_trace->devs[vmid]; + nvgpu_cond_signal_interruptible(&dev->readout_wq); +} + +void gk20a_ctxsw_trace_channel_reset(struct gk20a *g, struct channel_gk20a *ch) +{ +#ifdef CONFIG_GK20A_CTXSW_TRACE + struct nvgpu_gpu_ctxsw_trace_entry entry = { + .vmid = 0, + .tag = NVGPU_CTXSW_TAG_ENGINE_RESET, + .context_id = 0, + .pid = ch->tgid, + }; + + if (!g->ctxsw_trace) + return; + + g->ops.ptimer.read_ptimer(g, &entry.timestamp); + gk20a_ctxsw_trace_write(g, &entry); + gk20a_ctxsw_trace_wake_up(g, 0); +#endif + trace_gk20a_channel_reset(ch->chid, ch->tsgid); +} + +void gk20a_ctxsw_trace_tsg_reset(struct gk20a *g, struct tsg_gk20a *tsg) +{ +#ifdef CONFIG_GK20A_CTXSW_TRACE + struct nvgpu_gpu_ctxsw_trace_entry entry = { + .vmid = 0, + .tag = NVGPU_CTXSW_TAG_ENGINE_RESET, + .context_id = 0, + .pid = tsg->tgid, + }; + + if (!g->ctxsw_trace) + return; + + g->ops.ptimer.read_ptimer(g, &entry.timestamp); + gk20a_ctxsw_trace_write(g, &entry); + gk20a_ctxsw_trace_wake_up(g, 0); +#endif + trace_gk20a_channel_reset(~0, tsg->tsgid); +} + +/* + * Convert linux nvgpu ctxsw tags type of the form of NVGPU_CTXSW_TAG_* + * into common nvgpu ctxsw tags type of the form of NVGPU_GPU_CTXSW_TAG_* + */ + +u8 nvgpu_gpu_ctxsw_tags_to_common_tags(u8 tags) +{ + switch (tags){ + case NVGPU_CTXSW_TAG_SOF: + return NVGPU_GPU_CTXSW_TAG_SOF; + case NVGPU_CTXSW_TAG_CTXSW_REQ_BY_HOST: + return NVGPU_GPU_CTXSW_TAG_CTXSW_REQ_BY_HOST; + case NVGPU_CTXSW_TAG_FE_ACK: + return NVGPU_GPU_CTXSW_TAG_FE_ACK; + case NVGPU_CTXSW_TAG_FE_ACK_WFI: + return NVGPU_GPU_CTXSW_TAG_FE_ACK_WFI; + case NVGPU_CTXSW_TAG_FE_ACK_GFXP: + return NVGPU_GPU_CTXSW_TAG_FE_ACK_GFXP; + case NVGPU_CTXSW_TAG_FE_ACK_CTAP: + return NVGPU_GPU_CTXSW_TAG_FE_ACK_CTAP; + case NVGPU_CTXSW_TAG_FE_ACK_CILP: + return NVGPU_GPU_CTXSW_TAG_FE_ACK_CILP; + case NVGPU_CTXSW_TAG_SAVE_END: + return NVGPU_GPU_CTXSW_TAG_SAVE_END; + case NVGPU_CTXSW_TAG_RESTORE_START: + return NVGPU_GPU_CTXSW_TAG_RESTORE_START; + case NVGPU_CTXSW_TAG_CONTEXT_START: + return NVGPU_GPU_CTXSW_TAG_CONTEXT_START; + case NVGPU_CTXSW_TAG_ENGINE_RESET: + return NVGPU_GPU_CTXSW_TAG_ENGINE_RESET; + case NVGPU_CTXSW_TAG_INVALID_TIMESTAMP: + return NVGPU_GPU_CTXSW_TAG_INVALID_TIMESTAMP; + } + + WARN_ON(1); + return tags; +} diff --git a/include/os/linux/ctxsw_trace.h b/include/os/linux/ctxsw_trace.h new file mode 100644 index 0000000..88ca7f2 --- /dev/null +++ b/include/os/linux/ctxsw_trace.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CTXSW_TRACE_H__ +#define __CTXSW_TRACE_H__ + +#include + +#define GK20A_CTXSW_TRACE_NUM_DEVS 1 + +struct file; +struct inode; +struct poll_table_struct; + +struct gk20a; + +int gk20a_ctxsw_dev_release(struct inode *inode, struct file *filp); +int gk20a_ctxsw_dev_open(struct inode *inode, struct file *filp); +long gk20a_ctxsw_dev_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg); +ssize_t gk20a_ctxsw_dev_read(struct file *filp, char __user *buf, + size_t size, loff_t *offs); +unsigned int gk20a_ctxsw_dev_poll(struct file *filp, + struct poll_table_struct *pts); + +#endif /* __CTXSW_TRACE_H__ */ diff --git a/include/os/linux/debug.c b/include/os/linux/debug.c new file mode 100644 index 0000000..5f0703c --- /dev/null +++ b/include/os/linux/debug.c @@ -0,0 +1,457 @@ +/* + * Copyright (C) 2017-2018 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "debug_cde.h" +#include "debug_ce.h" +#include "debug_fifo.h" +#include "debug_gr.h" +#include "debug_allocator.h" +#include "debug_kmem.h" +#include "debug_pmu.h" +#include "debug_sched.h" +#include "debug_hal.h" +#include "debug_xve.h" +#include "debug_ltc.h" +#include "debug_bios.h" +#include "os_linux.h" +#include "platform_gk20a.h" + +#include + +#include +#include +#include + +#include + +unsigned int gk20a_debug_trace_cmdbuf; + +static inline void gk20a_debug_write_printk(void *ctx, const char *str, + size_t len) +{ + pr_info("%s", str); +} + +static inline void gk20a_debug_write_to_seqfile(void *ctx, const char *str, + size_t len) +{ + seq_write((struct seq_file *)ctx, str, len); +} + +void gk20a_debug_output(struct gk20a_debug_output *o, + const char *fmt, ...) +{ + va_list args; + int len; + + va_start(args, fmt); + len = vsnprintf(o->buf, sizeof(o->buf), fmt, args); + va_end(args); + o->fn(o->ctx, o->buf, len); +} + +static int gk20a_gr_dump_regs(struct gk20a *g, + struct gk20a_debug_output *o) +{ + if (g->ops.gr.dump_gr_regs) + gr_gk20a_elpg_protected_call(g, g->ops.gr.dump_gr_regs(g, o)); + + return 0; +} + +int gk20a_gr_debug_dump(struct gk20a *g) +{ + struct gk20a_debug_output o = { + .fn = gk20a_debug_write_printk + }; + + gk20a_gr_dump_regs(g, &o); + + return 0; +} + +static int gk20a_gr_debug_show(struct seq_file *s, void *unused) +{ + struct device *dev = s->private; + struct gk20a *g = gk20a_get_platform(dev)->g; + struct gk20a_debug_output o = { + .fn = gk20a_debug_write_to_seqfile, + .ctx = s, + }; + int err; + + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to power on gpu: %d", err); + return -EINVAL; + } + + gk20a_gr_dump_regs(g, &o); + + gk20a_idle(g); + + return 0; +} + +void gk20a_debug_dump(struct gk20a *g) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev_from_gk20a(g)); + struct gk20a_debug_output o = { + .fn = gk20a_debug_write_printk + }; + + if (platform->dump_platform_dependencies) + platform->dump_platform_dependencies(dev_from_gk20a(g)); + + /* HAL only initialized after 1st power-on */ + if (g->ops.debug.show_dump) + g->ops.debug.show_dump(g, &o); +} + +static int gk20a_debug_show(struct seq_file *s, void *unused) +{ + struct device *dev = s->private; + struct gk20a_debug_output o = { + .fn = gk20a_debug_write_to_seqfile, + .ctx = s, + }; + struct gk20a *g; + int err; + + g = gk20a_get_platform(dev)->g; + + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to power on gpu: %d", err); + return -EFAULT; + } + + /* HAL only initialized after 1st power-on */ + if (g->ops.debug.show_dump) + g->ops.debug.show_dump(g, &o); + + gk20a_idle(g); + return 0; +} + +static int gk20a_gr_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, gk20a_gr_debug_show, inode->i_private); +} + +static int gk20a_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, gk20a_debug_show, inode->i_private); +} + +static const struct file_operations gk20a_gr_debug_fops = { + .open = gk20a_gr_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static const struct file_operations gk20a_debug_fops = { + .open = gk20a_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o) +{ + g->ops.fifo.dump_pbdma_status(g, o); + g->ops.fifo.dump_eng_status(g, o); + + gk20a_debug_dump_all_channel_status_ramfc(g, o); +} + +static ssize_t disable_bigpage_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[3]; + struct gk20a *g = file->private_data; + + if (g->mm.disable_bigpage) + buf[0] = 'Y'; + else + buf[0] = 'N'; + buf[1] = '\n'; + buf[2] = 0x00; + return simple_read_from_buffer(user_buf, count, ppos, buf, 2); +} + +static ssize_t disable_bigpage_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[32]; + int buf_size; + bool bv; + struct gk20a *g = file->private_data; + + buf_size = min(count, (sizeof(buf)-1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + + if (strtobool(buf, &bv) == 0) { + g->mm.disable_bigpage = bv; + gk20a_init_gpu_characteristics(g); + } + + return count; +} + +static struct file_operations disable_bigpage_fops = { + .open = simple_open, + .read = disable_bigpage_read, + .write = disable_bigpage_write, +}; + +static int railgate_residency_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); + unsigned long time_since_last_state_transition_ms; + unsigned long total_rail_gate_time_ms; + unsigned long total_rail_ungate_time_ms; + + if (platform->is_railgated(dev_from_gk20a(g))) { + time_since_last_state_transition_ms = + jiffies_to_msecs(jiffies - + g->pstats.last_rail_gate_complete); + total_rail_ungate_time_ms = g->pstats.total_rail_ungate_time_ms; + total_rail_gate_time_ms = + g->pstats.total_rail_gate_time_ms + + time_since_last_state_transition_ms; + } else { + time_since_last_state_transition_ms = + jiffies_to_msecs(jiffies - + g->pstats.last_rail_ungate_complete); + total_rail_gate_time_ms = g->pstats.total_rail_gate_time_ms; + total_rail_ungate_time_ms = + g->pstats.total_rail_ungate_time_ms + + time_since_last_state_transition_ms; + } + + seq_printf(s, "Time with Rails Gated: %lu ms\n" + "Time with Rails UnGated: %lu ms\n" + "Total railgating cycles: %lu\n", + total_rail_gate_time_ms, + total_rail_ungate_time_ms, + g->pstats.railgating_cycle_count - 1); + return 0; + +} + +static int railgate_residency_open(struct inode *inode, struct file *file) +{ + return single_open(file, railgate_residency_show, inode->i_private); +} + +static const struct file_operations railgate_residency_fops = { + .open = railgate_residency_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int gk20a_railgating_debugfs_init(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *d; + + d = debugfs_create_file( + "railgate_residency", S_IRUGO|S_IWUSR, l->debugfs, g, + &railgate_residency_fops); + if (!d) + return -ENOMEM; + + return 0; +} +static ssize_t timeouts_enabled_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[3]; + struct gk20a *g = file->private_data; + + if (nvgpu_is_timeouts_enabled(g)) + buf[0] = 'Y'; + else + buf[0] = 'N'; + buf[1] = '\n'; + buf[2] = 0x00; + return simple_read_from_buffer(user_buf, count, ppos, buf, 2); +} + +static ssize_t timeouts_enabled_write(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[3]; + int buf_size; + bool timeouts_enabled; + struct gk20a *g = file->private_data; + + buf_size = min(count, (sizeof(buf)-1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + + if (strtobool(buf, &timeouts_enabled) == 0) { + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + if (timeouts_enabled == false) { + /* requesting to disable timeouts */ + if (g->timeouts_disabled_by_user == false) { + nvgpu_atomic_inc(&g->timeouts_disabled_refcount); + g->timeouts_disabled_by_user = true; + } + } else { + /* requesting to enable timeouts */ + if (g->timeouts_disabled_by_user == true) { + nvgpu_atomic_dec(&g->timeouts_disabled_refcount); + g->timeouts_disabled_by_user = false; + } + } + nvgpu_mutex_release(&g->dbg_sessions_lock); + } + + return count; +} + +static const struct file_operations timeouts_enabled_fops = { + .open = simple_open, + .read = timeouts_enabled_read, + .write = timeouts_enabled_write, +}; + +void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct device *dev = dev_from_gk20a(g); + + l->debugfs = debugfs_create_dir(dev_name(dev), NULL); + if (!l->debugfs) + return; + + if (debugfs_symlink) + l->debugfs_alias = + debugfs_create_symlink(debugfs_symlink, + NULL, dev_name(dev)); + + debugfs_create_file("status", S_IRUGO, l->debugfs, + dev, &gk20a_debug_fops); + debugfs_create_file("gr_status", S_IRUGO, l->debugfs, + dev, &gk20a_gr_debug_fops); + debugfs_create_u32("trace_cmdbuf", S_IRUGO|S_IWUSR, + l->debugfs, &gk20a_debug_trace_cmdbuf); + + debugfs_create_u32("ch_wdt_timeout_ms", S_IRUGO|S_IWUSR, + l->debugfs, &g->ch_wdt_timeout_ms); + + debugfs_create_u32("disable_syncpoints", S_IRUGO, + l->debugfs, &g->disable_syncpoints); + + /* New debug logging API. */ + debugfs_create_u64("log_mask", S_IRUGO|S_IWUSR, + l->debugfs, &g->log_mask); + debugfs_create_u32("log_trace", S_IRUGO|S_IWUSR, + l->debugfs, &g->log_trace); + + l->debugfs_ltc_enabled = + debugfs_create_bool("ltc_enabled", S_IRUGO|S_IWUSR, + l->debugfs, + &g->mm.ltc_enabled_target); + + l->debugfs_gr_idle_timeout_default = + debugfs_create_u32("gr_idle_timeout_default_us", + S_IRUGO|S_IWUSR, l->debugfs, + &g->gr_idle_timeout_default); + l->debugfs_timeouts_enabled = + debugfs_create_file("timeouts_enabled", + S_IRUGO|S_IWUSR, + l->debugfs, + g, + &timeouts_enabled_fops); + + l->debugfs_disable_bigpage = + debugfs_create_file("disable_bigpage", + S_IRUGO|S_IWUSR, + l->debugfs, + g, + &disable_bigpage_fops); + + l->debugfs_timeslice_low_priority_us = + debugfs_create_u32("timeslice_low_priority_us", + S_IRUGO|S_IWUSR, + l->debugfs, + &g->timeslice_low_priority_us); + l->debugfs_timeslice_medium_priority_us = + debugfs_create_u32("timeslice_medium_priority_us", + S_IRUGO|S_IWUSR, + l->debugfs, + &g->timeslice_medium_priority_us); + l->debugfs_timeslice_high_priority_us = + debugfs_create_u32("timeslice_high_priority_us", + S_IRUGO|S_IWUSR, + l->debugfs, + &g->timeslice_high_priority_us); + l->debugfs_runlist_interleave = + debugfs_create_bool("runlist_interleave", + S_IRUGO|S_IWUSR, + l->debugfs, + &g->runlist_interleave); + l->debugfs_force_preemption_gfxp = + debugfs_create_bool("force_preemption_gfxp", S_IRUGO|S_IWUSR, + l->debugfs, + &g->gr.ctx_vars.force_preemption_gfxp); + + l->debugfs_force_preemption_cilp = + debugfs_create_bool("force_preemption_cilp", S_IRUGO|S_IWUSR, + l->debugfs, + &g->gr.ctx_vars.force_preemption_cilp); + + l->debugfs_dump_ctxsw_stats = + debugfs_create_bool("dump_ctxsw_stats_on_channel_close", + S_IRUGO|S_IWUSR, l->debugfs, + &g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close); + + gr_gk20a_debugfs_init(g); + gk20a_pmu_debugfs_init(g); + gk20a_railgating_debugfs_init(g); +#ifdef CONFIG_NVGPU_SUPPORT_CDE + gk20a_cde_debugfs_init(g); +#endif + gk20a_ce_debugfs_init(g); + nvgpu_alloc_debugfs_init(g); + nvgpu_hal_debugfs_init(g); + gk20a_fifo_debugfs_init(g); + gk20a_sched_debugfs_init(g); +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE + nvgpu_kmem_debugfs_init(g); +#endif + nvgpu_ltc_debugfs_init(g); + if (g->pci_vendor_id) { + nvgpu_xve_debugfs_init(g); + nvgpu_bios_debugfs_init(g); + } +} + +void gk20a_debug_deinit(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (!l->debugfs) + return; + + gk20a_fifo_debugfs_deinit(g); + + debugfs_remove_recursive(l->debugfs); + debugfs_remove(l->debugfs_alias); +} diff --git a/include/os/linux/debug_allocator.c b/include/os/linux/debug_allocator.c new file mode 100644 index 0000000..d63a903 --- /dev/null +++ b/include/os/linux/debug_allocator.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "debug_allocator.h" +#include "os_linux.h" + +#include +#include + +#include + +static int __alloc_show(struct seq_file *s, void *unused) +{ + struct nvgpu_allocator *a = s->private; + + nvgpu_alloc_print_stats(a, s, 1); + + return 0; +} + +static int __alloc_open(struct inode *inode, struct file *file) +{ + return single_open(file, __alloc_show, inode->i_private); +} + +static const struct file_operations __alloc_fops = { + .open = __alloc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +void nvgpu_init_alloc_debug(struct gk20a *g, struct nvgpu_allocator *a) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (!l->debugfs_allocators) + return; + + a->debugfs_entry = debugfs_create_file(a->name, S_IRUGO, + l->debugfs_allocators, + a, &__alloc_fops); +} + +void nvgpu_fini_alloc_debug(struct nvgpu_allocator *a) +{ +} + +void nvgpu_alloc_debugfs_init(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + l->debugfs_allocators = debugfs_create_dir("allocators", l->debugfs); + if (IS_ERR_OR_NULL(l->debugfs_allocators)) { + l->debugfs_allocators = NULL; + return; + } +} diff --git a/include/os/linux/debug_allocator.h b/include/os/linux/debug_allocator.h new file mode 100644 index 0000000..1b21cfc --- /dev/null +++ b/include/os/linux/debug_allocator.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_ALLOCATOR_H__ +#define __NVGPU_DEBUG_ALLOCATOR_H__ + +struct gk20a; +void nvgpu_alloc_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_ALLOCATOR_H__ */ diff --git a/include/os/linux/debug_bios.c b/include/os/linux/debug_bios.c new file mode 100644 index 0000000..f69ccf3 --- /dev/null +++ b/include/os/linux/debug_bios.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include + +#include "debug_bios.h" +#include "os_linux.h" + +#include +#include + +static int bios_version_show(struct seq_file *s, void *unused) +{ + struct gk20a *g = s->private; + + seq_printf(s, "Version %02x.%02x.%02x.%02x.%02x\n", + (g->bios.vbios_version >> 24) & 0xFF, + (g->bios.vbios_version >> 16) & 0xFF, + (g->bios.vbios_version >> 8) & 0xFF, + (g->bios.vbios_version >> 0) & 0xFF, + (g->bios.vbios_oem_version) & 0xFF); + + return 0; +} + +static int bios_version_open(struct inode *inode, struct file *file) +{ + return single_open(file, bios_version_show, inode->i_private); +} + +static const struct file_operations bios_version_fops = { + .open = bios_version_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + +int nvgpu_bios_debugfs_init(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *gpu_root = l->debugfs; + + debugfs_create_file("bios", S_IRUGO, + gpu_root, g, + &bios_version_fops); + + return 0; +} diff --git a/include/os/linux/debug_bios.h b/include/os/linux/debug_bios.h new file mode 100644 index 0000000..f8e7783 --- /dev/null +++ b/include/os/linux/debug_bios.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2018 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_BIOS_H__ +#define __NVGPU_DEBUG_BIOS_H__ + +struct gk20a; +int nvgpu_bios_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_BIOS_H__ */ diff --git a/include/os/linux/debug_cde.c b/include/os/linux/debug_cde.c new file mode 100644 index 0000000..f0afa6e --- /dev/null +++ b/include/os/linux/debug_cde.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "debug_cde.h" +#include "platform_gk20a.h" +#include "os_linux.h" + +#include + + +static ssize_t gk20a_cde_reload_write(struct file *file, + const char __user *userbuf, size_t count, loff_t *ppos) +{ + struct nvgpu_os_linux *l = file->private_data; + gk20a_cde_reload(l); + return count; +} + +static const struct file_operations gk20a_cde_reload_fops = { + .open = simple_open, + .write = gk20a_cde_reload_write, +}; + +void gk20a_cde_debugfs_init(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); + + if (!platform->has_cde) + return; + + debugfs_create_u32("cde_parameter", S_IWUSR | S_IRUGO, + l->debugfs, &l->cde_app.shader_parameter); + debugfs_create_u32("cde_ctx_count", S_IWUSR | S_IRUGO, + l->debugfs, &l->cde_app.ctx_count); + debugfs_create_u32("cde_ctx_usecount", S_IWUSR | S_IRUGO, + l->debugfs, &l->cde_app.ctx_usecount); + debugfs_create_u32("cde_ctx_count_top", S_IWUSR | S_IRUGO, + l->debugfs, &l->cde_app.ctx_count_top); + debugfs_create_file("reload_cde_firmware", S_IWUSR, l->debugfs, + l, &gk20a_cde_reload_fops); +} diff --git a/include/os/linux/debug_cde.h b/include/os/linux/debug_cde.h new file mode 100644 index 0000000..4895edd --- /dev/null +++ b/include/os/linux/debug_cde.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_CDE_H__ +#define __NVGPU_DEBUG_CDE_H__ + +struct gk20a; +void gk20a_cde_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_CDE_H__ */ diff --git a/include/os/linux/debug_ce.c b/include/os/linux/debug_ce.c new file mode 100644 index 0000000..cea0bb4 --- /dev/null +++ b/include/os/linux/debug_ce.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "debug_ce.h" +#include "os_linux.h" + +#include + +void gk20a_ce_debugfs_init(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + debugfs_create_u32("ce_app_ctx_count", S_IWUSR | S_IRUGO, + l->debugfs, &g->ce_app.ctx_count); + debugfs_create_u32("ce_app_state", S_IWUSR | S_IRUGO, + l->debugfs, &g->ce_app.app_state); + debugfs_create_u32("ce_app_next_ctx_id", S_IWUSR | S_IRUGO, + l->debugfs, &g->ce_app.next_ctx_id); +} diff --git a/include/os/linux/debug_ce.h b/include/os/linux/debug_ce.h new file mode 100644 index 0000000..2a8750c --- /dev/null +++ b/include/os/linux/debug_ce.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_CE_H__ +#define __NVGPU_DEBUG_CE_H__ + +struct gk20a; +void gk20a_ce_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_CE_H__ */ diff --git a/include/os/linux/debug_clk_gm20b.c b/include/os/linux/debug_clk_gm20b.c new file mode 100644 index 0000000..b8b95fd --- /dev/null +++ b/include/os/linux/debug_clk_gm20b.c @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2017-2018 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include + +#include +#include + +#include "gm20b/clk_gm20b.h" +#include "os_linux.h" +#include "platform_gk20a.h" + +static int rate_get(void *data, u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + struct clk_gk20a *clk = &g->clk; + + *val = (u64)rate_gpc2clk_to_gpu(clk->gpc_pll.freq); + return 0; +} +static int rate_set(void *data, u64 val) +{ + struct gk20a *g = (struct gk20a *)data; + if (nvgpu_clk_arb_has_active_req(g)) + return 0; + return g->ops.clk.set_rate(g, CTRL_CLK_DOMAIN_GPCCLK, (u32)val); +} +DEFINE_SIMPLE_ATTRIBUTE(rate_fops, rate_get, rate_set, "%llu\n"); + +static int pll_reg_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + struct nvgpu_clk_pll_debug_data d; + u32 reg, m, n, pl, f; + int err = 0; + + if (g->ops.clk.get_pll_debug_data) { + err = g->ops.clk.get_pll_debug_data(g, &d); + if (err) + return err; + } else { + return -EINVAL; + } + + seq_printf(s, "bypassctrl = %s, ", + d.trim_sys_bypassctrl_val ? "bypass" : "vco"); + seq_printf(s, "sel_vco = %s, ", + d.trim_sys_sel_vco_val ? "vco" : "bypass"); + + seq_printf(s, "cfg = 0x%x : %s : %s : %s\n", d.trim_sys_gpcpll_cfg_val, + d.trim_sys_gpcpll_cfg_enabled ? "enabled" : "disabled", + d.trim_sys_gpcpll_cfg_locked ? "locked" : "unlocked", + d.trim_sys_gpcpll_cfg_sync_on ? "sync_on" : "sync_off"); + + reg = d.trim_sys_gpcpll_coeff_val; + m = d.trim_sys_gpcpll_coeff_mdiv; + n = d.trim_sys_gpcpll_coeff_ndiv; + pl = d.trim_sys_gpcpll_coeff_pldiv; + f = g->clk.gpc_pll.clk_in * n / (m * nvgpu_pl_to_div(pl)); + seq_printf(s, "coef = 0x%x : m = %u : n = %u : pl = %u", reg, m, n, pl); + seq_printf(s, " : pll_f(gpu_f) = %u(%u) kHz\n", f, f/2); + + seq_printf(s, "dvfs0 = 0x%x : d = %u : dmax = %u : doffs = %u\n", + d.trim_sys_gpcpll_dvfs0_val, + d.trim_sys_gpcpll_dvfs0_dfs_coeff, + d.trim_sys_gpcpll_dvfs0_dfs_det_max, + d.trim_sys_gpcpll_dvfs0_dfs_dc_offset); + + return 0; +} + +static int pll_reg_open(struct inode *inode, struct file *file) +{ + return single_open(file, pll_reg_show, inode->i_private); +} + +static const struct file_operations pll_reg_fops = { + .open = pll_reg_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int pll_reg_raw_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + struct nvgpu_clk_pll_debug_data d; + u32 reg; + int err = 0; + + if (g->ops.clk.get_pll_debug_data) { + err = g->ops.clk.get_pll_debug_data(g, &d); + if (err) + return err; + } else { + return -EINVAL; + } + + seq_puts(s, "GPCPLL REGISTERS:\n"); + for (reg = d.trim_sys_gpcpll_cfg_reg; + reg < d.trim_sys_gpcpll_dvfs2_reg; + reg += sizeof(u32)) + seq_printf(s, "[0x%02x] = 0x%08x\n", reg, gk20a_readl(g, reg)); + + reg = d.trim_bcast_gpcpll_dvfs2_reg; + if (reg) + seq_printf(s, "[0x%02x] = 0x%08x\n", reg, gk20a_readl(g, reg)); + + seq_puts(s, "\nGPC CLK OUT REGISTERS:\n"); + + seq_printf(s, "[0x%02x] = 0x%08x\n", d.trim_sys_sel_vco_reg, + d.trim_sys_sel_vco_val); + seq_printf(s, "[0x%02x] = 0x%08x\n", d.trim_sys_gpc2clk_out_reg, + d.trim_sys_gpc2clk_out_val); + seq_printf(s, "[0x%02x] = 0x%08x\n", d.trim_sys_bypassctrl_reg, + d.trim_sys_bypassctrl_val); + + return 0; +} + +static int pll_reg_raw_open(struct inode *inode, struct file *file) +{ + return single_open(file, pll_reg_raw_show, inode->i_private); +} + +static ssize_t pll_reg_raw_write(struct file *file, + const char __user *userbuf, size_t count, loff_t *ppos) +{ + struct gk20a *g = file->f_path.dentry->d_inode->i_private; + char buf[80]; + u32 reg, val; + int err = 0; + + if (sizeof(buf) <= count) + return -EINVAL; + + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + /* terminate buffer and trim - white spaces may be appended + * at the end when invoked from shell command line */ + buf[count] = '\0'; + strim(buf); + + if (sscanf(buf, "[0x%x] = 0x%x", ®, &val) != 2) + return -EINVAL; + + if (g->ops.clk.pll_reg_write(g, reg, val)) + err = g->ops.clk.pll_reg_write(g, reg, val); + else + err = -EINVAL; + + return err; +} + +static const struct file_operations pll_reg_raw_fops = { + .open = pll_reg_raw_open, + .read = seq_read, + .write = pll_reg_raw_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static int monitor_get(void *data, u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + int err = 0; + + if (g->ops.clk.get_gpcclk_clock_counter) + err = g->ops.clk.get_gpcclk_clock_counter(&g->clk, val); + else + err = -EINVAL; + + return err; +} +DEFINE_SIMPLE_ATTRIBUTE(monitor_fops, monitor_get, NULL, "%llu\n"); + +static int voltage_get(void *data, u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + int err = 0; + + if (g->ops.clk.get_voltage) + err = g->ops.clk.get_voltage(&g->clk, val); + else + err = -EINVAL; + + return err; +} +DEFINE_SIMPLE_ATTRIBUTE(voltage_fops, voltage_get, NULL, "%llu\n"); + +static int pll_param_show(struct seq_file *s, void *data) +{ + struct pll_parms *gpc_pll_params = gm20b_get_gpc_pll_parms(); + + seq_printf(s, "ADC offs = %d uV, ADC slope = %d uV, VCO ctrl = 0x%x\n", + gpc_pll_params->uvdet_offs, gpc_pll_params->uvdet_slope, + gpc_pll_params->vco_ctrl); + return 0; +} + +static int pll_param_open(struct inode *inode, struct file *file) +{ + return single_open(file, pll_param_show, inode->i_private); +} + +static const struct file_operations pll_param_fops = { + .open = pll_param_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +int gm20b_clk_init_debugfs(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *d; + + if (!l->debugfs) + return -EINVAL; + + d = debugfs_create_file( + "rate", S_IRUGO|S_IWUSR, l->debugfs, g, &rate_fops); + if (!d) + goto err_out; + + d = debugfs_create_file( + "pll_reg", S_IRUGO, l->debugfs, g, &pll_reg_fops); + if (!d) + goto err_out; + + d = debugfs_create_file("pll_reg_raw", + S_IRUGO, l->debugfs, g, &pll_reg_raw_fops); + if (!d) + goto err_out; + + d = debugfs_create_file( + "monitor", S_IRUGO, l->debugfs, g, &monitor_fops); + if (!d) + goto err_out; + + d = debugfs_create_file( + "voltage", S_IRUGO, l->debugfs, g, &voltage_fops); + if (!d) + goto err_out; + + d = debugfs_create_file( + "pll_param", S_IRUGO, l->debugfs, g, &pll_param_fops); + if (!d) + goto err_out; + + d = debugfs_create_u32("pll_na_mode", S_IRUGO, l->debugfs, + (u32 *)&g->clk.gpc_pll.mode); + if (!d) + goto err_out; + + d = debugfs_create_u32("fmax2x_at_vmin_safe_t", S_IRUGO, + l->debugfs, (u32 *)&g->clk.dvfs_safe_max_freq); + if (!d) + goto err_out; + + return 0; + +err_out: + pr_err("%s: Failed to make debugfs node\n", __func__); + return -ENOMEM; +} diff --git a/include/os/linux/debug_clk_gm20b.h b/include/os/linux/debug_clk_gm20b.h new file mode 100644 index 0000000..850ad89 --- /dev/null +++ b/include/os/linux/debug_clk_gm20b.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __DEBUG_CLK_GM20B_H +#define __DEBUG_CLK_GM20B_H + +#ifdef CONFIG_DEBUG_FS +int gm20b_clk_init_debugfs(struct gk20a *g); +#else +inline int gm20b_clk_init_debugfs(struct gk20a *g) +{ + return 0; +} +#endif + +#endif diff --git a/include/os/linux/debug_clk_gp106.c b/include/os/linux/debug_clk_gp106.c new file mode 100644 index 0000000..4900c00 --- /dev/null +++ b/include/os/linux/debug_clk_gp106.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include + +#include "os_linux.h" + +void nvgpu_clk_arb_pstate_change_lock(struct gk20a *g, bool lock); + +static int gp106_get_rate_show(void *data , u64 *val) +{ + struct namemap_cfg *c = (struct namemap_cfg *)data; + struct gk20a *g = c->g; + + if (!g->ops.clk.get_rate_cntr) + return -EINVAL; + + *val = c->is_counter ? (u64)c->scale * g->ops.clk.get_rate_cntr(g, c) : + 0 /* TODO PLL read */; + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(get_rate_fops, gp106_get_rate_show, NULL, "%llu\n"); + +static int sys_cfc_read(void *data , u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + bool bload = boardobjgrpmask_bitget( + &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_SYS); + + /* val = 1 implies CLFC is loaded or enabled */ + *val = bload ? 1 : 0; + return 0; +} +static int sys_cfc_write(void *data , u64 val) +{ + struct gk20a *g = (struct gk20a *)data; + int status; + /* val = 1 implies load or enable the CLFC */ + bool bload = val ? true : false; + + nvgpu_clk_arb_pstate_change_lock(g, true); + status = clk_pmu_freq_controller_load(g, bload, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_SYS); + nvgpu_clk_arb_pstate_change_lock(g, false); + + return status; +} +DEFINE_SIMPLE_ATTRIBUTE(sys_cfc_fops, sys_cfc_read, sys_cfc_write, "%llu\n"); + +static int ltc_cfc_read(void *data , u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + bool bload = boardobjgrpmask_bitget( + &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_LTC); + + /* val = 1 implies CLFC is loaded or enabled */ + *val = bload ? 1 : 0; + return 0; +} +static int ltc_cfc_write(void *data , u64 val) +{ + struct gk20a *g = (struct gk20a *)data; + int status; + /* val = 1 implies load or enable the CLFC */ + bool bload = val ? true : false; + + nvgpu_clk_arb_pstate_change_lock(g, true); + status = clk_pmu_freq_controller_load(g, bload, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_LTC); + nvgpu_clk_arb_pstate_change_lock(g, false); + + return status; +} +DEFINE_SIMPLE_ATTRIBUTE(ltc_cfc_fops, ltc_cfc_read, ltc_cfc_write, "%llu\n"); + +static int xbar_cfc_read(void *data , u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + bool bload = boardobjgrpmask_bitget( + &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_XBAR); + + /* val = 1 implies CLFC is loaded or enabled */ + *val = bload ? 1 : 0; + return 0; +} +static int xbar_cfc_write(void *data , u64 val) +{ + struct gk20a *g = (struct gk20a *)data; + int status; + /* val = 1 implies load or enable the CLFC */ + bool bload = val ? true : false; + + nvgpu_clk_arb_pstate_change_lock(g, true); + status = clk_pmu_freq_controller_load(g, bload, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_XBAR); + nvgpu_clk_arb_pstate_change_lock(g, false); + + return status; +} +DEFINE_SIMPLE_ATTRIBUTE(xbar_cfc_fops, xbar_cfc_read, + xbar_cfc_write, "%llu\n"); + +static int gpc_cfc_read(void *data , u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + bool bload = boardobjgrpmask_bitget( + &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC0); + + /* val = 1 implies CLFC is loaded or enabled */ + *val = bload ? 1 : 0; + return 0; +} +static int gpc_cfc_write(void *data , u64 val) +{ + struct gk20a *g = (struct gk20a *)data; + int status; + /* val = 1 implies load or enable the CLFC */ + bool bload = val ? true : false; + + nvgpu_clk_arb_pstate_change_lock(g, true); + status = clk_pmu_freq_controller_load(g, bload, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC0); + nvgpu_clk_arb_pstate_change_lock(g, false); + + return status; +} +DEFINE_SIMPLE_ATTRIBUTE(gpc_cfc_fops, gpc_cfc_read, gpc_cfc_write, "%llu\n"); + +int gp106_clk_init_debugfs(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *gpu_root = l->debugfs; + struct dentry *clocks_root, *clk_freq_ctlr_root; + struct dentry *d; + unsigned int i; + + if (NULL == (clocks_root = debugfs_create_dir("clocks", gpu_root))) + return -ENOMEM; + + clk_freq_ctlr_root = debugfs_create_dir("clk_freq_ctlr", gpu_root); + if (clk_freq_ctlr_root == NULL) + return -ENOMEM; + + d = debugfs_create_file("sys", S_IRUGO | S_IWUSR, clk_freq_ctlr_root, + g, &sys_cfc_fops); + d = debugfs_create_file("ltc", S_IRUGO | S_IWUSR, clk_freq_ctlr_root, + g, <c_cfc_fops); + d = debugfs_create_file("xbar", S_IRUGO | S_IWUSR, clk_freq_ctlr_root, + g, &xbar_cfc_fops); + d = debugfs_create_file("gpc", S_IRUGO | S_IWUSR, clk_freq_ctlr_root, + g, &gpc_cfc_fops); + + nvgpu_log(g, gpu_dbg_info, "g=%p", g); + + for (i = 0; i < g->clk.namemap_num; i++) { + if (g->clk.clk_namemap[i].is_enable) { + d = debugfs_create_file( + g->clk.clk_namemap[i].name, + S_IRUGO, + clocks_root, + &g->clk.clk_namemap[i], + &get_rate_fops); + if (!d) + goto err_out; + } + } + return 0; + +err_out: + pr_err("%s: Failed to make debugfs node\n", __func__); + debugfs_remove_recursive(clocks_root); + return -ENOMEM; +} diff --git a/include/os/linux/debug_clk_gp106.h b/include/os/linux/debug_clk_gp106.h new file mode 100644 index 0000000..b1d031d --- /dev/null +++ b/include/os/linux/debug_clk_gp106.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __DEBUG_CLK_GP106_H +#define __DEBUG_CLK_GP106_H + +#ifdef CONFIG_DEBUG_FS +int gp106_clk_init_debugfs(struct gk20a *g); +#else +inline int gp106_clk_init_debugfs(struct gk20a *g) +{ + return 0; +} +#endif + +#endif diff --git a/include/os/linux/debug_clk_gv100.c b/include/os/linux/debug_clk_gv100.c new file mode 100644 index 0000000..623f2b6 --- /dev/null +++ b/include/os/linux/debug_clk_gv100.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "gv100/clk_gv100.h" + +#include "os_linux.h" + +void nvgpu_clk_arb_pstate_change_lock(struct gk20a *g, bool lock); + +static int gv100_get_rate_show(void *data , u64 *val) +{ + struct namemap_cfg *c = (struct namemap_cfg *)data; + struct gk20a *g = c->g; + + if (!g->ops.clk.get_rate_cntr) + return -EINVAL; + + *val = c->is_counter ? (u64)c->scale * g->ops.clk.get_rate_cntr(g, c) : + 0 /* TODO PLL read */; + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(get_rate_fops, gv100_get_rate_show, NULL, "%llu\n"); + +static int sys_cfc_read(void *data , u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + bool bload = boardobjgrpmask_bitget( + &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_SYS); + + /* val = 1 implies CLFC is loaded or enabled */ + *val = bload ? 1 : 0; + return 0; +} +static int sys_cfc_write(void *data , u64 val) +{ + struct gk20a *g = (struct gk20a *)data; + int status; + /* val = 1 implies load or enable the CLFC */ + bool bload = val ? true : false; + + nvgpu_clk_arb_pstate_change_lock(g, true); + status = clk_pmu_freq_controller_load(g, bload, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_SYS); + nvgpu_clk_arb_pstate_change_lock(g, false); + + return status; +} +DEFINE_SIMPLE_ATTRIBUTE(sys_cfc_fops, sys_cfc_read, sys_cfc_write, "%llu\n"); + +static int ltc_cfc_read(void *data , u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + bool bload = boardobjgrpmask_bitget( + &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_LTC); + + /* val = 1 implies CLFC is loaded or enabled */ + *val = bload ? 1 : 0; + return 0; +} +static int ltc_cfc_write(void *data , u64 val) +{ + struct gk20a *g = (struct gk20a *)data; + int status; + /* val = 1 implies load or enable the CLFC */ + bool bload = val ? true : false; + + nvgpu_clk_arb_pstate_change_lock(g, true); + status = clk_pmu_freq_controller_load(g, bload, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_LTC); + nvgpu_clk_arb_pstate_change_lock(g, false); + + return status; +} +DEFINE_SIMPLE_ATTRIBUTE(ltc_cfc_fops, ltc_cfc_read, ltc_cfc_write, "%llu\n"); + +static int xbar_cfc_read(void *data , u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + bool bload = boardobjgrpmask_bitget( + &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_XBAR); + + /* val = 1 implies CLFC is loaded or enabled */ + *val = bload ? 1 : 0; + return 0; +} +static int xbar_cfc_write(void *data , u64 val) +{ + struct gk20a *g = (struct gk20a *)data; + int status; + /* val = 1 implies load or enable the CLFC */ + bool bload = val ? true : false; + + nvgpu_clk_arb_pstate_change_lock(g, true); + status = clk_pmu_freq_controller_load(g, bload, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_XBAR); + nvgpu_clk_arb_pstate_change_lock(g, false); + + return status; +} +DEFINE_SIMPLE_ATTRIBUTE(xbar_cfc_fops, xbar_cfc_read, + xbar_cfc_write, "%llu\n"); + +static int gpc_cfc_read(void *data , u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + bool bload = boardobjgrpmask_bitget( + &g->clk_pmu.clk_freq_controllers.freq_ctrl_load_mask.super, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC0); + + /* val = 1 implies CLFC is loaded or enabled */ + *val = bload ? 1 : 0; + return 0; +} +static int gpc_cfc_write(void *data , u64 val) +{ + struct gk20a *g = (struct gk20a *)data; + int status; + /* val = 1 implies load or enable the CLFC */ + bool bload = val ? true : false; + + nvgpu_clk_arb_pstate_change_lock(g, true); + status = clk_pmu_freq_controller_load(g, bload, + CTRL_CLK_CLK_FREQ_CONTROLLER_ID_GPC0); + nvgpu_clk_arb_pstate_change_lock(g, false); + + return status; +} +DEFINE_SIMPLE_ATTRIBUTE(gpc_cfc_fops, gpc_cfc_read, gpc_cfc_write, "%llu\n"); + +int gv100_clk_init_debugfs(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *gpu_root = l->debugfs; + struct dentry *clocks_root, *clk_freq_ctlr_root; + struct dentry *d; + unsigned int i; + + if (NULL == (clocks_root = debugfs_create_dir("clocks", gpu_root))) + return -ENOMEM; + + clk_freq_ctlr_root = debugfs_create_dir("clk_freq_ctlr", gpu_root); + if (clk_freq_ctlr_root == NULL) + return -ENOMEM; + + d = debugfs_create_file("sys", S_IRUGO | S_IWUSR, clk_freq_ctlr_root, + g, &sys_cfc_fops); + d = debugfs_create_file("ltc", S_IRUGO | S_IWUSR, clk_freq_ctlr_root, + g, <c_cfc_fops); + d = debugfs_create_file("xbar", S_IRUGO | S_IWUSR, clk_freq_ctlr_root, + g, &xbar_cfc_fops); + d = debugfs_create_file("gpc", S_IRUGO | S_IWUSR, clk_freq_ctlr_root, + g, &gpc_cfc_fops); + + nvgpu_log(g, gpu_dbg_info, "g=%p", g); + + for (i = 0; i < g->clk.namemap_num; i++) { + if (g->clk.clk_namemap[i].is_enable) { + d = debugfs_create_file( + g->clk.clk_namemap[i].name, + S_IRUGO, + clocks_root, + &g->clk.clk_namemap[i], + &get_rate_fops); + if (!d) + goto err_out; + } + } + return 0; + +err_out: + pr_err("%s: Failed to make debugfs node\n", __func__); + debugfs_remove_recursive(clocks_root); + return -ENOMEM; +} diff --git a/include/os/linux/debug_clk_gv100.h b/include/os/linux/debug_clk_gv100.h new file mode 100644 index 0000000..419b4ab --- /dev/null +++ b/include/os/linux/debug_clk_gv100.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __DEBUG_CLK_GV100_H +#define __DEBUG_CLK_GV100_H + +#ifdef CONFIG_DEBUG_FS +int gv100_clk_init_debugfs(struct gk20a *g); +#else +static inline int gv100_clk_init_debugfs(struct gk20a *g) +{ + return 0; +} +#endif + +#endif diff --git a/include/os/linux/debug_fecs_trace.c b/include/os/linux/debug_fecs_trace.c new file mode 100644 index 0000000..7786053 --- /dev/null +++ b/include/os/linux/debug_fecs_trace.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include + +#include "os_linux.h" + +/* + * The sequence iterator functions. We simply use the count of the + * next line as our internal position. + */ +static void *gk20a_fecs_trace_debugfs_ring_seq_start( + struct seq_file *s, loff_t *pos) +{ + if (*pos >= GK20A_FECS_TRACE_NUM_RECORDS) + return NULL; + + return pos; +} + +static void *gk20a_fecs_trace_debugfs_ring_seq_next( + struct seq_file *s, void *v, loff_t *pos) +{ + ++(*pos); + if (*pos >= GK20A_FECS_TRACE_NUM_RECORDS) + return NULL; + return pos; +} + +static void gk20a_fecs_trace_debugfs_ring_seq_stop( + struct seq_file *s, void *v) +{ +} + +static int gk20a_fecs_trace_debugfs_ring_seq_show( + struct seq_file *s, void *v) +{ + loff_t *pos = (loff_t *) v; + struct gk20a *g = *(struct gk20a **)s->private; + struct gk20a_fecs_trace_record *r = + gk20a_fecs_trace_get_record(g, *pos); + int i; + const u32 invalid_tag = gk20a_fecs_trace_record_ts_tag_invalid_ts_v(); + u32 tag; + u64 timestamp; + + seq_printf(s, "record #%lld (%p)\n", *pos, r); + seq_printf(s, "\tmagic_lo=%08x\n", r->magic_lo); + seq_printf(s, "\tmagic_hi=%08x\n", r->magic_hi); + if (gk20a_fecs_trace_is_valid_record(r)) { + seq_printf(s, "\tcontext_ptr=%08x\n", r->context_ptr); + seq_printf(s, "\tcontext_id=%08x\n", r->context_id); + seq_printf(s, "\tnew_context_ptr=%08x\n", r->new_context_ptr); + seq_printf(s, "\tnew_context_id=%08x\n", r->new_context_id); + for (i = 0; i < gk20a_fecs_trace_num_ts(); i++) { + tag = gk20a_fecs_trace_record_ts_tag_v(r->ts[i]); + if (tag == invalid_tag) + continue; + timestamp = gk20a_fecs_trace_record_ts_timestamp_v(r->ts[i]); + timestamp <<= GK20A_FECS_TRACE_PTIMER_SHIFT; + seq_printf(s, "\ttag=%02x timestamp=%012llx\n", tag, timestamp); + } + } + return 0; +} + +/* + * Tie them all together into a set of seq_operations. + */ +static const struct seq_operations gk20a_fecs_trace_debugfs_ring_seq_ops = { + .start = gk20a_fecs_trace_debugfs_ring_seq_start, + .next = gk20a_fecs_trace_debugfs_ring_seq_next, + .stop = gk20a_fecs_trace_debugfs_ring_seq_stop, + .show = gk20a_fecs_trace_debugfs_ring_seq_show +}; + +/* + * Time to set up the file operations for our /proc file. In this case, + * all we need is an open function which sets up the sequence ops. + */ + +static int gk20a_ctxsw_debugfs_ring_open(struct inode *inode, + struct file *file) +{ + struct gk20a **p; + + p = __seq_open_private(file, &gk20a_fecs_trace_debugfs_ring_seq_ops, + sizeof(struct gk20a *)); + if (!p) + return -ENOMEM; + + *p = (struct gk20a *)inode->i_private; + return 0; +}; + +/* + * The file operations structure contains our open function along with + * set of the canned seq_ ops. + */ +static const struct file_operations gk20a_fecs_trace_debugfs_ring_fops = { + .owner = THIS_MODULE, + .open = gk20a_ctxsw_debugfs_ring_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private +}; + +static int gk20a_fecs_trace_debugfs_read(void *arg, u64 *val) +{ + *val = gk20a_fecs_trace_get_read_index((struct gk20a *)arg); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(gk20a_fecs_trace_debugfs_read_fops, + gk20a_fecs_trace_debugfs_read, NULL, "%llu\n"); + +static int gk20a_fecs_trace_debugfs_write(void *arg, u64 *val) +{ + *val = gk20a_fecs_trace_get_write_index((struct gk20a *)arg); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(gk20a_fecs_trace_debugfs_write_fops, + gk20a_fecs_trace_debugfs_write, NULL, "%llu\n"); + +int nvgpu_fecs_trace_init_debugfs(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + debugfs_create_file("ctxsw_trace_read", 0600, l->debugfs, g, + &gk20a_fecs_trace_debugfs_read_fops); + debugfs_create_file("ctxsw_trace_write", 0600, l->debugfs, g, + &gk20a_fecs_trace_debugfs_write_fops); + debugfs_create_file("ctxsw_trace_ring", 0600, l->debugfs, g, + &gk20a_fecs_trace_debugfs_ring_fops); + + return 0; +} diff --git a/include/os/linux/debug_fecs_trace.h b/include/os/linux/debug_fecs_trace.h new file mode 100644 index 0000000..54ebaaf --- /dev/null +++ b/include/os/linux/debug_fecs_trace.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LINUX_DEBUG_FECS_TRACE_H +#define LINUX_DEBUG_FECS_TRACE_H + +struct gk20a; + +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_GK20A_CTXSW_TRACE) +int nvgpu_fecs_trace_init_debugfs(struct gk20a *g); +#else +static int nvgpu_fecs_trace_init_debugfs(struct gk20a *g) +{ + return 0; +} +#endif +#endif diff --git a/include/os/linux/debug_fifo.c b/include/os/linux/debug_fifo.c new file mode 100644 index 0000000..98da8bc --- /dev/null +++ b/include/os/linux/debug_fifo.c @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2017-2020 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "debug_fifo.h" +#include "os_linux.h" + +#include +#include + +#include +#include +#include + +void __gk20a_fifo_profile_free(struct nvgpu_ref *ref); + +static void *gk20a_fifo_sched_debugfs_seq_start( + struct seq_file *s, loff_t *pos) +{ + struct gk20a *g = s->private; + struct fifo_gk20a *f = &g->fifo; + + if (*pos >= f->num_channels) + return NULL; + + return &f->channel[*pos]; +} + +static void *gk20a_fifo_sched_debugfs_seq_next( + struct seq_file *s, void *v, loff_t *pos) +{ + struct gk20a *g = s->private; + struct fifo_gk20a *f = &g->fifo; + + ++(*pos); + if (*pos >= f->num_channels) + return NULL; + + return &f->channel[*pos]; +} + +static void gk20a_fifo_sched_debugfs_seq_stop( + struct seq_file *s, void *v) +{ +} + +static int gk20a_fifo_sched_debugfs_seq_show( + struct seq_file *s, void *v) +{ + struct gk20a *g = s->private; + struct fifo_gk20a *f = &g->fifo; + struct channel_gk20a *ch = v; + struct tsg_gk20a *tsg = NULL; + + struct fifo_engine_info_gk20a *engine_info; + struct fifo_runlist_info_gk20a *runlist; + u32 runlist_id; + int ret = SEQ_SKIP; + u32 engine_id; + + engine_id = gk20a_fifo_get_gr_engine_id(g); + engine_info = (f->engine_info + engine_id); + runlist_id = engine_info->runlist_id; + runlist = &f->runlist_info[runlist_id]; + + if (ch == f->channel) { + seq_puts(s, "chid tsgid pid timeslice timeout interleave graphics_preempt compute_preempt\n"); + seq_puts(s, " (usecs) (msecs)\n"); + ret = 0; + } + + if (!test_bit(ch->chid, runlist->active_channels)) + return ret; + + if (gk20a_channel_get(ch)) { + tsg = tsg_gk20a_from_ch(ch); + + if (tsg) + seq_printf(s, "%-8d %-8d %-8d %-9d %-8d %-10d %-8d %-8d\n", + ch->chid, + ch->tsgid, + ch->tgid, + tsg->timeslice_us, + ch->timeout_ms_max, + tsg->interleave_level, + tsg->gr_ctx.graphics_preempt_mode, + tsg->gr_ctx.compute_preempt_mode); + gk20a_channel_put(ch); + } + return 0; +} + +static const struct seq_operations gk20a_fifo_sched_debugfs_seq_ops = { + .start = gk20a_fifo_sched_debugfs_seq_start, + .next = gk20a_fifo_sched_debugfs_seq_next, + .stop = gk20a_fifo_sched_debugfs_seq_stop, + .show = gk20a_fifo_sched_debugfs_seq_show +}; + +static int gk20a_fifo_sched_debugfs_open(struct inode *inode, + struct file *file) +{ + struct gk20a *g = inode->i_private; + int err; + + err = seq_open(file, &gk20a_fifo_sched_debugfs_seq_ops); + if (err) + return err; + + nvgpu_log(g, gpu_dbg_info, "i_private=%p", inode->i_private); + + ((struct seq_file *)file->private_data)->private = inode->i_private; + return 0; +}; + +/* + * The file operations structure contains our open function along with + * set of the canned seq_ ops. + */ +static const struct file_operations gk20a_fifo_sched_debugfs_fops = { + .owner = THIS_MODULE, + .open = gk20a_fifo_sched_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + +static int gk20a_fifo_profile_enable(void *data, u64 val) +{ + struct gk20a *g = (struct gk20a *) data; + struct fifo_gk20a *f = &g->fifo; + + + nvgpu_mutex_acquire(&f->profile.lock); + if (val == 0) { + if (f->profile.enabled) { + f->profile.enabled = false; + nvgpu_ref_put(&f->profile.ref, + __gk20a_fifo_profile_free); + } + } else { + if (!f->profile.enabled) { + /* not kref init as it can have a running condition if + * we enable/disable/enable while kickoff is happening + */ + if (!nvgpu_ref_get_unless_zero(&f->profile.ref)) { + f->profile.data = nvgpu_vzalloc(g, + FIFO_PROFILING_ENTRIES * + sizeof(struct fifo_profile_gk20a)); + f->profile.sorted = nvgpu_vzalloc(g, + FIFO_PROFILING_ENTRIES * + sizeof(u64)); + if (!(f->profile.data && f->profile.sorted)) { + nvgpu_vfree(g, f->profile.data); + nvgpu_vfree(g, f->profile.sorted); + nvgpu_mutex_release(&f->profile.lock); + return -ENOMEM; + } + nvgpu_ref_init(&f->profile.ref); + } + atomic_set(&f->profile.get.atomic_var, 0); + f->profile.enabled = true; + } + } + nvgpu_mutex_release(&f->profile.lock); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE( + gk20a_fifo_profile_enable_debugfs_fops, + NULL, + gk20a_fifo_profile_enable, + "%llu\n" +); + +static int __profile_cmp(const void *a, const void *b) +{ + return *((unsigned long long *) a) - *((unsigned long long *) b); +} + +/* + * This uses about 800b in the stack, but the function using it is not part + * of a callstack where much memory is being used, so it is fine + */ +#define PERCENTILE_WIDTH 5 +#define PERCENTILE_RANGES (100/PERCENTILE_WIDTH) + +static unsigned int __gk20a_fifo_create_stats(struct gk20a *g, + u64 *percentiles, u32 index_end, u32 index_start) +{ + unsigned int nelem = 0; + unsigned int index; + struct fifo_profile_gk20a *profile; + + for (index = 0; index < FIFO_PROFILING_ENTRIES; index++) { + profile = &g->fifo.profile.data[index]; + + if (profile->timestamp[index_end] > + profile->timestamp[index_start]) { + /* This is a valid element */ + g->fifo.profile.sorted[nelem] = + profile->timestamp[index_end] - + profile->timestamp[index_start]; + nelem++; + } + } + + /* sort it */ + sort(g->fifo.profile.sorted, nelem, sizeof(unsigned long long), + __profile_cmp, NULL); + + /* build ranges */ + for (index = 0; index < PERCENTILE_RANGES; index++) { + percentiles[index] = nelem < PERCENTILE_RANGES ? 0 : + g->fifo.profile.sorted[(PERCENTILE_WIDTH * (index + 1) * + nelem)/100 - 1]; + } + return nelem; +} + +static int gk20a_fifo_profile_stats(struct seq_file *s, void *unused) +{ + struct gk20a *g = s->private; + unsigned int get, nelem, index; + /* + * 800B in the stack, but function is declared statically and only + * called from debugfs handler + */ + u64 percentiles_ioctl[PERCENTILE_RANGES]; + u64 percentiles_kickoff[PERCENTILE_RANGES]; + u64 percentiles_jobtracking[PERCENTILE_RANGES]; + u64 percentiles_append[PERCENTILE_RANGES]; + u64 percentiles_userd[PERCENTILE_RANGES]; + + if (!nvgpu_ref_get_unless_zero(&g->fifo.profile.ref)) { + seq_printf(s, "Profiling disabled\n"); + return 0; + } + + get = atomic_read(&g->fifo.profile.get.atomic_var); + + __gk20a_fifo_create_stats(g, percentiles_ioctl, + PROFILE_IOCTL_EXIT, PROFILE_IOCTL_ENTRY); + __gk20a_fifo_create_stats(g, percentiles_kickoff, + PROFILE_END, PROFILE_ENTRY); + __gk20a_fifo_create_stats(g, percentiles_jobtracking, + PROFILE_JOB_TRACKING, PROFILE_IOCTL_ENTRY); + __gk20a_fifo_create_stats(g, percentiles_append, + PROFILE_APPEND, PROFILE_JOB_TRACKING); + nelem = __gk20a_fifo_create_stats(g, percentiles_userd, + PROFILE_END, PROFILE_APPEND); + + seq_printf(s, "Number of kickoffs: %d\n", nelem); + seq_printf(s, "Perc \t ioctl(ns) \t kickoff(ns) \t pbcopy(ns) \t jobtrack(ns) \t userd(ns)\n"); + + for (index = 0; index < PERCENTILE_RANGES; index++) + seq_printf(s, "[%2dpc]\t%8lld\t%8lld\t%8lld\t%8lld\t%8lld\n", + PERCENTILE_WIDTH * (index+1), + percentiles_ioctl[index], + percentiles_kickoff[index], + percentiles_append[index], + percentiles_jobtracking[index], + percentiles_userd[index]); + + nvgpu_ref_put(&g->fifo.profile.ref, __gk20a_fifo_profile_free); + + return 0; +} + +static int gk20a_fifo_profile_stats_open(struct inode *inode, struct file *file) +{ + return single_open(file, gk20a_fifo_profile_stats, inode->i_private); +} + +static const struct file_operations gk20a_fifo_profile_stats_debugfs_fops = { + .open = gk20a_fifo_profile_stats_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + +void gk20a_fifo_debugfs_init(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *gpu_root = l->debugfs; + struct dentry *fifo_root; + struct dentry *profile_root; + + fifo_root = debugfs_create_dir("fifo", gpu_root); + if (IS_ERR_OR_NULL(fifo_root)) + return; + + nvgpu_log(g, gpu_dbg_info, "g=%p", g); + + debugfs_create_file("sched", 0600, fifo_root, g, + &gk20a_fifo_sched_debugfs_fops); + + profile_root = debugfs_create_dir("profile", fifo_root); + if (IS_ERR_OR_NULL(profile_root)) + return; + + nvgpu_mutex_init(&g->fifo.profile.lock); + g->fifo.profile.enabled = false; + atomic_set(&g->fifo.profile.get.atomic_var, 0); + atomic_set(&g->fifo.profile.ref.refcount.atomic_var, 0); + + debugfs_create_file("enable", 0600, profile_root, g, + &gk20a_fifo_profile_enable_debugfs_fops); + + debugfs_create_file("stats", 0600, profile_root, g, + &gk20a_fifo_profile_stats_debugfs_fops); + +} + +void gk20a_fifo_profile_snapshot(struct fifo_profile_gk20a *profile, int idx) +{ + if (profile) + profile->timestamp[idx] = nvgpu_current_time_ns(); +} + +void __gk20a_fifo_profile_free(struct nvgpu_ref *ref) +{ + struct fifo_gk20a *f = container_of(ref, struct fifo_gk20a, + profile.ref); + nvgpu_vfree(f->g, f->profile.data); + nvgpu_vfree(f->g, f->profile.sorted); +} + +/* Get the next element in the ring buffer of profile entries + * and grab a reference to the structure + */ +struct fifo_profile_gk20a *gk20a_fifo_profile_acquire(struct gk20a *g) +{ + struct fifo_gk20a *f = &g->fifo; + struct fifo_profile_gk20a *profile; + unsigned int index; + + /* If kref is zero, profiling is not enabled */ + if (!nvgpu_ref_get_unless_zero(&f->profile.ref)) + return NULL; + index = atomic_inc_return(&f->profile.get.atomic_var); + profile = &f->profile.data[index % FIFO_PROFILING_ENTRIES]; + + return profile; +} + +/* Free the reference to the structure. This allows deferred cleanups */ +void gk20a_fifo_profile_release(struct gk20a *g, + struct fifo_profile_gk20a *profile) +{ + nvgpu_ref_put(&g->fifo.profile.ref, __gk20a_fifo_profile_free); +} + +void gk20a_fifo_debugfs_deinit(struct gk20a *g) +{ + struct fifo_gk20a *f = &g->fifo; + + nvgpu_mutex_acquire(&f->profile.lock); + if (f->profile.enabled) { + f->profile.enabled = false; + nvgpu_ref_put(&f->profile.ref, __gk20a_fifo_profile_free); + } + nvgpu_mutex_release(&f->profile.lock); +} diff --git a/include/os/linux/debug_fifo.h b/include/os/linux/debug_fifo.h new file mode 100644 index 0000000..46ac853 --- /dev/null +++ b/include/os/linux/debug_fifo.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_FIFO_H__ +#define __NVGPU_DEBUG_FIFO_H__ + +struct gk20a; +void gk20a_fifo_debugfs_init(struct gk20a *g); +void gk20a_fifo_debugfs_deinit(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_FIFO_H__ */ diff --git a/include/os/linux/debug_gr.c b/include/os/linux/debug_gr.c new file mode 100644 index 0000000..d54c6d6 --- /dev/null +++ b/include/os/linux/debug_gr.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "debug_gr.h" +#include "os_linux.h" + +#include + +int gr_gk20a_debugfs_init(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + l->debugfs_gr_default_attrib_cb_size = + debugfs_create_u32("gr_default_attrib_cb_size", + S_IRUGO|S_IWUSR, l->debugfs, + &g->gr.attrib_cb_default_size); + + return 0; +} + diff --git a/include/os/linux/debug_gr.h b/include/os/linux/debug_gr.h new file mode 100644 index 0000000..4b46acb --- /dev/null +++ b/include/os/linux/debug_gr.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_GR_H__ +#define __NVGPU_DEBUG_GR_H__ + +struct gk20a; +int gr_gk20a_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_GR_H__ */ diff --git a/include/os/linux/debug_hal.c b/include/os/linux/debug_hal.c new file mode 100644 index 0000000..031e335 --- /dev/null +++ b/include/os/linux/debug_hal.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "debug_hal.h" +#include "os_linux.h" + +#include +#include + +/* Format and print a single function pointer to the specified seq_file. */ +static void __hal_print_op(struct seq_file *s, void *op_ptr) +{ + seq_printf(s, "%pF\n", op_ptr); +} + +/* + * Prints an array of function pointer addresses in op_ptrs to the + * specified seq_file + */ +static void __hal_print_ops(struct seq_file *s, void **op_ptrs, int num_ops) +{ + int i; + + for (i = 0; i < num_ops; i++) + __hal_print_op(s, op_ptrs[i]); +} + +/* + * Show file operation, which generates content of the file once. Prints a list + * of gpu operations as defined by gops and the corresponding function pointer + * destination addresses. Relies on no compiler reordering of struct fields and + * assumption that all members are function pointers. + */ +static int __hal_show(struct seq_file *s, void *unused) +{ + struct gpu_ops *gops = s->private; + + __hal_print_ops(s, (void **)gops, sizeof(*gops) / sizeof(void *)); + + return 0; +} + +static int __hal_open(struct inode *inode, struct file *file) +{ + return single_open(file, __hal_show, inode->i_private); +} + +static const struct file_operations __hal_fops = { + .open = __hal_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +void nvgpu_hal_debugfs_fini(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (!(l->debugfs_hal == NULL)) + debugfs_remove_recursive(l->debugfs_hal); +} + +void nvgpu_hal_debugfs_init(struct gk20a *g) +{ + struct dentry *d; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (!l->debugfs) + return; + l->debugfs_hal = debugfs_create_dir("hal", l->debugfs); + if (IS_ERR_OR_NULL(l->debugfs_hal)) { + l->debugfs_hal = NULL; + return; + } + + /* Pass along reference to the gpu_ops struct as private data */ + d = debugfs_create_file("gops", S_IRUGO, l->debugfs_hal, + &g->ops, &__hal_fops); + if (!d) { + nvgpu_err(g, "%s: Failed to make debugfs node\n", __func__); + debugfs_remove_recursive(l->debugfs_hal); + return; + } +} diff --git a/include/os/linux/debug_hal.h b/include/os/linux/debug_hal.h new file mode 100644 index 0000000..eee6f23 --- /dev/null +++ b/include/os/linux/debug_hal.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_HAL_H__ +#define __NVGPU_DEBUG_HAL_H__ + +struct gk20a; +void nvgpu_hal_debugfs_fini(struct gk20a *g); +void nvgpu_hal_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_HAL_H__ */ diff --git a/include/os/linux/debug_kmem.c b/include/os/linux/debug_kmem.c new file mode 100644 index 0000000..a0c7d47 --- /dev/null +++ b/include/os/linux/debug_kmem.c @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include "os_linux.h" +#include "debug_kmem.h" +#include "kmem_priv.h" + +/** + * to_human_readable_bytes - Determine suffix for passed size. + * + * @bytes - Number of bytes to generate a suffix for. + * @hr_bytes [out] - The human readable number of bytes. + * @hr_suffix [out] - The suffix for the HR number of bytes. + * + * Computes a human readable decomposition of the passed number of bytes. The + * suffix for the bytes is passed back through the @hr_suffix pointer. The right + * number of bytes is then passed back in @hr_bytes. This returns the following + * ranges: + * + * 0 - 1023 B + * 1 - 1023 KB + * 1 - 1023 MB + * 1 - 1023 GB + * 1 - 1023 TB + * 1 - ... PB + */ +static void __to_human_readable_bytes(u64 bytes, u64 *hr_bytes, + const char **hr_suffix) +{ + static const char *suffixes[] = + { "B", "KB", "MB", "GB", "TB", "PB" }; + + u64 suffix_ind = 0; + + while (suffix_ind < ARRAY_SIZE(suffixes) && bytes >= 1024) { + bytes >>= 10; + suffix_ind++; + } + + /* + * Handle case where bytes > 1023PB. + */ + suffix_ind = suffix_ind < ARRAY_SIZE(suffixes) ? + suffix_ind : ARRAY_SIZE(suffixes) - 1; + + *hr_bytes = bytes; + *hr_suffix = suffixes[suffix_ind]; +} + +/** + * print_hr_bytes - Print human readable bytes + * + * @s - A seq_file to print to. May be NULL. + * @msg - A message to print before the bytes. + * @bytes - Number of bytes. + * + * Print @msg followed by the human readable decomposition of the passed number + * of bytes. + * + * If @s is NULL then this prints will be made to the kernel log. + */ +static void print_hr_bytes(struct seq_file *s, const char *msg, u64 bytes) +{ + u64 hr_bytes; + const char *hr_suffix; + + __to_human_readable_bytes(bytes, &hr_bytes, &hr_suffix); + __pstat(s, "%s%lld %s\n", msg, hr_bytes, hr_suffix); +} + +/** + * print_histogram - Build a histogram of the memory usage. + * + * @tracker The tracking to pull data from. + * @s A seq_file to dump info into. + */ +static void print_histogram(struct nvgpu_mem_alloc_tracker *tracker, + struct seq_file *s) +{ + int i; + u64 pot_min, pot_max; + u64 nr_buckets; + unsigned int *buckets; + unsigned int total_allocs; + struct nvgpu_rbtree_node *node; + static const char histogram_line[] = + "++++++++++++++++++++++++++++++++++++++++"; + + /* + * pot_min is essentially a round down to the nearest power of 2. This + * is the start of the histogram. pot_max is just a round up to the + * nearest power of two. Each histogram bucket is one power of two so + * the histogram buckets are exponential. + */ + pot_min = (u64)rounddown_pow_of_two(tracker->min_alloc); + pot_max = (u64)roundup_pow_of_two(tracker->max_alloc); + + nr_buckets = __ffs(pot_max) - __ffs(pot_min); + + buckets = kzalloc(sizeof(*buckets) * nr_buckets, GFP_KERNEL); + if (!buckets) { + __pstat(s, "OOM: could not allocate bucket storage!?\n"); + return; + } + + /* + * Iterate across all of the allocs and determine what bucket they + * should go in. Round the size down to the nearest power of two to + * find the right bucket. + */ + nvgpu_rbtree_enum_start(0, &node, tracker->allocs); + while (node) { + int b; + u64 bucket_min; + struct nvgpu_mem_alloc *alloc = + nvgpu_mem_alloc_from_rbtree_node(node); + + bucket_min = (u64)rounddown_pow_of_two(alloc->size); + if (bucket_min < tracker->min_alloc) + bucket_min = tracker->min_alloc; + + b = __ffs(bucket_min) - __ffs(pot_min); + + /* + * Handle the one case were there's an alloc exactly as big as + * the maximum bucket size of the largest bucket. Most of the + * buckets have an inclusive minimum and exclusive maximum. But + * the largest bucket needs to have an _inclusive_ maximum as + * well. + */ + if (b == (int)nr_buckets) + b--; + + buckets[b]++; + + nvgpu_rbtree_enum_next(&node, node); + } + + total_allocs = 0; + for (i = 0; i < (int)nr_buckets; i++) + total_allocs += buckets[i]; + + __pstat(s, "Alloc histogram:\n"); + + /* + * Actually compute the histogram lines. + */ + for (i = 0; i < (int)nr_buckets; i++) { + char this_line[sizeof(histogram_line) + 1]; + u64 line_length; + u64 hr_bytes; + const char *hr_suffix; + + memset(this_line, 0, sizeof(this_line)); + + /* + * Compute the normalized line length. Cant use floating point + * so we will just multiply everything by 1000 and use fixed + * point. + */ + line_length = (1000 * buckets[i]) / total_allocs; + line_length *= sizeof(histogram_line); + line_length /= 1000; + + memset(this_line, '+', line_length); + + __to_human_readable_bytes(1 << (__ffs(pot_min) + i), + &hr_bytes, &hr_suffix); + __pstat(s, " [%-4lld %-4lld] %-2s %5u | %s\n", + hr_bytes, hr_bytes << 1, + hr_suffix, buckets[i], this_line); + } +} + +/** + * nvgpu_kmem_print_stats - Print kmem tracking stats. + * + * @tracker The tracking to pull data from. + * @s A seq_file to dump info into. + * + * Print stats from a tracker. If @s is non-null then seq_printf() will be + * used with @s. Otherwise the stats are pr_info()ed. + */ +void nvgpu_kmem_print_stats(struct nvgpu_mem_alloc_tracker *tracker, + struct seq_file *s) +{ + nvgpu_lock_tracker(tracker); + + __pstat(s, "Mem tracker: %s\n\n", tracker->name); + + __pstat(s, "Basic Stats:\n"); + __pstat(s, " Number of allocs %lld\n", + tracker->nr_allocs); + __pstat(s, " Number of frees %lld\n", + tracker->nr_frees); + print_hr_bytes(s, " Smallest alloc ", tracker->min_alloc); + print_hr_bytes(s, " Largest alloc ", tracker->max_alloc); + print_hr_bytes(s, " Bytes allocated ", tracker->bytes_alloced); + print_hr_bytes(s, " Bytes freed ", tracker->bytes_freed); + print_hr_bytes(s, " Bytes allocated (real) ", + tracker->bytes_alloced_real); + print_hr_bytes(s, " Bytes freed (real) ", + tracker->bytes_freed_real); + __pstat(s, "\n"); + + print_histogram(tracker, s); + + nvgpu_unlock_tracker(tracker); +} + +static int __kmem_tracking_show(struct seq_file *s, void *unused) +{ + struct nvgpu_mem_alloc_tracker *tracker = s->private; + + nvgpu_kmem_print_stats(tracker, s); + + return 0; +} + +static int __kmem_tracking_open(struct inode *inode, struct file *file) +{ + return single_open(file, __kmem_tracking_show, inode->i_private); +} + +static const struct file_operations __kmem_tracking_fops = { + .open = __kmem_tracking_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __kmem_traces_dump_tracker(struct gk20a *g, + struct nvgpu_mem_alloc_tracker *tracker, + struct seq_file *s) +{ + struct nvgpu_rbtree_node *node; + + nvgpu_rbtree_enum_start(0, &node, tracker->allocs); + while (node) { + struct nvgpu_mem_alloc *alloc = + nvgpu_mem_alloc_from_rbtree_node(node); + + kmem_print_mem_alloc(g, alloc, s); + + nvgpu_rbtree_enum_next(&node, node); + } + + return 0; +} + +static int __kmem_traces_show(struct seq_file *s, void *unused) +{ + struct gk20a *g = s->private; + + nvgpu_lock_tracker(g->vmallocs); + seq_puts(s, "Oustanding vmallocs:\n"); + __kmem_traces_dump_tracker(g, g->vmallocs, s); + seq_puts(s, "\n"); + nvgpu_unlock_tracker(g->vmallocs); + + nvgpu_lock_tracker(g->kmallocs); + seq_puts(s, "Oustanding kmallocs:\n"); + __kmem_traces_dump_tracker(g, g->kmallocs, s); + nvgpu_unlock_tracker(g->kmallocs); + + return 0; +} + +static int __kmem_traces_open(struct inode *inode, struct file *file) +{ + return single_open(file, __kmem_traces_show, inode->i_private); +} + +static const struct file_operations __kmem_traces_fops = { + .open = __kmem_traces_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +void nvgpu_kmem_debugfs_init(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *node; + + l->debugfs_kmem = debugfs_create_dir("kmem_tracking", l->debugfs); + if (IS_ERR_OR_NULL(l->debugfs_kmem)) + return; + + node = debugfs_create_file(g->vmallocs->name, S_IRUGO, + l->debugfs_kmem, + g->vmallocs, &__kmem_tracking_fops); + node = debugfs_create_file(g->kmallocs->name, S_IRUGO, + l->debugfs_kmem, + g->kmallocs, &__kmem_tracking_fops); + node = debugfs_create_file("traces", S_IRUGO, + l->debugfs_kmem, + g, &__kmem_traces_fops); +} diff --git a/include/os/linux/debug_kmem.h b/include/os/linux/debug_kmem.h new file mode 100644 index 0000000..44322b5 --- /dev/null +++ b/include/os/linux/debug_kmem.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_KMEM_H__ +#define __NVGPU_DEBUG_KMEM_H__ + +struct gk20a; +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE +void nvgpu_kmem_debugfs_init(struct gk20a *g); +#endif + +#endif /* __NVGPU_DEBUG_KMEM_H__ */ diff --git a/include/os/linux/debug_ltc.c b/include/os/linux/debug_ltc.c new file mode 100644 index 0000000..1b4c221 --- /dev/null +++ b/include/os/linux/debug_ltc.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2018 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "debug_ltc.h" +#include "os_linux.h" + +#include + +#include +#include + +static ssize_t ltc_intr_illegal_compstat_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[3]; + struct gk20a *g = file->private_data; + + if (g->ltc_intr_en_illegal_compstat) + buf[0] = 'Y'; + else + buf[0] = 'N'; + buf[1] = '\n'; + buf[2] = 0x00; + + return simple_read_from_buffer(user_buf, count, ppos, buf, 2); +} + +static ssize_t ltc_intr_illegal_compstat_write(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[3]; + int buf_size; + bool intr_illegal_compstat_enabled; + struct gk20a *g = file->private_data; + int err; + + if (!g->ops.ltc.intr_en_illegal_compstat) + return -EINVAL; + + buf_size = min(count, (sizeof(buf)-1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + + err = gk20a_busy(g); + if (err) + return err; + + if (strtobool(buf, &intr_illegal_compstat_enabled) == 0) { + g->ops.ltc.intr_en_illegal_compstat(g, + intr_illegal_compstat_enabled); + g->ltc_intr_en_illegal_compstat = intr_illegal_compstat_enabled; + } + + gk20a_idle(g); + + return buf_size; +} + +static const struct file_operations ltc_intr_illegal_compstat_fops = { + .open = simple_open, + .read = ltc_intr_illegal_compstat_read, + .write = ltc_intr_illegal_compstat_write, +}; + +int nvgpu_ltc_debugfs_init(struct gk20a *g) +{ + struct dentry *d; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *gpu_root = l->debugfs; + + l->debugfs_ltc = debugfs_create_dir("ltc", gpu_root); + if (IS_ERR_OR_NULL(l->debugfs_ltc)) + return -ENODEV; + + /* Debug fs node to enable/disable illegal_compstat */ + d = debugfs_create_file("intr_illegal_compstat_enable", 0600, + l->debugfs_ltc, g, + <c_intr_illegal_compstat_fops); + if (!d) + return -ENOMEM; + + return 0; +} diff --git a/include/os/linux/debug_ltc.h b/include/os/linux/debug_ltc.h new file mode 100644 index 0000000..3ad734c --- /dev/null +++ b/include/os/linux/debug_ltc.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2018 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_LTC_H__ +#define __NVGPU_DEBUG_LTC_H__ + +struct gk20a; +int nvgpu_ltc_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_LTC_H__ */ diff --git a/include/os/linux/debug_pmgr.c b/include/os/linux/debug_pmgr.c new file mode 100644 index 0000000..c264978 --- /dev/null +++ b/include/os/linux/debug_pmgr.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "os_linux.h" + +#include "pmgr/pmgr.h" + +static int pmgr_pwr_devices_get_power_u64(void *data, u64 *p) +{ + struct gk20a *g = (struct gk20a *)data; + int err; + u32 val; + + err = pmgr_pwr_devices_get_power(g, &val); + *p = val; + + return err; +} + +static int pmgr_pwr_devices_get_current_u64(void *data, u64 *p) +{ + struct gk20a *g = (struct gk20a *)data; + int err; + u32 val; + + err = pmgr_pwr_devices_get_current(g, &val); + *p = val; + + return err; +} + +static int pmgr_pwr_devices_get_voltage_u64(void *data, u64 *p) +{ + struct gk20a *g = (struct gk20a *)data; + int err; + u32 val; + + err = pmgr_pwr_devices_get_voltage(g, &val); + *p = val; + + return err; +} + +DEFINE_SIMPLE_ATTRIBUTE( + pmgr_power_ctrl_fops, pmgr_pwr_devices_get_power_u64, NULL, "%llu\n"); + +DEFINE_SIMPLE_ATTRIBUTE( + pmgr_current_ctrl_fops, pmgr_pwr_devices_get_current_u64, NULL, "%llu\n"); + +DEFINE_SIMPLE_ATTRIBUTE( + pmgr_voltage_ctrl_fops, pmgr_pwr_devices_get_voltage_u64, NULL, "%llu\n"); + +static void pmgr_debugfs_init(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *dbgentry; + + dbgentry = debugfs_create_file( + "power", S_IRUGO, l->debugfs, g, &pmgr_power_ctrl_fops); + if (!dbgentry) + nvgpu_err(g, "debugfs entry create failed for power"); + + dbgentry = debugfs_create_file( + "current", S_IRUGO, l->debugfs, g, &pmgr_current_ctrl_fops); + if (!dbgentry) + nvgpu_err(g, "debugfs entry create failed for current"); + + dbgentry = debugfs_create_file( + "voltage", S_IRUGO, l->debugfs, g, &pmgr_voltage_ctrl_fops); + if (!dbgentry) + nvgpu_err(g, "debugfs entry create failed for voltage"); +} + +int nvgpu_pmgr_init_debugfs_linux(struct nvgpu_os_linux *l) +{ + struct gk20a *g = &l->g; + int ret = 0; + + if (!nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) + return ret; + + if (!g->ops.clk.support_pmgr_domain) + return ret; + + pmgr_debugfs_init(g); + + return ret; +} + diff --git a/include/os/linux/debug_pmgr.h b/include/os/linux/debug_pmgr.h new file mode 100644 index 0000000..bd6c556 --- /dev/null +++ b/include/os/linux/debug_pmgr.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __LINUX_DEBUG_PMGR_H +#define __LINUX_DEBUG_PMGR_H + +#ifdef CONFIG_DEBUG_FS +int nvgpu_pmgr_init_debugfs_linux(struct nvgpu_os_linux *l); +#else +int nvgpu_pmgr_init_debugfs_linux(struct nvgpu_os_linux *l) +{ + return 0; +} +#endif +#endif diff --git a/include/os/linux/debug_pmu.c b/include/os/linux/debug_pmu.c new file mode 100644 index 0000000..f3e36d0 --- /dev/null +++ b/include/os/linux/debug_pmu.c @@ -0,0 +1,484 @@ +/* + * Copyright (C) 2017-2019 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "debug_pmu.h" +#include "os_linux.h" + +#include +#include +#include + +static int lpwr_debug_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + + if (g->ops.pmu.pmu_pg_engines_feature_list && + g->ops.pmu.pmu_pg_engines_feature_list(g, + PMU_PG_ELPG_ENGINE_ID_GRAPHICS) != + NVGPU_PMU_GR_FEATURE_MASK_POWER_GATING) { + seq_printf(s, "PSTATE: %u\n" + "RPPG Enabled: %u\n" + "RPPG ref count: %u\n" + "RPPG state: %u\n" + "MSCG Enabled: %u\n" + "MSCG pstate state: %u\n" + "MSCG transition state: %u\n", + g->ops.clk_arb.get_current_pstate(g), + g->elpg_enabled, g->pmu.elpg_refcnt, + g->pmu.elpg_stat, g->mscg_enabled, + g->pmu.mscg_stat, g->pmu.mscg_transition_state); + + } else + seq_printf(s, "ELPG Enabled: %u\n" + "ELPG ref count: %u\n" + "ELPG state: %u\n", + g->elpg_enabled, g->pmu.elpg_refcnt, + g->pmu.elpg_stat); + + return 0; + +} + +static int lpwr_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, lpwr_debug_show, inode->i_private); +} + +static const struct file_operations lpwr_debug_fops = { + .open = lpwr_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int mscg_stat_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + u64 total_ingating, total_ungating, residency, divisor, dividend; + struct pmu_pg_stats_data pg_stat_data = { 0 }; + int err; + + /* Don't unnecessarily power on the device */ + if (g->power_on) { + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_pmu_get_pg_stats(g, + PMU_PG_ELPG_ENGINE_ID_MS, &pg_stat_data); + gk20a_idle(g); + } + total_ingating = g->pg_ingating_time_us + + (u64)pg_stat_data.ingating_time; + total_ungating = g->pg_ungating_time_us + + (u64)pg_stat_data.ungating_time; + + divisor = total_ingating + total_ungating; + + /* We compute the residency on a scale of 1000 */ + dividend = total_ingating * 1000; + + if (divisor) + residency = div64_u64(dividend, divisor); + else + residency = 0; + + seq_printf(s, + "Time in MSCG: %llu us\n" + "Time out of MSCG: %llu us\n" + "MSCG residency ratio: %llu\n" + "MSCG Entry Count: %u\n" + "MSCG Avg Entry latency %u\n" + "MSCG Avg Exit latency %u\n", + total_ingating, total_ungating, + residency, pg_stat_data.gating_cnt, + pg_stat_data.avg_entry_latency_us, + pg_stat_data.avg_exit_latency_us); + return 0; + +} + +static int mscg_stat_open(struct inode *inode, struct file *file) +{ + return single_open(file, mscg_stat_show, inode->i_private); +} + +static const struct file_operations mscg_stat_fops = { + .open = mscg_stat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int mscg_transitions_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + struct pmu_pg_stats_data pg_stat_data = { 0 }; + u32 total_gating_cnt; + int err; + + if (g->power_on) { + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_pmu_get_pg_stats(g, + PMU_PG_ELPG_ENGINE_ID_MS, &pg_stat_data); + gk20a_idle(g); + } + total_gating_cnt = g->pg_gating_cnt + pg_stat_data.gating_cnt; + + seq_printf(s, "%u\n", total_gating_cnt); + return 0; + +} + +static int mscg_transitions_open(struct inode *inode, struct file *file) +{ + return single_open(file, mscg_transitions_show, inode->i_private); +} + +static const struct file_operations mscg_transitions_fops = { + .open = mscg_transitions_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int elpg_stat_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + struct pmu_pg_stats_data pg_stat_data = { 0 }; + u64 total_ingating, total_ungating, residency, divisor, dividend; + int err; + + /* Don't unnecessarily power on the device */ + if (g->power_on) { + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_pmu_get_pg_stats(g, + PMU_PG_ELPG_ENGINE_ID_GRAPHICS, &pg_stat_data); + gk20a_idle(g); + } + total_ingating = g->pg_ingating_time_us + + (u64)pg_stat_data.ingating_time; + total_ungating = g->pg_ungating_time_us + + (u64)pg_stat_data.ungating_time; + divisor = total_ingating + total_ungating; + + /* We compute the residency on a scale of 1000 */ + dividend = total_ingating * 1000; + + if (divisor) + residency = div64_u64(dividend, divisor); + else + residency = 0; + + seq_printf(s, + "Time in ELPG: %llu us\n" + "Time out of ELPG: %llu us\n" + "ELPG residency ratio: %llu\n" + "ELPG Entry Count: %u\n" + "ELPG Avg Entry latency %u us\n" + "ELPG Avg Exit latency %u us\n", + total_ingating, total_ungating, + residency, pg_stat_data.gating_cnt, + pg_stat_data.avg_entry_latency_us, + pg_stat_data.avg_exit_latency_us); + return 0; + +} + +static int elpg_stat_open(struct inode *inode, struct file *file) +{ + return single_open(file, elpg_stat_show, inode->i_private); +} + +static const struct file_operations elpg_stat_fops = { + .open = elpg_stat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int elpg_transitions_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + struct pmu_pg_stats_data pg_stat_data = { 0 }; + u32 total_gating_cnt; + int err; + + if (g->power_on) { + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_pmu_get_pg_stats(g, + PMU_PG_ELPG_ENGINE_ID_GRAPHICS, &pg_stat_data); + gk20a_idle(g); + } + total_gating_cnt = g->pg_gating_cnt + pg_stat_data.gating_cnt; + + seq_printf(s, "%u\n", total_gating_cnt); + return 0; + +} + +static int elpg_transitions_open(struct inode *inode, struct file *file) +{ + return single_open(file, elpg_transitions_show, inode->i_private); +} + +static const struct file_operations elpg_transitions_fops = { + .open = elpg_transitions_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int falc_trace_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + struct nvgpu_pmu *pmu = &g->pmu; + u32 i = 0, j = 0, k, l, m; + char part_str[40]; + void *tracebuffer; + char *trace; + u32 *trace1; + + /* allocate system memory to copy pmu trace buffer */ + tracebuffer = nvgpu_kzalloc(g, GK20A_PMU_TRACE_BUFSIZE); + if (tracebuffer == NULL) + return -ENOMEM; + + /* read pmu traces into system memory buffer */ + nvgpu_mem_rd_n(g, &pmu->trace_buf, + 0, tracebuffer, GK20A_PMU_TRACE_BUFSIZE); + + trace = (char *)tracebuffer; + trace1 = (u32 *)tracebuffer; + + for (i = 0; i < GK20A_PMU_TRACE_BUFSIZE; i += 0x40) { + for (j = 0; j < 0x40; j++) + if (trace1[(i / 4) + j]) + break; + if (j == 0x40) + break; + seq_printf(s, "Index %x: ", trace1[(i / 4)]); + l = 0; + m = 0; + while (nvgpu_find_hex_in_string((trace+i+20+m), g, &k)) { + if (k >= 40) + break; + strncpy(part_str, (trace+i+20+m), k); + part_str[k] = 0; + seq_printf(s, "%s0x%x", part_str, + trace1[(i / 4) + 1 + l]); + l++; + m += k + 2; + } + seq_printf(s, "%s", (trace+i+20+m)); + } + + nvgpu_kfree(g, tracebuffer); + return 0; +} + +static int falc_trace_open(struct inode *inode, struct file *file) +{ + return single_open(file, falc_trace_show, inode->i_private); +} + +static const struct file_operations falc_trace_fops = { + .open = falc_trace_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int perfmon_events_enable_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + + seq_printf(s, "%u\n", g->pmu.perfmon_sampling_enabled ? 1 : 0); + return 0; + +} + +static int perfmon_events_enable_open(struct inode *inode, struct file *file) +{ + return single_open(file, perfmon_events_enable_show, inode->i_private); +} + +static ssize_t perfmon_events_enable_write(struct file *file, + const char __user *userbuf, size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct gk20a *g = s->private; + unsigned long val = 0; + char buf[40]; + int buf_size; + int err; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, (sizeof(buf)-1)); + + if (copy_from_user(buf, userbuf, buf_size)) + return -EFAULT; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + /* Don't turn on gk20a unnecessarily */ + if (g->power_on) { + err = gk20a_busy(g); + if (err) + return err; + + if (val && !g->pmu.perfmon_sampling_enabled && + nvgpu_is_enabled(g, NVGPU_PMU_PERFMON)) { + g->pmu.perfmon_sampling_enabled = true; + g->ops.pmu.pmu_perfmon_start_sampling(&(g->pmu)); + } else if (!val && g->pmu.perfmon_sampling_enabled && + nvgpu_is_enabled(g, NVGPU_PMU_PERFMON)) { + g->pmu.perfmon_sampling_enabled = false; + g->ops.pmu.pmu_perfmon_stop_sampling(&(g->pmu)); + } + gk20a_idle(g); + } else { + g->pmu.perfmon_sampling_enabled = val ? true : false; + } + + return count; +} + +static const struct file_operations perfmon_events_enable_fops = { + .open = perfmon_events_enable_open, + .read = seq_read, + .write = perfmon_events_enable_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static int perfmon_events_count_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + + seq_printf(s, "%lu\n", g->pmu.perfmon_events_cnt); + return 0; + +} + +static int perfmon_events_count_open(struct inode *inode, struct file *file) +{ + return single_open(file, perfmon_events_count_show, inode->i_private); +} + +static const struct file_operations perfmon_events_count_fops = { + .open = perfmon_events_count_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int security_show(struct seq_file *s, void *data) +{ + struct gk20a *g = s->private; + + seq_printf(s, "%d\n", g->pmu.pmu_mode); + return 0; + +} + +static int security_open(struct inode *inode, struct file *file) +{ + return single_open(file, security_show, inode->i_private); +} + +static const struct file_operations security_fops = { + .open = security_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +int gk20a_pmu_debugfs_init(struct gk20a *g) +{ + struct dentry *d; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + d = debugfs_create_file( + "lpwr_debug", S_IRUGO|S_IWUSR, l->debugfs, g, + &lpwr_debug_fops); + if (!d) + goto err_out; + + d = debugfs_create_file( + "mscg_residency", S_IRUGO|S_IWUSR, l->debugfs, g, + &mscg_stat_fops); + if (!d) + goto err_out; + + d = debugfs_create_file( + "mscg_transitions", S_IRUGO, l->debugfs, g, + &mscg_transitions_fops); + if (!d) + goto err_out; + + d = debugfs_create_file( + "elpg_residency", S_IRUGO|S_IWUSR, l->debugfs, g, + &elpg_stat_fops); + if (!d) + goto err_out; + + d = debugfs_create_file( + "elpg_transitions", S_IRUGO, l->debugfs, g, + &elpg_transitions_fops); + if (!d) + goto err_out; + + d = debugfs_create_file( + "pmu_security", S_IRUGO, l->debugfs, g, + &security_fops); + if (!d) + goto err_out; + + /* No access to PMU if virtual */ + if (!g->is_virtual) { + d = debugfs_create_file( + "falc_trace", S_IRUGO, l->debugfs, g, + &falc_trace_fops); + if (!d) + goto err_out; + + d = debugfs_create_file( + "perfmon_events_enable", S_IRUGO, l->debugfs, g, + &perfmon_events_enable_fops); + if (!d) + goto err_out; + + d = debugfs_create_file( + "perfmon_events_count", S_IRUGO, l->debugfs, g, + &perfmon_events_count_fops); + if (!d) + goto err_out; + } + return 0; +err_out: + pr_err("%s: Failed to make debugfs node\n", __func__); + return -ENOMEM; +} diff --git a/include/os/linux/debug_pmu.h b/include/os/linux/debug_pmu.h new file mode 100644 index 0000000..c4e3243 --- /dev/null +++ b/include/os/linux/debug_pmu.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_PMU_H__ +#define __NVGPU_DEBUG_PMU_H__ + +struct gk20a; +int gk20a_pmu_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_PMU_H__ */ diff --git a/include/os/linux/debug_sched.c b/include/os/linux/debug_sched.c new file mode 100644 index 0000000..fa43dc4 --- /dev/null +++ b/include/os/linux/debug_sched.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2017-2020 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "debug_sched.h" +#include "os_linux.h" + +#include +#include + +static int gk20a_sched_debugfs_show(struct seq_file *s, void *unused) +{ + struct gk20a *g = s->private; + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + bool sched_busy = true; + + int n = sched->bitmap_size / sizeof(u64); + int i; + int err; + + err = gk20a_busy(g); + if (err) + return err; + + if (nvgpu_mutex_tryacquire(&sched->busy_lock)) { + sched_busy = false; + nvgpu_mutex_release(&sched->busy_lock); + } + + seq_printf(s, "control_locked=%d\n", sched->control_locked); + seq_printf(s, "busy=%d\n", sched_busy); + seq_printf(s, "bitmap_size=%zu\n", sched->bitmap_size); + + nvgpu_mutex_acquire(&sched->status_lock); + + seq_puts(s, "active_tsg_bitmap\n"); + for (i = 0; i < n; i++) + seq_printf(s, "\t0x%016llx\n", sched->active_tsg_bitmap[i]); + + seq_puts(s, "recent_tsg_bitmap\n"); + for (i = 0; i < n; i++) + seq_printf(s, "\t0x%016llx\n", sched->recent_tsg_bitmap[i]); + + nvgpu_mutex_release(&sched->status_lock); + + gk20a_idle(g); + + return 0; +} + +static int gk20a_sched_debugfs_open(struct inode *inode, struct file *file) +{ + return single_open(file, gk20a_sched_debugfs_show, inode->i_private); +} + +static const struct file_operations gk20a_sched_debugfs_fops = { + .open = gk20a_sched_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +void gk20a_sched_debugfs_init(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + debugfs_create_file("sched_ctrl", S_IRUGO, l->debugfs, + g, &gk20a_sched_debugfs_fops); +} diff --git a/include/os/linux/debug_sched.h b/include/os/linux/debug_sched.h new file mode 100644 index 0000000..34a8f55 --- /dev/null +++ b/include/os/linux/debug_sched.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_SCHED_H__ +#define __NVGPU_DEBUG_SCHED_H__ + +struct gk20a; +void gk20a_sched_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_SCHED_H__ */ diff --git a/include/os/linux/debug_therm_gp106.c b/include/os/linux/debug_therm_gp106.c new file mode 100644 index 0000000..dfe3946 --- /dev/null +++ b/include/os/linux/debug_therm_gp106.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "os_linux.h" + +static int therm_get_internal_sensor_curr_temp(void *data, u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + u32 readval; + int err; + + if (!g->ops.therm.get_internal_sensor_curr_temp) + return -EINVAL; + + err = g->ops.therm.get_internal_sensor_curr_temp(g, &readval); + if (!err) + *val = readval; + + return err; +} +DEFINE_SIMPLE_ATTRIBUTE(therm_ctrl_fops, therm_get_internal_sensor_curr_temp, NULL, "%llu\n"); + +int gp106_therm_init_debugfs(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *dbgentry; + + dbgentry = debugfs_create_file( + "temp", S_IRUGO, l->debugfs, g, &therm_ctrl_fops); + if (!dbgentry) + nvgpu_err(g, "debugfs entry create failed for therm_curr_temp"); + + return 0; +} diff --git a/include/os/linux/debug_therm_gp106.h b/include/os/linux/debug_therm_gp106.h new file mode 100644 index 0000000..3e9380d --- /dev/null +++ b/include/os/linux/debug_therm_gp106.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __DEBUG_THERM_GP106_H +#define __DEBUG_THERM_GP106_H + +#ifdef CONFIG_DEBUG_FS +int gp106_therm_init_debugfs(struct gk20a *g); +#else +static inline int gp106_therm_init_debugfs(struct gk20a *g) +{ + return 0; +} +#endif + +#endif diff --git a/include/os/linux/debug_xve.c b/include/os/linux/debug_xve.c new file mode 100644 index 0000000..128d316 --- /dev/null +++ b/include/os/linux/debug_xve.c @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include + +#include "debug_xve.h" +#include "os_linux.h" + +#include +#include + +static ssize_t xve_link_speed_write(struct file *filp, + const char __user *buff, + size_t len, loff_t *off) +{ + struct gk20a *g = ((struct seq_file *)filp->private_data)->private; + char kbuff[16]; + u32 buff_size, check_len; + u32 link_speed = 0; + int ret; + + buff_size = min_t(size_t, 16, len); + + memset(kbuff, 0, 16); + if (copy_from_user(kbuff, buff, buff_size)) + return -EFAULT; + + check_len = strlen("Gen1"); + if (strncmp(kbuff, "Gen1", check_len) == 0) + link_speed = GPU_XVE_SPEED_2P5; + else if (strncmp(kbuff, "Gen2", check_len) == 0) + link_speed = GPU_XVE_SPEED_5P0; + else if (strncmp(kbuff, "Gen3", check_len) == 0) + link_speed = GPU_XVE_SPEED_8P0; + else + nvgpu_err(g, "%s: Unknown PCIe speed: %s", + __func__, kbuff); + + if (!link_speed) + return -EINVAL; + + /* Brief pause... To help rate limit this. */ + nvgpu_msleep(250); + + /* + * And actually set the speed. Yay. + */ + ret = g->ops.xve.set_speed(g, link_speed); + if (ret) + return ret; + + return len; +} + +static int xve_link_speed_show(struct seq_file *s, void *unused) +{ + struct gk20a *g = s->private; + u32 speed; + int err; + + err = g->ops.xve.get_speed(g, &speed); + if (err) + return err; + + seq_printf(s, "Current PCIe speed:\n %s\n", xve_speed_to_str(speed)); + + return 0; +} + +static int xve_link_speed_open(struct inode *inode, struct file *file) +{ + return single_open(file, xve_link_speed_show, inode->i_private); +} + +static const struct file_operations xve_link_speed_fops = { + .open = xve_link_speed_open, + .read = seq_read, + .write = xve_link_speed_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static int xve_available_speeds_show(struct seq_file *s, void *unused) +{ + struct gk20a *g = s->private; + u32 available_speeds; + + g->ops.xve.available_speeds(g, &available_speeds); + + seq_puts(s, "Available PCIe bus speeds:\n"); + if (available_speeds & GPU_XVE_SPEED_2P5) + seq_puts(s, " Gen1\n"); + if (available_speeds & GPU_XVE_SPEED_5P0) + seq_puts(s, " Gen2\n"); + if (available_speeds & GPU_XVE_SPEED_8P0) + seq_puts(s, " Gen3\n"); + + return 0; +} + +static int xve_available_speeds_open(struct inode *inode, struct file *file) +{ + return single_open(file, xve_available_speeds_show, inode->i_private); +} + +static const struct file_operations xve_available_speeds_fops = { + .open = xve_available_speeds_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int xve_link_control_status_show(struct seq_file *s, void *unused) +{ + struct gk20a *g = s->private; + u32 link_status; + + link_status = g->ops.xve.get_link_control_status(g); + seq_printf(s, "0x%08x\n", link_status); + + return 0; +} + +static int xve_link_control_status_open(struct inode *inode, struct file *file) +{ + return single_open(file, xve_link_control_status_show, inode->i_private); +} + +static const struct file_operations xve_link_control_status_fops = { + .open = xve_link_control_status_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +int nvgpu_xve_debugfs_init(struct gk20a *g) +{ + int err = -ENODEV; + + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *gpu_root = l->debugfs; + + l->debugfs_xve = debugfs_create_dir("xve", gpu_root); + if (IS_ERR_OR_NULL(l->debugfs_xve)) + goto fail; + + /* + * These are just debug nodes. If they fail to get made it's not worth + * worrying the higher level SW. + */ + debugfs_create_file("link_speed", S_IRUGO, + l->debugfs_xve, g, + &xve_link_speed_fops); + debugfs_create_file("available_speeds", S_IRUGO, + l->debugfs_xve, g, + &xve_available_speeds_fops); + debugfs_create_file("link_control_status", S_IRUGO, + l->debugfs_xve, g, + &xve_link_control_status_fops); + + err = 0; +fail: + return err; +} diff --git a/include/os/linux/debug_xve.h b/include/os/linux/debug_xve.h new file mode 100644 index 0000000..f3b1ac5 --- /dev/null +++ b/include/os/linux/debug_xve.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __NVGPU_DEBUG_XVE_H__ +#define __NVGPU_DEBUG_XVE_H__ + +struct gk20a; +int nvgpu_xve_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_SVE_H__ */ diff --git a/include/os/linux/dmabuf.c b/include/os/linux/dmabuf.c new file mode 100644 index 0000000..e8e3313 --- /dev/null +++ b/include/os/linux/dmabuf.c @@ -0,0 +1,219 @@ +/* +* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "gk20a/fence_gk20a.h" + +#include "platform_gk20a.h" +#include "dmabuf.h" +#include "os_linux.h" +#include "dmabuf_vidmem.h" + +static void gk20a_mm_delete_priv(void *_priv) +{ + struct gk20a_buffer_state *s, *s_tmp; + struct gk20a_dmabuf_priv *priv = _priv; + struct gk20a *g; + + if (!priv) + return; + + g = priv->g; + + if (priv->comptags.allocated && priv->comptags.lines) { + BUG_ON(!priv->comptag_allocator); + gk20a_comptaglines_free(priv->comptag_allocator, + priv->comptags.offset, + priv->comptags.lines); + } + + /* Free buffer states */ + nvgpu_list_for_each_entry_safe(s, s_tmp, &priv->states, + gk20a_buffer_state, list) { + gk20a_fence_put(s->fence); + nvgpu_list_del(&s->list); + nvgpu_kfree(g, s); + } + + nvgpu_kfree(g, priv); +} + +enum nvgpu_aperture gk20a_dmabuf_aperture(struct gk20a *g, + struct dma_buf *dmabuf) +{ + struct gk20a *buf_owner = nvgpu_vidmem_buf_owner(dmabuf); + bool unified_memory = nvgpu_is_enabled(g, NVGPU_MM_UNIFIED_MEMORY); + + if (buf_owner == NULL) { + /* Not nvgpu-allocated, assume system memory */ + return APERTURE_SYSMEM; + } else if (WARN_ON(buf_owner == g && unified_memory)) { + /* Looks like our video memory, but this gpu doesn't support + * it. Warn about a bug and bail out */ + nvgpu_warn(g, + "dmabuf is our vidmem but we don't have local vidmem"); + return APERTURE_INVALID; + } else if (buf_owner != g) { + /* Someone else's vidmem */ + return APERTURE_INVALID; + } else { + /* Yay, buf_owner == g */ + return APERTURE_VIDMEM; + } +} + +struct sg_table *gk20a_mm_pin(struct device *dev, struct dma_buf *dmabuf, + struct dma_buf_attachment **attachment) +{ + struct gk20a_dmabuf_priv *priv; + + priv = dma_buf_get_drvdata(dmabuf, dev); + if (WARN_ON(!priv)) + return ERR_PTR(-EINVAL); + + nvgpu_mutex_acquire(&priv->lock); + + if (priv->pin_count == 0) { + priv->attach = dma_buf_attach(dmabuf, dev); + if (IS_ERR(priv->attach)) { + nvgpu_mutex_release(&priv->lock); + return (struct sg_table *)priv->attach; + } + + priv->sgt = dma_buf_map_attachment(priv->attach, + DMA_BIDIRECTIONAL); + if (IS_ERR(priv->sgt)) { + dma_buf_detach(dmabuf, priv->attach); + nvgpu_mutex_release(&priv->lock); + return priv->sgt; + } + } + + priv->pin_count++; + nvgpu_mutex_release(&priv->lock); + *attachment = priv->attach; + return priv->sgt; +} + +void gk20a_mm_unpin(struct device *dev, struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment, + struct sg_table *sgt) +{ + struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(dmabuf, dev); + dma_addr_t dma_addr; + + if (IS_ERR(priv) || !priv) + return; + + nvgpu_mutex_acquire(&priv->lock); + WARN_ON(priv->sgt != sgt); + WARN_ON(priv->attach != attachment); + priv->pin_count--; + WARN_ON(priv->pin_count < 0); + dma_addr = sg_dma_address(priv->sgt->sgl); + if (priv->pin_count == 0) { + dma_buf_unmap_attachment(priv->attach, priv->sgt, + DMA_BIDIRECTIONAL); + dma_buf_detach(dmabuf, priv->attach); + } + nvgpu_mutex_release(&priv->lock); +} + +int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev) +{ + struct gk20a *g = gk20a_get_platform(dev)->g; + struct gk20a_dmabuf_priv *priv; + + priv = dma_buf_get_drvdata(dmabuf, dev); + if (likely(priv)) + return 0; + + nvgpu_mutex_acquire(&g->mm.priv_lock); + priv = dma_buf_get_drvdata(dmabuf, dev); + if (priv) + goto priv_exist_or_err; + + priv = nvgpu_kzalloc(g, sizeof(*priv)); + if (!priv) { + priv = ERR_PTR(-ENOMEM); + goto priv_exist_or_err; + } + + nvgpu_mutex_init(&priv->lock); + nvgpu_init_list_node(&priv->states); + priv->g = g; + dma_buf_set_drvdata(dmabuf, dev, priv, gk20a_mm_delete_priv); + +priv_exist_or_err: + nvgpu_mutex_release(&g->mm.priv_lock); + if (IS_ERR(priv)) + return -ENOMEM; + + return 0; +} + +int gk20a_dmabuf_get_state(struct dma_buf *dmabuf, struct gk20a *g, + u64 offset, struct gk20a_buffer_state **state) +{ + int err = 0; + struct gk20a_dmabuf_priv *priv; + struct gk20a_buffer_state *s; + struct device *dev = dev_from_gk20a(g); + + if (WARN_ON(offset >= (u64)dmabuf->size)) + return -EINVAL; + + err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev); + if (err) + return err; + + priv = dma_buf_get_drvdata(dmabuf, dev); + if (WARN_ON(!priv)) + return -ENOSYS; + + nvgpu_mutex_acquire(&priv->lock); + + nvgpu_list_for_each_entry(s, &priv->states, gk20a_buffer_state, list) + if (s->offset == offset) + goto out; + + /* State not found, create state. */ + s = nvgpu_kzalloc(g, sizeof(*s)); + if (!s) { + err = -ENOMEM; + goto out; + } + + s->offset = offset; + nvgpu_init_list_node(&s->list); + nvgpu_mutex_init(&s->lock); + nvgpu_list_add_tail(&s->list, &priv->states); + +out: + nvgpu_mutex_release(&priv->lock); + if (!err) + *state = s; + return err; +} diff --git a/include/os/linux/dmabuf.h b/include/os/linux/dmabuf.h new file mode 100644 index 0000000..8399eaa --- /dev/null +++ b/include/os/linux/dmabuf.h @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __COMMON_LINUX_DMABUF_H__ +#define __COMMON_LINUX_DMABUF_H__ + +#include +#include +#include +#include + +struct sg_table; +struct dma_buf; +struct dma_buf_attachment; +struct device; + +struct gk20a; +struct gk20a_buffer_state; + +struct gk20a_dmabuf_priv { + struct nvgpu_mutex lock; + + struct gk20a *g; + + struct gk20a_comptag_allocator *comptag_allocator; + struct gk20a_comptags comptags; + + struct dma_buf_attachment *attach; + struct sg_table *sgt; + + int pin_count; + + struct nvgpu_list_node states; + + u64 buffer_id; +}; + +struct sg_table *gk20a_mm_pin(struct device *dev, struct dma_buf *dmabuf, + struct dma_buf_attachment **attachment); +void gk20a_mm_unpin(struct device *dev, struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment, + struct sg_table *sgt); + +int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev); + +int gk20a_dmabuf_get_state(struct dma_buf *dmabuf, struct gk20a *g, + u64 offset, struct gk20a_buffer_state **state); + +#endif diff --git a/include/os/linux/dmabuf_vidmem.c b/include/os/linux/dmabuf_vidmem.c new file mode 100644 index 0000000..bada5dc --- /dev/null +++ b/include/os/linux/dmabuf_vidmem.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#ifdef CONFIG_NVGPU_USE_TEGRA_ALLOC_FD +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "gk20a/mm_gk20a.h" +#include "dmabuf_vidmem.h" + +bool nvgpu_addr_is_vidmem_page_alloc(u64 addr) +{ + return !!(addr & 1ULL); +} + +void nvgpu_vidmem_set_page_alloc(struct scatterlist *sgl, u64 addr) +{ + /* set bit 0 to indicate vidmem allocation */ + sg_dma_address(sgl) = (addr | 1ULL); +} + +struct nvgpu_page_alloc *nvgpu_vidmem_get_page_alloc(struct scatterlist *sgl) +{ + u64 addr; + + addr = sg_dma_address(sgl); + + if (nvgpu_addr_is_vidmem_page_alloc(addr)) + addr = addr & ~1ULL; + else + WARN_ON(1); + + return (struct nvgpu_page_alloc *)(uintptr_t)addr; +} + +static struct sg_table *gk20a_vidbuf_map_dma_buf( + struct dma_buf_attachment *attach, enum dma_data_direction dir) +{ + struct nvgpu_vidmem_buf *buf = attach->dmabuf->priv; + + return buf->mem->priv.sgt; +} + +static void gk20a_vidbuf_unmap_dma_buf(struct dma_buf_attachment *attach, + struct sg_table *sgt, + enum dma_data_direction dir) +{ +} + +static void gk20a_vidbuf_release(struct dma_buf *dmabuf) +{ + struct nvgpu_vidmem_buf *buf = dmabuf->priv; + struct nvgpu_vidmem_linux *linux_buf = buf->priv; + struct gk20a *g = buf->g; + + vidmem_dbg(g, "Releasing Linux VIDMEM buf: dmabuf=0x%p size=%zuKB", + dmabuf, buf->mem->size >> 10); + + if (linux_buf && linux_buf->dmabuf_priv_delete) + linux_buf->dmabuf_priv_delete(linux_buf->dmabuf_priv); + + nvgpu_kfree(g, linux_buf); + nvgpu_vidmem_buf_free(g, buf); + + gk20a_put(g); +} + +static void *gk20a_vidbuf_kmap(struct dma_buf *dmabuf, unsigned long page_num) +{ + WARN_ON("Not supported"); + return NULL; +} + +static void *gk20a_vidbuf_kmap_atomic(struct dma_buf *dmabuf, + unsigned long page_num) +{ + WARN_ON("Not supported"); + return NULL; +} + +static int gk20a_vidbuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +{ + return -EINVAL; +} + +static int gk20a_vidbuf_set_private(struct dma_buf *dmabuf, + struct device *dev, void *priv, void (*delete)(void *priv)) +{ + struct nvgpu_vidmem_buf *buf = dmabuf->priv; + struct nvgpu_vidmem_linux *linux_buf = buf->priv; + + linux_buf->dmabuf_priv = priv; + linux_buf->dmabuf_priv_delete = delete; + + return 0; +} + +static void *gk20a_vidbuf_get_private(struct dma_buf *dmabuf, + struct device *dev) +{ + struct nvgpu_vidmem_buf *buf = dmabuf->priv; + struct nvgpu_vidmem_linux *linux_buf = buf->priv; + + return linux_buf->dmabuf_priv; +} + +static const struct dma_buf_ops gk20a_vidbuf_ops = { + .map_dma_buf = gk20a_vidbuf_map_dma_buf, + .unmap_dma_buf = gk20a_vidbuf_unmap_dma_buf, + .release = gk20a_vidbuf_release, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + .map_atomic = gk20a_vidbuf_kmap_atomic, + .map = gk20a_vidbuf_kmap, +#else + .kmap_atomic = gk20a_vidbuf_kmap_atomic, + .kmap = gk20a_vidbuf_kmap, +#endif + .mmap = gk20a_vidbuf_mmap, + .set_drvdata = gk20a_vidbuf_set_private, + .get_drvdata = gk20a_vidbuf_get_private, +}; + +static struct dma_buf *gk20a_vidbuf_export(struct nvgpu_vidmem_buf *buf) +{ + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + + exp_info.priv = buf; + exp_info.ops = &gk20a_vidbuf_ops; + exp_info.size = buf->mem->size; + exp_info.flags = O_RDWR; + + return dma_buf_export(&exp_info); +} + +struct gk20a *nvgpu_vidmem_buf_owner(struct dma_buf *dmabuf) +{ + struct nvgpu_vidmem_buf *buf = dmabuf->priv; + + if (dmabuf->ops != &gk20a_vidbuf_ops) + return NULL; + + return buf->g; +} + +int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes) +{ + struct nvgpu_vidmem_buf *buf = NULL; + struct nvgpu_vidmem_linux *priv; + int err, fd; + + /* + * This ref is released when the dma_buf is closed. + */ + if (!gk20a_get(g)) + return -ENODEV; + + vidmem_dbg(g, "Allocating vidmem buf: %zu bytes", bytes); + + priv = nvgpu_kzalloc(g, sizeof(*priv)); + if (!priv) { + err = -ENOMEM; + goto fail; + } + + buf = nvgpu_vidmem_user_alloc(g, bytes); + if (IS_ERR(buf)) { + err = PTR_ERR(buf); + goto fail; + } + + priv->dmabuf = gk20a_vidbuf_export(buf); + if (IS_ERR(priv->dmabuf)) { + err = PTR_ERR(priv->dmabuf); + goto fail; + } + + buf->priv = priv; + +#ifdef CONFIG_NVGPU_USE_TEGRA_ALLOC_FD + fd = tegra_alloc_fd(current->files, 1024, O_RDWR); +#else + fd = get_unused_fd_flags(O_RDWR); +#endif + if (fd < 0) { + /* ->release frees what we have done */ + dma_buf_put(priv->dmabuf); + return fd; + } + + /* fclose() on this drops one ref, freeing the dma buf */ + fd_install(fd, priv->dmabuf->file); + + vidmem_dbg(g, "Alloced Linux VIDMEM buf: dmabuf=0x%p size=%zuKB", + priv->dmabuf, buf->mem->size >> 10); + + return fd; + +fail: + nvgpu_vidmem_buf_free(g, buf); + nvgpu_kfree(g, priv); + gk20a_put(g); + + vidmem_dbg(g, "Failed to alloc Linux VIDMEM buf: %d", err); + return err; +} + +int nvgpu_vidmem_buf_access_memory(struct gk20a *g, struct dma_buf *dmabuf, + void *buffer, u64 offset, u64 size, u32 cmd) +{ + struct nvgpu_vidmem_buf *vidmem_buf; + struct nvgpu_mem *mem; + int err = 0; + + if (gk20a_dmabuf_aperture(g, dmabuf) != APERTURE_VIDMEM) + return -EINVAL; + + vidmem_buf = dmabuf->priv; + mem = vidmem_buf->mem; + + nvgpu_speculation_barrier(); + switch (cmd) { + case NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY_CMD_READ: + nvgpu_mem_rd_n(g, mem, offset, buffer, size); + break; + + case NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY_CMD_WRITE: + nvgpu_mem_wr_n(g, mem, offset, buffer, size); + break; + + default: + err = -EINVAL; + } + + return err; +} + +void __nvgpu_mem_free_vidmem_alloc(struct gk20a *g, struct nvgpu_mem *vidmem) +{ + nvgpu_free(vidmem->allocator, + (u64)nvgpu_vidmem_get_page_alloc(vidmem->priv.sgt->sgl)); + nvgpu_free_sgtable(g, &vidmem->priv.sgt); +} diff --git a/include/os/linux/dmabuf_vidmem.h b/include/os/linux/dmabuf_vidmem.h new file mode 100644 index 0000000..977fd78 --- /dev/null +++ b/include/os/linux/dmabuf_vidmem.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NVGPU_LINUX_DMABUF_VIDMEM_H__ +#define __NVGPU_LINUX_DMABUF_VIDMEM_H__ + +#include + +struct dma_buf; + +struct gk20a; +struct scatterlist; + +#ifdef CONFIG_GK20A_VIDMEM + +struct gk20a *nvgpu_vidmem_buf_owner(struct dma_buf *dmabuf); +int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes); + +void nvgpu_vidmem_set_page_alloc(struct scatterlist *sgl, u64 addr); +struct nvgpu_page_alloc *nvgpu_vidmem_get_page_alloc(struct scatterlist *sgl); + +int nvgpu_vidmem_buf_access_memory(struct gk20a *g, struct dma_buf *dmabuf, + void *buffer, u64 offset, u64 size, u32 cmd); + +#else /* !CONFIG_GK20A_VIDMEM */ + +static inline struct gk20a *nvgpu_vidmem_buf_owner(struct dma_buf *dmabuf) +{ + return NULL; +} + +static inline int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes) +{ + return -ENOSYS; +} + +static inline void nvgpu_vidmem_set_page_alloc(struct scatterlist *sgl, + u64 addr) +{ +} + +static inline struct nvgpu_page_alloc *nvgpu_vidmem_get_page_alloc( + struct scatterlist *sgl) +{ + return NULL; +} + +static inline int nvgpu_vidmem_buf_access_memory(struct gk20a *g, + struct dma_buf *dmabuf, + void *buffer, u64 offset, + u64 size, u32 cmd) +{ + return -ENOSYS; +} + +#endif + + +struct nvgpu_vidmem_linux { + struct dma_buf *dmabuf; + void *dmabuf_priv; + void (*dmabuf_priv_delete)(void *); +}; + +#endif diff --git a/include/os/linux/driver_common.c b/include/os/linux/driver_common.c new file mode 100644 index 0000000..c76dabe --- /dev/null +++ b/include/os/linux/driver_common.c @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "platform_gk20a.h" +#include "module.h" +#include "os_linux.h" +#include "sysfs.h" +#include "ioctl.h" +#include "gk20a/regops_gk20a.h" + +#define EMC3D_DEFAULT_RATIO 750 + +void nvgpu_kernel_restart(void *cmd) +{ + kernel_restart(cmd); +} + +static void nvgpu_init_vars(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = dev_get_drvdata(dev); + + nvgpu_cond_init(&l->sw_irq_stall_last_handled_wq); + nvgpu_cond_init(&l->sw_irq_nonstall_last_handled_wq); + + init_rwsem(&l->busy_lock); + nvgpu_rwsem_init(&g->deterministic_busy); + + nvgpu_spinlock_init(&g->mc_enable_lock); + + nvgpu_mutex_init(&platform->railgate_lock); + nvgpu_mutex_init(&g->dbg_sessions_lock); + nvgpu_mutex_init(&g->client_lock); + nvgpu_mutex_init(&g->power_lock); + nvgpu_mutex_init(&g->ctxsw_disable_lock); + nvgpu_mutex_init(&g->tpc_pg_lock); + nvgpu_mutex_init(&g->clk_arb_enable_lock); + nvgpu_mutex_init(&g->cg_pg_lock); + + /* Init the clock req count to 0 */ + nvgpu_atomic_set(&g->clk_arb_global_nr, 0); + + nvgpu_mutex_init(&l->ctrl.privs_lock); + nvgpu_init_list_node(&l->ctrl.privs); + + l->regs_saved = l->regs; + l->bar1_saved = l->bar1; + + g->emc3d_ratio = EMC3D_DEFAULT_RATIO; + + /* Set DMA parameters to allow larger sgt lists */ + dev->dma_parms = &l->dma_parms; + dma_set_max_seg_size(dev, UINT_MAX); + + /* + * A default of 16GB is the largest supported DMA size that is + * acceptable to all currently supported Tegra SoCs. + */ + if (!platform->dma_mask) + platform->dma_mask = DMA_BIT_MASK(34); + + dma_set_mask(dev, platform->dma_mask); + dma_set_coherent_mask(dev, platform->dma_mask); + + nvgpu_init_list_node(&g->profiler_objects); + + nvgpu_init_list_node(&g->boardobj_head); + nvgpu_init_list_node(&g->boardobjgrp_head); + + __nvgpu_set_enabled(g, NVGPU_HAS_SYNCPOINTS, platform->has_syncpoints); +} + +static void nvgpu_init_gr_vars(struct gk20a *g) +{ + gk20a_init_gr(g); + + nvgpu_log_info(g, "total ram pages : %lu", totalram_pages); + g->gr.max_comptag_mem = totalram_size_in_mb; +} + +static void nvgpu_init_timeout(struct gk20a *g) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); + + g->timeouts_disabled_by_user = false; + nvgpu_atomic_set(&g->timeouts_disabled_refcount, 0); + + if (nvgpu_platform_is_silicon(g)) { + g->gr_idle_timeout_default = NVGPU_DEFAULT_GR_IDLE_TIMEOUT; + } else if (nvgpu_platform_is_fpga(g)) { + g->gr_idle_timeout_default = GK20A_TIMEOUT_FPGA; + } else { + g->gr_idle_timeout_default = (u32)ULONG_MAX; + } + g->ch_wdt_timeout_ms = platform->ch_wdt_timeout_ms; + g->fifo_eng_timeout_us = GRFIFO_TIMEOUT_CHECK_PERIOD_US; +} + +static void nvgpu_init_timeslice(struct gk20a *g) +{ + g->runlist_interleave = true; + + g->timeslice_low_priority_us = 1300; + g->timeslice_medium_priority_us = 2600; + g->timeslice_high_priority_us = 5200; + + g->min_timeslice_us = 1000; + g->max_timeslice_us = 50000; +} + +static void nvgpu_init_pm_vars(struct gk20a *g) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); + u32 i = 0; + + /* + * Set up initial power settings. For non-slicon platforms, disable + * power features and for silicon platforms, read from platform data + */ + g->slcg_enabled = + nvgpu_platform_is_silicon(g) ? platform->enable_slcg : false; + g->blcg_enabled = + nvgpu_platform_is_silicon(g) ? platform->enable_blcg : false; + g->elcg_enabled = + nvgpu_platform_is_silicon(g) ? platform->enable_elcg : false; + g->elpg_enabled = + nvgpu_platform_is_silicon(g) ? platform->enable_elpg : false; + g->aelpg_enabled = + nvgpu_platform_is_silicon(g) ? platform->enable_aelpg : false; + g->mscg_enabled = + nvgpu_platform_is_silicon(g) ? platform->enable_mscg : false; + g->can_elpg = + nvgpu_platform_is_silicon(g) ? platform->can_elpg_init : false; + + __nvgpu_set_enabled(g, NVGPU_GPU_CAN_ELCG, + nvgpu_platform_is_silicon(g) ? platform->can_elcg : false); + __nvgpu_set_enabled(g, NVGPU_GPU_CAN_SLCG, + nvgpu_platform_is_silicon(g) ? platform->can_slcg : false); + __nvgpu_set_enabled(g, NVGPU_GPU_CAN_BLCG, + nvgpu_platform_is_silicon(g) ? platform->can_blcg : false); + + g->aggressive_sync_destroy = platform->aggressive_sync_destroy; + g->aggressive_sync_destroy_thresh = platform->aggressive_sync_destroy_thresh; +#ifdef CONFIG_NVGPU_SUPPORT_CDE + g->has_cde = platform->has_cde; +#endif + g->ptimer_src_freq = platform->ptimer_src_freq; + g->support_pmu = support_gk20a_pmu(dev_from_gk20a(g)); + __nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, platform->can_railgate_init); + g->can_tpc_powergate = platform->can_tpc_powergate; + + for (i = 0; i < MAX_TPC_PG_CONFIGS; i++) + g->valid_tpc_mask[i] = platform->valid_tpc_mask[i]; + + g->ldiv_slowdown_factor = platform->ldiv_slowdown_factor_init; + /* if default delay is not set, set default delay to 500msec */ + if (platform->railgate_delay_init) + g->railgate_delay = platform->railgate_delay_init; + else + g->railgate_delay = NVGPU_DEFAULT_RAILGATE_IDLE_TIMEOUT; + __nvgpu_set_enabled(g, NVGPU_PMU_PERFMON, platform->enable_perfmon); + + /* set default values to aelpg parameters */ + g->pmu.aelpg_param[0] = APCTRL_SAMPLING_PERIOD_PG_DEFAULT_US; + g->pmu.aelpg_param[1] = APCTRL_MINIMUM_IDLE_FILTER_DEFAULT_US; + g->pmu.aelpg_param[2] = APCTRL_MINIMUM_TARGET_SAVING_DEFAULT_US; + g->pmu.aelpg_param[3] = APCTRL_POWER_BREAKEVEN_DEFAULT_US; + g->pmu.aelpg_param[4] = APCTRL_CYCLES_PER_SAMPLE_MAX_DEFAULT; + + __nvgpu_set_enabled(g, NVGPU_SUPPORT_ASPM, !platform->disable_aspm); +} + +static void nvgpu_init_vbios_vars(struct gk20a *g) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); + + __nvgpu_set_enabled(g, NVGPU_PMU_RUN_PREOS, platform->run_preos); + g->vbios_min_version = platform->vbios_min_version; +} + +static void nvgpu_init_ltc_vars(struct gk20a *g) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); + + g->ltc_streamid = platform->ltc_streamid; +} + +static void nvgpu_init_mm_vars(struct gk20a *g) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); + + g->mm.disable_bigpage = platform->disable_bigpage; + __nvgpu_set_enabled(g, NVGPU_MM_HONORS_APERTURE, + platform->honors_aperture); + __nvgpu_set_enabled(g, NVGPU_MM_UNIFIED_MEMORY, + platform->unified_memory); + __nvgpu_set_enabled(g, NVGPU_MM_UNIFY_ADDRESS_SPACES, + platform->unify_address_spaces); + __nvgpu_set_enabled(g, NVGPU_MM_FORCE_128K_PMU_VM, + platform->force_128K_pmu_vm); + + nvgpu_mutex_init(&g->mm.tlb_lock); + nvgpu_mutex_init(&g->mm.priv_lock); +} + +int nvgpu_probe(struct gk20a *g, + const char *debugfs_symlink, + const char *interface_name, + struct class *class) +{ + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = dev_get_drvdata(dev); + int err = 0; + + nvgpu_init_vars(g); + nvgpu_init_gr_vars(g); + nvgpu_init_timeout(g); + nvgpu_init_timeslice(g); + nvgpu_init_pm_vars(g); + nvgpu_init_vbios_vars(g); + nvgpu_init_ltc_vars(g); + err = nvgpu_init_soc_vars(g); + if (err) { + nvgpu_err(g, "init soc vars failed"); + return err; + } + + /* Initialize the platform interface. */ + err = platform->probe(dev); + if (err) { + if (err == -EPROBE_DEFER) + nvgpu_info(g, "platform probe failed"); + else + nvgpu_err(g, "platform probe failed"); + return err; + } + + nvgpu_init_mm_vars(g); + + /* platform probe can defer do user init only if probe succeeds */ + err = gk20a_user_init(dev, interface_name, class); + if (err) + return err; + + if (platform->late_probe) { + err = platform->late_probe(dev); + if (err) { + nvgpu_err(g, "late probe failed"); + return err; + } + } + + nvgpu_create_sysfs(dev); + gk20a_debug_init(g, debugfs_symlink); + + g->dbg_regops_tmp_buf = nvgpu_kzalloc(g, SZ_4K); + if (!g->dbg_regops_tmp_buf) { + nvgpu_err(g, "couldn't allocate regops tmp buf"); + return -ENOMEM; + } + g->dbg_regops_tmp_buf_ops = + SZ_4K / sizeof(g->dbg_regops_tmp_buf[0]); + + g->remove_support = gk20a_remove_support; + + nvgpu_ref_init(&g->refcount); + + return 0; +} + +/** + * cyclic_delta - Returns delta of cyclic integers a and b. + * + * @a - First integer + * @b - Second integer + * + * Note: if a is ahead of b, delta is positive. + */ +static int cyclic_delta(int a, int b) +{ + return a - b; +} + +/** + * nvgpu_wait_for_deferred_interrupts - Wait for interrupts to complete + * + * @g - The GPU to wait on. + * + * Waits until all interrupt handlers that have been scheduled to run have + * completed. + */ +void nvgpu_wait_for_deferred_interrupts(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + int stall_irq_threshold = atomic_read(&l->hw_irq_stall_count); + int nonstall_irq_threshold = atomic_read(&l->hw_irq_nonstall_count); + + /* wait until all stalling irqs are handled */ + NVGPU_COND_WAIT(&l->sw_irq_stall_last_handled_wq, + cyclic_delta(stall_irq_threshold, + atomic_read(&l->sw_irq_stall_last_handled)) + <= 0, 0); + + /* wait until all non-stalling irqs are handled */ + NVGPU_COND_WAIT(&l->sw_irq_nonstall_last_handled_wq, + cyclic_delta(nonstall_irq_threshold, + atomic_read(&l->sw_irq_nonstall_last_handled)) + <= 0, 0); +} + +static void nvgpu_free_gk20a(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + kfree(l); +} + +void nvgpu_init_gk20a(struct gk20a *g) +{ + g->free = nvgpu_free_gk20a; +} diff --git a/include/os/linux/driver_common.h b/include/os/linux/driver_common.h new file mode 100644 index 0000000..6f42f77 --- /dev/null +++ b/include/os/linux/driver_common.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NVGPU_LINUX_DRIVER_COMMON +#define NVGPU_LINUX_DRIVER_COMMON + +void nvgpu_init_gk20a(struct gk20a *g); + +#endif diff --git a/include/os/linux/dt.c b/include/os/linux/dt.c new file mode 100644 index 0000000..88e391e --- /dev/null +++ b/include/os/linux/dt.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "os_linux.h" + +int nvgpu_dt_read_u32_index(struct gk20a *g, const char *name, + u32 index, u32 *value) +{ + struct device *dev = dev_from_gk20a(g); + struct device_node *np = dev->of_node; + + return of_property_read_u32_index(np, name, index, value); +} diff --git a/include/os/linux/ecc_sysfs.c b/include/os/linux/ecc_sysfs.c new file mode 100644 index 0000000..73ae3dc --- /dev/null +++ b/include/os/linux/ecc_sysfs.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "os_linux.h" + +int nvgpu_ecc_sysfs_init(struct gk20a *g) +{ + struct device *dev = dev_from_gk20a(g); + struct nvgpu_ecc *ecc = &g->ecc; + struct dev_ext_attribute *attr; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct nvgpu_ecc_stat *stat; + int i = 0, err; + + attr = nvgpu_kzalloc(g, sizeof(*attr) * ecc->stats_count); + if (!attr) + return -ENOMEM; + + nvgpu_list_for_each_entry(stat, + &ecc->stats_list, nvgpu_ecc_stat, node) { + if (i >= ecc->stats_count) { + err = -EINVAL; + nvgpu_err(g, "stats_list longer than stats_count %d", + ecc->stats_count); + break; + } + sysfs_attr_init(&attr[i].attr.attr); + attr[i].attr.attr.name = stat->name; + attr[i].attr.attr.mode = VERIFY_OCTAL_PERMISSIONS(S_IRUGO); + attr[i].var = &stat->counter; + attr[i].attr.show = device_show_int; + err = device_create_file(dev, &attr[i].attr); + if (err) { + nvgpu_err(g, "sysfs node create failed for %s\n", + stat->name); + break; + } + i++; + } + + if (err) { + while (i-- > 0) + device_remove_file(dev, &attr[i].attr); + nvgpu_kfree(g, attr); + return err; + } + + l->ecc_attrs = attr; + + return 0; +} + +void nvgpu_ecc_sysfs_remove(struct gk20a *g) +{ + struct device *dev = dev_from_gk20a(g); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct nvgpu_ecc *ecc = &g->ecc; + int i; + + for (i = 0; i < ecc->stats_count; i++) + device_remove_file(dev, &l->ecc_attrs[i].attr); + nvgpu_kfree(g, l->ecc_attrs); + l->ecc_attrs = NULL; +} diff --git a/include/os/linux/firmware.c b/include/os/linux/firmware.c new file mode 100644 index 0000000..8f0344b --- /dev/null +++ b/include/os/linux/firmware.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include +#include +#include + +#include "platform_gk20a.h" +#include "os_linux.h" + +static const struct firmware *do_request_firmware(struct device *dev, + const char *prefix, const char *fw_name, int flags) +{ + const struct firmware *fw; + char *fw_path = NULL; + int path_len, err; + + if (prefix) { + path_len = strlen(prefix) + strlen(fw_name); + path_len += 2; /* for the path separator and zero terminator*/ + + fw_path = nvgpu_kzalloc(get_gk20a(dev), + sizeof(*fw_path) * path_len); + if (!fw_path) + return NULL; + + sprintf(fw_path, "%s/%s", prefix, fw_name); + fw_name = fw_path; + } + + if (flags & NVGPU_REQUEST_FIRMWARE_NO_WARN) + err = request_firmware_direct(&fw, fw_name, dev); + else + err = request_firmware(&fw, fw_name, dev); + + nvgpu_kfree(get_gk20a(dev), fw_path); + if (err) + return NULL; + return fw; +} + +/* This is a simple wrapper around request_firmware that takes 'fw_name' and + * applies an IP specific relative path prefix to it. The caller is + * responsible for calling nvgpu_release_firmware later. */ +struct nvgpu_firmware *nvgpu_request_firmware(struct gk20a *g, + const char *fw_name, + int flags) +{ + struct device *dev = dev_from_gk20a(g); + struct nvgpu_firmware *fw; + const struct firmware *linux_fw; + + /* current->fs is NULL when calling from SYS_EXIT. + Add a check here to prevent crash in request_firmware */ + if (!current->fs || !fw_name) + return NULL; + + fw = nvgpu_kzalloc(g, sizeof(*fw)); + if (!fw) + return NULL; + + linux_fw = do_request_firmware(dev, g->name, fw_name, flags); + +#ifdef CONFIG_TEGRA_GK20A + /* TO BE REMOVED - Support loading from legacy SOC specific path. */ + if (!linux_fw && !(flags & NVGPU_REQUEST_FIRMWARE_NO_SOC)) { + struct gk20a_platform *platform = gk20a_get_platform(dev); + linux_fw = do_request_firmware(dev, + platform->soc_name, fw_name, flags); + } +#endif + + if (!linux_fw) + goto err; + + fw->data = nvgpu_kmalloc(g, linux_fw->size); + if (!fw->data) + goto err_release; + + memcpy(fw->data, linux_fw->data, linux_fw->size); + fw->size = linux_fw->size; + + release_firmware(linux_fw); + + return fw; + +err_release: + release_firmware(linux_fw); +err: + nvgpu_kfree(g, fw); + return NULL; +} + +void nvgpu_release_firmware(struct gk20a *g, struct nvgpu_firmware *fw) +{ + if(!fw) + return; + + nvgpu_kfree(g, fw->data); + nvgpu_kfree(g, fw); +} diff --git a/include/os/linux/fuse.c b/include/os/linux/fuse.c new file mode 100644 index 0000000..27851f9 --- /dev/null +++ b/include/os/linux/fuse.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include + +#include + +int nvgpu_tegra_get_gpu_speedo_id(struct gk20a *g) +{ + return tegra_sku_info.gpu_speedo_id; +} + +/* + * Use tegra_fuse_control_read/write() APIs for fuse offsets upto 0x100 + * Use tegra_fuse_readl/writel() APIs for fuse offsets above 0x100 + */ +void nvgpu_tegra_fuse_write_bypass(struct gk20a *g, u32 val) +{ + tegra_fuse_control_write(val, FUSE_FUSEBYPASS_0); +} + +void nvgpu_tegra_fuse_write_access_sw(struct gk20a *g, u32 val) +{ + tegra_fuse_control_write(val, FUSE_WRITE_ACCESS_SW_0); +} + +void nvgpu_tegra_fuse_write_opt_gpu_tpc0_disable(struct gk20a *g, u32 val) +{ + tegra_fuse_writel(val, FUSE_OPT_GPU_TPC0_DISABLE_0); +} + +void nvgpu_tegra_fuse_write_opt_gpu_tpc1_disable(struct gk20a *g, u32 val) +{ + tegra_fuse_writel(val, FUSE_OPT_GPU_TPC1_DISABLE_0); +} + +int nvgpu_tegra_fuse_read_gcplex_config_fuse(struct gk20a *g, u32 *val) +{ + return tegra_fuse_readl(FUSE_GCPLEX_CONFIG_FUSE_0, val); +} + +int nvgpu_tegra_fuse_read_reserved_calib(struct gk20a *g, u32 *val) +{ + return tegra_fuse_readl(FUSE_RESERVED_CALIB0_0, val); +} diff --git a/include/os/linux/intr.c b/include/os/linux/intr.c new file mode 100644 index 0000000..8838b72 --- /dev/null +++ b/include/os/linux/intr.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include + +#include + +#include +#include +#include "os_linux.h" + +irqreturn_t nvgpu_intr_stall(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + u32 mc_intr_0; + + trace_mc_gk20a_intr_stall(g->name); + + if (!g->power_on) + return IRQ_NONE; + + /* not from gpu when sharing irq with others */ + mc_intr_0 = g->ops.mc.intr_stall(g); + if (unlikely(!mc_intr_0)) + return IRQ_NONE; + + g->ops.mc.intr_stall_pause(g); + + atomic_inc(&l->hw_irq_stall_count); + + trace_mc_gk20a_intr_stall_done(g->name); + + return IRQ_WAKE_THREAD; +} + +irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + int hw_irq_count; + + nvgpu_log(g, gpu_dbg_intr, "interrupt thread launched"); + + trace_mc_gk20a_intr_thread_stall(g->name); + + hw_irq_count = atomic_read(&l->hw_irq_stall_count); + g->ops.mc.isr_stall(g); + g->ops.mc.intr_stall_resume(g); + /* sync handled irq counter before re-enabling interrupts */ + atomic_set(&l->sw_irq_stall_last_handled, hw_irq_count); + + nvgpu_cond_broadcast(&l->sw_irq_stall_last_handled_wq); + + trace_mc_gk20a_intr_thread_stall_done(g->name); + + return IRQ_HANDLED; +} + +irqreturn_t nvgpu_intr_nonstall(struct gk20a *g) +{ + u32 non_stall_intr_val; + u32 hw_irq_count; + int ops_old, ops_new, ops = 0; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (!g->power_on) + return IRQ_NONE; + + /* not from gpu when sharing irq with others */ + non_stall_intr_val = g->ops.mc.intr_nonstall(g); + if (unlikely(!non_stall_intr_val)) + return IRQ_NONE; + + g->ops.mc.intr_nonstall_pause(g); + + ops = g->ops.mc.isr_nonstall(g); + if (ops) { + do { + ops_old = atomic_read(&l->nonstall_ops); + ops_new = ops_old | ops; + } while (ops_old != atomic_cmpxchg(&l->nonstall_ops, + ops_old, ops_new)); + + queue_work(l->nonstall_work_queue, &l->nonstall_fn_work); + } + + hw_irq_count = atomic_inc_return(&l->hw_irq_nonstall_count); + + /* sync handled irq counter before re-enabling interrupts */ + atomic_set(&l->sw_irq_nonstall_last_handled, hw_irq_count); + + g->ops.mc.intr_nonstall_resume(g); + + nvgpu_cond_broadcast(&l->sw_irq_nonstall_last_handled_wq); + + return IRQ_HANDLED; +} + +static void mc_gk20a_handle_intr_nonstall(struct gk20a *g, u32 ops) +{ + bool semaphore_wakeup, post_events; + + semaphore_wakeup = + (((ops & GK20A_NONSTALL_OPS_WAKEUP_SEMAPHORE) != 0U) ? + true : false); + post_events = (((ops & GK20A_NONSTALL_OPS_POST_EVENTS) != 0U) ? + true: false); + + if (semaphore_wakeup) { + g->ops.semaphore_wakeup(g, post_events); + } +} + +void nvgpu_intr_nonstall_cb(struct work_struct *work) +{ + struct nvgpu_os_linux *l = + container_of(work, struct nvgpu_os_linux, nonstall_fn_work); + struct gk20a *g = &l->g; + + do { + u32 ops; + + ops = atomic_xchg(&l->nonstall_ops, 0); + mc_gk20a_handle_intr_nonstall(g, ops); + } while (atomic_read(&l->nonstall_ops) != 0); +} diff --git a/include/os/linux/intr.h b/include/os/linux/intr.h new file mode 100644 index 0000000..d43cdcc --- /dev/null +++ b/include/os/linux/intr.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __NVGPU_LINUX_INTR_H__ +#define __NVGPU_LINUX_INTR_H__ +struct gk20a; + +irqreturn_t nvgpu_intr_stall(struct gk20a *g); +irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g); +irqreturn_t nvgpu_intr_nonstall(struct gk20a *g); +void nvgpu_intr_nonstall_cb(struct work_struct *work); +#endif diff --git a/include/os/linux/io.c b/include/os/linux/io.c new file mode 100644 index 0000000..3e84e88 --- /dev/null +++ b/include/os/linux/io.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include + +#include "os_linux.h" + +void nvgpu_writel(struct gk20a *g, u32 r, u32 v) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (unlikely(!l->regs)) { + __gk20a_warn_on_no_regs(); + nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v); + } else { + writel_relaxed(v, l->regs + r); + nvgpu_wmb(); + nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x", r, v); + } +} + +void nvgpu_writel_relaxed(struct gk20a *g, u32 r, u32 v) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (unlikely(!l->regs)) { + __gk20a_warn_on_no_regs(); + nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v); + } else { + writel_relaxed(v, l->regs + r); + } +} + +u32 nvgpu_readl(struct gk20a *g, u32 r) +{ + u32 v = __nvgpu_readl(g, r); + + if (v == 0xffffffff) + __nvgpu_check_gpu_state(g); + + return v; +} + +u32 __nvgpu_readl(struct gk20a *g, u32 r) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + u32 v = 0xffffffff; + + if (unlikely(!l->regs)) { + __gk20a_warn_on_no_regs(); + nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v); + } else { + v = readl(l->regs + r); + nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x", r, v); + } + + return v; +} + +void nvgpu_writel_loop(struct gk20a *g, u32 r, u32 v) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (unlikely(!l->regs)) { + __gk20a_warn_on_no_regs(); + nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v); + } else { + nvgpu_wmb(); + do { + writel_relaxed(v, l->regs + r); + } while (readl(l->regs + r) != v); + nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x", r, v); + } +} + +void nvgpu_bar1_writel(struct gk20a *g, u32 b, u32 v) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (unlikely(!l->bar1)) { + __gk20a_warn_on_no_regs(); + nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v); + } else { + nvgpu_wmb(); + writel_relaxed(v, l->bar1 + b); + nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x", b, v); + } +} + +u32 nvgpu_bar1_readl(struct gk20a *g, u32 b) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + u32 v = 0xffffffff; + + if (unlikely(!l->bar1)) { + __gk20a_warn_on_no_regs(); + nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v); + } else { + v = readl(l->bar1 + b); + nvgpu_log(g, gpu_dbg_reg, "b=0x%x v=0x%x", b, v); + } + + return v; +} + +bool nvgpu_io_exists(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + return l->regs != NULL; +} + +bool nvgpu_io_valid_reg(struct gk20a *g, u32 r) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + return r < resource_size(l->regs); +} diff --git a/include/os/linux/io_usermode.c b/include/os/linux/io_usermode.c new file mode 100644 index 0000000..ffc532f --- /dev/null +++ b/include/os/linux/io_usermode.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include + +#include "os_linux.h" + +#include + +void nvgpu_usermode_writel(struct gk20a *g, u32 r, u32 v) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + void __iomem *reg = l->usermode_regs + (r - usermode_cfg0_r()); + + writel_relaxed(v, reg); + nvgpu_log(g, gpu_dbg_reg, "usermode r=0x%x v=0x%x", r, v); +} diff --git a/include/os/linux/ioctl.c b/include/os/linux/ioctl.c new file mode 100644 index 0000000..a40df2a --- /dev/null +++ b/include/os/linux/ioctl.c @@ -0,0 +1,297 @@ +/* + * NVGPU IOCTLs + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include +#include + +#include "gk20a/dbg_gpu_gk20a.h" + +#include "ioctl_channel.h" +#include "ioctl_ctrl.h" +#include "ioctl_as.h" +#include "ioctl_tsg.h" +#include "ioctl_dbg.h" +#include "module.h" +#include "os_linux.h" +#include "ctxsw_trace.h" +#include "platform_gk20a.h" + +#define GK20A_NUM_CDEVS 7 + +const struct file_operations gk20a_channel_ops = { + .owner = THIS_MODULE, + .release = gk20a_channel_release, + .open = gk20a_channel_open, +#ifdef CONFIG_COMPAT + .compat_ioctl = gk20a_channel_ioctl, +#endif + .unlocked_ioctl = gk20a_channel_ioctl, +}; + +static const struct file_operations gk20a_ctrl_ops = { + .owner = THIS_MODULE, + .release = gk20a_ctrl_dev_release, + .open = gk20a_ctrl_dev_open, + .unlocked_ioctl = gk20a_ctrl_dev_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gk20a_ctrl_dev_ioctl, +#endif + .mmap = gk20a_ctrl_dev_mmap, +}; + +static const struct file_operations gk20a_dbg_ops = { + .owner = THIS_MODULE, + .release = gk20a_dbg_gpu_dev_release, + .open = gk20a_dbg_gpu_dev_open, + .unlocked_ioctl = gk20a_dbg_gpu_dev_ioctl, + .poll = gk20a_dbg_gpu_dev_poll, +#ifdef CONFIG_COMPAT + .compat_ioctl = gk20a_dbg_gpu_dev_ioctl, +#endif +}; + +static const struct file_operations gk20a_as_ops = { + .owner = THIS_MODULE, + .release = gk20a_as_dev_release, + .open = gk20a_as_dev_open, +#ifdef CONFIG_COMPAT + .compat_ioctl = gk20a_as_dev_ioctl, +#endif + .unlocked_ioctl = gk20a_as_dev_ioctl, +}; + +/* + * Note: We use a different 'open' to trigger handling of the profiler session. + * Most of the code is shared between them... Though, at some point if the + * code does get too tangled trying to handle each in the same path we can + * separate them cleanly. + */ +static const struct file_operations gk20a_prof_ops = { + .owner = THIS_MODULE, + .release = gk20a_dbg_gpu_dev_release, + .open = gk20a_prof_gpu_dev_open, + .unlocked_ioctl = gk20a_dbg_gpu_dev_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gk20a_dbg_gpu_dev_ioctl, +#endif +}; + +static const struct file_operations gk20a_tsg_ops = { + .owner = THIS_MODULE, + .release = nvgpu_ioctl_tsg_dev_release, + .open = nvgpu_ioctl_tsg_dev_open, +#ifdef CONFIG_COMPAT + .compat_ioctl = nvgpu_ioctl_tsg_dev_ioctl, +#endif + .unlocked_ioctl = nvgpu_ioctl_tsg_dev_ioctl, +}; + +#ifdef CONFIG_GK20A_CTXSW_TRACE +static const struct file_operations gk20a_ctxsw_ops = { + .owner = THIS_MODULE, + .release = gk20a_ctxsw_dev_release, + .open = gk20a_ctxsw_dev_open, +#ifdef CONFIG_COMPAT + .compat_ioctl = gk20a_ctxsw_dev_ioctl, +#endif + .unlocked_ioctl = gk20a_ctxsw_dev_ioctl, + .poll = gk20a_ctxsw_dev_poll, + .read = gk20a_ctxsw_dev_read, + .mmap = gk20a_ctxsw_dev_mmap, +}; +#endif + +static const struct file_operations gk20a_sched_ops = { + .owner = THIS_MODULE, + .release = gk20a_sched_dev_release, + .open = gk20a_sched_dev_open, +#ifdef CONFIG_COMPAT + .compat_ioctl = gk20a_sched_dev_ioctl, +#endif + .unlocked_ioctl = gk20a_sched_dev_ioctl, + .poll = gk20a_sched_dev_poll, + .read = gk20a_sched_dev_read, +}; + +static int gk20a_create_device( + struct device *dev, int devno, + const char *interface_name, const char *cdev_name, + struct cdev *cdev, struct device **out, + const struct file_operations *ops, + struct class *class) +{ + struct device *subdev; + int err; + struct gk20a *g = gk20a_from_dev(dev); + + nvgpu_log_fn(g, " "); + + cdev_init(cdev, ops); + cdev->owner = THIS_MODULE; + + err = cdev_add(cdev, devno, 1); + if (err) { + dev_err(dev, "failed to add %s cdev\n", cdev_name); + return err; + } + + subdev = device_create(class, NULL, devno, NULL, + interface_name, cdev_name); + + if (IS_ERR(subdev)) { + err = PTR_ERR(dev); + cdev_del(cdev); + dev_err(dev, "failed to create %s device for %s\n", + cdev_name, dev_name(dev)); + return err; + } + + *out = subdev; + return 0; +} + +void gk20a_user_deinit(struct device *dev, struct class *class) +{ + struct gk20a *g = gk20a_from_dev(dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (l->channel.node) { + device_destroy(class, l->channel.cdev.dev); + cdev_del(&l->channel.cdev); + } + + if (l->as_dev.node) { + device_destroy(class, l->as_dev.cdev.dev); + cdev_del(&l->as_dev.cdev); + } + + if (l->ctrl.node) { + device_destroy(class, l->ctrl.cdev.dev); + cdev_del(&l->ctrl.cdev); + } + + if (l->dbg.node) { + device_destroy(class, l->dbg.cdev.dev); + cdev_del(&l->dbg.cdev); + } + + if (l->prof.node) { + device_destroy(class, l->prof.cdev.dev); + cdev_del(&l->prof.cdev); + } + + if (l->tsg.node) { + device_destroy(class, l->tsg.cdev.dev); + cdev_del(&l->tsg.cdev); + } + + if (l->ctxsw.node) { + device_destroy(class, l->ctxsw.cdev.dev); + cdev_del(&l->ctxsw.cdev); + } + + if (l->sched.node) { + device_destroy(class, l->sched.cdev.dev); + cdev_del(&l->sched.cdev); + } + + if (l->cdev_region) + unregister_chrdev_region(l->cdev_region, GK20A_NUM_CDEVS); +} + +int gk20a_user_init(struct device *dev, const char *interface_name, + struct class *class) +{ + int err; + dev_t devno; + struct gk20a *g = gk20a_from_dev(dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + err = alloc_chrdev_region(&devno, 0, GK20A_NUM_CDEVS, dev_name(dev)); + if (err) { + dev_err(dev, "failed to allocate devno\n"); + goto fail; + } + l->cdev_region = devno; + + err = gk20a_create_device(dev, devno++, interface_name, "", + &l->channel.cdev, &l->channel.node, + &gk20a_channel_ops, + class); + if (err) + goto fail; + + err = gk20a_create_device(dev, devno++, interface_name, "-as", + &l->as_dev.cdev, &l->as_dev.node, + &gk20a_as_ops, + class); + if (err) + goto fail; + + err = gk20a_create_device(dev, devno++, interface_name, "-ctrl", + &l->ctrl.cdev, &l->ctrl.node, + &gk20a_ctrl_ops, + class); + if (err) + goto fail; + + err = gk20a_create_device(dev, devno++, interface_name, "-dbg", + &l->dbg.cdev, &l->dbg.node, + &gk20a_dbg_ops, + class); + if (err) + goto fail; + + err = gk20a_create_device(dev, devno++, interface_name, "-prof", + &l->prof.cdev, &l->prof.node, + &gk20a_prof_ops, + class); + if (err) + goto fail; + + err = gk20a_create_device(dev, devno++, interface_name, "-tsg", + &l->tsg.cdev, &l->tsg.node, + &gk20a_tsg_ops, + class); + if (err) + goto fail; + +#if defined(CONFIG_GK20A_CTXSW_TRACE) + err = gk20a_create_device(dev, devno++, interface_name, "-ctxsw", + &l->ctxsw.cdev, &l->ctxsw.node, + &gk20a_ctxsw_ops, + class); + if (err) + goto fail; +#endif + + err = gk20a_create_device(dev, devno++, interface_name, "-sched", + &l->sched.cdev, &l->sched.node, + &gk20a_sched_ops, + class); + if (err) + goto fail; + + return 0; +fail: + gk20a_user_deinit(dev, &nvgpu_class); + return err; +} diff --git a/include/os/linux/ioctl.h b/include/os/linux/ioctl.h new file mode 100644 index 0000000..7bf1671 --- /dev/null +++ b/include/os/linux/ioctl.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#ifndef __NVGPU_IOCTL_H__ +#define __NVGPU_IOCTL_H__ + +struct device; +struct class; + +int gk20a_user_init(struct device *dev, const char *interface_name, + struct class *class); +void gk20a_user_deinit(struct device *dev, struct class *class); + +#endif diff --git a/include/os/linux/ioctl_as.c b/include/os/linux/ioctl_as.c new file mode 100644 index 0000000..f0cec17 --- /dev/null +++ b/include/os/linux/ioctl_as.c @@ -0,0 +1,427 @@ +/* + * GK20A Address Spaces + * + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include "platform_gk20a.h" +#include "ioctl_as.h" +#include "os_linux.h" + +static u32 gk20a_as_translate_as_alloc_space_flags(struct gk20a *g, u32 flags) +{ + u32 core_flags = 0; + + if (flags & NVGPU_AS_ALLOC_SPACE_FLAGS_FIXED_OFFSET) + core_flags |= NVGPU_VM_AREA_ALLOC_FIXED_OFFSET; + if (flags & NVGPU_AS_ALLOC_SPACE_FLAGS_SPARSE) + core_flags |= NVGPU_VM_AREA_ALLOC_SPARSE; + + return core_flags; +} + +static int gk20a_as_ioctl_bind_channel( + struct gk20a_as_share *as_share, + struct nvgpu_as_bind_channel_args *args) +{ + int err = 0; + struct channel_gk20a *ch; + struct gk20a *g = gk20a_from_vm(as_share->vm); + + nvgpu_log_fn(g, " "); + + ch = gk20a_get_channel_from_file(args->channel_fd); + if (!ch) + return -EINVAL; + + if (gk20a_channel_as_bound(ch)) { + err = -EINVAL; + goto out; + } + + /* this will set channel_gk20a->vm */ + err = ch->g->ops.mm.vm_bind_channel(as_share->vm, ch); + +out: + gk20a_channel_put(ch); + return err; +} + +static int gk20a_as_ioctl_alloc_space( + struct gk20a_as_share *as_share, + struct nvgpu_as_alloc_space_args *args) +{ + struct gk20a *g = gk20a_from_vm(as_share->vm); + + nvgpu_log_fn(g, " "); + return nvgpu_vm_area_alloc(as_share->vm, args->pages, args->page_size, + &args->o_a.offset, + gk20a_as_translate_as_alloc_space_flags(g, + args->flags)); +} + +static int gk20a_as_ioctl_free_space( + struct gk20a_as_share *as_share, + struct nvgpu_as_free_space_args *args) +{ + struct gk20a *g = gk20a_from_vm(as_share->vm); + + nvgpu_log_fn(g, " "); + return nvgpu_vm_area_free(as_share->vm, args->offset); +} + +static int gk20a_as_ioctl_map_buffer_ex( + struct gk20a_as_share *as_share, + struct nvgpu_as_map_buffer_ex_args *args) +{ + struct gk20a *g = gk20a_from_vm(as_share->vm); + + nvgpu_log_fn(g, " "); + + /* unsupported, direct kind control must be used */ + if (!(args->flags & NVGPU_AS_MAP_BUFFER_FLAGS_DIRECT_KIND_CTRL)) { + struct gk20a *g = as_share->vm->mm->g; + nvgpu_log_info(g, "Direct kind control must be requested"); + return -EINVAL; + } + + return nvgpu_vm_map_buffer(as_share->vm, args->dmabuf_fd, + &args->offset, args->flags, + args->page_size, + args->compr_kind, + args->incompr_kind, + args->buffer_offset, + args->mapping_size, + NULL); +} + +static int gk20a_as_ioctl_unmap_buffer( + struct gk20a_as_share *as_share, + struct nvgpu_as_unmap_buffer_args *args) +{ + struct gk20a *g = gk20a_from_vm(as_share->vm); + + nvgpu_log_fn(g, " "); + + nvgpu_vm_unmap(as_share->vm, args->offset, NULL); + + return 0; +} + +static int gk20a_as_ioctl_map_buffer_batch( + struct gk20a_as_share *as_share, + struct nvgpu_as_map_buffer_batch_args *args) +{ + struct gk20a *g = gk20a_from_vm(as_share->vm); + u32 i; + int err = 0; + + struct nvgpu_as_unmap_buffer_args __user *user_unmap_args = + (struct nvgpu_as_unmap_buffer_args __user *)(uintptr_t) + args->unmaps; + struct nvgpu_as_map_buffer_ex_args __user *user_map_args = + (struct nvgpu_as_map_buffer_ex_args __user *)(uintptr_t) + args->maps; + + struct vm_gk20a_mapping_batch batch; + + nvgpu_log_fn(g, " "); + + if (args->num_unmaps > NVGPU_IOCTL_AS_MAP_BUFFER_BATCH_LIMIT || + args->num_maps > NVGPU_IOCTL_AS_MAP_BUFFER_BATCH_LIMIT) + return -EINVAL; + + nvgpu_vm_mapping_batch_start(&batch); + + for (i = 0; i < args->num_unmaps; ++i) { + struct nvgpu_as_unmap_buffer_args unmap_args; + + if (copy_from_user(&unmap_args, &user_unmap_args[i], + sizeof(unmap_args))) { + err = -EFAULT; + break; + } + + nvgpu_vm_unmap(as_share->vm, unmap_args.offset, &batch); + } + + nvgpu_speculation_barrier(); + if (err) { + nvgpu_vm_mapping_batch_finish(as_share->vm, &batch); + + args->num_unmaps = i; + args->num_maps = 0; + return err; + } + + for (i = 0; i < args->num_maps; ++i) { + s16 compressible_kind; + s16 incompressible_kind; + + struct nvgpu_as_map_buffer_ex_args map_args; + memset(&map_args, 0, sizeof(map_args)); + + if (copy_from_user(&map_args, &user_map_args[i], + sizeof(map_args))) { + err = -EFAULT; + break; + } + + if (map_args.flags & + NVGPU_AS_MAP_BUFFER_FLAGS_DIRECT_KIND_CTRL) { + compressible_kind = map_args.compr_kind; + incompressible_kind = map_args.incompr_kind; + } else { + /* direct kind control must be used */ + err = -EINVAL; + break; + } + + err = nvgpu_vm_map_buffer( + as_share->vm, map_args.dmabuf_fd, + &map_args.offset, map_args.flags, map_args.page_size, + compressible_kind, incompressible_kind, + map_args.buffer_offset, + map_args.mapping_size, + &batch); + if (err) + break; + } + + nvgpu_vm_mapping_batch_finish(as_share->vm, &batch); + + if (err) + args->num_maps = i; + /* note: args->num_unmaps will be unmodified, which is ok + * since all unmaps are done */ + + return err; +} + +static int gk20a_as_ioctl_get_va_regions( + struct gk20a_as_share *as_share, + struct nvgpu_as_get_va_regions_args *args) +{ + unsigned int i; + unsigned int write_entries; + struct nvgpu_as_va_region __user *user_region_ptr; + struct vm_gk20a *vm = as_share->vm; + struct gk20a *g = gk20a_from_vm(vm); + unsigned int page_sizes = GMMU_PAGE_SIZE_KERNEL; + + nvgpu_log_fn(g, " "); + + if (!vm->big_pages) + page_sizes--; + + write_entries = args->buf_size / sizeof(struct nvgpu_as_va_region); + if (write_entries > page_sizes) + write_entries = page_sizes; + + user_region_ptr = + (struct nvgpu_as_va_region __user *)(uintptr_t)args->buf_addr; + + for (i = 0; i < write_entries; ++i) { + struct nvgpu_as_va_region region; + struct nvgpu_allocator *vma = vm->vma[i]; + + memset(®ion, 0, sizeof(struct nvgpu_as_va_region)); + + region.page_size = vm->gmmu_page_sizes[i]; + region.offset = nvgpu_alloc_base(vma); + /* No __aeabi_uldivmod() on some platforms... */ + region.pages = (nvgpu_alloc_end(vma) - + nvgpu_alloc_base(vma)) >> ilog2(region.page_size); + + if (copy_to_user(user_region_ptr + i, ®ion, sizeof(region))) + return -EFAULT; + } + + args->buf_size = + page_sizes * sizeof(struct nvgpu_as_va_region); + + return 0; +} + +static int nvgpu_as_ioctl_get_sync_ro_map( + struct gk20a_as_share *as_share, + struct nvgpu_as_get_sync_ro_map_args *args) +{ +#ifdef CONFIG_TEGRA_GK20A_NVHOST + struct vm_gk20a *vm = as_share->vm; + struct gk20a *g = gk20a_from_vm(vm); + u64 base_gpuva; + u32 sync_size; + int err = 0; + + if (!g->ops.fifo.get_sync_ro_map) + return -EINVAL; + + if (!nvgpu_has_syncpoints(g)) + return -EINVAL; + + err = g->ops.fifo.get_sync_ro_map(vm, &base_gpuva, &sync_size); + if (err) + return err; + + args->base_gpuva = base_gpuva; + args->sync_size = sync_size; + + return err; +#else + return -EINVAL; +#endif +} + +int gk20a_as_dev_open(struct inode *inode, struct file *filp) +{ + struct nvgpu_os_linux *l; + struct gk20a_as_share *as_share; + struct gk20a *g; + int err; + + l = container_of(inode->i_cdev, struct nvgpu_os_linux, as_dev.cdev); + g = &l->g; + + nvgpu_log_fn(g, " "); + + err = gk20a_as_alloc_share(g, 0, 0, &as_share); + if (err) { + nvgpu_log_fn(g, "failed to alloc share"); + return err; + } + + filp->private_data = as_share; + return 0; +} + +int gk20a_as_dev_release(struct inode *inode, struct file *filp) +{ + struct gk20a_as_share *as_share = filp->private_data; + + if (!as_share) + return 0; + + return gk20a_as_release_share(as_share); +} + +long gk20a_as_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int err = 0; + struct gk20a_as_share *as_share = filp->private_data; + struct gk20a *g = gk20a_from_as(as_share->as); + + u8 buf[NVGPU_AS_IOCTL_MAX_ARG_SIZE]; + + nvgpu_log_fn(g, "start %d", _IOC_NR(cmd)); + + if ((_IOC_TYPE(cmd) != NVGPU_AS_IOCTL_MAGIC) || + (_IOC_NR(cmd) == 0) || + (_IOC_NR(cmd) > NVGPU_AS_IOCTL_LAST) || + (_IOC_SIZE(cmd) > NVGPU_AS_IOCTL_MAX_ARG_SIZE)) + return -EINVAL; + + memset(buf, 0, sizeof(buf)); + if (_IOC_DIR(cmd) & _IOC_WRITE) { + if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + } + + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_speculation_barrier(); + switch (cmd) { + case NVGPU_AS_IOCTL_BIND_CHANNEL: + trace_gk20a_as_ioctl_bind_channel(g->name); + err = gk20a_as_ioctl_bind_channel(as_share, + (struct nvgpu_as_bind_channel_args *)buf); + + break; + case NVGPU32_AS_IOCTL_ALLOC_SPACE: + { + struct nvgpu32_as_alloc_space_args *args32 = + (struct nvgpu32_as_alloc_space_args *)buf; + struct nvgpu_as_alloc_space_args args; + + args.pages = args32->pages; + args.page_size = args32->page_size; + args.flags = args32->flags; + args.o_a.offset = args32->o_a.offset; + trace_gk20a_as_ioctl_alloc_space(g->name); + err = gk20a_as_ioctl_alloc_space(as_share, &args); + args32->o_a.offset = args.o_a.offset; + break; + } + case NVGPU_AS_IOCTL_ALLOC_SPACE: + trace_gk20a_as_ioctl_alloc_space(g->name); + err = gk20a_as_ioctl_alloc_space(as_share, + (struct nvgpu_as_alloc_space_args *)buf); + break; + case NVGPU_AS_IOCTL_FREE_SPACE: + trace_gk20a_as_ioctl_free_space(g->name); + err = gk20a_as_ioctl_free_space(as_share, + (struct nvgpu_as_free_space_args *)buf); + break; + case NVGPU_AS_IOCTL_MAP_BUFFER_EX: + trace_gk20a_as_ioctl_map_buffer(g->name); + err = gk20a_as_ioctl_map_buffer_ex(as_share, + (struct nvgpu_as_map_buffer_ex_args *)buf); + break; + case NVGPU_AS_IOCTL_UNMAP_BUFFER: + trace_gk20a_as_ioctl_unmap_buffer(g->name); + err = gk20a_as_ioctl_unmap_buffer(as_share, + (struct nvgpu_as_unmap_buffer_args *)buf); + break; + case NVGPU_AS_IOCTL_GET_VA_REGIONS: + trace_gk20a_as_ioctl_get_va_regions(g->name); + err = gk20a_as_ioctl_get_va_regions(as_share, + (struct nvgpu_as_get_va_regions_args *)buf); + break; + case NVGPU_AS_IOCTL_MAP_BUFFER_BATCH: + err = gk20a_as_ioctl_map_buffer_batch(as_share, + (struct nvgpu_as_map_buffer_batch_args *)buf); + break; + case NVGPU_AS_IOCTL_GET_SYNC_RO_MAP: + err = nvgpu_as_ioctl_get_sync_ro_map(as_share, + (struct nvgpu_as_get_sync_ro_map_args *)buf); + break; + default: + err = -ENOTTY; + break; + } + + gk20a_idle(g); + + if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ)) + if (copy_to_user((void __user *)arg, buf, _IOC_SIZE(cmd))) + err = -EFAULT; + + return err; +} diff --git a/include/os/linux/ioctl_as.h b/include/os/linux/ioctl_as.h new file mode 100644 index 0000000..b3de378 --- /dev/null +++ b/include/os/linux/ioctl_as.h @@ -0,0 +1,30 @@ +/* + * GK20A Address Spaces + * + * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#ifndef __NVGPU_COMMON_LINUX_AS_H__ +#define __NVGPU_COMMON_LINUX_AS_H__ + +struct inode; +struct file; + +/* MAP_BUFFER_BATCH_LIMIT: the upper limit for num_unmaps and + * num_maps */ +#define NVGPU_IOCTL_AS_MAP_BUFFER_BATCH_LIMIT 256 + +/* struct file_operations driver interface */ +int gk20a_as_dev_open(struct inode *inode, struct file *filp); +int gk20a_as_dev_release(struct inode *inode, struct file *filp); +long gk20a_as_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); + +#endif diff --git a/include/os/linux/ioctl_channel.c b/include/os/linux/ioctl_channel.c new file mode 100644 index 0000000..0f39cc7 --- /dev/null +++ b/include/os/linux/ioctl_channel.c @@ -0,0 +1,1388 @@ +/* + * GK20A Graphics channel + * + * Copyright (c) 2011-2020, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a/dbg_gpu_gk20a.h" +#include "gk20a/fence_gk20a.h" + +#include "platform_gk20a.h" +#include "ioctl_channel.h" +#include "channel.h" +#include "os_linux.h" +#include "ctxsw_trace.h" + +/* the minimal size of client buffer */ +#define CSS_MIN_CLIENT_SNAPSHOT_SIZE \ + (sizeof(struct gk20a_cs_snapshot_fifo) + \ + sizeof(struct gk20a_cs_snapshot_fifo_entry) * 256) + +static const char *gr_gk20a_graphics_preempt_mode_name(u32 graphics_preempt_mode) +{ + switch (graphics_preempt_mode) { + case NVGPU_PREEMPTION_MODE_GRAPHICS_WFI: + return "WFI"; + default: + return "?"; + } +} + +static const char *gr_gk20a_compute_preempt_mode_name(u32 compute_preempt_mode) +{ + switch (compute_preempt_mode) { + case NVGPU_PREEMPTION_MODE_COMPUTE_WFI: + return "WFI"; + case NVGPU_PREEMPTION_MODE_COMPUTE_CTA: + return "CTA"; + default: + return "?"; + } +} + +static void gk20a_channel_trace_sched_param( + void (*trace)(int chid, int tsgid, pid_t pid, u32 timeslice, + u32 timeout, const char *interleave, + const char *graphics_preempt_mode, + const char *compute_preempt_mode), + struct channel_gk20a *ch) +{ + struct tsg_gk20a *tsg = tsg_gk20a_from_ch(ch); + + if (!tsg) + return; + + (trace)(ch->chid, ch->tsgid, ch->pid, + tsg_gk20a_from_ch(ch)->timeslice_us, + ch->timeout_ms_max, + gk20a_fifo_interleave_level_name(tsg->interleave_level), + gr_gk20a_graphics_preempt_mode_name( + tsg->gr_ctx.graphics_preempt_mode), + gr_gk20a_compute_preempt_mode_name( + tsg->gr_ctx.compute_preempt_mode)); +} + +/* + * Although channels do have pointers back to the gk20a struct that they were + * created under in cases where the driver is killed that pointer can be bad. + * The channel memory can be freed before the release() function for a given + * channel is called. This happens when the driver dies and userspace doesn't + * get a chance to call release() until after the entire gk20a driver data is + * unloaded and freed. + */ +struct channel_priv { + struct gk20a *g; + struct channel_gk20a *c; +}; + +#if defined(CONFIG_GK20A_CYCLE_STATS) + +void gk20a_channel_free_cycle_stats_buffer(struct channel_gk20a *ch) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + + /* disable existing cyclestats buffer */ + nvgpu_mutex_acquire(&ch->cyclestate.cyclestate_buffer_mutex); + if (priv->cyclestate_buffer_handler) { + dma_buf_vunmap(priv->cyclestate_buffer_handler, + ch->cyclestate.cyclestate_buffer); + dma_buf_put(priv->cyclestate_buffer_handler); + priv->cyclestate_buffer_handler = NULL; + ch->cyclestate.cyclestate_buffer = NULL; + ch->cyclestate.cyclestate_buffer_size = 0; + } + nvgpu_mutex_release(&ch->cyclestate.cyclestate_buffer_mutex); +} + +int gk20a_channel_cycle_stats(struct channel_gk20a *ch, int dmabuf_fd) +{ + struct dma_buf *dmabuf; + void *virtual_address; + struct nvgpu_channel_linux *priv = ch->os_priv; + + /* is it allowed to handle calls for current GPU? */ + if (!nvgpu_is_enabled(ch->g, NVGPU_SUPPORT_CYCLE_STATS)) + return -ENOSYS; + + if (dmabuf_fd && !priv->cyclestate_buffer_handler) { + + /* set up new cyclestats buffer */ + dmabuf = dma_buf_get(dmabuf_fd); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + virtual_address = dma_buf_vmap(dmabuf); + if (!virtual_address) + return -ENOMEM; + + priv->cyclestate_buffer_handler = dmabuf; + ch->cyclestate.cyclestate_buffer = virtual_address; + ch->cyclestate.cyclestate_buffer_size = dmabuf->size; + return 0; + + } else if (!dmabuf_fd && priv->cyclestate_buffer_handler) { + gk20a_channel_free_cycle_stats_buffer(ch); + return 0; + + } else if (!dmabuf_fd && !priv->cyclestate_buffer_handler) { + /* no request from GL */ + return 0; + + } else { + pr_err("channel already has cyclestats buffer\n"); + return -EINVAL; + } +} + +int gk20a_flush_cycle_stats_snapshot(struct channel_gk20a *ch) +{ + int ret; + + nvgpu_mutex_acquire(&ch->cs_client_mutex); + if (ch->cs_client) + ret = gr_gk20a_css_flush(ch, ch->cs_client); + else + ret = -EBADF; + nvgpu_mutex_release(&ch->cs_client_mutex); + + return ret; +} + +int gk20a_attach_cycle_stats_snapshot(struct channel_gk20a *ch, + u32 dmabuf_fd, + u32 perfmon_id_count, + u32 *perfmon_id_start) +{ + int ret = 0; + struct gk20a *g = ch->g; + struct gk20a_cs_snapshot_client_linux *client_linux; + struct gk20a_cs_snapshot_client *client; + + nvgpu_mutex_acquire(&ch->cs_client_mutex); + if (ch->cs_client) { + nvgpu_mutex_release(&ch->cs_client_mutex); + return -EEXIST; + } + + client_linux = nvgpu_kzalloc(g, sizeof(*client_linux)); + if (!client_linux) { + ret = -ENOMEM; + goto err; + } + + client_linux->dmabuf_fd = dmabuf_fd; + client_linux->dma_handler = dma_buf_get(client_linux->dmabuf_fd); + if (IS_ERR(client_linux->dma_handler)) { + ret = PTR_ERR(client_linux->dma_handler); + client_linux->dma_handler = NULL; + goto err_free; + } + + client = &client_linux->cs_client; + client->snapshot_size = client_linux->dma_handler->size; + if (client->snapshot_size < CSS_MIN_CLIENT_SNAPSHOT_SIZE) { + ret = -ENOMEM; + goto err_put; + } + + client->snapshot = (struct gk20a_cs_snapshot_fifo *) + dma_buf_vmap(client_linux->dma_handler); + if (!client->snapshot) { + ret = -ENOMEM; + goto err_put; + } + + ch->cs_client = client; + + ret = gr_gk20a_css_attach(ch, + perfmon_id_count, + perfmon_id_start, + ch->cs_client); + + nvgpu_mutex_release(&ch->cs_client_mutex); + + return ret; + +err_put: + dma_buf_put(client_linux->dma_handler); +err_free: + nvgpu_kfree(g, client_linux); +err: + nvgpu_mutex_release(&ch->cs_client_mutex); + return ret; +} + +int gk20a_channel_free_cycle_stats_snapshot(struct channel_gk20a *ch) +{ + int ret; + struct gk20a_cs_snapshot_client_linux *client_linux; + + nvgpu_mutex_acquire(&ch->cs_client_mutex); + if (!ch->cs_client) { + nvgpu_mutex_release(&ch->cs_client_mutex); + return 0; + } + + client_linux = container_of(ch->cs_client, + struct gk20a_cs_snapshot_client_linux, + cs_client); + + ret = gr_gk20a_css_detach(ch, ch->cs_client); + + if (client_linux->dma_handler) { + if (ch->cs_client->snapshot) + dma_buf_vunmap(client_linux->dma_handler, + ch->cs_client->snapshot); + dma_buf_put(client_linux->dma_handler); + } + + ch->cs_client = NULL; + nvgpu_kfree(ch->g, client_linux); + + nvgpu_mutex_release(&ch->cs_client_mutex); + + return ret; +} +#endif + +static int gk20a_channel_set_wdt_status(struct channel_gk20a *ch, + struct nvgpu_channel_wdt_args *args) +{ + u32 status = args->wdt_status & (NVGPU_IOCTL_CHANNEL_DISABLE_WDT | + NVGPU_IOCTL_CHANNEL_ENABLE_WDT); + + if (status == NVGPU_IOCTL_CHANNEL_DISABLE_WDT) + ch->timeout.enabled = false; + else if (status == NVGPU_IOCTL_CHANNEL_ENABLE_WDT) + ch->timeout.enabled = true; + else + return -EINVAL; + + if (args->wdt_status & NVGPU_IOCTL_CHANNEL_WDT_FLAG_SET_TIMEOUT) + ch->timeout.limit_ms = args->timeout_ms; + + ch->timeout.debug_dump = (args->wdt_status & + NVGPU_IOCTL_CHANNEL_WDT_FLAG_DISABLE_DUMP) == 0; + + return 0; +} + +static void gk20a_channel_free_error_notifiers(struct channel_gk20a *ch) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + + nvgpu_mutex_acquire(&priv->error_notifier.mutex); + if (priv->error_notifier.dmabuf) { + dma_buf_vunmap(priv->error_notifier.dmabuf, priv->error_notifier.vaddr); + dma_buf_put(priv->error_notifier.dmabuf); + priv->error_notifier.dmabuf = NULL; + priv->error_notifier.notification = NULL; + priv->error_notifier.vaddr = NULL; + } + nvgpu_mutex_release(&priv->error_notifier.mutex); +} + +static int gk20a_init_error_notifier(struct channel_gk20a *ch, + struct nvgpu_set_error_notifier *args) +{ + struct dma_buf *dmabuf; + void *va; + u64 end = args->offset + sizeof(struct nvgpu_notification); + struct nvgpu_channel_linux *priv = ch->os_priv; + + if (!args->mem) { + pr_err("gk20a_init_error_notifier: invalid memory handle\n"); + return -EINVAL; + } + + dmabuf = dma_buf_get(args->mem); + + gk20a_channel_free_error_notifiers(ch); + + if (IS_ERR(dmabuf)) { + pr_err("Invalid handle: %d\n", args->mem); + return -EINVAL; + } + + if (end > dmabuf->size || end < sizeof(struct nvgpu_notification)) { + dma_buf_put(dmabuf); + nvgpu_err(ch->g, "gk20a_init_error_notifier: invalid offset"); + return -EINVAL; + } + + nvgpu_speculation_barrier(); + + /* map handle */ + va = dma_buf_vmap(dmabuf); + if (!va) { + dma_buf_put(dmabuf); + pr_err("Cannot map notifier handle\n"); + return -ENOMEM; + } + + priv->error_notifier.notification = va + args->offset; + priv->error_notifier.vaddr = va; + memset(priv->error_notifier.notification, 0, + sizeof(struct nvgpu_notification)); + + /* set channel notifiers pointer */ + nvgpu_mutex_acquire(&priv->error_notifier.mutex); + priv->error_notifier.dmabuf = dmabuf; + nvgpu_mutex_release(&priv->error_notifier.mutex); + + return 0; +} + +/* + * This returns the channel with a reference. The caller must + * gk20a_channel_put() the ref back after use. + * + * NULL is returned if the channel was not found. + */ +struct channel_gk20a *gk20a_get_channel_from_file(int fd) +{ + struct channel_gk20a *ch; + struct channel_priv *priv; + struct file *f = fget(fd); + + if (!f) + return NULL; + + if (f->f_op != &gk20a_channel_ops) { + fput(f); + return NULL; + } + + priv = (struct channel_priv *)f->private_data; + ch = gk20a_channel_get(priv->c); + fput(f); + return ch; +} + +int gk20a_channel_release(struct inode *inode, struct file *filp) +{ + struct channel_priv *priv = filp->private_data; + struct channel_gk20a *ch; + struct gk20a *g; + + int err; + + /* We could still end up here even if the channel_open failed, e.g. + * if we ran out of hw channel IDs. + */ + if (!priv) + return 0; + + ch = priv->c; + g = priv->g; + + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to release a channel!"); + goto channel_release; + } + + trace_gk20a_channel_release(dev_name(dev_from_gk20a(g))); + + gk20a_channel_close(ch); + gk20a_channel_free_error_notifiers(ch); + + gk20a_idle(g); + +channel_release: + gk20a_put(g); + nvgpu_kfree(g, filp->private_data); + filp->private_data = NULL; + return 0; +} + +/* note: runlist_id -1 is synonym for the ENGINE_GR_GK20A runlist id */ +static int __gk20a_channel_open(struct gk20a *g, + struct file *filp, s32 runlist_id) +{ + int err; + struct channel_gk20a *ch; + struct channel_priv *priv; + + nvgpu_log_fn(g, " "); + + g = gk20a_get(g); + if (!g) + return -ENODEV; + + trace_gk20a_channel_open(dev_name(dev_from_gk20a(g))); + + priv = nvgpu_kzalloc(g, sizeof(*priv)); + if (!priv) { + err = -ENOMEM; + goto free_ref; + } + + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to power on, %d", err); + goto fail_busy; + } + /* All the user space channel should be non privilege */ + ch = gk20a_open_new_channel(g, runlist_id, false, + nvgpu_current_pid(g), nvgpu_current_tid(g)); + gk20a_idle(g); + if (!ch) { + nvgpu_err(g, + "failed to get f"); + err = -ENOMEM; + goto fail_busy; + } + + gk20a_channel_trace_sched_param( + trace_gk20a_channel_sched_defaults, ch); + + priv->g = g; + priv->c = ch; + + filp->private_data = priv; + return 0; + +fail_busy: + nvgpu_kfree(g, priv); +free_ref: + gk20a_put(g); + return err; +} + +int gk20a_channel_open(struct inode *inode, struct file *filp) +{ + struct nvgpu_os_linux *l = container_of(inode->i_cdev, + struct nvgpu_os_linux, channel.cdev); + struct gk20a *g = &l->g; + int ret; + + nvgpu_log_fn(g, "start"); + ret = __gk20a_channel_open(g, filp, -1); + + nvgpu_log_fn(g, "end"); + return ret; +} + +int gk20a_channel_open_ioctl(struct gk20a *g, + struct nvgpu_channel_open_args *args) +{ + int err; + int fd; + struct file *file; + char name[64]; + s32 runlist_id = args->in.runlist_id; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + err = get_unused_fd_flags(O_RDWR); + if (err < 0) + return err; + fd = err; + + snprintf(name, sizeof(name), "nvhost-%s-fd%d", + dev_name(dev_from_gk20a(g)), fd); + + file = anon_inode_getfile(name, l->channel.cdev.ops, NULL, O_RDWR); + if (IS_ERR(file)) { + err = PTR_ERR(file); + goto clean_up; + } + + err = __gk20a_channel_open(g, file, runlist_id); + if (err) + goto clean_up_file; + + fd_install(fd, file); + args->out.channel_fd = fd; + return 0; + +clean_up_file: + fput(file); +clean_up: + put_unused_fd(fd); + return err; +} + +static u32 nvgpu_setup_bind_user_flags_to_common_flags(u32 user_flags) +{ + u32 flags = 0; + + if (user_flags & NVGPU_CHANNEL_SETUP_BIND_FLAGS_VPR_ENABLED) + flags |= NVGPU_SETUP_BIND_FLAGS_SUPPORT_VPR; + + if (user_flags & NVGPU_CHANNEL_SETUP_BIND_FLAGS_DETERMINISTIC) + flags |= NVGPU_SETUP_BIND_FLAGS_SUPPORT_DETERMINISTIC; + + if (user_flags & NVGPU_CHANNEL_SETUP_BIND_FLAGS_REPLAYABLE_FAULTS_ENABLE) + flags |= NVGPU_SETUP_BIND_FLAGS_REPLAYABLE_FAULTS_ENABLE; + + if (user_flags & NVGPU_CHANNEL_SETUP_BIND_FLAGS_USERMODE_SUPPORT) + flags |= NVGPU_SETUP_BIND_FLAGS_USERMODE_SUPPORT; + + return flags; +} + +static void nvgpu_get_setup_bind_args( + struct nvgpu_channel_setup_bind_args *channel_setup_bind_args, + struct nvgpu_setup_bind_args *setup_bind_args) +{ + setup_bind_args->num_gpfifo_entries = + channel_setup_bind_args->num_gpfifo_entries; + setup_bind_args->num_inflight_jobs = + channel_setup_bind_args->num_inflight_jobs; + setup_bind_args->userd_dmabuf_fd = + channel_setup_bind_args->userd_dmabuf_fd; + setup_bind_args->userd_dmabuf_offset = + channel_setup_bind_args->userd_dmabuf_offset; + setup_bind_args->gpfifo_dmabuf_fd = + channel_setup_bind_args->gpfifo_dmabuf_fd; + setup_bind_args->gpfifo_dmabuf_offset = + channel_setup_bind_args->gpfifo_dmabuf_offset; + setup_bind_args->flags = nvgpu_setup_bind_user_flags_to_common_flags( + channel_setup_bind_args->flags); +} + +static void nvgpu_get_gpfifo_ex_args( + struct nvgpu_alloc_gpfifo_ex_args *alloc_gpfifo_ex_args, + struct nvgpu_setup_bind_args *setup_bind_args) +{ + setup_bind_args->num_gpfifo_entries = alloc_gpfifo_ex_args->num_entries; + setup_bind_args->num_inflight_jobs = + alloc_gpfifo_ex_args->num_inflight_jobs; + setup_bind_args->flags = nvgpu_setup_bind_user_flags_to_common_flags( + alloc_gpfifo_ex_args->flags); +} + +static void nvgpu_get_gpfifo_args( + struct nvgpu_alloc_gpfifo_args *alloc_gpfifo_args, + struct nvgpu_setup_bind_args *setup_bind_args) +{ + /* + * Kernel can insert one extra gpfifo entry before user + * submitted gpfifos and another one after, for internal usage. + * Triple the requested size. + */ + setup_bind_args->num_gpfifo_entries = + alloc_gpfifo_args->num_entries * 3; + setup_bind_args->num_inflight_jobs = 0; + setup_bind_args->flags = nvgpu_setup_bind_user_flags_to_common_flags( + alloc_gpfifo_args->flags); +} + +static void nvgpu_get_fence_args( + struct nvgpu_fence *fence_args_in, + struct nvgpu_channel_fence *fence_args_out) +{ + fence_args_out->id = fence_args_in->id; + fence_args_out->value = fence_args_in->value; +} + +static int gk20a_channel_wait_semaphore(struct channel_gk20a *ch, + ulong id, u32 offset, + u32 payload, u32 timeout) +{ + struct dma_buf *dmabuf; + void *data; + u32 *semaphore; + int ret = 0; + + /* do not wait if channel has timed out */ + if (gk20a_channel_check_timedout(ch)) { + return -ETIMEDOUT; + } + + dmabuf = dma_buf_get(id); + if (IS_ERR(dmabuf)) { + nvgpu_err(ch->g, "invalid notifier nvmap handle 0x%lx", id); + return -EINVAL; + } + + data = dma_buf_kmap(dmabuf, offset >> PAGE_SHIFT); + if (!data) { + nvgpu_err(ch->g, "failed to map notifier memory"); + ret = -EINVAL; + goto cleanup_put; + } + + semaphore = data + (offset & ~PAGE_MASK); + + ret = NVGPU_COND_WAIT_INTERRUPTIBLE( + &ch->semaphore_wq, + *semaphore == payload || + gk20a_channel_check_timedout(ch), + timeout); + + dma_buf_kunmap(dmabuf, offset >> PAGE_SHIFT, data); +cleanup_put: + dma_buf_put(dmabuf); + return ret; +} + +static int gk20a_channel_wait(struct channel_gk20a *ch, + struct nvgpu_wait_args *args) +{ + struct dma_buf *dmabuf; + struct gk20a *g = ch->g; + struct notification *notif; + struct timespec tv; + u64 jiffies; + ulong id; + u32 offset; + int remain, ret = 0; + u64 end; + + nvgpu_log_fn(g, " "); + + if (gk20a_channel_check_timedout(ch)) { + return -ETIMEDOUT; + } + + switch (args->type) { + case NVGPU_WAIT_TYPE_NOTIFIER: + id = args->condition.notifier.dmabuf_fd; + offset = args->condition.notifier.offset; + end = offset + sizeof(struct notification); + + dmabuf = dma_buf_get(id); + if (IS_ERR(dmabuf)) { + nvgpu_err(g, "invalid notifier nvmap handle 0x%lx", + id); + return -EINVAL; + } + + if (end > dmabuf->size || end < sizeof(struct notification)) { + dma_buf_put(dmabuf); + nvgpu_err(g, "invalid notifier offset"); + return -EINVAL; + } + + nvgpu_speculation_barrier(); + + notif = dma_buf_vmap(dmabuf); + if (!notif) { + nvgpu_err(g, "failed to map notifier memory"); + return -ENOMEM; + } + + notif = (struct notification *)((uintptr_t)notif + offset); + + /* user should set status pending before + * calling this ioctl */ + remain = NVGPU_COND_WAIT_INTERRUPTIBLE( + &ch->notifier_wq, + notif->status == 0 || + gk20a_channel_check_timedout(ch), + args->timeout); + + if (remain == 0 && notif->status != 0) { + ret = -ETIMEDOUT; + goto notif_clean_up; + } else if (remain < 0) { + ret = -EINTR; + goto notif_clean_up; + } + + /* TBD: fill in correct information */ + jiffies = get_jiffies_64(); + jiffies_to_timespec(jiffies, &tv); + notif->timestamp.nanoseconds[0] = tv.tv_nsec; + notif->timestamp.nanoseconds[1] = tv.tv_sec; + notif->info32 = 0xDEADBEEF; /* should be object name */ + notif->info16 = ch->chid; /* should be method offset */ + +notif_clean_up: + dma_buf_vunmap(dmabuf, notif); + return ret; + + case NVGPU_WAIT_TYPE_SEMAPHORE: + ret = gk20a_channel_wait_semaphore(ch, + args->condition.semaphore.dmabuf_fd, + args->condition.semaphore.offset, + args->condition.semaphore.payload, + args->timeout); + + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int gk20a_channel_zcull_bind(struct channel_gk20a *ch, + struct nvgpu_zcull_bind_args *args) +{ + struct gk20a *g = ch->g; + struct gr_gk20a *gr = &g->gr; + + nvgpu_log_fn(gr->g, " "); + + return g->ops.gr.bind_ctxsw_zcull(g, gr, ch, + args->gpu_va, args->mode); +} + +static int gk20a_ioctl_channel_submit_gpfifo( + struct channel_gk20a *ch, + struct nvgpu_submit_gpfifo_args *args) +{ + struct nvgpu_channel_fence fence; + struct gk20a_fence *fence_out; + struct fifo_profile_gk20a *profile = NULL; + u32 submit_flags = 0; + int fd = -1; + struct gk20a *g = ch->g; + struct nvgpu_gpfifo_userdata userdata; + + int ret = 0; + nvgpu_log_fn(g, " "); + + profile = gk20a_fifo_profile_acquire(ch->g); + gk20a_fifo_profile_snapshot(profile, PROFILE_IOCTL_ENTRY); + + if (gk20a_channel_check_timedout(ch)) { + return -ETIMEDOUT; + } + + nvgpu_get_fence_args(&args->fence, &fence); + submit_flags = + nvgpu_submit_gpfifo_user_flags_to_common_flags(args->flags); + + /* Try and allocate an fd here*/ + if ((args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET) + && (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE)) { + fd = get_unused_fd_flags(O_RDWR); + if (fd < 0) + return fd; + } + + userdata.entries = (struct nvgpu_gpfifo_entry __user *) + (uintptr_t)args->gpfifo; + userdata.context = NULL; + + ret = nvgpu_submit_channel_gpfifo_user(ch, + userdata, args->num_entries, + submit_flags, &fence, &fence_out, profile); + + if (ret) { + if (fd != -1) + put_unused_fd(fd); + goto clean_up; + } + + /* Convert fence_out to something we can pass back to user space. */ + if (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET) { + if (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE) { + ret = gk20a_fence_install_fd(fence_out, fd); + if (ret) + put_unused_fd(fd); + else + args->fence.id = fd; + } else { + args->fence.id = fence_out->syncpt_id; + args->fence.value = fence_out->syncpt_value; + } + } + gk20a_fence_put(fence_out); + + gk20a_fifo_profile_snapshot(profile, PROFILE_IOCTL_EXIT); + if (profile) + gk20a_fifo_profile_release(ch->g, profile); + +clean_up: + return ret; +} + +/* + * Convert linux specific runlist level of the form NVGPU_RUNLIST_INTERLEAVE_LEVEL_* + * to common runlist level of the form NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_* + */ +u32 nvgpu_get_common_runlist_level(u32 level) +{ + nvgpu_speculation_barrier(); + switch (level) { + case NVGPU_RUNLIST_INTERLEAVE_LEVEL_LOW: + return NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_LOW; + case NVGPU_RUNLIST_INTERLEAVE_LEVEL_MEDIUM: + return NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_MEDIUM; + case NVGPU_RUNLIST_INTERLEAVE_LEVEL_HIGH: + return NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_HIGH; + default: + pr_err("%s: incorrect runlist level\n", __func__); + } + + return level; +} + +static u32 nvgpu_obj_ctx_user_flags_to_common_flags(u32 user_flags) +{ + u32 flags = 0; + + if (user_flags & NVGPU_ALLOC_OBJ_FLAGS_GFXP) + flags |= NVGPU_OBJ_CTX_FLAGS_SUPPORT_GFXP; + + if (user_flags & NVGPU_ALLOC_OBJ_FLAGS_CILP) + flags |= NVGPU_OBJ_CTX_FLAGS_SUPPORT_CILP; + + return flags; +} + +static int nvgpu_ioctl_channel_alloc_obj_ctx(struct channel_gk20a *ch, + u32 class_num, u32 user_flags) +{ + return ch->g->ops.gr.alloc_obj_ctx(ch, class_num, + nvgpu_obj_ctx_user_flags_to_common_flags(user_flags)); +} + +/* + * Convert common preemption mode flags of the form NVGPU_PREEMPTION_MODE_GRAPHICS_* + * into linux preemption mode flags of the form NVGPU_GRAPHICS_PREEMPTION_MODE_* + */ +u32 nvgpu_get_ioctl_graphics_preempt_mode_flags(u32 graphics_preempt_mode_flags) +{ + u32 flags = 0; + + if (graphics_preempt_mode_flags & NVGPU_PREEMPTION_MODE_GRAPHICS_WFI) + flags |= NVGPU_GRAPHICS_PREEMPTION_MODE_WFI; + if (graphics_preempt_mode_flags & NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP) + flags |= NVGPU_GRAPHICS_PREEMPTION_MODE_GFXP; + + return flags; +} + +/* + * Convert common preemption mode flags of the form NVGPU_PREEMPTION_MODE_COMPUTE_* + * into linux preemption mode flags of the form NVGPU_COMPUTE_PREEMPTION_MODE_* + */ +u32 nvgpu_get_ioctl_compute_preempt_mode_flags(u32 compute_preempt_mode_flags) +{ + u32 flags = 0; + + if (compute_preempt_mode_flags & NVGPU_PREEMPTION_MODE_COMPUTE_WFI) + flags |= NVGPU_COMPUTE_PREEMPTION_MODE_WFI; + if (compute_preempt_mode_flags & NVGPU_PREEMPTION_MODE_COMPUTE_CTA) + flags |= NVGPU_COMPUTE_PREEMPTION_MODE_CTA; + if (compute_preempt_mode_flags & NVGPU_PREEMPTION_MODE_COMPUTE_CILP) + flags |= NVGPU_COMPUTE_PREEMPTION_MODE_CILP; + + return flags; +} + +/* + * Convert common preemption modes of the form NVGPU_PREEMPTION_MODE_GRAPHICS_* + * into linux preemption modes of the form NVGPU_GRAPHICS_PREEMPTION_MODE_* + */ +u32 nvgpu_get_ioctl_graphics_preempt_mode(u32 graphics_preempt_mode) +{ + switch (graphics_preempt_mode) { + case NVGPU_PREEMPTION_MODE_GRAPHICS_WFI: + return NVGPU_GRAPHICS_PREEMPTION_MODE_WFI; + case NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP: + return NVGPU_GRAPHICS_PREEMPTION_MODE_GFXP; + } + + return graphics_preempt_mode; +} + +/* + * Convert common preemption modes of the form NVGPU_PREEMPTION_MODE_COMPUTE_* + * into linux preemption modes of the form NVGPU_COMPUTE_PREEMPTION_MODE_* + */ +u32 nvgpu_get_ioctl_compute_preempt_mode(u32 compute_preempt_mode) +{ + switch (compute_preempt_mode) { + case NVGPU_PREEMPTION_MODE_COMPUTE_WFI: + return NVGPU_COMPUTE_PREEMPTION_MODE_WFI; + case NVGPU_PREEMPTION_MODE_COMPUTE_CTA: + return NVGPU_COMPUTE_PREEMPTION_MODE_CTA; + case NVGPU_PREEMPTION_MODE_COMPUTE_CILP: + return NVGPU_COMPUTE_PREEMPTION_MODE_CILP; + } + + return compute_preempt_mode; +} + +/* + * Convert linux preemption modes of the form NVGPU_GRAPHICS_PREEMPTION_MODE_* + * into common preemption modes of the form NVGPU_PREEMPTION_MODE_GRAPHICS_* + */ +static u32 nvgpu_get_common_graphics_preempt_mode(u32 graphics_preempt_mode) +{ + nvgpu_speculation_barrier(); + switch (graphics_preempt_mode) { + case NVGPU_GRAPHICS_PREEMPTION_MODE_WFI: + return NVGPU_PREEMPTION_MODE_GRAPHICS_WFI; + case NVGPU_GRAPHICS_PREEMPTION_MODE_GFXP: + return NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP; + } + + return graphics_preempt_mode; +} + +/* + * Convert linux preemption modes of the form NVGPU_COMPUTE_PREEMPTION_MODE_* + * into common preemption modes of the form NVGPU_PREEMPTION_MODE_COMPUTE_* + */ +static u32 nvgpu_get_common_compute_preempt_mode(u32 compute_preempt_mode) +{ + nvgpu_speculation_barrier(); + switch (compute_preempt_mode) { + case NVGPU_COMPUTE_PREEMPTION_MODE_WFI: + return NVGPU_PREEMPTION_MODE_COMPUTE_WFI; + case NVGPU_COMPUTE_PREEMPTION_MODE_CTA: + return NVGPU_PREEMPTION_MODE_COMPUTE_CTA; + case NVGPU_COMPUTE_PREEMPTION_MODE_CILP: + return NVGPU_PREEMPTION_MODE_COMPUTE_CILP; + } + + return compute_preempt_mode; +} + +static int nvgpu_ioctl_channel_set_preemption_mode(struct channel_gk20a *ch, + u32 graphics_preempt_mode, u32 compute_preempt_mode) +{ + int err; + + if (ch->g->ops.gr.set_preemption_mode) { + err = gk20a_busy(ch->g); + if (err) { + nvgpu_err(ch->g, "failed to power on, %d", err); + return err; + } + err = ch->g->ops.gr.set_preemption_mode(ch, + nvgpu_get_common_graphics_preempt_mode(graphics_preempt_mode), + nvgpu_get_common_compute_preempt_mode(compute_preempt_mode)); + gk20a_idle(ch->g); + } else { + err = -EINVAL; + } + + return err; +} + +static int nvgpu_ioctl_channel_get_user_syncpoint(struct channel_gk20a *ch, + struct nvgpu_get_user_syncpoint_args *args) +{ +#ifdef CONFIG_TEGRA_GK20A_NVHOST + struct gk20a *g = ch->g; + int err; + + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_USER_SYNCPOINT)) { + nvgpu_err(g, "user syncpoints not supported"); + return -EINVAL; + } + + if (!nvgpu_has_syncpoints(g)) { + nvgpu_err(g, "syncpoints not supported"); + return -EINVAL; + } + + if (g->aggressive_sync_destroy_thresh) { + nvgpu_err(g, "sufficient syncpoints not available"); + return -EINVAL; + } + + nvgpu_mutex_acquire(&ch->sync_lock); + if (ch->user_sync) { + nvgpu_mutex_release(&ch->sync_lock); + } else { + ch->user_sync = nvgpu_channel_sync_create(ch, true); + if (!ch->user_sync) { + nvgpu_mutex_release(&ch->sync_lock); + return -ENOMEM; + } + nvgpu_mutex_release(&ch->sync_lock); + + if (g->ops.fifo.resetup_ramfc) { + err = g->ops.fifo.resetup_ramfc(ch); + if (err) + return err; + } + } + + args->syncpoint_id = ch->user_sync->syncpt_id(ch->user_sync); + args->syncpoint_max = nvgpu_nvhost_syncpt_read_maxval(g->nvhost_dev, + args->syncpoint_id); + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SYNCPOINT_ADDRESS)) + args->gpu_va = ch->user_sync->syncpt_address(ch->user_sync); + else + args->gpu_va = 0; + + return 0; +#else + return -EINVAL; +#endif +} + +long gk20a_channel_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct channel_priv *priv = filp->private_data; + struct channel_gk20a *ch = priv->c; + struct device *dev = dev_from_gk20a(ch->g); + u8 buf[NVGPU_IOCTL_CHANNEL_MAX_ARG_SIZE] = {0}; + int err = 0; + struct gk20a *g = ch->g; + + nvgpu_log_fn(g, "start %d", _IOC_NR(cmd)); + + if ((_IOC_TYPE(cmd) != NVGPU_IOCTL_MAGIC) || + (_IOC_NR(cmd) == 0) || + (_IOC_NR(cmd) > NVGPU_IOCTL_CHANNEL_LAST) || + (_IOC_SIZE(cmd) > NVGPU_IOCTL_CHANNEL_MAX_ARG_SIZE)) + return -EINVAL; + + if (_IOC_DIR(cmd) & _IOC_WRITE) { + if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + } + + /* take a ref or return timeout if channel refs can't be taken */ + ch = gk20a_channel_get(ch); + if (!ch) + return -ETIMEDOUT; + + /* protect our sanity for threaded userspace - most of the channel is + * not thread safe */ + nvgpu_mutex_acquire(&ch->ioctl_lock); + + /* this ioctl call keeps a ref to the file which keeps a ref to the + * channel */ + + nvgpu_speculation_barrier(); + switch (cmd) { + case NVGPU_IOCTL_CHANNEL_OPEN: + err = gk20a_channel_open_ioctl(ch->g, + (struct nvgpu_channel_open_args *)buf); + break; + case NVGPU_IOCTL_CHANNEL_SET_NVMAP_FD: + break; + case NVGPU_IOCTL_CHANNEL_ALLOC_OBJ_CTX: + { + struct nvgpu_alloc_obj_ctx_args *args = + (struct nvgpu_alloc_obj_ctx_args *)buf; + + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + err = nvgpu_ioctl_channel_alloc_obj_ctx(ch, args->class_num, args->flags); + gk20a_idle(ch->g); + break; + } + case NVGPU_IOCTL_CHANNEL_SETUP_BIND: + { + struct nvgpu_channel_setup_bind_args *channel_setup_bind_args = + (struct nvgpu_channel_setup_bind_args *)buf; + struct nvgpu_setup_bind_args setup_bind_args; + + nvgpu_get_setup_bind_args(channel_setup_bind_args, + &setup_bind_args); + + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + + if (!is_power_of_2(setup_bind_args.num_gpfifo_entries)) { + err = -EINVAL; + gk20a_idle(ch->g); + break; + } + err = nvgpu_channel_setup_bind(ch, &setup_bind_args); + channel_setup_bind_args->work_submit_token = + setup_bind_args.work_submit_token; + gk20a_idle(ch->g); + break; + } + case NVGPU_IOCTL_CHANNEL_ALLOC_GPFIFO_EX: + { + struct nvgpu_alloc_gpfifo_ex_args *alloc_gpfifo_ex_args = + (struct nvgpu_alloc_gpfifo_ex_args *)buf; + struct nvgpu_setup_bind_args setup_bind_args; + + nvgpu_get_gpfifo_ex_args(alloc_gpfifo_ex_args, &setup_bind_args); + + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + + if (!is_power_of_2(alloc_gpfifo_ex_args->num_entries)) { + err = -EINVAL; + gk20a_idle(ch->g); + break; + } + err = nvgpu_channel_setup_bind(ch, &setup_bind_args); + gk20a_idle(ch->g); + break; + } + case NVGPU_IOCTL_CHANNEL_ALLOC_GPFIFO: + { + struct nvgpu_alloc_gpfifo_args *alloc_gpfifo_args = + (struct nvgpu_alloc_gpfifo_args *)buf; + struct nvgpu_setup_bind_args setup_bind_args; + + nvgpu_get_gpfifo_args(alloc_gpfifo_args, &setup_bind_args); + + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + + err = nvgpu_channel_setup_bind(ch, &setup_bind_args); + gk20a_idle(ch->g); + break; + } + case NVGPU_IOCTL_CHANNEL_SUBMIT_GPFIFO: + err = gk20a_ioctl_channel_submit_gpfifo(ch, + (struct nvgpu_submit_gpfifo_args *)buf); + break; + case NVGPU_IOCTL_CHANNEL_WAIT: + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + + /* waiting is thread-safe, not dropping this mutex could + * deadlock in certain conditions */ + nvgpu_mutex_release(&ch->ioctl_lock); + + err = gk20a_channel_wait(ch, + (struct nvgpu_wait_args *)buf); + + nvgpu_mutex_acquire(&ch->ioctl_lock); + + gk20a_idle(ch->g); + break; + case NVGPU_IOCTL_CHANNEL_ZCULL_BIND: + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + err = gk20a_channel_zcull_bind(ch, + (struct nvgpu_zcull_bind_args *)buf); + gk20a_idle(ch->g); + break; + case NVGPU_IOCTL_CHANNEL_SET_ERROR_NOTIFIER: + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + err = gk20a_init_error_notifier(ch, + (struct nvgpu_set_error_notifier *)buf); + gk20a_idle(ch->g); + break; + case NVGPU_IOCTL_CHANNEL_SET_TIMEOUT: + { + u32 timeout = + (u32)((struct nvgpu_set_timeout_args *)buf)->timeout; + nvgpu_log(g, gpu_dbg_gpu_dbg, "setting timeout (%d ms) for chid %d", + timeout, ch->chid); + ch->timeout_ms_max = timeout; + gk20a_channel_trace_sched_param( + trace_gk20a_channel_set_timeout, ch); + break; + } + case NVGPU_IOCTL_CHANNEL_SET_TIMEOUT_EX: + { + u32 timeout = + (u32)((struct nvgpu_set_timeout_args *)buf)->timeout; + bool timeout_debug_dump = !((u32) + ((struct nvgpu_set_timeout_ex_args *)buf)->flags & + (1 << NVGPU_TIMEOUT_FLAG_DISABLE_DUMP)); + nvgpu_log(g, gpu_dbg_gpu_dbg, "setting timeout (%d ms) for chid %d", + timeout, ch->chid); + ch->timeout_ms_max = timeout; + ch->timeout_debug_dump = timeout_debug_dump; + gk20a_channel_trace_sched_param( + trace_gk20a_channel_set_timeout, ch); + break; + } + case NVGPU_IOCTL_CHANNEL_GET_TIMEDOUT: + ((struct nvgpu_get_param_args *)buf)->value = + gk20a_channel_check_timedout(ch); + break; + case NVGPU_IOCTL_CHANNEL_ENABLE: + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + if (ch->g->ops.fifo.enable_channel) + ch->g->ops.fifo.enable_channel(ch); + else + err = -ENOSYS; + gk20a_idle(ch->g); + break; + case NVGPU_IOCTL_CHANNEL_DISABLE: + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + if (ch->g->ops.fifo.disable_channel) + ch->g->ops.fifo.disable_channel(ch); + else + err = -ENOSYS; + gk20a_idle(ch->g); + break; + case NVGPU_IOCTL_CHANNEL_PREEMPT: + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + err = gk20a_fifo_preempt(ch->g, ch); + gk20a_idle(ch->g); + break; + case NVGPU_IOCTL_CHANNEL_RESCHEDULE_RUNLIST: + if (!capable(CAP_SYS_NICE)) { + err = -EPERM; + break; + } + if (!ch->g->ops.fifo.reschedule_runlist) { + err = -ENOSYS; + break; + } + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + err = ch->g->ops.fifo.reschedule_runlist(ch, + NVGPU_RESCHEDULE_RUNLIST_PREEMPT_NEXT & + ((struct nvgpu_reschedule_runlist_args *)buf)->flags); + gk20a_idle(ch->g); + break; + case NVGPU_IOCTL_CHANNEL_FORCE_RESET: + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + err = ch->g->ops.fifo.force_reset_ch(ch, + NVGPU_ERR_NOTIFIER_RESETCHANNEL_VERIF_ERROR, true); + gk20a_idle(ch->g); + break; + case NVGPU_IOCTL_CHANNEL_WDT: + err = gk20a_channel_set_wdt_status(ch, + (struct nvgpu_channel_wdt_args *)buf); + break; + case NVGPU_IOCTL_CHANNEL_SET_PREEMPTION_MODE: + err = nvgpu_ioctl_channel_set_preemption_mode(ch, + ((struct nvgpu_preemption_mode_args *)buf)->graphics_preempt_mode, + ((struct nvgpu_preemption_mode_args *)buf)->compute_preempt_mode); + break; + case NVGPU_IOCTL_CHANNEL_SET_BOOSTED_CTX: + if (ch->g->ops.gr.set_boosted_ctx) { + bool boost = + ((struct nvgpu_boosted_ctx_args *)buf)->boost; + + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + err = ch->g->ops.gr.set_boosted_ctx(ch, boost); + gk20a_idle(ch->g); + } else { + err = -EINVAL; + } + break; + case NVGPU_IOCTL_CHANNEL_GET_USER_SYNCPOINT: + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + err = nvgpu_ioctl_channel_get_user_syncpoint(ch, + (struct nvgpu_get_user_syncpoint_args *)buf); + gk20a_idle(ch->g); + break; + default: + dev_dbg(dev, "unrecognized ioctl cmd: 0x%x", cmd); + err = -ENOTTY; + break; + } + + if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ)) + err = copy_to_user((void __user *)arg, buf, _IOC_SIZE(cmd)); + + nvgpu_mutex_release(&ch->ioctl_lock); + + gk20a_channel_put(ch); + + nvgpu_log_fn(g, "end"); + + return err; +} diff --git a/include/os/linux/ioctl_channel.h b/include/os/linux/ioctl_channel.h new file mode 100644 index 0000000..3e80289 --- /dev/null +++ b/include/os/linux/ioctl_channel.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#ifndef __NVGPU_IOCTL_CHANNEL_H__ +#define __NVGPU_IOCTL_CHANNEL_H__ + +#include + +#include "gk20a/css_gr_gk20a.h" + +struct inode; +struct file; +struct gk20a; +struct nvgpu_channel_open_args; + +struct gk20a_cs_snapshot_client_linux { + struct gk20a_cs_snapshot_client cs_client; + + u32 dmabuf_fd; + struct dma_buf *dma_handler; +}; + +int gk20a_channel_open(struct inode *inode, struct file *filp); +int gk20a_channel_release(struct inode *inode, struct file *filp); +long gk20a_channel_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg); +int gk20a_channel_open_ioctl(struct gk20a *g, + struct nvgpu_channel_open_args *args); + +int gk20a_channel_cycle_stats(struct channel_gk20a *ch, int dmabuf_fd); +void gk20a_channel_free_cycle_stats_buffer(struct channel_gk20a *ch); + +int gk20a_attach_cycle_stats_snapshot(struct channel_gk20a *ch, + u32 dmabuf_fd, + u32 perfmon_id_count, + u32 *perfmon_id_start); +int gk20a_flush_cycle_stats_snapshot(struct channel_gk20a *ch); +int gk20a_channel_free_cycle_stats_snapshot(struct channel_gk20a *ch); + +extern const struct file_operations gk20a_channel_ops; + +u32 nvgpu_get_common_runlist_level(u32 level); + +u32 nvgpu_get_ioctl_graphics_preempt_mode_flags(u32 graphics_preempt_mode_flags); +u32 nvgpu_get_ioctl_compute_preempt_mode_flags(u32 compute_preempt_mode_flags); +u32 nvgpu_get_ioctl_graphics_preempt_mode(u32 graphics_preempt_mode); +u32 nvgpu_get_ioctl_compute_preempt_mode(u32 compute_preempt_mode); +#endif diff --git a/include/os/linux/ioctl_clk_arb.c b/include/os/linux/ioctl_clk_arb.c new file mode 100644 index 0000000..477222d --- /dev/null +++ b/include/os/linux/ioctl_clk_arb.c @@ -0,0 +1,574 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#ifdef CONFIG_DEBUG_FS +#include +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk/clk.h" +#include "pstate/pstate.h" +#include "lpwr/lpwr.h" +#include "volt/volt.h" + +#ifdef CONFIG_DEBUG_FS +#include "os_linux.h" +#endif + +static int nvgpu_clk_arb_release_completion_dev(struct inode *inode, + struct file *filp) +{ + struct nvgpu_clk_dev *dev = filp->private_data; + struct nvgpu_clk_session *session = dev->session; + + + clk_arb_dbg(session->g, " "); + + /* This is done to account for the extra refcount taken in + * nvgpu_clk_arb_commit_request_fd without events support in iGPU + */ + if (!session->g->clk_arb->clk_arb_events_supported) { + nvgpu_ref_put(&dev->refcount, nvgpu_clk_arb_free_fd); + } + + nvgpu_ref_put(&session->refcount, nvgpu_clk_arb_free_session); + nvgpu_ref_put(&dev->refcount, nvgpu_clk_arb_free_fd); + return 0; +} + +static inline unsigned int nvgpu_convert_poll_mask(unsigned int nvgpu_poll_mask) +{ + unsigned int poll_mask = 0; + + if (nvgpu_poll_mask & NVGPU_POLLIN) + poll_mask |= POLLIN; + if (nvgpu_poll_mask & NVGPU_POLLPRI) + poll_mask |= POLLPRI; + if (nvgpu_poll_mask & NVGPU_POLLOUT) + poll_mask |= POLLOUT; + if (nvgpu_poll_mask & NVGPU_POLLRDNORM) + poll_mask |= POLLRDNORM; + if (nvgpu_poll_mask & NVGPU_POLLHUP) + poll_mask |= POLLHUP; + + return poll_mask; +} + +static unsigned int nvgpu_clk_arb_poll_dev(struct file *filp, poll_table *wait) +{ + struct nvgpu_clk_dev *dev = filp->private_data; + + clk_arb_dbg(dev->session->g, " "); + + poll_wait(filp, &dev->readout_wq.wq, wait); + return nvgpu_convert_poll_mask(nvgpu_atomic_xchg(&dev->poll_mask, 0)); +} + +void nvgpu_clk_arb_event_post_event(struct nvgpu_clk_dev *dev) +{ + nvgpu_cond_broadcast_interruptible(&dev->readout_wq); +} + +static int nvgpu_clk_arb_release_event_dev(struct inode *inode, + struct file *filp) +{ + struct nvgpu_clk_dev *dev = filp->private_data; + struct nvgpu_clk_session *session = dev->session; + struct nvgpu_clk_arb *arb; + + arb = session->g->clk_arb; + + clk_arb_dbg(session->g, " "); + + if (arb) { + nvgpu_spinlock_acquire(&arb->users_lock); + nvgpu_list_del(&dev->link); + nvgpu_spinlock_release(&arb->users_lock); + nvgpu_clk_notification_queue_free(arb->g, &dev->queue); + } + + nvgpu_ref_put(&session->refcount, nvgpu_clk_arb_free_session); + nvgpu_ref_put(&dev->refcount, nvgpu_clk_arb_free_fd); + + return 0; +} + +static inline u32 nvgpu_convert_gpu_event(u32 nvgpu_event) +{ + u32 nvgpu_gpu_event; + + switch (nvgpu_event) { + case NVGPU_EVENT_VF_UPDATE: + nvgpu_gpu_event = NVGPU_GPU_EVENT_VF_UPDATE; + break; + case NVGPU_EVENT_ALARM_TARGET_VF_NOT_POSSIBLE: + nvgpu_gpu_event = NVGPU_GPU_EVENT_ALARM_TARGET_VF_NOT_POSSIBLE; + break; + case NVGPU_EVENT_ALARM_LOCAL_TARGET_VF_NOT_POSSIBLE: + nvgpu_gpu_event = NVGPU_GPU_EVENT_ALARM_LOCAL_TARGET_VF_NOT_POSSIBLE; + break; + case NVGPU_EVENT_ALARM_CLOCK_ARBITER_FAILED: + nvgpu_gpu_event = NVGPU_GPU_EVENT_ALARM_CLOCK_ARBITER_FAILED; + break; + case NVGPU_EVENT_ALARM_VF_TABLE_UPDATE_FAILED: + nvgpu_gpu_event = NVGPU_GPU_EVENT_ALARM_VF_TABLE_UPDATE_FAILED; + break; + case NVGPU_EVENT_ALARM_THERMAL_ABOVE_THRESHOLD: + nvgpu_gpu_event = NVGPU_GPU_EVENT_ALARM_THERMAL_ABOVE_THRESHOLD; + break; + case NVGPU_EVENT_ALARM_POWER_ABOVE_THRESHOLD: + nvgpu_gpu_event = NVGPU_GPU_EVENT_ALARM_POWER_ABOVE_THRESHOLD; + break; + case NVGPU_EVENT_ALARM_GPU_LOST: + nvgpu_gpu_event = NVGPU_GPU_EVENT_ALARM_GPU_LOST; + break; + default: + /* Control shouldn't come here */ + nvgpu_gpu_event = NVGPU_GPU_EVENT_ALARM_GPU_LOST + 1; + break; + } + return nvgpu_gpu_event; +} + +static inline u32 __pending_event(struct nvgpu_clk_dev *dev, + struct nvgpu_gpu_event_info *info) { + + u32 tail, head; + u32 events = 0; + struct nvgpu_clk_notification *p_notif; + + tail = nvgpu_atomic_read(&dev->queue.tail); + head = nvgpu_atomic_read(&dev->queue.head); + + head = (tail - head) < dev->queue.size ? head : tail - dev->queue.size; + + if (_WRAPGTEQ(tail, head) && info) { + head++; + p_notif = &dev->queue.notifications[head % dev->queue.size]; + events |= nvgpu_convert_gpu_event(p_notif->notification); + info->event_id = ffs(events) - 1; + info->timestamp = p_notif->timestamp; + nvgpu_atomic_set(&dev->queue.head, head); + } + + return events; +} + +static ssize_t nvgpu_clk_arb_read_event_dev(struct file *filp, char __user *buf, + size_t size, loff_t *off) +{ + struct nvgpu_clk_dev *dev = filp->private_data; + struct nvgpu_gpu_event_info info; + ssize_t err; + + clk_arb_dbg(dev->session->g, + "filp=%p, buf=%p, size=%zu", filp, buf, size); + + if ((size - *off) < sizeof(info)) + return 0; + + memset(&info, 0, sizeof(info)); + /* Get the oldest event from the queue */ + while (!__pending_event(dev, &info)) { + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + err = NVGPU_COND_WAIT_INTERRUPTIBLE(&dev->readout_wq, + __pending_event(dev, &info), 0); + if (err) + return err; + if (info.timestamp) + break; + } + + if (copy_to_user(buf + *off, &info, sizeof(info))) + return -EFAULT; + + return sizeof(info); +} + +static int nvgpu_clk_arb_set_event_filter(struct nvgpu_clk_dev *dev, + struct nvgpu_gpu_set_event_filter_args *args) +{ + struct gk20a *g = dev->session->g; + u32 mask; + + nvgpu_log(g, gpu_dbg_fn, " "); + + if (args->flags) + return -EINVAL; + + if (args->size != 1) + return -EINVAL; + + if (copy_from_user(&mask, (void __user *) args->buffer, + args->size * sizeof(u32))) + return -EFAULT; + + /* update alarm mask */ + nvgpu_atomic_set(&dev->enabled_mask, mask); + + return 0; +} + +static long nvgpu_clk_arb_ioctl_event_dev(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct nvgpu_clk_dev *dev = filp->private_data; + struct gk20a *g = dev->session->g; + u8 buf[NVGPU_EVENT_IOCTL_MAX_ARG_SIZE]; + int err = 0; + + nvgpu_log(g, gpu_dbg_fn, "nr=%d", _IOC_NR(cmd)); + + if ((_IOC_TYPE(cmd) != NVGPU_EVENT_IOCTL_MAGIC) || (_IOC_NR(cmd) == 0) + || (_IOC_NR(cmd) > NVGPU_EVENT_IOCTL_LAST)) + return -EINVAL; + + BUG_ON(_IOC_SIZE(cmd) > NVGPU_EVENT_IOCTL_MAX_ARG_SIZE); + + memset(buf, 0, sizeof(buf)); + if (_IOC_DIR(cmd) & _IOC_WRITE) { + if (copy_from_user(buf, (void __user *) arg, _IOC_SIZE(cmd))) + return -EFAULT; + } + + switch (cmd) { + case NVGPU_EVENT_IOCTL_SET_FILTER: + err = nvgpu_clk_arb_set_event_filter(dev, + (struct nvgpu_gpu_set_event_filter_args *)buf); + break; + default: + nvgpu_warn(g, "unrecognized event ioctl cmd: 0x%x", cmd); + err = -ENOTTY; + } + + if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ)) + err = copy_to_user((void __user *) arg, buf, _IOC_SIZE(cmd)); + + return err; +} + +static const struct file_operations completion_dev_ops = { + .owner = THIS_MODULE, + .release = nvgpu_clk_arb_release_completion_dev, + .poll = nvgpu_clk_arb_poll_dev, +}; + +static const struct file_operations event_dev_ops = { + .owner = THIS_MODULE, + .release = nvgpu_clk_arb_release_event_dev, + .poll = nvgpu_clk_arb_poll_dev, + .read = nvgpu_clk_arb_read_event_dev, +#ifdef CONFIG_COMPAT + .compat_ioctl = nvgpu_clk_arb_ioctl_event_dev, +#endif + .unlocked_ioctl = nvgpu_clk_arb_ioctl_event_dev, +}; + +static int nvgpu_clk_arb_install_fd(struct gk20a *g, + struct nvgpu_clk_session *session, + const struct file_operations *fops, + struct nvgpu_clk_dev **_dev) +{ + struct file *file; + int fd; + int err; + int status; + char name[64]; + struct nvgpu_clk_dev *dev; + + clk_arb_dbg(g, " "); + + dev = nvgpu_kzalloc(g, sizeof(*dev)); + if (!dev) + return -ENOMEM; + + status = nvgpu_clk_notification_queue_alloc(g, &dev->queue, + DEFAULT_EVENT_NUMBER); + if (status < 0) { + err = status; + goto fail; + } + + fd = get_unused_fd_flags(O_RDWR); + if (fd < 0) { + err = fd; + goto fail; + } + + snprintf(name, sizeof(name), "%s-clk-fd%d", g->name, fd); + file = anon_inode_getfile(name, fops, dev, O_RDWR); + if (IS_ERR(file)) { + err = PTR_ERR(file); + goto fail_fd; + } + + fd_install(fd, file); + + nvgpu_cond_init(&dev->readout_wq); + + nvgpu_atomic_set(&dev->poll_mask, 0); + + dev->session = session; + nvgpu_ref_init(&dev->refcount); + + nvgpu_ref_get(&session->refcount); + + *_dev = dev; + + return fd; + +fail_fd: + put_unused_fd(fd); +fail: + nvgpu_kfree(g, dev); + + return err; +} + +int nvgpu_clk_arb_install_event_fd(struct gk20a *g, + struct nvgpu_clk_session *session, int *event_fd, u32 alarm_mask) +{ + struct nvgpu_clk_arb *arb = g->clk_arb; + struct nvgpu_clk_dev *dev; + int fd; + + clk_arb_dbg(g, " "); + + fd = nvgpu_clk_arb_install_fd(g, session, &event_dev_ops, &dev); + if (fd < 0) + return fd; + + /* TODO: alarm mask needs to be set to default value to prevent + * failures of legacy tests. This will be removed when sanity is + * updated + */ + if (alarm_mask) + nvgpu_atomic_set(&dev->enabled_mask, alarm_mask); + else + nvgpu_atomic_set(&dev->enabled_mask, EVENT(VF_UPDATE)); + + dev->arb_queue_head = nvgpu_atomic_read(&arb->notification_queue.head); + + nvgpu_spinlock_acquire(&arb->users_lock); + nvgpu_list_add_tail(&dev->link, &arb->users); + nvgpu_spinlock_release(&arb->users_lock); + + *event_fd = fd; + + return 0; +} + +int nvgpu_clk_arb_install_request_fd(struct gk20a *g, + struct nvgpu_clk_session *session, int *request_fd) +{ + struct nvgpu_clk_dev *dev; + int fd; + + clk_arb_dbg(g, " "); + + fd = nvgpu_clk_arb_install_fd(g, session, &completion_dev_ops, &dev); + if (fd < 0) + return fd; + + *request_fd = fd; + + return 0; +} + +int nvgpu_clk_arb_commit_request_fd(struct gk20a *g, + struct nvgpu_clk_session *session, int request_fd) +{ + struct nvgpu_clk_arb *arb = g->clk_arb; + struct nvgpu_clk_dev *dev; + struct fd fd; + int err = 0; + + clk_arb_dbg(g, " "); + + fd = fdget(request_fd); + if (!fd.file) + return -EINVAL; + + if (fd.file->f_op != &completion_dev_ops) { + err = -EINVAL; + goto fdput_fd; + } + + dev = (struct nvgpu_clk_dev *) fd.file->private_data; + + if (!dev || dev->session != session) { + err = -EINVAL; + goto fdput_fd; + } + + clk_arb_dbg(g, "requested target = %u\n", + (u32)dev->gpc2clk_target_mhz); + + nvgpu_atomic_inc(&g->clk_arb_global_nr); + nvgpu_ref_get(&dev->refcount); + nvgpu_spinlock_acquire(&session->session_lock); + nvgpu_list_add(&dev->node, &session->targets); + nvgpu_spinlock_release(&session->session_lock); + nvgpu_clk_arb_worker_enqueue(g, &arb->update_arb_work_item); + +fdput_fd: + fdput(fd); + return err; +} + +int nvgpu_clk_arb_set_session_target_mhz(struct nvgpu_clk_session *session, + int request_fd, u32 api_domain, u16 target_mhz) +{ + struct nvgpu_clk_dev *dev; + struct fd fd; + int err = 0; + + clk_arb_dbg(session->g, + "domain=0x%08x target_mhz=%u", api_domain, target_mhz); + + fd = fdget(request_fd); + if (!fd.file) + return -EINVAL; + + if (fd.file->f_op != &completion_dev_ops) { + err = -EINVAL; + goto fdput_fd; + } + + dev = fd.file->private_data; + if (!dev || dev->session != session) { + err = -EINVAL; + goto fdput_fd; + } + + switch (api_domain) { + case NVGPU_CLK_DOMAIN_MCLK: + dev->mclk_target_mhz = target_mhz; + break; + + case NVGPU_CLK_DOMAIN_GPCCLK: + dev->gpc2clk_target_mhz = target_mhz * 2ULL; + break; + + default: + err = -EINVAL; + } + +fdput_fd: + fdput(fd); + return err; +} + +u32 nvgpu_clk_arb_get_arbiter_clk_domains(struct gk20a *g) +{ + u32 clk_domains = g->ops.clk_arb.get_arbiter_clk_domains(g); + u32 api_domains = 0; + + if (clk_domains & CTRL_CLK_DOMAIN_GPC2CLK) + api_domains |= BIT(NVGPU_GPU_CLK_DOMAIN_GPCCLK); + + if (clk_domains & CTRL_CLK_DOMAIN_MCLK) + api_domains |= BIT(NVGPU_GPU_CLK_DOMAIN_MCLK); + + return api_domains; +} + +#ifdef CONFIG_DEBUG_FS +static int nvgpu_clk_arb_stats_show(struct seq_file *s, void *unused) +{ + struct gk20a *g = s->private; + struct nvgpu_clk_arb *arb = g->clk_arb; + struct nvgpu_clk_arb_debug *debug; + + u64 num; + s64 tmp, avg, std, max, min; + + debug = NV_ACCESS_ONCE(arb->debug); + /* Make copy of structure and ensure no reordering */ + nvgpu_smp_rmb(); + if (!debug) + return -EINVAL; + + std = debug->switch_std; + avg = debug->switch_avg; + max = debug->switch_max; + min = debug->switch_min; + num = debug->switch_num; + + tmp = std; + do_div(tmp, num); + seq_printf(s, "Number of transitions: %lld\n", + num); + seq_printf(s, "max / min : %lld / %lld usec\n", + max, min); + seq_printf(s, "avg / std : %lld / %ld usec\n", + avg, int_sqrt(tmp)); + + return 0; +} + +static int nvgpu_clk_arb_stats_open(struct inode *inode, struct file *file) +{ + return single_open(file, nvgpu_clk_arb_stats_show, inode->i_private); +} + +static const struct file_operations nvgpu_clk_arb_stats_fops = { + .open = nvgpu_clk_arb_stats_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + +int nvgpu_clk_arb_debugfs_init(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *gpu_root = l->debugfs; + struct dentry *d; + + nvgpu_log(g, gpu_dbg_info, "g=%p", g); + + d = debugfs_create_file( + "arb_stats", + S_IRUGO, + gpu_root, + g, + &nvgpu_clk_arb_stats_fops); + if (!d) + return -ENOMEM; + + return 0; +} +#endif diff --git a/include/os/linux/ioctl_ctrl.c b/include/os/linux/ioctl_ctrl.c new file mode 100644 index 0000000..ee141ff --- /dev/null +++ b/include/os/linux/ioctl_ctrl.c @@ -0,0 +1,2106 @@ +/* + * Copyright (c) 2011-2020, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ioctl_ctrl.h" +#include "ioctl_dbg.h" +#include "ioctl_as.h" +#include "ioctl_tsg.h" +#include "ioctl_channel.h" +#include "gk20a/fence_gk20a.h" + +#include "platform_gk20a.h" +#include "os_linux.h" +#include "dmabuf.h" +#include "channel.h" +#include "dmabuf_vidmem.h" + +#define HZ_TO_MHZ(a) ((a > 0xF414F9CD7ULL) ? 0xffff : (a >> 32) ? \ + (u32) ((a * 0x10C8ULL) >> 32) : (u16) ((u32) a/MHZ)) +#define MHZ_TO_HZ(a) ((u64)a * MHZ) + +struct gk20a_ctrl_priv { + struct device *dev; + struct gk20a *g; + struct nvgpu_clk_session *clk_session; + + struct nvgpu_list_node list; + struct { + struct vm_area_struct *vma; + unsigned long flags; + bool vma_mapped; + } usermode_vma; +}; + +static inline struct gk20a_ctrl_priv * +gk20a_ctrl_priv_from_list(struct nvgpu_list_node *node) +{ + return (struct gk20a_ctrl_priv *) + ((uintptr_t)node - offsetof(struct gk20a_ctrl_priv, list)); +} + +static u32 gk20a_as_translate_as_alloc_flags(struct gk20a *g, u32 flags) +{ + u32 core_flags = 0; + + if (flags & NVGPU_GPU_IOCTL_ALLOC_AS_FLAGS_USERSPACE_MANAGED) + core_flags |= NVGPU_AS_ALLOC_USERSPACE_MANAGED; + + return core_flags; +} + +int gk20a_ctrl_dev_open(struct inode *inode, struct file *filp) +{ + struct nvgpu_os_linux *l; + struct gk20a *g; + struct gk20a_ctrl_priv *priv; + int err = 0; + + l = container_of(inode->i_cdev, + struct nvgpu_os_linux, ctrl.cdev); + g = gk20a_get(&l->g); + if (!g) + return -ENODEV; + + nvgpu_log_fn(g, " "); + + priv = nvgpu_kzalloc(g, sizeof(struct gk20a_ctrl_priv)); + if (!priv) { + err = -ENOMEM; + goto free_ref; + } + filp->private_data = priv; + priv->dev = dev_from_gk20a(g); + /* + * We dont close the arbiter fd's after driver teardown to support + * GPU_LOST events, so we store g here, instead of dereferencing the + * dev structure on teardown + */ + priv->g = g; + + if (!g->sw_ready) { + err = gk20a_busy(g); + if (err) + goto free_ref; + gk20a_idle(g); + } + + err = nvgpu_clk_arb_init_session(g, &priv->clk_session); +free_ref: + if (err != 0) { + gk20a_put(g); + if (priv) + nvgpu_kfree(g, priv); + } else { + nvgpu_mutex_acquire(&l->ctrl.privs_lock); + nvgpu_list_add(&priv->list, &l->ctrl.privs); + nvgpu_mutex_release(&l->ctrl.privs_lock); + } + + return err; +} +int gk20a_ctrl_dev_release(struct inode *inode, struct file *filp) +{ + struct gk20a_ctrl_priv *priv = filp->private_data; + struct gk20a *g = priv->g; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + nvgpu_log_fn(g, " "); + + nvgpu_mutex_acquire(&l->ctrl.privs_lock); + nvgpu_list_del(&priv->list); + nvgpu_mutex_release(&l->ctrl.privs_lock); + + if (priv->clk_session) + nvgpu_clk_arb_release_session(g, priv->clk_session); + + gk20a_put(g); + nvgpu_kfree(g, priv); + + return 0; +} + +struct nvgpu_flags_mapping { + u64 ioctl_flag; + int enabled_flag; +}; + +static struct nvgpu_flags_mapping flags_mapping[] = { + {NVGPU_GPU_FLAGS_CAN_RAILGATE, + NVGPU_CAN_RAILGATE}, + {NVGPU_GPU_FLAGS_HAS_SYNCPOINTS, + NVGPU_HAS_SYNCPOINTS}, + {NVGPU_GPU_FLAGS_SUPPORT_PARTIAL_MAPPINGS, + NVGPU_SUPPORT_PARTIAL_MAPPINGS}, + {NVGPU_GPU_FLAGS_SUPPORT_SPARSE_ALLOCS, + NVGPU_SUPPORT_SPARSE_ALLOCS}, + {NVGPU_GPU_FLAGS_SUPPORT_SYNC_FENCE_FDS, + NVGPU_SUPPORT_SYNC_FENCE_FDS}, + {NVGPU_GPU_FLAGS_SUPPORT_CYCLE_STATS, + NVGPU_SUPPORT_CYCLE_STATS}, + {NVGPU_GPU_FLAGS_SUPPORT_CYCLE_STATS_SNAPSHOT, + NVGPU_SUPPORT_CYCLE_STATS_SNAPSHOT}, + {NVGPU_GPU_FLAGS_SUPPORT_USERSPACE_MANAGED_AS, + NVGPU_SUPPORT_USERSPACE_MANAGED_AS}, + {NVGPU_GPU_FLAGS_SUPPORT_TSG, + NVGPU_SUPPORT_TSG}, + {NVGPU_GPU_FLAGS_SUPPORT_CLOCK_CONTROLS, + NVGPU_SUPPORT_CLOCK_CONTROLS}, + {NVGPU_GPU_FLAGS_SUPPORT_GET_VOLTAGE, + NVGPU_SUPPORT_GET_VOLTAGE}, + {NVGPU_GPU_FLAGS_SUPPORT_GET_CURRENT, + NVGPU_SUPPORT_GET_CURRENT}, + {NVGPU_GPU_FLAGS_SUPPORT_GET_POWER, + NVGPU_SUPPORT_GET_POWER}, + {NVGPU_GPU_FLAGS_SUPPORT_GET_TEMPERATURE, + NVGPU_SUPPORT_GET_TEMPERATURE}, + {NVGPU_GPU_FLAGS_SUPPORT_SET_THERM_ALERT_LIMIT, + NVGPU_SUPPORT_SET_THERM_ALERT_LIMIT}, + {NVGPU_GPU_FLAGS_SUPPORT_DEVICE_EVENTS, + NVGPU_SUPPORT_DEVICE_EVENTS}, + {NVGPU_GPU_FLAGS_SUPPORT_FECS_CTXSW_TRACE, + NVGPU_SUPPORT_FECS_CTXSW_TRACE}, + {NVGPU_GPU_FLAGS_SUPPORT_DETERMINISTIC_SUBMIT_NO_JOBTRACKING, + NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_NO_JOBTRACKING}, + {NVGPU_GPU_FLAGS_SUPPORT_DETERMINISTIC_SUBMIT_FULL, + NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_FULL}, + {NVGPU_GPU_FLAGS_SUPPORT_DETERMINISTIC_OPTS, + NVGPU_SUPPORT_DETERMINISTIC_OPTS}, + {NVGPU_GPU_FLAGS_SUPPORT_SYNCPOINT_ADDRESS, + NVGPU_SUPPORT_SYNCPOINT_ADDRESS}, + {NVGPU_GPU_FLAGS_SUPPORT_USER_SYNCPOINT, + NVGPU_SUPPORT_USER_SYNCPOINT}, + {NVGPU_GPU_FLAGS_SUPPORT_USERMODE_SUBMIT, + NVGPU_SUPPORT_USERMODE_SUBMIT}, + {NVGPU_GPU_FLAGS_SUPPORT_IO_COHERENCE, + NVGPU_SUPPORT_IO_COHERENCE}, + {NVGPU_GPU_FLAGS_SUPPORT_RESCHEDULE_RUNLIST, + NVGPU_SUPPORT_RESCHEDULE_RUNLIST}, + {NVGPU_GPU_FLAGS_SUPPORT_MAP_DIRECT_KIND_CTRL, + NVGPU_SUPPORT_MAP_DIRECT_KIND_CTRL}, + {NVGPU_GPU_FLAGS_ECC_ENABLED_SM_LRF, + NVGPU_ECC_ENABLED_SM_LRF}, + {NVGPU_GPU_FLAGS_ECC_ENABLED_SM_SHM, + NVGPU_ECC_ENABLED_SM_SHM}, + {NVGPU_GPU_FLAGS_ECC_ENABLED_TEX, + NVGPU_ECC_ENABLED_TEX}, + {NVGPU_GPU_FLAGS_ECC_ENABLED_LTC, + NVGPU_ECC_ENABLED_LTC}, + {NVGPU_GPU_FLAGS_SUPPORT_TSG_SUBCONTEXTS, + NVGPU_SUPPORT_TSG_SUBCONTEXTS}, + {NVGPU_GPU_FLAGS_SUPPORT_SCG, + NVGPU_SUPPORT_SCG}, + {NVGPU_GPU_FLAGS_SUPPORT_VPR, + NVGPU_SUPPORT_VPR}, + {NVGPU_GPU_FLAGS_SUPPORT_SET_CTX_MMU_DEBUG_MODE, + NVGPU_SUPPORT_SET_CTX_MMU_DEBUG_MODE}, +}; + +static u64 nvgpu_ctrl_ioctl_gpu_characteristics_flags(struct gk20a *g) +{ + unsigned int i; + u64 ioctl_flags = 0; + + for (i = 0; i < sizeof(flags_mapping)/sizeof(*flags_mapping); i++) { + if (nvgpu_is_enabled(g, flags_mapping[i].enabled_flag)) + ioctl_flags |= flags_mapping[i].ioctl_flag; + } + + if (!capable(CAP_SYS_NICE)) { + ioctl_flags &= ~NVGPU_GPU_FLAGS_SUPPORT_RESCHEDULE_RUNLIST; + } + + return ioctl_flags; +} + +static void nvgpu_set_preemption_mode_flags(struct gk20a *g, + struct nvgpu_gpu_characteristics *gpu) +{ + struct nvgpu_preemption_modes_rec preemption_mode_rec; + + g->ops.gr.get_preemption_mode_flags(g, &preemption_mode_rec); + + gpu->graphics_preemption_mode_flags = + nvgpu_get_ioctl_graphics_preempt_mode_flags( + preemption_mode_rec.graphics_preemption_mode_flags); + gpu->compute_preemption_mode_flags = + nvgpu_get_ioctl_compute_preempt_mode_flags( + preemption_mode_rec.compute_preemption_mode_flags); + + gpu->default_graphics_preempt_mode = + nvgpu_get_ioctl_graphics_preempt_mode( + preemption_mode_rec.default_graphics_preempt_mode); + gpu->default_compute_preempt_mode = + nvgpu_get_ioctl_compute_preempt_mode( + preemption_mode_rec.default_compute_preempt_mode); +} + +static long +gk20a_ctrl_ioctl_gpu_characteristics( + struct gk20a *g, + struct nvgpu_gpu_get_characteristics *request) +{ + struct nvgpu_gpu_characteristics gpu; + long err = 0; + + if (gk20a_busy(g)) { + nvgpu_err(g, "failed to power on gpu"); + return -EINVAL; + } + + memset(&gpu, 0, sizeof(gpu)); + + gpu.L2_cache_size = g->ops.ltc.determine_L2_size_bytes(g); + gpu.on_board_video_memory_size = 0; /* integrated GPU */ + + gpu.num_gpc = g->gr.gpc_count; + gpu.max_gpc_count = g->gr.max_gpc_count; + + gpu.num_tpc_per_gpc = g->gr.max_tpc_per_gpc_count; + + gpu.bus_type = NVGPU_GPU_BUS_TYPE_AXI; /* always AXI for now */ + + gpu.compression_page_size = g->ops.fb.compression_page_size(g); + + if (g->ops.gr.get_gpc_mask) { + gpu.gpc_mask = g->ops.gr.get_gpc_mask(g); + } else { + gpu.gpc_mask = BIT32(g->gr.gpc_count) - 1; + } + + gpu.flags = nvgpu_ctrl_ioctl_gpu_characteristics_flags(g); + + gpu.arch = g->params.gpu_arch; + gpu.impl = g->params.gpu_impl; + gpu.rev = g->params.gpu_rev; + gpu.reg_ops_limit = NVGPU_IOCTL_DBG_REG_OPS_LIMIT; + gpu.map_buffer_batch_limit = nvgpu_is_enabled(g, NVGPU_SUPPORT_MAP_BUFFER_BATCH) ? + NVGPU_IOCTL_AS_MAP_BUFFER_BATCH_LIMIT : 0; + gpu.twod_class = g->ops.get_litter_value(g, GPU_LIT_TWOD_CLASS); + gpu.threed_class = g->ops.get_litter_value(g, GPU_LIT_THREED_CLASS); + gpu.compute_class = g->ops.get_litter_value(g, GPU_LIT_COMPUTE_CLASS); + gpu.gpfifo_class = g->ops.get_litter_value(g, GPU_LIT_GPFIFO_CLASS); + gpu.inline_to_memory_class = + g->ops.get_litter_value(g, GPU_LIT_I2M_CLASS); + gpu.dma_copy_class = + g->ops.get_litter_value(g, GPU_LIT_DMA_COPY_CLASS); + + gpu.vbios_version = g->bios.vbios_version; + gpu.vbios_oem_version = g->bios.vbios_oem_version; + + gpu.big_page_size = nvgpu_mm_get_default_big_page_size(g); + gpu.pde_coverage_bit_count = + g->ops.mm.get_mmu_levels(g, gpu.big_page_size)[0].lo_bit[0]; + gpu.available_big_page_sizes = nvgpu_mm_get_available_big_page_sizes(g); + + gpu.sm_arch_sm_version = g->params.sm_arch_sm_version; + gpu.sm_arch_spa_version = g->params.sm_arch_spa_version; + gpu.sm_arch_warp_count = g->params.sm_arch_warp_count; + + gpu.max_css_buffer_size = g->gr.max_css_buffer_size; + + gpu.gpu_ioctl_nr_last = NVGPU_GPU_IOCTL_LAST; + gpu.tsg_ioctl_nr_last = NVGPU_TSG_IOCTL_LAST; + gpu.dbg_gpu_ioctl_nr_last = NVGPU_DBG_GPU_IOCTL_LAST; + gpu.ioctl_channel_nr_last = NVGPU_IOCTL_CHANNEL_LAST; + gpu.as_ioctl_nr_last = NVGPU_AS_IOCTL_LAST; + gpu.event_ioctl_nr_last = NVGPU_EVENT_IOCTL_LAST; + gpu.gpu_va_bit_count = 40; + + strlcpy(gpu.chipname, g->name, sizeof(gpu.chipname)); + gpu.max_fbps_count = g->ops.gr.get_max_fbps_count(g); + gpu.fbp_en_mask = g->ops.gr.get_fbp_en_mask(g); + gpu.max_ltc_per_fbp = g->ops.gr.get_max_ltc_per_fbp(g); + gpu.max_lts_per_ltc = g->ops.gr.get_max_lts_per_ltc(g); + gpu.gr_compbit_store_base_hw = g->gr.compbit_store.base_hw; + gpu.gr_gobs_per_comptagline_per_slice = + g->gr.gobs_per_comptagline_per_slice; + gpu.num_ltc = g->ltc_count; + gpu.lts_per_ltc = g->gr.slices_per_ltc; + gpu.cbc_cache_line_size = g->gr.cacheline_size; + gpu.cbc_comptags_per_line = g->gr.comptags_per_cacheline; + + if (g->ops.clk.get_maxrate) + gpu.max_freq = g->ops.clk.get_maxrate(g, CTRL_CLK_DOMAIN_GPCCLK); + + gpu.local_video_memory_size = g->mm.vidmem.size; + + gpu.pci_vendor_id = g->pci_vendor_id; + gpu.pci_device_id = g->pci_device_id; + gpu.pci_subsystem_vendor_id = g->pci_subsystem_vendor_id; + gpu.pci_subsystem_device_id = g->pci_subsystem_device_id; + gpu.pci_class = g->pci_class; + gpu.pci_revision = g->pci_revision; + + nvgpu_set_preemption_mode_flags(g, &gpu); + + if (request->gpu_characteristics_buf_size > 0) { + size_t write_size = sizeof(gpu); + + nvgpu_speculation_barrier(); + if (write_size > request->gpu_characteristics_buf_size) + write_size = request->gpu_characteristics_buf_size; + + err = copy_to_user((void __user *)(uintptr_t) + request->gpu_characteristics_buf_addr, + &gpu, write_size); + } + + if (err == 0) + request->gpu_characteristics_buf_size = sizeof(gpu); + + gk20a_idle(g); + + return err; +} + +static int gk20a_ctrl_prepare_compressible_read( + struct gk20a *g, + struct nvgpu_gpu_prepare_compressible_read_args *args) +{ + int ret = -ENOSYS; + +#ifdef CONFIG_NVGPU_SUPPORT_CDE + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct nvgpu_channel_fence fence; + struct gk20a_fence *fence_out = NULL; + int submit_flags = nvgpu_submit_gpfifo_user_flags_to_common_flags( + args->submit_flags); + int fd = -1; + + fence.id = args->fence.syncpt_id; + fence.value = args->fence.syncpt_value; + + /* Try and allocate an fd here*/ + if ((submit_flags & NVGPU_SUBMIT_FLAGS_FENCE_GET) + && (submit_flags & NVGPU_SUBMIT_FLAGS_SYNC_FENCE)) { + fd = get_unused_fd_flags(O_RDWR); + if (fd < 0) + return fd; + } + + ret = gk20a_prepare_compressible_read(l, args->handle, + args->request_compbits, args->offset, + args->compbits_hoffset, args->compbits_voffset, + args->scatterbuffer_offset, + args->width, args->height, args->block_height_log2, + submit_flags, &fence, &args->valid_compbits, + &args->zbc_color, &fence_out); + + if (ret) { + if (fd != -1) + put_unused_fd(fd); + return ret; + } + + /* Convert fence_out to something we can pass back to user space. */ + if (submit_flags & NVGPU_SUBMIT_FLAGS_FENCE_GET) { + if (submit_flags & NVGPU_SUBMIT_FLAGS_SYNC_FENCE) { + if (fence_out) { + ret = gk20a_fence_install_fd(fence_out, fd); + if (ret) + put_unused_fd(fd); + else + args->fence.fd = fd; + } else { + args->fence.fd = -1; + put_unused_fd(fd); + } + } else { + if (fence_out) { + args->fence.syncpt_id = fence_out->syncpt_id; + args->fence.syncpt_value = + fence_out->syncpt_value; + } else { + args->fence.syncpt_id = -1; + args->fence.syncpt_value = 0; + } + } + } + gk20a_fence_put(fence_out); +#endif + + return ret; +} + +static int gk20a_ctrl_mark_compressible_write( + struct gk20a *g, + struct nvgpu_gpu_mark_compressible_write_args *args) +{ + int ret = -ENOSYS; + +#ifdef CONFIG_NVGPU_SUPPORT_CDE + ret = gk20a_mark_compressible_write(g, args->handle, + args->valid_compbits, args->offset, args->zbc_color); +#endif + + return ret; +} + +static int gk20a_ctrl_alloc_as( + struct gk20a *g, + struct nvgpu_alloc_as_args *args) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct gk20a_as_share *as_share; + int err; + int fd; + struct file *file; + char name[64]; + + err = get_unused_fd_flags(O_RDWR); + if (err < 0) + return err; + fd = err; + + snprintf(name, sizeof(name), "nvhost-%s-fd%d", g->name, fd); + + file = anon_inode_getfile(name, l->as_dev.cdev.ops, NULL, O_RDWR); + if (IS_ERR(file)) { + err = PTR_ERR(file); + goto clean_up; + } + + err = gk20a_as_alloc_share(g, args->big_page_size, + gk20a_as_translate_as_alloc_flags(g, + args->flags), + &as_share); + if (err) + goto clean_up_file; + + fd_install(fd, file); + file->private_data = as_share; + + args->as_fd = fd; + return 0; + +clean_up_file: + fput(file); +clean_up: + put_unused_fd(fd); + return err; +} + +static int gk20a_ctrl_open_tsg(struct gk20a *g, + struct nvgpu_gpu_open_tsg_args *args) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + int err; + int fd; + struct file *file; + char name[64]; + + err = get_unused_fd_flags(O_RDWR); + if (err < 0) + return err; + fd = err; + + snprintf(name, sizeof(name), "nvgpu-%s-tsg%d", g->name, fd); + + file = anon_inode_getfile(name, l->tsg.cdev.ops, NULL, O_RDWR); + if (IS_ERR(file)) { + err = PTR_ERR(file); + goto clean_up; + } + + err = nvgpu_ioctl_tsg_open(g, file); + if (err) + goto clean_up_file; + + fd_install(fd, file); + args->tsg_fd = fd; + return 0; + +clean_up_file: + fput(file); +clean_up: + put_unused_fd(fd); + return err; +} + +static int gk20a_ctrl_get_tpc_masks(struct gk20a *g, + struct nvgpu_gpu_get_tpc_masks_args *args) +{ + struct gr_gk20a *gr = &g->gr; + int err = 0; + const u32 gpc_tpc_mask_size = sizeof(u32) * gr->max_gpc_count; + + if (args->mask_buf_size > 0) { + size_t write_size = gpc_tpc_mask_size; + + nvgpu_speculation_barrier(); + if (write_size > args->mask_buf_size) + write_size = args->mask_buf_size; + + err = copy_to_user((void __user *)(uintptr_t) + args->mask_buf_addr, + gr->gpc_tpc_mask, write_size); + } + + if (err == 0) + args->mask_buf_size = gpc_tpc_mask_size; + + return err; +} + +static int gk20a_ctrl_get_fbp_l2_masks( + struct gk20a *g, struct nvgpu_gpu_get_fbp_l2_masks_args *args) +{ + struct gr_gk20a *gr = &g->gr; + int err = 0; + const u32 fbp_l2_mask_size = sizeof(u32) * gr->max_fbps_count; + + if (args->mask_buf_size > 0) { + size_t write_size = fbp_l2_mask_size; + + nvgpu_speculation_barrier(); + if (write_size > args->mask_buf_size) + write_size = args->mask_buf_size; + + err = copy_to_user((void __user *)(uintptr_t) + args->mask_buf_addr, + gr->fbp_rop_l2_en_mask, write_size); + } + + if (err == 0) + args->mask_buf_size = fbp_l2_mask_size; + + return err; +} + +static int nvgpu_gpu_ioctl_l2_fb_ops(struct gk20a *g, + struct nvgpu_gpu_l2_fb_args *args) +{ + int ret; + bool always_poweron; + + if ((!args->l2_flush && !args->fb_flush) || + (!args->l2_flush && args->l2_invalidate)) + return -EINVAL; + + /* Handle this case for joint rails or DGPU */ + always_poweron = (!nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE) || + !pm_runtime_enabled(dev_from_gk20a(g))); + + /* In case of not always power_on, exit if g->power_on is false */ + if (!always_poweron && !gk20a_check_poweron(g)) { + return 0; + } + + /* There is a small window between a call to gk20a_idle() has occured + * and railgate being actually triggered(setting g->power_on = false), + * when l2_flush can race with railgate. Its better to take a busy_lock + * to prevent the gk20a_idle() from proceeding. There is a very small + * chance that gk20a_idle() might begin before gk20a_busy(). Having + * a locked access to g->power_on further reduces the probability of + * gk20a_idle() being triggered before gk20a_busy() + */ + ret = gk20a_busy(g); + + if (ret != 0) { + nvgpu_err(g, "failed to take power ref"); + return ret; + } + + if (args->l2_flush) + g->ops.mm.l2_flush(g, args->l2_invalidate ? true : false); + + if (args->fb_flush) + g->ops.mm.fb_flush(g); + + gk20a_idle(g); + + return 0; +} + +static int nvgpu_gpu_ioctl_set_mmu_debug_mode( + struct gk20a *g, + struct nvgpu_gpu_mmu_debug_mode_args *args) +{ + if (gk20a_busy(g)) { + nvgpu_err(g, "failed to power on gpu"); + return -EINVAL; + } + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + g->ops.fb.set_debug_mode(g, args->state == 1); + nvgpu_mutex_release(&g->dbg_sessions_lock); + + gk20a_idle(g); + return 0; +} + +static int nvgpu_gpu_ioctl_set_debug_mode( + struct gk20a *g, + struct nvgpu_gpu_sm_debug_mode_args *args) +{ + struct channel_gk20a *ch; + int err; + + ch = gk20a_get_channel_from_file(args->channel_fd); + if (!ch) + return -EINVAL; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + if (g->ops.gr.set_sm_debug_mode) + err = g->ops.gr.set_sm_debug_mode(g, ch, + args->sms, !!args->enable); + else + err = -ENOSYS; + nvgpu_mutex_release(&g->dbg_sessions_lock); + + gk20a_channel_put(ch); + return err; +} + +static int nvgpu_gpu_ioctl_trigger_suspend(struct gk20a *g) +{ + int err; + + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + err = gr_gk20a_elpg_protected_call(g, + g->ops.gr.trigger_suspend(g)); + nvgpu_mutex_release(&g->dbg_sessions_lock); + + gk20a_idle(g); + + return err; +} + +static int nvgpu_gpu_ioctl_wait_for_pause(struct gk20a *g, + struct nvgpu_gpu_wait_pause_args *args) +{ + int err; + struct warpstate *ioctl_w_state; + struct nvgpu_warpstate *w_state = NULL; + u32 sm_count, ioctl_size, size, sm_id; + + sm_count = g->gr.gpc_count * g->gr.tpc_count; + + ioctl_size = sm_count * sizeof(struct warpstate); + ioctl_w_state = nvgpu_kzalloc(g, ioctl_size); + if (!ioctl_w_state) + return -ENOMEM; + + size = sm_count * sizeof(struct nvgpu_warpstate); + w_state = nvgpu_kzalloc(g, size); + if (!w_state) { + err = -ENOMEM; + goto out_free; + } + + err = gk20a_busy(g); + if (err) + goto out_free; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + (void)gr_gk20a_elpg_protected_call(g, + g->ops.gr.wait_for_pause(g, w_state)); + + for (sm_id = 0; sm_id < g->gr.no_of_sm; sm_id++) { + ioctl_w_state[sm_id].valid_warps[0] = + w_state[sm_id].valid_warps[0]; + ioctl_w_state[sm_id].valid_warps[1] = + w_state[sm_id].valid_warps[1]; + ioctl_w_state[sm_id].trapped_warps[0] = + w_state[sm_id].trapped_warps[0]; + ioctl_w_state[sm_id].trapped_warps[1] = + w_state[sm_id].trapped_warps[1]; + ioctl_w_state[sm_id].paused_warps[0] = + w_state[sm_id].paused_warps[0]; + ioctl_w_state[sm_id].paused_warps[1] = + w_state[sm_id].paused_warps[1]; + } + /* Copy to user space - pointed by "args->pwarpstate" */ + if (copy_to_user((void __user *)(uintptr_t)args->pwarpstate, + w_state, ioctl_size)) { + nvgpu_log_fn(g, "copy_to_user failed!"); + err = -EFAULT; + } + + nvgpu_mutex_release(&g->dbg_sessions_lock); + + gk20a_idle(g); + +out_free: + nvgpu_kfree(g, w_state); + nvgpu_kfree(g, ioctl_w_state); + + return err; +} + +static int nvgpu_gpu_ioctl_resume_from_pause(struct gk20a *g) +{ + int err; + + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + err = gr_gk20a_elpg_protected_call(g, + g->ops.gr.resume_from_pause(g)); + nvgpu_mutex_release(&g->dbg_sessions_lock); + + gk20a_idle(g); + + return err; +} + +static int nvgpu_gpu_ioctl_clear_sm_errors(struct gk20a *g) +{ + int err; + + err = gk20a_busy(g); + if (err) + return err; + + err = gr_gk20a_elpg_protected_call(g, + g->ops.gr.clear_sm_errors(g)); + + gk20a_idle(g); + + return err; +} + +static int nvgpu_gpu_ioctl_has_any_exception( + struct gk20a *g, + struct nvgpu_gpu_tpc_exception_en_status_args *args) +{ + u32 tpc_exception_en; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + tpc_exception_en = g->ops.gr.tpc_enabled_exceptions(g); + nvgpu_mutex_release(&g->dbg_sessions_lock); + + args->tpc_exception_en_sm_mask = tpc_exception_en; + + return 0; +} + +static int gk20a_ctrl_get_num_vsms(struct gk20a *g, + struct nvgpu_gpu_num_vsms *args) +{ + struct gr_gk20a *gr = &g->gr; + args->num_vsms = gr->no_of_sm; + return 0; +} + +static int gk20a_ctrl_vsm_mapping(struct gk20a *g, + struct nvgpu_gpu_vsms_mapping *args) +{ + int err = 0; + struct gr_gk20a *gr = &g->gr; + size_t write_size = gr->no_of_sm * + sizeof(struct nvgpu_gpu_vsms_mapping_entry); + struct nvgpu_gpu_vsms_mapping_entry *vsms_buf; + u32 i; + + vsms_buf = nvgpu_kzalloc(g, write_size); + if (vsms_buf == NULL) + return -ENOMEM; + + for (i = 0; i < gr->no_of_sm; i++) { + vsms_buf[i].gpc_index = gr->sm_to_cluster[i].gpc_index; + if (g->ops.gr.get_nonpes_aware_tpc) + vsms_buf[i].tpc_index = + g->ops.gr.get_nonpes_aware_tpc(g, + gr->sm_to_cluster[i].gpc_index, + gr->sm_to_cluster[i].tpc_index); + else + vsms_buf[i].tpc_index = + gr->sm_to_cluster[i].tpc_index; + } + + err = copy_to_user((void __user *)(uintptr_t) + args->vsms_map_buf_addr, + vsms_buf, write_size); + nvgpu_kfree(g, vsms_buf); + + return err; +} + +static int nvgpu_gpu_get_cpu_time_correlation_info( + struct gk20a *g, + struct nvgpu_gpu_get_cpu_time_correlation_info_args *args) +{ + struct nvgpu_cpu_time_correlation_sample *samples; + int err; + u32 i; + + if (args->count > NVGPU_GPU_GET_CPU_TIME_CORRELATION_INFO_MAX_COUNT || + args->source_id != NVGPU_GPU_GET_CPU_TIME_CORRELATION_INFO_SRC_ID_TSC) + return -EINVAL; + + samples = nvgpu_kzalloc(g, args->count * + sizeof(struct nvgpu_cpu_time_correlation_sample)); + if (!samples) { + return -ENOMEM; + } + + err = g->ops.ptimer.get_timestamps_zipper(g, + args->source_id, args->count, samples); + if (!err) { + for (i = 0; i < args->count; i++) { + args->samples[i].cpu_timestamp = samples[i].cpu_timestamp; + args->samples[i].gpu_timestamp = samples[i].gpu_timestamp; + } + } + + nvgpu_kfree(g, samples); + + return err; +} + +static int nvgpu_gpu_get_gpu_time( + struct gk20a *g, + struct nvgpu_gpu_get_gpu_time_args *args) +{ + u64 time; + int err; + + err = gk20a_busy(g); + if (err) + return err; + + err = g->ops.ptimer.read_ptimer(g, &time); + if (!err) + args->gpu_timestamp = time; + + gk20a_idle(g); + return err; +} + +static int nvgpu_gpu_get_engine_info( + struct gk20a *g, + struct nvgpu_gpu_get_engine_info_args *args) +{ + int err = 0; + u32 engine_enum = ENGINE_INVAL_GK20A; + u32 report_index = 0; + u32 engine_id_idx; + const u32 max_buffer_engines = args->engine_info_buf_size / + sizeof(struct nvgpu_gpu_get_engine_info_item); + struct nvgpu_gpu_get_engine_info_item __user *dst_item_list = + (void __user *)(uintptr_t)args->engine_info_buf_addr; + + for (engine_id_idx = 0; engine_id_idx < g->fifo.num_engines; + ++engine_id_idx) { + u32 active_engine_id = g->fifo.active_engines_list[engine_id_idx]; + const struct fifo_engine_info_gk20a *src_info = + &g->fifo.engine_info[active_engine_id]; + struct nvgpu_gpu_get_engine_info_item dst_info; + + memset(&dst_info, 0, sizeof(dst_info)); + + engine_enum = src_info->engine_enum; + + switch (engine_enum) { + case ENGINE_GR_GK20A: + dst_info.engine_id = NVGPU_GPU_ENGINE_ID_GR; + break; + + case ENGINE_GRCE_GK20A: + dst_info.engine_id = NVGPU_GPU_ENGINE_ID_GR_COPY; + break; + + case ENGINE_ASYNC_CE_GK20A: + dst_info.engine_id = NVGPU_GPU_ENGINE_ID_ASYNC_COPY; + break; + + default: + nvgpu_err(g, "Unmapped engine enum %u", + engine_enum); + continue; + } + + dst_info.engine_instance = src_info->inst_id; + dst_info.runlist_id = src_info->runlist_id; + + if (report_index < max_buffer_engines) { + err = copy_to_user(&dst_item_list[report_index], + &dst_info, sizeof(dst_info)); + if (err) + goto clean_up; + } + + ++report_index; + } + + args->engine_info_buf_size = + report_index * sizeof(struct nvgpu_gpu_get_engine_info_item); + +clean_up: + return err; +} + +static int nvgpu_gpu_alloc_vidmem(struct gk20a *g, + struct nvgpu_gpu_alloc_vidmem_args *args) +{ + u32 align = args->in.alignment ? args->in.alignment : SZ_4K; + int fd; + + nvgpu_log_fn(g, " "); + + /* not yet supported */ + if (WARN_ON(args->in.flags & NVGPU_GPU_ALLOC_VIDMEM_FLAG_CPU_MASK)) + return -EINVAL; + + /* not yet supported */ + if (WARN_ON(args->in.flags & NVGPU_GPU_ALLOC_VIDMEM_FLAG_VPR)) + return -EINVAL; + + if (args->in.size & (SZ_4K - 1)) + return -EINVAL; + + if (!args->in.size) + return -EINVAL; + + if (align & (align - 1)) + return -EINVAL; + + if (align > roundup_pow_of_two(args->in.size)) { + /* log this special case, buddy allocator detail */ + nvgpu_warn(g, + "alignment larger than buffer size rounded up to power of 2 is not supported"); + return -EINVAL; + } + + fd = nvgpu_vidmem_export_linux(g, args->in.size); + if (fd < 0) + return fd; + + args->out.dmabuf_fd = fd; + + nvgpu_log_fn(g, "done, fd=%d", fd); + + return 0; +} + +static int nvgpu_gpu_get_memory_state(struct gk20a *g, + struct nvgpu_gpu_get_memory_state_args *args) +{ + int err; + + nvgpu_log_fn(g, " "); + + if (args->reserved[0] || args->reserved[1] || + args->reserved[2] || args->reserved[3]) + return -EINVAL; + + err = nvgpu_vidmem_get_space(g, &args->total_free_bytes); + + nvgpu_log_fn(g, "done, err=%d, bytes=%lld", err, args->total_free_bytes); + + return err; +} + +static u32 nvgpu_gpu_convert_clk_domain(u32 clk_domain) +{ + u32 domain = 0; + + if (clk_domain == NVGPU_GPU_CLK_DOMAIN_MCLK) + domain = NVGPU_CLK_DOMAIN_MCLK; + else if (clk_domain == NVGPU_GPU_CLK_DOMAIN_GPCCLK) + domain = NVGPU_CLK_DOMAIN_GPCCLK; + else + domain = NVGPU_CLK_DOMAIN_MAX + 1; + + return domain; +} + +static int nvgpu_gpu_clk_get_vf_points(struct gk20a *g, + struct gk20a_ctrl_priv *priv, + struct nvgpu_gpu_clk_vf_points_args *args) +{ + struct nvgpu_gpu_clk_vf_point clk_point; + struct nvgpu_gpu_clk_vf_point __user *entry; + struct nvgpu_clk_session *session = priv->clk_session; + u32 clk_domains = 0; + int err; + u16 last_mhz; + u16 *fpoints; + u32 i; + u32 max_points = 0; + u32 num_points = 0; + u16 min_mhz; + u16 max_mhz; + + nvgpu_log_fn(g, " "); + + if (!session || args->flags) + return -EINVAL; + + clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g); + args->num_entries = 0; + + if (!nvgpu_clk_arb_is_valid_domain(g, + nvgpu_gpu_convert_clk_domain(args->clk_domain))) + return -EINVAL; + + err = nvgpu_clk_arb_get_arbiter_clk_f_points(g, + nvgpu_gpu_convert_clk_domain(args->clk_domain), + &max_points, NULL); + if (err) + return err; + + if (!args->max_entries) { + args->max_entries = max_points; + return 0; + } + + if (args->max_entries < max_points) + return -EINVAL; + + err = nvgpu_clk_arb_get_arbiter_clk_range(g, + nvgpu_gpu_convert_clk_domain(args->clk_domain), + &min_mhz, &max_mhz); + if (err) + return err; + + fpoints = nvgpu_kcalloc(g, max_points, sizeof(u16)); + if (!fpoints) + return -ENOMEM; + + err = nvgpu_clk_arb_get_arbiter_clk_f_points(g, + nvgpu_gpu_convert_clk_domain(args->clk_domain), + &max_points, fpoints); + if (err) + goto fail; + + entry = (struct nvgpu_gpu_clk_vf_point __user *) + (uintptr_t)args->clk_vf_point_entries; + + last_mhz = 0; + num_points = 0; + for (i = 0; (i < max_points) && !err; i++) { + + /* filter out duplicate frequencies */ + if (fpoints[i] == last_mhz) + continue; + + /* filter out out-of-range frequencies */ + if ((fpoints[i] < min_mhz) || (fpoints[i] > max_mhz)) + continue; + + last_mhz = fpoints[i]; + clk_point.freq_hz = MHZ_TO_HZ(fpoints[i]); + + err = copy_to_user((void __user *)entry, &clk_point, + sizeof(clk_point)); + + num_points++; + entry++; + } + + args->num_entries = num_points; + +fail: + nvgpu_kfree(g, fpoints); + return err; +} + +static int nvgpu_gpu_clk_get_range(struct gk20a *g, + struct gk20a_ctrl_priv *priv, + struct nvgpu_gpu_clk_range_args *args) +{ + struct nvgpu_gpu_clk_range clk_range; + struct nvgpu_gpu_clk_range __user *entry; + struct nvgpu_clk_session *session = priv->clk_session; + + u32 clk_domains = 0; + u32 num_domains; + u32 num_entries; + u32 i; + int bit; + int err; + u16 min_mhz, max_mhz; + + nvgpu_log_fn(g, " "); + + if (!session) + return -EINVAL; + + clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g); + num_domains = hweight_long(clk_domains); + + if (!args->flags) { + if (!args->num_entries) { + args->num_entries = num_domains; + return 0; + } + + if (args->num_entries < num_domains) + return -EINVAL; + + args->num_entries = 0; + num_entries = num_domains; + + } else { + if (args->flags != NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) + return -EINVAL; + + num_entries = args->num_entries; + if (num_entries > num_domains) + return -EINVAL; + } + + entry = (struct nvgpu_gpu_clk_range __user *) + (uintptr_t)args->clk_range_entries; + + for (i = 0; i < num_entries; i++, entry++) { + + if (args->flags == NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) { + if (copy_from_user(&clk_range, (void __user *)entry, + sizeof(clk_range))) + return -EFAULT; + } else { + bit = ffs(clk_domains) - 1; + clk_range.clk_domain = bit; + clk_domains &= ~BIT(bit); + } + + clk_range.flags = 0; + err = nvgpu_clk_arb_get_arbiter_clk_range(g, + nvgpu_gpu_convert_clk_domain(clk_range.clk_domain), + &min_mhz, &max_mhz); + clk_range.min_hz = MHZ_TO_HZ(min_mhz); + clk_range.max_hz = MHZ_TO_HZ(max_mhz); + + if (err) + return err; + + err = copy_to_user(entry, &clk_range, sizeof(clk_range)); + if (err) + return -EFAULT; + } + + args->num_entries = num_entries; + + return 0; +} + +static int nvgpu_gpu_clk_set_info(struct gk20a *g, + struct gk20a_ctrl_priv *priv, + struct nvgpu_gpu_clk_set_info_args *args) +{ + struct nvgpu_gpu_clk_info clk_info; + struct nvgpu_gpu_clk_info __user *entry; + struct nvgpu_clk_session *session = priv->clk_session; + + int fd; + u32 clk_domains = 0; + u16 freq_mhz; + int i; + int ret; + + nvgpu_log_fn(g, " "); + + if (!session || args->flags) + return -EINVAL; + + clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g); + if (!clk_domains) + return -EINVAL; + + entry = (struct nvgpu_gpu_clk_info __user *) + (uintptr_t)args->clk_info_entries; + + for (i = 0; i < args->num_entries; i++, entry++) { + + if (copy_from_user(&clk_info, entry, sizeof(clk_info))) + return -EFAULT; + + if (!nvgpu_clk_arb_is_valid_domain(g, + nvgpu_gpu_convert_clk_domain(clk_info.clk_domain))) + return -EINVAL; + } + nvgpu_speculation_barrier(); + + entry = (struct nvgpu_gpu_clk_info __user *) + (uintptr_t)args->clk_info_entries; + + ret = nvgpu_clk_arb_install_request_fd(g, session, &fd); + if (ret < 0) + return ret; + + for (i = 0; i < args->num_entries; i++, entry++) { + + if (copy_from_user(&clk_info, (void __user *)entry, + sizeof(clk_info))) + return -EFAULT; + freq_mhz = HZ_TO_MHZ(clk_info.freq_hz); + + nvgpu_clk_arb_set_session_target_mhz(session, fd, + nvgpu_gpu_convert_clk_domain(clk_info.clk_domain), freq_mhz); + } + + nvgpu_speculation_barrier(); + ret = nvgpu_clk_arb_commit_request_fd(g, session, fd); + if (ret < 0) + return ret; + + args->completion_fd = fd; + + return ret; +} + +static int nvgpu_gpu_clk_get_info(struct gk20a *g, + struct gk20a_ctrl_priv *priv, + struct nvgpu_gpu_clk_get_info_args *args) +{ + struct nvgpu_gpu_clk_info clk_info; + struct nvgpu_gpu_clk_info __user *entry; + struct nvgpu_clk_session *session = priv->clk_session; + u32 clk_domains = 0; + u32 num_domains; + u32 num_entries; + u32 i; + u16 freq_mhz; + int err; + int bit; + + nvgpu_log_fn(g, " "); + + if (!session) + return -EINVAL; + + clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g); + num_domains = hweight_long(clk_domains); + + if (!args->flags) { + if (!args->num_entries) { + args->num_entries = num_domains; + return 0; + } + + if (args->num_entries < num_domains) + return -EINVAL; + + args->num_entries = 0; + num_entries = num_domains; + + } else { + if (args->flags != NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) + return -EINVAL; + + num_entries = args->num_entries; + if (num_entries > num_domains * 3) + return -EINVAL; + } + + entry = (struct nvgpu_gpu_clk_info __user *) + (uintptr_t)args->clk_info_entries; + + for (i = 0; i < num_entries; i++, entry++) { + + if (args->flags == NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) { + if (copy_from_user(&clk_info, (void __user *)entry, + sizeof(clk_info))) + return -EFAULT; + } else { + bit = ffs(clk_domains) - 1; + clk_info.clk_domain = bit; + clk_domains &= ~BIT(bit); + clk_info.clk_type = args->clk_type; + } + + nvgpu_speculation_barrier(); + switch (clk_info.clk_type) { + case NVGPU_GPU_CLK_TYPE_TARGET: + err = nvgpu_clk_arb_get_session_target_mhz(session, + nvgpu_gpu_convert_clk_domain(clk_info.clk_domain), + &freq_mhz); + break; + case NVGPU_GPU_CLK_TYPE_ACTUAL: + err = nvgpu_clk_arb_get_arbiter_actual_mhz(g, + nvgpu_gpu_convert_clk_domain(clk_info.clk_domain), + &freq_mhz); + break; + case NVGPU_GPU_CLK_TYPE_EFFECTIVE: + err = nvgpu_clk_arb_get_arbiter_effective_mhz(g, + nvgpu_gpu_convert_clk_domain(clk_info.clk_domain), + &freq_mhz); + break; + default: + freq_mhz = 0; + err = -EINVAL; + break; + } + if (err) + return err; + + clk_info.flags = 0; + clk_info.freq_hz = MHZ_TO_HZ(freq_mhz); + + err = copy_to_user((void __user *)entry, &clk_info, + sizeof(clk_info)); + if (err) + return -EFAULT; + } + + nvgpu_speculation_barrier(); + args->num_entries = num_entries; + + return 0; +} + +static int nvgpu_gpu_get_event_fd(struct gk20a *g, + struct gk20a_ctrl_priv *priv, + struct nvgpu_gpu_get_event_fd_args *args) +{ + struct nvgpu_clk_session *session = priv->clk_session; + + nvgpu_log_fn(g, " "); + + if (!session) + return -EINVAL; + + return nvgpu_clk_arb_install_event_fd(g, session, &args->event_fd, + args->flags); +} + +static int nvgpu_gpu_get_voltage(struct gk20a *g, + struct nvgpu_gpu_get_voltage_args *args) +{ + int err = -EINVAL; + + nvgpu_log_fn(g, " "); + + if (args->reserved) + return -EINVAL; + + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_GET_VOLTAGE)) + return -EINVAL; + + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_speculation_barrier(); + switch (args->which) { + case NVGPU_GPU_VOLTAGE_CORE: + err = volt_get_voltage(g, CTRL_VOLT_DOMAIN_LOGIC, &args->voltage); + break; + case NVGPU_GPU_VOLTAGE_SRAM: + err = volt_get_voltage(g, CTRL_VOLT_DOMAIN_SRAM, &args->voltage); + break; + case NVGPU_GPU_VOLTAGE_BUS: + err = pmgr_pwr_devices_get_voltage(g, &args->voltage); + break; + default: + err = -EINVAL; + } + + gk20a_idle(g); + + return err; +} + +static int nvgpu_gpu_get_current(struct gk20a *g, + struct nvgpu_gpu_get_current_args *args) +{ + int err; + + nvgpu_log_fn(g, " "); + + if (args->reserved[0] || args->reserved[1] || args->reserved[2]) + return -EINVAL; + + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_GET_CURRENT)) + return -EINVAL; + + err = gk20a_busy(g); + if (err) + return err; + + err = pmgr_pwr_devices_get_current(g, &args->currnt); + + gk20a_idle(g); + + return err; +} + +static int nvgpu_gpu_get_power(struct gk20a *g, + struct nvgpu_gpu_get_power_args *args) +{ + int err; + + nvgpu_log_fn(g, " "); + + if (args->reserved[0] || args->reserved[1] || args->reserved[2]) + return -EINVAL; + + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_GET_POWER)) + return -EINVAL; + + err = gk20a_busy(g); + if (err) + return err; + + err = pmgr_pwr_devices_get_power(g, &args->power); + + gk20a_idle(g); + + return err; +} + +static int nvgpu_gpu_get_temperature(struct gk20a *g, + struct nvgpu_gpu_get_temperature_args *args) +{ + int err; + u32 temp_f24_8; + + nvgpu_log_fn(g, " "); + + if (args->reserved[0] || args->reserved[1] || args->reserved[2]) + return -EINVAL; + + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_GET_TEMPERATURE)) + return -EINVAL; + + if (!g->ops.therm.get_internal_sensor_curr_temp) + return -EINVAL; + + err = gk20a_busy(g); + if (err) + return err; + + err = g->ops.therm.get_internal_sensor_curr_temp(g, &temp_f24_8); + + gk20a_idle(g); + + args->temp_f24_8 = (s32)temp_f24_8; + + return err; +} + +static int nvgpu_gpu_set_therm_alert_limit(struct gk20a *g, + struct nvgpu_gpu_set_therm_alert_limit_args *args) +{ + int err; + + nvgpu_log_fn(g, " "); + + if (args->reserved[0] || args->reserved[1] || args->reserved[2]) + return -EINVAL; + + if (!g->ops.therm.configure_therm_alert) + return -EINVAL; + + err = gk20a_busy(g); + if (err) + return err; + + err = g->ops.therm.configure_therm_alert(g, args->temp_f24_8); + + gk20a_idle(g); + + return err; +} + +static int nvgpu_gpu_set_deterministic_ch_railgate(struct channel_gk20a *ch, + u32 flags) +{ + int err = 0; + bool allow; + bool disallow; + + allow = flags & + NVGPU_GPU_SET_DETERMINISTIC_OPTS_FLAGS_ALLOW_RAILGATING; + + disallow = flags & + NVGPU_GPU_SET_DETERMINISTIC_OPTS_FLAGS_DISALLOW_RAILGATING; + + /* Can't be both at the same time */ + if (allow && disallow) + return -EINVAL; + + /* Nothing to do */ + if (!allow && !disallow) + return 0; + + /* + * Moving into explicit idle or back from it? A call that doesn't + * change the status is a no-op. + */ + if (!ch->deterministic_railgate_allowed && + allow) { + gk20a_idle(ch->g); + } else if (ch->deterministic_railgate_allowed && + !allow) { + err = gk20a_busy(ch->g); + if (err) { + nvgpu_warn(ch->g, + "cannot busy to restore deterministic ch"); + return err; + } + } + ch->deterministic_railgate_allowed = allow; + + return err; +} + +static int nvgpu_gpu_set_deterministic_ch(struct channel_gk20a *ch, u32 flags) +{ + if (!ch->deterministic) + return -EINVAL; + + return nvgpu_gpu_set_deterministic_ch_railgate(ch, flags); +} + +static int nvgpu_gpu_set_deterministic_opts(struct gk20a *g, + struct nvgpu_gpu_set_deterministic_opts_args *args) +{ + int __user *user_channels; + u32 i = 0; + int err = 0; + + nvgpu_log_fn(g, " "); + + user_channels = (int __user *)(uintptr_t)args->channels; + + /* Upper limit; prevent holding deterministic_busy for long */ + if (args->num_channels > g->fifo.num_channels) { + err = -EINVAL; + goto out; + } + + /* Trivial sanity check first */ + if (!access_ok(VERIFY_READ, user_channels, + args->num_channels * sizeof(int))) { + err = -EFAULT; + goto out; + } + + nvgpu_rwsem_down_read(&g->deterministic_busy); + + /* note: we exit at the first failure */ + for (; i < args->num_channels; i++) { + int ch_fd = 0; + struct channel_gk20a *ch; + + if (copy_from_user(&ch_fd, &user_channels[i], sizeof(int))) { + /* User raced with above access_ok */ + err = -EFAULT; + break; + } + + ch = gk20a_get_channel_from_file(ch_fd); + if (!ch) { + err = -EINVAL; + break; + } + + err = nvgpu_gpu_set_deterministic_ch(ch, args->flags); + + gk20a_channel_put(ch); + + if (err) + break; + } + + nvgpu_speculation_barrier(); + nvgpu_rwsem_up_read(&g->deterministic_busy); + +out: + args->num_channels = i; + return err; +} + +long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct gk20a_ctrl_priv *priv = filp->private_data; + struct gk20a *g = priv->g; + struct nvgpu_gpu_zcull_get_ctx_size_args *get_ctx_size_args; + struct nvgpu_gpu_zcull_get_info_args *get_info_args; + struct nvgpu_gpu_zbc_set_table_args *set_table_args; + struct nvgpu_gpu_zbc_query_table_args *query_table_args; + u8 buf[NVGPU_GPU_IOCTL_MAX_ARG_SIZE]; + struct gr_zcull_info *zcull_info; + struct zbc_entry *zbc_val; + struct zbc_query_params *zbc_tbl; + int i, err = 0; + + nvgpu_log_fn(g, "start %d", _IOC_NR(cmd)); + + if ((_IOC_TYPE(cmd) != NVGPU_GPU_IOCTL_MAGIC) || + (_IOC_NR(cmd) == 0) || + (_IOC_NR(cmd) > NVGPU_GPU_IOCTL_LAST) || + (_IOC_SIZE(cmd) > NVGPU_GPU_IOCTL_MAX_ARG_SIZE)) + return -EINVAL; + + memset(buf, 0, sizeof(buf)); + if (_IOC_DIR(cmd) & _IOC_WRITE) { + if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + } + + if (!g->sw_ready) { + err = gk20a_busy(g); + if (err) + return err; + + gk20a_idle(g); + } + + nvgpu_speculation_barrier(); + switch (cmd) { + case NVGPU_GPU_IOCTL_ZCULL_GET_CTX_SIZE: + get_ctx_size_args = (struct nvgpu_gpu_zcull_get_ctx_size_args *)buf; + + get_ctx_size_args->size = gr_gk20a_get_ctxsw_zcull_size(g, &g->gr); + + break; + case NVGPU_GPU_IOCTL_ZCULL_GET_INFO: + get_info_args = (struct nvgpu_gpu_zcull_get_info_args *)buf; + + memset(get_info_args, 0, sizeof(struct nvgpu_gpu_zcull_get_info_args)); + + zcull_info = nvgpu_kzalloc(g, sizeof(struct gr_zcull_info)); + if (zcull_info == NULL) + return -ENOMEM; + + err = g->ops.gr.get_zcull_info(g, &g->gr, zcull_info); + if (err) { + nvgpu_kfree(g, zcull_info); + break; + } + + get_info_args->width_align_pixels = zcull_info->width_align_pixels; + get_info_args->height_align_pixels = zcull_info->height_align_pixels; + get_info_args->pixel_squares_by_aliquots = zcull_info->pixel_squares_by_aliquots; + get_info_args->aliquot_total = zcull_info->aliquot_total; + get_info_args->region_byte_multiplier = zcull_info->region_byte_multiplier; + get_info_args->region_header_size = zcull_info->region_header_size; + get_info_args->subregion_header_size = zcull_info->subregion_header_size; + get_info_args->subregion_width_align_pixels = zcull_info->subregion_width_align_pixels; + get_info_args->subregion_height_align_pixels = zcull_info->subregion_height_align_pixels; + get_info_args->subregion_count = zcull_info->subregion_count; + + nvgpu_kfree(g, zcull_info); + break; + case NVGPU_GPU_IOCTL_ZBC_SET_TABLE: + set_table_args = (struct nvgpu_gpu_zbc_set_table_args *)buf; + + zbc_val = nvgpu_kzalloc(g, sizeof(struct zbc_entry)); + if (zbc_val == NULL) + return -ENOMEM; + + zbc_val->format = set_table_args->format; + zbc_val->type = set_table_args->type; + + nvgpu_speculation_barrier(); + switch (zbc_val->type) { + case GK20A_ZBC_TYPE_COLOR: + for (i = 0; i < GK20A_ZBC_COLOR_VALUE_SIZE; i++) { + zbc_val->color_ds[i] = set_table_args->color_ds[i]; + zbc_val->color_l2[i] = set_table_args->color_l2[i]; + } + break; + case GK20A_ZBC_TYPE_DEPTH: + case T19X_ZBC: + zbc_val->depth = set_table_args->depth; + break; + default: + err = -EINVAL; + } + + if (!err) { + err = gk20a_busy(g); + if (!err) { + err = g->ops.gr.zbc_set_table(g, &g->gr, + zbc_val); + gk20a_idle(g); + } + } + + if (zbc_val) + nvgpu_kfree(g, zbc_val); + break; + case NVGPU_GPU_IOCTL_ZBC_QUERY_TABLE: + query_table_args = (struct nvgpu_gpu_zbc_query_table_args *)buf; + + zbc_tbl = nvgpu_kzalloc(g, sizeof(struct zbc_query_params)); + if (zbc_tbl == NULL) + return -ENOMEM; + + zbc_tbl->type = query_table_args->type; + zbc_tbl->index_size = query_table_args->index_size; + + err = g->ops.gr.zbc_query_table(g, &g->gr, zbc_tbl); + + if (!err) { + switch (zbc_tbl->type) { + case GK20A_ZBC_TYPE_COLOR: + for (i = 0; i < GK20A_ZBC_COLOR_VALUE_SIZE; i++) { + query_table_args->color_ds[i] = zbc_tbl->color_ds[i]; + query_table_args->color_l2[i] = zbc_tbl->color_l2[i]; + } + break; + case GK20A_ZBC_TYPE_DEPTH: + case T19X_ZBC: + query_table_args->depth = zbc_tbl->depth; + break; + case GK20A_ZBC_TYPE_INVALID: + query_table_args->index_size = zbc_tbl->index_size; + break; + default: + err = -EINVAL; + } + if (!err) { + query_table_args->format = zbc_tbl->format; + query_table_args->ref_cnt = zbc_tbl->ref_cnt; + } + } + + if (zbc_tbl) + nvgpu_kfree(g, zbc_tbl); + break; + + case NVGPU_GPU_IOCTL_GET_CHARACTERISTICS: + err = gk20a_ctrl_ioctl_gpu_characteristics( + g, (struct nvgpu_gpu_get_characteristics *)buf); + break; + case NVGPU_GPU_IOCTL_PREPARE_COMPRESSIBLE_READ: + err = gk20a_ctrl_prepare_compressible_read(g, + (struct nvgpu_gpu_prepare_compressible_read_args *)buf); + break; + case NVGPU_GPU_IOCTL_MARK_COMPRESSIBLE_WRITE: + err = gk20a_ctrl_mark_compressible_write(g, + (struct nvgpu_gpu_mark_compressible_write_args *)buf); + break; + case NVGPU_GPU_IOCTL_ALLOC_AS: + err = gk20a_ctrl_alloc_as(g, + (struct nvgpu_alloc_as_args *)buf); + break; + case NVGPU_GPU_IOCTL_OPEN_TSG: + err = gk20a_ctrl_open_tsg(g, + (struct nvgpu_gpu_open_tsg_args *)buf); + break; + case NVGPU_GPU_IOCTL_GET_TPC_MASKS: + err = gk20a_ctrl_get_tpc_masks(g, + (struct nvgpu_gpu_get_tpc_masks_args *)buf); + break; + case NVGPU_GPU_IOCTL_GET_FBP_L2_MASKS: + err = gk20a_ctrl_get_fbp_l2_masks(g, + (struct nvgpu_gpu_get_fbp_l2_masks_args *)buf); + break; + case NVGPU_GPU_IOCTL_OPEN_CHANNEL: + /* this arg type here, but ..gpu_open_channel_args in nvgpu.h + * for consistency - they are the same */ + err = gk20a_channel_open_ioctl(g, + (struct nvgpu_channel_open_args *)buf); + break; + case NVGPU_GPU_IOCTL_FLUSH_L2: + err = nvgpu_gpu_ioctl_l2_fb_ops(g, + (struct nvgpu_gpu_l2_fb_args *)buf); + break; + + case NVGPU_GPU_IOCTL_SET_MMUDEBUG_MODE: + err = nvgpu_gpu_ioctl_set_mmu_debug_mode(g, + (struct nvgpu_gpu_mmu_debug_mode_args *)buf); + break; + + case NVGPU_GPU_IOCTL_SET_SM_DEBUG_MODE: + err = gr_gk20a_elpg_protected_call(g, + nvgpu_gpu_ioctl_set_debug_mode(g, (struct nvgpu_gpu_sm_debug_mode_args *)buf)); + break; + + case NVGPU_GPU_IOCTL_TRIGGER_SUSPEND: + err = nvgpu_gpu_ioctl_trigger_suspend(g); + break; + + case NVGPU_GPU_IOCTL_WAIT_FOR_PAUSE: + err = nvgpu_gpu_ioctl_wait_for_pause(g, + (struct nvgpu_gpu_wait_pause_args *)buf); + break; + + case NVGPU_GPU_IOCTL_RESUME_FROM_PAUSE: + err = nvgpu_gpu_ioctl_resume_from_pause(g); + break; + + case NVGPU_GPU_IOCTL_CLEAR_SM_ERRORS: + err = nvgpu_gpu_ioctl_clear_sm_errors(g); + break; + + case NVGPU_GPU_IOCTL_GET_TPC_EXCEPTION_EN_STATUS: + err = nvgpu_gpu_ioctl_has_any_exception(g, + (struct nvgpu_gpu_tpc_exception_en_status_args *)buf); + break; + + case NVGPU_GPU_IOCTL_NUM_VSMS: + err = gk20a_ctrl_get_num_vsms(g, + (struct nvgpu_gpu_num_vsms *)buf); + break; + case NVGPU_GPU_IOCTL_VSMS_MAPPING: + err = gk20a_ctrl_vsm_mapping(g, + (struct nvgpu_gpu_vsms_mapping *)buf); + break; + + case NVGPU_GPU_IOCTL_GET_CPU_TIME_CORRELATION_INFO: + err = nvgpu_gpu_get_cpu_time_correlation_info(g, + (struct nvgpu_gpu_get_cpu_time_correlation_info_args *)buf); + break; + + case NVGPU_GPU_IOCTL_GET_GPU_TIME: + err = nvgpu_gpu_get_gpu_time(g, + (struct nvgpu_gpu_get_gpu_time_args *)buf); + break; + + case NVGPU_GPU_IOCTL_GET_ENGINE_INFO: + err = nvgpu_gpu_get_engine_info(g, + (struct nvgpu_gpu_get_engine_info_args *)buf); + break; + + case NVGPU_GPU_IOCTL_ALLOC_VIDMEM: + err = nvgpu_gpu_alloc_vidmem(g, + (struct nvgpu_gpu_alloc_vidmem_args *)buf); + break; + + case NVGPU_GPU_IOCTL_GET_MEMORY_STATE: + err = nvgpu_gpu_get_memory_state(g, + (struct nvgpu_gpu_get_memory_state_args *)buf); + break; + + case NVGPU_GPU_IOCTL_CLK_GET_RANGE: + err = nvgpu_gpu_clk_get_range(g, priv, + (struct nvgpu_gpu_clk_range_args *)buf); + break; + + case NVGPU_GPU_IOCTL_CLK_GET_VF_POINTS: + err = nvgpu_gpu_clk_get_vf_points(g, priv, + (struct nvgpu_gpu_clk_vf_points_args *)buf); + break; + + case NVGPU_GPU_IOCTL_CLK_SET_INFO: + err = nvgpu_gpu_clk_set_info(g, priv, + (struct nvgpu_gpu_clk_set_info_args *)buf); + break; + + case NVGPU_GPU_IOCTL_CLK_GET_INFO: + err = nvgpu_gpu_clk_get_info(g, priv, + (struct nvgpu_gpu_clk_get_info_args *)buf); + break; + + case NVGPU_GPU_IOCTL_GET_EVENT_FD: + err = nvgpu_gpu_get_event_fd(g, priv, + (struct nvgpu_gpu_get_event_fd_args *)buf); + break; + + case NVGPU_GPU_IOCTL_GET_VOLTAGE: + err = nvgpu_gpu_get_voltage(g, + (struct nvgpu_gpu_get_voltage_args *)buf); + break; + + case NVGPU_GPU_IOCTL_GET_CURRENT: + err = nvgpu_gpu_get_current(g, + (struct nvgpu_gpu_get_current_args *)buf); + break; + + case NVGPU_GPU_IOCTL_GET_POWER: + err = nvgpu_gpu_get_power(g, + (struct nvgpu_gpu_get_power_args *)buf); + break; + + case NVGPU_GPU_IOCTL_GET_TEMPERATURE: + err = nvgpu_gpu_get_temperature(g, + (struct nvgpu_gpu_get_temperature_args *)buf); + break; + + case NVGPU_GPU_IOCTL_SET_THERM_ALERT_LIMIT: + err = nvgpu_gpu_set_therm_alert_limit(g, + (struct nvgpu_gpu_set_therm_alert_limit_args *)buf); + break; + + case NVGPU_GPU_IOCTL_SET_DETERMINISTIC_OPTS: + err = nvgpu_gpu_set_deterministic_opts(g, + (struct nvgpu_gpu_set_deterministic_opts_args *)buf); + break; + + default: + nvgpu_log_info(g, "unrecognized gpu ioctl cmd: 0x%x", cmd); + err = -ENOTTY; + break; + } + + if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ)) + err = copy_to_user((void __user *)arg, buf, _IOC_SIZE(cmd)); + + return err; +} + +static void usermode_vma_close(struct vm_area_struct *vma) +{ + struct gk20a_ctrl_priv *priv = vma->vm_private_data; + struct gk20a *g = priv->g; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + nvgpu_mutex_acquire(&l->ctrl.privs_lock); + priv->usermode_vma.vma = NULL; + priv->usermode_vma.vma_mapped = false; + nvgpu_mutex_release(&l->ctrl.privs_lock); +} + +struct vm_operations_struct usermode_vma_ops = { + /* no .open - we use VM_DONTCOPY and don't support fork */ + .close = usermode_vma_close, +}; + +int gk20a_ctrl_dev_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct gk20a_ctrl_priv *priv = filp->private_data; + struct gk20a *g = priv->g; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + u64 addr; + int err; + + if (g->ops.fifo.usermode_base == NULL) + return -ENOSYS; + + if (priv->usermode_vma.vma != NULL) + return -EBUSY; + + if (vma->vm_end - vma->vm_start != SZ_4K) + return -EINVAL; + + if (vma->vm_pgoff != 0UL) + return -EINVAL; + + addr = l->regs_bus_addr + g->ops.fifo.usermode_base(g); + + /* Sync with poweron/poweroff, and require valid regs */ + err = gk20a_busy(g); + if (err) { + return err; + } + + nvgpu_mutex_acquire(&l->ctrl.privs_lock); + + vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE | + VM_DONTDUMP | VM_PFNMAP; + vma->vm_ops = &usermode_vma_ops; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + err = io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot); + if (!err) { + priv->usermode_vma.vma = vma; + priv->usermode_vma.flags = vma->vm_flags; + vma->vm_private_data = priv; + priv->usermode_vma.vma_mapped = true; + } + nvgpu_mutex_release(&l->ctrl.privs_lock); + + gk20a_idle(g); + + return err; +} + +static void alter_usermode_mapping(struct gk20a *g, + struct gk20a_ctrl_priv *priv, + bool poweroff) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct vm_area_struct *vma = priv->usermode_vma.vma; + bool vma_mapped = priv->usermode_vma.vma_mapped; + u64 addr; + int err; + + if (!vma) { + /* Nothing to do - no mmap called */ + return; + } + + addr = l->regs_bus_addr + g->ops.fifo.usermode_base(g); + + down_write(&vma->vm_mm->mmap_sem); + + /* + * This is a no-op for the below cases + * a) poweroff and !vma_mapped - > do nothing as no map exists + * b) !poweroff and vmap_mapped -> do nothing as already mapped + */ + if (poweroff && vma_mapped) { + err = zap_vma_ptes(vma, vma->vm_start, SZ_4K); + if (err == 0) { + vma->vm_flags = VM_NONE; + priv->usermode_vma.vma_mapped = false; + } else { + nvgpu_err(g, "can't remove usermode mapping"); + } + } else if (!poweroff && !vma_mapped) { + vma->vm_flags = priv->usermode_vma.flags; + err = io_remap_pfn_range(vma, vma->vm_start, + addr >> PAGE_SHIFT, + SZ_4K, vma->vm_page_prot); + if (err != 0) { + nvgpu_err(g, "can't restore usermode mapping"); + vma->vm_flags = VM_NONE; + } else { + priv->usermode_vma.vma_mapped = true; + } + } + + up_write(&vma->vm_mm->mmap_sem); +} + +static void alter_usermode_mappings(struct gk20a *g, bool poweroff) +{ + struct gk20a_ctrl_priv *priv; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + nvgpu_mutex_acquire(&l->ctrl.privs_lock); + nvgpu_list_for_each_entry(priv, &l->ctrl.privs, + gk20a_ctrl_priv, list) { + alter_usermode_mapping(g, priv, poweroff); + } + nvgpu_mutex_release(&l->ctrl.privs_lock); +} + +void nvgpu_hide_usermode_for_poweroff(struct gk20a *g) +{ + alter_usermode_mappings(g, true); +} + +void nvgpu_restore_usermode_for_poweron(struct gk20a *g) +{ + alter_usermode_mappings(g, false); +} diff --git a/include/os/linux/ioctl_ctrl.h b/include/os/linux/ioctl_ctrl.h new file mode 100644 index 0000000..3e1f798 --- /dev/null +++ b/include/os/linux/ioctl_ctrl.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __NVGPU_IOCTL_CTRL_H__ +#define __NVGPU_IOCTL_CTRL_H__ + +int gk20a_ctrl_dev_open(struct inode *inode, struct file *filp); +int gk20a_ctrl_dev_release(struct inode *inode, struct file *filp); +long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +int gk20a_ctrl_dev_mmap(struct file *filp, struct vm_area_struct *vma); + +void nvgpu_hide_usermode_for_poweroff(struct gk20a *g); +void nvgpu_restore_usermode_for_poweron(struct gk20a *g); + +#endif diff --git a/include/os/linux/ioctl_dbg.c b/include/os/linux/ioctl_dbg.c new file mode 100644 index 0000000..b5a1071 --- /dev/null +++ b/include/os/linux/ioctl_dbg.c @@ -0,0 +1,2210 @@ +/* + * Tegra GK20A GPU Debugger/Profiler Driver + * + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "gk20a/gr_gk20a.h" +#include "gk20a/regops_gk20a.h" +#include "gk20a/dbg_gpu_gk20a.h" +#include "os_linux.h" +#include "platform_gk20a.h" +#include "ioctl_dbg.h" +#include "ioctl_channel.h" +#include "dmabuf_vidmem.h" + +struct dbg_session_gk20a_linux { + struct device *dev; + struct dbg_session_gk20a dbg_s; +}; + +struct dbg_session_channel_data_linux { + /* + * We have to keep a ref to the _file_, not the channel, because + * close(channel_fd) is synchronous and would deadlock if we had an + * open debug session fd holding a channel ref at that time. Holding a + * ref to the file makes close(channel_fd) just drop a kernel ref to + * the file; the channel will close when the last file ref is dropped. + */ + struct file *ch_f; + struct dbg_session_channel_data ch_data; +}; +/* turn seriously unwieldy names -> something shorter */ +#define REGOP_LINUX(x) NVGPU_DBG_GPU_REG_OP_##x + +/* silly allocator - just increment id */ +static nvgpu_atomic_t unique_id = NVGPU_ATOMIC_INIT(0); +static int generate_unique_id(void) +{ + return nvgpu_atomic_add_return(1, &unique_id); +} + +static int alloc_profiler(struct gk20a *g, + struct dbg_profiler_object_data **_prof) +{ + struct dbg_profiler_object_data *prof; + *_prof = NULL; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + prof = nvgpu_kzalloc(g, sizeof(*prof)); + if (!prof) + return -ENOMEM; + + prof->prof_handle = generate_unique_id(); + *_prof = prof; + return 0; +} + +static int alloc_session(struct gk20a *g, struct dbg_session_gk20a_linux **_dbg_s_linux) +{ + struct dbg_session_gk20a_linux *dbg_s_linux; + *_dbg_s_linux = NULL; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + dbg_s_linux = nvgpu_kzalloc(g, sizeof(*dbg_s_linux)); + if (!dbg_s_linux) + return -ENOMEM; + + dbg_s_linux->dbg_s.id = generate_unique_id(); + *_dbg_s_linux = dbg_s_linux; + return 0; +} + +static int gk20a_perfbuf_release_locked(struct gk20a *g, u64 offset); + +static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_exec_reg_ops_args *args); + +static int nvgpu_ioctl_powergate_gk20a(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_powergate_args *args); + +static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *args); + +static int nvgpu_dbg_gpu_ioctl_hwpm_ctxsw_mode(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_hwpm_ctxsw_mode_args *args); + +static int nvgpu_dbg_gpu_ioctl_set_mmu_debug_mode( + struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_set_ctx_mmu_debug_mode_args *args); + +static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm( + struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_suspend_resume_all_sms_args *args); + +static int nvgpu_ioctl_allocate_profiler_object(struct dbg_session_gk20a_linux *dbg_s, + struct nvgpu_dbg_gpu_profiler_obj_mgt_args *args); + +static int nvgpu_ioctl_free_profiler_object(struct dbg_session_gk20a_linux *dbg_s_linux, + struct nvgpu_dbg_gpu_profiler_obj_mgt_args *args); + +static int nvgpu_ioctl_profiler_reserve(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_profiler_reserve_args *args); + +static int gk20a_perfbuf_map(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_perfbuf_map_args *args); + +static int gk20a_perfbuf_unmap(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_perfbuf_unmap_args *args); + +static int nvgpu_dbg_timeout_enable(struct dbg_session_gk20a *dbg_s, + int timeout_mode); + +static int nvgpu_profiler_reserve_acquire(struct dbg_session_gk20a *dbg_s, + u32 profiler_handle); + +static void gk20a_dbg_session_nvgpu_mutex_acquire(struct dbg_session_gk20a *dbg_s); + +static void gk20a_dbg_session_nvgpu_mutex_release(struct dbg_session_gk20a *dbg_s); + +static int nvgpu_profiler_reserve_release(struct dbg_session_gk20a *dbg_s, + u32 profiler_handle); + +static int dbg_unbind_all_channels_gk20a(struct dbg_session_gk20a *dbg_s); + +static int gk20a_dbg_gpu_do_dev_open(struct inode *inode, + struct file *filp, bool is_profiler); + +static int nvgpu_set_sm_exception_type_mask_locked( + struct dbg_session_gk20a *dbg_s, + u32 exception_mask); + +unsigned int gk20a_dbg_gpu_dev_poll(struct file *filep, poll_table *wait) +{ + unsigned int mask = 0; + struct dbg_session_gk20a_linux *dbg_session_linux = filep->private_data; + struct dbg_session_gk20a *dbg_s = &dbg_session_linux->dbg_s; + struct gk20a *g = dbg_s->g; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + poll_wait(filep, &dbg_s->dbg_events.wait_queue.wq, wait); + + gk20a_dbg_session_nvgpu_mutex_acquire(dbg_s); + + if (dbg_s->dbg_events.events_enabled && + dbg_s->dbg_events.num_pending_events > 0) { + nvgpu_log(g, gpu_dbg_gpu_dbg, "found pending event on session id %d", + dbg_s->id); + nvgpu_log(g, gpu_dbg_gpu_dbg, "%d events pending", + dbg_s->dbg_events.num_pending_events); + mask = (POLLPRI | POLLIN); + } + + gk20a_dbg_session_nvgpu_mutex_release(dbg_s); + + return mask; +} + +int gk20a_dbg_gpu_dev_release(struct inode *inode, struct file *filp) +{ + struct dbg_session_gk20a_linux *dbg_session_linux = filp->private_data; + struct dbg_session_gk20a *dbg_s = &dbg_session_linux->dbg_s; + struct gk20a *g = dbg_s->g; + struct dbg_profiler_object_data *prof_obj, *tmp_obj; + + nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, "%s", g->name); + + /* unbind channels */ + dbg_unbind_all_channels_gk20a(dbg_s); + + /* Powergate/Timeout enable is called here as possibility of dbg_session + * which called powergate/timeout disable ioctl, to be killed without + * calling powergate/timeout enable ioctl + */ + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + if (dbg_s->is_pg_disabled) { + nvgpu_set_powergate_locked(dbg_s, false); + } + nvgpu_dbg_timeout_enable(dbg_s, NVGPU_DBG_GPU_IOCTL_TIMEOUT_ENABLE); + + /* If this session owned the perf buffer, release it */ + if (g->perfbuf.owner == dbg_s) + gk20a_perfbuf_release_locked(g, g->perfbuf.offset); + + /* Per-context profiler objects were released when we called + * dbg_unbind_all_channels. We could still have global ones. + */ + nvgpu_list_for_each_entry_safe(prof_obj, tmp_obj, &g->profiler_objects, + dbg_profiler_object_data, prof_obj_entry) { + if (prof_obj->session_id == dbg_s->id) { + if (prof_obj->has_reservation) + g->ops.dbg_session_ops. + release_profiler_reservation(dbg_s, prof_obj); + nvgpu_list_del(&prof_obj->prof_obj_entry); + nvgpu_kfree(g, prof_obj); + } + } + nvgpu_mutex_release(&g->dbg_sessions_lock); + + nvgpu_mutex_destroy(&dbg_s->ch_list_lock); + nvgpu_mutex_destroy(&dbg_s->ioctl_lock); + + nvgpu_kfree(g, dbg_session_linux); + gk20a_put(g); + + return 0; +} + +int gk20a_prof_gpu_dev_open(struct inode *inode, struct file *filp) +{ + struct nvgpu_os_linux *l = container_of(inode->i_cdev, + struct nvgpu_os_linux, prof.cdev); + struct gk20a *g = &l->g; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + return gk20a_dbg_gpu_do_dev_open(inode, filp, true /* is profiler */); +} + +static int nvgpu_dbg_gpu_ioctl_timeout(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_timeout_args *args) +{ + int err; + struct gk20a *g = dbg_s->g; + + nvgpu_log(g, gpu_dbg_fn, "timeout enable/disable = %d", args->enable); + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + err = nvgpu_dbg_timeout_enable(dbg_s, args->enable); + nvgpu_mutex_release(&g->dbg_sessions_lock); + + return err; +} + +static int nvgpu_dbg_gpu_ioctl_read_single_sm_error_state( + struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_read_single_sm_error_state_args *args) +{ + struct gk20a *g = dbg_s->g; + struct gr_gk20a *gr = &g->gr; + struct nvgpu_tsg_sm_error_state *sm_error_state; + struct nvgpu_dbg_gpu_sm_error_state_record sm_error_state_record; + struct channel_gk20a *ch; + struct tsg_gk20a *tsg; + u32 sm_id; + int err = 0; + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (ch == NULL) { + return -EINVAL; + } + + tsg = tsg_gk20a_from_ch(ch); + if (tsg == NULL) { + nvgpu_err(g, "no valid tsg from ch"); + return -EINVAL; + } + + sm_id = args->sm_id; + if (sm_id >= gr->no_of_sm) { + return -EINVAL; + } + + if (tsg->sm_error_states == NULL) { + return -EINVAL; + } + + nvgpu_speculation_barrier(); + + sm_error_state = tsg->sm_error_states + sm_id; + sm_error_state_record.hww_global_esr = + sm_error_state->hww_global_esr; + sm_error_state_record.hww_warp_esr = + sm_error_state->hww_warp_esr; + sm_error_state_record.hww_warp_esr_pc = + sm_error_state->hww_warp_esr_pc; + sm_error_state_record.hww_global_esr_report_mask = + sm_error_state->hww_global_esr_report_mask; + sm_error_state_record.hww_warp_esr_report_mask = + sm_error_state->hww_warp_esr_report_mask; + + if (args->sm_error_state_record_size > 0) { + size_t write_size = sizeof(*sm_error_state); + + nvgpu_speculation_barrier(); + if (write_size > args->sm_error_state_record_size) + write_size = args->sm_error_state_record_size; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + err = copy_to_user((void __user *)(uintptr_t) + args->sm_error_state_record_mem, + &sm_error_state_record, + write_size); + nvgpu_mutex_release(&g->dbg_sessions_lock); + if (err != 0) { + nvgpu_err(g, "copy_to_user failed!"); + return err; + } + + args->sm_error_state_record_size = write_size; + } + + return 0; +} + + +static int nvgpu_dbg_gpu_ioctl_set_next_stop_trigger_type( + struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_set_next_stop_trigger_type_args *args) +{ + struct gk20a *g = dbg_s->g; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + gk20a_dbg_session_nvgpu_mutex_acquire(dbg_s); + + dbg_s->broadcast_stop_trigger = (args->broadcast != 0); + + gk20a_dbg_session_nvgpu_mutex_release(dbg_s); + + return 0; +} + +static int nvgpu_dbg_timeout_enable(struct dbg_session_gk20a *dbg_s, + int timeout_mode) +{ + struct gk20a *g = dbg_s->g; + int err = 0; + + nvgpu_log(g, gpu_dbg_gpu_dbg, "Timeouts mode requested : %d", + timeout_mode); + + nvgpu_speculation_barrier(); + switch (timeout_mode) { + case NVGPU_DBG_GPU_IOCTL_TIMEOUT_ENABLE: + if (dbg_s->is_timeout_disabled == true) + nvgpu_atomic_dec(&g->timeouts_disabled_refcount); + dbg_s->is_timeout_disabled = false; + break; + + case NVGPU_DBG_GPU_IOCTL_TIMEOUT_DISABLE: + if (dbg_s->is_timeout_disabled == false) + nvgpu_atomic_inc(&g->timeouts_disabled_refcount); + dbg_s->is_timeout_disabled = true; + break; + + default: + nvgpu_err(g, + "unrecognized dbg gpu timeout mode : 0x%x", + timeout_mode); + err = -EINVAL; + break; + } + + if (!err) + nvgpu_log(g, gpu_dbg_gpu_dbg, "dbg is timeout disabled %s, " + "timeouts disabled refcount %d", + dbg_s->is_timeout_disabled ? "true" : "false", + nvgpu_atomic_read(&g->timeouts_disabled_refcount)); + return err; +} + +static int gk20a_dbg_gpu_do_dev_open(struct inode *inode, + struct file *filp, bool is_profiler) +{ + struct nvgpu_os_linux *l; + struct dbg_session_gk20a_linux *dbg_session_linux; + struct dbg_session_gk20a *dbg_s; + struct gk20a *g; + + struct device *dev; + + int err; + + if (!is_profiler) + l = container_of(inode->i_cdev, + struct nvgpu_os_linux, dbg.cdev); + else + l = container_of(inode->i_cdev, + struct nvgpu_os_linux, prof.cdev); + g = gk20a_get(&l->g); + if (!g) + return -ENODEV; + + dev = dev_from_gk20a(g); + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "dbg session: %s", g->name); + + err = alloc_session(g, &dbg_session_linux); + if (err) + goto free_ref; + + dbg_s = &dbg_session_linux->dbg_s; + + filp->private_data = dbg_session_linux; + dbg_session_linux->dev = dev; + dbg_s->g = g; + dbg_s->is_profiler = is_profiler; + dbg_s->is_pg_disabled = false; + dbg_s->is_timeout_disabled = false; + + nvgpu_cond_init(&dbg_s->dbg_events.wait_queue); + nvgpu_init_list_node(&dbg_s->ch_list); + err = nvgpu_mutex_init(&dbg_s->ch_list_lock); + if (err) + goto err_free_session; + err = nvgpu_mutex_init(&dbg_s->ioctl_lock); + if (err) + goto err_destroy_lock; + dbg_s->dbg_events.events_enabled = false; + dbg_s->dbg_events.num_pending_events = 0; + + return 0; + +err_destroy_lock: + nvgpu_mutex_destroy(&dbg_s->ch_list_lock); +err_free_session: + nvgpu_kfree(g, dbg_session_linux); +free_ref: + gk20a_put(g); + return err; +} + +void nvgpu_dbg_session_post_event(struct dbg_session_gk20a *dbg_s) +{ + nvgpu_cond_broadcast_interruptible(&dbg_s->dbg_events.wait_queue); +} + +static int dbg_unbind_single_channel_gk20a(struct dbg_session_gk20a *dbg_s, + struct dbg_session_channel_data *ch_data) +{ + struct gk20a *g = dbg_s->g; + u32 chid; + struct dbg_session_data *session_data; + struct dbg_profiler_object_data *prof_obj, *tmp_obj; + struct dbg_session_channel_data_linux *ch_data_linux; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + chid = ch_data->chid; + + /* If there's a profiler ctx reservation record associated with this + * session/channel pair, release it. + */ + nvgpu_list_for_each_entry_safe(prof_obj, tmp_obj, &g->profiler_objects, + dbg_profiler_object_data, prof_obj_entry) { + if ((prof_obj->session_id == dbg_s->id) && + (prof_obj->ch->chid == chid)) { + if (prof_obj->has_reservation) { + g->ops.dbg_session_ops. + release_profiler_reservation(dbg_s, prof_obj); + } + nvgpu_list_del(&prof_obj->prof_obj_entry); + nvgpu_kfree(g, prof_obj); + } + } + + nvgpu_list_del(&ch_data->ch_entry); + + session_data = ch_data->session_data; + nvgpu_list_del(&session_data->dbg_s_entry); + nvgpu_kfree(dbg_s->g, session_data); + + ch_data_linux = container_of(ch_data, struct dbg_session_channel_data_linux, + ch_data); + + fput(ch_data_linux->ch_f); + nvgpu_kfree(dbg_s->g, ch_data_linux); + + return 0; +} + +static int dbg_bind_channel_gk20a(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_bind_channel_args *args) +{ + struct file *f; + struct gk20a *g = dbg_s->g; + struct channel_gk20a *ch; + struct dbg_session_channel_data_linux *ch_data_linux; + struct dbg_session_data *session_data; + int err = 0; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s fd=%d", + g->name, args->channel_fd); + + /* + * Although gk20a_get_channel_from_file gives us a channel ref, need to + * hold a ref to the file during the session lifetime. See comment in + * struct dbg_session_channel_data. + */ + f = fget(args->channel_fd); + if (!f) + return -ENODEV; + + ch = gk20a_get_channel_from_file(args->channel_fd); + if (!ch) { + nvgpu_log_fn(g, "no channel found for fd"); + err = -EINVAL; + goto out_fput; + } + + nvgpu_log_fn(g, "%s hwchid=%d", g->name, ch->chid); + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + nvgpu_mutex_acquire(&ch->dbg_s_lock); + + ch_data_linux = nvgpu_kzalloc(g, sizeof(*ch_data_linux)); + if (!ch_data_linux) { + err = -ENOMEM; + goto out_chput; + } + ch_data_linux->ch_f = f; + ch_data_linux->ch_data.channel_fd = args->channel_fd; + ch_data_linux->ch_data.chid = ch->chid; + ch_data_linux->ch_data.unbind_single_channel = dbg_unbind_single_channel_gk20a; + nvgpu_init_list_node(&ch_data_linux->ch_data.ch_entry); + + session_data = nvgpu_kzalloc(g, sizeof(*session_data)); + if (!session_data) { + err = -ENOMEM; + goto out_kfree; + } + session_data->dbg_s = dbg_s; + nvgpu_init_list_node(&session_data->dbg_s_entry); + ch_data_linux->ch_data.session_data = session_data; + + nvgpu_list_add(&session_data->dbg_s_entry, &ch->dbg_s_list); + + nvgpu_mutex_acquire(&dbg_s->ch_list_lock); + nvgpu_list_add_tail(&ch_data_linux->ch_data.ch_entry, &dbg_s->ch_list); + nvgpu_mutex_release(&dbg_s->ch_list_lock); + + nvgpu_mutex_release(&ch->dbg_s_lock); + nvgpu_mutex_release(&g->dbg_sessions_lock); + + gk20a_channel_put(ch); + + return 0; + +out_kfree: + nvgpu_kfree(g, ch_data_linux); +out_chput: + gk20a_channel_put(ch); + nvgpu_mutex_release(&ch->dbg_s_lock); + nvgpu_mutex_release(&g->dbg_sessions_lock); +out_fput: + fput(f); + return err; +} + +static int dbg_unbind_all_channels_gk20a(struct dbg_session_gk20a *dbg_s) +{ + struct dbg_session_channel_data *ch_data, *tmp; + struct gk20a *g = dbg_s->g; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + nvgpu_mutex_acquire(&dbg_s->ch_list_lock); + nvgpu_list_for_each_entry_safe(ch_data, tmp, &dbg_s->ch_list, + dbg_session_channel_data, ch_entry) + ch_data->unbind_single_channel(dbg_s, ch_data); + nvgpu_mutex_release(&dbg_s->ch_list_lock); + nvgpu_mutex_release(&g->dbg_sessions_lock); + + return 0; +} + +/* + * Convert common regops op values of the form of NVGPU_DBG_REG_OP_* + * into linux regops op values of the form of NVGPU_DBG_GPU_REG_OP_* + */ +static u32 nvgpu_get_regops_op_values_linux(u32 regops_op) +{ + switch (regops_op) { + case REGOP(READ_32): + return REGOP_LINUX(READ_32); + case REGOP(WRITE_32): + return REGOP_LINUX(WRITE_32); + case REGOP(READ_64): + return REGOP_LINUX(READ_64); + case REGOP(WRITE_64): + return REGOP_LINUX(WRITE_64); + case REGOP(READ_08): + return REGOP_LINUX(READ_08); + case REGOP(WRITE_08): + return REGOP_LINUX(WRITE_08); + } + + return regops_op; +} + +/* + * Convert linux regops op values of the form of NVGPU_DBG_GPU_REG_OP_* + * into common regops op values of the form of NVGPU_DBG_REG_OP_* + */ +static u32 nvgpu_get_regops_op_values_common(u32 regops_op) +{ + switch (regops_op) { + case REGOP_LINUX(READ_32): + return REGOP(READ_32); + case REGOP_LINUX(WRITE_32): + return REGOP(WRITE_32); + case REGOP_LINUX(READ_64): + return REGOP(READ_64); + case REGOP_LINUX(WRITE_64): + return REGOP(WRITE_64); + case REGOP_LINUX(READ_08): + return REGOP(READ_08); + case REGOP_LINUX(WRITE_08): + return REGOP(WRITE_08); + } + + return regops_op; +} + +/* + * Convert common regops type values of the form of NVGPU_DBG_REG_OP_TYPE_* + * into linux regops type values of the form of NVGPU_DBG_GPU_REG_OP_TYPE_* + */ +static u32 nvgpu_get_regops_type_values_linux(u32 regops_type) +{ + switch (regops_type) { + case REGOP(TYPE_GLOBAL): + return REGOP_LINUX(TYPE_GLOBAL); + case REGOP(TYPE_GR_CTX): + return REGOP_LINUX(TYPE_GR_CTX); + case REGOP(TYPE_GR_CTX_TPC): + return REGOP_LINUX(TYPE_GR_CTX_TPC); + case REGOP(TYPE_GR_CTX_SM): + return REGOP_LINUX(TYPE_GR_CTX_SM); + case REGOP(TYPE_GR_CTX_CROP): + return REGOP_LINUX(TYPE_GR_CTX_CROP); + case REGOP(TYPE_GR_CTX_ZROP): + return REGOP_LINUX(TYPE_GR_CTX_ZROP); + case REGOP(TYPE_GR_CTX_QUAD): + return REGOP_LINUX(TYPE_GR_CTX_QUAD); + } + + return regops_type; +} + +/* + * Convert linux regops type values of the form of NVGPU_DBG_GPU_REG_OP_TYPE_* + * into common regops type values of the form of NVGPU_DBG_REG_OP_TYPE_* + */ +static u32 nvgpu_get_regops_type_values_common(u32 regops_type) +{ + switch (regops_type) { + case REGOP_LINUX(TYPE_GLOBAL): + return REGOP(TYPE_GLOBAL); + case REGOP_LINUX(TYPE_GR_CTX): + return REGOP(TYPE_GR_CTX); + case REGOP_LINUX(TYPE_GR_CTX_TPC): + return REGOP(TYPE_GR_CTX_TPC); + case REGOP_LINUX(TYPE_GR_CTX_SM): + return REGOP(TYPE_GR_CTX_SM); + case REGOP_LINUX(TYPE_GR_CTX_CROP): + return REGOP(TYPE_GR_CTX_CROP); + case REGOP_LINUX(TYPE_GR_CTX_ZROP): + return REGOP(TYPE_GR_CTX_ZROP); + case REGOP_LINUX(TYPE_GR_CTX_QUAD): + return REGOP(TYPE_GR_CTX_QUAD); + } + + return regops_type; +} + +/* + * Convert common regops status values of the form of NVGPU_DBG_REG_OP_STATUS_* + * into linux regops type values of the form of NVGPU_DBG_GPU_REG_OP_STATUS_* + */ +static u32 nvgpu_get_regops_status_values_linux(u32 regops_status) +{ + switch (regops_status) { + case REGOP(STATUS_SUCCESS): + return REGOP_LINUX(STATUS_SUCCESS); + case REGOP(STATUS_INVALID_OP): + return REGOP_LINUX(STATUS_INVALID_OP); + case REGOP(STATUS_INVALID_TYPE): + return REGOP_LINUX(STATUS_INVALID_TYPE); + case REGOP(STATUS_INVALID_OFFSET): + return REGOP_LINUX(STATUS_INVALID_OFFSET); + case REGOP(STATUS_UNSUPPORTED_OP): + return REGOP_LINUX(STATUS_UNSUPPORTED_OP); + case REGOP(STATUS_INVALID_MASK ): + return REGOP_LINUX(STATUS_INVALID_MASK); + } + + return regops_status; +} + +/* + * Convert linux regops status values of the form of NVGPU_DBG_GPU_REG_OP_STATUS_* + * into common regops type values of the form of NVGPU_DBG_REG_OP_STATUS_* + */ +static u32 nvgpu_get_regops_status_values_common(u32 regops_status) +{ + switch (regops_status) { + case REGOP_LINUX(STATUS_SUCCESS): + return REGOP(STATUS_SUCCESS); + case REGOP_LINUX(STATUS_INVALID_OP): + return REGOP(STATUS_INVALID_OP); + case REGOP_LINUX(STATUS_INVALID_TYPE): + return REGOP(STATUS_INVALID_TYPE); + case REGOP_LINUX(STATUS_INVALID_OFFSET): + return REGOP(STATUS_INVALID_OFFSET); + case REGOP_LINUX(STATUS_UNSUPPORTED_OP): + return REGOP(STATUS_UNSUPPORTED_OP); + case REGOP_LINUX(STATUS_INVALID_MASK ): + return REGOP(STATUS_INVALID_MASK); + } + + return regops_status; +} + +static int nvgpu_get_regops_data_common(struct nvgpu_dbg_gpu_reg_op *in, + struct nvgpu_dbg_reg_op *out, u32 num_ops) +{ + u32 i; + + if(in == NULL || out == NULL) + return -ENOMEM; + + for (i = 0; i < num_ops; i++) { + out[i].op = nvgpu_get_regops_op_values_common(in[i].op); + out[i].type = nvgpu_get_regops_type_values_common(in[i].type); + out[i].status = nvgpu_get_regops_status_values_common(in[i].status); + out[i].quad = in[i].quad; + out[i].group_mask = in[i].group_mask; + out[i].sub_group_mask = in[i].sub_group_mask; + out[i].offset = in[i].offset; + out[i].value_lo = in[i].value_lo; + out[i].value_hi = in[i].value_hi; + out[i].and_n_mask_lo = in[i].and_n_mask_lo; + out[i].and_n_mask_hi = in[i].and_n_mask_hi; + } + + return 0; +} + +static int nvgpu_get_regops_data_linux(struct nvgpu_dbg_reg_op *in, + struct nvgpu_dbg_gpu_reg_op *out, u32 num_ops) +{ + u32 i; + + if(in == NULL || out == NULL) + return -ENOMEM; + + for (i = 0; i < num_ops; i++) { + out[i].op = nvgpu_get_regops_op_values_linux(in[i].op); + out[i].type = nvgpu_get_regops_type_values_linux(in[i].type); + out[i].status = nvgpu_get_regops_status_values_linux(in[i].status); + out[i].quad = in[i].quad; + out[i].group_mask = in[i].group_mask; + out[i].sub_group_mask = in[i].sub_group_mask; + out[i].offset = in[i].offset; + out[i].value_lo = in[i].value_lo; + out[i].value_hi = in[i].value_hi; + out[i].and_n_mask_lo = in[i].and_n_mask_lo; + out[i].and_n_mask_hi = in[i].and_n_mask_hi; + } + + return 0; +} + +static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_exec_reg_ops_args *args) +{ + int err = 0, powergate_err = 0; + bool is_pg_disabled = false; + + struct gk20a *g = dbg_s->g; + struct channel_gk20a *ch; + + bool is_current_ctx; + + + nvgpu_log_fn(g, "%d ops, max fragment %d", args->num_ops, g->dbg_regops_tmp_buf_ops); + + if (args->num_ops > NVGPU_IOCTL_DBG_REG_OPS_LIMIT) { + nvgpu_err(g, "regops limit exceeded"); + return -EINVAL; + } + + if (args->num_ops == 0) { + /* Nothing to do */ + return 0; + } + + if (g->dbg_regops_tmp_buf_ops == 0 || !g->dbg_regops_tmp_buf) { + nvgpu_err(g, "reg ops work buffer not allocated"); + return -ENODEV; + } + + if (!dbg_s->id) { + nvgpu_err(g, "can't call reg_ops on an unbound debugger session"); + return -EINVAL; + } + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (!dbg_s->is_profiler && !ch) { + nvgpu_err(g, "bind a channel before regops for a debugging session"); + return -EINVAL; + } + + /* since exec_reg_ops sends methods to the ucode, it must take the + * global gpu lock to protect against mixing methods from debug sessions + * on other channels */ + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + if (!dbg_s->is_pg_disabled && !g->is_virtual) { + /* In the virtual case, the server will handle + * disabling/enabling powergating when processing reg ops + */ + powergate_err = nvgpu_set_powergate_locked(dbg_s, true); + if (!powergate_err) { + is_pg_disabled = true; + } + } + + if (!powergate_err) { + u64 ops_offset = 0; /* index offset */ + + struct nvgpu_dbg_gpu_reg_op *linux_fragment = NULL; + + linux_fragment = nvgpu_kzalloc(g, g->dbg_regops_tmp_buf_ops * + sizeof(struct nvgpu_dbg_gpu_reg_op)); + + if (!linux_fragment) + return -ENOMEM; + + while (ops_offset < args->num_ops && !err) { + const u64 num_ops = + min(args->num_ops - ops_offset, + (u64)(g->dbg_regops_tmp_buf_ops)); + const u64 fragment_size = + num_ops * sizeof(struct nvgpu_dbg_gpu_reg_op); + + void __user *const fragment = + (void __user *)(uintptr_t) + (args->ops + + ops_offset * sizeof(struct nvgpu_dbg_gpu_reg_op)); + + nvgpu_log_fn(g, "Regops fragment: start_op=%llu ops=%llu", + ops_offset, num_ops); + + nvgpu_log_fn(g, "Copying regops from userspace"); + + if (copy_from_user(linux_fragment, + fragment, fragment_size)) { + nvgpu_err(g, "copy_from_user failed!"); + err = -EFAULT; + break; + } + + err = nvgpu_get_regops_data_common(linux_fragment, + g->dbg_regops_tmp_buf, num_ops); + + if (err) + break; + + err = g->ops.regops.exec_regops( + dbg_s, g->dbg_regops_tmp_buf, num_ops, &is_current_ctx); + + if (err) { + break; + } + + if (ops_offset == 0) { + args->gr_ctx_resident = is_current_ctx; + } + + err = nvgpu_get_regops_data_linux(g->dbg_regops_tmp_buf, + linux_fragment, num_ops); + + if (err) + break; + + nvgpu_log_fn(g, "Copying result to userspace"); + + if (copy_to_user(fragment, linux_fragment, + fragment_size)) { + nvgpu_err(g, "copy_to_user failed!"); + err = -EFAULT; + break; + } + + ops_offset += num_ops; + } + + nvgpu_speculation_barrier(); + nvgpu_kfree(g, linux_fragment); + + /* enable powergate, if previously disabled */ + if (is_pg_disabled) { + powergate_err = nvgpu_set_powergate_locked(dbg_s, + false); + } + } + + nvgpu_mutex_release(&g->dbg_sessions_lock); + + if (!err && powergate_err) + err = powergate_err; + + if (err) + nvgpu_err(g, "dbg regops failed"); + + return err; +} + +static int nvgpu_ioctl_powergate_gk20a(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_powergate_args *args) +{ + int err; + struct gk20a *g = dbg_s->g; + nvgpu_log_fn(g, "%s powergate mode = %d", + g->name, args->mode); + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + if ((args->mode != NVGPU_DBG_GPU_POWERGATE_MODE_DISABLE) && + (args->mode != NVGPU_DBG_GPU_POWERGATE_MODE_ENABLE)) { + nvgpu_err(g, "invalid powergate mode"); + err = -EINVAL; + goto pg_err_end; + } + + err = nvgpu_set_powergate_locked(dbg_s, + args->mode == NVGPU_DBG_GPU_POWERGATE_MODE_DISABLE); +pg_err_end: + nvgpu_mutex_release(&g->dbg_sessions_lock); + return err; +} + +static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *args) +{ + int err; + struct gk20a *g = dbg_s->g; + struct channel_gk20a *ch_gk20a; + + nvgpu_log_fn(g, "%s smpc ctxsw mode = %d", + g->name, args->mode); + + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to poweron"); + return err; + } + + /* Take the global lock, since we'll be doing global regops */ + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + ch_gk20a = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (!ch_gk20a) { + nvgpu_err(g, + "no bound channel for smpc ctxsw mode update"); + err = -EINVAL; + goto clean_up; + } + + err = g->ops.gr.update_smpc_ctxsw_mode(g, ch_gk20a, + args->mode == NVGPU_DBG_GPU_SMPC_CTXSW_MODE_CTXSW); + if (err) { + nvgpu_err(g, + "error (%d) during smpc ctxsw mode update", err); + } + + clean_up: + nvgpu_mutex_release(&g->dbg_sessions_lock); + gk20a_idle(g); + return err; +} + +/* + * Convert linux hwpm ctxsw mode type of the form of NVGPU_DBG_GPU_HWPM_CTXSW_MODE_* + * into common hwpm ctxsw mode type of the form of NVGPU_DBG_HWPM_CTXSW_MODE_* + */ + +static u32 nvgpu_hwpm_ctxsw_mode_to_common_mode(u32 mode) +{ + nvgpu_speculation_barrier(); + switch (mode){ + case NVGPU_DBG_GPU_HWPM_CTXSW_MODE_NO_CTXSW: + return NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW; + case NVGPU_DBG_GPU_HWPM_CTXSW_MODE_CTXSW: + return NVGPU_DBG_HWPM_CTXSW_MODE_CTXSW; + case NVGPU_DBG_GPU_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW: + return NVGPU_DBG_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW; + } + + return mode; +} + + +static int nvgpu_dbg_gpu_ioctl_hwpm_ctxsw_mode(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_hwpm_ctxsw_mode_args *args) +{ + int err; + struct gk20a *g = dbg_s->g; + struct channel_gk20a *ch_gk20a; + u32 mode = nvgpu_hwpm_ctxsw_mode_to_common_mode(args->mode); + + nvgpu_log_fn(g, "%s pm ctxsw mode = %d", g->name, args->mode); + + /* Must have a valid reservation to enable/disable hwpm cxtsw. + * Just print an error message for now, but eventually this should + * return an error, at the point where all client sw has been + * cleaned up. + */ + if (!dbg_s->has_profiler_reservation) { + nvgpu_err(g, + "session doesn't have a valid reservation"); + } + + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to poweron"); + return err; + } + + /* Take the global lock, since we'll be doing global regops */ + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + ch_gk20a = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (!ch_gk20a) { + nvgpu_err(g, + "no bound channel for pm ctxsw mode update"); + err = -EINVAL; + goto clean_up; + } + if (g->dbg_powergating_disabled_refcount == 0) { + nvgpu_err(g, "powergate is not disabled"); + err = -ENOSYS; + goto clean_up; + } + err = g->ops.gr.update_hwpm_ctxsw_mode(g, ch_gk20a, 0, + mode); + + if (err) + nvgpu_err(g, + "error (%d) during pm ctxsw mode update", err); + /* gk20a would require a WAR to set the core PM_ENABLE bit, not + * added here with gk20a being deprecated + */ + clean_up: + nvgpu_mutex_release(&g->dbg_sessions_lock); + gk20a_idle(g); + return err; +} + +static int nvgpu_dbg_gpu_ioctl_set_mmu_debug_mode( + struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_set_ctx_mmu_debug_mode_args *args) +{ + int err; + struct gk20a *g = dbg_s->g; + struct channel_gk20a *ch; + bool enable = (args->mode == NVGPU_DBG_GPU_CTX_MMU_DEBUG_MODE_ENABLED); + + nvgpu_log_fn(g, "mode=%u", args->mode); + + if (args->reserved != 0U) { + return -EINVAL; + } + + if ((g->ops.fb.set_mmu_debug_mode == NULL) && + (g->ops.gr.set_mmu_debug_mode == NULL)) { + return -ENOSYS; + } + + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to poweron"); + return err; + } + + /* Take the global lock, since we'll be doing global regops */ + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (!ch) { + nvgpu_err(g, "no bound channel for mmu debug mode"); + err = -EINVAL; + goto clean_up; + } + + err = nvgpu_tsg_set_mmu_debug_mode(ch, enable); + if (err) { + nvgpu_err(g, "set mmu debug mode failed, err=%d", err); + } + +clean_up: + nvgpu_mutex_release(&g->dbg_sessions_lock); + gk20a_idle(g); + return err; +} + +static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm( + struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_suspend_resume_all_sms_args *args) +{ + struct gk20a *g = dbg_s->g; + struct channel_gk20a *ch; + int err = 0, action = args->mode; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "action: %d", args->mode); + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (!ch) + return -EINVAL; + + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to poweron"); + return err; + } + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + /* Suspend GPU context switching */ + err = gr_gk20a_disable_ctxsw(g); + if (err) { + nvgpu_err(g, "unable to stop gr ctxsw"); + /* this should probably be ctx-fatal... */ + goto clean_up; + } + + nvgpu_speculation_barrier(); + switch (action) { + case NVGPU_DBG_GPU_SUSPEND_ALL_SMS: + gr_gk20a_suspend_context(ch); + break; + + case NVGPU_DBG_GPU_RESUME_ALL_SMS: + gr_gk20a_resume_context(ch); + break; + } + + err = gr_gk20a_enable_ctxsw(g); + if (err) + nvgpu_err(g, "unable to restart ctxsw!"); + +clean_up: + nvgpu_mutex_release(&g->dbg_sessions_lock); + gk20a_idle(g); + + return err; +} + +static int nvgpu_ioctl_allocate_profiler_object( + struct dbg_session_gk20a_linux *dbg_session_linux, + struct nvgpu_dbg_gpu_profiler_obj_mgt_args *args) +{ + int err = 0; + struct dbg_session_gk20a *dbg_s = &dbg_session_linux->dbg_s; + struct gk20a *g = get_gk20a(dbg_session_linux->dev); + struct dbg_profiler_object_data *prof_obj; + + nvgpu_log_fn(g, "%s", g->name); + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + err = alloc_profiler(g, &prof_obj); + if (err) + goto clean_up; + + prof_obj->session_id = dbg_s->id; + + if (dbg_s->is_profiler) + prof_obj->ch = NULL; + else { + prof_obj->ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (prof_obj->ch == NULL) { + nvgpu_err(g, + "bind a channel for dbg session"); + nvgpu_kfree(g, prof_obj); + err = -EINVAL; + goto clean_up; + } + } + + /* Return handle to client */ + args->profiler_handle = prof_obj->prof_handle; + + nvgpu_init_list_node(&prof_obj->prof_obj_entry); + + nvgpu_list_add(&prof_obj->prof_obj_entry, &g->profiler_objects); +clean_up: + nvgpu_mutex_release(&g->dbg_sessions_lock); + return err; +} + +static int nvgpu_ioctl_free_profiler_object( + struct dbg_session_gk20a_linux *dbg_s_linux, + struct nvgpu_dbg_gpu_profiler_obj_mgt_args *args) +{ + int err = 0; + struct dbg_session_gk20a *dbg_s = &dbg_s_linux->dbg_s; + struct gk20a *g = get_gk20a(dbg_s_linux->dev); + struct dbg_profiler_object_data *prof_obj, *tmp_obj; + bool obj_found = false; + + nvgpu_log_fn(g, "%s session_id = %d profiler_handle = %x", + g->name, dbg_s->id, args->profiler_handle); + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + /* Remove profiler object from the list, if a match is found */ + nvgpu_list_for_each_entry_safe(prof_obj, tmp_obj, &g->profiler_objects, + dbg_profiler_object_data, prof_obj_entry) { + if (prof_obj->prof_handle == args->profiler_handle) { + if (prof_obj->session_id != dbg_s->id) { + nvgpu_err(g, + "invalid handle %x", + args->profiler_handle); + err = -EINVAL; + break; + } + if (prof_obj->has_reservation) + g->ops.dbg_session_ops. + release_profiler_reservation(dbg_s, prof_obj); + nvgpu_list_del(&prof_obj->prof_obj_entry); + nvgpu_kfree(g, prof_obj); + obj_found = true; + break; + } + } + if (!obj_found) { + nvgpu_err(g, "profiler %x not found", + args->profiler_handle); + err = -EINVAL; + } + + nvgpu_mutex_release(&g->dbg_sessions_lock); + return err; +} + +static struct dbg_profiler_object_data *find_matching_prof_obj( + struct dbg_session_gk20a *dbg_s, + u32 profiler_handle) +{ + struct gk20a *g = dbg_s->g; + struct dbg_profiler_object_data *prof_obj; + + nvgpu_list_for_each_entry(prof_obj, &g->profiler_objects, + dbg_profiler_object_data, prof_obj_entry) { + if (prof_obj->prof_handle == profiler_handle) { + if (prof_obj->session_id != dbg_s->id) { + nvgpu_err(g, + "invalid handle %x", + profiler_handle); + return NULL; + } + return prof_obj; + } + } + return NULL; +} + +/* used in scenarios where the debugger session can take just the inter-session + * lock for performance, but the profiler session must take the per-gpu lock + * since it might not have an associated channel. */ +static void gk20a_dbg_session_nvgpu_mutex_acquire(struct dbg_session_gk20a *dbg_s) +{ + struct channel_gk20a *ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + + if (dbg_s->is_profiler || !ch) + nvgpu_mutex_acquire(&dbg_s->g->dbg_sessions_lock); + else + nvgpu_mutex_acquire(&ch->dbg_s_lock); +} + +static void gk20a_dbg_session_nvgpu_mutex_release(struct dbg_session_gk20a *dbg_s) +{ + struct channel_gk20a *ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + + if (dbg_s->is_profiler || !ch) + nvgpu_mutex_release(&dbg_s->g->dbg_sessions_lock); + else + nvgpu_mutex_release(&ch->dbg_s_lock); +} + +static void gk20a_dbg_gpu_events_enable(struct dbg_session_gk20a *dbg_s) +{ + struct gk20a *g = dbg_s->g; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + gk20a_dbg_session_nvgpu_mutex_acquire(dbg_s); + + dbg_s->dbg_events.events_enabled = true; + dbg_s->dbg_events.num_pending_events = 0; + + gk20a_dbg_session_nvgpu_mutex_release(dbg_s); +} + +static void gk20a_dbg_gpu_events_disable(struct dbg_session_gk20a *dbg_s) +{ + struct gk20a *g = dbg_s->g; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + gk20a_dbg_session_nvgpu_mutex_acquire(dbg_s); + + dbg_s->dbg_events.events_enabled = false; + dbg_s->dbg_events.num_pending_events = 0; + + gk20a_dbg_session_nvgpu_mutex_release(dbg_s); +} + +static void gk20a_dbg_gpu_events_clear(struct dbg_session_gk20a *dbg_s) +{ + struct gk20a *g = dbg_s->g; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + gk20a_dbg_session_nvgpu_mutex_acquire(dbg_s); + + if (dbg_s->dbg_events.events_enabled && + dbg_s->dbg_events.num_pending_events > 0) + dbg_s->dbg_events.num_pending_events--; + + gk20a_dbg_session_nvgpu_mutex_release(dbg_s); +} + + +static int gk20a_dbg_gpu_events_ctrl(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_events_ctrl_args *args) +{ + int ret = 0; + struct channel_gk20a *ch; + struct gk20a *g = dbg_s->g; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "dbg events ctrl cmd %d", args->cmd); + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (!ch) { + nvgpu_err(g, "no channel bound to dbg session"); + return -EINVAL; + } + + nvgpu_speculation_barrier(); + switch (args->cmd) { + case NVGPU_DBG_GPU_EVENTS_CTRL_CMD_ENABLE: + gk20a_dbg_gpu_events_enable(dbg_s); + break; + + case NVGPU_DBG_GPU_EVENTS_CTRL_CMD_DISABLE: + gk20a_dbg_gpu_events_disable(dbg_s); + break; + + case NVGPU_DBG_GPU_EVENTS_CTRL_CMD_CLEAR: + gk20a_dbg_gpu_events_clear(dbg_s); + break; + + default: + nvgpu_err(g, "unrecognized dbg gpu events ctrl cmd: 0x%x", + args->cmd); + ret = -EINVAL; + break; + } + + return ret; +} + +static int gk20a_perfbuf_map(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_perfbuf_map_args *args) +{ + struct gk20a *g = dbg_s->g; + struct mm_gk20a *mm = &g->mm; + int err; + u32 virt_size; + u32 big_page_size = g->ops.mm.get_default_big_page_size(); + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + if (g->perfbuf.owner) { + nvgpu_mutex_release(&g->dbg_sessions_lock); + return -EBUSY; + } + + mm->perfbuf.vm = nvgpu_vm_init(g, big_page_size, + big_page_size << 10, + NV_MM_DEFAULT_KERNEL_SIZE, + NV_MM_DEFAULT_KERNEL_SIZE + NV_MM_DEFAULT_USER_SIZE, + false, false, "perfbuf"); + if (!mm->perfbuf.vm) { + nvgpu_mutex_release(&g->dbg_sessions_lock); + return -ENOMEM; + } + + err = nvgpu_vm_map_buffer(mm->perfbuf.vm, + args->dmabuf_fd, + &args->offset, + 0, + SZ_4K, + 0, + 0, + 0, + 0, + NULL); + if (err) + goto err_remove_vm; + + /* perf output buffer may not cross a 4GB boundary */ + virt_size = u64_lo32(args->mapping_size); + if (u64_hi32(args->offset) != u64_hi32(args->offset + virt_size - 1)) { + err = -EINVAL; + goto err_unmap; + } + + err = g->ops.dbg_session_ops.perfbuffer_enable(g, + args->offset, virt_size); + if (err) + goto err_unmap; + + g->perfbuf.owner = dbg_s; + g->perfbuf.offset = args->offset; + nvgpu_mutex_release(&g->dbg_sessions_lock); + + return 0; + +err_unmap: + nvgpu_vm_unmap(mm->perfbuf.vm, args->offset, NULL); +err_remove_vm: + nvgpu_vm_put(mm->perfbuf.vm); + nvgpu_mutex_release(&g->dbg_sessions_lock); + return err; +} + +static int gk20a_perfbuf_unmap(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_perfbuf_unmap_args *args) +{ + struct gk20a *g = dbg_s->g; + int err; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + if ((g->perfbuf.owner != dbg_s) || + (g->perfbuf.offset != args->offset)) { + nvgpu_mutex_release(&g->dbg_sessions_lock); + return -EINVAL; + } + + err = gk20a_perfbuf_release_locked(g, args->offset); + + nvgpu_mutex_release(&g->dbg_sessions_lock); + + return err; +} + +static int gk20a_dbg_pc_sampling(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_pc_sampling_args *args) +{ + struct channel_gk20a *ch; + struct gk20a *g = dbg_s->g; + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (!ch) + return -EINVAL; + + nvgpu_log_fn(g, " "); + + return g->ops.gr.update_pc_sampling ? + g->ops.gr.update_pc_sampling(ch, args->enable) : -EINVAL; +} + +static int nvgpu_dbg_gpu_ioctl_clear_single_sm_error_state( + struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_clear_single_sm_error_state_args *args) +{ + struct gk20a *g = dbg_s->g; + struct gr_gk20a *gr = &g->gr; + u32 sm_id; + struct channel_gk20a *ch; + int err = 0; + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (ch == NULL) { + return -EINVAL; + } + + sm_id = args->sm_id; + if (sm_id >= gr->no_of_sm) + return -EINVAL; + + nvgpu_speculation_barrier(); + + err = gk20a_busy(g); + if (err != 0) { + return err; + } + + err = gr_gk20a_elpg_protected_call(g, + g->ops.gr.clear_sm_error_state(g, ch, sm_id)); + + gk20a_idle(g); + + return err; +} + +static int +nvgpu_dbg_gpu_ioctl_suspend_resume_contexts(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_suspend_resume_contexts_args *args) +{ + struct gk20a *g = dbg_s->g; + int err = 0; + int ctx_resident_ch_fd = -1; + + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_speculation_barrier(); + switch (args->action) { + case NVGPU_DBG_GPU_SUSPEND_ALL_CONTEXTS: + err = g->ops.gr.suspend_contexts(g, dbg_s, + &ctx_resident_ch_fd); + break; + + case NVGPU_DBG_GPU_RESUME_ALL_CONTEXTS: + err = g->ops.gr.resume_contexts(g, dbg_s, + &ctx_resident_ch_fd); + break; + } + + if (ctx_resident_ch_fd < 0) { + args->is_resident_context = 0; + } else { + args->is_resident_context = 1; + args->resident_context_fd = ctx_resident_ch_fd; + } + + gk20a_idle(g); + + return err; +} + +static int nvgpu_dbg_gpu_ioctl_access_fb_memory(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_access_fb_memory_args *args) +{ + struct gk20a *g = dbg_s->g; + struct dma_buf *dmabuf; + void __user *user_buffer = (void __user *)(uintptr_t)args->buffer; + void *buffer; + u64 size, access_size, offset; + u64 access_limit_size = SZ_4K; + int err = 0; + + if ((args->offset & 3) || (!args->size) || (args->size & 3)) + return -EINVAL; + + dmabuf = dma_buf_get(args->dmabuf_fd); + if (IS_ERR(dmabuf)) + return -EINVAL; + + if ((args->offset > dmabuf->size) || + (args->size > dmabuf->size) || + (args->offset + args->size > dmabuf->size)) { + err = -EINVAL; + goto fail_dmabuf_put; + } + + buffer = nvgpu_big_zalloc(g, access_limit_size); + if (!buffer) { + err = -ENOMEM; + goto fail_dmabuf_put; + } + + size = args->size; + offset = 0; + + err = gk20a_busy(g); + if (err) + goto fail_free_buffer; + + while (size) { + /* Max access size of access_limit_size in one loop */ + access_size = min(access_limit_size, size); + + if (args->cmd == + NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY_CMD_WRITE) { + err = copy_from_user(buffer, user_buffer + offset, + access_size); + if (err) + goto fail_idle; + } + + err = nvgpu_vidmem_buf_access_memory(g, dmabuf, buffer, + args->offset + offset, access_size, + args->cmd); + if (err) + goto fail_idle; + + if (args->cmd == + NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY_CMD_READ) { + err = copy_to_user(user_buffer + offset, + buffer, access_size); + if (err) + goto fail_idle; + } + + size -= access_size; + offset += access_size; + } + nvgpu_speculation_barrier(); + +fail_idle: + gk20a_idle(g); +fail_free_buffer: + nvgpu_big_free(g, buffer); +fail_dmabuf_put: + dma_buf_put(dmabuf); + + return err; +} + +static int nvgpu_ioctl_profiler_reserve(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_profiler_reserve_args *args) +{ + if (args->acquire) + return nvgpu_profiler_reserve_acquire(dbg_s, args->profiler_handle); + + return nvgpu_profiler_reserve_release(dbg_s, args->profiler_handle); +} + +static void nvgpu_dbg_gpu_ioctl_get_timeout(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_timeout_args *args) +{ + bool status; + struct gk20a *g = dbg_s->g; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + status = nvgpu_is_timeouts_enabled(g); + nvgpu_mutex_release(&g->dbg_sessions_lock); + + if (status) + args->enable = NVGPU_DBG_GPU_IOCTL_TIMEOUT_ENABLE; + else + args->enable = NVGPU_DBG_GPU_IOCTL_TIMEOUT_DISABLE; +} + +static int gk20a_perfbuf_release_locked(struct gk20a *g, u64 offset) +{ + struct mm_gk20a *mm = &g->mm; + struct vm_gk20a *vm = mm->perfbuf.vm; + int err; + + err = g->ops.dbg_session_ops.perfbuffer_disable(g); + + nvgpu_vm_unmap(vm, offset, NULL); + nvgpu_free_inst_block(g, &mm->perfbuf.inst_block); + nvgpu_vm_put(vm); + + g->perfbuf.owner = NULL; + g->perfbuf.offset = 0; + return err; +} + +static int nvgpu_profiler_reserve_release(struct dbg_session_gk20a *dbg_s, + u32 profiler_handle) +{ + struct gk20a *g = dbg_s->g; + struct dbg_profiler_object_data *prof_obj; + int err = 0; + + nvgpu_log_fn(g, "%s profiler_handle = %x", g->name, profiler_handle); + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + /* Find matching object. */ + prof_obj = find_matching_prof_obj(dbg_s, profiler_handle); + + if (!prof_obj) { + nvgpu_err(g, "object not found"); + err = -EINVAL; + goto exit; + } + + if (prof_obj->has_reservation) + g->ops.dbg_session_ops.release_profiler_reservation(dbg_s, prof_obj); + else { + nvgpu_err(g, "No reservation found"); + err = -EINVAL; + goto exit; + } +exit: + nvgpu_mutex_release(&g->dbg_sessions_lock); + return err; +} + +static int nvgpu_profiler_reserve_acquire(struct dbg_session_gk20a *dbg_s, + u32 profiler_handle) +{ + struct gk20a *g = dbg_s->g; + struct dbg_profiler_object_data *prof_obj, *my_prof_obj; + int err = 0; + struct tsg_gk20a *tsg; + + nvgpu_log_fn(g, "%s profiler_handle = %x", g->name, profiler_handle); + + if (g->profiler_reservation_count < 0) { + nvgpu_err(g, "Negative reservation count!"); + return -EINVAL; + } + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + + /* Find matching object. */ + my_prof_obj = find_matching_prof_obj(dbg_s, profiler_handle); + + if (!my_prof_obj) { + nvgpu_err(g, "object not found"); + err = -EINVAL; + goto exit; + } + + /* If we already have the reservation, we're done */ + if (my_prof_obj->has_reservation) { + err = 0; + goto exit; + } + + if (my_prof_obj->ch == NULL) { + /* Global reservations are only allowed if there are no other + * global or per-context reservations currently held + */ + if (!g->ops.dbg_session_ops.check_and_set_global_reservation( + dbg_s, my_prof_obj)) { + nvgpu_err(g, + "global reserve: have existing reservation"); + err = -EBUSY; + } + } else if (g->global_profiler_reservation_held) { + /* If there's a global reservation, + * we can't take a per-context one. + */ + nvgpu_err(g, + "per-ctxt reserve: global reservation in effect"); + err = -EBUSY; + } else if ((tsg = tsg_gk20a_from_ch(my_prof_obj->ch)) != NULL) { + /* TSG: check that another channel in the TSG + * doesn't already have the reservation + */ + u32 my_tsgid = tsg->tsgid; + + nvgpu_list_for_each_entry(prof_obj, &g->profiler_objects, + dbg_profiler_object_data, prof_obj_entry) { + if (prof_obj->has_reservation && + (prof_obj->ch->tsgid == my_tsgid)) { + nvgpu_err(g, + "per-ctxt reserve (tsg): already reserved"); + err = -EBUSY; + goto exit; + } + } + + if (!g->ops.dbg_session_ops.check_and_set_context_reservation( + dbg_s, my_prof_obj)) { + /* Another guest OS has the global reservation */ + nvgpu_err(g, + "per-ctxt reserve: global reservation in effect"); + err = -EBUSY; + } + } else { + /* channel: check that some other profiler object doesn't + * already have the reservation. + */ + struct channel_gk20a *my_ch = my_prof_obj->ch; + + nvgpu_list_for_each_entry(prof_obj, &g->profiler_objects, + dbg_profiler_object_data, prof_obj_entry) { + if (prof_obj->has_reservation && + (prof_obj->ch == my_ch)) { + nvgpu_err(g, + "per-ctxt reserve (ch): already reserved"); + err = -EBUSY; + goto exit; + } + } + + if (!g->ops.dbg_session_ops.check_and_set_context_reservation( + dbg_s, my_prof_obj)) { + /* Another guest OS has the global reservation */ + nvgpu_err(g, + "per-ctxt reserve: global reservation in effect"); + err = -EBUSY; + } + } +exit: + nvgpu_mutex_release(&g->dbg_sessions_lock); + return err; +} + +static int dbg_unbind_channel_gk20a(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_unbind_channel_args *args) +{ + struct dbg_session_channel_data *ch_data; + struct gk20a *g = dbg_s->g; + bool channel_found = false; + struct channel_gk20a *ch; + int err; + + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s fd=%d", + g->name, args->channel_fd); + + ch = gk20a_get_channel_from_file(args->channel_fd); + if (!ch) { + nvgpu_log_fn(g, "no channel found for fd"); + return -EINVAL; + } + + nvgpu_mutex_acquire(&dbg_s->ch_list_lock); + nvgpu_list_for_each_entry(ch_data, &dbg_s->ch_list, + dbg_session_channel_data, ch_entry) { + if (ch->chid == ch_data->chid) { + channel_found = true; + break; + } + } + nvgpu_mutex_release(&dbg_s->ch_list_lock); + + if (!channel_found) { + nvgpu_log_fn(g, "channel not bounded, fd=%d\n", args->channel_fd); + err = -EINVAL; + goto out; + } + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + nvgpu_mutex_acquire(&dbg_s->ch_list_lock); + err = dbg_unbind_single_channel_gk20a(dbg_s, ch_data); + nvgpu_mutex_release(&dbg_s->ch_list_lock); + nvgpu_mutex_release(&g->dbg_sessions_lock); + +out: + gk20a_channel_put(ch); + return err; +} + +static int nvgpu_set_sm_exception_type_mask_locked( + struct dbg_session_gk20a *dbg_s, + u32 exception_mask) +{ + struct gk20a *g = dbg_s->g; + int err = 0; + struct channel_gk20a *ch = NULL; + + /* + * Obtain the fisrt channel from the channel list in + * dbg_session, find the context associated with channel + * and set the sm_mask_type to that context + */ + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (ch != NULL) { + struct tsg_gk20a *tsg; + + tsg = tsg_gk20a_from_ch(ch); + if (tsg != NULL) { + tsg->sm_exception_mask_type = exception_mask; + goto type_mask_end; + } + } + + nvgpu_log_fn(g, "unable to find the TSG\n"); + err = -EINVAL; + +type_mask_end: + return err; +} + +static int nvgpu_dbg_gpu_set_sm_exception_type_mask( + struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_set_sm_exception_type_mask_args *args) +{ + int err = 0; + struct gk20a *g = dbg_s->g; + u32 sm_exception_mask_type = NVGPU_SM_EXCEPTION_TYPE_MASK_NONE; + + nvgpu_speculation_barrier(); + switch (args->exception_type_mask) { + case NVGPU_DBG_GPU_IOCTL_SET_SM_EXCEPTION_TYPE_MASK_FATAL: + sm_exception_mask_type = NVGPU_SM_EXCEPTION_TYPE_MASK_FATAL; + break; + case NVGPU_DBG_GPU_IOCTL_SET_SM_EXCEPTION_TYPE_MASK_NONE: + sm_exception_mask_type = NVGPU_SM_EXCEPTION_TYPE_MASK_NONE; + break; + default: + nvgpu_err(g, + "unrecognized dbg sm exception type mask: 0x%x", + args->exception_type_mask); + err = -EINVAL; + break; + } + + if (err != 0) { + return err; + } + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + err = nvgpu_set_sm_exception_type_mask_locked(dbg_s, + sm_exception_mask_type); + nvgpu_mutex_release(&g->dbg_sessions_lock); + + return err; +} + +#if defined(CONFIG_GK20A_CYCLE_STATS) +static int nvgpu_dbg_gpu_cycle_stats(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_cycle_stats_args *args) +{ + struct channel_gk20a *ch = NULL; + int err; + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (ch == NULL) { + return -EINVAL; + } + + err = gk20a_busy(ch->g); + if (err != 0) { + return err; + } + + err = gk20a_channel_cycle_stats(ch, args->dmabuf_fd); + + gk20a_idle(ch->g); + return err; +} + +static int nvgpu_dbg_gpu_cycle_stats_snapshot(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_cycle_stats_snapshot_args *args) +{ + struct channel_gk20a *ch = NULL; + int err; + + if (!args->dmabuf_fd) { + return -EINVAL; + } + + nvgpu_speculation_barrier(); + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (ch == NULL) { + return -EINVAL; + } + + /* is it allowed to handle calls for current GPU? */ + if (!nvgpu_is_enabled(ch->g, NVGPU_SUPPORT_CYCLE_STATS_SNAPSHOT)) { + return -ENOSYS; + } + + err = gk20a_busy(ch->g); + if (err != 0) { + return err; + } + + /* handle the command (most frequent cases first) */ + switch (args->cmd) { + case NVGPU_DBG_GPU_IOCTL_CYCLE_STATS_SNAPSHOT_CMD_FLUSH: + err = gk20a_flush_cycle_stats_snapshot(ch); + args->extra = 0; + break; + + case NVGPU_DBG_GPU_IOCTL_CYCLE_STATS_SNAPSHOT_CMD_ATTACH: + err = gk20a_attach_cycle_stats_snapshot(ch, + args->dmabuf_fd, + args->extra, + &args->extra); + break; + + case NVGPU_DBG_GPU_IOCTL_CYCLE_STATS_SNAPSHOT_CMD_DETACH: + err = gk20a_channel_free_cycle_stats_snapshot(ch); + args->extra = 0; + break; + + default: + pr_err("cyclestats: unknown command %u\n", args->cmd); + err = -EINVAL; + break; + } + + gk20a_idle(ch->g); + return err; +} + +#endif + +int gk20a_dbg_gpu_dev_open(struct inode *inode, struct file *filp) +{ + struct nvgpu_os_linux *l = container_of(inode->i_cdev, + struct nvgpu_os_linux, dbg.cdev); + struct gk20a *g = &l->g; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + return gk20a_dbg_gpu_do_dev_open(inode, filp, false /* not profiler */); +} + +long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct dbg_session_gk20a_linux *dbg_s_linux = filp->private_data; + struct dbg_session_gk20a *dbg_s = &dbg_s_linux->dbg_s; + struct gk20a *g = dbg_s->g; + u8 buf[NVGPU_DBG_GPU_IOCTL_MAX_ARG_SIZE]; + int err = 0; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); + + if ((_IOC_TYPE(cmd) != NVGPU_DBG_GPU_IOCTL_MAGIC) || + (_IOC_NR(cmd) == 0) || + (_IOC_NR(cmd) > NVGPU_DBG_GPU_IOCTL_LAST) || + (_IOC_SIZE(cmd) > NVGPU_DBG_GPU_IOCTL_MAX_ARG_SIZE)) + return -EINVAL; + + memset(buf, 0, sizeof(buf)); + if (_IOC_DIR(cmd) & _IOC_WRITE) { + if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + } + + if (!g->sw_ready) { + err = gk20a_busy(g); + if (err) + return err; + + gk20a_idle(g); + } + + /* protect from threaded user space calls */ + nvgpu_mutex_acquire(&dbg_s->ioctl_lock); + + nvgpu_speculation_barrier(); + switch (cmd) { + case NVGPU_DBG_GPU_IOCTL_BIND_CHANNEL: + err = dbg_bind_channel_gk20a(dbg_s, + (struct nvgpu_dbg_gpu_bind_channel_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_REG_OPS: + err = nvgpu_ioctl_channel_reg_ops(dbg_s, + (struct nvgpu_dbg_gpu_exec_reg_ops_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_POWERGATE: + err = nvgpu_ioctl_powergate_gk20a(dbg_s, + (struct nvgpu_dbg_gpu_powergate_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_EVENTS_CTRL: + err = gk20a_dbg_gpu_events_ctrl(dbg_s, + (struct nvgpu_dbg_gpu_events_ctrl_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_SMPC_CTXSW_MODE: + err = nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(dbg_s, + (struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_HWPM_CTXSW_MODE: + err = nvgpu_dbg_gpu_ioctl_hwpm_ctxsw_mode(dbg_s, + (struct nvgpu_dbg_gpu_hwpm_ctxsw_mode_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_SUSPEND_RESUME_ALL_SMS: + err = nvgpu_dbg_gpu_ioctl_suspend_resume_sm(dbg_s, + (struct nvgpu_dbg_gpu_suspend_resume_all_sms_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_PERFBUF_MAP: + err = gk20a_perfbuf_map(dbg_s, + (struct nvgpu_dbg_gpu_perfbuf_map_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_PERFBUF_UNMAP: + err = gk20a_perfbuf_unmap(dbg_s, + (struct nvgpu_dbg_gpu_perfbuf_unmap_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_PC_SAMPLING: + err = gk20a_dbg_pc_sampling(dbg_s, + (struct nvgpu_dbg_gpu_pc_sampling_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_SET_NEXT_STOP_TRIGGER_TYPE: + err = nvgpu_dbg_gpu_ioctl_set_next_stop_trigger_type(dbg_s, + (struct nvgpu_dbg_gpu_set_next_stop_trigger_type_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_TIMEOUT: + err = nvgpu_dbg_gpu_ioctl_timeout(dbg_s, + (struct nvgpu_dbg_gpu_timeout_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_GET_TIMEOUT: + nvgpu_dbg_gpu_ioctl_get_timeout(dbg_s, + (struct nvgpu_dbg_gpu_timeout_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_READ_SINGLE_SM_ERROR_STATE: + err = nvgpu_dbg_gpu_ioctl_read_single_sm_error_state(dbg_s, + (struct nvgpu_dbg_gpu_read_single_sm_error_state_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_CLEAR_SINGLE_SM_ERROR_STATE: + err = nvgpu_dbg_gpu_ioctl_clear_single_sm_error_state(dbg_s, + (struct nvgpu_dbg_gpu_clear_single_sm_error_state_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_UNBIND_CHANNEL: + err = dbg_unbind_channel_gk20a(dbg_s, + (struct nvgpu_dbg_gpu_unbind_channel_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_SUSPEND_RESUME_CONTEXTS: + err = nvgpu_dbg_gpu_ioctl_suspend_resume_contexts(dbg_s, + (struct nvgpu_dbg_gpu_suspend_resume_contexts_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY: + err = nvgpu_dbg_gpu_ioctl_access_fb_memory(dbg_s, + (struct nvgpu_dbg_gpu_access_fb_memory_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_PROFILER_ALLOCATE: + err = nvgpu_ioctl_allocate_profiler_object(dbg_s_linux, + (struct nvgpu_dbg_gpu_profiler_obj_mgt_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_PROFILER_FREE: + err = nvgpu_ioctl_free_profiler_object(dbg_s_linux, + (struct nvgpu_dbg_gpu_profiler_obj_mgt_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_PROFILER_RESERVE: + err = nvgpu_ioctl_profiler_reserve(dbg_s, + (struct nvgpu_dbg_gpu_profiler_reserve_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_SET_SM_EXCEPTION_TYPE_MASK: + err = nvgpu_dbg_gpu_set_sm_exception_type_mask(dbg_s, + (struct nvgpu_dbg_gpu_set_sm_exception_type_mask_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_SET_CTX_MMU_DEBUG_MODE: + err = nvgpu_dbg_gpu_ioctl_set_mmu_debug_mode(dbg_s, + (struct nvgpu_dbg_gpu_set_ctx_mmu_debug_mode_args *)buf); + break; + +#ifdef CONFIG_GK20A_CYCLE_STATS + case NVGPU_DBG_GPU_IOCTL_CYCLE_STATS: + err = nvgpu_dbg_gpu_cycle_stats(dbg_s, + (struct nvgpu_dbg_gpu_cycle_stats_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_CYCLE_STATS_SNAPSHOT: + err = nvgpu_dbg_gpu_cycle_stats_snapshot(dbg_s, + (struct nvgpu_dbg_gpu_cycle_stats_snapshot_args *)buf); + break; +#endif + + default: + nvgpu_err(g, + "unrecognized dbg gpu ioctl cmd: 0x%x", + cmd); + err = -ENOTTY; + break; + } + + nvgpu_mutex_release(&dbg_s->ioctl_lock); + + nvgpu_log(g, gpu_dbg_gpu_dbg, "ret=%d", err); + + if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ)) + err = copy_to_user((void __user *)arg, + buf, _IOC_SIZE(cmd)); + + return err; +} diff --git a/include/os/linux/ioctl_dbg.h b/include/os/linux/ioctl_dbg.h new file mode 100644 index 0000000..2e188cc --- /dev/null +++ b/include/os/linux/ioctl_dbg.h @@ -0,0 +1,38 @@ +/* + * Tegra GK20A GPU Debugger Driver + * + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef DBG_GPU_IOCTL_GK20A_H +#define DBG_GPU_IOCTL_GK20A_H + +struct inode; +struct file; +typedef struct poll_table_struct poll_table; + +/* NVGPU_DBG_GPU_IOCTL_REG_OPS: the upper limit for the number + * of regops */ +#define NVGPU_IOCTL_DBG_REG_OPS_LIMIT 1024 + +/* module debug driver interface */ +int gk20a_dbg_gpu_dev_release(struct inode *inode, struct file *filp); +int gk20a_dbg_gpu_dev_open(struct inode *inode, struct file *filp); +long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +unsigned int gk20a_dbg_gpu_dev_poll(struct file *filep, poll_table *wait); + +/* used by profiler driver interface */ +int gk20a_prof_gpu_dev_open(struct inode *inode, struct file *filp); + +#endif diff --git a/include/os/linux/ioctl_tsg.c b/include/os/linux/ioctl_tsg.c new file mode 100644 index 0000000..2f8cb3a --- /dev/null +++ b/include/os/linux/ioctl_tsg.c @@ -0,0 +1,750 @@ +/* + * Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "gv11b/fifo_gv11b.h" +#include "platform_gk20a.h" +#include "ioctl_tsg.h" +#include "ioctl_channel.h" +#include "os_linux.h" + +struct tsg_private { + struct gk20a *g; + struct tsg_gk20a *tsg; +}; + +static int gk20a_tsg_bind_channel_fd(struct tsg_gk20a *tsg, int ch_fd) +{ + struct channel_gk20a *ch; + int err; + + ch = gk20a_get_channel_from_file(ch_fd); + if (!ch) + return -EINVAL; + + err = ch->g->ops.fifo.tsg_bind_channel(tsg, ch); + + gk20a_channel_put(ch); + return err; +} + +static int gk20a_tsg_ioctl_bind_channel_ex(struct gk20a *g, + struct tsg_gk20a *tsg, struct nvgpu_tsg_bind_channel_ex_args *arg) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + struct channel_gk20a *ch; + struct gr_gk20a *gr = &g->gr; + int err = 0; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsg->tsgid); + + nvgpu_mutex_acquire(&sched->control_lock); + if (sched->control_locked) { + err = -EPERM; + goto mutex_release; + } + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to power on gpu"); + goto mutex_release; + } + + ch = gk20a_get_channel_from_file(arg->channel_fd); + if (!ch) { + err = -EINVAL; + goto idle; + } + + if (arg->tpc_pg_enabled && (!tsg->tpc_num_initialized)) { + if ((arg->num_active_tpcs > gr->max_tpc_count) || + !(arg->num_active_tpcs)) { + nvgpu_err(g, "Invalid num of active TPCs"); + err = -EINVAL; + goto ch_put; + } + tsg->tpc_num_initialized = true; + tsg->num_active_tpcs = arg->num_active_tpcs; + tsg->tpc_pg_enabled = true; + } else { + tsg->tpc_pg_enabled = false; nvgpu_log(g, gpu_dbg_info, "dynamic TPC-PG not enabled"); + } + + if (arg->subcontext_id < g->fifo.max_subctx_count) { + ch->subctx_id = arg->subcontext_id; + } else { + err = -EINVAL; + goto ch_put; + } + + nvgpu_log(g, gpu_dbg_info, "channel id : %d : subctx: %d", + ch->chid, ch->subctx_id); + + /* Use runqueue selector 1 for all ASYNC ids */ + if (ch->subctx_id > CHANNEL_INFO_VEID0) + ch->runqueue_sel = 1; + + err = ch->g->ops.fifo.tsg_bind_channel(tsg, ch); +ch_put: + gk20a_channel_put(ch); +idle: + gk20a_idle(g); +mutex_release: + nvgpu_mutex_release(&sched->control_lock); + return err; +} + +static int gk20a_tsg_unbind_channel_fd(struct tsg_gk20a *tsg, int ch_fd) +{ + struct channel_gk20a *ch; + int err = 0; + + ch = gk20a_get_channel_from_file(ch_fd); + if (!ch) + return -EINVAL; + + if (ch->tsgid != tsg->tsgid) { + err = -EINVAL; + goto out; + } + + err = gk20a_tsg_unbind_channel(ch); + + /* + * Mark the channel timedout since channel unbound from TSG + * has no context of its own so it can't serve any job + */ + gk20a_channel_set_timedout(ch); + +out: + gk20a_channel_put(ch); + return err; +} + +static int gk20a_tsg_get_event_data_from_id(struct tsg_gk20a *tsg, + unsigned int event_id, + struct gk20a_event_id_data **event_id_data) +{ + struct gk20a_event_id_data *local_event_id_data; + bool event_found = false; + + nvgpu_mutex_acquire(&tsg->event_id_list_lock); + nvgpu_list_for_each_entry(local_event_id_data, &tsg->event_id_list, + gk20a_event_id_data, event_id_node) { + if (local_event_id_data->event_id == event_id) { + event_found = true; + break; + } + } + nvgpu_mutex_release(&tsg->event_id_list_lock); + + if (event_found) { + *event_id_data = local_event_id_data; + return 0; + } else { + return -1; + } +} + +/* + * Convert common event_id of the form NVGPU_EVENT_ID_* to Linux specific + * event_id of the form NVGPU_IOCTL_CHANNEL_EVENT_ID_* which is used in IOCTLs + */ +static u32 nvgpu_event_id_to_ioctl_channel_event_id(u32 event_id) +{ + switch (event_id) { + case NVGPU_EVENT_ID_BPT_INT: + return NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_INT; + case NVGPU_EVENT_ID_BPT_PAUSE: + return NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_PAUSE; + case NVGPU_EVENT_ID_BLOCKING_SYNC: + return NVGPU_IOCTL_CHANNEL_EVENT_ID_BLOCKING_SYNC; + case NVGPU_EVENT_ID_CILP_PREEMPTION_STARTED: + return NVGPU_IOCTL_CHANNEL_EVENT_ID_CILP_PREEMPTION_STARTED; + case NVGPU_EVENT_ID_CILP_PREEMPTION_COMPLETE: + return NVGPU_IOCTL_CHANNEL_EVENT_ID_CILP_PREEMPTION_COMPLETE; + case NVGPU_EVENT_ID_GR_SEMAPHORE_WRITE_AWAKEN: + return NVGPU_IOCTL_CHANNEL_EVENT_ID_GR_SEMAPHORE_WRITE_AWAKEN; + } + + return NVGPU_IOCTL_CHANNEL_EVENT_ID_MAX; +} + +void gk20a_tsg_event_id_post_event(struct tsg_gk20a *tsg, + int __event_id) +{ + struct gk20a_event_id_data *event_id_data; + u32 event_id; + int err = 0; + struct gk20a *g = tsg->g; + + event_id = nvgpu_event_id_to_ioctl_channel_event_id(__event_id); + if (event_id >= NVGPU_IOCTL_CHANNEL_EVENT_ID_MAX) + return; + + err = gk20a_tsg_get_event_data_from_id(tsg, event_id, + &event_id_data); + if (err) + return; + + nvgpu_mutex_acquire(&event_id_data->lock); + + nvgpu_log_info(g, + "posting event for event_id=%d on tsg=%d\n", + event_id, tsg->tsgid); + event_id_data->event_posted = true; + + nvgpu_cond_broadcast_interruptible(&event_id_data->event_id_wq); + + nvgpu_mutex_release(&event_id_data->lock); +} + +static unsigned int gk20a_event_id_poll(struct file *filep, poll_table *wait) +{ + unsigned int mask = 0; + struct gk20a_event_id_data *event_id_data = filep->private_data; + struct gk20a *g = event_id_data->g; + u32 event_id = event_id_data->event_id; + struct tsg_gk20a *tsg = g->fifo.tsg + event_id_data->id; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_info, " "); + + poll_wait(filep, &event_id_data->event_id_wq.wq, wait); + + nvgpu_mutex_acquire(&event_id_data->lock); + + if (event_id_data->event_posted) { + nvgpu_log_info(g, + "found pending event_id=%d on TSG=%d\n", + event_id, tsg->tsgid); + mask = (POLLPRI | POLLIN); + event_id_data->event_posted = false; + } + + nvgpu_mutex_release(&event_id_data->lock); + + return mask; +} + +static int gk20a_event_id_release(struct inode *inode, struct file *filp) +{ + struct gk20a_event_id_data *event_id_data = filp->private_data; + struct gk20a *g = event_id_data->g; + struct tsg_gk20a *tsg = g->fifo.tsg + event_id_data->id; + + nvgpu_mutex_acquire(&tsg->event_id_list_lock); + nvgpu_list_del(&event_id_data->event_id_node); + nvgpu_mutex_release(&tsg->event_id_list_lock); + + nvgpu_mutex_destroy(&event_id_data->lock); + gk20a_put(g); + nvgpu_kfree(g, event_id_data); + filp->private_data = NULL; + + return 0; +} + +const struct file_operations gk20a_event_id_ops = { + .owner = THIS_MODULE, + .poll = gk20a_event_id_poll, + .release = gk20a_event_id_release, +}; + +static int gk20a_tsg_event_id_enable(struct tsg_gk20a *tsg, + int event_id, + int *fd) +{ + int err = 0; + int local_fd; + struct file *file; + char name[64]; + struct gk20a_event_id_data *event_id_data; + struct gk20a *g; + + g = gk20a_get(tsg->g); + if (!g) + return -ENODEV; + + err = gk20a_tsg_get_event_data_from_id(tsg, + event_id, &event_id_data); + if (err == 0) { + /* We already have event enabled */ + err = -EINVAL; + goto free_ref; + } + + err = get_unused_fd_flags(O_RDWR); + if (err < 0) + goto free_ref; + local_fd = err; + + snprintf(name, sizeof(name), "nvgpu-event%d-fd%d", + event_id, local_fd); + + file = anon_inode_getfile(name, &gk20a_event_id_ops, + NULL, O_RDWR); + if (IS_ERR(file)) { + err = PTR_ERR(file); + goto clean_up; + } + + event_id_data = nvgpu_kzalloc(tsg->g, sizeof(*event_id_data)); + if (!event_id_data) { + err = -ENOMEM; + goto clean_up_file; + } + event_id_data->g = g; + event_id_data->id = tsg->tsgid; + event_id_data->event_id = event_id; + + nvgpu_cond_init(&event_id_data->event_id_wq); + err = nvgpu_mutex_init(&event_id_data->lock); + if (err) + goto clean_up_free; + + nvgpu_init_list_node(&event_id_data->event_id_node); + + nvgpu_mutex_acquire(&tsg->event_id_list_lock); + nvgpu_list_add_tail(&event_id_data->event_id_node, &tsg->event_id_list); + nvgpu_mutex_release(&tsg->event_id_list_lock); + + fd_install(local_fd, file); + file->private_data = event_id_data; + + *fd = local_fd; + + return 0; + +clean_up_free: + nvgpu_kfree(g, event_id_data); +clean_up_file: + fput(file); +clean_up: + put_unused_fd(local_fd); +free_ref: + gk20a_put(g); + return err; +} + +static int gk20a_tsg_event_id_ctrl(struct gk20a *g, struct tsg_gk20a *tsg, + struct nvgpu_event_id_ctrl_args *args) +{ + int err = 0; + int fd = -1; + + if (args->event_id >= NVGPU_IOCTL_CHANNEL_EVENT_ID_MAX) + return -EINVAL; + + nvgpu_speculation_barrier(); + switch (args->cmd) { + case NVGPU_IOCTL_CHANNEL_EVENT_ID_CMD_ENABLE: + err = gk20a_tsg_event_id_enable(tsg, args->event_id, &fd); + if (!err) + args->event_fd = fd; + break; + + default: + nvgpu_err(tsg->g, "unrecognized tsg event id cmd: 0x%x", + args->cmd); + err = -EINVAL; + break; + } + + return err; +} + +int nvgpu_ioctl_tsg_open(struct gk20a *g, struct file *filp) +{ + struct tsg_private *priv; + struct tsg_gk20a *tsg; + struct device *dev; + int err; + + g = gk20a_get(g); + if (!g) + return -ENODEV; + + dev = dev_from_gk20a(g); + + nvgpu_log(g, gpu_dbg_fn, "tsg: %s", dev_name(dev)); + + priv = nvgpu_kmalloc(g, sizeof(*priv)); + if (!priv) { + err = -ENOMEM; + goto free_ref; + } + + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to power on, %d", err); + goto free_mem; + } + + tsg = gk20a_tsg_open(g, nvgpu_current_pid(g)); + gk20a_idle(g); + if (!tsg) { + err = -ENOMEM; + goto free_mem; + } + + priv->g = g; + priv->tsg = tsg; + filp->private_data = priv; + + gk20a_sched_ctrl_tsg_added(g, tsg); + + return 0; + +free_mem: + nvgpu_kfree(g, priv); +free_ref: + gk20a_put(g); + return err; +} + +int nvgpu_ioctl_tsg_dev_open(struct inode *inode, struct file *filp) +{ + struct nvgpu_os_linux *l; + struct gk20a *g; + int ret; + + l = container_of(inode->i_cdev, + struct nvgpu_os_linux, tsg.cdev); + g = &l->g; + + nvgpu_log_fn(g, " "); + + ret = gk20a_busy(g); + if (ret) { + nvgpu_err(g, "failed to power on, %d", ret); + return ret; + } + + ret = nvgpu_ioctl_tsg_open(&l->g, filp); + + gk20a_idle(g); + nvgpu_log_fn(g, "done"); + return ret; +} + +void nvgpu_ioctl_tsg_release(struct nvgpu_ref *ref) +{ + struct tsg_gk20a *tsg = container_of(ref, struct tsg_gk20a, refcount); + struct gk20a *g = tsg->g; + + gk20a_sched_ctrl_tsg_removed(g, tsg); + + gk20a_tsg_release(ref); + gk20a_put(g); +} + +int nvgpu_ioctl_tsg_dev_release(struct inode *inode, struct file *filp) +{ + struct tsg_private *priv = filp->private_data; + struct tsg_gk20a *tsg; + + if (!priv) { + /* open failed, never got a tsg for this file */ + return 0; + } + + tsg = priv->tsg; + + nvgpu_ref_put(&tsg->refcount, nvgpu_ioctl_tsg_release); + nvgpu_kfree(tsg->g, priv); + return 0; +} + +static int gk20a_tsg_ioctl_set_runlist_interleave(struct gk20a *g, + struct tsg_gk20a *tsg, struct nvgpu_runlist_interleave_args *arg) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + u32 level = arg->level; + int err; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsg->tsgid); + + nvgpu_mutex_acquire(&sched->control_lock); + if (sched->control_locked) { + err = -EPERM; + goto done; + } + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to power on gpu"); + goto done; + } + + level = nvgpu_get_common_runlist_level(level); + err = gk20a_tsg_set_runlist_interleave(tsg, level); + + gk20a_idle(g); +done: + nvgpu_mutex_release(&sched->control_lock); + return err; +} + +static int gk20a_tsg_ioctl_set_timeslice(struct gk20a *g, + struct tsg_gk20a *tsg, struct nvgpu_timeslice_args *arg) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + int err; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsg->tsgid); + + nvgpu_mutex_acquire(&sched->control_lock); + if (sched->control_locked) { + err = -EPERM; + goto done; + } + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to power on gpu"); + goto done; + } + err = gk20a_tsg_set_timeslice(tsg, arg->timeslice_us); + gk20a_idle(g); +done: + nvgpu_mutex_release(&sched->control_lock); + return err; +} + +static int gk20a_tsg_ioctl_get_timeslice(struct gk20a *g, + struct tsg_gk20a *tsg, struct nvgpu_timeslice_args *arg) +{ + arg->timeslice_us = gk20a_tsg_get_timeslice(tsg); + return 0; +} + +static int gk20a_tsg_ioctl_read_single_sm_error_state(struct gk20a *g, + struct tsg_gk20a *tsg, + struct nvgpu_tsg_read_single_sm_error_state_args *args) +{ + struct gr_gk20a *gr = &g->gr; + struct nvgpu_tsg_sm_error_state *sm_error_state; + struct nvgpu_tsg_sm_error_state_record sm_error_state_record; + u32 sm_id; + int err = 0; + + sm_id = args->sm_id; + if (sm_id >= gr->no_of_sm) + return -EINVAL; + + nvgpu_speculation_barrier(); + + sm_error_state = tsg->sm_error_states + sm_id; + sm_error_state_record.global_esr = + sm_error_state->hww_global_esr; + sm_error_state_record.warp_esr = + sm_error_state->hww_warp_esr; + sm_error_state_record.warp_esr_pc = + sm_error_state->hww_warp_esr_pc; + sm_error_state_record.global_esr_report_mask = + sm_error_state->hww_global_esr_report_mask; + sm_error_state_record.warp_esr_report_mask = + sm_error_state->hww_warp_esr_report_mask; + + if (args->record_size > 0) { + size_t write_size = sizeof(*sm_error_state); + + nvgpu_speculation_barrier(); + if (write_size > args->record_size) + write_size = args->record_size; + + nvgpu_mutex_acquire(&g->dbg_sessions_lock); + err = copy_to_user((void __user *)(uintptr_t) + args->record_mem, + &sm_error_state_record, + write_size); + nvgpu_mutex_release(&g->dbg_sessions_lock); + if (err) { + nvgpu_err(g, "copy_to_user failed!"); + return err; + } + + args->record_size = write_size; + } + + return 0; +} + +long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct tsg_private *priv = filp->private_data; + struct tsg_gk20a *tsg = priv->tsg; + struct gk20a *g = tsg->g; + u8 __maybe_unused buf[NVGPU_TSG_IOCTL_MAX_ARG_SIZE]; + int err = 0; + + nvgpu_log_fn(g, "start %d", _IOC_NR(cmd)); + + if ((_IOC_TYPE(cmd) != NVGPU_TSG_IOCTL_MAGIC) || + (_IOC_NR(cmd) == 0) || + (_IOC_NR(cmd) > NVGPU_TSG_IOCTL_LAST) || + (_IOC_SIZE(cmd) > NVGPU_TSG_IOCTL_MAX_ARG_SIZE)) + return -EINVAL; + + memset(buf, 0, sizeof(buf)); + if (_IOC_DIR(cmd) & _IOC_WRITE) { + if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + } + + if (!g->sw_ready) { + err = gk20a_busy(g); + if (err) + return err; + + gk20a_idle(g); + } + + switch (cmd) { + case NVGPU_TSG_IOCTL_BIND_CHANNEL: + { + int ch_fd = *(int *)buf; + if (ch_fd < 0) { + err = -EINVAL; + break; + } + err = gk20a_tsg_bind_channel_fd(tsg, ch_fd); + break; + } + + case NVGPU_TSG_IOCTL_BIND_CHANNEL_EX: + { + err = gk20a_tsg_ioctl_bind_channel_ex(g, tsg, + (struct nvgpu_tsg_bind_channel_ex_args *)buf); + break; + } + + case NVGPU_TSG_IOCTL_UNBIND_CHANNEL: + { + int ch_fd = *(int *)buf; + + if (ch_fd < 0) { + err = -EINVAL; + break; + } + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, + "failed to host gk20a for ioctl cmd: 0x%x", cmd); + break; + } + err = gk20a_tsg_unbind_channel_fd(tsg, ch_fd); + gk20a_idle(g); + break; + } + + case NVGPU_IOCTL_TSG_ENABLE: + { + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, + "failed to host gk20a for ioctl cmd: 0x%x", cmd); + return err; + } + g->ops.fifo.enable_tsg(tsg); + gk20a_idle(g); + break; + } + + case NVGPU_IOCTL_TSG_DISABLE: + { + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, + "failed to host gk20a for ioctl cmd: 0x%x", cmd); + return err; + } + g->ops.fifo.disable_tsg(tsg); + gk20a_idle(g); + break; + } + + case NVGPU_IOCTL_TSG_PREEMPT: + { + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, + "failed to host gk20a for ioctl cmd: 0x%x", cmd); + return err; + } + /* preempt TSG */ + err = g->ops.fifo.preempt_tsg(g, tsg); + gk20a_idle(g); + break; + } + + case NVGPU_IOCTL_TSG_EVENT_ID_CTRL: + { + err = gk20a_tsg_event_id_ctrl(g, tsg, + (struct nvgpu_event_id_ctrl_args *)buf); + break; + } + + case NVGPU_IOCTL_TSG_SET_RUNLIST_INTERLEAVE: + err = gk20a_tsg_ioctl_set_runlist_interleave(g, tsg, + (struct nvgpu_runlist_interleave_args *)buf); + break; + + case NVGPU_IOCTL_TSG_SET_TIMESLICE: + { + err = gk20a_tsg_ioctl_set_timeslice(g, tsg, + (struct nvgpu_timeslice_args *)buf); + break; + } + case NVGPU_IOCTL_TSG_GET_TIMESLICE: + { + err = gk20a_tsg_ioctl_get_timeslice(g, tsg, + (struct nvgpu_timeslice_args *)buf); + break; + } + + case NVGPU_TSG_IOCTL_READ_SINGLE_SM_ERROR_STATE: + { + err = gk20a_tsg_ioctl_read_single_sm_error_state(g, tsg, + (struct nvgpu_tsg_read_single_sm_error_state_args *)buf); + break; + } + + default: + nvgpu_err(g, "unrecognized tsg gpu ioctl cmd: 0x%x", + cmd); + err = -ENOTTY; + break; + } + + if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ)) + err = copy_to_user((void __user *)arg, + buf, _IOC_SIZE(cmd)); + + return err; +} diff --git a/include/os/linux/ioctl_tsg.h b/include/os/linux/ioctl_tsg.h new file mode 100644 index 0000000..67399fd --- /dev/null +++ b/include/os/linux/ioctl_tsg.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#ifndef NVGPU_IOCTL_TSG_H +#define NVGPU_IOCTL_TSG_H + +struct inode; +struct file; +struct gk20a; +struct nvgpu_ref; + +int nvgpu_ioctl_tsg_dev_release(struct inode *inode, struct file *filp); +int nvgpu_ioctl_tsg_dev_open(struct inode *inode, struct file *filp); +int nvgpu_ioctl_tsg_open(struct gk20a *g, struct file *filp); +long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg); +void nvgpu_ioctl_tsg_release(struct nvgpu_ref *ref); + +#endif diff --git a/include/os/linux/kmem.c b/include/os/linux/kmem.c new file mode 100644 index 0000000..395cc45 --- /dev/null +++ b/include/os/linux/kmem.c @@ -0,0 +1,653 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kmem_priv.h" + +/* + * Statically declared because this needs to be shared across all nvgpu driver + * instances. This makes sure that all kmem caches are _definitely_ uniquely + * named. + */ +static atomic_t kmem_cache_id; + +void *__nvgpu_big_alloc(struct gk20a *g, size_t size, bool clear) +{ + void *p; + + if (size > PAGE_SIZE) { + if (clear) + p = nvgpu_vzalloc(g, size); + else + p = nvgpu_vmalloc(g, size); + } else { + if (clear) + p = nvgpu_kzalloc(g, size); + else + p = nvgpu_kmalloc(g, size); + } + + return p; +} + +void nvgpu_big_free(struct gk20a *g, void *p) +{ + /* + * This will have to be fixed eventually. Allocs that use + * nvgpu_big_[mz]alloc() will need to remember the size of the alloc + * when freeing. + */ + if (is_vmalloc_addr(p)) + nvgpu_vfree(g, p); + else + nvgpu_kfree(g, p); +} + +void *__nvgpu_kmalloc(struct gk20a *g, size_t size, void *ip) +{ + void *alloc; + +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE + alloc = __nvgpu_track_kmalloc(g, size, ip); +#else + alloc = kmalloc(size, GFP_KERNEL); +#endif + + kmem_dbg(g, "kmalloc: size=%-6ld addr=0x%p gfp=0x%08x", + size, alloc, GFP_KERNEL); + + return alloc; +} + +void *__nvgpu_kzalloc(struct gk20a *g, size_t size, void *ip) +{ + void *alloc; + +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE + alloc = __nvgpu_track_kzalloc(g, size, ip); +#else + alloc = kzalloc(size, GFP_KERNEL); +#endif + + kmem_dbg(g, "kzalloc: size=%-6ld addr=0x%p gfp=0x%08x", + size, alloc, GFP_KERNEL); + + return alloc; +} + +void *__nvgpu_kcalloc(struct gk20a *g, size_t n, size_t size, void *ip) +{ + void *alloc; + +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE + alloc = __nvgpu_track_kcalloc(g, n, size, ip); +#else + alloc = kcalloc(n, size, GFP_KERNEL); +#endif + + kmem_dbg(g, "kcalloc: size=%-6ld addr=0x%p gfp=0x%08x", + n * size, alloc, GFP_KERNEL); + + return alloc; +} + +void *__nvgpu_vmalloc(struct gk20a *g, unsigned long size, void *ip) +{ + void *alloc; + +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE + alloc = __nvgpu_track_vmalloc(g, size, ip); +#else + alloc = vmalloc(size); +#endif + + kmem_dbg(g, "vmalloc: size=%-6ld addr=0x%p", size, alloc); + + return alloc; +} + +void *__nvgpu_vzalloc(struct gk20a *g, unsigned long size, void *ip) +{ + void *alloc; + +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE + alloc = __nvgpu_track_vzalloc(g, size, ip); +#else + alloc = vzalloc(size); +#endif + + kmem_dbg(g, "vzalloc: size=%-6ld addr=0x%p", size, alloc); + + return alloc; +} + +void __nvgpu_kfree(struct gk20a *g, void *addr) +{ + kmem_dbg(g, "kfree: addr=0x%p", addr); +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE + __nvgpu_track_kfree(g, addr); +#else + kfree(addr); +#endif +} + +void __nvgpu_vfree(struct gk20a *g, void *addr) +{ + kmem_dbg(g, "vfree: addr=0x%p", addr); +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE + __nvgpu_track_vfree(g, addr); +#else + vfree(addr); +#endif +} + +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE + +void nvgpu_lock_tracker(struct nvgpu_mem_alloc_tracker *tracker) +{ + nvgpu_mutex_acquire(&tracker->lock); +} + +void nvgpu_unlock_tracker(struct nvgpu_mem_alloc_tracker *tracker) +{ + nvgpu_mutex_release(&tracker->lock); +} + +void kmem_print_mem_alloc(struct gk20a *g, + struct nvgpu_mem_alloc *alloc, + struct seq_file *s) +{ +#ifdef __NVGPU_SAVE_KALLOC_STACK_TRACES + int i; + + __pstat(s, "nvgpu-alloc: addr=0x%llx size=%ld\n", + alloc->addr, alloc->size); + for (i = 0; i < alloc->stack_length; i++) + __pstat(s, " %3d [<%p>] %pS\n", i, + (void *)alloc->stack[i], + (void *)alloc->stack[i]); + __pstat(s, "\n"); +#else + __pstat(s, "nvgpu-alloc: addr=0x%llx size=%ld src=%pF\n", + alloc->addr, alloc->size, alloc->ip); +#endif +} + +static int nvgpu_add_alloc(struct nvgpu_mem_alloc_tracker *tracker, + struct nvgpu_mem_alloc *alloc) +{ + alloc->allocs_entry.key_start = alloc->addr; + alloc->allocs_entry.key_end = alloc->addr + alloc->size; + + nvgpu_rbtree_insert(&alloc->allocs_entry, &tracker->allocs); + return 0; +} + +static struct nvgpu_mem_alloc *nvgpu_rem_alloc( + struct nvgpu_mem_alloc_tracker *tracker, u64 alloc_addr) +{ + struct nvgpu_mem_alloc *alloc; + struct nvgpu_rbtree_node *node = NULL; + + nvgpu_rbtree_search(alloc_addr, &node, tracker->allocs); + if (!node) + return NULL; + + alloc = nvgpu_mem_alloc_from_rbtree_node(node); + + nvgpu_rbtree_unlink(node, &tracker->allocs); + + return alloc; +} + +static int __nvgpu_save_kmem_alloc(struct nvgpu_mem_alloc_tracker *tracker, + unsigned long size, unsigned long real_size, + u64 addr, void *ip) +{ + int ret; + struct nvgpu_mem_alloc *alloc; +#ifdef __NVGPU_SAVE_KALLOC_STACK_TRACES + struct stack_trace stack_trace; +#endif + + alloc = kzalloc(sizeof(*alloc), GFP_KERNEL); + if (!alloc) + return -ENOMEM; + + alloc->owner = tracker; + alloc->size = size; + alloc->real_size = real_size; + alloc->addr = addr; + alloc->ip = ip; + +#ifdef __NVGPU_SAVE_KALLOC_STACK_TRACES + stack_trace.max_entries = MAX_STACK_TRACE; + stack_trace.nr_entries = 0; + stack_trace.entries = alloc->stack; + /* + * This 4 here skips the 2 function calls that happen for all traced + * allocs due to nvgpu: + * + * __nvgpu_save_kmem_alloc+0x7c/0x128 + * __nvgpu_track_kzalloc+0xcc/0xf8 + * + * And the function calls that get made by the stack trace code itself. + * If the trace savings code changes this will likely have to change + * as well. + */ + stack_trace.skip = 4; + save_stack_trace(&stack_trace); + alloc->stack_length = stack_trace.nr_entries; +#endif + + nvgpu_lock_tracker(tracker); + tracker->bytes_alloced += size; + tracker->bytes_alloced_real += real_size; + tracker->nr_allocs++; + + /* Keep track of this for building a histogram later on. */ + if (tracker->max_alloc < size) + tracker->max_alloc = size; + if (tracker->min_alloc > size) + tracker->min_alloc = size; + + ret = nvgpu_add_alloc(tracker, alloc); + if (ret) { + WARN(1, "Duplicate alloc??? 0x%llx\n", addr); + kfree(alloc); + nvgpu_unlock_tracker(tracker); + return ret; + } + nvgpu_unlock_tracker(tracker); + + return 0; +} + +static int __nvgpu_free_kmem_alloc(struct nvgpu_mem_alloc_tracker *tracker, + u64 addr) +{ + struct nvgpu_mem_alloc *alloc; + + nvgpu_lock_tracker(tracker); + alloc = nvgpu_rem_alloc(tracker, addr); + if (WARN(!alloc, "Possible double-free detected: 0x%llx!", addr)) { + nvgpu_unlock_tracker(tracker); + return -EINVAL; + } + + memset((void *)alloc->addr, 0, alloc->size); + + tracker->nr_frees++; + tracker->bytes_freed += alloc->size; + tracker->bytes_freed_real += alloc->real_size; + nvgpu_unlock_tracker(tracker); + + return 0; +} + +static void __nvgpu_check_valloc_size(unsigned long size) +{ + WARN(size < PAGE_SIZE, "Alloc smaller than page size! (%lu)!\n", size); +} + +static void __nvgpu_check_kalloc_size(size_t size) +{ + WARN(size > PAGE_SIZE, "Alloc larger than page size! (%zu)!\n", size); +} + +void *__nvgpu_track_vmalloc(struct gk20a *g, unsigned long size, + void *ip) +{ + void *alloc = vmalloc(size); + + if (!alloc) + return NULL; + + __nvgpu_check_valloc_size(size); + + /* + * Ignore the return message. If this fails let's not cause any issues + * for the rest of the driver. + */ + __nvgpu_save_kmem_alloc(g->vmallocs, size, roundup_pow_of_two(size), + (u64)(uintptr_t)alloc, ip); + + return alloc; +} + +void *__nvgpu_track_vzalloc(struct gk20a *g, unsigned long size, + void *ip) +{ + void *alloc = vzalloc(size); + + if (!alloc) + return NULL; + + __nvgpu_check_valloc_size(size); + + /* + * Ignore the return message. If this fails let's not cause any issues + * for the rest of the driver. + */ + __nvgpu_save_kmem_alloc(g->vmallocs, size, roundup_pow_of_two(size), + (u64)(uintptr_t)alloc, ip); + + return alloc; +} + +void *__nvgpu_track_kmalloc(struct gk20a *g, size_t size, void *ip) +{ + void *alloc = kmalloc(size, GFP_KERNEL); + + if (!alloc) + return NULL; + + __nvgpu_check_kalloc_size(size); + + __nvgpu_save_kmem_alloc(g->kmallocs, size, roundup_pow_of_two(size), + (u64)(uintptr_t)alloc, ip); + + return alloc; +} + +void *__nvgpu_track_kzalloc(struct gk20a *g, size_t size, void *ip) +{ + void *alloc = kzalloc(size, GFP_KERNEL); + + if (!alloc) + return NULL; + + __nvgpu_check_kalloc_size(size); + + __nvgpu_save_kmem_alloc(g->kmallocs, size, roundup_pow_of_two(size), + (u64)(uintptr_t)alloc, ip); + + return alloc; +} + +void *__nvgpu_track_kcalloc(struct gk20a *g, size_t n, size_t size, + void *ip) +{ + void *alloc = kcalloc(n, size, GFP_KERNEL); + + if (!alloc) + return NULL; + + __nvgpu_check_kalloc_size(n * size); + + __nvgpu_save_kmem_alloc(g->kmallocs, n * size, + roundup_pow_of_two(n * size), + (u64)(uintptr_t)alloc, ip); + + return alloc; +} + +void __nvgpu_track_vfree(struct gk20a *g, void *addr) +{ + /* + * Often it is accepted practice to pass NULL pointers into free + * functions to save code. + */ + if (!addr) + return; + + __nvgpu_free_kmem_alloc(g->vmallocs, (u64)(uintptr_t)addr); + + vfree(addr); +} + +void __nvgpu_track_kfree(struct gk20a *g, void *addr) +{ + if (!addr) + return; + + __nvgpu_free_kmem_alloc(g->kmallocs, (u64)(uintptr_t)addr); + + kfree(addr); +} + +static int __do_check_for_outstanding_allocs( + struct gk20a *g, + struct nvgpu_mem_alloc_tracker *tracker, + const char *type, bool silent) +{ + struct nvgpu_rbtree_node *node; + int count = 0; + + nvgpu_rbtree_enum_start(0, &node, tracker->allocs); + while (node) { + struct nvgpu_mem_alloc *alloc = + nvgpu_mem_alloc_from_rbtree_node(node); + + if (!silent) + kmem_print_mem_alloc(g, alloc, NULL); + + count++; + nvgpu_rbtree_enum_next(&node, node); + } + + return count; +} + +/** + * check_for_outstanding_allocs - Count and display outstanding allocs + * + * @g - The GPU. + * @silent - If set don't print anything about the allocs. + * + * Dump (or just count) the number of allocations left outstanding. + */ +static int check_for_outstanding_allocs(struct gk20a *g, bool silent) +{ + int count = 0; + + count += __do_check_for_outstanding_allocs(g, g->kmallocs, "kmalloc", + silent); + count += __do_check_for_outstanding_allocs(g, g->vmallocs, "vmalloc", + silent); + + return count; +} + +static void do_nvgpu_kmem_cleanup(struct nvgpu_mem_alloc_tracker *tracker, + void (*force_free_func)(const void *)) +{ + struct nvgpu_rbtree_node *node; + + nvgpu_rbtree_enum_start(0, &node, tracker->allocs); + while (node) { + struct nvgpu_mem_alloc *alloc = + nvgpu_mem_alloc_from_rbtree_node(node); + + if (force_free_func) + force_free_func((void *)alloc->addr); + + nvgpu_rbtree_unlink(node, &tracker->allocs); + kfree(alloc); + + nvgpu_rbtree_enum_start(0, &node, tracker->allocs); + } +} + +/** + * nvgpu_kmem_cleanup - Cleanup the kmem tracking + * + * @g - The GPU. + * @force_free - If set will also free leaked objects if possible. + * + * Cleanup all of the allocs made by nvgpu_kmem tracking code. If @force_free + * is non-zero then the allocation made by nvgpu is also freed. This is risky, + * though, as it is possible that the memory is still in use by other parts of + * the GPU driver not aware that this has happened. + * + * In theory it should be fine if the GPU driver has been deinitialized and + * there are no bugs in that code. However, if there are any bugs in that code + * then they could likely manifest as odd crashes indeterminate amounts of time + * in the future. So use @force_free at your own risk. + */ +static void nvgpu_kmem_cleanup(struct gk20a *g, bool force_free) +{ + do_nvgpu_kmem_cleanup(g->kmallocs, force_free ? kfree : NULL); + do_nvgpu_kmem_cleanup(g->vmallocs, force_free ? vfree : NULL); +} + +void nvgpu_kmem_fini(struct gk20a *g, int flags) +{ + int count; + bool silent, force_free; + + if (!flags) + return; + + silent = !(flags & NVGPU_KMEM_FINI_DUMP_ALLOCS); + force_free = !!(flags & NVGPU_KMEM_FINI_FORCE_CLEANUP); + + count = check_for_outstanding_allocs(g, silent); + nvgpu_kmem_cleanup(g, force_free); + + /* + * If we leak objects we can either BUG() out or just WARN(). In general + * it doesn't make sense to BUG() on here since leaking a few objects + * won't crash the kernel but it can be helpful for development. + * + * If neither flag is set then we just silently do nothing. + */ + if (count > 0) { + if (flags & NVGPU_KMEM_FINI_WARN) { + WARN(1, "Letting %d allocs leak!!\n", count); + } else if (flags & NVGPU_KMEM_FINI_BUG) { + nvgpu_err(g, "Letting %d allocs leak!!", count); + BUG(); + } + } +} + +int nvgpu_kmem_init(struct gk20a *g) +{ + int err; + + g->vmallocs = kzalloc(sizeof(*g->vmallocs), GFP_KERNEL); + g->kmallocs = kzalloc(sizeof(*g->kmallocs), GFP_KERNEL); + + if (!g->vmallocs || !g->kmallocs) { + err = -ENOMEM; + goto fail; + } + + g->vmallocs->name = "vmalloc"; + g->kmallocs->name = "kmalloc"; + + g->vmallocs->allocs = NULL; + g->kmallocs->allocs = NULL; + + nvgpu_mutex_init(&g->vmallocs->lock); + nvgpu_mutex_init(&g->kmallocs->lock); + + g->vmallocs->min_alloc = PAGE_SIZE; + g->kmallocs->min_alloc = KMALLOC_MIN_SIZE; + + /* + * This needs to go after all the other initialization since they use + * the nvgpu_kzalloc() API. + */ + g->vmallocs->allocs_cache = nvgpu_kmem_cache_create(g, + sizeof(struct nvgpu_mem_alloc)); + g->kmallocs->allocs_cache = nvgpu_kmem_cache_create(g, + sizeof(struct nvgpu_mem_alloc)); + + if (!g->vmallocs->allocs_cache || !g->kmallocs->allocs_cache) { + err = -ENOMEM; + if (g->vmallocs->allocs_cache) + nvgpu_kmem_cache_destroy(g->vmallocs->allocs_cache); + if (g->kmallocs->allocs_cache) + nvgpu_kmem_cache_destroy(g->kmallocs->allocs_cache); + goto fail; + } + + return 0; + +fail: + if (g->vmallocs) + kfree(g->vmallocs); + if (g->kmallocs) + kfree(g->kmallocs); + return err; +} + +#else /* !CONFIG_NVGPU_TRACK_MEM_USAGE */ + +int nvgpu_kmem_init(struct gk20a *g) +{ + return 0; +} + +void nvgpu_kmem_fini(struct gk20a *g, int flags) +{ +} +#endif /* CONFIG_NVGPU_TRACK_MEM_USAGE */ + +struct nvgpu_kmem_cache *nvgpu_kmem_cache_create(struct gk20a *g, size_t size) +{ + struct nvgpu_kmem_cache *cache = + nvgpu_kzalloc(g, sizeof(struct nvgpu_kmem_cache)); + + if (!cache) + return NULL; + + cache->g = g; + + snprintf(cache->name, sizeof(cache->name), + "nvgpu-cache-0x%p-%d-%d", g, (int)size, + atomic_inc_return(&kmem_cache_id)); + cache->cache = kmem_cache_create(cache->name, + size, size, 0, NULL); + if (!cache->cache) { + nvgpu_kfree(g, cache); + return NULL; + } + + return cache; +} + +void nvgpu_kmem_cache_destroy(struct nvgpu_kmem_cache *cache) +{ + struct gk20a *g = cache->g; + + kmem_cache_destroy(cache->cache); + nvgpu_kfree(g, cache); +} + +void *nvgpu_kmem_cache_alloc(struct nvgpu_kmem_cache *cache) +{ + return kmem_cache_alloc(cache->cache, GFP_KERNEL); +} + +void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr) +{ + kmem_cache_free(cache->cache, ptr); +} diff --git a/include/os/linux/kmem_priv.h b/include/os/linux/kmem_priv.h new file mode 100644 index 0000000..a41762a --- /dev/null +++ b/include/os/linux/kmem_priv.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __KMEM_PRIV_H__ +#define __KMEM_PRIV_H__ + +#include +#include + +struct seq_file; + +#define __pstat(s, fmt, msg...) \ + do { \ + if (s) \ + seq_printf(s, fmt, ##msg); \ + else \ + pr_info(fmt, ##msg); \ + } while (0) + +#define MAX_STACK_TRACE 20 + +/* + * Linux specific version of the nvgpu_kmem_cache struct. This type is + * completely opaque to the rest of the driver. + */ +struct nvgpu_kmem_cache { + struct gk20a *g; + struct kmem_cache *cache; + + /* + * Memory to hold the kmem_cache unique name. Only necessary on our + * k3.10 kernel when not using the SLUB allocator but it's easier to + * just carry this on to newer kernels. + */ + char name[128]; +}; + +#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE + +struct nvgpu_mem_alloc { + struct nvgpu_mem_alloc_tracker *owner; + + void *ip; +#ifdef __NVGPU_SAVE_KALLOC_STACK_TRACES + unsigned long stack[MAX_STACK_TRACE]; + int stack_length; +#endif + + u64 addr; + + unsigned long size; + unsigned long real_size; + + struct nvgpu_rbtree_node allocs_entry; +}; + +static inline struct nvgpu_mem_alloc * +nvgpu_mem_alloc_from_rbtree_node(struct nvgpu_rbtree_node *node) +{ + return (struct nvgpu_mem_alloc *) + ((uintptr_t)node - offsetof(struct nvgpu_mem_alloc, allocs_entry)); +}; + +/* + * Linux specific tracking of vmalloc, kmalloc, etc. + */ +struct nvgpu_mem_alloc_tracker { + const char *name; + struct nvgpu_kmem_cache *allocs_cache; + struct nvgpu_rbtree_node *allocs; + struct nvgpu_mutex lock; + + u64 bytes_alloced; + u64 bytes_freed; + u64 bytes_alloced_real; + u64 bytes_freed_real; + u64 nr_allocs; + u64 nr_frees; + + unsigned long min_alloc; + unsigned long max_alloc; +}; + +void nvgpu_lock_tracker(struct nvgpu_mem_alloc_tracker *tracker); +void nvgpu_unlock_tracker(struct nvgpu_mem_alloc_tracker *tracker); + +void kmem_print_mem_alloc(struct gk20a *g, + struct nvgpu_mem_alloc *alloc, + struct seq_file *s); +#endif /* CONFIG_NVGPU_TRACK_MEM_USAGE */ + +#endif /* __KMEM_PRIV_H__ */ diff --git a/include/os/linux/linux-channel.c b/include/os/linux/linux-channel.c new file mode 100644 index 0000000..d035baf --- /dev/null +++ b/include/os/linux/linux-channel.c @@ -0,0 +1,657 @@ +/* + * Copyright (c) 2017-2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * This is required for nvgpu_vm_find_buf() which is used in the tracing + * code. Once we can get and access userspace buffers without requiring + * direct dma_buf usage this can be removed. + */ +#include + +#include "channel.h" +#include "ioctl_channel.h" +#include "os_linux.h" +#include "dmabuf.h" + +#include + +#include +#include +#include +#include + +#include "sync_sema_android.h" + +u32 nvgpu_submit_gpfifo_user_flags_to_common_flags(u32 user_flags) +{ + u32 flags = 0; + + if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_WAIT) + flags |= NVGPU_SUBMIT_FLAGS_FENCE_WAIT; + + if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET) + flags |= NVGPU_SUBMIT_FLAGS_FENCE_GET; + + if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_HW_FORMAT) + flags |= NVGPU_SUBMIT_FLAGS_HW_FORMAT; + + if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE) + flags |= NVGPU_SUBMIT_FLAGS_SYNC_FENCE; + + if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SUPPRESS_WFI) + flags |= NVGPU_SUBMIT_FLAGS_SUPPRESS_WFI; + + if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SKIP_BUFFER_REFCOUNTING) + flags |= NVGPU_SUBMIT_FLAGS_SKIP_BUFFER_REFCOUNTING; + + return flags; +} + +/* + * API to convert error_notifiers in common code and of the form + * NVGPU_ERR_NOTIFIER_* into Linux specific error_notifiers exposed to user + * space and of the form NVGPU_CHANNEL_* + */ +static u32 nvgpu_error_notifier_to_channel_notifier(u32 error_notifier) +{ + switch (error_notifier) { + case NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT: + return NVGPU_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT; + case NVGPU_ERR_NOTIFIER_GR_ERROR_SW_METHOD: + return NVGPU_CHANNEL_GR_ERROR_SW_METHOD; + case NVGPU_ERR_NOTIFIER_GR_ERROR_SW_NOTIFY: + return NVGPU_CHANNEL_GR_ERROR_SW_NOTIFY; + case NVGPU_ERR_NOTIFIER_GR_EXCEPTION: + return NVGPU_CHANNEL_GR_EXCEPTION; + case NVGPU_ERR_NOTIFIER_GR_SEMAPHORE_TIMEOUT: + return NVGPU_CHANNEL_GR_SEMAPHORE_TIMEOUT; + case NVGPU_ERR_NOTIFIER_GR_ILLEGAL_NOTIFY: + return NVGPU_CHANNEL_GR_ILLEGAL_NOTIFY; + case NVGPU_ERR_NOTIFIER_FIFO_ERROR_MMU_ERR_FLT: + return NVGPU_CHANNEL_FIFO_ERROR_MMU_ERR_FLT; + case NVGPU_ERR_NOTIFIER_PBDMA_ERROR: + return NVGPU_CHANNEL_PBDMA_ERROR; + case NVGPU_ERR_NOTIFIER_FECS_ERR_UNIMP_FIRMWARE_METHOD: + return NVGPU_CHANNEL_FECS_ERR_UNIMP_FIRMWARE_METHOD; + case NVGPU_ERR_NOTIFIER_RESETCHANNEL_VERIF_ERROR: + return NVGPU_CHANNEL_RESETCHANNEL_VERIF_ERROR; + case NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH: + return NVGPU_CHANNEL_PBDMA_PUSHBUFFER_CRC_MISMATCH; + } + + pr_warn("%s: invalid error_notifier requested %u\n", __func__, error_notifier); + + return error_notifier; +} + +/** + * nvgpu_set_error_notifier_locked() + * Should be called with ch->error_notifier_mutex held + * + * error should be of the form NVGPU_ERR_NOTIFIER_* + */ +void nvgpu_set_error_notifier_locked(struct channel_gk20a *ch, u32 error) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + + error = nvgpu_error_notifier_to_channel_notifier(error); + + if (priv->error_notifier.dmabuf) { + struct nvgpu_notification *notification = + priv->error_notifier.notification; + struct timespec time_data; + u64 nsec; + + getnstimeofday(&time_data); + nsec = ((u64)time_data.tv_sec) * 1000000000u + + (u64)time_data.tv_nsec; + notification->time_stamp.nanoseconds[0] = + (u32)nsec; + notification->time_stamp.nanoseconds[1] = + (u32)(nsec >> 32); + notification->info32 = error; + notification->status = 0xffff; + + nvgpu_err(ch->g, + "error notifier set to %d for ch %d", error, ch->chid); + } +} + +/* error should be of the form NVGPU_ERR_NOTIFIER_* */ +void nvgpu_set_error_notifier(struct channel_gk20a *ch, u32 error) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + + nvgpu_mutex_acquire(&priv->error_notifier.mutex); + nvgpu_set_error_notifier_locked(ch, error); + nvgpu_mutex_release(&priv->error_notifier.mutex); +} + +void nvgpu_set_error_notifier_if_empty(struct channel_gk20a *ch, u32 error) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + + nvgpu_mutex_acquire(&priv->error_notifier.mutex); + if (priv->error_notifier.dmabuf) { + struct nvgpu_notification *notification = + priv->error_notifier.notification; + + /* Don't overwrite error flag if it is already set */ + if (notification->status != 0xffff) + nvgpu_set_error_notifier_locked(ch, error); + } + nvgpu_mutex_release(&priv->error_notifier.mutex); +} + +/* error_notifier should be of the form NVGPU_ERR_NOTIFIER_* */ +bool nvgpu_is_error_notifier_set(struct channel_gk20a *ch, u32 error_notifier) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + bool notifier_set = false; + + error_notifier = nvgpu_error_notifier_to_channel_notifier(error_notifier); + + nvgpu_mutex_acquire(&priv->error_notifier.mutex); + if (priv->error_notifier.dmabuf) { + struct nvgpu_notification *notification = + priv->error_notifier.notification; + u32 err = notification->info32; + + if (err == error_notifier) + notifier_set = true; + } + nvgpu_mutex_release(&priv->error_notifier.mutex); + + return notifier_set; +} + +static void gk20a_channel_update_runcb_fn(struct work_struct *work) +{ + struct nvgpu_channel_completion_cb *completion_cb = + container_of(work, struct nvgpu_channel_completion_cb, work); + struct nvgpu_channel_linux *priv = + container_of(completion_cb, + struct nvgpu_channel_linux, completion_cb); + struct channel_gk20a *ch = priv->ch; + void (*fn)(struct channel_gk20a *, void *); + void *user_data; + + nvgpu_spinlock_acquire(&completion_cb->lock); + fn = completion_cb->fn; + user_data = completion_cb->user_data; + nvgpu_spinlock_release(&completion_cb->lock); + + if (fn) + fn(ch, user_data); +} + +static void nvgpu_channel_work_completion_init(struct channel_gk20a *ch) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + + priv->completion_cb.fn = NULL; + priv->completion_cb.user_data = NULL; + nvgpu_spinlock_init(&priv->completion_cb.lock); + INIT_WORK(&priv->completion_cb.work, gk20a_channel_update_runcb_fn); +} + +static void nvgpu_channel_work_completion_clear(struct channel_gk20a *ch) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + + nvgpu_spinlock_acquire(&priv->completion_cb.lock); + priv->completion_cb.fn = NULL; + priv->completion_cb.user_data = NULL; + nvgpu_spinlock_release(&priv->completion_cb.lock); + cancel_work_sync(&priv->completion_cb.work); +} + +static void nvgpu_channel_work_completion_signal(struct channel_gk20a *ch) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + + if (priv->completion_cb.fn) + schedule_work(&priv->completion_cb.work); +} + +static void nvgpu_channel_work_completion_cancel_sync(struct channel_gk20a *ch) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + + if (priv->completion_cb.fn) + cancel_work_sync(&priv->completion_cb.work); +} + +struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g, + void (*update_fn)(struct channel_gk20a *, void *), + void *update_fn_data, + int runlist_id, + bool is_privileged_channel) +{ + struct channel_gk20a *ch; + struct nvgpu_channel_linux *priv; + + ch = gk20a_open_new_channel(g, runlist_id, is_privileged_channel, + nvgpu_current_pid(g), nvgpu_current_tid(g)); + + if (ch) { + priv = ch->os_priv; + nvgpu_spinlock_acquire(&priv->completion_cb.lock); + priv->completion_cb.fn = update_fn; + priv->completion_cb.user_data = update_fn_data; + nvgpu_spinlock_release(&priv->completion_cb.lock); + } + + return ch; +} + +static void nvgpu_channel_open_linux(struct channel_gk20a *ch) +{ +} + +static void nvgpu_channel_close_linux(struct channel_gk20a *ch) +{ + nvgpu_channel_work_completion_clear(ch); + +#if defined(CONFIG_GK20A_CYCLE_STATS) + gk20a_channel_free_cycle_stats_buffer(ch); + gk20a_channel_free_cycle_stats_snapshot(ch); +#endif +} + +static int nvgpu_channel_alloc_linux(struct gk20a *g, struct channel_gk20a *ch) +{ + struct nvgpu_channel_linux *priv; + int err; + + priv = nvgpu_kzalloc(g, sizeof(*priv)); + if (!priv) + return -ENOMEM; + + ch->os_priv = priv; + priv->ch = ch; + +#ifdef CONFIG_SYNC + ch->has_os_fence_framework_support = true; +#endif + + err = nvgpu_mutex_init(&priv->error_notifier.mutex); + if (err) { + nvgpu_kfree(g, priv); + return err; + } + + nvgpu_channel_work_completion_init(ch); + + return 0; +} + +static void nvgpu_channel_free_linux(struct gk20a *g, struct channel_gk20a *ch) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + + nvgpu_mutex_destroy(&priv->error_notifier.mutex); + nvgpu_kfree(g, priv); + + ch->os_priv = NULL; + +#ifdef CONFIG_SYNC + ch->has_os_fence_framework_support = false; +#endif +} + +static int nvgpu_channel_init_os_fence_framework(struct channel_gk20a *ch, + const char *fmt, ...) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + struct nvgpu_os_fence_framework *fence_framework; + char name[30]; + va_list args; + + fence_framework = &priv->fence_framework; + + va_start(args, fmt); + vsnprintf(name, sizeof(name), fmt, args); + va_end(args); + + fence_framework->timeline = gk20a_sync_timeline_create(name); + + if (!fence_framework->timeline) + return -EINVAL; + + return 0; +} +static void nvgpu_channel_signal_os_fence_framework(struct channel_gk20a *ch) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + struct nvgpu_os_fence_framework *fence_framework; + + fence_framework = &priv->fence_framework; + + gk20a_sync_timeline_signal(fence_framework->timeline); +} + +static void nvgpu_channel_destroy_os_fence_framework(struct channel_gk20a *ch) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + struct nvgpu_os_fence_framework *fence_framework; + + fence_framework = &priv->fence_framework; + + gk20a_sync_timeline_destroy(fence_framework->timeline); + fence_framework->timeline = NULL; +} + +static bool nvgpu_channel_fence_framework_exists(struct channel_gk20a *ch) +{ + struct nvgpu_channel_linux *priv = ch->os_priv; + struct nvgpu_os_fence_framework *fence_framework; + + fence_framework = &priv->fence_framework; + + return (fence_framework->timeline != NULL); +} + +static int nvgpu_channel_copy_user_gpfifo(struct nvgpu_gpfifo_entry *dest, + struct nvgpu_gpfifo_userdata userdata, u32 start, u32 length) +{ + struct nvgpu_gpfifo_entry __user *user_gpfifo = userdata.entries; + unsigned long n; + + n = copy_from_user(dest, user_gpfifo + start, + length * sizeof(struct nvgpu_gpfifo_entry)); + + return n == 0 ? 0 : -EFAULT; +} + +int nvgpu_usermode_buf_from_dmabuf(struct gk20a *g, int dmabuf_fd, + struct nvgpu_mem *mem, struct nvgpu_usermode_buf_linux *buf) +{ + struct device *dev = dev_from_gk20a(g); + struct dma_buf *dmabuf; + struct sg_table *sgt; + struct dma_buf_attachment *attachment; + int err; + + dmabuf = dma_buf_get(dmabuf_fd); + if (IS_ERR(dmabuf)) { + return PTR_ERR(dmabuf); + } + + if (gk20a_dmabuf_aperture(g, dmabuf) == APERTURE_INVALID) { + err = -EINVAL; + goto put_dmabuf; + } + + err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev); + if (err != 0) { + goto put_dmabuf; + } + + sgt = gk20a_mm_pin(dev, dmabuf, &attachment); + if (IS_ERR(sgt)) { + nvgpu_warn(g, "Failed to pin dma_buf!"); + err = PTR_ERR(sgt); + goto put_dmabuf; + } + + buf->dmabuf = dmabuf; + buf->attachment = attachment; + buf->sgt = sgt; + + /* + * This mem is unmapped and freed in a common path; for Linux, we'll + * also need to unref the dmabuf stuff (above) but the sgt here is only + * borrowed, so it cannot be freed by nvgpu_mem_*. + */ + mem->mem_flags = NVGPU_MEM_FLAG_FOREIGN_SGT; + mem->aperture = APERTURE_SYSMEM; + mem->skip_wmb = 0; + mem->size = dmabuf->size; + + mem->priv.flags = 0; + mem->priv.pages = NULL; + mem->priv.sgt = sgt; + + return 0; +put_dmabuf: + dma_buf_put(dmabuf); + return err; +} + +void nvgpu_channel_free_usermode_buffers(struct channel_gk20a *c) +{ + struct nvgpu_channel_linux *priv = c->os_priv; + struct gk20a *g = c->g; + struct device *dev = dev_from_gk20a(g); + + if (priv->usermode.gpfifo.dmabuf != NULL) { + gk20a_mm_unpin(dev, priv->usermode.gpfifo.dmabuf, + priv->usermode.gpfifo.attachment, + priv->usermode.gpfifo.sgt); + dma_buf_put(priv->usermode.gpfifo.dmabuf); + priv->usermode.gpfifo.dmabuf = NULL; + } + + if (priv->usermode.userd.dmabuf != NULL) { + gk20a_mm_unpin(dev, priv->usermode.userd.dmabuf, + priv->usermode.userd.attachment, + priv->usermode.userd.sgt); + dma_buf_put(priv->usermode.userd.dmabuf); + priv->usermode.userd.dmabuf = NULL; + } +} + +static int nvgpu_channel_alloc_usermode_buffers(struct channel_gk20a *c, + struct nvgpu_setup_bind_args *args) +{ + struct nvgpu_channel_linux *priv = c->os_priv; + struct gk20a *g = c->g; + struct device *dev = dev_from_gk20a(g); + size_t gpfifo_size; + int err; + + if (args->gpfifo_dmabuf_fd == 0 || args->userd_dmabuf_fd == 0) { + return -EINVAL; + } + + if (args->gpfifo_dmabuf_offset != 0 || + args->userd_dmabuf_offset != 0) { + /* TODO - not yet supported */ + return -EINVAL; + } + + err = nvgpu_usermode_buf_from_dmabuf(g, args->gpfifo_dmabuf_fd, + &c->usermode_gpfifo, &priv->usermode.gpfifo); + if (err < 0) { + return err; + } + + gpfifo_size = max_t(u32, SZ_4K, + args->num_gpfifo_entries * + nvgpu_get_gpfifo_entry_size()); + + if (c->usermode_gpfifo.size < gpfifo_size) { + err = -EINVAL; + goto free_gpfifo; + } + + c->usermode_gpfifo.gpu_va = nvgpu_gmmu_map(c->vm, &c->usermode_gpfifo, + c->usermode_gpfifo.size, 0, gk20a_mem_flag_none, + false, c->usermode_gpfifo.aperture); + + if (c->usermode_gpfifo.gpu_va == 0) { + err = -ENOMEM; + goto unmap_free_gpfifo; + } + + err = nvgpu_usermode_buf_from_dmabuf(g, args->userd_dmabuf_fd, + &c->usermode_userd, &priv->usermode.userd); + if (err < 0) { + goto unmap_free_gpfifo; + } + + args->work_submit_token = g->fifo.channel_base + c->chid; + + return 0; +unmap_free_gpfifo: + nvgpu_dma_unmap_free(c->vm, &c->usermode_gpfifo); +free_gpfifo: + gk20a_mm_unpin(dev, priv->usermode.gpfifo.dmabuf, + priv->usermode.gpfifo.attachment, + priv->usermode.gpfifo.sgt); + dma_buf_put(priv->usermode.gpfifo.dmabuf); + priv->usermode.gpfifo.dmabuf = NULL; + return err; +} + +int nvgpu_init_channel_support_linux(struct nvgpu_os_linux *l) +{ + struct gk20a *g = &l->g; + struct fifo_gk20a *f = &g->fifo; + int chid; + int err; + + for (chid = 0; chid < (int)f->num_channels; chid++) { + struct channel_gk20a *ch = &f->channel[chid]; + + err = nvgpu_channel_alloc_linux(g, ch); + if (err) + goto err_clean; + } + + g->os_channel.open = nvgpu_channel_open_linux; + g->os_channel.close = nvgpu_channel_close_linux; + g->os_channel.work_completion_signal = + nvgpu_channel_work_completion_signal; + g->os_channel.work_completion_cancel_sync = + nvgpu_channel_work_completion_cancel_sync; + + g->os_channel.os_fence_framework_inst_exists = + nvgpu_channel_fence_framework_exists; + g->os_channel.init_os_fence_framework = + nvgpu_channel_init_os_fence_framework; + g->os_channel.signal_os_fence_framework = + nvgpu_channel_signal_os_fence_framework; + g->os_channel.destroy_os_fence_framework = + nvgpu_channel_destroy_os_fence_framework; + + g->os_channel.copy_user_gpfifo = + nvgpu_channel_copy_user_gpfifo; + + g->os_channel.alloc_usermode_buffers = + nvgpu_channel_alloc_usermode_buffers; + + g->os_channel.free_usermode_buffers = + nvgpu_channel_free_usermode_buffers; + + return 0; + +err_clean: + for (; chid >= 0; chid--) { + struct channel_gk20a *ch = &f->channel[chid]; + + nvgpu_channel_free_linux(g, ch); + } + return err; +} + +void nvgpu_remove_channel_support_linux(struct nvgpu_os_linux *l) +{ + struct gk20a *g = &l->g; + struct fifo_gk20a *f = &g->fifo; + unsigned int chid; + + for (chid = 0; chid < f->num_channels; chid++) { + struct channel_gk20a *ch = &f->channel[chid]; + + nvgpu_channel_free_linux(g, ch); + } + + g->os_channel.os_fence_framework_inst_exists = NULL; + g->os_channel.init_os_fence_framework = NULL; + g->os_channel.signal_os_fence_framework = NULL; + g->os_channel.destroy_os_fence_framework = NULL; +} + +u32 nvgpu_get_gpfifo_entry_size(void) +{ + return sizeof(struct nvgpu_gpfifo_entry); +} + +#ifdef CONFIG_DEBUG_FS +static void trace_write_pushbuffer(struct channel_gk20a *c, + struct nvgpu_gpfifo_entry *g) +{ + void *mem = NULL; + unsigned int words; + u64 offset; + struct dma_buf *dmabuf = NULL; + + if (gk20a_debug_trace_cmdbuf) { + u64 gpu_va = (u64)g->entry0 | + (u64)((u64)pbdma_gp_entry1_get_hi_v(g->entry1) << 32); + int err; + + words = pbdma_gp_entry1_length_v(g->entry1); + err = nvgpu_vm_find_buf(c->vm, gpu_va, &dmabuf, &offset); + if (!err) + mem = dma_buf_vmap(dmabuf); + } + + if (mem) { + u32 i; + /* + * Write in batches of 128 as there seems to be a limit + * of how much you can output to ftrace at once. + */ + for (i = 0; i < words; i += 128U) { + trace_gk20a_push_cmdbuf( + c->g->name, + 0, + min(words - i, 128U), + offset + i * sizeof(u32), + mem); + } + dma_buf_vunmap(dmabuf, mem); + } +} + +void trace_write_pushbuffers(struct channel_gk20a *c, u32 count) +{ + struct nvgpu_gpfifo_entry *gp = c->gpfifo.mem.cpu_va; + u32 n = c->gpfifo.entry_num; + u32 start = c->gpfifo.put; + u32 i; + + if (!gk20a_debug_trace_cmdbuf) + return; + + if (!gp) + return; + + for (i = 0; i < count; i++) + trace_write_pushbuffer(c, &gp[(start + i) % n]); +} +#endif diff --git a/include/os/linux/linux-dma.c b/include/os/linux/linux-dma.c new file mode 100644 index 0000000..d704b2a --- /dev/null +++ b/include/os/linux/linux-dma.c @@ -0,0 +1,534 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "platform_gk20a.h" +#include "os_linux.h" +#include "dmabuf_vidmem.h" + +#ifdef __DMA_ATTRS_LONGS +#define NVGPU_DEFINE_DMA_ATTRS(x) \ + struct dma_attrs x = { \ + .flags = { [0 ... __DMA_ATTRS_LONGS-1] = 0 }, \ + } +#define NVGPU_DMA_ATTR(attrs) &attrs +#else +#define NVGPU_DEFINE_DMA_ATTRS(attrs) unsigned long attrs = 0 +#define NVGPU_DMA_ATTR(attrs) attrs +#endif + +/* + * Enough to hold all the possible flags in string form. When a new flag is + * added it must be added here as well!! + */ +#define NVGPU_DMA_STR_SIZE \ + sizeof("NO_KERNEL_MAPPING FORCE_CONTIGUOUS") + +/* + * The returned string is kmalloc()ed here but must be freed by the caller. + */ +static char *nvgpu_dma_flags_to_str(struct gk20a *g, unsigned long flags) +{ + char *buf = nvgpu_kzalloc(g, NVGPU_DMA_STR_SIZE); + int bytes_available = NVGPU_DMA_STR_SIZE; + + /* + * Return the empty buffer if there's no flags. Makes it easier on the + * calling code to just print it instead of any if (NULL) type logic. + */ + if (!flags) + return buf; + +#define APPEND_FLAG(flag, str_flag) \ + do { \ + if (flags & flag) { \ + strncat(buf, str_flag, bytes_available); \ + bytes_available -= strlen(str_flag); \ + } \ + } while (0) + + APPEND_FLAG(NVGPU_DMA_NO_KERNEL_MAPPING, "NO_KERNEL_MAPPING "); + APPEND_FLAG(NVGPU_DMA_FORCE_CONTIGUOUS, "FORCE_CONTIGUOUS "); +#undef APPEND_FLAG + + return buf; +} + +/** + * __dma_dbg - Debug print for DMA allocs and frees. + * + * @g - The GPU. + * @size - The requested size of the alloc (size_t). + * @flags - The flags (unsigned long). + * @type - A string describing the type (i.e: sysmem or vidmem). + * @what - A string with 'alloc' or 'free'. + * + * @flags is the DMA flags. If there are none or it doesn't make sense to print + * flags just pass 0. + * + * Please use dma_dbg_alloc() and dma_dbg_free() instead of this function. + */ +static void __dma_dbg(struct gk20a *g, size_t size, unsigned long flags, + const char *type, const char *what, + const char *func, int line) +{ + char *flags_str = NULL; + + /* + * Don't bother making the flags_str if debugging is + * not enabled. This saves a malloc and a free. + */ + if (!nvgpu_log_mask_enabled(g, gpu_dbg_dma)) + return; + + flags_str = nvgpu_dma_flags_to_str(g, flags); + + __nvgpu_log_dbg(g, gpu_dbg_dma, + func, line, + "DMA %s: [%s] size=%-7zu " + "aligned=%-7zu total=%-10llukB %s", + what, type, + size, PAGE_ALIGN(size), + g->dma_memory_used >> 10, + flags_str); + + if (flags_str) + nvgpu_kfree(g, flags_str); +} + +#define dma_dbg_alloc(g, size, flags, type) \ + __dma_dbg(g, size, flags, type, "alloc", __func__, __LINE__) +#define dma_dbg_free(g, size, flags, type) \ + __dma_dbg(g, size, flags, type, "free", __func__, __LINE__) + +/* + * For after the DMA alloc is done. + */ +#define __dma_dbg_done(g, size, type, what) \ + nvgpu_log(g, gpu_dbg_dma, \ + "DMA %s: [%s] size=%-7zu Done!", \ + what, type, size); \ + +#define dma_dbg_alloc_done(g, size, type) \ + __dma_dbg_done(g, size, type, "alloc") +#define dma_dbg_free_done(g, size, type) \ + __dma_dbg_done(g, size, type, "free") + +#if defined(CONFIG_GK20A_VIDMEM) +static u64 __nvgpu_dma_alloc(struct nvgpu_allocator *allocator, u64 at, + size_t size) +{ + u64 addr = 0; + + if (at) + addr = nvgpu_alloc_fixed(allocator, at, size, 0); + else + addr = nvgpu_alloc(allocator, size); + + return addr; +} +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) +static void nvgpu_dma_flags_to_attrs(unsigned long *attrs, + unsigned long flags) +#define ATTR_ARG(x) *x +#else +static void nvgpu_dma_flags_to_attrs(struct dma_attrs *attrs, + unsigned long flags) +#define ATTR_ARG(x) x +#endif +{ + if (flags & NVGPU_DMA_NO_KERNEL_MAPPING) + dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, ATTR_ARG(attrs)); + if (flags & NVGPU_DMA_FORCE_CONTIGUOUS) + dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, ATTR_ARG(attrs)); +#undef ATTR_ARG +} + +int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem) +{ + struct device *d = dev_from_gk20a(g); + int err; + dma_addr_t iova; + NVGPU_DEFINE_DMA_ATTRS(dma_attrs); + void *alloc_ret; + + if (nvgpu_mem_is_valid(mem)) { + nvgpu_warn(g, "memory leak !!"); + WARN_ON(1); + } + + /* + * WAR for IO coherent chips: the DMA API does not seem to generate + * mappings that work correctly. Unclear why - Bug ID: 2040115. + * + * Basically we just tell the DMA API not to map with NO_KERNEL_MAPPING + * and then make a vmap() ourselves. + */ + if (nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM)) + flags |= NVGPU_DMA_NO_KERNEL_MAPPING; + + /* + * Before the debug print so we see this in the total. But during + * cleanup in the fail path this has to be subtracted. + */ + g->dma_memory_used += PAGE_ALIGN(size); + + dma_dbg_alloc(g, size, flags, "sysmem"); + + /* + * Save the old size but for actual allocation purposes the size is + * going to be page aligned. + */ + mem->size = size; + size = PAGE_ALIGN(size); + + nvgpu_dma_flags_to_attrs(&dma_attrs, flags); + + alloc_ret = dma_alloc_attrs(d, size, &iova, + GFP_KERNEL|__GFP_ZERO, + NVGPU_DMA_ATTR(dma_attrs)); + if (!alloc_ret) + return -ENOMEM; + + if (flags & NVGPU_DMA_NO_KERNEL_MAPPING) { + mem->priv.pages = alloc_ret; + err = nvgpu_get_sgtable_from_pages(g, &mem->priv.sgt, + mem->priv.pages, + iova, size); + } else { + mem->cpu_va = alloc_ret; + err = nvgpu_get_sgtable_attrs(g, &mem->priv.sgt, mem->cpu_va, + iova, size, flags); + } + if (err) + goto fail_free_dma; + + if (nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM)) { + mem->cpu_va = vmap(mem->priv.pages, + size >> PAGE_SHIFT, + 0, PAGE_KERNEL); + if (!mem->cpu_va) { + err = -ENOMEM; + goto fail_free_sgt; + } + } + + mem->aligned_size = size; + mem->aperture = APERTURE_SYSMEM; + mem->priv.flags = flags; + + dma_dbg_alloc_done(g, mem->size, "sysmem"); + + return 0; + +fail_free_sgt: + nvgpu_free_sgtable(g, &mem->priv.sgt); +fail_free_dma: + dma_free_attrs(d, size, alloc_ret, iova, NVGPU_DMA_ATTR(dma_attrs)); + mem->cpu_va = NULL; + mem->priv.sgt = NULL; + mem->size = 0; + g->dma_memory_used -= mem->aligned_size; + return err; +} + +int nvgpu_dma_alloc_flags_vid_at(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem, u64 at) +{ +#if defined(CONFIG_GK20A_VIDMEM) + u64 addr; + int err; + struct nvgpu_allocator *vidmem_alloc = g->mm.vidmem.cleared ? + &g->mm.vidmem.allocator : + &g->mm.vidmem.bootstrap_allocator; + u64 before_pending; + + if (nvgpu_mem_is_valid(mem)) { + nvgpu_warn(g, "memory leak !!"); + WARN_ON(1); + } + + dma_dbg_alloc(g, size, flags, "vidmem"); + + mem->size = size; + size = PAGE_ALIGN(size); + + if (!nvgpu_alloc_initialized(&g->mm.vidmem.allocator)) + return -ENOSYS; + + /* + * Our own allocator doesn't have any flags yet, and we can't + * kernel-map these, so require explicit flags. + */ + WARN_ON(flags != NVGPU_DMA_NO_KERNEL_MAPPING); + + nvgpu_mutex_acquire(&g->mm.vidmem.clear_list_mutex); + before_pending = atomic64_read(&g->mm.vidmem.bytes_pending.atomic_var); + addr = __nvgpu_dma_alloc(vidmem_alloc, at, size); + nvgpu_mutex_release(&g->mm.vidmem.clear_list_mutex); + if (!addr) { + /* + * If memory is known to be freed soon, let the user know that + * it may be available after a while. + */ + if (before_pending) + return -EAGAIN; + else + return -ENOMEM; + } + + if (at) + mem->mem_flags |= NVGPU_MEM_FLAG_FIXED; + + mem->priv.sgt = nvgpu_kzalloc(g, sizeof(struct sg_table)); + if (!mem->priv.sgt) { + err = -ENOMEM; + goto fail_physfree; + } + + err = sg_alloc_table(mem->priv.sgt, 1, GFP_KERNEL); + if (err) + goto fail_kfree; + + nvgpu_vidmem_set_page_alloc(mem->priv.sgt->sgl, addr); + sg_set_page(mem->priv.sgt->sgl, NULL, size, 0); + + mem->aligned_size = size; + mem->aperture = APERTURE_VIDMEM; + mem->vidmem_alloc = (struct nvgpu_page_alloc *)(uintptr_t)addr; + mem->allocator = vidmem_alloc; + mem->priv.flags = flags; + + nvgpu_init_list_node(&mem->clear_list_entry); + + dma_dbg_alloc_done(g, mem->size, "vidmem"); + + return 0; + +fail_kfree: + nvgpu_kfree(g, mem->priv.sgt); +fail_physfree: + nvgpu_free(&g->mm.vidmem.allocator, addr); + mem->size = 0; + return err; +#else + return -ENOSYS; +#endif +} + +void nvgpu_dma_free_sys(struct gk20a *g, struct nvgpu_mem *mem) +{ + struct device *d = dev_from_gk20a(g); + + g->dma_memory_used -= mem->aligned_size; + + dma_dbg_free(g, mem->size, mem->priv.flags, "sysmem"); + + if (!(mem->mem_flags & NVGPU_MEM_FLAG_SHADOW_COPY) && + !(mem->mem_flags & __NVGPU_MEM_FLAG_NO_DMA) && + (mem->cpu_va || mem->priv.pages)) { + /* + * Free side of WAR for bug 2040115. + */ + if (nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM)) + vunmap(mem->cpu_va); + + if (mem->priv.flags) { + NVGPU_DEFINE_DMA_ATTRS(dma_attrs); + + nvgpu_dma_flags_to_attrs(&dma_attrs, mem->priv.flags); + + if (mem->priv.flags & NVGPU_DMA_NO_KERNEL_MAPPING) { + dma_free_attrs(d, mem->aligned_size, mem->priv.pages, + sg_dma_address(mem->priv.sgt->sgl), + NVGPU_DMA_ATTR(dma_attrs)); + } else { + dma_free_attrs(d, mem->aligned_size, mem->cpu_va, + sg_dma_address(mem->priv.sgt->sgl), + NVGPU_DMA_ATTR(dma_attrs)); + } + } else { + dma_free_coherent(d, mem->aligned_size, mem->cpu_va, + sg_dma_address(mem->priv.sgt->sgl)); + } + mem->cpu_va = NULL; + mem->priv.pages = NULL; + } + + /* + * When this flag is set we expect that pages is still populated but not + * by the DMA API. + */ + if (mem->mem_flags & __NVGPU_MEM_FLAG_NO_DMA) + nvgpu_kfree(g, mem->priv.pages); + + if ((mem->mem_flags & NVGPU_MEM_FLAG_FOREIGN_SGT) == 0 && + mem->priv.sgt != NULL) { + nvgpu_free_sgtable(g, &mem->priv.sgt); + } + + dma_dbg_free_done(g, mem->size, "sysmem"); + + mem->size = 0; + mem->aligned_size = 0; + mem->aperture = APERTURE_INVALID; +} + +void nvgpu_dma_free_vid(struct gk20a *g, struct nvgpu_mem *mem) +{ +#if defined(CONFIG_GK20A_VIDMEM) + size_t mem_size = mem->size; + + dma_dbg_free(g, mem->size, mem->priv.flags, "vidmem"); + + /* Sanity check - only this supported when allocating. */ + WARN_ON(mem->priv.flags != NVGPU_DMA_NO_KERNEL_MAPPING); + + if (mem->mem_flags & NVGPU_MEM_FLAG_USER_MEM) { + int err = nvgpu_vidmem_clear_list_enqueue(g, mem); + + /* + * If there's an error here then that means we can't clear the + * vidmem. That's too bad; however, we still own the nvgpu_mem + * buf so we have to free that. + * + * We don't need to worry about the vidmem allocator itself + * since when that gets cleaned up in the driver shutdown path + * all the outstanding allocs are force freed. + */ + if (err) + nvgpu_kfree(g, mem); + } else { + nvgpu_memset(g, mem, 0, 0, mem->aligned_size); + nvgpu_free(mem->allocator, + (u64)nvgpu_vidmem_get_page_alloc(mem->priv.sgt->sgl)); + nvgpu_free_sgtable(g, &mem->priv.sgt); + + mem->size = 0; + mem->aligned_size = 0; + mem->aperture = APERTURE_INVALID; + } + + dma_dbg_free_done(g, mem_size, "vidmem"); +#endif +} + +int nvgpu_get_sgtable_attrs(struct gk20a *g, struct sg_table **sgt, + void *cpuva, u64 iova, size_t size, unsigned long flags) +{ + int err = 0; + struct sg_table *tbl; + NVGPU_DEFINE_DMA_ATTRS(dma_attrs); + + tbl = nvgpu_kzalloc(g, sizeof(struct sg_table)); + if (!tbl) { + err = -ENOMEM; + goto fail; + } + + nvgpu_dma_flags_to_attrs(&dma_attrs, flags); + err = dma_get_sgtable_attrs(dev_from_gk20a(g), tbl, cpuva, iova, + size, NVGPU_DMA_ATTR(dma_attrs)); + if (err) + goto fail; + + sg_dma_address(tbl->sgl) = iova; + *sgt = tbl; + + return 0; + +fail: + if (tbl) + nvgpu_kfree(g, tbl); + + return err; +} + +int nvgpu_get_sgtable(struct gk20a *g, struct sg_table **sgt, + void *cpuva, u64 iova, size_t size) +{ + return nvgpu_get_sgtable_attrs(g, sgt, cpuva, iova, size, 0); +} + +int nvgpu_get_sgtable_from_pages(struct gk20a *g, struct sg_table **sgt, + struct page **pages, u64 iova, size_t size) +{ + int err = 0; + struct sg_table *tbl; + + tbl = nvgpu_kzalloc(g, sizeof(struct sg_table)); + if (!tbl) { + err = -ENOMEM; + goto fail; + } + + err = sg_alloc_table_from_pages(tbl, pages, + DIV_ROUND_UP(size, PAGE_SIZE), + 0, size, GFP_KERNEL); + if (err) + goto fail; + + sg_dma_address(tbl->sgl) = iova; + *sgt = tbl; + + return 0; + +fail: + if (tbl) + nvgpu_kfree(g, tbl); + + return err; +} + +void nvgpu_free_sgtable(struct gk20a *g, struct sg_table **sgt) +{ + sg_free_table(*sgt); + nvgpu_kfree(g, *sgt); + *sgt = NULL; +} + +bool nvgpu_iommuable(struct gk20a *g) +{ +#ifdef CONFIG_TEGRA_GK20A + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + /* + * Check against the nvgpu device to see if it's been marked as + * IOMMU'able. + */ + if (!device_is_iommuable(l->dev)) + return false; +#endif + + return true; +} diff --git a/include/os/linux/log.c b/include/os/linux/log.c new file mode 100644 index 0000000..bd9f67d --- /dev/null +++ b/include/os/linux/log.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include +#include + +#include "platform_gk20a.h" +#include "os_linux.h" + +/* + * Define a length for log buffers. This is the buffer that the 'fmt, ...' part + * of __nvgpu_do_log_print() prints into. This buffer lives on the stack so it + * needs to not be overly sized since we have limited kernel stack space. But at + * the same time we don't want it to be restrictive either. + */ +#define LOG_BUFFER_LENGTH 160 + +/* + * Annoying quirk of Linux: this has to be a string literal since the printk() + * function and friends use the preprocessor to concatenate stuff to the start + * of this string when printing. + */ +#define LOG_FMT "nvgpu: %s %33s:%-4d [%s] %s\n" + +static const char *log_types[] = { + "ERR", + "WRN", + "DBG", + "INFO", +}; + +int nvgpu_log_mask_enabled(struct gk20a *g, u64 log_mask) +{ + return !!(g->log_mask & log_mask); +} + +static inline const char *nvgpu_log_name(struct gk20a *g) +{ + return dev_name(dev_from_gk20a(g)); +} + +#ifdef CONFIG_GK20A_TRACE_PRINTK +static void __nvgpu_trace_printk_log(u32 trace, const char *gpu_name, + const char *func_name, int line, + const char *log_type, const char *log) +{ + trace_printk(LOG_FMT, gpu_name, func_name, line, log_type, log); +} +#endif + +static void __nvgpu_really_print_log(u32 trace, const char *gpu_name, + const char *func_name, int line, + enum nvgpu_log_type type, const char *log) +{ + const char *name = gpu_name ? gpu_name : ""; + const char *log_type = log_types[type]; + +#ifdef CONFIG_GK20A_TRACE_PRINTK + if (trace) + return __nvgpu_trace_printk_log(trace, name, func_name, + line, log_type, log); +#endif + switch (type) { + case NVGPU_DEBUG: + /* + * We could use pr_debug() here but we control debug enablement + * separately from the Linux kernel. Perhaps this is a bug in + * nvgpu. + */ + pr_info(LOG_FMT, name, func_name, line, log_type, log); + break; + case NVGPU_INFO: + pr_info(LOG_FMT, name, func_name, line, log_type, log); + break; + case NVGPU_WARNING: + pr_warn(LOG_FMT, name, func_name, line, log_type, log); + break; + case NVGPU_ERROR: + pr_err(LOG_FMT, name, func_name, line, log_type, log); + break; + } +} + +__attribute__((format (printf, 5, 6))) +void __nvgpu_log_msg(struct gk20a *g, const char *func_name, int line, + enum nvgpu_log_type type, const char *fmt, ...) +{ + char log[LOG_BUFFER_LENGTH]; + va_list args; + + va_start(args, fmt); + vsnprintf(log, LOG_BUFFER_LENGTH, fmt, args); + va_end(args); + + __nvgpu_really_print_log(0, g ? nvgpu_log_name(g) : "", + func_name, line, type, log); +} + +__attribute__((format (printf, 5, 6))) +void __nvgpu_log_dbg(struct gk20a *g, u64 log_mask, + const char *func_name, int line, + const char *fmt, ...) +{ + char log[LOG_BUFFER_LENGTH]; + va_list args; + + if ((log_mask & g->log_mask) == 0) + return; + + va_start(args, fmt); + vsnprintf(log, LOG_BUFFER_LENGTH, fmt, args); + va_end(args); + + __nvgpu_really_print_log(g->log_trace, nvgpu_log_name(g), + func_name, line, NVGPU_DEBUG, log); +} diff --git a/include/os/linux/ltc.c b/include/os/linux/ltc.c new file mode 100644 index 0000000..baeb20b --- /dev/null +++ b/include/os/linux/ltc.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "gk20a/gr_gk20a.h" + +int nvgpu_ltc_alloc_cbc(struct gk20a *g, size_t compbit_backing_size, + bool vidmem_alloc) +{ + struct gr_gk20a *gr = &g->gr; + unsigned long flags = 0; + + if (nvgpu_mem_is_valid(&gr->compbit_store.mem)) + return 0; + + if (vidmem_alloc) { + /* + * Backing store MUST be physically contiguous and allocated in + * one chunk + * Vidmem allocation API does not support FORCE_CONTIGUOUS like + * flag to allocate contiguous memory + * But this allocation will happen in vidmem bootstrap allocator + * which always allocates contiguous memory + */ + return nvgpu_dma_alloc_vid(g, + compbit_backing_size, + &gr->compbit_store.mem); + } else { + if (!nvgpu_iommuable(g)) + flags = NVGPU_DMA_FORCE_CONTIGUOUS; + + return nvgpu_dma_alloc_flags_sys(g, + flags, + compbit_backing_size, + &gr->compbit_store.mem); + } +} diff --git a/include/os/linux/module.c b/include/os/linux/module.c new file mode 100644 index 0000000..807df2c --- /dev/null +++ b/include/os/linux/module.c @@ -0,0 +1,1529 @@ +/* + * GK20A Graphics + * + * Copyright (c) 2011-2020, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "platform_gk20a.h" +#include "sysfs.h" +#include "vgpu/vgpu_linux.h" +#include "scale.h" +#include "pci.h" +#include "module.h" +#include "module_usermode.h" +#include "intr.h" +#include "ioctl.h" +#include "ioctl_ctrl.h" + +#include "os_linux.h" +#include "os_ops.h" +#include "ctxsw_trace.h" +#include "driver_common.h" +#include "channel.h" +#include "debug_pmgr.h" + +#ifdef CONFIG_NVGPU_SUPPORT_CDE +#include "cde.h" +#endif + +#define CLASS_NAME "nvidia-gpu" +/* TODO: Change to e.g. "nvidia-gpu%s" once we have symlinks in place. */ + +#define GK20A_WAIT_FOR_IDLE_MS 2000 + +#define CREATE_TRACE_POINTS +#include + +static int nvgpu_kernel_shutdown_notification(struct notifier_block *nb, + unsigned long event, void *unused) +{ + struct gk20a *g = container_of(nb, struct gk20a, nvgpu_reboot_nb); + + __nvgpu_set_enabled(g, NVGPU_KERNEL_IS_DYING, true); + return NOTIFY_DONE; +} + +struct device_node *nvgpu_get_node(struct gk20a *g) +{ + struct device *dev = dev_from_gk20a(g); + + if (dev_is_pci(dev)) { + struct pci_bus *bus = to_pci_dev(dev)->bus; + + while (!pci_is_root_bus(bus)) + bus = bus->parent; + + return bus->bridge->parent->of_node; + } + + return dev->of_node; +} + +void gk20a_busy_noresume(struct gk20a *g) +{ + pm_runtime_get_noresume(dev_from_gk20a(g)); +} + +/* + * Check if the device can go busy. + */ +static int nvgpu_can_busy(struct gk20a *g) +{ + /* Can't do anything if the system is rebooting/shutting down. */ + if (nvgpu_is_enabled(g, NVGPU_KERNEL_IS_DYING)) + return 0; + + /* Can't do anything if the driver is restarting. */ + if (nvgpu_is_enabled(g, NVGPU_DRIVER_IS_DYING)) + return 0; + + return 1; +} + +int gk20a_busy(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + int ret = 0; + struct device *dev; + + if (!g) + return -ENODEV; + + atomic_inc(&g->usage_count.atomic_var); + + down_read(&l->busy_lock); + + if (!nvgpu_can_busy(g)) { + ret = -ENODEV; + atomic_dec(&g->usage_count.atomic_var); + goto fail; + } + + dev = dev_from_gk20a(g); + + if (pm_runtime_enabled(dev)) { + /* Increment usage count and attempt to resume device */ + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + /* Mark suspended so runtime pm will retry later */ + pm_runtime_set_suspended(dev); + pm_runtime_put_noidle(dev); + atomic_dec(&g->usage_count.atomic_var); + goto fail; + } + } else { + ret = gk20a_gpu_is_virtual(dev) ? + vgpu_pm_finalize_poweron(dev) : + gk20a_pm_finalize_poweron(dev); + if (ret) { + atomic_dec(&g->usage_count.atomic_var); + goto fail; + } + } + +fail: + up_read(&l->busy_lock); + + return ret < 0 ? ret : 0; +} + +void gk20a_idle_nosuspend(struct gk20a *g) +{ + pm_runtime_put_noidle(dev_from_gk20a(g)); +} + +void gk20a_idle(struct gk20a *g) +{ + struct device *dev; + + atomic_dec(&g->usage_count.atomic_var); + + dev = dev_from_gk20a(g); + + if (!(dev && nvgpu_can_busy(g))) + return; + + if (pm_runtime_enabled(dev)) { + pm_runtime_mark_last_busy(dev); + pm_runtime_put_sync_autosuspend(dev); + } +} + +/* + * Undoes gk20a_lockout_registers(). + */ +static int gk20a_restore_registers(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + l->regs = l->regs_saved; + l->bar1 = l->bar1_saved; + + nvgpu_restore_usermode_registers(g); + + return 0; +} + +int nvgpu_finalize_poweron_linux(struct nvgpu_os_linux *l) +{ + struct gk20a *g = &l->g; + int err; + + if (l->init_done) + return 0; + + err = nvgpu_init_channel_support_linux(l); + if (err) { + nvgpu_err(g, "failed to init linux channel support"); + return err; + } + + if (l->ops.clk.init_debugfs) { + err = l->ops.clk.init_debugfs(g); + if (err) { + nvgpu_err(g, "failed to init linux clk debugfs"); + return err; + } + } + + if (l->ops.therm.init_debugfs) { + err = l->ops.therm.init_debugfs(g); + if (err) { + nvgpu_err(g, "failed to init linux therm debugfs"); + return err; + } + } + + if (l->ops.fecs_trace.init_debugfs) { + err = l->ops.fecs_trace.init_debugfs(g); + if (err) { + nvgpu_err(g, "failed to init linux fecs trace debugfs"); + return err; + } + } + + err = nvgpu_pmgr_init_debugfs_linux(l); + if (err) { + nvgpu_err(g, "failed to init linux pmgr debugfs"); + return err; + } + + l->init_done = true; + + return 0; +} + +bool gk20a_check_poweron(struct gk20a *g) +{ + bool ret; + + nvgpu_mutex_acquire(&g->power_lock); + ret = g->power_on; + nvgpu_mutex_release(&g->power_lock); + + return ret; +} + +int gk20a_pm_finalize_poweron(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct gk20a_platform *platform = gk20a_get_platform(dev); + int err = 0; + + nvgpu_log_fn(g, " "); + + nvgpu_mutex_acquire(&g->power_lock); + + if (g->power_on) + goto done; + + trace_gk20a_finalize_poweron(dev_name(dev)); + + /* Increment platform power refcount */ + if (platform->busy) { + err = platform->busy(dev); + if (err < 0) { + nvgpu_err(g, "failed to poweron platform dependency"); + goto done; + } + } + + err = gk20a_restore_registers(g); + if (err) + goto done; + + nvgpu_restore_usermode_for_poweron(g); + + /* Enable interrupt workqueue */ + if (!l->nonstall_work_queue) { + l->nonstall_work_queue = alloc_workqueue("%s", + WQ_HIGHPRI, 1, "mc_nonstall"); + INIT_WORK(&l->nonstall_fn_work, nvgpu_intr_nonstall_cb); + } + + err = nvgpu_detect_chip(g); + if (err) + goto done; + + if (g->sim) { + if (g->sim->sim_init_late) + g->sim->sim_init_late(g); + } + + err = gk20a_finalize_poweron(g); + if (err) + goto done; + + err = nvgpu_init_os_linux_ops(l); + if (err) + goto done; + + err = nvgpu_finalize_poweron_linux(l); + if (err) + goto done; + + nvgpu_init_mm_ce_context(g); + + nvgpu_vidmem_thread_unpause(&g->mm); + + /* Initialise scaling: it will initialize scaling drive only once */ + if (IS_ENABLED(CONFIG_GK20A_DEVFREQ) && + nvgpu_platform_is_silicon(g)) { + gk20a_scale_init(dev); + if (platform->initscale) + platform->initscale(dev); + } + + trace_gk20a_finalize_poweron_done(dev_name(dev)); + + enable_irq(g->irq_stall); + if (g->irq_stall != g->irq_nonstall) + enable_irq(g->irq_nonstall); + g->irqs_enabled = 1; + + gk20a_scale_resume(dev_from_gk20a(g)); + +#ifdef CONFIG_NVGPU_SUPPORT_CDE + if (platform->has_cde) + gk20a_init_cde_support(l); +#endif + + err = gk20a_sched_ctrl_init(g); + if (err) { + nvgpu_err(g, "failed to init sched control"); + goto done; + } + + g->sw_ready = true; + +done: + if (err) + g->power_on = false; + + nvgpu_mutex_release(&g->power_lock); + return err; +} + +/* + * Locks out the driver from accessing GPU registers. This prevents access to + * thse registers after the GPU has been clock or power gated. This should help + * find annoying bugs where register reads and writes are silently dropped + * after the GPU has been turned off. On older chips these reads and writes can + * also lock the entire CPU up. + */ +static int gk20a_lockout_registers(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + l->regs = NULL; + l->bar1 = NULL; + + nvgpu_lockout_usermode_registers(g); + + return 0; +} + +static int gk20a_pm_prepare_poweroff(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); +#ifdef CONFIG_NVGPU_SUPPORT_CDE + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); +#endif + struct gk20a_platform *platform = gk20a_get_platform(dev); + bool irqs_enabled; + int ret = 0; + + nvgpu_log_fn(g, " "); + + nvgpu_mutex_acquire(&g->power_lock); + + if (!g->power_on) + goto done; + + /* disable IRQs and wait for completion */ + irqs_enabled = g->irqs_enabled; + if (irqs_enabled) { + disable_irq(g->irq_stall); + if (g->irq_stall != g->irq_nonstall) + disable_irq(g->irq_nonstall); + g->irqs_enabled = 0; + } + + gk20a_scale_suspend(dev); + +#ifdef CONFIG_NVGPU_SUPPORT_CDE + gk20a_cde_suspend(l); +#endif + + ret = gk20a_prepare_poweroff(g); + if (ret) + goto error; + + /* Decrement platform power refcount */ + if (platform->idle) + platform->idle(dev); + + /* Stop CPU from accessing the GPU registers. */ + gk20a_lockout_registers(g); + + nvgpu_hide_usermode_for_poweroff(g); + nvgpu_mutex_release(&g->power_lock); + return 0; + +error: + /* re-enabled IRQs if previously enabled */ + if (irqs_enabled) { + enable_irq(g->irq_stall); + if (g->irq_stall != g->irq_nonstall) + enable_irq(g->irq_nonstall); + g->irqs_enabled = 1; + } + + gk20a_scale_resume(dev); +done: + nvgpu_mutex_release(&g->power_lock); + + return ret; +} + +static struct of_device_id tegra_gk20a_of_match[] = { +#ifdef CONFIG_TEGRA_GK20A + { .compatible = "nvidia,tegra210-gm20b", + .data = &gm20b_tegra_platform }, + { .compatible = "nvidia,tegra186-gp10b", + .data = &gp10b_tegra_platform }, + { .compatible = "nvidia,gv11b", + .data = &gv11b_tegra_platform }, +#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION + { .compatible = "nvidia,gv11b-vgpu", + .data = &gv11b_vgpu_tegra_platform}, +#endif +#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION + { .compatible = "nvidia,tegra124-gk20a-vgpu", + .data = &vgpu_tegra_platform }, +#endif +#endif + + { }, +}; +MODULE_DEVICE_TABLE(of, tegra_gk20a_of_match); + +#ifdef CONFIG_PM +/** + * __gk20a_do_idle() - force the GPU to idle and railgate + * + * In success, this call MUST be balanced by caller with __gk20a_do_unidle() + * + * Acquires two locks : &l->busy_lock and &platform->railgate_lock + * In success, we hold these locks and return + * In failure, we release these locks and return + */ +int __gk20a_do_idle(struct gk20a *g, bool force_reset) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct nvgpu_timeout timeout; + int ref_cnt; + int target_ref_cnt = 0; + bool is_railgated; + int err = 0; + + /* + * Hold back deterministic submits and changes to deterministic + * channels - this must be outside the power busy locks. + */ + gk20a_channel_deterministic_idle(g); + + /* acquire busy lock to block other busy() calls */ + down_write(&l->busy_lock); + + /* acquire railgate lock to prevent unrailgate in midst of do_idle() */ + nvgpu_mutex_acquire(&platform->railgate_lock); + + /* check if it is already railgated ? */ + if (platform->is_railgated(dev)) + return 0; + + /* + * release railgate_lock, prevent suspend by incrementing usage counter, + * re-acquire railgate_lock + */ + nvgpu_mutex_release(&platform->railgate_lock); + pm_runtime_get_sync(dev); + + /* + * One refcount taken in this API + * If User disables rail gating, we take one more + * extra refcount + */ + if (nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE)) + target_ref_cnt = 1; + else + target_ref_cnt = 2; + nvgpu_mutex_acquire(&platform->railgate_lock); + + nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS, + NVGPU_TIMER_CPU_TIMER); + + /* check and wait until GPU is idle (with a timeout) */ + do { + nvgpu_usleep_range(1000, 1100); + ref_cnt = atomic_read(&dev->power.usage_count); + } while (ref_cnt != target_ref_cnt && !nvgpu_timeout_expired(&timeout)); + + if (ref_cnt != target_ref_cnt) { + nvgpu_err(g, "failed to idle - refcount %d != target_ref_cnt", + ref_cnt); + goto fail_drop_usage_count; + } + + /* check if global force_reset flag is set */ + force_reset |= platform->force_reset_in_do_idle; + + nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS, + NVGPU_TIMER_CPU_TIMER); + + if (nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE) && !force_reset) { + /* + * Case 1 : GPU railgate is supported + * + * if GPU is now idle, we will have only one ref count, + * drop this ref which will rail gate the GPU + */ + pm_runtime_put_sync(dev); + + /* add sufficient delay to allow GPU to rail gate */ + nvgpu_msleep(g->railgate_delay); + + /* check in loop if GPU is railgated or not */ + do { + nvgpu_usleep_range(1000, 1100); + is_railgated = platform->is_railgated(dev); + } while (!is_railgated && !nvgpu_timeout_expired(&timeout)); + + if (is_railgated) { + return 0; + } else { + nvgpu_err(g, "failed to idle in timeout"); + goto fail_timeout; + } + } else { + /* + * Case 2 : GPU railgate is not supported or we explicitly + * do not want to depend on runtime PM + * + * if GPU is now idle, call prepare_poweroff() to save the + * state and then do explicit railgate + * + * __gk20a_do_unidle() needs to unrailgate, call + * finalize_poweron(), and then call pm_runtime_put_sync() + * to balance the GPU usage counter + */ + + /* Save the GPU state */ + err = gk20a_pm_prepare_poweroff(dev); + if (err) + goto fail_drop_usage_count; + + /* railgate GPU */ + platform->railgate(dev); + + nvgpu_udelay(10); + + g->forced_reset = true; + return 0; + } + +fail_drop_usage_count: + pm_runtime_put_noidle(dev); +fail_timeout: + nvgpu_mutex_release(&platform->railgate_lock); + up_write(&l->busy_lock); + gk20a_channel_deterministic_unidle(g); + return -EBUSY; +} + +/** + * gk20a_do_idle() - wrap up for __gk20a_do_idle() to be called + * from outside of GPU driver + * + * In success, this call MUST be balanced by caller with gk20a_do_unidle() + */ +static int gk20a_do_idle(void *_g) +{ + struct gk20a *g = (struct gk20a *)_g; + + return __gk20a_do_idle(g, true); +} + +/** + * __gk20a_do_unidle() - unblock all the tasks blocked by __gk20a_do_idle() + */ +int __gk20a_do_unidle(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = dev_get_drvdata(dev); + int err; + + if (g->forced_reset) { + /* + * If we did a forced-reset/railgate + * then unrailgate the GPU here first + */ + platform->unrailgate(dev); + + /* restore the GPU state */ + err = gk20a_pm_finalize_poweron(dev); + if (err) + return err; + + /* balance GPU usage counter */ + pm_runtime_put_sync(dev); + + g->forced_reset = false; + } + + /* release the lock and open up all other busy() calls */ + nvgpu_mutex_release(&platform->railgate_lock); + up_write(&l->busy_lock); + + gk20a_channel_deterministic_unidle(g); + + return 0; +} + +/** + * gk20a_do_unidle() - wrap up for __gk20a_do_unidle() + */ +static int gk20a_do_unidle(void *_g) +{ + struct gk20a *g = (struct gk20a *)_g; + + return __gk20a_do_unidle(g); +} +#endif + +void __iomem *nvgpu_devm_ioremap_resource(struct platform_device *dev, int i, + struct resource **out) +{ + struct resource *r = platform_get_resource(dev, IORESOURCE_MEM, i); + + if (!r) + return NULL; + if (out) + *out = r; + return devm_ioremap_resource(&dev->dev, r); +} + +void __iomem *nvgpu_devm_ioremap(struct device *dev, resource_size_t offset, + resource_size_t size) +{ + return devm_ioremap(dev, offset, size); +} + +u64 nvgpu_resource_addr(struct platform_device *dev, int i) +{ + struct resource *r = platform_get_resource(dev, IORESOURCE_MEM, i); + + if (!r) + return 0; + + return r->start; +} + +static irqreturn_t gk20a_intr_isr_stall(int irq, void *dev_id) +{ + struct gk20a *g = dev_id; + + return nvgpu_intr_stall(g); +} + +static irqreturn_t gk20a_intr_isr_nonstall(int irq, void *dev_id) +{ + struct gk20a *g = dev_id; + + return nvgpu_intr_nonstall(g); +} + +static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id) +{ + struct gk20a *g = dev_id; + + return nvgpu_intr_thread_stall(g); +} + +void gk20a_remove_support(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct sim_nvgpu_linux *sim_linux; + + tegra_unregister_idle_unidle(gk20a_do_idle); + + nvgpu_kfree(g, g->dbg_regops_tmp_buf); + + nvgpu_remove_channel_support_linux(l); + + if (g->pmu.remove_support) + g->pmu.remove_support(&g->pmu); + + if (g->acr.remove_support != NULL) { + g->acr.remove_support(&g->acr); + } + + if (g->gr.remove_support) + g->gr.remove_support(&g->gr); + + if (g->mm.remove_ce_support) + g->mm.remove_ce_support(&g->mm); + + if (g->fifo.remove_support) + g->fifo.remove_support(&g->fifo); + + if (g->mm.remove_support) + g->mm.remove_support(&g->mm); + + if (g->sim) { + sim_linux = container_of(g->sim, struct sim_nvgpu_linux, sim); + if (g->sim->remove_support) + g->sim->remove_support(g); + if (sim_linux->remove_support_linux) + sim_linux->remove_support_linux(g); + } + + nvgpu_remove_usermode_support(g); + + nvgpu_free_enabled_flags(g); + + gk20a_lockout_registers(g); +} + +static int gk20a_init_support(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct gk20a *g = get_gk20a(dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + int err = -ENOMEM; + + tegra_register_idle_unidle(gk20a_do_idle, gk20a_do_unidle, g); + + l->regs = nvgpu_devm_ioremap_resource(pdev, + GK20A_BAR0_IORESOURCE_MEM, + &l->reg_mem); + if (IS_ERR(l->regs)) { + nvgpu_err(g, "failed to remap gk20a registers"); + err = PTR_ERR(l->regs); + goto fail; + } + + l->regs_bus_addr = nvgpu_resource_addr(pdev, + GK20A_BAR0_IORESOURCE_MEM); + if (!l->regs_bus_addr) { + nvgpu_err(g, "failed to read register bus offset"); + err = -ENODEV; + goto fail; + } + + l->bar1 = nvgpu_devm_ioremap_resource(pdev, + GK20A_BAR1_IORESOURCE_MEM, + &l->bar1_mem); + if (IS_ERR(l->bar1)) { + nvgpu_err(g, "failed to remap gk20a bar1"); + err = PTR_ERR(l->bar1); + goto fail; + } + + err = nvgpu_init_sim_support_linux(g, pdev); + if (err) + goto fail; + err = nvgpu_init_sim_support(g); + if (err) + goto fail_sim; + + nvgpu_init_usermode_support(g); + return 0; + +fail_sim: + nvgpu_remove_sim_support_linux(g); +fail: + if (l->regs) + l->regs = NULL; + + if (l->bar1) + l->bar1 = NULL; + + return err; +} + +static int gk20a_pm_railgate(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + int ret = 0; + struct gk20a *g = get_gk20a(dev); + + /* return early if platform didn't implement railgate */ + if (!platform->railgate) + return 0; + + /* if platform is already railgated, then just return */ + if (platform->is_railgated && platform->is_railgated(dev)) + return ret; + +#ifdef CONFIG_DEBUG_FS + g->pstats.last_rail_gate_start = jiffies; + + if (g->pstats.railgating_cycle_count >= 1) + g->pstats.total_rail_ungate_time_ms = + g->pstats.total_rail_ungate_time_ms + + jiffies_to_msecs(g->pstats.last_rail_gate_start - + g->pstats.last_rail_ungate_complete); +#endif + + ret = platform->railgate(dev); + if (ret) { + nvgpu_err(g, "failed to railgate platform, err=%d", ret); + return ret; + } + +#ifdef CONFIG_DEBUG_FS + g->pstats.last_rail_gate_complete = jiffies; +#endif + ret = tegra_fuse_clock_disable(); + if (ret) + nvgpu_err(g, "failed to disable tegra fuse clock, err=%d", ret); + + return ret; +} + +static int gk20a_pm_unrailgate(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + int ret = 0; + struct gk20a *g = get_gk20a(dev); + + /* return early if platform didn't implement unrailgate */ + if (!platform->unrailgate) + return 0; + + ret = tegra_fuse_clock_enable(); + if (ret) { + nvgpu_err(g, "failed to enable tegra fuse clock, err=%d", ret); + return ret; + } +#ifdef CONFIG_DEBUG_FS + g->pstats.last_rail_ungate_start = jiffies; + if (g->pstats.railgating_cycle_count >= 1) + g->pstats.total_rail_gate_time_ms = + g->pstats.total_rail_gate_time_ms + + jiffies_to_msecs(g->pstats.last_rail_ungate_start - + g->pstats.last_rail_gate_complete); + + g->pstats.railgating_cycle_count++; +#endif + + trace_gk20a_pm_unrailgate(dev_name(dev)); + + nvgpu_mutex_acquire(&platform->railgate_lock); + ret = platform->unrailgate(dev); + nvgpu_mutex_release(&platform->railgate_lock); + +#ifdef CONFIG_DEBUG_FS + g->pstats.last_rail_ungate_complete = jiffies; +#endif + + return ret; +} + +/* + * Remove association of the driver with OS interrupt handler + */ +void nvgpu_free_irq(struct gk20a *g) +{ + struct device *dev = dev_from_gk20a(g); + + devm_free_irq(dev, g->irq_stall, g); + if (g->irq_stall != g->irq_nonstall) + devm_free_irq(dev, g->irq_nonstall, g); +} + +/* + * Idle the GPU in preparation of shutdown/remove. + * gk20a_driver_start_unload() does not idle the GPU, but instead changes the SW + * state to prevent further activity on the driver SW side. + * On driver removal quiesce() should be called after start_unload() + */ +int nvgpu_quiesce(struct gk20a *g) +{ + int err; + struct device *dev = dev_from_gk20a(g); + + if (g->power_on) { + err = gk20a_wait_for_idle(g); + if (err) { + nvgpu_err(g, "failed to idle GPU, err=%d", err); + return err; + } + + err = gk20a_fifo_disable_all_engine_activity(g, true); + if (err) { + nvgpu_err(g, + "failed to disable engine activity, err=%d", + err); + return err; + } + + err = gk20a_fifo_wait_engine_idle(g); + if (err) { + nvgpu_err(g, "failed to idle engines, err=%d", + err); + return err; + } + } + + if (gk20a_gpu_is_virtual(dev)) + err = vgpu_pm_prepare_poweroff(dev); + else + err = gk20a_pm_prepare_poweroff(dev); + + if (err) + nvgpu_err(g, "failed to prepare for poweroff, err=%d", + err); + + return err; +} + +static void gk20a_pm_shutdown(struct platform_device *pdev) +{ + struct gk20a_platform *platform = platform_get_drvdata(pdev); + struct gk20a *g = platform->g; + int err; + + nvgpu_info(g, "shutting down"); + + /* vgpu has nothing to clean up currently */ + if (gk20a_gpu_is_virtual(&pdev->dev)) + return; + + if (!g->power_on) + goto finish; + + gk20a_driver_start_unload(g); + + /* If GPU is already railgated, + * just prevent more requests, and return */ + if (platform->is_railgated && platform->is_railgated(&pdev->dev)) { + __pm_runtime_disable(&pdev->dev, false); + nvgpu_info(g, "already railgated, shut down complete"); + return; + } + + /* Prevent more requests by disabling Runtime PM */ + __pm_runtime_disable(&pdev->dev, false); + + err = nvgpu_quiesce(g); + if (err) + goto finish; + + err = gk20a_pm_railgate(&pdev->dev); + if (err) + nvgpu_err(g, "failed to railgate, err=%d", err); + +finish: + nvgpu_info(g, "shut down complete"); +} + +#ifdef CONFIG_PM +static int gk20a_pm_runtime_resume(struct device *dev) +{ + int err = 0; + + err = gk20a_pm_unrailgate(dev); + if (err) + goto fail; + + if (gk20a_gpu_is_virtual(dev)) + err = vgpu_pm_finalize_poweron(dev); + else + err = gk20a_pm_finalize_poweron(dev); + if (err) + goto fail_poweron; + + return 0; + +fail_poweron: + gk20a_pm_railgate(dev); +fail: + return err; +} + +static int gk20a_pm_runtime_suspend(struct device *dev) +{ + int err = 0; + struct gk20a *g = get_gk20a(dev); + + if (!g) + return 0; + + if (gk20a_gpu_is_virtual(dev)) + err = vgpu_pm_prepare_poweroff(dev); + else + err = gk20a_pm_prepare_poweroff(dev); + if (err) { + nvgpu_err(g, "failed to power off, err=%d", err); + goto fail; + } + + err = gk20a_pm_railgate(dev); + if (err) + goto fail; + + return 0; + +fail: + gk20a_pm_finalize_poweron(dev); + pm_runtime_mark_last_busy(dev); + return err; +} + +static int gk20a_pm_suspend(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct gk20a *g = get_gk20a(dev); + int ret = 0; + int usage_count; + struct nvgpu_timeout timeout; + + if (!g->power_on) { + if (platform->suspend) + ret = platform->suspend(dev); + + if (ret) + return ret; + + if (!pm_runtime_enabled(dev)) + ret = gk20a_pm_railgate(dev); + + return ret; + } + + nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS, + NVGPU_TIMER_CPU_TIMER); + /* + * Hold back deterministic submits and changes to deterministic + * channels - this must be outside the power busy locks. + */ + gk20a_channel_deterministic_idle(g); + + /* check and wait until GPU is idle (with a timeout) */ + do { + nvgpu_usleep_range(1000, 1100); + usage_count = nvgpu_atomic_read(&g->usage_count); + } while (usage_count != 0 && !nvgpu_timeout_expired(&timeout)); + + if (usage_count != 0) { + nvgpu_err(g, "failed to idle - usage_count %d", usage_count); + ret = -EINVAL; + goto fail_idle; + } + + ret = gk20a_pm_runtime_suspend(dev); + if (ret) + goto fail_idle; + + if (platform->suspend) + ret = platform->suspend(dev); + if (ret) + goto fail_suspend; + + g->suspended = true; + + return 0; + +fail_suspend: + gk20a_pm_runtime_resume(dev); +fail_idle: + gk20a_channel_deterministic_unidle(g); + return ret; +} + +static int gk20a_pm_resume(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct gk20a *g = get_gk20a(dev); + int ret = 0; + + if (!g->suspended) { + if (platform->resume) + ret = platform->resume(dev); + if (ret) + return ret; + + if (!pm_runtime_enabled(dev)) + ret = gk20a_pm_unrailgate(dev); + + return ret; + } + + if (platform->resume) + ret = platform->resume(dev); + if (ret) + return ret; + + ret = gk20a_pm_runtime_resume(dev); + if (ret) + return ret; + + g->suspended = false; + + gk20a_channel_deterministic_unidle(g); + + return ret; +} + +static const struct dev_pm_ops gk20a_pm_ops = { + .runtime_resume = gk20a_pm_runtime_resume, + .runtime_suspend = gk20a_pm_runtime_suspend, + .resume = gk20a_pm_resume, + .suspend = gk20a_pm_suspend, +}; +#endif + +static int gk20a_pm_init(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + int err = 0; + + nvgpu_log_fn(g, " "); + + /* + * Initialise pm runtime. For railgate disable + * case, set autosuspend delay to negative which + * will suspend runtime pm + */ + if (g->railgate_delay && nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE)) + pm_runtime_set_autosuspend_delay(dev, + g->railgate_delay); + else + pm_runtime_set_autosuspend_delay(dev, -1); + + pm_runtime_use_autosuspend(dev); + pm_runtime_enable(dev); + + return err; +} + +static int gk20a_pm_deinit(struct device *dev) +{ + pm_runtime_dont_use_autosuspend(dev); + pm_runtime_disable(dev); + return 0; +} + +/* + * Start the process for unloading the driver. Set NVGPU_DRIVER_IS_DYING. + */ +void gk20a_driver_start_unload(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + nvgpu_log(g, gpu_dbg_shutdown, "Driver is now going down!\n"); + + down_write(&l->busy_lock); + __nvgpu_set_enabled(g, NVGPU_DRIVER_IS_DYING, true); + /* GR SW ready needs to be invalidated at this time with the busy lock + * held to prevent a racing condition on the gr/mm code */ + g->gr.sw_ready = false; + g->sw_ready = false; + up_write(&l->busy_lock); + + if (g->is_virtual) + return; + + gk20a_wait_for_idle(g); + + nvgpu_wait_for_deferred_interrupts(g); + + if (l->nonstall_work_queue) { + cancel_work_sync(&l->nonstall_fn_work); + destroy_workqueue(l->nonstall_work_queue); + l->nonstall_work_queue = NULL; + } +} + +static inline void set_gk20a(struct platform_device *pdev, struct gk20a *gk20a) +{ + gk20a_get_platform(&pdev->dev)->g = gk20a; +} + +static int nvgpu_read_fuse_overrides(struct gk20a *g) +{ + struct device_node *np = nvgpu_get_node(g); + struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); + u32 *fuses; + int count, i; + + if (!np) /* may be pcie device */ + return 0; + + count = of_property_count_elems_of_size(np, "fuse-overrides", 8); + if (count <= 0) + return count; + + fuses = nvgpu_kmalloc(g, sizeof(u32) * count * 2); + if (!fuses) + return -ENOMEM; + of_property_read_u32_array(np, "fuse-overrides", fuses, count * 2); + for (i = 0; i < count; i++) { + u32 fuse, value; + + fuse = fuses[2 * i]; + value = fuses[2 * i + 1]; + switch (fuse) { + case GM20B_FUSE_OPT_TPC_DISABLE: + g->tpc_fs_mask_user = ~value; + break; + case GP10B_FUSE_OPT_ECC_EN: + g->gr.fecs_feature_override_ecc_val = value; + break; + case GV11B_FUSE_OPT_TPC_DISABLE: + if (platform->set_tpc_pg_mask != NULL) + platform->set_tpc_pg_mask(dev_from_gk20a(g), + value); + break; + default: + nvgpu_err(g, "ignore unknown fuse override %08x", fuse); + break; + } + } + + nvgpu_kfree(g, fuses); + + return 0; +} + +static int gk20a_probe(struct platform_device *dev) +{ + struct nvgpu_os_linux *l = NULL; + struct gk20a *gk20a; + int err; + struct gk20a_platform *platform = NULL; + struct device_node *np; + + if (dev->dev.of_node) { + const struct of_device_id *match; + + match = of_match_device(tegra_gk20a_of_match, &dev->dev); + if (match) + platform = (struct gk20a_platform *)match->data; + } else + platform = (struct gk20a_platform *)dev->dev.platform_data; + + if (!platform) { + dev_err(&dev->dev, "no platform data\n"); + return -ENODATA; + } + + platform_set_drvdata(dev, platform); + + if (gk20a_gpu_is_virtual(&dev->dev)) + return vgpu_probe(dev); + + l = kzalloc(sizeof(*l), GFP_KERNEL); + if (!l) { + dev_err(&dev->dev, "couldn't allocate gk20a support"); + return -ENOMEM; + } + + hash_init(l->ecc_sysfs_stats_htable); + + gk20a = &l->g; + + nvgpu_log_fn(gk20a, " "); + + nvgpu_init_gk20a(gk20a); + set_gk20a(dev, gk20a); + l->dev = &dev->dev; + gk20a->log_mask = NVGPU_DEFAULT_DBG_MASK; + + nvgpu_kmem_init(gk20a); + + err = nvgpu_init_enabled_flags(gk20a); + if (err) + goto return_err; + + np = nvgpu_get_node(gk20a); + if (of_dma_is_coherent(np)) { + __nvgpu_set_enabled(gk20a, NVGPU_USE_COHERENT_SYSMEM, true); + __nvgpu_set_enabled(gk20a, NVGPU_SUPPORT_IO_COHERENCE, true); + } + + if (nvgpu_platform_is_simulation(gk20a)) + __nvgpu_set_enabled(gk20a, NVGPU_IS_FMODEL, true); + + gk20a->irq_stall = platform_get_irq(dev, 0); + gk20a->irq_nonstall = platform_get_irq(dev, 1); + if (gk20a->irq_stall < 0 || gk20a->irq_nonstall < 0) { + err = -ENXIO; + goto return_err; + } + + err = devm_request_threaded_irq(&dev->dev, + gk20a->irq_stall, + gk20a_intr_isr_stall, + gk20a_intr_thread_stall, + 0, "gk20a_stall", gk20a); + if (err) { + dev_err(&dev->dev, + "failed to request stall intr irq @ %d\n", + gk20a->irq_stall); + goto return_err; + } + err = devm_request_irq(&dev->dev, + gk20a->irq_nonstall, + gk20a_intr_isr_nonstall, + 0, "gk20a_nonstall", gk20a); + if (err) { + dev_err(&dev->dev, + "failed to request non-stall intr irq @ %d\n", + gk20a->irq_nonstall); + goto return_err; + } + disable_irq(gk20a->irq_stall); + if (gk20a->irq_stall != gk20a->irq_nonstall) + disable_irq(gk20a->irq_nonstall); + + err = gk20a_init_support(dev); + if (err) + goto return_err; + + err = nvgpu_read_fuse_overrides(gk20a); + +#ifdef CONFIG_RESET_CONTROLLER + platform->reset_control = devm_reset_control_get(&dev->dev, NULL); + if (IS_ERR(platform->reset_control)) + platform->reset_control = NULL; +#endif + + err = nvgpu_probe(gk20a, "gpu.0", INTERFACE_NAME, &nvgpu_class); + if (err) + goto return_err; + + err = gk20a_pm_init(&dev->dev); + if (err) { + dev_err(&dev->dev, "pm init failed"); + goto return_err; + } + + gk20a->nvgpu_reboot_nb.notifier_call = + nvgpu_kernel_shutdown_notification; + err = register_reboot_notifier(&gk20a->nvgpu_reboot_nb); + if (err) + goto return_err; + + return 0; + +return_err: + nvgpu_free_enabled_flags(gk20a); + + /* + * Last since the above allocs may use data structures in here. + */ + nvgpu_kmem_fini(gk20a, NVGPU_KMEM_FINI_FORCE_CLEANUP); + + kfree(l); + + return err; +} + +int nvgpu_remove(struct device *dev, struct class *class) +{ + struct gk20a *g = get_gk20a(dev); +#ifdef CONFIG_NVGPU_SUPPORT_CDE + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); +#endif + struct gk20a_platform *platform = gk20a_get_platform(dev); + int err; + + nvgpu_log_fn(g, " "); + + err = nvgpu_quiesce(g); + WARN(err, "gpu failed to idle during driver removal"); + + if (nvgpu_mem_is_valid(&g->syncpt_mem)) + nvgpu_dma_free(g, &g->syncpt_mem); + +#ifdef CONFIG_NVGPU_SUPPORT_CDE + if (platform->has_cde) + gk20a_cde_destroy(l); +#endif + +#ifdef CONFIG_GK20A_CTXSW_TRACE + gk20a_ctxsw_trace_cleanup(g); +#endif + + gk20a_sched_ctrl_cleanup(g); + + if (IS_ENABLED(CONFIG_GK20A_DEVFREQ)) + gk20a_scale_exit(dev); + + nvgpu_clk_arb_cleanup_arbiter(g); + + gk20a_user_deinit(dev, class); + + gk20a_debug_deinit(g); + + nvgpu_remove_sysfs(dev); + + if (platform->secure_buffer.destroy) + platform->secure_buffer.destroy(g, + &platform->secure_buffer); + + if (platform->remove) + platform->remove(dev); + + nvgpu_mutex_destroy(&g->clk_arb_enable_lock); + + nvgpu_log_fn(g, "removed"); + + return err; +} + +static int __exit gk20a_remove(struct platform_device *pdev) +{ + int err; + struct device *dev = &pdev->dev; + struct gk20a *g = get_gk20a(dev); + + if (gk20a_gpu_is_virtual(dev)) + return vgpu_remove(pdev); + + err = nvgpu_remove(dev, &nvgpu_class); + + unregister_reboot_notifier(&g->nvgpu_reboot_nb); + + set_gk20a(pdev, NULL); + + gk20a_put(g); + + gk20a_pm_deinit(dev); + + return err; +} + +static struct platform_driver gk20a_driver = { + .probe = gk20a_probe, + .remove = __exit_p(gk20a_remove), + .shutdown = gk20a_pm_shutdown, + .driver = { + .owner = THIS_MODULE, + .name = "gk20a", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, +#ifdef CONFIG_OF + .of_match_table = tegra_gk20a_of_match, +#endif +#ifdef CONFIG_PM + .pm = &gk20a_pm_ops, +#endif + .suppress_bind_attrs = true, + } +}; + +struct class nvgpu_class = { + .owner = THIS_MODULE, + .name = CLASS_NAME, +}; + +static int __init gk20a_init(void) +{ + + int ret; + + ret = class_register(&nvgpu_class); + if (ret) + return ret; + + ret = nvgpu_pci_init(); + if (ret) + return ret; + + return platform_driver_register(&gk20a_driver); +} + +static void __exit gk20a_exit(void) +{ + nvgpu_pci_exit(); + platform_driver_unregister(&gk20a_driver); + class_unregister(&nvgpu_class); +} + +MODULE_LICENSE("GPL v2"); +module_init(gk20a_init); +module_exit(gk20a_exit); diff --git a/include/os/linux/module.h b/include/os/linux/module.h new file mode 100644 index 0000000..76c7274 --- /dev/null +++ b/include/os/linux/module.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#ifndef __NVGPU_COMMON_LINUX_MODULE_H__ +#define __NVGPU_COMMON_LINUX_MODULE_H__ + +struct gk20a; +struct device; +struct nvgpu_os_linux; + +int gk20a_pm_finalize_poweron(struct device *dev); +int nvgpu_finalize_poweron_linux(struct nvgpu_os_linux *l); +void gk20a_remove_support(struct gk20a *g); +void gk20a_driver_start_unload(struct gk20a *g); +int nvgpu_quiesce(struct gk20a *g); +int nvgpu_remove(struct device *dev, struct class *class); +void nvgpu_free_irq(struct gk20a *g); +struct device_node *nvgpu_get_node(struct gk20a *g); +void __iomem *nvgpu_devm_ioremap_resource(struct platform_device *dev, int i, + struct resource **out); +void __iomem *nvgpu_devm_ioremap(struct device *dev, resource_size_t offset, + resource_size_t size); +u64 nvgpu_resource_addr(struct platform_device *dev, int i); +extern struct class nvgpu_class; + +#endif diff --git a/include/os/linux/module_usermode.c b/include/os/linux/module_usermode.c new file mode 100644 index 0000000..ea01c1b --- /dev/null +++ b/include/os/linux/module_usermode.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include + +#include "os_linux.h" + +/* + * Locks out the driver from accessing GPU registers. This prevents access to + * thse registers after the GPU has been clock or power gated. This should help + * find annoying bugs where register reads and writes are silently dropped + * after the GPU has been turned off. On older chips these reads and writes can + * also lock the entire CPU up. + */ +void nvgpu_lockout_usermode_registers(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + l->usermode_regs = NULL; +} + +/* + * Undoes t19x_lockout_registers(). + */ +void nvgpu_restore_usermode_registers(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + l->usermode_regs = l->usermode_regs_saved; +} + +void nvgpu_remove_usermode_support(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (l->usermode_regs) { + l->usermode_regs = NULL; + } +} + +void nvgpu_init_usermode_support(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + l->usermode_regs = l->regs + usermode_cfg0_r(); + l->usermode_regs_saved = l->usermode_regs; +} diff --git a/include/os/linux/module_usermode.h b/include/os/linux/module_usermode.h new file mode 100644 index 0000000..b17053c --- /dev/null +++ b/include/os/linux/module_usermode.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NVGPU_MODULE_T19X_H__ +#define __NVGPU_MODULE_T19X_H__ + +struct gk20a; + +void nvgpu_init_usermode_support(struct gk20a *g); +void nvgpu_remove_usermode_support(struct gk20a *g); +void nvgpu_lockout_usermode_registers(struct gk20a *g); +void nvgpu_restore_usermode_registers(struct gk20a *g); + +#endif diff --git a/include/os/linux/nvgpu_mem.c b/include/os/linux/nvgpu_mem.c new file mode 100644 index 0000000..d6a3189 --- /dev/null +++ b/include/os/linux/nvgpu_mem.c @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "os_linux.h" +#include "dmabuf_vidmem.h" + +#include "gk20a/mm_gk20a.h" +#include "platform_gk20a.h" + +static u64 __nvgpu_sgl_phys(struct gk20a *g, struct nvgpu_sgl *sgl) +{ + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = gk20a_get_platform(dev); + u64 ipa = sg_phys((struct scatterlist *)sgl); + + if (platform->phys_addr) + return platform->phys_addr(g, ipa); + + return ipa; +} + +/* + * Obtain a SYSMEM address from a Linux SGL. This should eventually go away + * and/or become private to this file once all bad usages of Linux SGLs are + * cleaned up in the driver. + */ +u64 nvgpu_mem_get_addr_sgl(struct gk20a *g, struct scatterlist *sgl) +{ + if (nvgpu_is_enabled(g, NVGPU_MM_USE_PHYSICAL_SG) || + !nvgpu_iommuable(g)) + return g->ops.mm.gpu_phys_addr(g, NULL, + __nvgpu_sgl_phys(g, (struct nvgpu_sgl *)sgl)); + + if (sg_dma_address(sgl) == 0) + return g->ops.mm.gpu_phys_addr(g, NULL, + __nvgpu_sgl_phys(g, (struct nvgpu_sgl *)sgl)); + + if (sg_dma_address(sgl) == DMA_ERROR_CODE) + return 0; + + return nvgpu_mem_iommu_translate(g, sg_dma_address(sgl)); +} + +/* + * Obtain the address the GPU should use from the %mem assuming this is a SYSMEM + * allocation. + */ +static u64 nvgpu_mem_get_addr_sysmem(struct gk20a *g, struct nvgpu_mem *mem) +{ + return nvgpu_mem_get_addr_sgl(g, mem->priv.sgt->sgl); +} + +/* + * Return the base address of %mem. Handles whether this is a VIDMEM or SYSMEM + * allocation. + * + * Note: this API does not make sense to use for _VIDMEM_ buffers with greater + * than one scatterlist chunk. If there's more than one scatterlist chunk then + * the buffer will not be contiguous. As such the base address probably isn't + * very useful. This is true for SYSMEM as well, if there's no IOMMU. + * + * However! It _is_ OK to use this on discontiguous sysmem buffers _if_ there's + * an IOMMU present and enabled for the GPU. + * + * %attrs can be NULL. If it is not NULL then it may be inspected to determine + * if the address needs to be modified before writing into a PTE. + */ +u64 nvgpu_mem_get_addr(struct gk20a *g, struct nvgpu_mem *mem) +{ + struct nvgpu_page_alloc *alloc; + + if (mem->aperture == APERTURE_SYSMEM) + return nvgpu_mem_get_addr_sysmem(g, mem); + + /* + * Otherwise get the vidmem address. + */ + alloc = mem->vidmem_alloc; + + /* This API should not be used with > 1 chunks */ + WARN_ON(alloc->nr_chunks != 1); + + return alloc->base; +} + +/* + * This should only be used on contiguous buffers regardless of whether + * there's an IOMMU present/enabled. This applies to both SYSMEM and + * VIDMEM. + */ +u64 nvgpu_mem_get_phys_addr(struct gk20a *g, struct nvgpu_mem *mem) +{ + /* + * For a VIDMEM buf, this is identical to simply get_addr() so just fall + * back to that. + */ + if (mem->aperture == APERTURE_VIDMEM) + return nvgpu_mem_get_addr(g, mem); + + return __nvgpu_sgl_phys(g, (struct nvgpu_sgl *)mem->priv.sgt->sgl); +} + +/* + * Be careful how you use this! You are responsible for correctly freeing this + * memory. + */ +int nvgpu_mem_create_from_mem(struct gk20a *g, + struct nvgpu_mem *dest, struct nvgpu_mem *src, + u64 start_page, int nr_pages) +{ + int ret; + u64 start = start_page * PAGE_SIZE; + u64 size = nr_pages * PAGE_SIZE; + dma_addr_t new_iova; + + if (src->aperture != APERTURE_SYSMEM) + return -EINVAL; + + /* Some silly things a caller might do... */ + if (size > src->size) + return -EINVAL; + if ((start + size) > src->size) + return -EINVAL; + + dest->mem_flags = src->mem_flags | NVGPU_MEM_FLAG_SHADOW_COPY; + dest->aperture = src->aperture; + dest->skip_wmb = src->skip_wmb; + dest->size = size; + + /* + * Re-use the CPU mapping only if the mapping was made by the DMA API. + * + * Bug 2040115: the DMA API wrapper makes the mapping that we should + * re-use. + */ + if (!(src->priv.flags & NVGPU_DMA_NO_KERNEL_MAPPING) || + nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM)) + dest->cpu_va = src->cpu_va + (PAGE_SIZE * start_page); + + dest->priv.pages = src->priv.pages + start_page; + dest->priv.flags = src->priv.flags; + + new_iova = sg_dma_address(src->priv.sgt->sgl) ? + sg_dma_address(src->priv.sgt->sgl) + start : 0; + + /* + * Make a new SG table that is based only on the subset of pages that + * is passed to us. This table gets freed by the dma free routines. + */ + if (src->priv.flags & NVGPU_DMA_NO_KERNEL_MAPPING) + ret = nvgpu_get_sgtable_from_pages(g, &dest->priv.sgt, + src->priv.pages + start_page, + new_iova, size); + else + ret = nvgpu_get_sgtable(g, &dest->priv.sgt, dest->cpu_va, + new_iova, size); + + return ret; +} + +int __nvgpu_mem_create_from_pages(struct gk20a *g, struct nvgpu_mem *dest, + struct page **pages, int nr_pages) +{ + struct sg_table *sgt; + struct page **our_pages = + nvgpu_kmalloc(g, sizeof(struct page *) * nr_pages); + + if (!our_pages) + return -ENOMEM; + + memcpy(our_pages, pages, sizeof(struct page *) * nr_pages); + + if (nvgpu_get_sgtable_from_pages(g, &sgt, pages, 0, + nr_pages * PAGE_SIZE)) { + nvgpu_kfree(g, our_pages); + return -ENOMEM; + } + + /* + * If we are making an SGT from physical pages we can be reasonably + * certain that this should bypass the SMMU - thus we set the DMA (aka + * IOVA) address to 0. This tells the GMMU mapping code to not make a + * mapping directed to the SMMU. + */ + sg_dma_address(sgt->sgl) = 0; + + dest->mem_flags = __NVGPU_MEM_FLAG_NO_DMA; + dest->aperture = APERTURE_SYSMEM; + dest->skip_wmb = 0; + dest->size = PAGE_SIZE * nr_pages; + + dest->priv.flags = 0; + dest->priv.pages = our_pages; + dest->priv.sgt = sgt; + + return 0; +} + +#ifdef CONFIG_TEGRA_GK20A_NVHOST +int __nvgpu_mem_create_from_phys(struct gk20a *g, struct nvgpu_mem *dest, + u64 src_phys, int nr_pages) +{ + struct page **pages = + nvgpu_kmalloc(g, sizeof(struct page *) * nr_pages); + int i, ret = 0; + + if (!pages) + return -ENOMEM; + + for (i = 0; i < nr_pages; i++) + pages[i] = phys_to_page(src_phys + PAGE_SIZE * i); + + ret = __nvgpu_mem_create_from_pages(g, dest, pages, nr_pages); + nvgpu_kfree(g, pages); + + return ret; +} +#endif + +static struct nvgpu_sgl *nvgpu_mem_linux_sgl_next(struct nvgpu_sgl *sgl) +{ + return (struct nvgpu_sgl *)sg_next((struct scatterlist *)sgl); +} + +static u64 nvgpu_mem_linux_sgl_phys(struct gk20a *g, struct nvgpu_sgl *sgl) +{ + return (u64)__nvgpu_sgl_phys(g, sgl); +} + +static u64 nvgpu_mem_linux_sgl_dma(struct nvgpu_sgl *sgl) +{ + return (u64)sg_dma_address((struct scatterlist *)sgl); +} + +static u64 nvgpu_mem_linux_sgl_length(struct nvgpu_sgl *sgl) +{ + return (u64)((struct scatterlist *)sgl)->length; +} + +static u64 nvgpu_mem_linux_sgl_gpu_addr(struct gk20a *g, + struct nvgpu_sgl *sgl, + struct nvgpu_gmmu_attrs *attrs) +{ + if (sg_dma_address((struct scatterlist *)sgl) == 0) + return g->ops.mm.gpu_phys_addr(g, attrs, + __nvgpu_sgl_phys(g, sgl)); + + if (sg_dma_address((struct scatterlist *)sgl) == DMA_ERROR_CODE) + return 0; + + return nvgpu_mem_iommu_translate(g, + sg_dma_address((struct scatterlist *)sgl)); +} + +static bool nvgpu_mem_linux_sgt_iommuable(struct gk20a *g, + struct nvgpu_sgt *sgt) +{ + if (nvgpu_is_enabled(g, NVGPU_MM_USE_PHYSICAL_SG)) + return false; + return true; +} + +static void nvgpu_mem_linux_sgl_free(struct gk20a *g, struct nvgpu_sgt *sgt) +{ + /* + * Free this SGT. All we do is free the passed SGT. The actual Linux + * SGT/SGL needs to be freed separately. + */ + nvgpu_kfree(g, sgt); +} + +static const struct nvgpu_sgt_ops nvgpu_linux_sgt_ops = { + .sgl_next = nvgpu_mem_linux_sgl_next, + .sgl_phys = nvgpu_mem_linux_sgl_phys, + .sgl_dma = nvgpu_mem_linux_sgl_dma, + .sgl_length = nvgpu_mem_linux_sgl_length, + .sgl_gpu_addr = nvgpu_mem_linux_sgl_gpu_addr, + .sgt_iommuable = nvgpu_mem_linux_sgt_iommuable, + .sgt_free = nvgpu_mem_linux_sgl_free, +}; + +static struct nvgpu_sgt *__nvgpu_mem_get_sgl_from_vidmem( + struct gk20a *g, + struct scatterlist *linux_sgl) +{ + struct nvgpu_page_alloc *vidmem_alloc; + + vidmem_alloc = nvgpu_vidmem_get_page_alloc(linux_sgl); + if (!vidmem_alloc) + return NULL; + + return &vidmem_alloc->sgt; +} + +struct nvgpu_sgt *nvgpu_linux_sgt_create(struct gk20a *g, struct sg_table *sgt) +{ + struct nvgpu_sgt *nvgpu_sgt; + struct scatterlist *linux_sgl = sgt->sgl; + + if (nvgpu_addr_is_vidmem_page_alloc(sg_dma_address(linux_sgl))) + return __nvgpu_mem_get_sgl_from_vidmem(g, linux_sgl); + + nvgpu_sgt = nvgpu_kzalloc(g, sizeof(*nvgpu_sgt)); + if (!nvgpu_sgt) + return NULL; + + nvgpu_log(g, gpu_dbg_sgl, "Making Linux SGL!"); + + nvgpu_sgt->sgl = (struct nvgpu_sgl *)linux_sgl; + nvgpu_sgt->ops = &nvgpu_linux_sgt_ops; + + return nvgpu_sgt; +} + +struct nvgpu_sgt *nvgpu_sgt_create_from_mem(struct gk20a *g, + struct nvgpu_mem *mem) +{ + return nvgpu_linux_sgt_create(g, mem->priv.sgt); +} diff --git a/include/os/linux/nvhost.c b/include/os/linux/nvhost.c new file mode 100644 index 0000000..a9341c7 --- /dev/null +++ b/include/os/linux/nvhost.c @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "nvhost_priv.h" + +#include "os_linux.h" +#include "module.h" + +int nvgpu_get_nvhost_dev(struct gk20a *g) +{ + struct device_node *np = nvgpu_get_node(g); + struct platform_device *host1x_pdev = NULL; + const __be32 *host1x_ptr; + + host1x_ptr = of_get_property(np, "nvidia,host1x", NULL); + if (host1x_ptr) { + struct device_node *host1x_node = + of_find_node_by_phandle(be32_to_cpup(host1x_ptr)); + + host1x_pdev = of_find_device_by_node(host1x_node); + if (!host1x_pdev) { + nvgpu_warn(g, "host1x device not available"); + return -EPROBE_DEFER; + } + + } else { + if (nvgpu_has_syncpoints(g)) { + nvgpu_warn(g, "host1x reference not found. assuming no syncpoints support"); + __nvgpu_set_enabled(g, NVGPU_HAS_SYNCPOINTS, false); + } + return 0; + } + + g->nvhost_dev = nvgpu_kzalloc(g, sizeof(struct nvgpu_nvhost_dev)); + if (!g->nvhost_dev) + return -ENOMEM; + + g->nvhost_dev->host1x_pdev = host1x_pdev; + + return 0; +} + +void nvgpu_free_nvhost_dev(struct gk20a *g) +{ + nvgpu_kfree(g, g->nvhost_dev); +} + +int nvgpu_nvhost_module_busy_ext( + struct nvgpu_nvhost_dev *nvhost_dev) +{ + return nvhost_module_busy_ext(nvhost_dev->host1x_pdev); +} + +void nvgpu_nvhost_module_idle_ext( + struct nvgpu_nvhost_dev *nvhost_dev) +{ + nvhost_module_idle_ext(nvhost_dev->host1x_pdev); +} + +void nvgpu_nvhost_debug_dump_device( + struct nvgpu_nvhost_dev *nvhost_dev) +{ + nvhost_debug_dump_device(nvhost_dev->host1x_pdev); +} + +const char *nvgpu_nvhost_syncpt_get_name( + struct nvgpu_nvhost_dev *nvhost_dev, int id) +{ + return nvhost_syncpt_get_name(nvhost_dev->host1x_pdev, id); +} + +bool nvgpu_nvhost_syncpt_is_valid_pt_ext( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id) +{ + return nvhost_syncpt_is_valid_pt_ext(nvhost_dev->host1x_pdev, id); +} + +int nvgpu_nvhost_syncpt_is_expired_ext( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id, u32 thresh) +{ + return nvhost_syncpt_is_expired_ext(nvhost_dev->host1x_pdev, + id, thresh); +} + +u32 nvgpu_nvhost_syncpt_incr_max_ext( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id, u32 incrs) +{ + return nvhost_syncpt_incr_max_ext(nvhost_dev->host1x_pdev, id, incrs); +} + +int nvgpu_nvhost_intr_register_notifier( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id, u32 thresh, + void (*callback)(void *, int), void *private_data) +{ + return nvhost_intr_register_notifier(nvhost_dev->host1x_pdev, + id, thresh, + callback, private_data); +} + +void nvgpu_nvhost_syncpt_set_min_eq_max_ext( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id) +{ + nvhost_syncpt_set_min_eq_max_ext(nvhost_dev->host1x_pdev, id); +} + +void nvgpu_nvhost_syncpt_put_ref_ext( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id) +{ + nvhost_syncpt_put_ref_ext(nvhost_dev->host1x_pdev, id); +} + +u32 nvgpu_nvhost_get_syncpt_host_managed( + struct nvgpu_nvhost_dev *nvhost_dev, + u32 param, const char *syncpt_name) +{ + return nvhost_get_syncpt_host_managed(nvhost_dev->host1x_pdev, + param, syncpt_name); +} + +u32 nvgpu_nvhost_get_syncpt_client_managed( + struct nvgpu_nvhost_dev *nvhost_dev, + const char *syncpt_name) +{ + return nvhost_get_syncpt_client_managed(nvhost_dev->host1x_pdev, + syncpt_name); +} + +int nvgpu_nvhost_syncpt_wait_timeout_ext( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id, + u32 thresh, u32 timeout, u32 *value, struct timespec *ts) +{ + return nvhost_syncpt_wait_timeout_ext(nvhost_dev->host1x_pdev, + id, thresh, timeout, value, ts); +} + +int nvgpu_nvhost_syncpt_read_ext_check( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id, u32 *val) +{ + return nvhost_syncpt_read_ext_check(nvhost_dev->host1x_pdev, id, val); +} + +u32 nvgpu_nvhost_syncpt_read_maxval( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id) +{ + return nvhost_syncpt_read_maxval(nvhost_dev->host1x_pdev, id); +} + +void nvgpu_nvhost_syncpt_set_safe_state( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id) +{ + u32 val; + + /* + * Add large number of increments to current value + * so that all waiters on this syncpoint are released + * + * We don't expect any case where more than 0x10000 increments + * are pending + */ + val = nvhost_syncpt_read_minval(nvhost_dev->host1x_pdev, id); + val += 0x10000; + + nvhost_syncpt_set_minval(nvhost_dev->host1x_pdev, id, val); + nvhost_syncpt_set_maxval(nvhost_dev->host1x_pdev, id, val); +} + +int nvgpu_nvhost_create_symlink(struct gk20a *g) +{ + struct device *dev = dev_from_gk20a(g); + int err = 0; + + if (g->nvhost_dev && + (dev->parent != &g->nvhost_dev->host1x_pdev->dev)) { + err = sysfs_create_link(&g->nvhost_dev->host1x_pdev->dev.kobj, + &dev->kobj, + dev_name(dev)); + } + + return err; +} + +void nvgpu_nvhost_remove_symlink(struct gk20a *g) +{ + struct device *dev = dev_from_gk20a(g); + + if (g->nvhost_dev && + (dev->parent != &g->nvhost_dev->host1x_pdev->dev)) { + sysfs_remove_link(&g->nvhost_dev->host1x_pdev->dev.kobj, + dev_name(dev)); + } +} + +#ifdef CONFIG_SYNC +u32 nvgpu_nvhost_sync_pt_id(struct sync_pt *pt) +{ + return nvhost_sync_pt_id(pt); +} + +u32 nvgpu_nvhost_sync_pt_thresh(struct sync_pt *pt) +{ + return nvhost_sync_pt_thresh(pt); +} + +struct sync_fence *nvgpu_nvhost_sync_fdget(int fd) +{ + return nvhost_sync_fdget(fd); +} + +int nvgpu_nvhost_sync_num_pts(struct sync_fence *fence) +{ + return nvhost_sync_num_pts(fence); +} + +struct sync_fence *nvgpu_nvhost_sync_create_fence( + struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 thresh, const char *name) +{ + struct nvhost_ctrl_sync_fence_info pt = { + .id = id, + .thresh = thresh, + }; + + return nvhost_sync_create_fence(nvhost_dev->host1x_pdev, &pt, 1, name); +} +#endif /* CONFIG_SYNC */ + +#ifdef CONFIG_TEGRA_T19X_GRHOST +int nvgpu_nvhost_syncpt_unit_interface_get_aperture( + struct nvgpu_nvhost_dev *nvhost_dev, + u64 *base, size_t *size) +{ + return nvhost_syncpt_unit_interface_get_aperture( + nvhost_dev->host1x_pdev, (phys_addr_t *)base, size); +} + +u32 nvgpu_nvhost_syncpt_unit_interface_get_byte_offset(u32 syncpt_id) +{ + return nvhost_syncpt_unit_interface_get_byte_offset(syncpt_id); +} + +int nvgpu_nvhost_syncpt_init(struct gk20a *g) +{ + int err = 0; + + if (!nvgpu_has_syncpoints(g)) + return -ENOSYS; + + err = nvgpu_get_nvhost_dev(g); + if (err) { + nvgpu_err(g, "host1x device not available"); + __nvgpu_set_enabled(g, NVGPU_HAS_SYNCPOINTS, false); + return -ENOSYS; + } + + err = nvgpu_nvhost_syncpt_unit_interface_get_aperture( + g->nvhost_dev, + &g->syncpt_unit_base, + &g->syncpt_unit_size); + if (err) { + nvgpu_err(g, "Failed to get syncpt interface"); + __nvgpu_set_enabled(g, NVGPU_HAS_SYNCPOINTS, false); + return -ENOSYS; + } + + g->syncpt_size = + nvgpu_nvhost_syncpt_unit_interface_get_byte_offset(1); + nvgpu_info(g, "syncpt_unit_base %llx syncpt_unit_size %zx size %x\n", + g->syncpt_unit_base, g->syncpt_unit_size, + g->syncpt_size); + + return 0; +} +#endif diff --git a/include/os/linux/nvhost_priv.h b/include/os/linux/nvhost_priv.h new file mode 100644 index 0000000..c03390a --- /dev/null +++ b/include/os/linux/nvhost_priv.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NVGPU_NVHOST_PRIV_H__ +#define __NVGPU_NVHOST_PRIV_H__ + +struct nvgpu_nvhost_dev { + struct platform_device *host1x_pdev; +}; + +#endif /* __NVGPU_NVHOST_PRIV_H__ */ diff --git a/include/os/linux/nvidia_p2p.c b/include/os/linux/nvidia_p2p.c new file mode 100644 index 0000000..87db8c5 --- /dev/null +++ b/include/os/linux/nvidia_p2p.c @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2018-2019, 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 +#include + +static void nvidia_p2p_mn_release(struct mmu_notifier *mn, + struct mm_struct *mm) +{ + struct nvidia_p2p_page_table *page_table = container_of(mn, + struct nvidia_p2p_page_table, + mn); + + page_table->free_callback(page_table->data); +} + +static void nvidia_p2p_mn_invl_range_start(struct mmu_notifier *mn, + struct mm_struct *mm, unsigned long start, unsigned long end) +{ + struct nvidia_p2p_page_table *page_table = container_of(mn, + struct nvidia_p2p_page_table, + mn); + u64 vaddr = 0; + u64 size = 0; + + vaddr = page_table->vaddr; + size = page_table->size; + + if (vaddr >= start && vaddr <= end) { + mmu_notifier_unregister_no_release(&page_table->mn, page_table->mm); + page_table->free_callback(page_table->data); + } +} + +static struct mmu_notifier_ops nvidia_p2p_mmu_ops = { + .release = nvidia_p2p_mn_release, + .invalidate_range_start = nvidia_p2p_mn_invl_range_start, +}; + +int nvidia_p2p_get_pages(u64 vaddr, u64 size, + struct nvidia_p2p_page_table **page_table, + void (*free_callback)(void *data), void *data) +{ + int ret = 0; + int user_pages = 0; + int locked = 0; + int nr_pages = size >> PAGE_SHIFT; + struct page **pages; + + if (nr_pages <= 0) { + return -EINVAL; + } + + *page_table = kzalloc(sizeof(**page_table), GFP_KERNEL); + if (!*page_table) { + return -ENOMEM; + } + + pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL); + if (!pages) { + ret = -ENOMEM; + goto free_page_table; + } + down_read(¤t->mm->mmap_sem); + locked = 1; + user_pages = get_user_pages_locked(vaddr & PAGE_MASK, nr_pages, + FOLL_WRITE | FOLL_FORCE, + pages, &locked); + up_read(¤t->mm->mmap_sem); + if (user_pages != nr_pages) { + ret = user_pages < 0 ? user_pages : -ENOMEM; + goto free_pages; + } + + (*page_table)->version = NVIDIA_P2P_PAGE_TABLE_VERSION; + (*page_table)->pages = pages; + (*page_table)->entries = user_pages; + (*page_table)->page_size = NVIDIA_P2P_PAGE_SIZE_4KB; + (*page_table)->size = size; + + (*page_table)->mn.ops = &nvidia_p2p_mmu_ops; + (*page_table)->mm = current->mm; + (*page_table)->free_callback = free_callback; + (*page_table)->data = data; + (*page_table)->vaddr = vaddr; + mutex_init(&(*page_table)->lock); + (*page_table)->mapped = NVIDIA_P2P_PINNED; + + ret = mmu_notifier_register(&(*page_table)->mn, (*page_table)->mm); + if (ret) { + goto free_pages; + } + + return 0; +free_pages: + while (--user_pages >= 0) { + put_page(pages[user_pages]); + } + kfree(pages); +free_page_table: + kfree(*page_table); + *page_table = NULL; + return ret; +} +EXPORT_SYMBOL(nvidia_p2p_get_pages); + +int nvidia_p2p_put_pages(struct nvidia_p2p_page_table *page_table) +{ + if (!page_table) { + return -EINVAL; + } + + mmu_notifier_unregister(&page_table->mn, page_table->mm); + + return 0; +} +EXPORT_SYMBOL(nvidia_p2p_put_pages); + +int nvidia_p2p_free_page_table(struct nvidia_p2p_page_table *page_table) +{ + int user_pages = 0; + struct page **pages = NULL; + + if (!page_table) { + return 0; + } + + mutex_lock(&page_table->lock); + + if (page_table->mapped & NVIDIA_P2P_MAPPED) { + WARN(1, "Attempting to free unmapped pages"); + } + + if (page_table->mapped & NVIDIA_P2P_PINNED) { + pages = page_table->pages; + user_pages = page_table->entries; + + while (--user_pages >= 0) { + put_page(pages[user_pages]); + } + + kfree(pages); + page_table->mapped &= (u32)~NVIDIA_P2P_PINNED; + } + + mutex_unlock(&page_table->lock); + + return 0; +} +EXPORT_SYMBOL(nvidia_p2p_free_page_table); + +int nvidia_p2p_dma_map_pages(struct device *dev, + struct nvidia_p2p_page_table *page_table, + struct nvidia_p2p_dma_mapping **dma_mapping, + enum dma_data_direction direction) +{ + struct sg_table *sgt = NULL; + struct scatterlist *sg; + struct page **pages = NULL; + u32 nr_pages = 0; + int ret = 0; + int i, count; + + if (!page_table) { + return -EINVAL; + } + + mutex_lock(&page_table->lock); + + pages = page_table->pages; + nr_pages = page_table->entries; + if (nr_pages <= 0) { + mutex_unlock(&page_table->lock); + return -EINVAL; + } + + *dma_mapping = kzalloc(sizeof(**dma_mapping), GFP_KERNEL); + if (!*dma_mapping) { + mutex_unlock(&page_table->lock); + return -ENOMEM; + } + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) { + ret = -ENOMEM; + goto free_dma_mapping; + } + ret = sg_alloc_table_from_pages(sgt, pages, + nr_pages, 0, page_table->size, GFP_KERNEL); + if (ret) { + goto free_sgt; + } + + (*dma_mapping)->version = NVIDIA_P2P_DMA_MAPPING_VERSION; + (*dma_mapping)->sgt = sgt; + (*dma_mapping)->dev = dev; + (*dma_mapping)->direction = direction; + (*dma_mapping)->page_table = page_table; + + count = dma_map_sg(dev, sgt->sgl, sgt->nents, direction); + if (count < 1) { + goto free_sg_table; + } + + (*dma_mapping)->entries = count; + + (*dma_mapping)->hw_address = kcalloc(count, sizeof(u64), GFP_KERNEL); + if (!((*dma_mapping)->hw_address)) { + ret = -ENOMEM; + goto unmap_sg; + } + (*dma_mapping)->hw_len = kcalloc(count, sizeof(u64), GFP_KERNEL); + if (!((*dma_mapping)->hw_len)) { + ret = -ENOMEM; + goto free_hw_address; + } + + for_each_sg(sgt->sgl, sg, count, i) { + (*dma_mapping)->hw_address[i] = sg_dma_address(sg); + (*dma_mapping)->hw_len[i] = sg_dma_len(sg); + } + (*dma_mapping)->page_table->mapped |= NVIDIA_P2P_MAPPED; + mutex_unlock(&page_table->lock); + + return 0; +free_hw_address: + kfree((*dma_mapping)->hw_address); +unmap_sg: + dma_unmap_sg(dev, sgt->sgl, + sgt->nents, direction); +free_sg_table: + sg_free_table(sgt); +free_sgt: + kfree(sgt); +free_dma_mapping: + kfree(*dma_mapping); + *dma_mapping = NULL; + mutex_unlock(&page_table->lock); + + return ret; +} +EXPORT_SYMBOL(nvidia_p2p_dma_map_pages); + +int nvidia_p2p_dma_unmap_pages(struct nvidia_p2p_dma_mapping *dma_mapping) +{ + struct nvidia_p2p_page_table *page_table = NULL; + + if (!dma_mapping) { + return -EINVAL; + } + + page_table = dma_mapping->page_table; + if (!page_table) { + return -EFAULT; + } + + mutex_lock(&page_table->lock); + if (page_table->mapped & NVIDIA_P2P_MAPPED) { + kfree(dma_mapping->hw_len); + kfree(dma_mapping->hw_address); + if (dma_mapping->entries) + dma_unmap_sg(dma_mapping->dev, + dma_mapping->sgt->sgl, + dma_mapping->sgt->nents, + dma_mapping->direction); + sg_free_table(dma_mapping->sgt); + kfree(dma_mapping->sgt); + kfree(dma_mapping); + page_table->mapped &= (u32)~NVIDIA_P2P_MAPPED; + } + mutex_unlock(&page_table->lock); + + return 0; +} +EXPORT_SYMBOL(nvidia_p2p_dma_unmap_pages); + +int nvidia_p2p_free_dma_mapping(struct nvidia_p2p_dma_mapping *dma_mapping) +{ + return nvidia_p2p_dma_unmap_pages(dma_mapping); +} +EXPORT_SYMBOL(nvidia_p2p_free_dma_mapping); diff --git a/include/os/linux/nvlink.c b/include/os/linux/nvlink.c new file mode 100644 index 0000000..dd7c02c --- /dev/null +++ b/include/os/linux/nvlink.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef CONFIG_TEGRA_NVLINK +#include +#endif + +#include +#include +#include +#include "module.h" + +#ifdef CONFIG_TEGRA_NVLINK +int nvgpu_nvlink_read_dt_props(struct gk20a *g) +{ + struct device_node *np; + struct nvlink_device *ndev = g->nvlink.priv; + u32 local_dev_id; + u32 local_link_id; + u32 remote_dev_id; + u32 remote_link_id; + bool is_master; + + /* Parse DT */ + np = nvgpu_get_node(g); + if (!np) + goto fail; + + np = of_get_child_by_name(np, "nvidia,nvlink"); + if (!np) + goto fail; + + np = of_get_child_by_name(np, "endpoint"); + if (!np) + goto fail; + + /* Parse DT structure to detect endpoint topology */ + of_property_read_u32(np, "local_dev_id", &local_dev_id); + of_property_read_u32(np, "local_link_id", &local_link_id); + of_property_read_u32(np, "remote_dev_id", &remote_dev_id); + of_property_read_u32(np, "remote_link_id", &remote_link_id); + is_master = of_property_read_bool(np, "is_master"); + + /* Check that we are in dGPU mode */ + if (local_dev_id != NVLINK_ENDPT_GV100) { + nvgpu_err(g, "Local nvlink device is not dGPU"); + return -EINVAL; + } + + ndev->is_master = is_master; + ndev->device_id = local_dev_id; + ndev->link.link_id = local_link_id; + ndev->link.remote_dev_info.device_id = remote_dev_id; + ndev->link.remote_dev_info.link_id = remote_link_id; + + return 0; + +fail: + nvgpu_info(g, "nvlink endpoint not found or invaling in DT"); + return -ENODEV; +} +#endif /* CONFIG_TEGRA_NVLINK */ + +void nvgpu_mss_nvlink_init_credits(struct gk20a *g) +{ + /* MSS_NVLINK_1_BASE */ + void __iomem *soc1 = ioremap(0x01f20010, 4096); + /* MSS_NVLINK_2_BASE */ + void __iomem *soc2 = ioremap(0x01f40010, 4096); + /* MSS_NVLINK_3_BASE */ + void __iomem *soc3 = ioremap(0x01f60010, 4096); + /* MSS_NVLINK_4_BASE */ + void __iomem *soc4 = ioremap(0x01f80010, 4096); + u32 val; + + nvgpu_log(g, gpu_dbg_info, "init nvlink soc credits"); + + val = readl_relaxed(soc1); + writel_relaxed(val, soc1); + val = readl_relaxed(soc1 + 4); + writel_relaxed(val, soc1 + 4); + + val = readl_relaxed(soc2); + writel_relaxed(val, soc2); + val = readl_relaxed(soc2 + 4); + writel_relaxed(val, soc2 + 4); + + val = readl_relaxed(soc3); + writel_relaxed(val, soc3); + val = readl_relaxed(soc3 + 4); + writel_relaxed(val, soc3 + 4); + + val = readl_relaxed(soc4); + writel_relaxed(val, soc4); + val = readl_relaxed(soc4 + 4); + writel_relaxed(val, soc4 + 4); +} + +int nvgpu_nvlink_deinit(struct gk20a *g) +{ +#ifdef CONFIG_TEGRA_NVLINK + struct nvlink_device *ndev = g->nvlink.priv; + int err; + + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_NVLINK)) + return -ENODEV; + + err = nvlink_shutdown(ndev); + if (err) { + nvgpu_err(g, "failed to shut down nvlink"); + return err; + } + + nvgpu_nvlink_remove(g); + + return 0; +#endif + return -ENODEV; +} diff --git a/include/os/linux/nvlink.h b/include/os/linux/nvlink.h new file mode 100644 index 0000000..4dc54f6 --- /dev/null +++ b/include/os/linux/nvlink.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NVGPU_OS_LINUX_NVLINK_H + +struct gk20a; +int nvgpu_nvlink_deinit(struct gk20a *g); + +#endif diff --git a/include/os/linux/os_fence_android.c b/include/os/linux/os_fence_android.c new file mode 100644 index 0000000..013989e --- /dev/null +++ b/include/os/linux/os_fence_android.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include +#include + +#include "../drivers/staging/android/sync.h" + +inline struct sync_fence *nvgpu_get_sync_fence(struct nvgpu_os_fence *s) +{ + struct sync_fence *fence = (struct sync_fence *)s->priv; + return fence; +} + +static void nvgpu_os_fence_clear(struct nvgpu_os_fence *fence_out) +{ + fence_out->priv = NULL; + fence_out->g = NULL; + fence_out->ops = NULL; +} + +void nvgpu_os_fence_init(struct nvgpu_os_fence *fence_out, + struct gk20a *g, const struct nvgpu_os_fence_ops *fops, + struct sync_fence *fence) +{ + fence_out->g = g; + fence_out->ops = fops; + fence_out->priv = (void *)fence; +} + +void nvgpu_os_fence_android_drop_ref(struct nvgpu_os_fence *s) +{ + struct sync_fence *fence = nvgpu_get_sync_fence(s); + + sync_fence_put(fence); + + nvgpu_os_fence_clear(s); +} + +void nvgpu_os_fence_android_install_fd(struct nvgpu_os_fence *s, int fd) +{ + struct sync_fence *fence = nvgpu_get_sync_fence(s); + + sync_fence_get(fence); + sync_fence_install(fence, fd); +} + +int nvgpu_os_fence_fdget(struct nvgpu_os_fence *fence_out, + struct channel_gk20a *c, int fd) +{ + int err = -ENOSYS; + +#ifdef CONFIG_TEGRA_GK20A_NVHOST + err = nvgpu_os_fence_syncpt_fdget(fence_out, c, fd); +#endif + + if (err) + err = nvgpu_os_fence_sema_fdget(fence_out, c, fd); + + if (err) + nvgpu_err(c->g, "error obtaining fence from fd %d", fd); + + return err; +} diff --git a/include/os/linux/os_fence_android_sema.c b/include/os/linux/os_fence_android_sema.c new file mode 100644 index 0000000..eb60600 --- /dev/null +++ b/include/os/linux/os_fence_android_sema.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a/mm_gk20a.h" + +#include "sync_sema_android.h" + +#include "../drivers/staging/android/sync.h" + +int nvgpu_os_fence_sema_wait_gen_cmd(struct nvgpu_os_fence *s, + struct priv_cmd_entry *wait_cmd, + struct channel_gk20a *c, + int max_wait_cmds) +{ + int err; + int wait_cmd_size; + int num_wait_cmds; + int i; + struct nvgpu_semaphore *sema; + struct sync_fence *sync_fence = nvgpu_get_sync_fence(s); + + wait_cmd_size = c->g->ops.fifo.get_sema_wait_cmd_size(); + + num_wait_cmds = sync_fence->num_fences; + if (num_wait_cmds == 0) + return 0; + + if (max_wait_cmds && num_wait_cmds > max_wait_cmds) + return -EINVAL; + + err = gk20a_channel_alloc_priv_cmdbuf(c, + wait_cmd_size * num_wait_cmds, + wait_cmd); + if (err) { + return err; + } + + for (i = 0; i < num_wait_cmds; i++) { + struct sync_pt *pt = sync_pt_from_fence( + sync_fence->cbs[i].sync_pt); + + sema = gk20a_sync_pt_sema(pt); + channel_sync_semaphore_gen_wait_cmd(c, sema, wait_cmd, + wait_cmd_size, i); + } + + return 0; +} + +static const struct nvgpu_os_fence_ops sema_ops = { + .program_waits = nvgpu_os_fence_sema_wait_gen_cmd, + .drop_ref = nvgpu_os_fence_android_drop_ref, + .install_fence = nvgpu_os_fence_android_install_fd, +}; + +int nvgpu_os_fence_sema_create( + struct nvgpu_os_fence *fence_out, + struct channel_gk20a *c, + struct nvgpu_semaphore *sema) +{ + struct sync_fence *fence; + + fence = gk20a_sync_fence_create(c, sema, "f-gk20a-0x%04x", + nvgpu_semaphore_gpu_ro_va(sema)); + + if (!fence) { + nvgpu_err(c->g, "error constructing new fence: f-gk20a-0x%04x", + (u32)nvgpu_semaphore_gpu_ro_va(sema)); + + return -ENOMEM; + } + + nvgpu_os_fence_init(fence_out, c->g, &sema_ops, fence); + + return 0; +} + +int nvgpu_os_fence_sema_fdget(struct nvgpu_os_fence *fence_out, + struct channel_gk20a *c, int fd) +{ + struct sync_fence *fence = gk20a_sync_fence_fdget(fd); + + if (!fence) + return -EINVAL; + + nvgpu_os_fence_init(fence_out, c->g, &sema_ops, fence); + + return 0; +} diff --git a/include/os/linux/os_fence_android_syncpt.c b/include/os/linux/os_fence_android_syncpt.c new file mode 100644 index 0000000..368a03c --- /dev/null +++ b/include/os/linux/os_fence_android_syncpt.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gk20a/mm_gk20a.h" + +#include "../drivers/staging/android/sync.h" + +int nvgpu_os_fence_syncpt_wait_gen_cmd(struct nvgpu_os_fence *s, + struct priv_cmd_entry *wait_cmd, + struct channel_gk20a *c, + int max_wait_cmds) +{ + int err; + int wait_cmd_size; + int num_wait_cmds; + int i; + u32 wait_id; + struct sync_pt *pt; + + struct sync_fence *sync_fence = (struct sync_fence *)s->priv; + + if (max_wait_cmds && sync_fence->num_fences > max_wait_cmds) + return -EINVAL; + + /* validate syncpt ids */ + for (i = 0; i < sync_fence->num_fences; i++) { + pt = sync_pt_from_fence(sync_fence->cbs[i].sync_pt); + wait_id = nvgpu_nvhost_sync_pt_id(pt); + if (!wait_id || !nvgpu_nvhost_syncpt_is_valid_pt_ext( + c->g->nvhost_dev, wait_id)) { + return -EINVAL; + } + } + + num_wait_cmds = nvgpu_nvhost_sync_num_pts(sync_fence); + if (num_wait_cmds == 0) + return 0; + + wait_cmd_size = c->g->ops.fifo.get_syncpt_wait_cmd_size(); + err = gk20a_channel_alloc_priv_cmdbuf(c, + wait_cmd_size * num_wait_cmds, wait_cmd); + if (err) { + return err; + } + + for (i = 0; i < sync_fence->num_fences; i++) { + struct sync_pt *pt = sync_pt_from_fence( + sync_fence->cbs[i].sync_pt); + u32 wait_id = nvgpu_nvhost_sync_pt_id(pt); + u32 wait_value = nvgpu_nvhost_sync_pt_thresh(pt); + + err = channel_sync_syncpt_gen_wait_cmd(c, wait_id, wait_value, + wait_cmd, wait_cmd_size, i, true); + } + + WARN_ON(i != num_wait_cmds); + + return 0; +} + +static const struct nvgpu_os_fence_ops syncpt_ops = { + .program_waits = nvgpu_os_fence_syncpt_wait_gen_cmd, + .drop_ref = nvgpu_os_fence_android_drop_ref, + .install_fence = nvgpu_os_fence_android_install_fd, +}; + +int nvgpu_os_fence_syncpt_create( + struct nvgpu_os_fence *fence_out, struct channel_gk20a *c, + struct nvgpu_nvhost_dev *nvhost_dev, u32 id, u32 thresh) +{ + struct sync_fence *fence = nvgpu_nvhost_sync_create_fence( + nvhost_dev, id, thresh, "fence"); + + if (IS_ERR(fence)) { + nvgpu_err(c->g, "error %d during construction of fence.", (int)PTR_ERR(fence)); + return PTR_ERR(fence); + } + + nvgpu_os_fence_init(fence_out, c->g, &syncpt_ops, fence); + + return 0; +} + +int nvgpu_os_fence_syncpt_fdget(struct nvgpu_os_fence *fence_out, + struct channel_gk20a *c, int fd) +{ + struct sync_fence *fence = nvgpu_nvhost_sync_fdget(fd); + + if (fence == NULL) { + return -ENOMEM; + } + + nvgpu_os_fence_init(fence_out, c->g, &syncpt_ops, fence); + + return 0; +} diff --git a/include/os/linux/os_linux.h b/include/os/linux/os_linux.h new file mode 100644 index 0000000..25c6c03 --- /dev/null +++ b/include/os/linux/os_linux.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NVGPU_OS_LINUX_H +#define NVGPU_OS_LINUX_H + +#include +#include +#include + +#include + +#include "cde.h" +#include "sched.h" + +struct nvgpu_os_linux_ops { + struct { + void (*get_program_numbers)(struct gk20a *g, + u32 block_height_log2, + u32 shader_parameter, + int *hprog, int *vprog); + bool (*need_scatter_buffer)(struct gk20a *g); + int (*populate_scatter_buffer)(struct gk20a *g, + struct sg_table *sgt, + size_t surface_size, + void *scatter_buffer_ptr, + size_t scatter_buffer_size); + } cde; + + struct { + int (*init_debugfs)(struct gk20a *g); + } clk; + + struct { + int (*init_debugfs)(struct gk20a *g); + } therm; + + struct { + int (*init_debugfs)(struct gk20a *g); + } fecs_trace; +}; + +struct nvgpu_os_linux { + struct gk20a g; + struct device *dev; + + struct { + struct cdev cdev; + struct device *node; + } channel; + + struct { + struct cdev cdev; + struct device *node; + /* see gk20a_ctrl_priv */ + struct nvgpu_list_node privs; + /* guards modifications to the list and its contents */ + struct nvgpu_mutex privs_lock; + } ctrl; + + struct { + struct cdev cdev; + struct device *node; + } as_dev; + + struct { + struct cdev cdev; + struct device *node; + } dbg; + + struct { + struct cdev cdev; + struct device *node; + } prof; + + struct { + struct cdev cdev; + struct device *node; + } tsg; + + struct { + struct cdev cdev; + struct device *node; + } ctxsw; + + struct { + struct cdev cdev; + struct device *node; + } sched; + + dev_t cdev_region; + + struct devfreq *devfreq; + + struct device_dma_parameters dma_parms; + + atomic_t hw_irq_stall_count; + atomic_t hw_irq_nonstall_count; + + struct nvgpu_cond sw_irq_stall_last_handled_wq; + atomic_t sw_irq_stall_last_handled; + + atomic_t nonstall_ops; + + struct nvgpu_cond sw_irq_nonstall_last_handled_wq; + atomic_t sw_irq_nonstall_last_handled; + + struct work_struct nonstall_fn_work; + struct workqueue_struct *nonstall_work_queue; + + struct resource *reg_mem; + void __iomem *regs; + void __iomem *regs_saved; + + struct resource *bar1_mem; + void __iomem *bar1; + void __iomem *bar1_saved; + + void __iomem *usermode_regs; + void __iomem *usermode_regs_saved; + + u64 regs_bus_addr; + + struct nvgpu_os_linux_ops ops; + +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs; + struct dentry *debugfs_alias; + + struct dentry *debugfs_ltc_enabled; + struct dentry *debugfs_timeouts_enabled; + struct dentry *debugfs_gr_idle_timeout_default; + struct dentry *debugfs_disable_bigpage; + struct dentry *debugfs_gr_default_attrib_cb_size; + + struct dentry *debugfs_timeslice_low_priority_us; + struct dentry *debugfs_timeslice_medium_priority_us; + struct dentry *debugfs_timeslice_high_priority_us; + struct dentry *debugfs_runlist_interleave; + struct dentry *debugfs_allocators; + struct dentry *debugfs_xve; + struct dentry *debugfs_kmem; + struct dentry *debugfs_hal; + struct dentry *debugfs_ltc; + + struct dentry *debugfs_force_preemption_cilp; + struct dentry *debugfs_force_preemption_gfxp; + struct dentry *debugfs_dump_ctxsw_stats; +#endif + DECLARE_HASHTABLE(ecc_sysfs_stats_htable, 5); + struct dev_ext_attribute *ecc_attrs; + + struct gk20a_cde_app cde_app; + + struct rw_semaphore busy_lock; + + bool init_done; +}; + +static inline struct nvgpu_os_linux *nvgpu_os_linux_from_gk20a(struct gk20a *g) +{ + return container_of(g, struct nvgpu_os_linux, g); +} + +static inline struct device *dev_from_gk20a(struct gk20a *g) +{ + return nvgpu_os_linux_from_gk20a(g)->dev; +} + +#define INTERFACE_NAME "nvhost%s-gpu" + +#define totalram_size_in_mb (totalram_pages >> (10 - (PAGE_SHIFT - 10))) + +#endif diff --git a/include/os/linux/os_ops.c b/include/os/linux/os_ops.c new file mode 100644 index 0000000..f1ab4b1 --- /dev/null +++ b/include/os/linux/os_ops.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "os_linux.h" + +#include "os_ops_gm20b.h" +#include "os_ops_gp10b.h" +#include "os_ops_gp106.h" +#include "os_ops_gv11b.h" +#include "os_ops_gv100.h" + +#if defined(CONFIG_TEGRA_GPU_NEXT) +#include "nvgpu_gpuid_next.h" +#endif + +int nvgpu_init_os_linux_ops(struct nvgpu_os_linux *l) +{ + struct gk20a *g = &l->g; + u32 ver = g->params.gpu_arch + g->params.gpu_impl; + + switch (ver) { + case GK20A_GPUID_GM20B: + case GK20A_GPUID_GM20B_B: + nvgpu_gm20b_init_os_ops(l); + break; + case NVGPU_GPUID_GP10B: + nvgpu_gp10b_init_os_ops(l); + break; + case NVGPU_GPUID_GP106: + nvgpu_gp106_init_os_ops(l); + break; + case NVGPU_GPUID_GV100: + nvgpu_gv100_init_os_ops(l); + break; + case NVGPU_GPUID_GV11B: + nvgpu_gv11b_init_os_ops(l); + break; +#if defined(CONFIG_TEGRA_GPU_NEXT) + case NVGPU_GPUID_NEXT: + NVGPU_NEXT_INIT_OS_OPS(l); + break; +#endif + default: + break; + } + + return 0; +} diff --git a/include/os/linux/os_ops.h b/include/os/linux/os_ops.h new file mode 100644 index 0000000..af3ce0a --- /dev/null +++ b/include/os/linux/os_ops.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __LINUX_OS_OPS_H +#define __LINUX_OS_OPS_H + +int nvgpu_init_os_linux_ops(struct nvgpu_os_linux *l); + +#endif diff --git a/include/os/linux/os_ops_gm20b.c b/include/os/linux/os_ops_gm20b.c new file mode 100644 index 0000000..77aee39 --- /dev/null +++ b/include/os/linux/os_ops_gm20b.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "os_linux.h" + +#include "cde_gm20b.h" +#include "debug_clk_gm20b.h" +#include "debug_fecs_trace.h" + + +static struct nvgpu_os_linux_ops gm20b_os_linux_ops = { +#ifdef CONFIG_NVGPU_SUPPORT_CDE + .cde = { + .get_program_numbers = gm20b_cde_get_program_numbers, + }, +#endif + .clk = { + .init_debugfs = gm20b_clk_init_debugfs, + }, + + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, +}; + +void nvgpu_gm20b_init_os_ops(struct nvgpu_os_linux *l) +{ +#ifdef CONFIG_NVGPU_SUPPORT_CDE + l->ops.cde = gm20b_os_linux_ops.cde; +#endif + l->ops.clk = gm20b_os_linux_ops.clk; + + l->ops.fecs_trace = gm20b_os_linux_ops.fecs_trace; +} diff --git a/include/os/linux/os_ops_gm20b.h b/include/os/linux/os_ops_gm20b.h new file mode 100644 index 0000000..7d27e40 --- /dev/null +++ b/include/os/linux/os_ops_gm20b.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __LINUX_OS_OPS_GM20B_H +#define __LINUX_OS_OPS_GM20B_H + +void nvgpu_gm20b_init_os_ops(struct nvgpu_os_linux *l); + +#endif diff --git a/include/os/linux/os_ops_gp106.c b/include/os/linux/os_ops_gp106.c new file mode 100644 index 0000000..14f1b00 --- /dev/null +++ b/include/os/linux/os_ops_gp106.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "os_linux.h" + +#include "debug_clk_gp106.h" +#include "debug_therm_gp106.h" +#include "debug_fecs_trace.h" + +static struct nvgpu_os_linux_ops gp106_os_linux_ops = { + .clk = { + .init_debugfs = gp106_clk_init_debugfs, + }, + .therm = { + .init_debugfs = gp106_therm_init_debugfs, + }, + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, +}; + +void nvgpu_gp106_init_os_ops(struct nvgpu_os_linux *l) +{ + l->ops.clk = gp106_os_linux_ops.clk; + l->ops.therm = gp106_os_linux_ops.therm; + l->ops.fecs_trace = gp106_os_linux_ops.fecs_trace; +} diff --git a/include/os/linux/os_ops_gp106.h b/include/os/linux/os_ops_gp106.h new file mode 100644 index 0000000..7d423d5 --- /dev/null +++ b/include/os/linux/os_ops_gp106.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __LINUX_OS_OPS_GP106_H +#define __LINUX_OS_OPS_GP106_H + +void nvgpu_gp106_init_os_ops(struct nvgpu_os_linux *l); + +#endif diff --git a/include/os/linux/os_ops_gp10b.c b/include/os/linux/os_ops_gp10b.c new file mode 100644 index 0000000..e2891f7 --- /dev/null +++ b/include/os/linux/os_ops_gp10b.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "os_linux.h" + +#include "cde_gp10b.h" +#include "debug_fecs_trace.h" + +static struct nvgpu_os_linux_ops gp10b_os_linux_ops = { +#ifdef CONFIG_NVGPU_SUPPORT_CDE + .cde = { + .get_program_numbers = gp10b_cde_get_program_numbers, + .need_scatter_buffer = gp10b_need_scatter_buffer, + .populate_scatter_buffer = gp10b_populate_scatter_buffer, + }, +#endif + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, +}; + +void nvgpu_gp10b_init_os_ops(struct nvgpu_os_linux *l) +{ +#ifdef CONFIG_NVGPU_SUPPORT_CDE + l->ops.cde = gp10b_os_linux_ops.cde; +#endif + l->ops.fecs_trace = gp10b_os_linux_ops.fecs_trace; +} diff --git a/include/os/linux/os_ops_gp10b.h b/include/os/linux/os_ops_gp10b.h new file mode 100644 index 0000000..0be1bca --- /dev/null +++ b/include/os/linux/os_ops_gp10b.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __LINUX_OS_OPS_GP10B_H +#define __LINUX_OS_OPS_GP10B_H + +void nvgpu_gp10b_init_os_ops(struct nvgpu_os_linux *l); + +#endif diff --git a/include/os/linux/os_ops_gv100.c b/include/os/linux/os_ops_gv100.c new file mode 100644 index 0000000..9d92bdf --- /dev/null +++ b/include/os/linux/os_ops_gv100.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "os_linux.h" + +#include "debug_clk_gv100.h" +#include "debug_therm_gp106.h" +#include "debug_fecs_trace.h" + +static struct nvgpu_os_linux_ops gv100_os_linux_ops = { + .clk = { + .init_debugfs = gv100_clk_init_debugfs, + }, + .therm = { + .init_debugfs = gp106_therm_init_debugfs, + }, + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, +}; + +void nvgpu_gv100_init_os_ops(struct nvgpu_os_linux *l) +{ + l->ops.clk = gv100_os_linux_ops.clk; + l->ops.therm = gv100_os_linux_ops.therm; + l->ops.fecs_trace = gv100_os_linux_ops.fecs_trace; +} diff --git a/include/os/linux/os_ops_gv100.h b/include/os/linux/os_ops_gv100.h new file mode 100644 index 0000000..43923b2 --- /dev/null +++ b/include/os/linux/os_ops_gv100.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __LINUX_OS_OPS_GV100_H +#define __LINUX_OS_OPS_GV100_H + +void nvgpu_gv100_init_os_ops(struct nvgpu_os_linux *l); + +#endif diff --git a/include/os/linux/os_ops_gv11b.c b/include/os/linux/os_ops_gv11b.c new file mode 100644 index 0000000..a82ad0a --- /dev/null +++ b/include/os/linux/os_ops_gv11b.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "os_linux.h" + +#include "debug_fecs_trace.h" + +static struct nvgpu_os_linux_ops gv11b_os_linux_ops = { + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, +}; + +void nvgpu_gv11b_init_os_ops(struct nvgpu_os_linux *l) +{ + l->ops.fecs_trace = gv11b_os_linux_ops.fecs_trace; +} diff --git a/include/os/linux/os_ops_gv11b.h b/include/os/linux/os_ops_gv11b.h new file mode 100644 index 0000000..eef6c4a --- /dev/null +++ b/include/os/linux/os_ops_gv11b.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LINUX_OS_OPS_GV11B_H +#define LINUX_OS_OPS_GV11B_H + +struct nvgpu_os_linux; + +void nvgpu_gv11b_init_os_ops(struct nvgpu_os_linux *l); + +#endif diff --git a/include/os/linux/os_sched.c b/include/os/linux/os_sched.c new file mode 100644 index 0000000..9a25da1 --- /dev/null +++ b/include/os/linux/os_sched.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include + +#include + +int nvgpu_current_tid(struct gk20a *g) +{ + return current->pid; +} + +int nvgpu_current_pid(struct gk20a *g) +{ + return current->tgid; +} + +void __nvgpu_print_current(struct gk20a *g, const char *func_name, int line, + void *ctx, enum nvgpu_log_type type) +{ + __nvgpu_log_msg(g, func_name, line, type, current->comm); +} diff --git a/include/os/linux/pci.c b/include/os/linux/pci.c new file mode 100644 index 0000000..07071d1 --- /dev/null +++ b/include/os/linux/pci.c @@ -0,0 +1,854 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nvlink.h" +#include "clk/clk.h" +#include "clk/clk_mclk.h" +#include "module.h" +#include "intr.h" +#include "sysfs.h" +#include "os_linux.h" +#include "platform_gk20a.h" + +#include "pci.h" +#include "pci_usermode.h" + +#include "driver_common.h" + +#define PCI_INTERFACE_NAME "card-%s%%s" + +static int nvgpu_pci_tegra_probe(struct device *dev) +{ + return 0; +} + +static int nvgpu_pci_tegra_remove(struct device *dev) +{ + return 0; +} + +static bool nvgpu_pci_tegra_is_railgated(struct device *pdev) +{ + return false; +} + +static long nvgpu_pci_clk_round_rate(struct device *dev, unsigned long rate) +{ + long ret = (long)rate; + + if (rate == UINT_MAX) + ret = BOOT_GPC2CLK_MHZ * 1000000UL; + + return ret; +} + +static struct gk20a_platform nvgpu_pci_device[] = { + { /* DEVICE=0x1c35 */ + /* ptimer src frequency in hz */ + .ptimer_src_freq = 31250000, + + .probe = nvgpu_pci_tegra_probe, + .remove = nvgpu_pci_tegra_remove, + + /* power management configuration */ + .railgate_delay_init = 500, + .can_railgate_init = false, + .can_elpg_init = true, + .enable_elpg = true, + .enable_elcg = false, + .enable_slcg = true, + .enable_blcg = true, + .enable_mscg = true, + .can_slcg = true, + .can_blcg = true, + .can_elcg = true, + + .disable_aspm = true, + + /* power management callbacks */ + .is_railgated = nvgpu_pci_tegra_is_railgated, + .clk_round_rate = nvgpu_pci_clk_round_rate, + + .ch_wdt_timeout_ms = 7000, + + .honors_aperture = true, + .dma_mask = DMA_BIT_MASK(40), + .vbios_min_version = 0x86063000, + .hardcode_sw_threshold = true, + .ina3221_dcb_index = 0, + .ina3221_i2c_address = 0x84, + .ina3221_i2c_port = 0x2, + }, + { /* DEVICE=0x1c36 */ + /* ptimer src frequency in hz */ + .ptimer_src_freq = 31250000, + + .probe = nvgpu_pci_tegra_probe, + .remove = nvgpu_pci_tegra_remove, + + /* power management configuration */ + .railgate_delay_init = 500, + .can_railgate_init = false, + .can_elpg_init = true, + .enable_elpg = true, + .enable_elcg = false, + .enable_slcg = true, + .enable_blcg = true, + .enable_mscg = true, + .can_slcg = true, + .can_blcg = true, + .can_elcg = true, + + .disable_aspm = true, + + /* power management callbacks */ + .is_railgated = nvgpu_pci_tegra_is_railgated, + .clk_round_rate = nvgpu_pci_clk_round_rate, + + .ch_wdt_timeout_ms = 7000, + + .honors_aperture = true, + .dma_mask = DMA_BIT_MASK(40), + .vbios_min_version = 0x86062d00, + .hardcode_sw_threshold = true, + .ina3221_dcb_index = 0, + .ina3221_i2c_address = 0x84, + .ina3221_i2c_port = 0x2, + }, + { /* DEVICE=0x1c37 */ + /* ptimer src frequency in hz */ + .ptimer_src_freq = 31250000, + + .probe = nvgpu_pci_tegra_probe, + .remove = nvgpu_pci_tegra_remove, + + /* power management configuration */ + .railgate_delay_init = 500, + .can_railgate_init = false, + .can_elpg_init = true, + .enable_elpg = true, + .enable_elcg = false, + .enable_slcg = true, + .enable_blcg = true, + .enable_mscg = true, + .can_slcg = true, + .can_blcg = true, + .can_elcg = true, + + .disable_aspm = true, + + /* power management callbacks */ + .is_railgated = nvgpu_pci_tegra_is_railgated, + .clk_round_rate = nvgpu_pci_clk_round_rate, + + .ch_wdt_timeout_ms = 7000, + + .honors_aperture = true, + .dma_mask = DMA_BIT_MASK(40), + .vbios_min_version = 0x86063000, + .hardcode_sw_threshold = true, + .ina3221_dcb_index = 0, + .ina3221_i2c_address = 0x84, + .ina3221_i2c_port = 0x2, + }, + { /* DEVICE=0x1c75 */ + /* ptimer src frequency in hz */ + .ptimer_src_freq = 31250000, + + .probe = nvgpu_pci_tegra_probe, + .remove = nvgpu_pci_tegra_remove, + + /* power management configuration */ + .railgate_delay_init = 500, + .can_railgate_init = false, + .can_elpg_init = true, + .enable_elpg = true, + .enable_elcg = false, + .enable_slcg = true, + .enable_blcg = true, + .enable_mscg = true, + .can_slcg = true, + .can_blcg = true, + .can_elcg = true, + + .disable_aspm = true, + + /* power management callbacks */ + .is_railgated = nvgpu_pci_tegra_is_railgated, + .clk_round_rate = nvgpu_pci_clk_round_rate, + + .ch_wdt_timeout_ms = 7000, + + .honors_aperture = true, + .dma_mask = DMA_BIT_MASK(40), + .vbios_min_version = 0x86065300, + .hardcode_sw_threshold = false, + .ina3221_dcb_index = 1, + .ina3221_i2c_address = 0x80, + .ina3221_i2c_port = 0x1, + }, + { /* DEVICE=PG503 SKU 201 */ + /* ptimer src frequency in hz */ + .ptimer_src_freq = 31250000, + + .probe = nvgpu_pci_tegra_probe, + .remove = nvgpu_pci_tegra_remove, + + /* power management configuration */ + .railgate_delay_init = 500, + .can_railgate_init = false, + .can_elpg_init = false, + .enable_elpg = false, + .enable_elcg = false, + .enable_slcg = false, + .enable_blcg = false, + .enable_mscg = false, + .can_slcg = false, + .can_blcg = false, + .can_elcg = false, + + .disable_aspm = true, + + /* power management callbacks */ + .is_railgated = nvgpu_pci_tegra_is_railgated, + .clk_round_rate = nvgpu_pci_clk_round_rate, + + .ch_wdt_timeout_ms = 7000, + + .honors_aperture = true, + .dma_mask = DMA_BIT_MASK(40), + .vbios_min_version = 0x88001e00, + .hardcode_sw_threshold = false, + .run_preos = true, + }, + { /* DEVICE=PG503 SKU 200 ES */ + /* ptimer src frequency in hz */ + .ptimer_src_freq = 31250000, + + .probe = nvgpu_pci_tegra_probe, + .remove = nvgpu_pci_tegra_remove, + + /* power management configuration */ + .railgate_delay_init = 500, + .can_railgate_init = false, + .can_elpg_init = false, + .enable_elpg = false, + .enable_elcg = false, + .enable_slcg = false, + .enable_blcg = false, + .enable_mscg = false, + .can_slcg = false, + .can_blcg = false, + .can_elcg = false, + + .disable_aspm = true, + + /* power management callbacks */ + .is_railgated = nvgpu_pci_tegra_is_railgated, + .clk_round_rate = nvgpu_pci_clk_round_rate, + + .ch_wdt_timeout_ms = 7000, + + .honors_aperture = true, + .dma_mask = DMA_BIT_MASK(40), + .vbios_min_version = 0x88001e00, + .hardcode_sw_threshold = false, + .run_preos = true, + }, + { + /* ptimer src frequency in hz */ + .ptimer_src_freq = 31250000, + + .probe = nvgpu_pci_tegra_probe, + .remove = nvgpu_pci_tegra_remove, + + /* power management configuration */ + .railgate_delay_init = 500, + .can_railgate_init = false, + .can_elpg_init = false, + .enable_elpg = false, + .enable_elcg = false, + .enable_slcg = false, + .enable_blcg = false, + .enable_mscg = false, + .can_slcg = false, + .can_blcg = false, + .can_elcg = false, + + .disable_aspm = true, + + /* power management callbacks */ + .is_railgated = nvgpu_pci_tegra_is_railgated, + .clk_round_rate = nvgpu_pci_clk_round_rate, + + .ch_wdt_timeout_ms = 7000, + + .honors_aperture = true, + .dma_mask = DMA_BIT_MASK(40), + .vbios_min_version = 0x88000126, + .hardcode_sw_threshold = false, + .run_preos = true, + .has_syncpoints = true, + }, + { /* SKU250 */ + /* ptimer src frequency in hz */ + .ptimer_src_freq = 31250000, + + .probe = nvgpu_pci_tegra_probe, + .remove = nvgpu_pci_tegra_remove, + + /* power management configuration */ + .railgate_delay_init = 500, + .can_railgate_init = false, + .can_elpg_init = false, + .enable_elpg = false, + .enable_elcg = false, + .enable_slcg = true, + .enable_blcg = true, + .enable_mscg = false, + .can_slcg = true, + .can_blcg = true, + .can_elcg = false, + + .disable_aspm = true, + + /* power management callbacks */ + .is_railgated = nvgpu_pci_tegra_is_railgated, + .clk_round_rate = nvgpu_pci_clk_round_rate, + + .ch_wdt_timeout_ms = 7000, + + .honors_aperture = true, + .dma_mask = DMA_BIT_MASK(40), + .vbios_min_version = 0x1, + .hardcode_sw_threshold = false, + .run_preos = true, + .has_syncpoints = true, + }, + { /* SKU 0x1e3f */ + /* ptimer src frequency in hz */ + .ptimer_src_freq = 31250000, + + .probe = nvgpu_pci_tegra_probe, + .remove = nvgpu_pci_tegra_remove, + + /* power management configuration */ + .railgate_delay_init = 500, + .can_railgate_init = false, + .can_elpg_init = false, + .enable_elpg = false, + .enable_elcg = false, + .enable_slcg = false, + .enable_blcg = false, + .enable_mscg = false, + .can_slcg = false, + .can_blcg = false, + .can_elcg = false, + + .disable_aspm = true, + + /* power management callbacks */ + .is_railgated = nvgpu_pci_tegra_is_railgated, + .clk_round_rate = nvgpu_pci_clk_round_rate, + + /* + * WAR: PCIE X1 is very slow, set to very high value till nvlink is up + */ + .ch_wdt_timeout_ms = 30000, + + .honors_aperture = true, + .dma_mask = DMA_BIT_MASK(40), + .vbios_min_version = 0x1, + .hardcode_sw_threshold = false, + .unified_memory = false, + }, + +}; + +static struct pci_device_id nvgpu_pci_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1c35), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16, + .driver_data = 0, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1c36), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16, + .driver_data = 1, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1c37), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16, + .driver_data = 2, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1c75), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16, + .driver_data = 3, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1db1), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16, + .driver_data = 4, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1db0), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16, + .driver_data = 5, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1dbe), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16, + .driver_data = 6, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1df1), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16, + .driver_data = 7, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x1e3f), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16, + .driver_data = 8, + }, + {} +}; + +static irqreturn_t nvgpu_pci_isr(int irq, void *dev_id) +{ + struct gk20a *g = dev_id; + irqreturn_t ret_stall; + irqreturn_t ret_nonstall; + + ret_stall = nvgpu_intr_stall(g); + ret_nonstall = nvgpu_intr_nonstall(g); + +#if defined(CONFIG_PCI_MSI) + /* Send MSI EOI */ + if (g->ops.xve.rearm_msi && g->msi_enabled) + g->ops.xve.rearm_msi(g); +#endif + + return (ret_stall == IRQ_NONE) ? ret_nonstall : IRQ_WAKE_THREAD; +} + +static irqreturn_t nvgpu_pci_intr_thread(int irq, void *dev_id) +{ + struct gk20a *g = dev_id; + + return nvgpu_intr_thread_stall(g); +} + +static int nvgpu_pci_init_support(struct pci_dev *pdev) +{ + int err = 0; + struct gk20a *g = get_gk20a(&pdev->dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct device *dev = &pdev->dev; + + l->regs = nvgpu_devm_ioremap(dev, pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + if (IS_ERR(l->regs)) { + nvgpu_err(g, "failed to remap gk20a registers"); + err = PTR_ERR(l->regs); + goto fail; + } + + l->regs_bus_addr = pci_resource_start(pdev, 0); + if (!l->regs_bus_addr) { + nvgpu_err(g, "failed to read register bus offset"); + err = -ENODEV; + goto fail; + } + + l->bar1 = nvgpu_devm_ioremap(dev, pci_resource_start(pdev, 1), + pci_resource_len(pdev, 1)); + if (IS_ERR(l->bar1)) { + nvgpu_err(g, "failed to remap gk20a bar1"); + err = PTR_ERR(l->bar1); + goto fail; + } + + err = nvgpu_init_sim_support_linux_pci(g); + if (err) + goto fail; + err = nvgpu_init_sim_support_pci(g); + if (err) + goto fail_sim; + + nvgpu_pci_init_usermode_support(l); + + return 0; + + fail_sim: + nvgpu_remove_sim_support_linux_pci(g); + fail: + if (l->regs) + l->regs = NULL; + + if (l->bar1) + l->bar1 = NULL; + + return err; +} + +static char *nvgpu_pci_devnode(struct device *dev, umode_t *mode) +{ + if (mode) + *mode = S_IRUGO | S_IWUGO; + return kasprintf(GFP_KERNEL, "nvgpu-pci/%s", dev_name(dev)); +} + +static struct class nvgpu_pci_class = { + .owner = THIS_MODULE, + .name = "nvidia-pci-gpu", + .devnode = nvgpu_pci_devnode, +}; + +#ifdef CONFIG_PM +static int nvgpu_pci_pm_runtime_resume(struct device *dev) +{ + return gk20a_pm_finalize_poweron(dev); +} + +static int nvgpu_pci_pm_runtime_suspend(struct device *dev) +{ + return 0; +} + +static int nvgpu_pci_pm_resume(struct device *dev) +{ + return gk20a_pm_finalize_poweron(dev); +} + +static int nvgpu_pci_pm_suspend(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops nvgpu_pci_pm_ops = { + .runtime_resume = nvgpu_pci_pm_runtime_resume, + .runtime_suspend = nvgpu_pci_pm_runtime_suspend, + .resume = nvgpu_pci_pm_resume, + .suspend = nvgpu_pci_pm_suspend, +}; +#endif + +static int nvgpu_pci_pm_init(struct device *dev) +{ +#ifdef CONFIG_PM + struct gk20a *g = get_gk20a(dev); + + if (!nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE)) { + pm_runtime_disable(dev); + } else { + if (g->railgate_delay) + pm_runtime_set_autosuspend_delay(dev, + g->railgate_delay); + + /* + * set gpu dev's use_autosuspend flag to allow + * runtime power management of GPU + */ + pm_runtime_use_autosuspend(dev); + + /* + * runtime PM for PCI devices is forbidden + * by default, so unblock RTPM of GPU + */ + pm_runtime_put_noidle(dev); + pm_runtime_allow(dev); + } +#endif + return 0; +} + +static int nvgpu_pci_pm_deinit(struct device *dev) +{ +#ifdef CONFIG_PM + struct gk20a *g = get_gk20a(dev); + + if (!nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE)) + pm_runtime_enable(dev); + else + pm_runtime_forbid(dev); +#endif + return 0; +} + +static int nvgpu_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *pent) +{ + struct gk20a_platform *platform = NULL; + struct nvgpu_os_linux *l; + struct gk20a *g; + int err; + char nodefmt[64]; + struct device_node *np; + + /* make sure driver_data is a sane index */ + if (pent->driver_data >= sizeof(nvgpu_pci_device) / + sizeof(nvgpu_pci_device[0])) { + return -EINVAL; + } + + l = kzalloc(sizeof(*l), GFP_KERNEL); + if (!l) { + dev_err(&pdev->dev, "couldn't allocate gk20a support"); + return -ENOMEM; + } + + hash_init(l->ecc_sysfs_stats_htable); + + g = &l->g; + + g->log_mask = NVGPU_DEFAULT_DBG_MASK; + + nvgpu_init_gk20a(g); + + nvgpu_kmem_init(g); + + /* Allocate memory to hold platform data*/ + platform = (struct gk20a_platform *)nvgpu_kzalloc( g, + sizeof(struct gk20a_platform)); + if (!platform) { + dev_err(&pdev->dev, "couldn't allocate platform data"); + err = -ENOMEM; + goto err_free_l; + } + + /* copy detected device data to allocated platform space*/ + memcpy((void *)platform, (void *)&nvgpu_pci_device[pent->driver_data], + sizeof(struct gk20a_platform)); + + pci_set_drvdata(pdev, platform); + + err = nvgpu_init_enabled_flags(g); + if (err) + goto err_free_platform; + + platform->g = g; + l->dev = &pdev->dev; + + np = nvgpu_get_node(g); + if (of_dma_is_coherent(np)) { + __nvgpu_set_enabled(g, NVGPU_USE_COHERENT_SYSMEM, true); + __nvgpu_set_enabled(g, NVGPU_SUPPORT_IO_COHERENCE, true); + } + + err = pci_enable_device(pdev); + if (err) + goto err_free_platform; + pci_set_master(pdev); + + g->pci_vendor_id = pdev->vendor; + g->pci_device_id = pdev->device; + g->pci_subsystem_vendor_id = pdev->subsystem_vendor; + g->pci_subsystem_device_id = pdev->subsystem_device; + g->pci_class = (pdev->class >> 8) & 0xFFFFU; // we only want base/sub + g->pci_revision = pdev->revision; + + g->ina3221_dcb_index = platform->ina3221_dcb_index; + g->ina3221_i2c_address = platform->ina3221_i2c_address; + g->ina3221_i2c_port = platform->ina3221_i2c_port; + g->hardcode_sw_threshold = platform->hardcode_sw_threshold; + +#if defined(CONFIG_PCI_MSI) + err = pci_enable_msi(pdev); + if (err) { + nvgpu_err(g, + "MSI could not be enabled, falling back to legacy"); + g->msi_enabled = false; + } else + g->msi_enabled = true; +#endif + + g->irq_stall = pdev->irq; + g->irq_nonstall = pdev->irq; + if (g->irq_stall < 0) { + err = -ENXIO; + goto err_disable_msi; + } + + err = devm_request_threaded_irq(&pdev->dev, + g->irq_stall, + nvgpu_pci_isr, + nvgpu_pci_intr_thread, +#if defined(CONFIG_PCI_MSI) + g->msi_enabled ? 0 : +#endif + IRQF_SHARED, "nvgpu", g); + if (err) { + nvgpu_err(g, + "failed to request irq @ %d", g->irq_stall); + goto err_disable_msi; + } + disable_irq(g->irq_stall); + + err = nvgpu_pci_init_support(pdev); + if (err) + goto err_free_irq; + + if (strchr(dev_name(&pdev->dev), '%')) { + nvgpu_err(g, "illegal character in device name"); + err = -EINVAL; + goto err_free_irq; + } + + snprintf(nodefmt, sizeof(nodefmt), + PCI_INTERFACE_NAME, dev_name(&pdev->dev)); + + err = nvgpu_probe(g, "gpu_pci", nodefmt, &nvgpu_pci_class); + if (err) + goto err_free_irq; + + err = nvgpu_pci_pm_init(&pdev->dev); + if (err) { + nvgpu_err(g, "pm init failed"); + goto err_free_irq; + } + + err = nvgpu_nvlink_probe(g); + /* + * ENODEV is a legal error which means there is no NVLINK + * any other error is fatal + */ + if (err) { + if (err != -ENODEV) { + nvgpu_err(g, "fatal error probing nvlink, bailing out"); + goto err_free_irq; + } + /* Enable Semaphore SHIM on nvlink only for now. */ + __nvgpu_set_enabled(g, NVGPU_SUPPORT_NVLINK, false); + __nvgpu_set_enabled(g, NVGPU_HAS_SYNCPOINTS, false); + } else { + err = nvgpu_nvhost_syncpt_init(g); + if (err) { + if (err != -ENOSYS) { + nvgpu_err(g, "syncpt init failed"); + goto err_free_irq; + } + } + } + + return 0; + +err_free_irq: + nvgpu_free_irq(g); +err_disable_msi: +#if defined(CONFIG_PCI_MSI) + if (g->msi_enabled) + pci_disable_msi(pdev); +#endif +err_free_platform: + nvgpu_kfree(g, platform); +err_free_l: + kfree(l); + return err; +} + +static void nvgpu_pci_remove(struct pci_dev *pdev) +{ + struct gk20a *g = get_gk20a(&pdev->dev); + struct device *dev = dev_from_gk20a(g); + int err; + + /* no support yet for unbind if DGPU is in VGPU mode */ + if (gk20a_gpu_is_virtual(dev)) + return; + + err = nvgpu_nvlink_deinit(g); + WARN(err, "gpu failed to remove nvlink"); + + gk20a_driver_start_unload(g); + + err = nvgpu_quiesce(g); + /* TODO: handle failure to idle */ + WARN(err, "gpu failed to idle during driver removal"); + + nvgpu_free_irq(g); + + nvgpu_remove(dev, &nvgpu_pci_class); + +#if defined(CONFIG_PCI_MSI) + if (g->msi_enabled) + pci_disable_msi(pdev); + else { + /* IRQ does not need to be enabled in MSI as the line is not + * shared + */ + enable_irq(g->irq_stall); + } +#endif + nvgpu_pci_pm_deinit(&pdev->dev); + + /* free allocated platform data space */ + gk20a_get_platform(&pdev->dev)->g = NULL; + nvgpu_kfree(g, gk20a_get_platform(&pdev->dev)); + + gk20a_put(g); +} + +static struct pci_driver nvgpu_pci_driver = { + .name = "nvgpu", + .id_table = nvgpu_pci_table, + .probe = nvgpu_pci_probe, + .remove = nvgpu_pci_remove, +#ifdef CONFIG_PM + .driver.pm = &nvgpu_pci_pm_ops, +#endif +}; + +int __init nvgpu_pci_init(void) +{ + int ret; + + ret = class_register(&nvgpu_pci_class); + if (ret) + return ret; + + return pci_register_driver(&nvgpu_pci_driver); +} + +void __exit nvgpu_pci_exit(void) +{ + pci_unregister_driver(&nvgpu_pci_driver); + class_unregister(&nvgpu_pci_class); +} diff --git a/include/os/linux/pci.h b/include/os/linux/pci.h new file mode 100644 index 0000000..cc6b77b --- /dev/null +++ b/include/os/linux/pci.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef NVGPU_PCI_H +#define NVGPU_PCI_H + +#ifdef CONFIG_GK20A_PCI +int nvgpu_pci_init(void); +void nvgpu_pci_exit(void); +#else +static inline int nvgpu_pci_init(void) { return 0; } +static inline void nvgpu_pci_exit(void) {} +#endif + +#endif diff --git a/include/os/linux/pci_usermode.c b/include/os/linux/pci_usermode.c new file mode 100644 index 0000000..270b834 --- /dev/null +++ b/include/os/linux/pci_usermode.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include + +#include + +#include "os_linux.h" + +void nvgpu_pci_init_usermode_support(struct nvgpu_os_linux *l) +{ + l->usermode_regs = l->regs + usermode_cfg0_r(); + l->usermode_regs_saved = l->usermode_regs; +} diff --git a/include/os/linux/pci_usermode.h b/include/os/linux/pci_usermode.h new file mode 100644 index 0000000..25a08d2 --- /dev/null +++ b/include/os/linux/pci_usermode.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __NVGPU_PCI_USERMODE_H__ +#define __NVGPU_PCI_USERMODE_H__ + +struct nvgpu_os_linux; + +void nvgpu_pci_init_usermode_support(struct nvgpu_os_linux *l); + +#endif diff --git a/include/os/linux/platform_gk20a.h b/include/os/linux/platform_gk20a.h new file mode 100644 index 0000000..adec860 --- /dev/null +++ b/include/os/linux/platform_gk20a.h @@ -0,0 +1,329 @@ +/* + * GK20A Platform (SoC) Interface + * + * Copyright (c) 2014-2019, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef _GK20A_PLATFORM_H_ +#define _GK20A_PLATFORM_H_ + +#include + +#include +#include + +#define GK20A_CLKS_MAX 4 + +struct gk20a; +struct channel_gk20a; +struct gr_ctx_buffer_desc; +struct gk20a_scale_profile; + +struct secure_page_buffer { + void (*destroy)(struct gk20a *, struct secure_page_buffer *); + size_t size; + dma_addr_t phys; + size_t used; +}; + +struct gk20a_platform { + /* Populated by the gk20a driver before probing the platform. */ + struct gk20a *g; + + /* Should be populated at probe. */ + bool can_railgate_init; + + /* Should be populated at probe. */ + bool can_tpc_powergate; + + /* Should be populated at probe. */ + bool can_elpg_init; + + /* Should be populated at probe. */ + bool has_syncpoints; + + /* channel limit after which to start aggressive sync destroy */ + unsigned int aggressive_sync_destroy_thresh; + + /* flag to set sync destroy aggressiveness */ + bool aggressive_sync_destroy; + + /* set if ASPM should be disabled on boot; only makes sense for PCI */ + bool disable_aspm; + + /* Set if the platform can unify the small/large address spaces. */ + bool unify_address_spaces; + + /* Clock configuration is stored here. Platform probe is responsible + * for filling this data. */ + struct clk *clk[GK20A_CLKS_MAX]; + int num_clks; + int maxmin_clk_id; + +#ifdef CONFIG_RESET_CONTROLLER + /* Reset control for device */ + struct reset_control *reset_control; +#endif + /* valid TPC-MASK */ + u32 valid_tpc_mask[MAX_TPC_PG_CONFIGS]; + + /* Delay before rail gated */ + int railgate_delay_init; + + /* init value for slowdown factor */ + u8 ldiv_slowdown_factor_init; + + /* Second Level Clock Gating: true = enable false = disable */ + bool enable_slcg; + + /* Block Level Clock Gating: true = enable flase = disable */ + bool enable_blcg; + + /* Engine Level Clock Gating: true = enable flase = disable */ + bool enable_elcg; + + /* Should be populated at probe. */ + bool can_slcg; + + /* Should be populated at probe. */ + bool can_blcg; + + /* Should be populated at probe. */ + bool can_elcg; + + /* Engine Level Power Gating: true = enable flase = disable */ + bool enable_elpg; + + /* Adaptative ELPG: true = enable flase = disable */ + bool enable_aelpg; + + /* PMU Perfmon: true = enable false = disable */ + bool enable_perfmon; + + /* Memory System Clock Gating: true = enable flase = disable*/ + bool enable_mscg; + + /* Timeout for per-channel watchdog (in mS) */ + u32 ch_wdt_timeout_ms; + + /* Disable big page support */ + bool disable_bigpage; + + /* + * gk20a_do_idle() API can take GPU either into rail gate or CAR reset + * This flag can be used to force CAR reset case instead of rail gate + */ + bool force_reset_in_do_idle; + + /* guest/vm id, needed for IPA to PA transation */ + int vmid; + + /* Initialize the platform interface of the gk20a driver. + * + * The platform implementation of this function must + * - set the power and clocks of the gk20a device to a known + * state, and + * - populate the gk20a_platform structure (a pointer to the + * structure can be obtained by calling gk20a_get_platform). + * + * After this function is finished, the driver will initialise + * pm runtime and genpd based on the platform configuration. + */ + int (*probe)(struct device *dev); + + /* Second stage initialisation - called once all power management + * initialisations are done. + */ + int (*late_probe)(struct device *dev); + + /* Remove device after power management has been done + */ + int (*remove)(struct device *dev); + + /* Poweron platform dependencies */ + int (*busy)(struct device *dev); + + /* Powerdown platform dependencies */ + void (*idle)(struct device *dev); + + /* Preallocated VPR buffer for kernel */ + size_t secure_buffer_size; + struct secure_page_buffer secure_buffer; + + /* Device is going to be suspended */ + int (*suspend)(struct device *); + + /* Device is going to be resumed */ + int (*resume)(struct device *); + + /* Called to turn off the device */ + int (*railgate)(struct device *dev); + + /* Called to turn on the device */ + int (*unrailgate)(struct device *dev); + struct nvgpu_mutex railgate_lock; + + /* Called to check state of device */ + bool (*is_railgated)(struct device *dev); + + /* get supported frequency list */ + int (*get_clk_freqs)(struct device *pdev, + unsigned long **freqs, int *num_freqs); + + /* clk related supported functions */ + long (*clk_round_rate)(struct device *dev, + unsigned long rate); + + /* Called to register GPCPLL with common clk framework */ + int (*clk_register)(struct gk20a *g); + + /* platform specific scale init quirks */ + void (*initscale)(struct device *dev); + + /* Postscale callback is called after frequency change */ + void (*postscale)(struct device *dev, + unsigned long freq); + + /* Pre callback is called before frequency change */ + void (*prescale)(struct device *dev); + + /* Set TPC_PG_MASK during probe */ + void (*set_tpc_pg_mask)(struct device *dev, u32 tpc_pg_mask); + + /* Devfreq governor name. If scaling is enabled, we request + * this governor to be used in scaling */ + const char *devfreq_governor; + + /* Quality of service notifier callback. If this is set, the scaling + * routines will register a callback to Qos. Each time we receive + * a new value, this callback gets called. */ + int (*qos_notify)(struct notifier_block *nb, + unsigned long n, void *p); + + /* Called as part of debug dump. If the gpu gets hung, this function + * is responsible for delivering all necessary debug data of other + * hw units which may interact with the gpu without direct supervision + * of the CPU. + */ + void (*dump_platform_dependencies)(struct device *dev); + + /* Defined when SMMU stage-2 is enabled, and we need to use physical + * addresses (not IPA). This is the case for GV100 nvlink in HV+L + * configuration, when dGPU is in pass-through mode. + */ + u64 (*phys_addr)(struct gk20a *g, u64 ipa); + + /* Callbacks to assert/deassert GPU reset */ + int (*reset_assert)(struct device *dev); + int (*reset_deassert)(struct device *dev); + struct clk *clk_reset; + struct dvfs_rail *gpu_rail; + + bool virtual_dev; +#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION + void *vgpu_priv; +#endif + /* source frequency for ptimer in hz */ + u32 ptimer_src_freq; + +#ifdef CONFIG_NVGPU_SUPPORT_CDE + bool has_cde; +#endif + + /* soc name for finding firmware files */ + const char *soc_name; + + /* false if vidmem aperture actually points to sysmem */ + bool honors_aperture; + /* unified or split memory with separate vidmem? */ + bool unified_memory; + /* WAR for gm20b chips. */ + bool force_128K_pmu_vm; + + /* + * DMA mask for Linux (both coh and non-coh). If not set defaults to + * 0x3ffffffff (i.e a 34 bit mask). + */ + u64 dma_mask; + + /* minimum supported VBIOS version */ + u32 vbios_min_version; + + /* true if we run preos microcode on this board */ + bool run_preos; + + /* true if we need to program sw threshold for + * power limits + */ + bool hardcode_sw_threshold; + + /* i2c device index, port and address for INA3221 */ + u32 ina3221_dcb_index; + u32 ina3221_i2c_address; + u32 ina3221_i2c_port; + + /* stream id to use */ + u32 ltc_streamid; + + /* synchronized access to platform->clk_get_freqs */ + struct nvgpu_mutex clk_get_freq_lock; +}; + +static inline struct gk20a_platform *gk20a_get_platform( + struct device *dev) +{ + return (struct gk20a_platform *)dev_get_drvdata(dev); +} + +#ifdef CONFIG_TEGRA_GK20A +extern struct gk20a_platform gm20b_tegra_platform; +extern struct gk20a_platform gp10b_tegra_platform; +extern struct gk20a_platform gv11b_tegra_platform; +#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION +extern struct gk20a_platform vgpu_tegra_platform; +extern struct gk20a_platform gv11b_vgpu_tegra_platform; +#endif +#endif + +int gk20a_tegra_busy(struct device *dev); +void gk20a_tegra_idle(struct device *dev); +void gk20a_tegra_debug_dump(struct device *pdev); + +static inline struct gk20a *get_gk20a(struct device *dev) +{ + return gk20a_get_platform(dev)->g; +} +static inline struct gk20a *gk20a_from_dev(struct device *dev) +{ + if (!dev) + return NULL; + + return ((struct gk20a_platform *)dev_get_drvdata(dev))->g; +} +static inline bool gk20a_gpu_is_virtual(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + + return platform->virtual_dev; +} + +static inline int support_gk20a_pmu(struct device *dev) +{ + if (IS_ENABLED(CONFIG_GK20A_PMU)) { + /* gPMU is not supported for vgpu */ + return !gk20a_gpu_is_virtual(dev); + } + + return 0; +} + +#endif diff --git a/include/os/linux/platform_gk20a_tegra.c b/include/os/linux/platform_gk20a_tegra.c new file mode 100644 index 0000000..c39e4f0 --- /dev/null +++ b/include/os/linux/platform_gk20a_tegra.c @@ -0,0 +1,966 @@ +/* + * GK20A Tegra Platform Interface + * + * Copyright (c) 2014-2019, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_TEGRA_DVFS) +#include +#endif +#include +#include +#include +#if defined(CONFIG_COMMON_CLK) +#include +#endif +#ifdef CONFIG_TEGRA_BWMGR +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "gm20b/clk_gm20b.h" + +#include "scale.h" +#include "platform_gk20a.h" +#include "clk.h" +#include "os_linux.h" + +#include "../../../arch/arm/mach-tegra/iomap.h" +#include + +#define TEGRA_GK20A_BW_PER_FREQ 32 +#define TEGRA_GM20B_BW_PER_FREQ 64 +#define TEGRA_DDR3_BW_PER_FREQ 16 +#define TEGRA_DDR4_BW_PER_FREQ 16 +#define MC_CLIENT_GPU 34 +#define PMC_GPU_RG_CNTRL_0 0x2d4 + +#ifdef CONFIG_COMMON_CLK +#define GPU_RAIL_NAME "vdd-gpu" +#else +#define GPU_RAIL_NAME "vdd_gpu" +#endif + +extern struct device tegra_vpr_dev; + +#ifdef CONFIG_TEGRA_BWMGR +struct gk20a_emc_params { + unsigned long bw_ratio; + unsigned long freq_last_set; + struct tegra_bwmgr_client *bwmgr_cl; +}; +#else +struct gk20a_emc_params { + unsigned long bw_ratio; + unsigned long freq_last_set; +}; +#endif + +#define MHZ_TO_HZ(x) ((x) * 1000000) +#define HZ_TO_MHZ(x) ((x) / 1000000) + +static void gk20a_tegra_secure_page_destroy(struct gk20a *g, + struct secure_page_buffer *secure_buffer) +{ + DEFINE_DMA_ATTRS(attrs); + dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, __DMA_ATTR(attrs)); + dma_free_attrs(&tegra_vpr_dev, secure_buffer->size, + (void *)(uintptr_t)secure_buffer->phys, + secure_buffer->phys, __DMA_ATTR(attrs)); + + secure_buffer->destroy = NULL; +} + +static int gk20a_tegra_secure_alloc(struct gk20a *g, + struct gr_ctx_buffer_desc *desc, + size_t size) +{ + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct secure_page_buffer *secure_buffer = &platform->secure_buffer; + dma_addr_t phys; + struct sg_table *sgt; + struct page *page; + int err = 0; + size_t aligned_size = PAGE_ALIGN(size); + + if (nvgpu_mem_is_valid(&desc->mem)) + return 0; + + /* We ran out of preallocated memory */ + if (secure_buffer->used + aligned_size > secure_buffer->size) { + nvgpu_err(platform->g, "failed to alloc %zu bytes of VPR, %zu/%zu used", + size, secure_buffer->used, secure_buffer->size); + return -ENOMEM; + } + + phys = secure_buffer->phys + secure_buffer->used; + + sgt = nvgpu_kzalloc(platform->g, sizeof(*sgt)); + if (!sgt) { + nvgpu_err(platform->g, "failed to allocate memory"); + return -ENOMEM; + } + err = sg_alloc_table(sgt, 1, GFP_KERNEL); + if (err) { + nvgpu_err(platform->g, "failed to allocate sg_table"); + goto fail_sgt; + } + page = phys_to_page(phys); + sg_set_page(sgt->sgl, page, size, 0); + /* This bypasses SMMU for VPR during gmmu_map. */ + sg_dma_address(sgt->sgl) = 0; + + desc->destroy = NULL; + + desc->mem.priv.sgt = sgt; + desc->mem.size = size; + desc->mem.aperture = APERTURE_SYSMEM; + + secure_buffer->used += aligned_size; + + return err; + +fail_sgt: + nvgpu_kfree(platform->g, sgt); + return err; +} + +/* + * gk20a_tegra_get_emc_rate() + * + * This function returns the minimum emc clock based on gpu frequency + */ + +static unsigned long gk20a_tegra_get_emc_rate(struct gk20a *g, + struct gk20a_emc_params *emc_params) +{ + unsigned long gpu_freq, gpu_fmax_at_vmin; + unsigned long emc_rate, emc_scale; + + gpu_freq = clk_get_rate(g->clk.tegra_clk); + gpu_fmax_at_vmin = tegra_dvfs_get_fmax_at_vmin_safe_t( + clk_get_parent(g->clk.tegra_clk)); + + /* When scaling emc, account for the gpu load when the + * gpu frequency is less than or equal to fmax@vmin. */ + if (gpu_freq <= gpu_fmax_at_vmin) + emc_scale = min(g->pmu.load_avg, g->emc3d_ratio); + else + emc_scale = g->emc3d_ratio; + + emc_rate = + (HZ_TO_MHZ(gpu_freq) * emc_params->bw_ratio * emc_scale) / 1000; + + return MHZ_TO_HZ(emc_rate); +} + +/* + * gk20a_tegra_prescale(profile, freq) + * + * This function informs EDP about changed constraints. + */ + +static void gk20a_tegra_prescale(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + u32 avg = 0; + + nvgpu_pmu_load_norm(g, &avg); + tegra_edp_notify_gpu_load(avg, clk_get_rate(g->clk.tegra_clk)); +} + +/* + * gk20a_tegra_calibrate_emc() + * + */ + +static void gk20a_tegra_calibrate_emc(struct device *dev, + struct gk20a_emc_params *emc_params) +{ + enum tegra_chipid cid = tegra_get_chip_id(); + long gpu_bw, emc_bw; + + /* store gpu bw based on soc */ + switch (cid) { + case TEGRA210: + gpu_bw = TEGRA_GM20B_BW_PER_FREQ; + break; + case TEGRA124: + case TEGRA132: + gpu_bw = TEGRA_GK20A_BW_PER_FREQ; + break; + default: + gpu_bw = 0; + break; + } + + /* TODO detect DDR type. + * Okay for now since DDR3 and DDR4 have the same BW ratio */ + emc_bw = TEGRA_DDR3_BW_PER_FREQ; + + /* Calculate the bandwidth ratio of gpu_freq <-> emc_freq + * NOTE the ratio must come out as an integer */ + emc_params->bw_ratio = (gpu_bw / emc_bw); +} + +#ifdef CONFIG_TEGRA_BWMGR +#ifdef CONFIG_TEGRA_DVFS +static void gm20b_bwmgr_set_rate(struct gk20a_platform *platform, bool enb) +{ + struct gk20a_scale_profile *profile = platform->g->scale_profile; + struct gk20a_emc_params *params; + unsigned long rate; + + if (!profile || !profile->private_data) + return; + + params = (struct gk20a_emc_params *)profile->private_data; + rate = (enb) ? params->freq_last_set : 0; + tegra_bwmgr_set_emc(params->bwmgr_cl, rate, TEGRA_BWMGR_SET_EMC_FLOOR); +} +#endif + +static void gm20b_tegra_postscale(struct device *dev, unsigned long freq) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + struct gk20a_emc_params *emc_params; + unsigned long emc_rate; + + if (!profile || !profile->private_data) + return; + + emc_params = profile->private_data; + emc_rate = gk20a_tegra_get_emc_rate(get_gk20a(dev), emc_params); + + if (emc_rate > tegra_bwmgr_get_max_emc_rate()) + emc_rate = tegra_bwmgr_get_max_emc_rate(); + + emc_params->freq_last_set = emc_rate; + if (platform->is_railgated && platform->is_railgated(dev)) + return; + + tegra_bwmgr_set_emc(emc_params->bwmgr_cl, emc_rate, + TEGRA_BWMGR_SET_EMC_FLOOR); + +} + +#endif + +#if defined(CONFIG_TEGRA_DVFS) +/* + * gk20a_tegra_is_railgated() + * + * Check status of gk20a power rail + */ + +static bool gk20a_tegra_is_railgated(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + struct gk20a_platform *platform = dev_get_drvdata(dev); + bool ret = false; + + if (!nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) + ret = !tegra_dvfs_is_rail_up(platform->gpu_rail); + + return ret; +} + +/* + * gm20b_tegra_railgate() + * + * Gate (disable) gm20b power rail + */ + +static int gm20b_tegra_railgate(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + struct gk20a_platform *platform = dev_get_drvdata(dev); + int ret = 0; + + if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL) || + !tegra_dvfs_is_rail_up(platform->gpu_rail)) + return 0; + + tegra_mc_flush(MC_CLIENT_GPU); + + udelay(10); + + /* enable clamp */ + tegra_pmc_writel_relaxed(0x1, PMC_GPU_RG_CNTRL_0); + tegra_pmc_readl(PMC_GPU_RG_CNTRL_0); + + udelay(10); + + platform->reset_assert(dev); + + udelay(10); + + /* + * GPCPLL is already disabled before entering this function; reference + * clocks are enabled until now - disable them just before rail gating + */ + clk_disable_unprepare(platform->clk_reset); + clk_disable_unprepare(platform->clk[0]); + clk_disable_unprepare(platform->clk[1]); + if (platform->clk[3]) + clk_disable_unprepare(platform->clk[3]); + + udelay(10); + + tegra_soctherm_gpu_tsens_invalidate(1); + + if (tegra_dvfs_is_rail_up(platform->gpu_rail)) { + ret = tegra_dvfs_rail_power_down(platform->gpu_rail); + if (ret) + goto err_power_off; + } else + pr_info("No GPU regulator?\n"); + +#ifdef CONFIG_TEGRA_BWMGR + gm20b_bwmgr_set_rate(platform, false); +#endif + + return 0; + +err_power_off: + nvgpu_err(platform->g, "Could not railgate GPU"); + return ret; +} + + +/* + * gm20b_tegra_unrailgate() + * + * Ungate (enable) gm20b power rail + */ + +static int gm20b_tegra_unrailgate(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct gk20a *g = platform->g; + int ret = 0; + bool first = false; + + if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) + return 0; + + ret = tegra_dvfs_rail_power_up(platform->gpu_rail); + if (ret) + return ret; + +#ifdef CONFIG_TEGRA_BWMGR + gm20b_bwmgr_set_rate(platform, true); +#endif + + tegra_soctherm_gpu_tsens_invalidate(0); + + if (!platform->clk_reset) { + platform->clk_reset = clk_get(dev, "gpu_gate"); + if (IS_ERR(platform->clk_reset)) { + nvgpu_err(g, "fail to get gpu reset clk"); + goto err_clk_on; + } + } + + if (!first) { + ret = clk_prepare_enable(platform->clk_reset); + if (ret) { + nvgpu_err(g, "could not turn on gpu_gate"); + goto err_clk_on; + } + + ret = clk_prepare_enable(platform->clk[0]); + if (ret) { + nvgpu_err(g, "could not turn on gpu pll"); + goto err_clk_on; + } + ret = clk_prepare_enable(platform->clk[1]); + if (ret) { + nvgpu_err(g, "could not turn on pwr clock"); + goto err_clk_on; + } + + if (platform->clk[3]) { + ret = clk_prepare_enable(platform->clk[3]); + if (ret) { + nvgpu_err(g, "could not turn on fuse clock"); + goto err_clk_on; + } + } + } + + udelay(10); + + platform->reset_assert(dev); + + udelay(10); + + tegra_pmc_writel_relaxed(0, PMC_GPU_RG_CNTRL_0); + tegra_pmc_readl(PMC_GPU_RG_CNTRL_0); + + udelay(10); + + clk_disable(platform->clk_reset); + platform->reset_deassert(dev); + clk_enable(platform->clk_reset); + + /* Flush MC after boot/railgate/SC7 */ + tegra_mc_flush(MC_CLIENT_GPU); + + udelay(10); + + tegra_mc_flush_done(MC_CLIENT_GPU); + + udelay(10); + + return 0; + +err_clk_on: + tegra_dvfs_rail_power_down(platform->gpu_rail); + + return ret; +} +#endif + + +static struct { + char *name; + unsigned long default_rate; +} tegra_gk20a_clocks[] = { + {"gpu_ref", UINT_MAX}, + {"pll_p_out5", 204000000}, + {"emc", UINT_MAX}, + {"fuse", UINT_MAX}, +}; + + + +/* + * gk20a_tegra_get_clocks() + * + * This function finds clocks in tegra platform and populates + * the clock information to gk20a platform data. + */ + +static int gk20a_tegra_get_clocks(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + char devname[16]; + unsigned int i; + int ret = 0; + + BUG_ON(GK20A_CLKS_MAX < ARRAY_SIZE(tegra_gk20a_clocks)); + + snprintf(devname, sizeof(devname), "tegra_%s", dev_name(dev)); + + platform->num_clks = 0; + for (i = 0; i < ARRAY_SIZE(tegra_gk20a_clocks); i++) { + long rate = tegra_gk20a_clocks[i].default_rate; + struct clk *c; + + c = clk_get_sys(devname, tegra_gk20a_clocks[i].name); + if (IS_ERR(c)) { + ret = PTR_ERR(c); + goto err_get_clock; + } + rate = clk_round_rate(c, rate); + clk_set_rate(c, rate); + platform->clk[i] = c; + } + platform->num_clks = i; + + return 0; + +err_get_clock: + + while (i--) + clk_put(platform->clk[i]); + return ret; +} + +#if defined(CONFIG_RESET_CONTROLLER) && defined(CONFIG_COMMON_CLK) +static int gm20b_tegra_reset_assert(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + + if (!platform->reset_control) { + WARN(1, "Reset control not initialized\n"); + return -ENOSYS; + } + + return reset_control_assert(platform->reset_control); +} + +static int gm20b_tegra_reset_deassert(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + + if (!platform->reset_control) { + WARN(1, "Reset control not initialized\n"); + return -ENOSYS; + } + + return reset_control_deassert(platform->reset_control); +} +#endif + +static void gk20a_tegra_scale_init(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + struct gk20a_emc_params *emc_params; + struct gk20a *g = platform->g; + + if (!profile) + return; + + if (profile->private_data) + return; + + emc_params = nvgpu_kzalloc(platform->g, sizeof(*emc_params)); + if (!emc_params) + return; + + emc_params->freq_last_set = -1; + gk20a_tegra_calibrate_emc(dev, emc_params); + +#ifdef CONFIG_TEGRA_BWMGR + emc_params->bwmgr_cl = tegra_bwmgr_register(TEGRA_BWMGR_CLIENT_GPU); + if (!emc_params->bwmgr_cl) { + nvgpu_log_info(g, "%s Missing GPU BWMGR client\n", __func__); + return; + } +#endif + + profile->private_data = emc_params; +} + +static void gk20a_tegra_scale_exit(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + struct gk20a_emc_params *emc_params; + + if (!profile) + return; + + emc_params = profile->private_data; +#ifdef CONFIG_TEGRA_BWMGR + tegra_bwmgr_unregister(emc_params->bwmgr_cl); +#endif + + nvgpu_kfree(platform->g, profile->private_data); +} + +void gk20a_tegra_debug_dump(struct device *dev) +{ +#ifdef CONFIG_TEGRA_GK20A_NVHOST + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a *g = platform->g; + + if (g->nvhost_dev) + nvgpu_nvhost_debug_dump_device(g->nvhost_dev); +#endif +} + +int gk20a_tegra_busy(struct device *dev) +{ +#ifdef CONFIG_TEGRA_GK20A_NVHOST + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a *g = platform->g; + + if (g->nvhost_dev) + return nvgpu_nvhost_module_busy_ext(g->nvhost_dev); +#endif + return 0; +} + +void gk20a_tegra_idle(struct device *dev) +{ +#ifdef CONFIG_TEGRA_GK20A_NVHOST + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a *g = platform->g; + + if (g->nvhost_dev) + nvgpu_nvhost_module_idle_ext(g->nvhost_dev); +#endif +} + +int gk20a_tegra_init_secure_alloc(struct gk20a_platform *platform) +{ + struct gk20a *g = platform->g; + struct secure_page_buffer *secure_buffer = &platform->secure_buffer; + DEFINE_DMA_ATTRS(attrs); + dma_addr_t iova; + + if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) + return 0; + + dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, __DMA_ATTR(attrs)); + (void)dma_alloc_attrs(&tegra_vpr_dev, platform->secure_buffer_size, &iova, + GFP_KERNEL, __DMA_ATTR(attrs)); + /* Some platforms disable VPR. In that case VPR allocations always + * fail. Just disable VPR usage in nvgpu in that case. */ + if (dma_mapping_error(&tegra_vpr_dev, iova)) + return 0; + + secure_buffer->size = platform->secure_buffer_size; + secure_buffer->phys = iova; + secure_buffer->destroy = gk20a_tegra_secure_page_destroy; + + g->ops.secure_alloc = gk20a_tegra_secure_alloc; + __nvgpu_set_enabled(g, NVGPU_SUPPORT_VPR, true); + + return 0; +} + +#ifdef CONFIG_COMMON_CLK +static struct clk *gk20a_clk_get(struct gk20a *g) +{ + if (!g->clk.tegra_clk) { + struct clk *clk, *clk_parent; + char clk_dev_id[32]; + struct device *dev = dev_from_gk20a(g); + + snprintf(clk_dev_id, 32, "tegra_%s", dev_name(dev)); + + clk = clk_get_sys(clk_dev_id, "gpu"); + if (IS_ERR(clk)) { + nvgpu_err(g, "fail to get tegra gpu clk %s/gpu\n", + clk_dev_id); + return NULL; + } + + clk_parent = clk_get_parent(clk); + if (IS_ERR_OR_NULL(clk_parent)) { + nvgpu_err(g, "fail to get tegra gpu clk parent%s/gpu\n", + clk_dev_id); + return NULL; + } + + g->clk.tegra_clk = clk; + g->clk.tegra_clk_parent = clk_parent; + } + + return g->clk.tegra_clk; +} + +static int gm20b_clk_prepare_ops(struct clk_hw *hw) +{ + struct clk_gk20a *clk = to_clk_gk20a(hw); + return gm20b_clk_prepare(clk); +} + +static void gm20b_clk_unprepare_ops(struct clk_hw *hw) +{ + struct clk_gk20a *clk = to_clk_gk20a(hw); + gm20b_clk_unprepare(clk); +} + +static int gm20b_clk_is_prepared_ops(struct clk_hw *hw) +{ + struct clk_gk20a *clk = to_clk_gk20a(hw); + return gm20b_clk_is_prepared(clk); +} + +static unsigned long gm20b_recalc_rate_ops(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_gk20a *clk = to_clk_gk20a(hw); + return gm20b_recalc_rate(clk, parent_rate); +} + +static int gm20b_gpcclk_set_rate_ops(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_gk20a *clk = to_clk_gk20a(hw); + return gm20b_gpcclk_set_rate(clk, rate, parent_rate); +} + +static long gm20b_round_rate_ops(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct clk_gk20a *clk = to_clk_gk20a(hw); + return gm20b_round_rate(clk, rate, parent_rate); +} + +static const struct clk_ops gm20b_clk_ops = { + .prepare = gm20b_clk_prepare_ops, + .unprepare = gm20b_clk_unprepare_ops, + .is_prepared = gm20b_clk_is_prepared_ops, + .recalc_rate = gm20b_recalc_rate_ops, + .set_rate = gm20b_gpcclk_set_rate_ops, + .round_rate = gm20b_round_rate_ops, +}; + +static int gm20b_register_gpcclk(struct gk20a *g) +{ + const char *parent_name = "pllg_ref"; + struct clk_gk20a *clk = &g->clk; + struct clk_init_data init; + struct clk *c; + int err = 0; + + /* make sure the clock is available */ + if (!gk20a_clk_get(g)) + return -ENOSYS; + + err = gm20b_init_clk_setup_sw(g); + if (err) + return err; + + init.name = "gpcclk"; + init.ops = &gm20b_clk_ops; + init.parent_names = &parent_name; + init.num_parents = 1; + init.flags = 0; + + /* Data in .init is copied by clk_register(), so stack variable OK */ + clk->hw.init = &init; + c = clk_register(dev_from_gk20a(g), &clk->hw); + if (IS_ERR(c)) { + nvgpu_err(g, "Failed to register GPCPLL clock"); + return -EINVAL; + } + + clk->g = g; + clk_register_clkdev(c, "gpcclk", "gpcclk"); + + return err; +} +#endif /* CONFIG_COMMON_CLK */ + +static int gk20a_tegra_probe(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct device_node *np = dev->of_node; + bool joint_xpu_rail = false; + int ret; + struct gk20a *g = platform->g; + +#ifdef CONFIG_COMMON_CLK + /* DVFS is not guaranteed to be initialized at the time of probe on + * kernels with Common Clock Framework enabled. + */ + if (!platform->gpu_rail) { + platform->gpu_rail = tegra_dvfs_get_rail_by_name(GPU_RAIL_NAME); + if (!platform->gpu_rail) { + nvgpu_log_info(g, "deferring probe no gpu_rail"); + return -EPROBE_DEFER; + } + } + + if (!tegra_dvfs_is_rail_ready(platform->gpu_rail)) { + nvgpu_log_info(g, "deferring probe gpu_rail not ready"); + return -EPROBE_DEFER; + } +#endif + +#ifdef CONFIG_TEGRA_GK20A_NVHOST + ret = nvgpu_get_nvhost_dev(platform->g); + if (ret) + return ret; +#endif + +#ifdef CONFIG_OF + joint_xpu_rail = of_property_read_bool(of_chosen, + "nvidia,tegra-joint_xpu_rail"); +#endif + + if (joint_xpu_rail) { + nvgpu_log_info(g, "XPU rails are joint\n"); + platform->can_railgate_init = false; + __nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, false); + } + + platform->g->clk.gpc_pll.id = GK20A_GPC_PLL; + if (tegra_get_chip_id() == TEGRA210) { + /* WAR for bug 1547668: Disable railgating and scaling + irrespective of platform data if the rework was not made. */ + np = of_find_node_by_path("/gpu-dvfs-rework"); + if (!(np && of_device_is_available(np))) { + platform->devfreq_governor = ""; + dev_warn(dev, "board does not support scaling"); + } + platform->g->clk.gpc_pll.id = GM20B_GPC_PLL_B1; + if (tegra_chip_get_revision() > TEGRA210_REVISION_A04p) + platform->g->clk.gpc_pll.id = GM20B_GPC_PLL_C1; + } + + if (tegra_get_chip_id() == TEGRA132) + platform->soc_name = "tegra13x"; + + gk20a_tegra_get_clocks(dev); + nvgpu_linux_init_clk_support(platform->g); + ret = gk20a_tegra_init_secure_alloc(platform); + if (ret) + return ret; + + if (platform->clk_register) { + ret = platform->clk_register(platform->g); + if (ret) + return ret; + } + + return 0; +} + +static int gk20a_tegra_late_probe(struct device *dev) +{ + return 0; +} + +static int gk20a_tegra_remove(struct device *dev) +{ + /* deinitialise tegra specific scaling quirks */ + gk20a_tegra_scale_exit(dev); + +#ifdef CONFIG_TEGRA_GK20A_NVHOST + nvgpu_free_nvhost_dev(get_gk20a(dev)); +#endif + + return 0; +} + +static int gk20a_tegra_suspend(struct device *dev) +{ + tegra_edp_notify_gpu_load(0, 0); + return 0; +} + +#if defined(CONFIG_COMMON_CLK) +static long gk20a_round_clk_rate(struct device *dev, unsigned long rate) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a *g = platform->g; + + /* make sure the clock is available */ + if (!gk20a_clk_get(g)) + return rate; + + return clk_round_rate(clk_get_parent(g->clk.tegra_clk), rate); +} + +static int gk20a_clk_get_freqs(struct device *dev, + unsigned long **freqs, int *num_freqs) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a *g = platform->g; + + /* make sure the clock is available */ + if (!gk20a_clk_get(g)) + return -ENOSYS; + + return tegra_dvfs_get_freqs(clk_get_parent(g->clk.tegra_clk), + freqs, num_freqs); +} +#endif + +struct gk20a_platform gm20b_tegra_platform = { + .has_syncpoints = true, + .aggressive_sync_destroy_thresh = 64, + + /* power management configuration */ + .railgate_delay_init = 500, + .can_railgate_init = true, + .can_elpg_init = true, + .enable_slcg = true, + .enable_blcg = true, + .enable_elcg = true, + .can_slcg = true, + .can_blcg = true, + .can_elcg = true, + .enable_elpg = true, + .enable_aelpg = true, + .enable_perfmon = true, + .ptimer_src_freq = 19200000, + + .force_reset_in_do_idle = false, + + .ch_wdt_timeout_ms = 5000, + + .probe = gk20a_tegra_probe, + .late_probe = gk20a_tegra_late_probe, + .remove = gk20a_tegra_remove, + /* power management callbacks */ + .suspend = gk20a_tegra_suspend, + +#if defined(CONFIG_TEGRA_DVFS) + .railgate = gm20b_tegra_railgate, + .unrailgate = gm20b_tegra_unrailgate, + .is_railgated = gk20a_tegra_is_railgated, +#endif + + .busy = gk20a_tegra_busy, + .idle = gk20a_tegra_idle, + +#if defined(CONFIG_RESET_CONTROLLER) && defined(CONFIG_COMMON_CLK) + .reset_assert = gm20b_tegra_reset_assert, + .reset_deassert = gm20b_tegra_reset_deassert, +#else + .reset_assert = gk20a_tegra_reset_assert, + .reset_deassert = gk20a_tegra_reset_deassert, +#endif + +#if defined(CONFIG_COMMON_CLK) + .clk_round_rate = gk20a_round_clk_rate, + .get_clk_freqs = gk20a_clk_get_freqs, +#endif + +#ifdef CONFIG_COMMON_CLK + .clk_register = gm20b_register_gpcclk, +#endif + + /* frequency scaling configuration */ + .initscale = gk20a_tegra_scale_init, + .prescale = gk20a_tegra_prescale, +#ifdef CONFIG_TEGRA_BWMGR + .postscale = gm20b_tegra_postscale, +#endif + .devfreq_governor = "nvhost_podgov", + .qos_notify = gk20a_scale_qos_notify, + + .dump_platform_dependencies = gk20a_tegra_debug_dump, + +#ifdef CONFIG_NVGPU_SUPPORT_CDE + .has_cde = true, +#endif + + .soc_name = "tegra21x", + + .unified_memory = true, + .dma_mask = DMA_BIT_MASK(34), + .force_128K_pmu_vm = true, + + .secure_buffer_size = 335872, +}; diff --git a/include/os/linux/platform_gk20a_tegra.h b/include/os/linux/platform_gk20a_tegra.h new file mode 100644 index 0000000..f7d5040 --- /dev/null +++ b/include/os/linux/platform_gk20a_tegra.h @@ -0,0 +1,23 @@ +/* + * GK20A Platform (SoC) Interface + * + * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef _NVGPU_PLATFORM_GK20A_TEGRA_H_ +#define _NVGPU_PLATFORM_GK20A_TEGRA_H_ + +struct gk20a_platform; + +int gk20a_tegra_init_secure_alloc(struct gk20a_platform *platform); + +#endif diff --git a/include/os/linux/platform_gp10b.h b/include/os/linux/platform_gp10b.h new file mode 100644 index 0000000..d256d12 --- /dev/null +++ b/include/os/linux/platform_gp10b.h @@ -0,0 +1,39 @@ +/* + * GP10B Platform (SoC) Interface + * + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _GP10B_PLATFORM_H_ +#define _GP10B_PLATFORM_H_ + +struct device; + +int gp10b_tegra_get_clocks(struct device *dev); +int gp10b_tegra_reset_assert(struct device *dev); +int gp10b_tegra_reset_deassert(struct device *dev); +void gp10b_tegra_scale_init(struct device *dev); +long gp10b_round_clk_rate(struct device *dev, unsigned long rate); +int gp10b_clk_get_freqs(struct device *dev, + unsigned long **freqs, int *num_freqs); +void gp10b_tegra_prescale(struct device *dev); +void gp10b_tegra_postscale(struct device *pdev, unsigned long freq); +#endif diff --git a/include/os/linux/platform_gp10b_tegra.c b/include/os/linux/platform_gp10b_tegra.c new file mode 100644 index 0000000..9bf8d63 --- /dev/null +++ b/include/os/linux/platform_gp10b_tegra.c @@ -0,0 +1,510 @@ +/* + * GP10B Tegra Platform Interface + * + * Copyright (c) 2014-2019, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "os_linux.h" + +#include "clk.h" + +#include "platform_gk20a.h" +#include "platform_gk20a_tegra.h" +#include "platform_gp10b.h" +#include "platform_gp10b_tegra.h" +#include "scale.h" + +/* Select every GP10B_FREQ_SELECT_STEP'th frequency from h/w table */ +#define GP10B_FREQ_SELECT_STEP 8 +/* Allow limited set of frequencies to be available */ +#define GP10B_NUM_SUPPORTED_FREQS 15 +/* Max number of freq supported in h/w */ +#define GP10B_MAX_SUPPORTED_FREQS 120 +static unsigned long +gp10b_freq_table[GP10B_MAX_SUPPORTED_FREQS / GP10B_FREQ_SELECT_STEP]; + +static bool freq_table_init_complete; +static int num_supported_freq; + +#define TEGRA_GP10B_BW_PER_FREQ 64 +#define TEGRA_DDR4_BW_PER_FREQ 16 + +#define EMC_BW_RATIO (TEGRA_GP10B_BW_PER_FREQ / TEGRA_DDR4_BW_PER_FREQ) + +#define GPCCLK_INIT_RATE 1000000000 + +static struct { + char *name; + unsigned long default_rate; +} tegra_gp10b_clocks[] = { + {"gpu", GPCCLK_INIT_RATE}, + {"gpu_sys", 204000000} }; + +/* + * gp10b_tegra_get_clocks() + * + * This function finds clocks in tegra platform and populates + * the clock information to gp10b platform data. + */ + +int gp10b_tegra_get_clocks(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + unsigned int i; + + platform->num_clks = 0; + for (i = 0; i < ARRAY_SIZE(tegra_gp10b_clocks); i++) { + long rate = tegra_gp10b_clocks[i].default_rate; + struct clk *c; + + c = clk_get(dev, tegra_gp10b_clocks[i].name); + if (IS_ERR(c)) { + nvgpu_err(platform->g, "cannot get clock %s", + tegra_gp10b_clocks[i].name); + } else { + clk_set_rate(c, rate); + platform->clk[i] = c; + } + } + platform->num_clks = i; + + if (platform->clk[0]) { + i = tegra_bpmp_dvfs_get_clk_id(dev->of_node, + tegra_gp10b_clocks[0].name); + if (i > 0) + platform->maxmin_clk_id = i; + } + + return 0; +} + +void gp10b_tegra_scale_init(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + struct tegra_bwmgr_client *bwmgr_handle; + + if (!profile) + return; + + if ((struct tegra_bwmgr_client *)profile->private_data) + return; + + bwmgr_handle = tegra_bwmgr_register(TEGRA_BWMGR_CLIENT_GPU); + if (!bwmgr_handle) + return; + + profile->private_data = (void *)bwmgr_handle; +} + +static void gp10b_tegra_scale_exit(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + + if (profile && profile->private_data) + tegra_bwmgr_unregister( + (struct tegra_bwmgr_client *)profile->private_data); +} + +static int gp10b_tegra_probe(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + bool joint_xpu_rail = false; + struct gk20a *g = platform->g; +#ifdef CONFIG_TEGRA_GK20A_NVHOST + int ret; + + ret = nvgpu_get_nvhost_dev(platform->g); + if (ret) + return ret; +#endif + + ret = gk20a_tegra_init_secure_alloc(platform); + if (ret) + return ret; + + platform->disable_bigpage = !device_is_iommuable(dev); + + platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close + = false; + platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close + = false; + + platform->g->gr.ctx_vars.force_preemption_gfxp = false; + platform->g->gr.ctx_vars.force_preemption_cilp = false; + +#ifdef CONFIG_OF + joint_xpu_rail = of_property_read_bool(of_chosen, + "nvidia,tegra-joint_xpu_rail"); +#endif + + if (joint_xpu_rail) { + nvgpu_log_info(g, "XPU rails are joint\n"); + platform->can_railgate_init = false; + __nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, false); + } + + gp10b_tegra_get_clocks(dev); + nvgpu_linux_init_clk_support(platform->g); + + nvgpu_mutex_init(&platform->clk_get_freq_lock); + + platform->g->ops.clk.support_clk_freq_controller = true; + + return 0; +} + +static int gp10b_tegra_late_probe(struct device *dev) +{ + return 0; +} + +static int gp10b_tegra_remove(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + + /* deinitialise tegra specific scaling quirks */ + gp10b_tegra_scale_exit(dev); + +#ifdef CONFIG_TEGRA_GK20A_NVHOST + nvgpu_free_nvhost_dev(get_gk20a(dev)); +#endif + + nvgpu_mutex_destroy(&platform->clk_get_freq_lock); + + return 0; +} + +static bool gp10b_tegra_is_railgated(struct device *dev) +{ + bool ret = false; + + if (tegra_bpmp_running()) + ret = !tegra_powergate_is_powered(TEGRA186_POWER_DOMAIN_GPU); + + return ret; +} + +static int gp10b_tegra_railgate(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + + /* remove emc frequency floor */ + if (profile) + tegra_bwmgr_set_emc( + (struct tegra_bwmgr_client *)profile->private_data, + 0, TEGRA_BWMGR_SET_EMC_FLOOR); + + if (tegra_bpmp_running() && + tegra_powergate_is_powered(TEGRA186_POWER_DOMAIN_GPU)) { + int i; + for (i = 0; i < platform->num_clks; i++) { + if (platform->clk[i]) + clk_disable_unprepare(platform->clk[i]); + } + tegra_powergate_partition(TEGRA186_POWER_DOMAIN_GPU); + } + return 0; +} + +static int gp10b_tegra_unrailgate(struct device *dev) +{ + int ret = 0; + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + + if (tegra_bpmp_running()) { + int i; + ret = tegra_unpowergate_partition(TEGRA186_POWER_DOMAIN_GPU); + for (i = 0; i < platform->num_clks; i++) { + if (platform->clk[i]) + clk_prepare_enable(platform->clk[i]); + } + } + + /* to start with set emc frequency floor to max rate*/ + if (profile) + tegra_bwmgr_set_emc( + (struct tegra_bwmgr_client *)profile->private_data, + tegra_bwmgr_get_max_emc_rate(), + TEGRA_BWMGR_SET_EMC_FLOOR); + return ret; +} + +static int gp10b_tegra_suspend(struct device *dev) +{ + return 0; +} + +int gp10b_tegra_reset_assert(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + int ret = 0; + + if (!platform->reset_control) + return -EINVAL; + + ret = reset_control_assert(platform->reset_control); + + return ret; +} + +int gp10b_tegra_reset_deassert(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + int ret = 0; + + if (!platform->reset_control) + return -EINVAL; + + ret = reset_control_deassert(platform->reset_control); + + return ret; +} + +void gp10b_tegra_prescale(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + u32 avg = 0; + + nvgpu_log_fn(g, " "); + + nvgpu_pmu_load_norm(g, &avg); + + nvgpu_log_fn(g, "done"); +} + +void gp10b_tegra_postscale(struct device *pdev, + unsigned long freq) +{ + struct gk20a_platform *platform = gk20a_get_platform(pdev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + struct gk20a *g = get_gk20a(pdev); + unsigned long emc_rate; + + nvgpu_log_fn(g, " "); + if (profile && profile->private_data && + !platform->is_railgated(pdev)) { + unsigned long emc_scale; + + if (freq <= gp10b_freq_table[0]) + emc_scale = 0; + else + emc_scale = g->emc3d_ratio; + + emc_rate = (freq * EMC_BW_RATIO * emc_scale) / 1000; + + if (emc_rate > tegra_bwmgr_get_max_emc_rate()) + emc_rate = tegra_bwmgr_get_max_emc_rate(); + + tegra_bwmgr_set_emc( + (struct tegra_bwmgr_client *)profile->private_data, + emc_rate, TEGRA_BWMGR_SET_EMC_FLOOR); + } + nvgpu_log_fn(g, "done"); +} + +long gp10b_round_clk_rate(struct device *dev, unsigned long rate) +{ + struct gk20a *g = get_gk20a(dev); + struct gk20a_scale_profile *profile = g->scale_profile; + unsigned long *freq_table = profile->devfreq_profile.freq_table; + int max_states = profile->devfreq_profile.max_state; + int i; + + for (i = 0; i < max_states; ++i) + if (freq_table[i] >= rate) + return freq_table[i]; + + return freq_table[max_states - 1]; +} + +int gp10b_clk_get_freqs(struct device *dev, + unsigned long **freqs, int *num_freqs) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a *g = platform->g; + unsigned long max_rate; + unsigned long new_rate = 0, prev_rate = 0; + int i, freq_counter = 0; + int sel_freq_cnt; + unsigned long loc_freq_table[GP10B_MAX_SUPPORTED_FREQS]; + + nvgpu_mutex_acquire(&platform->clk_get_freq_lock); + + if (freq_table_init_complete) { + + *freqs = gp10b_freq_table; + *num_freqs = num_supported_freq; + + nvgpu_mutex_release(&platform->clk_get_freq_lock); + + return 0; + } + + max_rate = clk_round_rate(platform->clk[0], (UINT_MAX - 1)); + + /* + * Walk the h/w frequency table and update the local table + */ + for (i = 0; i < GP10B_MAX_SUPPORTED_FREQS; ++i) { + prev_rate = new_rate; + new_rate = clk_round_rate(platform->clk[0], + prev_rate + 1); + loc_freq_table[i] = new_rate; + if (new_rate == max_rate) + break; + } + freq_counter = i + 1; + WARN_ON(freq_counter == GP10B_MAX_SUPPORTED_FREQS); + + /* + * If the number of achievable frequencies is less than or + * equal to GP10B_NUM_SUPPORTED_FREQS, select all frequencies + * else, select one out of every 8 frequencies + */ + if (freq_counter <= GP10B_NUM_SUPPORTED_FREQS) { + for (sel_freq_cnt = 0; sel_freq_cnt < freq_counter; ++sel_freq_cnt) + gp10b_freq_table[sel_freq_cnt] = + loc_freq_table[sel_freq_cnt]; + } else { + /* + * Walk the h/w frequency table and only select + * GP10B_FREQ_SELECT_STEP'th frequencies and + * add MAX freq to last + */ + sel_freq_cnt = 0; + for (i = 0; i < GP10B_MAX_SUPPORTED_FREQS; ++i) { + new_rate = loc_freq_table[i]; + + if (i % GP10B_FREQ_SELECT_STEP == 0 || + new_rate == max_rate) { + gp10b_freq_table[sel_freq_cnt++] = + new_rate; + + if (new_rate == max_rate) + break; + } + } + WARN_ON(sel_freq_cnt == GP10B_MAX_SUPPORTED_FREQS); + } + + /* Fill freq table */ + *freqs = gp10b_freq_table; + *num_freqs = sel_freq_cnt; + num_supported_freq = sel_freq_cnt; + + freq_table_init_complete = true; + + nvgpu_log_info(g, "min rate: %ld max rate: %ld num_of_freq %d\n", + gp10b_freq_table[0], max_rate, *num_freqs); + + nvgpu_mutex_release(&platform->clk_get_freq_lock); + + return 0; +} + +struct gk20a_platform gp10b_tegra_platform = { + .has_syncpoints = true, + + /* power management configuration */ + .railgate_delay_init = 500, + + /* ldiv slowdown factor */ + .ldiv_slowdown_factor_init = SLOWDOWN_FACTOR_FPDIV_BY16, + + /* power management configuration */ + .can_railgate_init = true, + .enable_elpg = true, + .can_elpg_init = true, + .enable_blcg = true, + .enable_slcg = true, + .enable_elcg = true, + .can_slcg = true, + .can_blcg = true, + .can_elcg = true, + .enable_aelpg = true, + .enable_perfmon = true, + + /* ptimer src frequency in hz*/ + .ptimer_src_freq = 31250000, + + .ch_wdt_timeout_ms = 5000, + + .probe = gp10b_tegra_probe, + .late_probe = gp10b_tegra_late_probe, + .remove = gp10b_tegra_remove, + + /* power management callbacks */ + .suspend = gp10b_tegra_suspend, + .railgate = gp10b_tegra_railgate, + .unrailgate = gp10b_tegra_unrailgate, + .is_railgated = gp10b_tegra_is_railgated, + + .busy = gk20a_tegra_busy, + .idle = gk20a_tegra_idle, + + .dump_platform_dependencies = gk20a_tegra_debug_dump, + +#ifdef CONFIG_NVGPU_SUPPORT_CDE + .has_cde = true, +#endif + + .clk_round_rate = gp10b_round_clk_rate, + .get_clk_freqs = gp10b_clk_get_freqs, + + /* frequency scaling configuration */ + .initscale = gp10b_tegra_scale_init, + .prescale = gp10b_tegra_prescale, + .postscale = gp10b_tegra_postscale, + .devfreq_governor = "nvhost_podgov", + + .qos_notify = gk20a_scale_qos_notify, + + .reset_assert = gp10b_tegra_reset_assert, + .reset_deassert = gp10b_tegra_reset_deassert, + + .force_reset_in_do_idle = false, + + .soc_name = "tegra18x", + + .unified_memory = true, + .dma_mask = DMA_BIT_MASK(36), + + .ltc_streamid = TEGRA_SID_GPUB, + + .secure_buffer_size = 401408, +}; diff --git a/include/os/linux/platform_gp10b_tegra.h b/include/os/linux/platform_gp10b_tegra.h new file mode 100644 index 0000000..85b46b9 --- /dev/null +++ b/include/os/linux/platform_gp10b_tegra.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _PLATFORM_GP10B_TEGRA_H_ +#define _PLATFORM_GP10B_TEGRA_H_ + +#include "gp10b/gr_gp10b.h" + +#endif diff --git a/include/os/linux/platform_gv11b_tegra.c b/include/os/linux/platform_gv11b_tegra.c new file mode 100644 index 0000000..6c9d0f5 --- /dev/null +++ b/include/os/linux/platform_gv11b_tegra.c @@ -0,0 +1,331 @@ +/* + * GV11B Tegra Platform Interface + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include "platform_gk20a.h" +#include "clk.h" +#include "scale.h" + +#include "platform_gp10b.h" +#include "platform_gp10b_tegra.h" + +#include "os_linux.h" +#include "platform_gk20a_tegra.h" +#include "gv11b/gr_gv11b.h" + +#define EMC3D_GV11B_RATIO 500 + +void gv11b_tegra_scale_init(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + + if (!profile) + return; + + platform->g->emc3d_ratio = EMC3D_GV11B_RATIO; + + gp10b_tegra_scale_init(dev); +} + +static void gv11b_tegra_scale_exit(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + + if (profile) + tegra_bwmgr_unregister( + (struct tegra_bwmgr_client *)profile->private_data); +} + +static int gv11b_tegra_probe(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + int err; + bool joint_xpu_rail = false; + struct gk20a *g = platform->g; + + err = nvgpu_nvhost_syncpt_init(platform->g); + if (err) { + if (err != -ENOSYS) + return err; + } + + err = gk20a_tegra_init_secure_alloc(platform); + if (err) + return err; + + platform->disable_bigpage = !device_is_iommuable(dev); + + platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close + = false; + platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close + = false; + + platform->g->gr.ctx_vars.force_preemption_gfxp = false; + platform->g->gr.ctx_vars.force_preemption_cilp = false; + +#ifdef CONFIG_OF + joint_xpu_rail = of_property_read_bool(of_chosen, + "nvidia,tegra-joint_xpu_rail"); +#endif + + if (joint_xpu_rail) { + nvgpu_log_info(g, "XPU rails are joint\n"); + platform->can_railgate_init = false; + __nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, false); + } + + gp10b_tegra_get_clocks(dev); + nvgpu_linux_init_clk_support(platform->g); + + nvgpu_mutex_init(&platform->clk_get_freq_lock); + + platform->g->ops.clk.support_clk_freq_controller = true; + + return 0; +} + +static int gv11b_tegra_late_probe(struct device *dev) +{ + return 0; +} + + +static int gv11b_tegra_remove(struct device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + + gv11b_tegra_scale_exit(dev); + +#ifdef CONFIG_TEGRA_GK20A_NVHOST + nvgpu_free_nvhost_dev(get_gk20a(dev)); +#endif + + nvgpu_mutex_destroy(&platform->clk_get_freq_lock); + + return 0; +} + +static bool gv11b_tegra_is_railgated(struct device *dev) +{ + bool ret = false; +#ifdef TEGRA194_POWER_DOMAIN_GPU + struct gk20a *g = get_gk20a(dev); + + if (tegra_bpmp_running()) { + nvgpu_log(g, gpu_dbg_info, "bpmp running"); + ret = !tegra_powergate_is_powered(TEGRA194_POWER_DOMAIN_GPU); + + nvgpu_log(g, gpu_dbg_info, "railgated? %s", ret ? "yes" : "no"); + } else { + nvgpu_log(g, gpu_dbg_info, "bpmp not running"); + } +#endif + return ret; +} + +static int gv11b_tegra_railgate(struct device *dev) +{ +#ifdef TEGRA194_POWER_DOMAIN_GPU + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + struct gk20a *g = get_gk20a(dev); + int i; + + /* remove emc frequency floor */ + if (profile) + tegra_bwmgr_set_emc( + (struct tegra_bwmgr_client *)profile->private_data, + 0, TEGRA_BWMGR_SET_EMC_FLOOR); + + if (tegra_bpmp_running()) { + nvgpu_log(g, gpu_dbg_info, "bpmp running"); + if (!tegra_powergate_is_powered(TEGRA194_POWER_DOMAIN_GPU)) { + nvgpu_log(g, gpu_dbg_info, "powergate is not powered"); + return 0; + } + nvgpu_log(g, gpu_dbg_info, "clk_disable_unprepare"); + for (i = 0; i < platform->num_clks; i++) { + if (platform->clk[i]) + clk_disable_unprepare(platform->clk[i]); + } + nvgpu_log(g, gpu_dbg_info, "powergate_partition"); + tegra_powergate_partition(TEGRA194_POWER_DOMAIN_GPU); + } else { + nvgpu_log(g, gpu_dbg_info, "bpmp not running"); + } +#endif + return 0; +} + +static int gv11b_tegra_unrailgate(struct device *dev) +{ + int ret = 0; +#ifdef TEGRA194_POWER_DOMAIN_GPU + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a *g = get_gk20a(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + int i; + + if (tegra_bpmp_running()) { + nvgpu_log(g, gpu_dbg_info, "bpmp running"); + ret = tegra_unpowergate_partition(TEGRA194_POWER_DOMAIN_GPU); + if (ret) { + nvgpu_log(g, gpu_dbg_info, + "unpowergate partition failed"); + return ret; + } + nvgpu_log(g, gpu_dbg_info, "clk_prepare_enable"); + for (i = 0; i < platform->num_clks; i++) { + if (platform->clk[i]) + clk_prepare_enable(platform->clk[i]); + } + } else { + nvgpu_log(g, gpu_dbg_info, "bpmp not running"); + } + + /* to start with set emc frequency floor to max rate*/ + if (profile) + tegra_bwmgr_set_emc( + (struct tegra_bwmgr_client *)profile->private_data, + tegra_bwmgr_get_max_emc_rate(), + TEGRA_BWMGR_SET_EMC_FLOOR); +#endif + return ret; +} + +static int gv11b_tegra_suspend(struct device *dev) +{ + return 0; +} + +static bool is_tpc_mask_valid(struct gk20a_platform *platform, u32 tpc_pg_mask) +{ + u32 i; + bool valid = false; + + for (i = 0; i < MAX_TPC_PG_CONFIGS; i++) { + if (tpc_pg_mask == platform->valid_tpc_mask[i]) { + valid = true; + break; + } + } + return valid; +} + +static void gv11b_tegra_set_tpc_pg_mask(struct device *dev, u32 tpc_pg_mask) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a *g = get_gk20a(dev); + + if (is_tpc_mask_valid(platform, tpc_pg_mask)) { + g->tpc_pg_mask = tpc_pg_mask; + } + +} + +struct gk20a_platform gv11b_tegra_platform = { + .has_syncpoints = true, + + /* ptimer src frequency in hz*/ + .ptimer_src_freq = 31250000, + + .ch_wdt_timeout_ms = 5000, + + .probe = gv11b_tegra_probe, + .late_probe = gv11b_tegra_late_probe, + .remove = gv11b_tegra_remove, + .railgate_delay_init = 500, + .can_railgate_init = true, + + .can_tpc_powergate = true, + .valid_tpc_mask[0] = 0x0, + .valid_tpc_mask[1] = 0x1, + .valid_tpc_mask[2] = 0x2, + .valid_tpc_mask[3] = 0x4, + .valid_tpc_mask[4] = 0x8, + .valid_tpc_mask[5] = 0x5, + .valid_tpc_mask[6] = 0x6, + .valid_tpc_mask[7] = 0x9, + .valid_tpc_mask[8] = 0xa, + + .set_tpc_pg_mask = gv11b_tegra_set_tpc_pg_mask, + + .can_slcg = true, + .can_blcg = true, + .can_elcg = true, + .enable_slcg = true, + .enable_blcg = true, + .enable_elcg = true, + .enable_perfmon = true, + + /* power management configuration */ + .enable_elpg = true, + .can_elpg_init = true, + .enable_aelpg = true, + + /* power management callbacks */ + .suspend = gv11b_tegra_suspend, + .railgate = gv11b_tegra_railgate, + .unrailgate = gv11b_tegra_unrailgate, + .is_railgated = gv11b_tegra_is_railgated, + + .busy = gk20a_tegra_busy, + .idle = gk20a_tegra_idle, + + .clk_round_rate = gp10b_round_clk_rate, + .get_clk_freqs = gp10b_clk_get_freqs, + + /* frequency scaling configuration */ + .initscale = gv11b_tegra_scale_init, + .prescale = gp10b_tegra_prescale, + .postscale = gp10b_tegra_postscale, + .devfreq_governor = "nvhost_podgov", + + .qos_notify = gk20a_scale_qos_notify, + + .dump_platform_dependencies = gk20a_tegra_debug_dump, + + .soc_name = "tegra19x", + + .honors_aperture = true, + .unified_memory = true, + .dma_mask = DMA_BIT_MASK(36), + + .reset_assert = gp10b_tegra_reset_assert, + .reset_deassert = gp10b_tegra_reset_deassert, + + .secure_buffer_size = 667648, +}; diff --git a/include/os/linux/rwsem.c b/include/os/linux/rwsem.c new file mode 100644 index 0000000..297ddf1 --- /dev/null +++ b/include/os/linux/rwsem.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include + +void nvgpu_rwsem_init(struct nvgpu_rwsem *rwsem) +{ + init_rwsem(&rwsem->rwsem); +} + +void nvgpu_rwsem_up_read(struct nvgpu_rwsem *rwsem) +{ + up_read(&rwsem->rwsem); +} + +void nvgpu_rwsem_down_read(struct nvgpu_rwsem *rwsem) +{ + down_read(&rwsem->rwsem); +} + +void nvgpu_rwsem_up_write(struct nvgpu_rwsem *rwsem) +{ + up_write(&rwsem->rwsem); +} + +void nvgpu_rwsem_down_write(struct nvgpu_rwsem *rwsem) +{ + down_write(&rwsem->rwsem); +} diff --git a/include/os/linux/scale.c b/include/os/linux/scale.c new file mode 100644 index 0000000..388e168 --- /dev/null +++ b/include/os/linux/scale.c @@ -0,0 +1,435 @@ +/* + * gk20a clock scaling profile + * + * Copyright (c) 2013-2020, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "platform_gk20a.h" +#include "scale.h" +#include "os_linux.h" + +/* + * gk20a_scale_qos_notify() + * + * This function is called when the minimum QoS requirement for the device + * has changed. The function calls postscaling callback if it is defined. + */ + +#if defined(CONFIG_GK20A_PM_QOS) && defined(CONFIG_COMMON_CLK) +int gk20a_scale_qos_notify(struct notifier_block *nb, + unsigned long n, void *p) +{ + struct gk20a_scale_profile *profile = + container_of(nb, struct gk20a_scale_profile, + qos_notify_block); + struct gk20a *g = get_gk20a(profile->dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct devfreq *devfreq = l->devfreq; + + if (!devfreq) + return NOTIFY_OK; + + mutex_lock(&devfreq->lock); + /* check for pm_qos min and max frequency requirement */ + profile->qos_min_freq = + (unsigned long)pm_qos_read_min_bound(PM_QOS_GPU_FREQ_BOUNDS) * 1000UL; + profile->qos_max_freq = + (unsigned long)pm_qos_read_max_bound(PM_QOS_GPU_FREQ_BOUNDS) * 1000UL; + + if (profile->qos_min_freq > profile->qos_max_freq) { + nvgpu_err(g, + "QoS: setting invalid limit, min_freq=%lu max_freq=%lu", + profile->qos_min_freq, profile->qos_max_freq); + profile->qos_min_freq = profile->qos_max_freq; + } + + update_devfreq(devfreq); + mutex_unlock(&devfreq->lock); + + return NOTIFY_OK; +} +#elif defined(CONFIG_GK20A_PM_QOS) +int gk20a_scale_qos_notify(struct notifier_block *nb, + unsigned long n, void *p) +{ + struct gk20a_scale_profile *profile = + container_of(nb, struct gk20a_scale_profile, + qos_notify_block); + struct gk20a_platform *platform = dev_get_drvdata(profile->dev); + struct gk20a *g = get_gk20a(profile->dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + unsigned long freq; + + if (!platform->postscale) + return NOTIFY_OK; + + /* get the frequency requirement. if devfreq is enabled, check if it + * has higher demand than qos */ + freq = platform->clk_round_rate(profile->dev, + (u32)pm_qos_read_min_bound(PM_QOS_GPU_FREQ_BOUNDS)); + if (l->devfreq) + freq = max(l->devfreq->previous_freq, freq); + + /* Update gpu load because we may scale the emc target + * if the gpu load changed. */ + nvgpu_pmu_load_update(g); + platform->postscale(profile->dev, freq); + + return NOTIFY_OK; +} +#else +int gk20a_scale_qos_notify(struct notifier_block *nb, + unsigned long n, void *p) +{ + return 0; +} +#endif + +/* + * gk20a_scale_make_freq_table(profile) + * + * This function initialises the frequency table for the given device profile + */ + +static int gk20a_scale_make_freq_table(struct gk20a_scale_profile *profile) +{ + struct gk20a_platform *platform = dev_get_drvdata(profile->dev); + int num_freqs, err; + unsigned long *freqs; + + if (platform->get_clk_freqs) { + /* get gpu frequency table */ + err = platform->get_clk_freqs(profile->dev, &freqs, + &num_freqs); + + if (err) + return -ENOSYS; + } else + return -ENOSYS; + + profile->devfreq_profile.freq_table = (unsigned long *)freqs; + profile->devfreq_profile.max_state = num_freqs; + + return 0; +} + +/* + * gk20a_scale_target(dev, *freq, flags) + * + * This function scales the clock + */ + +static int gk20a_scale_target(struct device *dev, unsigned long *freq, + u32 flags) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct gk20a *g = platform->g; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct gk20a_scale_profile *profile = g->scale_profile; + struct devfreq *devfreq = l->devfreq; + unsigned long local_freq = *freq; + unsigned long rounded_rate; + unsigned long min_freq = 0, max_freq = 0; + + if (nvgpu_clk_arb_has_active_req(g)) + return 0; + /* + * Calculate floor and cap frequency values + * + * Policy : + * We have two APIs to clip the frequency + * 1. devfreq + * 2. pm_qos + * + * To calculate floor (min) freq, we select MAX of floor frequencies + * requested from both APIs + * To get cap (max) freq, we select MIN of max frequencies + * + * In case we have conflict (min_freq > max_freq) after above + * steps, we ensure that max_freq wins over min_freq + */ + min_freq = max_t(u32, devfreq->min_freq, profile->qos_min_freq); + max_freq = min_t(u32, devfreq->max_freq, profile->qos_max_freq); + + if (min_freq > max_freq) + min_freq = max_freq; + + /* Clip requested frequency */ + if (local_freq < min_freq) + local_freq = min_freq; + + if (local_freq > max_freq) + local_freq = max_freq; + + /* set the final frequency */ + rounded_rate = platform->clk_round_rate(dev, local_freq); + + /* Check for duplicate request */ + if (rounded_rate == g->last_freq) + return 0; + + if (g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_GPCCLK) == rounded_rate) + *freq = rounded_rate; + else { + g->ops.clk.set_rate(g, CTRL_CLK_DOMAIN_GPCCLK, rounded_rate); + *freq = g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_GPCCLK); + } + + g->last_freq = *freq; + + /* postscale will only scale emc (dram clock) if evaluating + * gk20a_tegra_get_emc_rate() produces a new or different emc + * target because the load or_and gpufreq has changed */ + if (platform->postscale) + platform->postscale(dev, rounded_rate); + + return 0; +} + +/* + * update_load_estimate_busy_cycles(dev) + * + * Update load estimate using pmu idle counters. Result is normalised + * based on the time it was asked last time. + */ + +static void update_load_estimate_busy_cycles(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + struct gk20a_scale_profile *profile = g->scale_profile; + unsigned long dt; + u32 busy_cycles_norm; + ktime_t t; + + t = ktime_get(); + dt = ktime_us_delta(t, profile->last_event_time); + + profile->dev_stat.total_time = dt; + profile->last_event_time = t; + nvgpu_pmu_busy_cycles_norm(g, &busy_cycles_norm); + profile->dev_stat.busy_time = + (busy_cycles_norm * dt) / PMU_BUSY_CYCLES_NORM_MAX; +} + +/* + * gk20a_scale_suspend(dev) + * + * This function informs devfreq of suspend + */ + +void gk20a_scale_suspend(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct devfreq *devfreq = l->devfreq; + + if (!devfreq) + return; + + devfreq_suspend_device(devfreq); +} + +/* + * gk20a_scale_resume(dev) + * + * This functions informs devfreq of resume + */ + +void gk20a_scale_resume(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct devfreq *devfreq = l->devfreq; + + if (!devfreq) + return; + + g->last_freq = 0; + devfreq_resume_device(devfreq); +} + +/* + * gk20a_scale_get_dev_status(dev, *stat) + * + * This function queries the current device status. + */ + +static int gk20a_scale_get_dev_status(struct device *dev, + struct devfreq_dev_status *stat) +{ + struct gk20a *g = get_gk20a(dev); + struct gk20a_scale_profile *profile = g->scale_profile; + struct gk20a_platform *platform = dev_get_drvdata(dev); + + /* inform edp about new constraint */ + if (platform->prescale) + platform->prescale(dev); + + /* Make sure there are correct values for the current frequency */ + profile->dev_stat.current_frequency = + g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_GPCCLK); + + /* Update load estimate */ + update_load_estimate_busy_cycles(dev); + + /* Copy the contents of the current device status */ + *stat = profile->dev_stat; + + /* Finally, clear out the local values */ + profile->dev_stat.total_time = 0; + profile->dev_stat.busy_time = 0; + + return 0; +} + +/* + * get_cur_freq(struct device *dev, unsigned long *freq) + * + * This function gets the current GPU clock rate. + */ + +static int get_cur_freq(struct device *dev, unsigned long *freq) +{ + struct gk20a *g = get_gk20a(dev); + *freq = g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_GPCCLK); + return 0; +} + + +/* + * gk20a_scale_init(dev) + */ + +void gk20a_scale_init(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct gk20a *g = platform->g; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct gk20a_scale_profile *profile; + int err; + + if (g->scale_profile) + return; + + if (!platform->devfreq_governor && !platform->qos_notify) + return; + + profile = nvgpu_kzalloc(g, sizeof(*profile)); + if (!profile) + return; + + profile->dev = dev; + profile->dev_stat.busy = false; + + /* Create frequency table */ + err = gk20a_scale_make_freq_table(profile); + if (err || !profile->devfreq_profile.max_state) + goto err_get_freqs; + + profile->qos_min_freq = 0; + profile->qos_max_freq = UINT_MAX; + + /* Store device profile so we can access it if devfreq governor + * init needs that */ + g->scale_profile = profile; + + if (platform->devfreq_governor) { + struct devfreq *devfreq; + + profile->devfreq_profile.initial_freq = + profile->devfreq_profile.freq_table[0]; + profile->devfreq_profile.target = gk20a_scale_target; + profile->devfreq_profile.get_dev_status = + gk20a_scale_get_dev_status; + profile->devfreq_profile.get_cur_freq = get_cur_freq; + profile->devfreq_profile.polling_ms = 25; + + devfreq = devm_devfreq_add_device(dev, + &profile->devfreq_profile, + platform->devfreq_governor, NULL); + + if (IS_ERR_OR_NULL(devfreq)) + devfreq = NULL; + + l->devfreq = devfreq; + } + +#ifdef CONFIG_GK20A_PM_QOS + /* Should we register QoS callback for this device? */ + if (platform->qos_notify) { + profile->qos_notify_block.notifier_call = + platform->qos_notify; + + pm_qos_add_min_notifier(PM_QOS_GPU_FREQ_BOUNDS, + &profile->qos_notify_block); + pm_qos_add_max_notifier(PM_QOS_GPU_FREQ_BOUNDS, + &profile->qos_notify_block); + } +#endif + + return; + +err_get_freqs: + nvgpu_kfree(g, profile); +} + +void gk20a_scale_exit(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct gk20a *g = platform->g; + +#ifdef CONFIG_GK20A_PM_QOS + if (platform->qos_notify) { + pm_qos_remove_min_notifier(PM_QOS_GPU_FREQ_BOUNDS, + &g->scale_profile->qos_notify_block); + pm_qos_remove_max_notifier(PM_QOS_GPU_FREQ_BOUNDS, + &g->scale_profile->qos_notify_block); + } +#endif + + nvgpu_kfree(g, g->scale_profile); + g->scale_profile = NULL; +} + +/* + * gk20a_scale_hw_init(dev) + * + * Initialize hardware portion of the device + */ + +void gk20a_scale_hw_init(struct device *dev) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + + /* make sure that scaling has bee initialised */ + if (!profile) + return; + + profile->dev_stat.total_time = 0; + profile->last_event_time = ktime_get(); +} diff --git a/include/os/linux/scale.h b/include/os/linux/scale.h new file mode 100644 index 0000000..c1e6fe8 --- /dev/null +++ b/include/os/linux/scale.h @@ -0,0 +1,66 @@ +/* + * gk20a clock scaling profile + * + * Copyright (c) 2013-2016, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GK20A_SCALE_H +#define GK20A_SCALE_H + +#include + +struct clk; + +struct gk20a_scale_profile { + struct device *dev; + ktime_t last_event_time; + struct devfreq_dev_profile devfreq_profile; + struct devfreq_dev_status dev_stat; + struct notifier_block qos_notify_block; + unsigned long qos_min_freq; + unsigned long qos_max_freq; + void *private_data; +}; + +/* Initialization and de-initialization for module */ +void gk20a_scale_init(struct device *); +void gk20a_scale_exit(struct device *); +void gk20a_scale_hw_init(struct device *dev); + +#if defined(CONFIG_GK20A_DEVFREQ) +/* + * call when performing submit to notify scaling mechanism that the module is + * in use + */ +void gk20a_scale_notify_busy(struct device *); +void gk20a_scale_notify_idle(struct device *); + +void gk20a_scale_suspend(struct device *); +void gk20a_scale_resume(struct device *); +int gk20a_scale_qos_notify(struct notifier_block *nb, + unsigned long n, void *p); +#else +static inline void gk20a_scale_notify_busy(struct device *dev) {} +static inline void gk20a_scale_notify_idle(struct device *dev) {} +static inline void gk20a_scale_suspend(struct device *dev) {} +static inline void gk20a_scale_resume(struct device *dev) {} +static inline int gk20a_scale_qos_notify(struct notifier_block *nb, + unsigned long n, void *p) +{ + return -ENOSYS; +} +#endif + +#endif diff --git a/include/os/linux/sched.c b/include/os/linux/sched.c new file mode 100644 index 0000000..30c58a1 --- /dev/null +++ b/include/os/linux/sched.c @@ -0,0 +1,666 @@ +/* + * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "gk20a/gr_gk20a.h" +#include "sched.h" +#include "os_linux.h" +#include "ioctl_tsg.h" + +#include +#include + +ssize_t gk20a_sched_dev_read(struct file *filp, char __user *buf, + size_t size, loff_t *off) +{ + struct gk20a *g = filp->private_data; + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + struct nvgpu_sched_event_arg event = { 0 }; + int err; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, + "filp=%p buf=%p size=%zu", filp, buf, size); + + if (size < sizeof(event)) + return -EINVAL; + size = sizeof(event); + + nvgpu_mutex_acquire(&sched->status_lock); + while (!sched->status) { + nvgpu_mutex_release(&sched->status_lock); + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + err = NVGPU_COND_WAIT_INTERRUPTIBLE(&sched->readout_wq, + sched->status, 0); + if (err) + return err; + nvgpu_mutex_acquire(&sched->status_lock); + } + + event.reserved = 0; + event.status = sched->status; + + if (copy_to_user(buf, &event, size)) { + nvgpu_mutex_release(&sched->status_lock); + return -EFAULT; + } + + sched->status = 0; + + nvgpu_mutex_release(&sched->status_lock); + + return size; +} + +unsigned int gk20a_sched_dev_poll(struct file *filp, poll_table *wait) +{ + struct gk20a *g = filp->private_data; + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + unsigned int mask = 0; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, " "); + + nvgpu_mutex_acquire(&sched->status_lock); + poll_wait(filp, &sched->readout_wq.wq, wait); + if (sched->status) + mask |= POLLIN | POLLRDNORM; + nvgpu_mutex_release(&sched->status_lock); + + return mask; +} + +static int gk20a_sched_dev_ioctl_get_tsgs(struct gk20a *g, + struct nvgpu_sched_get_tsgs_args *arg) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "size=%u buffer=%llx", + arg->size, arg->buffer); + + if ((arg->size < sched->bitmap_size) || (!arg->buffer)) { + arg->size = sched->bitmap_size; + return -ENOSPC; + } + + nvgpu_mutex_acquire(&sched->status_lock); + if (copy_to_user((void __user *)(uintptr_t)arg->buffer, + sched->active_tsg_bitmap, sched->bitmap_size)) { + nvgpu_mutex_release(&sched->status_lock); + return -EFAULT; + } + nvgpu_mutex_release(&sched->status_lock); + + return 0; +} + +static int gk20a_sched_dev_ioctl_get_recent_tsgs(struct gk20a *g, + struct nvgpu_sched_get_tsgs_args *arg) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "size=%u buffer=%llx", + arg->size, arg->buffer); + + if ((arg->size < sched->bitmap_size) || (!arg->buffer)) { + arg->size = sched->bitmap_size; + return -ENOSPC; + } + + nvgpu_mutex_acquire(&sched->status_lock); + if (copy_to_user((void __user *)(uintptr_t)arg->buffer, + sched->recent_tsg_bitmap, sched->bitmap_size)) { + nvgpu_mutex_release(&sched->status_lock); + return -EFAULT; + } + + memset(sched->recent_tsg_bitmap, 0, sched->bitmap_size); + nvgpu_mutex_release(&sched->status_lock); + + return 0; +} + +static int gk20a_sched_dev_ioctl_get_tsgs_by_pid(struct gk20a *g, + struct nvgpu_sched_get_tsgs_by_pid_args *arg) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + struct fifo_gk20a *f = &g->fifo; + struct tsg_gk20a *tsg; + u64 *bitmap; + unsigned int tsgid; + /* pid at user level corresponds to kernel tgid */ + pid_t tgid = (pid_t)arg->pid; + int err = 0; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "pid=%d size=%u buffer=%llx", + (pid_t)arg->pid, arg->size, arg->buffer); + + if ((arg->size < sched->bitmap_size) || (!arg->buffer)) { + arg->size = sched->bitmap_size; + return -ENOSPC; + } + + bitmap = nvgpu_kzalloc(g, sched->bitmap_size); + if (!bitmap) + return -ENOMEM; + + nvgpu_mutex_acquire(&sched->status_lock); + for (tsgid = 0; tsgid < f->num_channels; tsgid++) { + if (NVGPU_SCHED_ISSET(tsgid, sched->active_tsg_bitmap)) { + tsg = &f->tsg[tsgid]; + if (tsg->tgid == tgid) + NVGPU_SCHED_SET(tsgid, bitmap); + } + } + nvgpu_mutex_release(&sched->status_lock); + + if (copy_to_user((void __user *)(uintptr_t)arg->buffer, + bitmap, sched->bitmap_size)) + err = -EFAULT; + + nvgpu_kfree(g, bitmap); + + return err; +} + +static int gk20a_sched_dev_ioctl_get_params(struct gk20a *g, + struct nvgpu_sched_tsg_get_params_args *arg) +{ + struct fifo_gk20a *f = &g->fifo; + struct tsg_gk20a *tsg; + u32 tsgid = arg->tsgid; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsgid); + + if (tsgid >= f->num_channels) + return -EINVAL; + + nvgpu_speculation_barrier(); + + tsg = &f->tsg[tsgid]; + if (!nvgpu_ref_get_unless_zero(&tsg->refcount)) + return -ENXIO; + + arg->pid = tsg->tgid; /* kernel tgid corresponds to user pid */ + arg->runlist_interleave = tsg->interleave_level; + arg->timeslice = gk20a_tsg_get_timeslice(tsg); + + arg->graphics_preempt_mode = + tsg->gr_ctx.graphics_preempt_mode; + arg->compute_preempt_mode = + tsg->gr_ctx.compute_preempt_mode; + + nvgpu_ref_put(&tsg->refcount, nvgpu_ioctl_tsg_release); + + return 0; +} + +static int gk20a_sched_dev_ioctl_tsg_set_timeslice( + struct gk20a *g, + struct nvgpu_sched_tsg_timeslice_args *arg) +{ + struct fifo_gk20a *f = &g->fifo; + struct tsg_gk20a *tsg; + u32 tsgid = arg->tsgid; + int err; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsgid); + + if (tsgid >= f->num_channels) + return -EINVAL; + + nvgpu_speculation_barrier(); + + tsg = &f->tsg[tsgid]; + if (!nvgpu_ref_get_unless_zero(&tsg->refcount)) + return -ENXIO; + + err = gk20a_busy(g); + if (err) + goto done; + + err = gk20a_tsg_set_timeslice(tsg, arg->timeslice); + + gk20a_idle(g); + +done: + nvgpu_ref_put(&tsg->refcount, nvgpu_ioctl_tsg_release); + + return err; +} + +static int gk20a_sched_dev_ioctl_tsg_set_runlist_interleave( + struct gk20a *g, + struct nvgpu_sched_tsg_runlist_interleave_args *arg) +{ + struct fifo_gk20a *f = &g->fifo; + struct tsg_gk20a *tsg; + u32 tsgid = arg->tsgid; + int err; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsgid); + + if (tsgid >= f->num_channels) + return -EINVAL; + + nvgpu_speculation_barrier(); + + tsg = &f->tsg[tsgid]; + if (!nvgpu_ref_get_unless_zero(&tsg->refcount)) + return -ENXIO; + + err = gk20a_busy(g); + if (err) + goto done; + + err = gk20a_tsg_set_runlist_interleave(tsg, arg->runlist_interleave); + + gk20a_idle(g); + +done: + nvgpu_ref_put(&tsg->refcount, nvgpu_ioctl_tsg_release); + + return err; +} + +static int gk20a_sched_dev_ioctl_lock_control(struct gk20a *g) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, " "); + + nvgpu_mutex_acquire(&sched->control_lock); + sched->control_locked = true; + nvgpu_mutex_release(&sched->control_lock); + return 0; +} + +static int gk20a_sched_dev_ioctl_unlock_control(struct gk20a *g) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, " "); + + nvgpu_mutex_acquire(&sched->control_lock); + sched->control_locked = false; + nvgpu_mutex_release(&sched->control_lock); + return 0; +} + +static int gk20a_sched_dev_ioctl_get_api_version(struct gk20a *g, + struct nvgpu_sched_api_version_args *args) +{ + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, " "); + + args->version = NVGPU_SCHED_API_VERSION; + return 0; +} + +static int gk20a_sched_dev_ioctl_get_tsg(struct gk20a *g, + struct nvgpu_sched_tsg_refcount_args *arg) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + struct fifo_gk20a *f = &g->fifo; + struct tsg_gk20a *tsg; + u32 tsgid = arg->tsgid; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsgid); + + if (tsgid >= f->num_channels) + return -EINVAL; + + nvgpu_speculation_barrier(); + + tsg = &f->tsg[tsgid]; + if (!nvgpu_ref_get_unless_zero(&tsg->refcount)) + return -ENXIO; + + nvgpu_mutex_acquire(&sched->status_lock); + if (NVGPU_SCHED_ISSET(tsgid, sched->ref_tsg_bitmap)) { + nvgpu_warn(g, "tsgid=%d already referenced", tsgid); + /* unlock status_lock as nvgpu_ioctl_tsg_release locks it */ + nvgpu_mutex_release(&sched->status_lock); + nvgpu_ref_put(&tsg->refcount, nvgpu_ioctl_tsg_release); + return -ENXIO; + } + + /* keep reference on TSG, will be released on + * NVGPU_SCHED_IOCTL_PUT_TSG ioctl, or close + */ + NVGPU_SCHED_SET(tsgid, sched->ref_tsg_bitmap); + nvgpu_mutex_release(&sched->status_lock); + + return 0; +} + +static int gk20a_sched_dev_ioctl_put_tsg(struct gk20a *g, + struct nvgpu_sched_tsg_refcount_args *arg) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + struct fifo_gk20a *f = &g->fifo; + struct tsg_gk20a *tsg; + u32 tsgid = arg->tsgid; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsgid); + + if (tsgid >= f->num_channels) + return -EINVAL; + + nvgpu_speculation_barrier(); + + nvgpu_mutex_acquire(&sched->status_lock); + if (!NVGPU_SCHED_ISSET(tsgid, sched->ref_tsg_bitmap)) { + nvgpu_mutex_release(&sched->status_lock); + nvgpu_warn(g, "tsgid=%d not previously referenced", tsgid); + return -ENXIO; + } + NVGPU_SCHED_CLR(tsgid, sched->ref_tsg_bitmap); + nvgpu_mutex_release(&sched->status_lock); + + tsg = &f->tsg[tsgid]; + nvgpu_ref_put(&tsg->refcount, nvgpu_ioctl_tsg_release); + + return 0; +} + +int gk20a_sched_dev_open(struct inode *inode, struct file *filp) +{ + struct nvgpu_os_linux *l = container_of(inode->i_cdev, + struct nvgpu_os_linux, sched.cdev); + struct gk20a *g; + struct nvgpu_sched_ctrl *sched; + int err = 0; + + g = gk20a_get(&l->g); + if (!g) + return -ENODEV; + sched = &g->sched_ctrl; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "g=%p", g); + + if (!sched->sw_ready) { + err = gk20a_busy(g); + if (err) + goto free_ref; + + gk20a_idle(g); + } + + if (!nvgpu_mutex_tryacquire(&sched->busy_lock)) { + err = -EBUSY; + goto free_ref; + } + + memcpy(sched->recent_tsg_bitmap, sched->active_tsg_bitmap, + sched->bitmap_size); + memset(sched->ref_tsg_bitmap, 0, sched->bitmap_size); + + filp->private_data = g; + nvgpu_log(g, gpu_dbg_sched, "filp=%p sched=%p", filp, sched); + +free_ref: + if (err) + gk20a_put(g); + return err; +} + +long gk20a_sched_dev_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct gk20a *g = filp->private_data; + u8 buf[NVGPU_CTXSW_IOCTL_MAX_ARG_SIZE]; + int err = 0; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "nr=%d", _IOC_NR(cmd)); + + if ((_IOC_TYPE(cmd) != NVGPU_SCHED_IOCTL_MAGIC) || + (_IOC_NR(cmd) == 0) || + (_IOC_NR(cmd) > NVGPU_SCHED_IOCTL_LAST) || + (_IOC_SIZE(cmd) > NVGPU_SCHED_IOCTL_MAX_ARG_SIZE)) + return -EINVAL; + + memset(buf, 0, sizeof(buf)); + if (_IOC_DIR(cmd) & _IOC_WRITE) { + if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + } + + nvgpu_speculation_barrier(); + switch (cmd) { + case NVGPU_SCHED_IOCTL_GET_TSGS: + err = gk20a_sched_dev_ioctl_get_tsgs(g, + (struct nvgpu_sched_get_tsgs_args *)buf); + break; + case NVGPU_SCHED_IOCTL_GET_RECENT_TSGS: + err = gk20a_sched_dev_ioctl_get_recent_tsgs(g, + (struct nvgpu_sched_get_tsgs_args *)buf); + break; + case NVGPU_SCHED_IOCTL_GET_TSGS_BY_PID: + err = gk20a_sched_dev_ioctl_get_tsgs_by_pid(g, + (struct nvgpu_sched_get_tsgs_by_pid_args *)buf); + break; + case NVGPU_SCHED_IOCTL_TSG_GET_PARAMS: + err = gk20a_sched_dev_ioctl_get_params(g, + (struct nvgpu_sched_tsg_get_params_args *)buf); + break; + case NVGPU_SCHED_IOCTL_TSG_SET_TIMESLICE: + err = gk20a_sched_dev_ioctl_tsg_set_timeslice(g, + (struct nvgpu_sched_tsg_timeslice_args *)buf); + break; + case NVGPU_SCHED_IOCTL_TSG_SET_RUNLIST_INTERLEAVE: + err = gk20a_sched_dev_ioctl_tsg_set_runlist_interleave(g, + (struct nvgpu_sched_tsg_runlist_interleave_args *)buf); + break; + case NVGPU_SCHED_IOCTL_LOCK_CONTROL: + err = gk20a_sched_dev_ioctl_lock_control(g); + break; + case NVGPU_SCHED_IOCTL_UNLOCK_CONTROL: + err = gk20a_sched_dev_ioctl_unlock_control(g); + break; + case NVGPU_SCHED_IOCTL_GET_API_VERSION: + err = gk20a_sched_dev_ioctl_get_api_version(g, + (struct nvgpu_sched_api_version_args *)buf); + break; + case NVGPU_SCHED_IOCTL_GET_TSG: + err = gk20a_sched_dev_ioctl_get_tsg(g, + (struct nvgpu_sched_tsg_refcount_args *)buf); + break; + case NVGPU_SCHED_IOCTL_PUT_TSG: + err = gk20a_sched_dev_ioctl_put_tsg(g, + (struct nvgpu_sched_tsg_refcount_args *)buf); + break; + default: + nvgpu_log_info(g, "unrecognized gpu ioctl cmd: 0x%x", cmd); + err = -ENOTTY; + } + + /* Some ioctls like NVGPU_SCHED_IOCTL_GET_TSGS might be called on + * purpose with NULL buffer and/or zero size to discover TSG bitmap + * size. We need to update user arguments in this case too, even + * if we return an error. + */ + if ((!err || (err == -ENOSPC)) && (_IOC_DIR(cmd) & _IOC_READ)) { + if (copy_to_user((void __user *)arg, buf, _IOC_SIZE(cmd))) + err = -EFAULT; + } + + return err; +} + +int gk20a_sched_dev_release(struct inode *inode, struct file *filp) +{ + struct gk20a *g = filp->private_data; + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + struct fifo_gk20a *f = &g->fifo; + struct tsg_gk20a *tsg; + unsigned int tsgid; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "sched: %p", sched); + + /* release any reference to TSGs */ + for (tsgid = 0; tsgid < f->num_channels; tsgid++) { + if (NVGPU_SCHED_ISSET(tsgid, sched->ref_tsg_bitmap)) { + tsg = &f->tsg[tsgid]; + nvgpu_ref_put(&tsg->refcount, nvgpu_ioctl_tsg_release); + } + } + + /* unlock control */ + nvgpu_mutex_acquire(&sched->control_lock); + sched->control_locked = false; + nvgpu_mutex_release(&sched->control_lock); + + nvgpu_mutex_release(&sched->busy_lock); + gk20a_put(g); + return 0; +} + +void gk20a_sched_ctrl_tsg_added(struct gk20a *g, struct tsg_gk20a *tsg) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + int err; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsg->tsgid); + + if (!sched->sw_ready) { + err = gk20a_busy(g); + if (err) { + WARN_ON(err); + return; + } + + gk20a_idle(g); + } + + nvgpu_mutex_acquire(&sched->status_lock); + NVGPU_SCHED_SET(tsg->tsgid, sched->active_tsg_bitmap); + NVGPU_SCHED_SET(tsg->tsgid, sched->recent_tsg_bitmap); + sched->status |= NVGPU_SCHED_STATUS_TSG_OPEN; + nvgpu_mutex_release(&sched->status_lock); + nvgpu_cond_signal_interruptible(&sched->readout_wq); +} + +void gk20a_sched_ctrl_tsg_removed(struct gk20a *g, struct tsg_gk20a *tsg) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsg->tsgid); + + nvgpu_mutex_acquire(&sched->status_lock); + NVGPU_SCHED_CLR(tsg->tsgid, sched->active_tsg_bitmap); + + /* clear recent_tsg_bitmap as well: if app manager did not + * notice that TSG was previously added, no need to notify it + * if the TSG has been released in the meantime. If the + * TSG gets reallocated, app manager will be notified as usual. + */ + NVGPU_SCHED_CLR(tsg->tsgid, sched->recent_tsg_bitmap); + + /* do not set event_pending, we only want to notify app manager + * when TSGs are added, so that it can apply sched params + */ + nvgpu_mutex_release(&sched->status_lock); +} + +int gk20a_sched_ctrl_init(struct gk20a *g) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + struct fifo_gk20a *f = &g->fifo; + int err; + + if (sched->sw_ready) + return 0; + + sched->bitmap_size = roundup(f->num_channels, 64) / 8; + sched->status = 0; + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "g=%p sched=%p size=%zu", + g, sched, sched->bitmap_size); + + sched->active_tsg_bitmap = nvgpu_kzalloc(g, sched->bitmap_size); + if (!sched->active_tsg_bitmap) + return -ENOMEM; + + sched->recent_tsg_bitmap = nvgpu_kzalloc(g, sched->bitmap_size); + if (!sched->recent_tsg_bitmap) { + err = -ENOMEM; + goto free_active; + } + + sched->ref_tsg_bitmap = nvgpu_kzalloc(g, sched->bitmap_size); + if (!sched->ref_tsg_bitmap) { + err = -ENOMEM; + goto free_recent; + } + + nvgpu_cond_init(&sched->readout_wq); + + err = nvgpu_mutex_init(&sched->status_lock); + if (err) + goto free_ref; + + err = nvgpu_mutex_init(&sched->control_lock); + if (err) + goto free_status_lock; + + err = nvgpu_mutex_init(&sched->busy_lock); + if (err) + goto free_control_lock; + + sched->sw_ready = true; + + return 0; + +free_control_lock: + nvgpu_mutex_destroy(&sched->control_lock); +free_status_lock: + nvgpu_mutex_destroy(&sched->status_lock); +free_ref: + nvgpu_kfree(g, sched->ref_tsg_bitmap); +free_recent: + nvgpu_kfree(g, sched->recent_tsg_bitmap); +free_active: + nvgpu_kfree(g, sched->active_tsg_bitmap); + + return err; +} + +void gk20a_sched_ctrl_cleanup(struct gk20a *g) +{ + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + + nvgpu_kfree(g, sched->active_tsg_bitmap); + nvgpu_kfree(g, sched->recent_tsg_bitmap); + nvgpu_kfree(g, sched->ref_tsg_bitmap); + sched->active_tsg_bitmap = NULL; + sched->recent_tsg_bitmap = NULL; + sched->ref_tsg_bitmap = NULL; + + nvgpu_mutex_destroy(&sched->status_lock); + nvgpu_mutex_destroy(&sched->control_lock); + nvgpu_mutex_destroy(&sched->busy_lock); + + sched->sw_ready = false; +} diff --git a/include/os/linux/sched.h b/include/os/linux/sched.h new file mode 100644 index 0000000..e88f37f --- /dev/null +++ b/include/os/linux/sched.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __NVGPU_SCHED_H +#define __NVGPU_SCHED_H + +struct gk20a; +struct gpu_ops; +struct tsg_gk20a; +struct poll_table_struct; + +int gk20a_sched_dev_release(struct inode *inode, struct file *filp); +int gk20a_sched_dev_open(struct inode *inode, struct file *filp); +long gk20a_sched_dev_ioctl(struct file *, unsigned int, unsigned long); +ssize_t gk20a_sched_dev_read(struct file *, char __user *, size_t, loff_t *); +unsigned int gk20a_sched_dev_poll(struct file *, struct poll_table_struct *); + +void gk20a_sched_ctrl_tsg_added(struct gk20a *, struct tsg_gk20a *); +void gk20a_sched_ctrl_tsg_removed(struct gk20a *, struct tsg_gk20a *); +int gk20a_sched_ctrl_init(struct gk20a *); + +void gk20a_sched_ctrl_cleanup(struct gk20a *g); + +#endif /* __NVGPU_SCHED_H */ diff --git a/include/os/linux/sim.c b/include/os/linux/sim.c new file mode 100644 index 0000000..792ce80 --- /dev/null +++ b/include/os/linux/sim.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "platform_gk20a.h" +#include "os_linux.h" +#include "module.h" + +void sim_writel(struct sim_nvgpu *sim, u32 r, u32 v) +{ + struct sim_nvgpu_linux *sim_linux = + container_of(sim, struct sim_nvgpu_linux, sim); + + writel(v, sim_linux->regs + r); +} + +u32 sim_readl(struct sim_nvgpu *sim, u32 r) +{ + struct sim_nvgpu_linux *sim_linux = + container_of(sim, struct sim_nvgpu_linux, sim); + + return readl(sim_linux->regs + r); +} + +void nvgpu_remove_sim_support_linux(struct gk20a *g) +{ + struct sim_nvgpu_linux *sim_linux; + + if (!g->sim) + return; + + sim_linux = container_of(g->sim, struct sim_nvgpu_linux, sim); + if (sim_linux->regs) { + sim_writel(g->sim, sim_config_r(), sim_config_mode_disabled_v()); + iounmap(sim_linux->regs); + sim_linux->regs = NULL; + } + nvgpu_kfree(g, sim_linux); + g->sim = NULL; +} + +int nvgpu_init_sim_support_linux(struct gk20a *g, + struct platform_device *dev) +{ + struct sim_nvgpu_linux *sim_linux; + int err = -ENOMEM; + + if (!nvgpu_platform_is_simulation(g)) + return 0; + + sim_linux = nvgpu_kzalloc(g, sizeof(*sim_linux)); + if (!sim_linux) + return err; + g->sim = &sim_linux->sim; + g->sim->g = g; + sim_linux->regs = nvgpu_devm_ioremap_resource(dev, + GK20A_SIM_IORESOURCE_MEM, + &sim_linux->reg_mem); + if (IS_ERR(sim_linux->regs)) { + nvgpu_err(g, "failed to remap gk20a sim regs"); + err = PTR_ERR(sim_linux->regs); + goto fail; + } + sim_linux->remove_support_linux = nvgpu_remove_sim_support_linux; + return 0; + +fail: + nvgpu_remove_sim_support_linux(g); + return err; +} diff --git a/include/os/linux/sim_pci.c b/include/os/linux/sim_pci.c new file mode 100644 index 0000000..340f1fa --- /dev/null +++ b/include/os/linux/sim_pci.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "os_linux.h" +#include "module.h" + +static bool _nvgpu_pci_is_simulation(struct gk20a *g, u32 sim_base) +{ + u32 cfg; + bool is_simulation = false; + + cfg = nvgpu_readl(g, sim_base + sim_config_r()); + if (sim_config_mode_v(cfg) == sim_config_mode_enabled_v()) + is_simulation = true; + + return is_simulation; +} + +void nvgpu_remove_sim_support_linux_pci(struct gk20a *g) +{ + struct sim_nvgpu_linux *sim_linux; + bool is_simulation; + + is_simulation = _nvgpu_pci_is_simulation(g, sim_r()); + + if (!is_simulation) { + return; + } + + if (!g->sim) { + nvgpu_warn(g, "sim_gk20a not allocated"); + return; + } + sim_linux = container_of(g->sim, struct sim_nvgpu_linux, sim); + + if (sim_linux->regs) { + sim_writel(g->sim, sim_config_r(), sim_config_mode_disabled_v()); + sim_linux->regs = NULL; + } + nvgpu_kfree(g, sim_linux); + g->sim = NULL; +} + +int nvgpu_init_sim_support_linux_pci(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct sim_nvgpu_linux *sim_linux; + int err = -ENOMEM; + bool is_simulation; + + is_simulation = _nvgpu_pci_is_simulation(g, sim_r()); + __nvgpu_set_enabled(g, NVGPU_IS_FMODEL, is_simulation); + + if (!is_simulation) + return 0; + + sim_linux = nvgpu_kzalloc(g, sizeof(*sim_linux)); + if (!sim_linux) + return err; + g->sim = &sim_linux->sim; + g->sim->g = g; + sim_linux->regs = l->regs + sim_r(); + sim_linux->remove_support_linux = nvgpu_remove_sim_support_linux_pci; + + return 0; +} diff --git a/include/os/linux/soc.c b/include/os/linux/soc.c new file mode 100644 index 0000000..1b27d6f --- /dev/null +++ b/include/os/linux/soc.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#ifdef CONFIG_TEGRA_HV_MANAGER +#include +#endif + +#include +#include "os_linux.h" +#include "platform_gk20a.h" + +bool nvgpu_platform_is_silicon(struct gk20a *g) +{ + return tegra_platform_is_silicon(); +} + +bool nvgpu_platform_is_simulation(struct gk20a *g) +{ + return tegra_platform_is_vdk(); +} + +bool nvgpu_platform_is_fpga(struct gk20a *g) +{ + return tegra_platform_is_fpga(); +} + +bool nvgpu_is_hypervisor_mode(struct gk20a *g) +{ + return is_tegra_hypervisor_mode(); +} + +bool nvgpu_is_bpmp_running(struct gk20a *g) +{ + return tegra_bpmp_running(); +} + +bool nvgpu_is_soc_t194_a01(struct gk20a *g) +{ + return ((tegra_get_chip_id() == TEGRA194 && + tegra_chip_get_revision() == TEGRA194_REVISION_A01) ? + true : false); +} + +#ifdef CONFIG_TEGRA_HV_MANAGER +/* When nvlink is enabled on dGPU, we need to use physical memory addresses. + * There is no SMMU translation. However, the device initially enumerates as a + * PCIe device. As such, when allocation memory for this PCIe device, the DMA + * framework ends up allocating memory using SMMU (if enabled in device tree). + * As a result, when we switch to nvlink, we need to use underlying physical + * addresses, even if memory mappings exist in SMMU. + * In addition, when stage-2 SMMU translation is enabled (for instance when HV + * is enabled), the addresses we get from dma_alloc are IPAs. We need to + * convert them to PA. + */ +static u64 nvgpu_tegra_hv_ipa_pa(struct gk20a *g, u64 ipa) +{ + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct hyp_ipa_pa_info info; + int err; + u64 pa = 0ULL; + + err = hyp_read_ipa_pa_info(&info, platform->vmid, ipa); + if (err < 0) { + /* WAR for bug 2096877 + * hyp_read_ipa_pa_info only looks up RAM mappings. + * assume one to one IPA:PA mapping for syncpt aperture + */ + u64 start = g->syncpt_unit_base; + u64 end = g->syncpt_unit_base + g->syncpt_unit_size; + if ((ipa >= start) && (ipa < end)) { + pa = ipa; + nvgpu_log(g, gpu_dbg_map_v, + "ipa=%llx vmid=%d -> pa=%llx (SYNCPT)\n", + ipa, platform->vmid, pa); + } else { + nvgpu_err(g, "ipa=%llx translation failed vmid=%u err=%d", + ipa, platform->vmid, err); + } + } else { + pa = info.base + info.offset; + nvgpu_log(g, gpu_dbg_map_v, + "ipa=%llx vmid=%d -> pa=%llx " + "base=%llx offset=%llx size=%llx\n", + ipa, platform->vmid, pa, info.base, + info.offset, info.size); + } + return pa; +} +#endif + +int nvgpu_init_soc_vars(struct gk20a *g) +{ +#ifdef CONFIG_TEGRA_HV_MANAGER + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = gk20a_get_platform(dev); + int err; + + if (nvgpu_is_hypervisor_mode(g)) { + err = hyp_read_gid(&platform->vmid); + if (err) { + nvgpu_err(g, "failed to read vmid"); + return err; + } + platform->phys_addr = nvgpu_tegra_hv_ipa_pa; + } +#endif + return 0; +} diff --git a/include/os/linux/sync_sema_android.c b/include/os/linux/sync_sema_android.c new file mode 100644 index 0000000..59e3b7a --- /dev/null +++ b/include/os/linux/sync_sema_android.c @@ -0,0 +1,418 @@ +/* + * Semaphore Sync Framework Integration + * + * Copyright (c) 2017-2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "../linux/channel.h" + +#include "../drivers/staging/android/sync.h" + +#include "sync_sema_android.h" + +static const struct sync_timeline_ops gk20a_sync_timeline_ops; + +struct gk20a_sync_timeline { + struct sync_timeline obj; + u32 max; + u32 min; +}; + +/** + * The sync framework dups pts when merging fences. We share a single + * refcounted gk20a_sync_pt for each duped pt. + */ +struct gk20a_sync_pt { + struct gk20a *g; + struct nvgpu_ref refcount; + u32 thresh; + struct nvgpu_semaphore *sema; + struct gk20a_sync_timeline *obj; + + /* + * Use a spin lock here since it will have better performance + * than a mutex - there should be very little contention on this + * lock. + */ + struct nvgpu_spinlock lock; +}; + +struct gk20a_sync_pt_inst { + struct sync_pt pt; + struct gk20a_sync_pt *shared; +}; + +/** + * Compares sync pt values a and b, both of which will trigger either before + * or after ref (i.e. a and b trigger before ref, or a and b trigger after + * ref). Supplying ref allows us to handle wrapping correctly. + * + * Returns -1 if a < b (a triggers before b) + * 0 if a = b (a and b trigger at the same time) + * 1 if a > b (b triggers before a) + */ +static int __gk20a_sync_pt_compare_ref( + u32 ref, + u32 a, + u32 b) +{ + /* + * We normalize both a and b by subtracting ref from them. + * Denote the normalized values by a_n and b_n. Note that because + * of wrapping, a_n and/or b_n may be negative. + * + * The normalized values a_n and b_n satisfy: + * - a positive value triggers before a negative value + * - a smaller positive value triggers before a greater positive value + * - a smaller negative value (greater in absolute value) triggers + * before a greater negative value (smaller in absolute value). + * + * Thus we can just stick to unsigned arithmetic and compare + * (u32)a_n to (u32)b_n. + * + * Just to reiterate the possible cases: + * + * 1A) ...ref..a....b.... + * 1B) ...ref..b....a.... + * 2A) ...b....ref..a.... b_n < 0 + * 2B) ...a....ref..b.... a_n > 0 + * 3A) ...a....b....ref.. a_n < 0, b_n < 0 + * 3A) ...b....a....ref.. a_n < 0, b_n < 0 + */ + u32 a_n = a - ref; + u32 b_n = b - ref; + if (a_n < b_n) + return -1; + else if (a_n > b_n) + return 1; + else + return 0; +} + +static struct gk20a_sync_pt *to_gk20a_sync_pt(struct sync_pt *pt) +{ + struct gk20a_sync_pt_inst *pti = + container_of(pt, struct gk20a_sync_pt_inst, pt); + return pti->shared; +} +static struct gk20a_sync_timeline *to_gk20a_timeline(struct sync_timeline *obj) +{ + if (WARN_ON(obj->ops != &gk20a_sync_timeline_ops)) + return NULL; + return (struct gk20a_sync_timeline *)obj; +} + +static void gk20a_sync_pt_free_shared(struct nvgpu_ref *ref) +{ + struct gk20a_sync_pt *pt = + container_of(ref, struct gk20a_sync_pt, refcount); + struct gk20a *g = pt->g; + + if (pt->sema) + nvgpu_semaphore_put(pt->sema); + nvgpu_kfree(g, pt); +} + +static struct gk20a_sync_pt *gk20a_sync_pt_create_shared( + struct gk20a *g, + struct gk20a_sync_timeline *obj, + struct nvgpu_semaphore *sema) +{ + struct gk20a_sync_pt *shared; + + shared = nvgpu_kzalloc(g, sizeof(*shared)); + if (!shared) + return NULL; + + nvgpu_ref_init(&shared->refcount); + shared->g = g; + shared->obj = obj; + shared->sema = sema; + shared->thresh = ++obj->max; /* sync framework has a lock */ + + nvgpu_spinlock_init(&shared->lock); + + nvgpu_semaphore_get(sema); + + return shared; +} + +static struct sync_pt *gk20a_sync_pt_create_inst( + struct gk20a *g, + struct gk20a_sync_timeline *obj, + struct nvgpu_semaphore *sema) +{ + struct gk20a_sync_pt_inst *pti; + + pti = (struct gk20a_sync_pt_inst *) + sync_pt_create(&obj->obj, sizeof(*pti)); + if (!pti) + return NULL; + + pti->shared = gk20a_sync_pt_create_shared(g, obj, sema); + if (!pti->shared) { + sync_pt_free(&pti->pt); + return NULL; + } + return &pti->pt; +} + +static void gk20a_sync_pt_free_inst(struct sync_pt *sync_pt) +{ + struct gk20a_sync_pt *pt = to_gk20a_sync_pt(sync_pt); + if (pt) + nvgpu_ref_put(&pt->refcount, gk20a_sync_pt_free_shared); +} + +static struct sync_pt *gk20a_sync_pt_dup_inst(struct sync_pt *sync_pt) +{ + struct gk20a_sync_pt_inst *pti; + struct gk20a_sync_pt *pt = to_gk20a_sync_pt(sync_pt); + + pti = (struct gk20a_sync_pt_inst *) + sync_pt_create(&pt->obj->obj, sizeof(*pti)); + if (!pti) + return NULL; + pti->shared = pt; + nvgpu_ref_get(&pt->refcount); + return &pti->pt; +} + +/* + * This function must be able to run on the same sync_pt concurrently. This + * requires a lock to protect access to the sync_pt's internal data structures + * which are modified as a side effect of calling this function. + */ +static int gk20a_sync_pt_has_signaled(struct sync_pt *sync_pt) +{ + struct gk20a_sync_pt *pt = to_gk20a_sync_pt(sync_pt); + struct gk20a_sync_timeline *obj = pt->obj; + bool signaled = true; + + nvgpu_spinlock_acquire(&pt->lock); + if (!pt->sema) + goto done; + + /* Acquired == not realeased yet == active == not signaled. */ + signaled = !nvgpu_semaphore_is_acquired(pt->sema); + + if (signaled) { + /* Update min if necessary. */ + if (__gk20a_sync_pt_compare_ref(obj->max, pt->thresh, + obj->min) == 1) + obj->min = pt->thresh; + + /* Release the semaphore to the pool. */ + nvgpu_semaphore_put(pt->sema); + pt->sema = NULL; + } +done: + nvgpu_spinlock_release(&pt->lock); + + return signaled; +} + +static int gk20a_sync_pt_compare(struct sync_pt *a, struct sync_pt *b) +{ + bool a_expired; + bool b_expired; + struct gk20a_sync_pt *pt_a = to_gk20a_sync_pt(a); + struct gk20a_sync_pt *pt_b = to_gk20a_sync_pt(b); + + if (WARN_ON(pt_a->obj != pt_b->obj)) + return 0; + + /* Early out */ + if (a == b) + return 0; + + a_expired = gk20a_sync_pt_has_signaled(a); + b_expired = gk20a_sync_pt_has_signaled(b); + if (a_expired && !b_expired) { + /* Easy, a was earlier */ + return -1; + } else if (!a_expired && b_expired) { + /* Easy, b was earlier */ + return 1; + } + + /* Both a and b are expired (trigger before min) or not + * expired (trigger after min), so we can use min + * as a reference value for __gk20a_sync_pt_compare_ref. + */ + return __gk20a_sync_pt_compare_ref(pt_a->obj->min, + pt_a->thresh, pt_b->thresh); +} + +static u32 gk20a_sync_timeline_current(struct gk20a_sync_timeline *obj) +{ + return obj->min; +} + +static void gk20a_sync_timeline_value_str(struct sync_timeline *timeline, + char *str, int size) +{ + struct gk20a_sync_timeline *obj = + (struct gk20a_sync_timeline *)timeline; + snprintf(str, size, "%d", gk20a_sync_timeline_current(obj)); +} + +static void gk20a_sync_pt_value_str_for_sema(struct gk20a_sync_pt *pt, + char *str, int size) +{ + struct nvgpu_semaphore *s = pt->sema; + + snprintf(str, size, "S: pool=%llu [v=%u,r_v=%u]", + s->location.pool->page_idx, + nvgpu_semaphore_get_value(s), + nvgpu_semaphore_read(s)); +} + +static void gk20a_sync_pt_value_str(struct sync_pt *sync_pt, char *str, + int size) +{ + struct gk20a_sync_pt *pt = to_gk20a_sync_pt(sync_pt); + + if (pt->sema) { + gk20a_sync_pt_value_str_for_sema(pt, str, size); + return; + } + + snprintf(str, size, "%d", pt->thresh); +} + +static const struct sync_timeline_ops gk20a_sync_timeline_ops = { + .driver_name = "nvgpu_semaphore", + .dup = gk20a_sync_pt_dup_inst, + .has_signaled = gk20a_sync_pt_has_signaled, + .compare = gk20a_sync_pt_compare, + .free_pt = gk20a_sync_pt_free_inst, + .timeline_value_str = gk20a_sync_timeline_value_str, + .pt_value_str = gk20a_sync_pt_value_str, +}; + +/* Public API */ + +struct sync_fence *gk20a_sync_fence_fdget(int fd) +{ + struct sync_fence *fence = sync_fence_fdget(fd); + int i; + + if (!fence) + return NULL; + + for (i = 0; i < fence->num_fences; i++) { + struct sync_pt *spt = sync_pt_from_fence(fence->cbs[i].sync_pt); + struct sync_timeline *t; + + if (spt == NULL) { + sync_fence_put(fence); + return NULL; + } + + t = sync_pt_parent(spt); + if (t->ops != &gk20a_sync_timeline_ops) { + sync_fence_put(fence); + return NULL; + } + } + + return fence; +} + +struct nvgpu_semaphore *gk20a_sync_pt_sema(struct sync_pt *spt) +{ + struct gk20a_sync_pt *pt = to_gk20a_sync_pt(spt); + struct nvgpu_semaphore *sema; + + nvgpu_spinlock_acquire(&pt->lock); + sema = pt->sema; + if (sema) + nvgpu_semaphore_get(sema); + nvgpu_spinlock_release(&pt->lock); + + return sema; +} + +void gk20a_sync_timeline_signal(struct sync_timeline *timeline) +{ + sync_timeline_signal(timeline, 0); +} + +void gk20a_sync_timeline_destroy(struct sync_timeline *timeline) +{ + sync_timeline_destroy(timeline); +} + +struct sync_timeline *gk20a_sync_timeline_create( + const char *name) +{ + struct gk20a_sync_timeline *obj; + + obj = (struct gk20a_sync_timeline *) + sync_timeline_create(&gk20a_sync_timeline_ops, + sizeof(struct gk20a_sync_timeline), + name); + if (!obj) + return NULL; + obj->max = 0; + obj->min = 0; + return &obj->obj; +} + +struct sync_fence *gk20a_sync_fence_create( + struct channel_gk20a *c, + struct nvgpu_semaphore *sema, + const char *fmt, ...) +{ + char name[30]; + va_list args; + struct sync_pt *pt; + struct sync_fence *fence; + struct gk20a *g = c->g; + + struct nvgpu_channel_linux *os_channel_priv = c->os_priv; + struct nvgpu_os_fence_framework *fence_framework = NULL; + struct gk20a_sync_timeline *timeline = NULL; + + fence_framework = &os_channel_priv->fence_framework; + + timeline = to_gk20a_timeline(fence_framework->timeline); + + pt = gk20a_sync_pt_create_inst(g, timeline, sema); + if (pt == NULL) + return NULL; + + va_start(args, fmt); + vsnprintf(name, sizeof(name), fmt, args); + va_end(args); + + fence = sync_fence_create(name, pt); + if (fence == NULL) { + sync_pt_free(pt); + return NULL; + } + return fence; +} diff --git a/include/os/linux/sync_sema_android.h b/include/os/linux/sync_sema_android.h new file mode 100644 index 0000000..4fca7be --- /dev/null +++ b/include/os/linux/sync_sema_android.h @@ -0,0 +1,51 @@ +/* + * Semaphore Sync Framework Integration + * + * Copyright (c) 2017-2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _GK20A_SYNC_H_ +#define _GK20A_SYNC_H_ + +struct sync_timeline; +struct sync_fence; +struct sync_pt; +struct nvgpu_semaphore; +struct fence; + +#ifdef CONFIG_SYNC +struct sync_timeline *gk20a_sync_timeline_create(const char *name); +void gk20a_sync_timeline_destroy(struct sync_timeline *); +void gk20a_sync_timeline_signal(struct sync_timeline *); +struct sync_fence *gk20a_sync_fence_create( + struct channel_gk20a *c, + struct nvgpu_semaphore *, + const char *fmt, ...); +struct sync_fence *gk20a_sync_fence_fdget(int fd); +struct nvgpu_semaphore *gk20a_sync_pt_sema(struct sync_pt *spt); +#else +static inline void gk20a_sync_timeline_destroy(struct sync_timeline *obj) {} +static inline void gk20a_sync_timeline_signal(struct sync_timeline *obj) {} +static inline struct sync_fence *gk20a_sync_fence_fdget(int fd) +{ + return NULL; +} +static inline struct sync_timeline *gk20a_sync_timeline_create( + const char *name) { + return NULL; +} +#endif + +#endif diff --git a/include/os/linux/sysfs.c b/include/os/linux/sysfs.c new file mode 100644 index 0000000..221ea0c --- /dev/null +++ b/include/os/linux/sysfs.c @@ -0,0 +1,1275 @@ +/* + * Copyright (c) 2011-2019, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "os_linux.h" +#include "sysfs.h" +#include "platform_gk20a.h" +#include "gk20a/gr_gk20a.h" +#include "gv11b/gr_gv11b.h" + +#define PTIMER_FP_FACTOR 1000000 + +#define ROOTRW (S_IRWXU|S_IRGRP|S_IROTH) + +#define TPC_MASK_FOR_ALL_ACTIVE_TPCs (u32) 0x0 + +static ssize_t elcg_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val = 0; + int err; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + err = gk20a_busy(g); + if (err) + return err; + + if (val) { + nvgpu_cg_elcg_set_elcg_enabled(g, true); + } else { + nvgpu_cg_elcg_set_elcg_enabled(g, false); + } + + gk20a_idle(g); + + nvgpu_info(g, "ELCG is %s.", val ? "enabled" : + "disabled"); + + return count; +} + +static ssize_t elcg_enable_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", g->elcg_enabled ? 1 : 0); +} + +static DEVICE_ATTR(elcg_enable, ROOTRW, elcg_enable_read, elcg_enable_store); + +static ssize_t blcg_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val = 0; + int err; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + err = gk20a_busy(g); + if (err) + return err; + + if (val) { + nvgpu_cg_blcg_set_blcg_enabled(g, true); + } else { + nvgpu_cg_blcg_set_blcg_enabled(g, false); + } + + gk20a_idle(g); + + nvgpu_info(g, "BLCG is %s.", val ? "enabled" : + "disabled"); + + return count; +} + +static ssize_t blcg_enable_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", g->blcg_enabled ? 1 : 0); +} + + +static DEVICE_ATTR(blcg_enable, ROOTRW, blcg_enable_read, blcg_enable_store); + +static ssize_t slcg_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val = 0; + int err; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + err = gk20a_busy(g); + if (err) { + return err; + } + + if (val) { + nvgpu_cg_slcg_set_slcg_enabled(g, true); + } else { + nvgpu_cg_slcg_set_slcg_enabled(g, false); + } + + /* + * TODO: slcg_therm_load_gating is not enabled anywhere during + * init. Therefore, it would be incongruous to add it here. Once + * it is added to init, we should add it here too. + */ + gk20a_idle(g); + + nvgpu_info(g, "SLCG is %s.", val ? "enabled" : + "disabled"); + + return count; +} + +static ssize_t slcg_enable_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", g->slcg_enabled ? 1 : 0); +} + +static DEVICE_ATTR(slcg_enable, ROOTRW, slcg_enable_read, slcg_enable_store); + +static ssize_t ptimer_scale_factor_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct gk20a *g = get_gk20a(dev); + struct gk20a_platform *platform = dev_get_drvdata(dev); + u32 src_freq_hz = platform->ptimer_src_freq; + u32 scaling_factor_fp; + ssize_t res; + + if (!src_freq_hz) { + nvgpu_err(g, "reference clk_m rate is not set correctly"); + return -EINVAL; + } + + scaling_factor_fp = (u32)(PTIMER_REF_FREQ_HZ) / + ((u32)(src_freq_hz) / + (u32)(PTIMER_FP_FACTOR)); + res = snprintf(buf, + PAGE_SIZE, + "%u.%u\n", + scaling_factor_fp / PTIMER_FP_FACTOR, + scaling_factor_fp % PTIMER_FP_FACTOR); + + return res; + +} + +static DEVICE_ATTR(ptimer_scale_factor, + S_IRUGO, + ptimer_scale_factor_show, + NULL); + +static ssize_t ptimer_ref_freq_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct gk20a *g = get_gk20a(dev); + struct gk20a_platform *platform = dev_get_drvdata(dev); + u32 src_freq_hz = platform->ptimer_src_freq; + ssize_t res; + + if (!src_freq_hz) { + nvgpu_err(g, "reference clk_m rate is not set correctly"); + return -EINVAL; + } + + res = snprintf(buf, PAGE_SIZE, "%u\n", PTIMER_REF_FREQ_HZ); + + return res; + +} + +static DEVICE_ATTR(ptimer_ref_freq, + S_IRUGO, + ptimer_ref_freq_show, + NULL); + +static ssize_t ptimer_src_freq_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct gk20a *g = get_gk20a(dev); + struct gk20a_platform *platform = dev_get_drvdata(dev); + u32 src_freq_hz = platform->ptimer_src_freq; + ssize_t res; + + if (!src_freq_hz) { + nvgpu_err(g, "reference clk_m rate is not set correctly"); + return -EINVAL; + } + + res = snprintf(buf, PAGE_SIZE, "%u\n", src_freq_hz); + + return res; + +} + +static DEVICE_ATTR(ptimer_src_freq, + S_IRUGO, + ptimer_src_freq_show, + NULL); + + +static ssize_t gpu_powered_on_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", g->power_on); +} + +static DEVICE_ATTR(gpu_powered_on, S_IRUGO, gpu_powered_on_show, NULL); + +#if defined(CONFIG_PM) +static ssize_t railgate_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned long railgate_enable = 0; + /* dev is guaranteed to be valid here. Ok to de-reference */ + struct gk20a *g = get_gk20a(dev); + struct gk20a_platform *platform = dev_get_drvdata(dev); + bool enabled = nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE); + int err; + + if (kstrtoul(buf, 10, &railgate_enable) < 0) + return -EINVAL; + + /* convert to boolean */ + railgate_enable = !!railgate_enable; + + /* writing same value should be treated as nop and successful */ + if (railgate_enable == enabled) + goto out; + + if (!platform->can_railgate_init) { + nvgpu_err(g, "Railgating is not supported"); + return -EINVAL; + } + + if (railgate_enable) { + __nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, true); + pm_runtime_set_autosuspend_delay(dev, g->railgate_delay); + } else { + __nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, false); + pm_runtime_set_autosuspend_delay(dev, -1); + } + /* wake-up system to make rail-gating setting effective */ + err = gk20a_busy(g); + if (err) + return err; + gk20a_idle(g); + +out: + nvgpu_info(g, "railgate is %s.", + nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE) ? + "enabled" : "disabled"); + + return count; +} + +static ssize_t railgate_enable_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", + nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE) ? 1 : 0); +} + +static DEVICE_ATTR(railgate_enable, ROOTRW, railgate_enable_read, + railgate_enable_store); +#endif + +static ssize_t railgate_delay_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int railgate_delay = 0, ret = 0; + struct gk20a *g = get_gk20a(dev); + int err; + + if (!nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE)) { + nvgpu_info(g, "does not support power-gating"); + return count; + } + + ret = sscanf(buf, "%d", &railgate_delay); + if (ret == 1 && railgate_delay >= 0) { + g->railgate_delay = railgate_delay; + pm_runtime_set_autosuspend_delay(dev, g->railgate_delay); + } else + nvgpu_err(g, "Invalid powergate delay"); + + /* wake-up system to make rail-gating delay effective immediately */ + err = gk20a_busy(g); + if (err) + return err; + gk20a_idle(g); + + return count; +} +static ssize_t railgate_delay_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", g->railgate_delay); +} +static DEVICE_ATTR(railgate_delay, ROOTRW, railgate_delay_show, + railgate_delay_store); + +static ssize_t is_railgated_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a_platform *platform = dev_get_drvdata(dev); + bool is_railgated = 0; + + if (platform->is_railgated) + is_railgated = platform->is_railgated(dev); + + return snprintf(buf, PAGE_SIZE, "%s\n", is_railgated ? "yes" : "no"); +} +static DEVICE_ATTR(is_railgated, S_IRUGO, is_railgated_show, NULL); + +static ssize_t counters_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + u32 busy_cycles, total_cycles; + ssize_t res; + + nvgpu_pmu_get_load_counters(g, &busy_cycles, &total_cycles); + + res = snprintf(buf, PAGE_SIZE, "%u %u\n", busy_cycles, total_cycles); + + return res; +} +static DEVICE_ATTR(counters, S_IRUGO, counters_show, NULL); + +static ssize_t counters_show_reset(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t res = counters_show(dev, attr, buf); + struct gk20a *g = get_gk20a(dev); + + nvgpu_pmu_reset_load_counters(g); + + return res; +} +static DEVICE_ATTR(counters_reset, S_IRUGO, counters_show_reset, NULL); + +static ssize_t gk20a_load_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct gk20a *g = get_gk20a(dev); + u32 busy_time; + ssize_t res; + int err; + + if (!g->power_on) { + busy_time = 0; + } else { + err = gk20a_busy(g); + if (err) + return err; + + nvgpu_pmu_load_update(g); + nvgpu_pmu_load_norm(g, &busy_time); + gk20a_idle(g); + } + + res = snprintf(buf, PAGE_SIZE, "%u\n", busy_time); + + return res; +} +static DEVICE_ATTR(load, S_IRUGO, gk20a_load_show, NULL); + +static ssize_t elpg_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val = 0; + int err; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (!g->power_on) { + return -EINVAL; + } else { + err = gk20a_busy(g); + if (err) + return -EAGAIN; + /* + * Since elpg is refcounted, we should not unnecessarily call + * enable/disable if it is already so. + */ + if (val != 0) { + nvgpu_pg_elpg_set_elpg_enabled(g, true); + } else { + nvgpu_pg_elpg_set_elpg_enabled(g, false); + } + gk20a_idle(g); + } + nvgpu_info(g, "ELPG is %s.", val ? "enabled" : + "disabled"); + + return count; +} + +static ssize_t elpg_enable_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", + nvgpu_pg_elpg_is_enabled(g) ? 1 : 0); +} + +static DEVICE_ATTR(elpg_enable, ROOTRW, elpg_enable_read, elpg_enable_store); + +static ssize_t ldiv_slowdown_factor_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val = 0; + int err; + + if (kstrtoul(buf, 10, &val) < 0) { + nvgpu_err(g, "parse error for input SLOWDOWN factor\n"); + return -EINVAL; + } + + if (val >= SLOWDOWN_FACTOR_FPDIV_BYMAX) { + nvgpu_err(g, "Invalid SLOWDOWN factor\n"); + return -EINVAL; + } + + if (val == g->ldiv_slowdown_factor) + return count; + + if (!g->power_on) { + g->ldiv_slowdown_factor = val; + } else { + err = gk20a_busy(g); + if (err) + return -EAGAIN; + + g->ldiv_slowdown_factor = val; + + if (g->ops.pmu.pmu_pg_init_param) + g->ops.pmu.pmu_pg_init_param(g, + PMU_PG_ELPG_ENGINE_ID_GRAPHICS); + + gk20a_idle(g); + } + + nvgpu_info(g, "ldiv_slowdown_factor is %x\n", g->ldiv_slowdown_factor); + + return count; +} + +static ssize_t ldiv_slowdown_factor_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", g->ldiv_slowdown_factor); +} + +static DEVICE_ATTR(ldiv_slowdown_factor, ROOTRW, + ldiv_slowdown_factor_read, ldiv_slowdown_factor_store); + +static ssize_t mscg_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + struct nvgpu_pmu *pmu = &g->pmu; + unsigned long val = 0; + int err; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (!g->power_on) { + g->mscg_enabled = val ? true : false; + } else { + err = gk20a_busy(g); + if (err) + return -EAGAIN; + /* + * Since elpg is refcounted, we should not unnecessarily call + * enable/disable if it is already so. + */ + if (val && !g->mscg_enabled) { + g->mscg_enabled = true; + if (g->ops.pmu.pmu_is_lpwr_feature_supported(g, + PMU_PG_LPWR_FEATURE_MSCG)) { + if (!ACCESS_ONCE(pmu->mscg_stat)) { + WRITE_ONCE(pmu->mscg_stat, + PMU_MSCG_ENABLED); + /* make status visible */ + smp_mb(); + } + } + + } else if (!val && g->mscg_enabled) { + if (g->ops.pmu.pmu_is_lpwr_feature_supported(g, + PMU_PG_LPWR_FEATURE_MSCG)) { + nvgpu_pmu_pg_global_enable(g, false); + WRITE_ONCE(pmu->mscg_stat, PMU_MSCG_DISABLED); + /* make status visible */ + smp_mb(); + g->mscg_enabled = false; + if (nvgpu_pg_elpg_is_enabled(g)) { + nvgpu_pg_elpg_enable(g); + } + } + g->mscg_enabled = false; + } + gk20a_idle(g); + } + nvgpu_info(g, "MSCG is %s.", g->mscg_enabled ? "enabled" : + "disabled"); + + return count; +} + +static ssize_t mscg_enable_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", g->mscg_enabled ? 1 : 0); +} + +static DEVICE_ATTR(mscg_enable, ROOTRW, mscg_enable_read, mscg_enable_store); + +static ssize_t aelpg_param_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + int status = 0; + union pmu_ap_cmd ap_cmd; + int *paramlist = (int *)g->pmu.aelpg_param; + u32 defaultparam[5] = { + APCTRL_SAMPLING_PERIOD_PG_DEFAULT_US, + APCTRL_MINIMUM_IDLE_FILTER_DEFAULT_US, + APCTRL_MINIMUM_TARGET_SAVING_DEFAULT_US, + APCTRL_POWER_BREAKEVEN_DEFAULT_US, + APCTRL_CYCLES_PER_SAMPLE_MAX_DEFAULT + }; + + /* Get each parameter value from input string*/ + sscanf(buf, "%d %d %d %d %d", ¶mlist[0], ¶mlist[1], + ¶mlist[2], ¶mlist[3], ¶mlist[4]); + + /* If parameter value is 0 then reset to SW default values*/ + if ((paramlist[0] | paramlist[1] | paramlist[2] + | paramlist[3] | paramlist[4]) == 0x00) { + memcpy(paramlist, defaultparam, sizeof(defaultparam)); + } + + /* If aelpg is enabled & pmu is ready then post values to + * PMU else store then post later + */ + if (g->aelpg_enabled && g->pmu.pmu_ready) { + /* Disable AELPG */ + ap_cmd.disable_ctrl.cmd_id = PMU_AP_CMD_ID_DISABLE_CTRL; + ap_cmd.disable_ctrl.ctrl_id = PMU_AP_CTRL_ID_GRAPHICS; + status = nvgpu_pmu_ap_send_command(g, &ap_cmd, false); + + /* Enable AELPG */ + nvgpu_aelpg_init(g); + nvgpu_aelpg_init_and_enable(g, PMU_AP_CTRL_ID_GRAPHICS); + } + + return count; +} + +static ssize_t aelpg_param_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, + "%d %d %d %d %d\n", g->pmu.aelpg_param[0], + g->pmu.aelpg_param[1], g->pmu.aelpg_param[2], + g->pmu.aelpg_param[3], g->pmu.aelpg_param[4]); +} + +static DEVICE_ATTR(aelpg_param, ROOTRW, + aelpg_param_read, aelpg_param_store); + +static ssize_t aelpg_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val = 0; + int status = 0; + union pmu_ap_cmd ap_cmd; + int err; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + err = gk20a_busy(g); + if (err) + return err; + + if (g->pmu.pmu_ready) { + if (val && !g->aelpg_enabled) { + g->aelpg_enabled = true; + /* Enable AELPG */ + ap_cmd.enable_ctrl.cmd_id = PMU_AP_CMD_ID_ENABLE_CTRL; + ap_cmd.enable_ctrl.ctrl_id = PMU_AP_CTRL_ID_GRAPHICS; + status = nvgpu_pmu_ap_send_command(g, &ap_cmd, false); + } else if (!val && g->aelpg_enabled) { + g->aelpg_enabled = false; + /* Disable AELPG */ + ap_cmd.disable_ctrl.cmd_id = PMU_AP_CMD_ID_DISABLE_CTRL; + ap_cmd.disable_ctrl.ctrl_id = PMU_AP_CTRL_ID_GRAPHICS; + status = nvgpu_pmu_ap_send_command(g, &ap_cmd, false); + } + } else { + nvgpu_info(g, "PMU is not ready, AELPG request failed"); + } + gk20a_idle(g); + + nvgpu_info(g, "AELPG is %s.", g->aelpg_enabled ? "enabled" : + "disabled"); + + return count; +} + +static ssize_t aelpg_enable_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", g->aelpg_enabled ? 1 : 0); +} + +static DEVICE_ATTR(aelpg_enable, ROOTRW, + aelpg_enable_read, aelpg_enable_store); + + +static ssize_t allow_all_enable_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", g->allow_all ? 1 : 0); +} + +static ssize_t allow_all_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val = 0; + int err; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + err = gk20a_busy(g); + g->allow_all = (val ? true : false); + gk20a_idle(g); + + return count; +} + +static DEVICE_ATTR(allow_all, ROOTRW, + allow_all_enable_read, allow_all_enable_store); + +static ssize_t emc3d_ratio_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val = 0; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + g->emc3d_ratio = val; + + return count; +} + +static ssize_t emc3d_ratio_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", g->emc3d_ratio); +} + +static DEVICE_ATTR(emc3d_ratio, ROOTRW, emc3d_ratio_read, emc3d_ratio_store); + +static ssize_t fmax_at_vmin_safe_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long gpu_fmax_at_vmin_hz = 0; + + if (g->ops.clk.get_fmax_at_vmin_safe) + gpu_fmax_at_vmin_hz = g->ops.clk.get_fmax_at_vmin_safe(g); + + return snprintf(buf, PAGE_SIZE, "%d\n", (int)(gpu_fmax_at_vmin_hz)); +} + +static DEVICE_ATTR(fmax_at_vmin_safe, S_IRUGO, fmax_at_vmin_safe_read, NULL); + +#ifdef CONFIG_PM +static ssize_t force_idle_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val = 0; + int err = 0; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (val) { + if (g->forced_idle) + return count; /* do nothing */ + else { + err = __gk20a_do_idle(g, false); + if (!err) { + g->forced_idle = 1; + nvgpu_info(g, "gpu is idle : %d", + g->forced_idle); + } + } + } else { + if (!g->forced_idle) + return count; /* do nothing */ + else { + err = __gk20a_do_unidle(g); + if (!err) { + g->forced_idle = 0; + nvgpu_info(g, "gpu is idle : %d", + g->forced_idle); + } + } + } + + return count; +} + +static ssize_t force_idle_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", g->forced_idle ? 1 : 0); +} + +static DEVICE_ATTR(force_idle, ROOTRW, force_idle_read, force_idle_store); +#endif + +static bool is_tpc_mask_valid(struct gk20a *g, u32 tpc_mask) +{ + u32 i; + bool valid = false; + + for (i = 0; i < MAX_TPC_PG_CONFIGS; i++) { + if (tpc_mask == g->valid_tpc_mask[i]) { + valid = true; + break; + } + } + return valid; +} + +static ssize_t tpc_pg_mask_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", g->tpc_pg_mask); +} + +static ssize_t tpc_pg_mask_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + struct gr_gk20a *gr = &g->gr; + unsigned long val = 0; + + nvgpu_mutex_acquire(&g->tpc_pg_lock); + + if (kstrtoul(buf, 10, &val) < 0) { + nvgpu_err(g, "invalid value"); + nvgpu_mutex_release(&g->tpc_pg_lock); + return -EINVAL; + } + + if (val == g->tpc_pg_mask) { + nvgpu_info(g, "no value change, same mask already set"); + goto exit; + } + + if (gr->ctx_vars.golden_image_size) { + nvgpu_err(g, "golden image size already initialized"); + nvgpu_mutex_release(&g->tpc_pg_lock); + return -ENODEV; + } + + /* checking that the value from userspace is within + * the possible valid TPC configurations. + */ + if (is_tpc_mask_valid(g, (u32)val)) { + g->tpc_pg_mask = val; + } else { + nvgpu_err(g, "TPC-PG mask is invalid"); + nvgpu_mutex_release(&g->tpc_pg_lock); + return -EINVAL; + } +exit: + nvgpu_mutex_release(&g->tpc_pg_lock); + + return count; +} + +static DEVICE_ATTR(tpc_pg_mask, ROOTRW, tpc_pg_mask_read, tpc_pg_mask_store); + +static ssize_t tpc_fs_mask_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val = 0; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (!g->gr.gpc_tpc_mask) + return -ENODEV; + + if (val && val != g->gr.gpc_tpc_mask[0] && g->ops.gr.set_gpc_tpc_mask) { + g->gr.gpc_tpc_mask[0] = val; + g->tpc_fs_mask_user = val; + + g->ops.gr.set_gpc_tpc_mask(g, 0); + + nvgpu_vfree(g, g->gr.ctx_vars.local_golden_image); + g->gr.ctx_vars.local_golden_image = NULL; + g->gr.ctx_vars.golden_image_initialized = false; + g->gr.ctx_vars.golden_image_size = 0; + /* Cause next poweron to reinit just gr */ + g->gr.sw_ready = false; + } + + return count; +} + +static ssize_t tpc_fs_mask_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + struct gr_gk20a *gr = &g->gr; + u32 gpc_index; + u32 tpc_fs_mask = 0; + int err = 0; + + err = gk20a_busy(g); + if (err) + return err; + + for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { + if (g->ops.gr.get_gpc_tpc_mask) + tpc_fs_mask |= + g->ops.gr.get_gpc_tpc_mask(g, gpc_index) << + (gr->max_tpc_per_gpc_count * gpc_index); + } + + gk20a_idle(g); + + return snprintf(buf, PAGE_SIZE, "0x%x\n", tpc_fs_mask); +} + +static DEVICE_ATTR(tpc_fs_mask, ROOTRW, tpc_fs_mask_read, tpc_fs_mask_store); + +static ssize_t min_timeslice_us_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", g->min_timeslice_us); +} + +static ssize_t min_timeslice_us_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (val > g->max_timeslice_us) + return -EINVAL; + + g->min_timeslice_us = val; + + return count; +} + +static DEVICE_ATTR(min_timeslice_us, ROOTRW, min_timeslice_us_read, + min_timeslice_us_store); + +static ssize_t max_timeslice_us_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", g->max_timeslice_us); +} + +static ssize_t max_timeslice_us_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (val < g->min_timeslice_us) + return -EINVAL; + + g->max_timeslice_us = val; + + return count; +} + +static DEVICE_ATTR(max_timeslice_us, ROOTRW, max_timeslice_us_read, + max_timeslice_us_store); + +static ssize_t czf_bypass_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (val >= 4) + return -EINVAL; + + g->gr.czf_bypass = val; + + return count; +} + +static ssize_t czf_bypass_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return sprintf(buf, "%d\n", g->gr.czf_bypass); +} + +static DEVICE_ATTR(czf_bypass, ROOTRW, czf_bypass_read, czf_bypass_store); + +static ssize_t pd_max_batches_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (val > 64) + return -EINVAL; + + g->gr.pd_max_batches = val; + + return count; +} + +static ssize_t pd_max_batches_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return sprintf(buf, "%d\n", g->gr.pd_max_batches); +} + +static DEVICE_ATTR(pd_max_batches, ROOTRW, pd_max_batches_read, pd_max_batches_store); + +static ssize_t gfxp_wfi_timeout_count_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + struct gr_gk20a *gr = &g->gr; + unsigned long val = 0; + int err = -1; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (g->ops.gr.get_max_gfxp_wfi_timeout_count) { + if (val >= g->ops.gr.get_max_gfxp_wfi_timeout_count(g)) + return -EINVAL; + } + + gr->gfxp_wfi_timeout_count = val; + + if (g->ops.gr.init_preemption_state && g->power_on) { + err = gk20a_busy(g); + if (err) + return err; + + err = gr_gk20a_elpg_protected_call(g, + g->ops.gr.init_preemption_state(g)); + + gk20a_idle(g); + + if (err) + return err; + } + return count; +} + +static ssize_t gfxp_wfi_timeout_unit_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + struct gr_gk20a *gr = &g->gr; + int err = -1; + + if (count > 0 && buf[0] == 's') + /* sysclk */ + gr->gfxp_wfi_timeout_unit = GFXP_WFI_TIMEOUT_UNIT_SYSCLK; + else + /* usec */ + gr->gfxp_wfi_timeout_unit = GFXP_WFI_TIMEOUT_UNIT_USEC; + + if (g->ops.gr.init_preemption_state && g->power_on) { + err = gk20a_busy(g); + if (err) + return err; + + err = gr_gk20a_elpg_protected_call(g, + g->ops.gr.init_preemption_state(g)); + + gk20a_idle(g); + + if (err) + return err; + } + + return count; +} + +static ssize_t gfxp_wfi_timeout_count_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + struct gr_gk20a *gr = &g->gr; + u32 val = gr->gfxp_wfi_timeout_count; + + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static ssize_t gfxp_wfi_timeout_unit_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + struct gr_gk20a *gr = &g->gr; + + if (gr->gfxp_wfi_timeout_unit == GFXP_WFI_TIMEOUT_UNIT_USEC) + return snprintf(buf, PAGE_SIZE, "usec\n"); + else + return snprintf(buf, PAGE_SIZE, "sysclk\n"); +} + +static DEVICE_ATTR(gfxp_wfi_timeout_count, (S_IRWXU|S_IRGRP|S_IROTH), + gfxp_wfi_timeout_count_read, gfxp_wfi_timeout_count_store); + +static DEVICE_ATTR(gfxp_wfi_timeout_unit, (S_IRWXU|S_IRGRP|S_IROTH), + gfxp_wfi_timeout_unit_read, gfxp_wfi_timeout_unit_store); + +static ssize_t comptag_mem_deduct_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (val >= totalram_size_in_mb) { + dev_err(dev, "comptag_mem_deduct can not be set above %lu", + totalram_size_in_mb); + return -EINVAL; + } + + g->gr.comptag_mem_deduct = val; + /* Deduct the part taken by the running system */ + g->gr.max_comptag_mem -= val; + + return count; +} + +static ssize_t comptag_mem_deduct_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return sprintf(buf, "%d\n", g->gr.comptag_mem_deduct); +} + +static DEVICE_ATTR(comptag_mem_deduct, ROOTRW, + comptag_mem_deduct_show, comptag_mem_deduct_store); + +void nvgpu_remove_sysfs(struct device *dev) +{ + device_remove_file(dev, &dev_attr_elcg_enable); + device_remove_file(dev, &dev_attr_blcg_enable); + device_remove_file(dev, &dev_attr_slcg_enable); + device_remove_file(dev, &dev_attr_ptimer_scale_factor); + device_remove_file(dev, &dev_attr_ptimer_ref_freq); + device_remove_file(dev, &dev_attr_ptimer_src_freq); + device_remove_file(dev, &dev_attr_elpg_enable); + device_remove_file(dev, &dev_attr_mscg_enable); + device_remove_file(dev, &dev_attr_emc3d_ratio); + device_remove_file(dev, &dev_attr_ldiv_slowdown_factor); + + device_remove_file(dev, &dev_attr_fmax_at_vmin_safe); + + device_remove_file(dev, &dev_attr_counters); + device_remove_file(dev, &dev_attr_counters_reset); + device_remove_file(dev, &dev_attr_load); + device_remove_file(dev, &dev_attr_railgate_delay); + device_remove_file(dev, &dev_attr_is_railgated); +#ifdef CONFIG_PM + device_remove_file(dev, &dev_attr_force_idle); + device_remove_file(dev, &dev_attr_railgate_enable); +#endif + device_remove_file(dev, &dev_attr_aelpg_param); + device_remove_file(dev, &dev_attr_aelpg_enable); + device_remove_file(dev, &dev_attr_allow_all); + device_remove_file(dev, &dev_attr_tpc_fs_mask); + device_remove_file(dev, &dev_attr_tpc_pg_mask); + device_remove_file(dev, &dev_attr_min_timeslice_us); + device_remove_file(dev, &dev_attr_max_timeslice_us); + +#ifdef CONFIG_TEGRA_GK20A_NVHOST + nvgpu_nvhost_remove_symlink(get_gk20a(dev)); +#endif + + device_remove_file(dev, &dev_attr_czf_bypass); + device_remove_file(dev, &dev_attr_pd_max_batches); + device_remove_file(dev, &dev_attr_gfxp_wfi_timeout_count); + device_remove_file(dev, &dev_attr_gfxp_wfi_timeout_unit); + device_remove_file(dev, &dev_attr_gpu_powered_on); + + device_remove_file(dev, &dev_attr_comptag_mem_deduct); + + if (strcmp(dev_name(dev), "gpu.0")) { + struct kobject *kobj = &dev->kobj; + struct device *parent = container_of((kobj->parent), + struct device, kobj); + sysfs_remove_link(&parent->kobj, "gpu.0"); + } +} + +int nvgpu_create_sysfs(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + int error = 0; + + error |= device_create_file(dev, &dev_attr_elcg_enable); + error |= device_create_file(dev, &dev_attr_blcg_enable); + error |= device_create_file(dev, &dev_attr_slcg_enable); + error |= device_create_file(dev, &dev_attr_ptimer_scale_factor); + error |= device_create_file(dev, &dev_attr_ptimer_ref_freq); + error |= device_create_file(dev, &dev_attr_ptimer_src_freq); + error |= device_create_file(dev, &dev_attr_elpg_enable); + error |= device_create_file(dev, &dev_attr_mscg_enable); + error |= device_create_file(dev, &dev_attr_emc3d_ratio); + error |= device_create_file(dev, &dev_attr_ldiv_slowdown_factor); + + error |= device_create_file(dev, &dev_attr_fmax_at_vmin_safe); + + error |= device_create_file(dev, &dev_attr_counters); + error |= device_create_file(dev, &dev_attr_counters_reset); + error |= device_create_file(dev, &dev_attr_load); + error |= device_create_file(dev, &dev_attr_railgate_delay); + error |= device_create_file(dev, &dev_attr_is_railgated); +#ifdef CONFIG_PM + error |= device_create_file(dev, &dev_attr_force_idle); + error |= device_create_file(dev, &dev_attr_railgate_enable); +#endif + error |= device_create_file(dev, &dev_attr_aelpg_param); + error |= device_create_file(dev, &dev_attr_aelpg_enable); + error |= device_create_file(dev, &dev_attr_allow_all); + error |= device_create_file(dev, &dev_attr_tpc_fs_mask); + error |= device_create_file(dev, &dev_attr_tpc_pg_mask); + error |= device_create_file(dev, &dev_attr_min_timeslice_us); + error |= device_create_file(dev, &dev_attr_max_timeslice_us); + +#ifdef CONFIG_TEGRA_GK20A_NVHOST + error |= nvgpu_nvhost_create_symlink(g); +#endif + + error |= device_create_file(dev, &dev_attr_czf_bypass); + error |= device_create_file(dev, &dev_attr_pd_max_batches); + error |= device_create_file(dev, &dev_attr_gfxp_wfi_timeout_count); + error |= device_create_file(dev, &dev_attr_gfxp_wfi_timeout_unit); + error |= device_create_file(dev, &dev_attr_gpu_powered_on); + + error |= device_create_file(dev, &dev_attr_comptag_mem_deduct); + + if (strcmp(dev_name(dev), "gpu.0")) { + struct kobject *kobj = &dev->kobj; + struct device *parent = container_of((kobj->parent), + struct device, kobj); + error |= sysfs_create_link(&parent->kobj, + &dev->kobj, "gpu.0"); + } + + if (error) + nvgpu_err(g, "Failed to create sysfs attributes!\n"); + + return error; +} diff --git a/include/os/linux/sysfs.h b/include/os/linux/sysfs.h new file mode 100644 index 0000000..8092584 --- /dev/null +++ b/include/os/linux/sysfs.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef NVGPU_SYSFS_H +#define NVGPU_SYSFS_H + +struct device; + +int nvgpu_create_sysfs(struct device *dev); +void nvgpu_remove_sysfs(struct device *dev); + +#endif diff --git a/include/os/linux/thread.c b/include/os/linux/thread.c new file mode 100644 index 0000000..c56bff6 --- /dev/null +++ b/include/os/linux/thread.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +int nvgpu_thread_proxy(void *threaddata) +{ + struct nvgpu_thread *thread = threaddata; + int ret = thread->fn(thread->data); + + thread->running = false; + return ret; +} + +int nvgpu_thread_create(struct nvgpu_thread *thread, + void *data, + int (*threadfn)(void *data), const char *name) +{ + struct task_struct *task = kthread_create(nvgpu_thread_proxy, + thread, name); + if (IS_ERR(task)) + return PTR_ERR(task); + + thread->task = task; + thread->fn = threadfn; + thread->data = data; + thread->running = true; + wake_up_process(task); + return 0; +}; + +void nvgpu_thread_stop(struct nvgpu_thread *thread) +{ + if (thread->task) { + kthread_stop(thread->task); + thread->task = NULL; + } +}; + +bool nvgpu_thread_should_stop(struct nvgpu_thread *thread) +{ + return kthread_should_stop(); +}; + +bool nvgpu_thread_is_running(struct nvgpu_thread *thread) +{ + return ACCESS_ONCE(thread->running); +}; + +void nvgpu_thread_join(struct nvgpu_thread *thread) +{ + while (ACCESS_ONCE(thread->running)) + nvgpu_msleep(10); +}; diff --git a/include/os/linux/timers.c b/include/os/linux/timers.c new file mode 100644 index 0000000..018fd2d --- /dev/null +++ b/include/os/linux/timers.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include +#include +#include + +#include "platform_gk20a.h" + +/* + * Returns 1 if the platform is pre-Si and should ignore the timeout checking. + * Setting %NVGPU_TIMER_NO_PRE_SI will make this always return 0 (i.e do the + * timeout check regardless of platform). + */ +static int nvgpu_timeout_is_pre_silicon(struct nvgpu_timeout *timeout) +{ + if (timeout->flags & NVGPU_TIMER_NO_PRE_SI) + return 0; + + return !nvgpu_platform_is_silicon(timeout->g); +} + +/** + * nvgpu_timeout_init - Init timer. + * + * @g - nvgpu device. + * @timeout - The timer. + * @duration - Timeout in milliseconds or number of retries. + * @flags - Flags for timer. + * + * This configures the timeout to start the timeout duration now, i.e: when this + * function is called. Available flags to pass to @flags: + * + * %NVGPU_TIMER_CPU_TIMER + * %NVGPU_TIMER_RETRY_TIMER + * %NVGPU_TIMER_NO_PRE_SI + * %NVGPU_TIMER_SILENT_TIMEOUT + * + * If neither %NVGPU_TIMER_CPU_TIMER or %NVGPU_TIMER_RETRY_TIMER is passed then + * a CPU timer is used by default. + */ +int nvgpu_timeout_init(struct gk20a *g, struct nvgpu_timeout *timeout, + u32 duration, unsigned long flags) +{ + if (flags & ~NVGPU_TIMER_FLAG_MASK) + return -EINVAL; + + memset(timeout, 0, sizeof(*timeout)); + + timeout->g = g; + timeout->flags = flags; + + if (flags & NVGPU_TIMER_RETRY_TIMER) + timeout->retries.max = duration; + else + timeout->time = ktime_to_ns(ktime_add_ns(ktime_get(), + (s64)NSEC_PER_MSEC * duration)); + + return 0; +} + +static int __nvgpu_timeout_expired_msg_cpu(struct nvgpu_timeout *timeout, + void *caller, + const char *fmt, va_list args) +{ + struct gk20a *g = timeout->g; + ktime_t now = ktime_get(); + + if (nvgpu_timeout_is_pre_silicon(timeout)) + return 0; + + if (ktime_after(now, ns_to_ktime(timeout->time))) { + if (!(timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT)) { + char buf[128]; + + vsnprintf(buf, sizeof(buf), fmt, args); + + nvgpu_err(g, "Timeout detected @ %pF %s", caller, buf); + } + + return -ETIMEDOUT; + } + + return 0; +} + +static int __nvgpu_timeout_expired_msg_retry(struct nvgpu_timeout *timeout, + void *caller, + const char *fmt, va_list args) +{ + struct gk20a *g = timeout->g; + + if (nvgpu_timeout_is_pre_silicon(timeout)) + return 0; + + if (timeout->retries.attempted >= timeout->retries.max) { + if (!(timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT)) { + char buf[128]; + + vsnprintf(buf, sizeof(buf), fmt, args); + + nvgpu_err(g, "No more retries @ %pF %s", caller, buf); + } + + return -ETIMEDOUT; + } + + timeout->retries.attempted++; + + return 0; +} + +/** + * __nvgpu_timeout_expired_msg - Check if a timeout has expired. + * + * @timeout - The timeout to check. + * @caller - Address of the caller of this function. + * @fmt - The fmt string. + * + * Returns -ETIMEDOUT if the timeout has expired, 0 otherwise. + * + * If a timeout occurs and %NVGPU_TIMER_SILENT_TIMEOUT is not set in the timeout + * then a message is printed based on %fmt. + */ +int __nvgpu_timeout_expired_msg(struct nvgpu_timeout *timeout, + void *caller, const char *fmt, ...) +{ + int ret; + va_list args; + + va_start(args, fmt); + if (timeout->flags & NVGPU_TIMER_RETRY_TIMER) + ret = __nvgpu_timeout_expired_msg_retry(timeout, caller, fmt, + args); + else + ret = __nvgpu_timeout_expired_msg_cpu(timeout, caller, fmt, + args); + va_end(args); + + return ret; +} + +/** + * nvgpu_timeout_peek_expired - Check the status of a timeout. + * + * @timeout - The timeout to check. + * + * Returns non-zero if the timeout is expired, zero otherwise. In the case of + * retry timers this will not increment the underlying retry count. Also if the + * timer has expired no messages will be printed. + * + * This function honors the pre-Si check as well. + */ +int nvgpu_timeout_peek_expired(struct nvgpu_timeout *timeout) +{ + if (nvgpu_timeout_is_pre_silicon(timeout)) + return 0; + + if (timeout->flags & NVGPU_TIMER_RETRY_TIMER) + return timeout->retries.attempted >= timeout->retries.max; + else + return ktime_after(ktime_get(), ns_to_ktime(timeout->time)); +} + +/** + * nvgpu_udelay - Delay for some number of microseconds. + * + * @usecs - Microseconds to wait for. + * + * Wait for at least @usecs microseconds. This is not guaranteed to be perfectly + * accurate. This is normally backed by a busy-loop so this means waits should + * be kept short, below 100us. If longer delays are necessary then + * nvgpu_msleep() should be preferred. + * + * Alternatively, on some platforms, nvgpu_usleep_range() is usable. This + * function will attempt to not use a busy-loop. + */ +void nvgpu_udelay(unsigned int usecs) +{ + udelay(usecs); +} + +/** + * nvgpu_usleep_range - Sleep for a range of microseconds. + * + * @min_us - Minimum wait time. + * @max_us - Maximum wait time. + * + * Wait for some number of microseconds between @min_us and @max_us. This, + * unlike nvgpu_udelay(), will attempt to sleep for the passed number of + * microseconds instead of busy looping. Not all platforms support this, + * and in that case this reduces to nvgpu_udelay(min_us). + * + * Linux note: this is not safe to use in atomic context. If you are in + * atomic context you must use nvgpu_udelay(). + */ +void nvgpu_usleep_range(unsigned int min_us, unsigned int max_us) +{ + usleep_range(min_us, max_us); +} + +/** + * nvgpu_msleep - Sleep for some milliseconds. + * + * @msecs - Sleep for at least this many milliseconds. + * + * Sleep for at least @msecs of milliseconds. For small @msecs (less than 20 ms + * or so) the sleep will be significantly longer due to scheduling overhead and + * mechanics. + */ +void nvgpu_msleep(unsigned int msecs) +{ + msleep(msecs); +} + +/** + * nvgpu_current_time_ms - Time in milliseconds from a monotonic clock. + * + * Return a clock in millisecond units. The start time of the clock is + * unspecified; the time returned can be compared with older ones to measure + * durations. The source clock does not jump when the system clock is adjusted. + */ +s64 nvgpu_current_time_ms(void) +{ + return ktime_to_ms(ktime_get()); +} + +/** + * nvgpu_current_time_ns - Time in nanoseconds from a monotonic clock. + * + * Return a clock in nanosecond units. The start time of the clock is + * unspecified; the time returned can be compared with older ones to measure + * durations. The source clock does not jump when the system clock is adjusted. + */ +s64 nvgpu_current_time_ns(void) +{ + return ktime_to_ns(ktime_get()); +} + +/** + * nvgpu_hr_timestamp - Opaque 'high resolution' time stamp. + * + * Return a "high resolution" time stamp. It does not really matter exactly what + * it is, so long as it generally returns unique values and monotonically + * increases - wrap around _is_ possible though in a system running for long + * enough. + * + * Note: what high resolution means is system dependent. + */ +u64 nvgpu_hr_timestamp(void) +{ + return get_cycles(); +} diff --git a/include/os/linux/vgpu/fecs_trace_vgpu.c b/include/os/linux/vgpu/fecs_trace_vgpu.c new file mode 100644 index 0000000..02a381e --- /dev/null +++ b/include/os/linux/vgpu/fecs_trace_vgpu.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "os/linux/os_linux.h" +#include "gk20a/fecs_trace_gk20a.h" +#include "vgpu/fecs_trace_vgpu.h" + +struct vgpu_fecs_trace { + struct tegra_hv_ivm_cookie *cookie; + struct nvgpu_ctxsw_ring_header *header; + struct nvgpu_gpu_ctxsw_trace_entry *entries; + int num_entries; + bool enabled; + void *buf; +}; + +int vgpu_fecs_trace_init(struct gk20a *g) +{ + struct device *dev = dev_from_gk20a(g); + struct device_node *np = dev->of_node; + struct of_phandle_args args; + struct vgpu_fecs_trace *vcst; + u32 mempool; + int err; + + nvgpu_log_fn(g, " "); + + vcst = nvgpu_kzalloc(g, sizeof(*vcst)); + if (!vcst) + return -ENOMEM; + + err = of_parse_phandle_with_fixed_args(np, + "mempool-fecs-trace", 1, 0, &args); + if (err) { + nvgpu_info(g, "does not support fecs trace"); + goto fail; + } + __nvgpu_set_enabled(g, NVGPU_SUPPORT_FECS_CTXSW_TRACE, true); + + mempool = args.args[0]; + vcst->cookie = vgpu_ivm_mempool_reserve(mempool); + if (IS_ERR(vcst->cookie)) { + nvgpu_info(g, + "mempool %u reserve failed", mempool); + vcst->cookie = NULL; + err = -EINVAL; + goto fail; + } + + vcst->buf = ioremap_cache(vgpu_ivm_get_ipa(vcst->cookie), + vgpu_ivm_get_size(vcst->cookie)); + if (!vcst->buf) { + nvgpu_info(g, "ioremap_cache failed"); + err = -EINVAL; + goto fail; + } + vcst->header = vcst->buf; + vcst->num_entries = vcst->header->num_ents; + if (unlikely(vcst->header->ent_size != sizeof(*vcst->entries))) { + nvgpu_err(g, "entry size mismatch"); + goto fail; + } + vcst->entries = vcst->buf + sizeof(*vcst->header); + g->fecs_trace = (struct gk20a_fecs_trace *)vcst; + + return 0; +fail: + iounmap(vcst->buf); + if (vcst->cookie) + vgpu_ivm_mempool_unreserve(vcst->cookie); + nvgpu_kfree(g, vcst); + return err; +} + +int vgpu_fecs_trace_deinit(struct gk20a *g) +{ + struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace; + + iounmap(vcst->buf); + vgpu_ivm_mempool_unreserve(vcst->cookie); + nvgpu_kfree(g, vcst); + return 0; +} + +int vgpu_fecs_trace_enable(struct gk20a *g) +{ + struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace; + struct tegra_vgpu_cmd_msg msg = { + .cmd = TEGRA_VGPU_CMD_FECS_TRACE_ENABLE, + .handle = vgpu_get_handle(g), + }; + int err; + + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + err = err ? err : msg.ret; + WARN_ON(err); + vcst->enabled = !err; + return err; +} + +int vgpu_fecs_trace_disable(struct gk20a *g) +{ + struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace; + struct tegra_vgpu_cmd_msg msg = { + .cmd = TEGRA_VGPU_CMD_FECS_TRACE_DISABLE, + .handle = vgpu_get_handle(g), + }; + int err; + + vcst->enabled = false; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + err = err ? err : msg.ret; + WARN_ON(err); + return err; +} + +bool vgpu_fecs_trace_is_enabled(struct gk20a *g) +{ + struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace; + + return (vcst && vcst->enabled); +} + +int vgpu_fecs_trace_poll(struct gk20a *g) +{ + struct tegra_vgpu_cmd_msg msg = { + .cmd = TEGRA_VGPU_CMD_FECS_TRACE_POLL, + .handle = vgpu_get_handle(g), + }; + int err; + + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + err = err ? err : msg.ret; + WARN_ON(err); + return err; +} + +int vgpu_alloc_user_buffer(struct gk20a *g, void **buf, size_t *size) +{ + struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace; + + *buf = vcst->buf; + *size = vgpu_ivm_get_size(vcst->cookie); + return 0; +} + +int vgpu_free_user_buffer(struct gk20a *g) +{ + return 0; +} + +int vgpu_mmap_user_buffer(struct gk20a *g, struct vm_area_struct *vma) +{ + struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace; + unsigned long size = vgpu_ivm_get_size(vcst->cookie); + unsigned long vsize = vma->vm_end - vma->vm_start; + + size = min(size, vsize); + size = round_up(size, PAGE_SIZE); + + return remap_pfn_range(vma, vma->vm_start, + vgpu_ivm_get_ipa(vcst->cookie) >> PAGE_SHIFT, + size, + vma->vm_page_prot); +} + +#ifdef CONFIG_GK20A_CTXSW_TRACE +int vgpu_fecs_trace_max_entries(struct gk20a *g, + struct nvgpu_gpu_ctxsw_trace_filter *filter) +{ + struct vgpu_fecs_trace *vcst = (struct vgpu_fecs_trace *)g->fecs_trace; + + return vcst->header->num_ents; +} + +#if NVGPU_CTXSW_FILTER_SIZE != TEGRA_VGPU_FECS_TRACE_FILTER_SIZE +#error "FECS trace filter size mismatch!" +#endif + +int vgpu_fecs_trace_set_filter(struct gk20a *g, + struct nvgpu_gpu_ctxsw_trace_filter *filter) +{ + struct tegra_vgpu_cmd_msg msg = { + .cmd = TEGRA_VGPU_CMD_FECS_TRACE_SET_FILTER, + .handle = vgpu_get_handle(g), + }; + struct tegra_vgpu_fecs_trace_filter *p = &msg.params.fecs_trace_filter; + int err; + + memcpy(&p->tag_bits, &filter->tag_bits, sizeof(p->tag_bits)); + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + err = err ? err : msg.ret; + WARN_ON(err); + return err; +} + +void vgpu_fecs_trace_data_update(struct gk20a *g) +{ + gk20a_ctxsw_trace_wake_up(g, 0); +} +#endif /* CONFIG_GK20A_CTXSW_TRACE */ diff --git a/include/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c b/include/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c new file mode 100644 index 0000000..0304bcc --- /dev/null +++ b/include/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include "vgpu/clk_vgpu.h" +#include "os/linux/platform_gk20a.h" +#include "os/linux/os_linux.h" +#include "os/linux/vgpu/vgpu_linux.h" +#include "os/linux/vgpu/platform_vgpu_tegra.h" + +static int gv11b_vgpu_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct gk20a_platform *platform = dev_get_drvdata(dev); + struct resource *r; + void __iomem *regs; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(platform->g); + struct gk20a *g = platform->g; + int ret; + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usermode"); + if (!r) { + nvgpu_err(g, "failed to get usermode regs"); + return -ENXIO; + } + regs = devm_ioremap_resource(dev, r); + if (IS_ERR(regs)) { + nvgpu_err(g, "failed to map usermode regs"); + return PTR_ERR(regs); + } + l->usermode_regs = regs; + +#ifdef CONFIG_TEGRA_GK20A_NVHOST + ret = nvgpu_get_nvhost_dev(g); + if (ret) { + l->usermode_regs = NULL; + return ret; + } + + ret = nvgpu_nvhost_syncpt_unit_interface_get_aperture(g->nvhost_dev, + &g->syncpt_unit_base, + &g->syncpt_unit_size); + if (ret) { + nvgpu_err(g, "Failed to get syncpt interface"); + return -ENOSYS; + } + g->syncpt_size = nvgpu_nvhost_syncpt_unit_interface_get_byte_offset(1); + nvgpu_info(g, "syncpt_unit_base %llx syncpt_unit_size %zx size %x\n", + g->syncpt_unit_base, g->syncpt_unit_size, g->syncpt_size); +#endif + vgpu_init_clk_support(platform->g); + + return 0; +} + +struct gk20a_platform gv11b_vgpu_tegra_platform = { + .has_syncpoints = true, + + /* power management configuration */ + .can_railgate_init = false, + .can_elpg_init = false, + .enable_slcg = false, + .enable_blcg = false, + .enable_elcg = false, + .enable_elpg = false, + .enable_aelpg = false, + .can_slcg = false, + .can_blcg = false, + .can_elcg = false, + + .ch_wdt_timeout_ms = 5000, + + .probe = gv11b_vgpu_probe, + + .clk_round_rate = vgpu_plat_clk_round_rate, + .get_clk_freqs = vgpu_plat_clk_get_freqs, + + /* frequency scaling configuration */ + .devfreq_governor = "userspace", + + .virtual_dev = true, + + /* power management callbacks */ + .suspend = vgpu_tegra_suspend, + .resume = vgpu_tegra_resume, +}; diff --git a/include/os/linux/vgpu/platform_vgpu_tegra.c b/include/os/linux/vgpu/platform_vgpu_tegra.c new file mode 100644 index 0000000..948323e --- /dev/null +++ b/include/os/linux/vgpu/platform_vgpu_tegra.c @@ -0,0 +1,97 @@ +/* + * Tegra Virtualized GPU Platform Interface + * + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "os/linux/platform_gk20a.h" +#include "vgpu/clk_vgpu.h" +#include "vgpu_linux.h" + +static int gk20a_tegra_probe(struct device *dev) +{ +#ifdef CONFIG_TEGRA_GK20A_NVHOST + struct gk20a_platform *platform = dev_get_drvdata(dev); + int ret; + + ret = nvgpu_get_nvhost_dev(platform->g); + if (ret) + return ret; + + vgpu_init_clk_support(platform->g); + return 0; +#else + return 0; +#endif +} + +long vgpu_plat_clk_round_rate(struct device *dev, unsigned long rate) +{ + /* server will handle frequency rounding */ + return rate; +} + +int vgpu_plat_clk_get_freqs(struct device *dev, unsigned long **freqs, + int *num_freqs) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a *g = platform->g; + + return vgpu_clk_get_freqs(g, freqs, num_freqs); +} + +int vgpu_plat_clk_cap_rate(struct device *dev, unsigned long rate) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct gk20a *g = platform->g; + + return vgpu_clk_cap_rate(g, rate); +} + +struct gk20a_platform vgpu_tegra_platform = { + .has_syncpoints = true, + .aggressive_sync_destroy_thresh = 64, + + /* power management configuration */ + .can_railgate_init = false, + .can_elpg_init = false, + .enable_slcg = false, + .enable_blcg = false, + .enable_elcg = false, + .enable_elpg = false, + .enable_aelpg = false, + .can_slcg = false, + .can_blcg = false, + .can_elcg = false, + + .ch_wdt_timeout_ms = 5000, + + .probe = gk20a_tegra_probe, + + .clk_round_rate = vgpu_plat_clk_round_rate, + .get_clk_freqs = vgpu_plat_clk_get_freqs, + + /* frequency scaling configuration */ + .devfreq_governor = "userspace", + + .virtual_dev = true, + + /* power management callbacks */ + .suspend = vgpu_tegra_suspend, + .resume = vgpu_tegra_resume, +}; diff --git a/include/os/linux/vgpu/platform_vgpu_tegra.h b/include/os/linux/vgpu/platform_vgpu_tegra.h new file mode 100644 index 0000000..fef346d --- /dev/null +++ b/include/os/linux/vgpu/platform_vgpu_tegra.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _VGPU_PLATFORM_H_ +#define _VGPU_PLATFORM_H_ + +long vgpu_plat_clk_round_rate(struct device *dev, unsigned long rate); +int vgpu_plat_clk_get_freqs(struct device *dev, unsigned long **freqs, + int *num_freqs); +int vgpu_plat_clk_cap_rate(struct device *dev, unsigned long rate); +#endif diff --git a/include/os/linux/vgpu/sysfs_vgpu.c b/include/os/linux/vgpu/sysfs_vgpu.c new file mode 100644 index 0000000..ade5d82 --- /dev/null +++ b/include/os/linux/vgpu/sysfs_vgpu.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "os/linux/platform_gk20a.h" +#include "os/linux/os_linux.h" +#include "vgpu/ecc_vgpu.h" + +static ssize_t vgpu_load_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct gk20a *g = get_gk20a(dev); + struct tegra_vgpu_cmd_msg msg = {0}; + struct tegra_vgpu_gpu_load_params *p = &msg.params.gpu_load; + int err; + + msg.cmd = TEGRA_VGPU_CMD_GET_GPU_LOAD; + msg.handle = vgpu_get_handle(g); + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + if (err) + return err; + + return snprintf(buf, PAGE_SIZE, "%u\n", p->load); +} +static DEVICE_ATTR(load, S_IRUGO, vgpu_load_show, NULL); + +static ssize_t vgpu_ecc_stat_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct gk20a *g = get_gk20a(dev); + struct tegra_vgpu_cmd_msg msg = {0}; + struct tegra_vgpu_ecc_counter_params *p = &msg.params.ecc_counter; + struct dev_ext_attribute *ext_attr = container_of(attr, + struct dev_ext_attribute, attr); + struct vgpu_ecc_stat *ecc_stat = ext_attr->var; + int err; + + p->ecc_id = ecc_stat->ecc_id; + + msg.cmd = TEGRA_VGPU_CMD_GET_ECC_COUNTER_VALUE; + msg.handle = vgpu_get_handle(g); + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + err = err ? err : msg.ret; + if (unlikely(err)) { + nvgpu_err(g, "ecc: cannot get ECC counter value: %d", err); + return err; + } + + return snprintf(buf, PAGE_SIZE, "%u\n", p->value); +} + +static int vgpu_create_ecc_sysfs(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct vgpu_priv_data *priv = vgpu_get_priv_data(g); + struct vgpu_ecc_stat *stats; + struct dev_ext_attribute *attrs; + int err, i, count; + + err = vgpu_ecc_get_info(g); + if (unlikely(err)) { + nvgpu_err(g, "ecc: cannot get ECC info: %d", err); + return err; + } + + stats = priv->ecc_stats; + count = priv->ecc_stats_count; + + attrs = nvgpu_kzalloc(g, count * sizeof(*attrs)); + if (unlikely(!attrs)) { + nvgpu_err(g, "ecc: no memory"); + vgpu_ecc_remove_info(g); + return -ENOMEM; + } + + for (i = 0; i < count; i++) { + sysfs_attr_init(&attrs[i].attr.attr); + attrs[i].attr.attr.name = stats[i].name; + attrs[i].attr.attr.mode = VERIFY_OCTAL_PERMISSIONS(S_IRUGO); + attrs[i].attr.show = vgpu_ecc_stat_show; + attrs[i].attr.store = NULL; + attrs[i].var = &stats[i]; + + err = device_create_file(dev, &attrs[i].attr); + if (unlikely(err)) { + nvgpu_warn(g, "ecc: cannot create file \"%s\": %d", + stats[i].name, err); + } + } + + l->ecc_attrs = attrs; + return 0; +} + +static void vgpu_remove_ecc_sysfs(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct vgpu_priv_data *priv = vgpu_get_priv_data(g); + int i; + + if (l->ecc_attrs) { + for (i = 0; i < priv->ecc_stats_count; i++) + device_remove_file(dev, &l->ecc_attrs[i].attr); + + nvgpu_kfree(g, l->ecc_attrs); + l->ecc_attrs = NULL; + } + + vgpu_ecc_remove_info(g); +} + +void vgpu_create_sysfs(struct device *dev) +{ + if (device_create_file(dev, &dev_attr_load)) + dev_err(dev, "Failed to create vgpu sysfs attributes!\n"); + + vgpu_create_ecc_sysfs(dev); +} + +void vgpu_remove_sysfs(struct device *dev) +{ + device_remove_file(dev, &dev_attr_load); + vgpu_remove_ecc_sysfs(dev); +} diff --git a/include/os/linux/vgpu/vgpu_ivc.c b/include/os/linux/vgpu/vgpu_ivc.c new file mode 100644 index 0000000..950f0d4 --- /dev/null +++ b/include/os/linux/vgpu/vgpu_ivc.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "os/linux/os_linux.h" + +int vgpu_ivc_init(struct gk20a *g, u32 elems, + const size_t *queue_sizes, u32 queue_start, u32 num_queues) +{ + struct platform_device *pdev = to_platform_device(dev_from_gk20a(g)); + + return tegra_gr_comm_init(pdev, elems, queue_sizes, queue_start, + num_queues); +} + +void vgpu_ivc_deinit(u32 queue_start, u32 num_queues) +{ + tegra_gr_comm_deinit(queue_start, num_queues); +} + +void vgpu_ivc_release(void *handle) +{ + tegra_gr_comm_release(handle); +} + +u32 vgpu_ivc_get_server_vmid(void) +{ + return tegra_gr_comm_get_server_vmid(); +} + +int vgpu_ivc_recv(u32 index, void **handle, void **data, + size_t *size, u32 *sender) +{ + return tegra_gr_comm_recv(index, handle, data, size, sender); +} + +int vgpu_ivc_send(u32 peer, u32 index, void *data, size_t size) +{ + return tegra_gr_comm_send(peer, index, data, size); +} + +int vgpu_ivc_sendrecv(u32 peer, u32 index, void **handle, + void **data, size_t *size) +{ + return tegra_gr_comm_sendrecv(peer, index, handle, data, size); +} + +u32 vgpu_ivc_get_peer_self(void) +{ + return TEGRA_GR_COMM_ID_SELF; +} + +void *vgpu_ivc_oob_get_ptr(u32 peer, u32 index, void **ptr, + size_t *size) +{ + return tegra_gr_comm_oob_get_ptr(peer, index, ptr, size); +} + +void vgpu_ivc_oob_put_ptr(void *handle) +{ + tegra_gr_comm_oob_put_ptr(handle); +} diff --git a/include/os/linux/vgpu/vgpu_ivm.c b/include/os/linux/vgpu/vgpu_ivm.c new file mode 100644 index 0000000..bbd444d --- /dev/null +++ b/include/os/linux/vgpu/vgpu_ivm.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include + +#include "os/linux/os_linux.h" + +struct tegra_hv_ivm_cookie *vgpu_ivm_mempool_reserve(unsigned int id) +{ + return tegra_hv_mempool_reserve(id); +} + +int vgpu_ivm_mempool_unreserve(struct tegra_hv_ivm_cookie *cookie) +{ + return tegra_hv_mempool_unreserve(cookie); +} + +u64 vgpu_ivm_get_ipa(struct tegra_hv_ivm_cookie *cookie) +{ + return cookie->ipa; +} + +u64 vgpu_ivm_get_size(struct tegra_hv_ivm_cookie *cookie) +{ + return cookie->size; +} + +void *vgpu_ivm_mempool_map(struct tegra_hv_ivm_cookie *cookie) +{ + return ioremap_cache(vgpu_ivm_get_ipa(cookie), + vgpu_ivm_get_size(cookie)); +} + +void vgpu_ivm_mempool_unmap(struct tegra_hv_ivm_cookie *cookie, + void *addr) +{ + iounmap(addr); +} diff --git a/include/os/linux/vgpu/vgpu_linux.c b/include/os/linux/vgpu/vgpu_linux.c new file mode 100644 index 0000000..80bcfff --- /dev/null +++ b/include/os/linux/vgpu/vgpu_linux.c @@ -0,0 +1,525 @@ +/* + * Virtualized GPU for Linux + * + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vgpu_linux.h" +#include "vgpu/fecs_trace_vgpu.h" +#include "vgpu/clk_vgpu.h" +#include "gk20a/regops_gk20a.h" +#include "gm20b/hal_gm20b.h" + +#include "os/linux/module.h" +#include "os/linux/os_linux.h" +#include "os/linux/ioctl.h" +#include "os/linux/scale.h" +#include "os/linux/driver_common.h" +#include "os/linux/platform_gk20a.h" +#include "os/linux/vgpu/platform_vgpu_tegra.h" + +struct vgpu_priv_data *vgpu_get_priv_data(struct gk20a *g) +{ + struct gk20a_platform *plat = gk20a_get_platform(dev_from_gk20a(g)); + + return (struct vgpu_priv_data *)plat->vgpu_priv; +} + +static void vgpu_remove_support(struct gk20a *g) +{ + vgpu_remove_support_common(g); +} + +static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct vgpu_priv_data *priv = vgpu_get_priv_data(g); + + nvgpu_mutex_init(&g->power_lock); + nvgpu_mutex_init(&g->ctxsw_disable_lock); + nvgpu_mutex_init(&g->clk_arb_enable_lock); + nvgpu_mutex_init(&g->cg_pg_lock); + + nvgpu_mutex_init(&priv->vgpu_clk_get_freq_lock); + + nvgpu_mutex_init(&l->ctrl.privs_lock); + nvgpu_init_list_node(&l->ctrl.privs); + + l->regs_saved = l->regs; + l->bar1_saved = l->bar1; + + nvgpu_atomic_set(&g->clk_arb_global_nr, 0); + + g->aggressive_sync_destroy = platform->aggressive_sync_destroy; + g->aggressive_sync_destroy_thresh = platform->aggressive_sync_destroy_thresh; + __nvgpu_set_enabled(g, NVGPU_HAS_SYNCPOINTS, platform->has_syncpoints); + g->ptimer_src_freq = platform->ptimer_src_freq; + __nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, platform->can_railgate_init); + g->railgate_delay = platform->railgate_delay_init; + + __nvgpu_set_enabled(g, NVGPU_MM_UNIFY_ADDRESS_SPACES, + platform->unify_address_spaces); +} + +static int vgpu_init_support(struct platform_device *pdev) +{ + struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct gk20a *g = get_gk20a(&pdev->dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + void __iomem *regs; + int err = 0; + + if (!r) { + nvgpu_err(g, "failed to get gk20a bar1"); + err = -ENXIO; + goto fail; + } + + if (r->name && !strcmp(r->name, "/vgpu")) { + regs = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(regs)) { + nvgpu_err(g, "failed to remap gk20a bar1"); + err = PTR_ERR(regs); + goto fail; + } + l->bar1 = regs; + l->bar1_mem = r; + } + + nvgpu_mutex_init(&g->dbg_sessions_lock); + nvgpu_mutex_init(&g->client_lock); + + nvgpu_init_list_node(&g->profiler_objects); + + g->dbg_regops_tmp_buf = nvgpu_kzalloc(g, SZ_4K); + if (!g->dbg_regops_tmp_buf) { + nvgpu_err(g, "couldn't allocate regops tmp buf"); + return -ENOMEM; + } + g->dbg_regops_tmp_buf_ops = + SZ_4K / sizeof(g->dbg_regops_tmp_buf[0]); + + g->remove_support = vgpu_remove_support; + return 0; + + fail: + vgpu_remove_support(g); + return err; +} + +int vgpu_pm_prepare_poweroff(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + int ret = 0; + + nvgpu_log_fn(g, " "); + + nvgpu_mutex_acquire(&g->power_lock); + + if (!g->power_on) + goto done; + + if (g->ops.fifo.channel_suspend) + ret = g->ops.fifo.channel_suspend(g); + if (ret) + goto done; + + g->power_on = false; + done: + nvgpu_mutex_release(&g->power_lock); + + return ret; +} + +int vgpu_pm_finalize_poweron(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + int err = 0; + + nvgpu_log_fn(g, " "); + + nvgpu_mutex_acquire(&g->power_lock); + + if (g->power_on) + goto done; + + g->power_on = true; + + vgpu_detect_chip(g); + err = vgpu_init_hal(g); + if (err) + goto done; + + if (g->ops.ltc.init_fs_state) + g->ops.ltc.init_fs_state(g); + + err = nvgpu_init_ltc_support(g); + if (err) { + nvgpu_err(g, "failed to init ltc"); + goto done; + } + + err = vgpu_init_mm_support(g); + if (err) { + nvgpu_err(g, "failed to init gk20a mm"); + goto done; + } + + err = vgpu_init_fifo_support(g); + if (err) { + nvgpu_err(g, "failed to init gk20a fifo"); + goto done; + } + + err = vgpu_init_gr_support(g); + if (err) { + nvgpu_err(g, "failed to init gk20a gr"); + goto done; + } + + err = nvgpu_clk_arb_init_arbiter(g); + if (err) { + nvgpu_err(g, "failed to init clk arb"); + goto done; + } + + err = g->ops.chip_init_gpu_characteristics(g); + if (err) { + nvgpu_err(g, "failed to init gk20a gpu characteristics"); + goto done; + } + + err = nvgpu_finalize_poweron_linux(l); + if (err) + goto done; + +#ifdef CONFIG_GK20A_CTXSW_TRACE + gk20a_ctxsw_trace_init(g); +#endif + gk20a_sched_ctrl_init(g); + gk20a_channel_resume(g); + + g->sw_ready = true; + +done: + if (err) + g->power_on = false; + + nvgpu_mutex_release(&g->power_lock); + return err; +} + +static int vgpu_qos_notify(struct notifier_block *nb, + unsigned long n, void *data) +{ + struct gk20a_scale_profile *profile = + container_of(nb, struct gk20a_scale_profile, + qos_notify_block); + struct gk20a *g = get_gk20a(profile->dev); + u32 max_freq; + int err; + + nvgpu_log_fn(g, " "); + + max_freq = (u32)pm_qos_read_max_bound(PM_QOS_GPU_FREQ_BOUNDS); + err = vgpu_plat_clk_cap_rate(profile->dev, max_freq); + if (err) + nvgpu_err(g, "%s failed, err=%d", __func__, err); + + return NOTIFY_OK; /* need notify call further */ +} + +static int vgpu_pm_qos_init(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + struct gk20a_scale_profile *profile = g->scale_profile; + + if (IS_ENABLED(CONFIG_GK20A_DEVFREQ)) { + if (!profile) + return -EINVAL; + } else { + profile = nvgpu_kzalloc(g, sizeof(*profile)); + if (!profile) + return -ENOMEM; + g->scale_profile = profile; + } + + profile->dev = dev; + profile->qos_notify_block.notifier_call = vgpu_qos_notify; + pm_qos_add_max_notifier(PM_QOS_GPU_FREQ_BOUNDS, + &profile->qos_notify_block); + return 0; +} + +static void vgpu_pm_qos_remove(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + + pm_qos_remove_max_notifier(PM_QOS_GPU_FREQ_BOUNDS, + &g->scale_profile->qos_notify_block); + nvgpu_kfree(g, g->scale_profile); + g->scale_profile = NULL; +} + +static int vgpu_pm_init(struct device *dev) +{ + struct gk20a *g = get_gk20a(dev); + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + unsigned long *freqs; + int num_freqs; + int err = 0; + + nvgpu_log_fn(g, " "); + + if (nvgpu_platform_is_simulation(g)) + return 0; + + __pm_runtime_disable(dev, false); + + if (IS_ENABLED(CONFIG_GK20A_DEVFREQ)) + gk20a_scale_init(dev); + + if (l->devfreq) { + /* set min/max frequency based on frequency table */ + err = platform->get_clk_freqs(dev, &freqs, &num_freqs); + if (err) + return err; + + if (num_freqs < 1) + return -EINVAL; + + l->devfreq->min_freq = freqs[0]; + l->devfreq->max_freq = freqs[num_freqs - 1]; + } + + err = vgpu_pm_qos_init(dev); + if (err) + return err; + + return err; +} + +int vgpu_probe(struct platform_device *pdev) +{ + struct nvgpu_os_linux *l; + struct gk20a *gk20a; + int err; + struct device *dev = &pdev->dev; + struct gk20a_platform *platform = gk20a_get_platform(dev); + struct vgpu_priv_data *priv; + + if (!platform) { + dev_err(dev, "no platform data\n"); + return -ENODATA; + } + + l = kzalloc(sizeof(*l), GFP_KERNEL); + if (!l) { + dev_err(dev, "couldn't allocate gk20a support"); + return -ENOMEM; + } + gk20a = &l->g; + + nvgpu_log_fn(gk20a, " "); + + nvgpu_init_gk20a(gk20a); + + nvgpu_kmem_init(gk20a); + + err = nvgpu_init_enabled_flags(gk20a); + if (err) { + kfree(gk20a); + return err; + } + + l->dev = dev; + if (tegra_platform_is_vdk()) + __nvgpu_set_enabled(gk20a, NVGPU_IS_FMODEL, true); + + gk20a->is_virtual = true; + + priv = nvgpu_kzalloc(gk20a, sizeof(*priv)); + if (!priv) { + kfree(gk20a); + return -ENOMEM; + } + + platform->g = gk20a; + platform->vgpu_priv = priv; + + err = gk20a_user_init(dev, INTERFACE_NAME, &nvgpu_class); + if (err) + return err; + + vgpu_init_support(pdev); + + vgpu_init_vars(gk20a, platform); + + init_rwsem(&l->busy_lock); + + nvgpu_spinlock_init(&gk20a->mc_enable_lock); + + gk20a->ch_wdt_timeout_ms = platform->ch_wdt_timeout_ms; + + /* Initialize the platform interface. */ + err = platform->probe(dev); + if (err) { + if (err == -EPROBE_DEFER) + nvgpu_info(gk20a, "platform probe failed"); + else + nvgpu_err(gk20a, "platform probe failed"); + return err; + } + + if (platform->late_probe) { + err = platform->late_probe(dev); + if (err) { + nvgpu_err(gk20a, "late probe failed"); + return err; + } + } + + err = vgpu_comm_init(gk20a); + if (err) { + nvgpu_err(gk20a, "failed to init comm interface"); + return -ENOSYS; + } + + priv->virt_handle = vgpu_connect(); + if (!priv->virt_handle) { + nvgpu_err(gk20a, "failed to connect to server node"); + vgpu_comm_deinit(); + return -ENOSYS; + } + + err = vgpu_get_constants(gk20a); + if (err) { + vgpu_comm_deinit(); + return err; + } + + err = vgpu_pm_init(dev); + if (err) { + nvgpu_err(gk20a, "pm init failed"); + return err; + } + + err = nvgpu_thread_create(&priv->intr_handler, gk20a, + vgpu_intr_thread, "gk20a"); + if (err) + return err; + + gk20a_debug_init(gk20a, "gpu.0"); + + /* Set DMA parameters to allow larger sgt lists */ + dev->dma_parms = &l->dma_parms; + dma_set_max_seg_size(dev, UINT_MAX); + + gk20a->gr_idle_timeout_default = NVGPU_DEFAULT_GR_IDLE_TIMEOUT; + gk20a->timeouts_disabled_by_user = false; + nvgpu_atomic_set(&gk20a->timeouts_disabled_refcount, 0); + + vgpu_create_sysfs(dev); + gk20a_init_gr(gk20a); + + nvgpu_log_info(gk20a, "total ram pages : %lu", totalram_pages); + gk20a->gr.max_comptag_mem = totalram_size_in_mb; + + nvgpu_ref_init(&gk20a->refcount); + + return 0; +} + +int vgpu_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct gk20a *g = get_gk20a(dev); + + nvgpu_log_fn(g, " "); + + vgpu_pm_qos_remove(dev); + if (g->remove_support) + g->remove_support(g); + + vgpu_comm_deinit(); + gk20a_sched_ctrl_cleanup(g); + gk20a_user_deinit(dev, &nvgpu_class); + vgpu_remove_sysfs(dev); + gk20a_get_platform(dev)->g = NULL; + gk20a_put(g); + + return 0; +} + +bool vgpu_is_reduced_bar1(struct gk20a *g) +{ + struct fifo_gk20a *f = &g->fifo; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + return resource_size(l->bar1_mem) == (resource_size_t)f->userd.size; +} + +int vgpu_tegra_suspend(struct device *dev) +{ + struct tegra_vgpu_cmd_msg msg = {}; + struct gk20a *g = get_gk20a(dev); + int err = 0; + + msg.cmd = TEGRA_VGPU_CMD_SUSPEND; + msg.handle = vgpu_get_handle(g); + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + err = err ? err : msg.ret; + if (err) + nvgpu_err(g, "vGPU suspend failed\n"); + + return err; +} + +int vgpu_tegra_resume(struct device *dev) +{ + struct tegra_vgpu_cmd_msg msg = {}; + struct gk20a *g = get_gk20a(dev); + int err = 0; + + msg.cmd = TEGRA_VGPU_CMD_RESUME; + msg.handle = vgpu_get_handle(g); + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + err = err ? err : msg.ret; + if (err) + nvgpu_err(g, "vGPU resume failed\n"); + + return err; +} diff --git a/include/os/linux/vgpu/vgpu_linux.h b/include/os/linux/vgpu/vgpu_linux.h new file mode 100644 index 0000000..ff7d3a6 --- /dev/null +++ b/include/os/linux/vgpu/vgpu_linux.h @@ -0,0 +1,68 @@ +/* + * Virtualized GPU Linux Interfaces + * + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __VGPU_LINUX_H__ +#define __VGPU_LINUX_H__ + +struct device; +struct platform_device; + +#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION + +#include + +int vgpu_pm_prepare_poweroff(struct device *dev); +int vgpu_pm_finalize_poweron(struct device *dev); +int vgpu_probe(struct platform_device *dev); +int vgpu_remove(struct platform_device *dev); + +void vgpu_create_sysfs(struct device *dev); +void vgpu_remove_sysfs(struct device *dev); + +int vgpu_tegra_suspend(struct device *dev); +int vgpu_tegra_resume(struct device *dev); +#else +/* define placeholders for functions used outside of vgpu */ + +static inline int vgpu_pm_prepare_poweroff(struct device *dev) +{ + return -ENOSYS; +} +static inline int vgpu_pm_finalize_poweron(struct device *dev) +{ + return -ENOSYS; +} +static inline int vgpu_probe(struct platform_device *dev) +{ + return -ENOSYS; +} +static inline int vgpu_remove(struct platform_device *dev) +{ + return -ENOSYS; +} +static inline int vgpu_tegra_suspend(struct device *dev) +{ + return -ENOSYS; +} +static inline int vgpu_tegra_resume(struct device *dev) +{ + return -ENOSYS; +} +#endif + +#endif diff --git a/include/os/linux/vm.c b/include/os/linux/vm.c new file mode 100644 index 0000000..dc807ab --- /dev/null +++ b/include/os/linux/vm.c @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "gk20a/mm_gk20a.h" + +#include "platform_gk20a.h" +#include "os_linux.h" +#include "dmabuf.h" +#include "dmabuf_vidmem.h" + +static u32 nvgpu_vm_translate_linux_flags(struct gk20a *g, u32 flags) +{ + u32 core_flags = 0; + + if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET) + core_flags |= NVGPU_VM_MAP_FIXED_OFFSET; + if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_CACHEABLE) + core_flags |= NVGPU_VM_MAP_CACHEABLE; + if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_IO_COHERENT) + core_flags |= NVGPU_VM_MAP_IO_COHERENT; + if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_UNMAPPED_PTE) + core_flags |= NVGPU_VM_MAP_UNMAPPED_PTE; + if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_L3_ALLOC) + core_flags |= NVGPU_VM_MAP_L3_ALLOC; + if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_DIRECT_KIND_CTRL) + core_flags |= NVGPU_VM_MAP_DIRECT_KIND_CTRL; + if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_PLATFORM_ATOMIC) + core_flags |= NVGPU_VM_MAP_PLATFORM_ATOMIC; + + if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_MAPPABLE_COMPBITS) + nvgpu_warn(g, "Ignoring deprecated flag: " + "NVGPU_AS_MAP_BUFFER_FLAGS_MAPPABLE_COMPBITS"); + + return core_flags; +} + +static struct nvgpu_mapped_buf *__nvgpu_vm_find_mapped_buf_reverse( + struct vm_gk20a *vm, struct dma_buf *dmabuf, u32 kind) +{ + struct nvgpu_rbtree_node *node = NULL; + struct nvgpu_rbtree_node *root = vm->mapped_buffers; + + nvgpu_rbtree_enum_start(0, &node, root); + + while (node) { + struct nvgpu_mapped_buf *mapped_buffer = + mapped_buffer_from_rbtree_node(node); + + if (mapped_buffer->os_priv.dmabuf == dmabuf && + mapped_buffer->kind == kind) + return mapped_buffer; + + nvgpu_rbtree_enum_next(&node, node); + } + + return NULL; +} + +int nvgpu_vm_find_buf(struct vm_gk20a *vm, u64 gpu_va, + struct dma_buf **dmabuf, + u64 *offset) +{ + struct nvgpu_mapped_buf *mapped_buffer; + struct gk20a *g = gk20a_from_vm(vm); + + nvgpu_log_fn(g, "gpu_va=0x%llx", gpu_va); + + nvgpu_mutex_acquire(&vm->update_gmmu_lock); + + mapped_buffer = __nvgpu_vm_find_mapped_buf_range(vm, gpu_va); + if (!mapped_buffer) { + nvgpu_mutex_release(&vm->update_gmmu_lock); + return -EINVAL; + } + + *dmabuf = mapped_buffer->os_priv.dmabuf; + *offset = gpu_va - mapped_buffer->addr; + + nvgpu_mutex_release(&vm->update_gmmu_lock); + + return 0; +} + +u64 nvgpu_os_buf_get_size(struct nvgpu_os_buffer *os_buf) +{ + return os_buf->dmabuf->size; +} + +/* + * vm->update_gmmu_lock must be held. This checks to see if we already have + * mapped the passed buffer into this VM. If so, just return the existing + * mapping address. + */ +struct nvgpu_mapped_buf *nvgpu_vm_find_mapping(struct vm_gk20a *vm, + struct nvgpu_os_buffer *os_buf, + u64 map_addr, + u32 flags, + int kind) +{ + struct gk20a *g = gk20a_from_vm(vm); + struct nvgpu_mapped_buf *mapped_buffer = NULL; + + if (flags & NVGPU_VM_MAP_FIXED_OFFSET) { + mapped_buffer = __nvgpu_vm_find_mapped_buf(vm, map_addr); + if (!mapped_buffer) + return NULL; + + if (mapped_buffer->os_priv.dmabuf != os_buf->dmabuf || + mapped_buffer->kind != (u32)kind) + return NULL; + } else { + mapped_buffer = + __nvgpu_vm_find_mapped_buf_reverse(vm, + os_buf->dmabuf, + kind); + if (!mapped_buffer) + return NULL; + } + + if (mapped_buffer->flags != flags) + return NULL; + + /* + * If we find the mapping here then that means we have mapped it already + * and the prior pin and get must be undone. + */ + gk20a_mm_unpin(os_buf->dev, os_buf->dmabuf, os_buf->attachment, + mapped_buffer->os_priv.sgt); + dma_buf_put(os_buf->dmabuf); + + nvgpu_log(g, gpu_dbg_map, + "gv: 0x%04x_%08x + 0x%-7zu " + "[dma: 0x%010llx, pa: 0x%010llx] " + "pgsz=%-3dKb as=%-2d " + "flags=0x%x apt=%s (reused)", + u64_hi32(mapped_buffer->addr), u64_lo32(mapped_buffer->addr), + os_buf->dmabuf->size, + (u64)sg_dma_address(mapped_buffer->os_priv.sgt->sgl), + (u64)sg_phys(mapped_buffer->os_priv.sgt->sgl), + vm->gmmu_page_sizes[mapped_buffer->pgsz_idx] >> 10, + vm_aspace_id(vm), + mapped_buffer->flags, + nvgpu_aperture_str(g, + gk20a_dmabuf_aperture(g, os_buf->dmabuf))); + + return mapped_buffer; +} + +int nvgpu_vm_map_linux(struct vm_gk20a *vm, + struct dma_buf *dmabuf, + u64 map_addr, + u32 flags, + u32 page_size, + s16 compr_kind, + s16 incompr_kind, + int rw_flag, + u64 buffer_offset, + u64 mapping_size, + struct vm_gk20a_mapping_batch *batch, + u64 *gpu_va) +{ + struct gk20a *g = gk20a_from_vm(vm); + struct device *dev = dev_from_gk20a(g); + struct nvgpu_os_buffer os_buf; + struct sg_table *sgt; + struct nvgpu_sgt *nvgpu_sgt = NULL; + struct nvgpu_mapped_buf *mapped_buffer = NULL; + struct dma_buf_attachment *attachment; + int err = 0; + + sgt = gk20a_mm_pin(dev, dmabuf, &attachment); + if (IS_ERR(sgt)) { + nvgpu_warn(g, "Failed to pin dma_buf!"); + return PTR_ERR(sgt); + } + os_buf.dmabuf = dmabuf; + os_buf.attachment = attachment; + os_buf.dev = dev; + + if (gk20a_dmabuf_aperture(g, dmabuf) == APERTURE_INVALID) { + err = -EINVAL; + goto clean_up; + } + + nvgpu_sgt = nvgpu_linux_sgt_create(g, sgt); + if (!nvgpu_sgt) { + err = -ENOMEM; + goto clean_up; + } + + mapped_buffer = nvgpu_vm_map(vm, + &os_buf, + nvgpu_sgt, + map_addr, + mapping_size, + buffer_offset, + rw_flag, + flags, + compr_kind, + incompr_kind, + batch, + gk20a_dmabuf_aperture(g, dmabuf)); + + nvgpu_sgt_free(g, nvgpu_sgt); + + if (IS_ERR(mapped_buffer)) { + err = PTR_ERR(mapped_buffer); + goto clean_up; + } + + mapped_buffer->os_priv.dmabuf = dmabuf; + mapped_buffer->os_priv.attachment = attachment; + mapped_buffer->os_priv.sgt = sgt; + + *gpu_va = mapped_buffer->addr; + return 0; + +clean_up: + gk20a_mm_unpin(dev, dmabuf, attachment, sgt); + + return err; +} + +int nvgpu_vm_map_buffer(struct vm_gk20a *vm, + int dmabuf_fd, + u64 *map_addr, + u32 flags, /*NVGPU_AS_MAP_BUFFER_FLAGS_*/ + u32 page_size, + s16 compr_kind, + s16 incompr_kind, + u64 buffer_offset, + u64 mapping_size, + struct vm_gk20a_mapping_batch *batch) +{ + struct gk20a *g = gk20a_from_vm(vm); + struct dma_buf *dmabuf; + u64 ret_va; + int err = 0; + + /* get ref to the mem handle (released on unmap_locked) */ + dmabuf = dma_buf_get(dmabuf_fd); + if (IS_ERR(dmabuf)) { + nvgpu_warn(g, "%s: fd %d is not a dmabuf", + __func__, dmabuf_fd); + return PTR_ERR(dmabuf); + } + + /* + * For regular maps we do not accept either an input address or a + * buffer_offset. + */ + if (!(flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET) && + (buffer_offset || *map_addr)) { + nvgpu_err(g, + "Regular map with addr/buf offset is not supported!"); + dma_buf_put(dmabuf); + return -EINVAL; + } + + /* + * Map size is always buffer size for non fixed mappings. As such map + * size should be left as zero by userspace for non-fixed maps. + */ + if (mapping_size && !(flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET)) { + nvgpu_err(g, "map_size && non-fixed-mapping!"); + dma_buf_put(dmabuf); + return -EINVAL; + } + + /* verify that we're not overflowing the buffer, i.e. + * (buffer_offset + mapping_size) > dmabuf->size. + * + * Since buffer_offset + mapping_size could overflow, first check + * that mapping size < dmabuf_size, at which point we can subtract + * mapping_size from both sides for the final comparison. + */ + if ((mapping_size > dmabuf->size) || + (buffer_offset > (dmabuf->size - mapping_size))) { + nvgpu_err(g, + "buf size %llx < (offset(%llx) + map_size(%llx))", + (u64)dmabuf->size, buffer_offset, mapping_size); + dma_buf_put(dmabuf); + return -EINVAL; + } + + err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev_from_vm(vm)); + if (err) { + dma_buf_put(dmabuf); + return err; + } + + err = nvgpu_vm_map_linux(vm, dmabuf, *map_addr, + nvgpu_vm_translate_linux_flags(g, flags), + page_size, + compr_kind, incompr_kind, + gk20a_mem_flag_none, + buffer_offset, + mapping_size, + batch, + &ret_va); + + if (!err) + *map_addr = ret_va; + else + dma_buf_put(dmabuf); + + return err; +} + +/* + * This is the function call-back for freeing OS specific components of an + * nvgpu_mapped_buf. This should most likely never be called outside of the + * core MM framework! + * + * Note: the VM lock will be held. + */ +void nvgpu_vm_unmap_system(struct nvgpu_mapped_buf *mapped_buffer) +{ + struct vm_gk20a *vm = mapped_buffer->vm; + + gk20a_mm_unpin(dev_from_vm(vm), mapped_buffer->os_priv.dmabuf, + mapped_buffer->os_priv.attachment, + mapped_buffer->os_priv.sgt); + + dma_buf_put(mapped_buffer->os_priv.dmabuf); +} diff --git a/include/os/linux/vpr.c b/include/os/linux/vpr.c new file mode 100644 index 0000000..3a98125 --- /dev/null +++ b/include/os/linux/vpr.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include + +#include +#include + +bool nvgpu_is_vpr_resize_enabled(void) +{ + return tegra_is_vpr_resize_supported(); +} diff --git a/include/os/posix/bitmap.c b/include/os/posix/bitmap.c new file mode 100644 index 0000000..99ba62c --- /dev/null +++ b/include/os/posix/bitmap.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include +#include + +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) + +unsigned long __nvgpu_posix_ffs(unsigned long word) +{ + return (__builtin_ffsl(word) - 1) & + ((sizeof(unsigned long) * 8UL) - 1UL); +} + +unsigned long __nvgpu_posix_fls(unsigned long word) +{ + unsigned long ret; + + if (word == 0UL) { + /* __builtin_clzl() below is undefined for 0, so we have + * to handle that as a special case. + */ + ret = 0UL; + } else { + ret = (sizeof(unsigned long) * 8UL) - __builtin_clzl(word); + } + + return ret; +} + +static unsigned long __find_next_bit(const unsigned long *addr, + unsigned long n, + unsigned long start, + bool invert) +{ + unsigned long idx; + unsigned long w; + unsigned long start_mask; + + /* + * We make a mask we can XOR into the word so that we can invert the + * word without requiring a branch. I.e instead of doing: + * + * w = invert ? ~addr[idx] : addr[idx] + * + * We can do: + * + * w = addr[idx] ^= invert_mask + * + * This saves us a branch every iteration through the loop. Now we can + * always just look for 1s. + */ + unsigned long invert_mask = invert ? ~0UL : 0UL; + + if (start >= n) + return n; + + start_mask = ~0UL << (start & (BITS_PER_LONG - 1)); + + idx = start / BITS_PER_LONG; + w = (addr[idx] ^ invert_mask) & start_mask; + + start = round_up(start, BITS_PER_LONG); + + /* + * Find the first non-zero word taking into account start and + * invert. + */ + while (!w) { + idx++; + start += BITS_PER_LONG; + + w = addr[idx] ^ invert_mask; + } + + return min(n, ffs(w) + idx * BITS_PER_LONG); +} + +unsigned long find_first_bit(const unsigned long *addr, unsigned long size) +{ + return __find_next_bit(addr, size, 0, false); +} + +unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) +{ + return __find_next_bit(addr, size, 0, true); +} + +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, + unsigned long offset) +{ + return __find_next_bit(addr, size, offset, false); +} + +static unsigned long find_next_zero_bit(const unsigned long *addr, + unsigned long size, + unsigned long offset) +{ + return __find_next_bit(addr, size, offset, true); +} + +void bitmap_set(unsigned long *map, unsigned int start, int len) +{ + unsigned int end = start + len; + + /* + * Super slow naive implementation. But speed isn't what matters here. + */ + while (start < end) + set_bit(start++, map); +} + +void bitmap_clear(unsigned long *map, unsigned int start, int len) +{ + unsigned int end = start + len; + + while (start < end) + clear_bit(start++, map); +} + +/* + * This is essentially a find-first-fit allocator: this searches a bitmap for + * the first space that is large enough to satisfy the requested size of bits. + * That means that this is not a vary smart allocator. But it is fast relative + * to an allocator that goes looking for an optimal location. + */ +unsigned long bitmap_find_next_zero_area_off(unsigned long *map, + unsigned long size, + unsigned long start, + unsigned int nr, + unsigned long align_mask, + unsigned long align_offset) +{ + unsigned long offs; + + while (start + nr <= size) { + start = find_next_zero_bit(map, size, start); + + start = ALIGN_MASK(start + align_offset, align_mask) - + align_offset; + + /* + * Not enough space left to satisfy the requested area. + */ + if ((start + nr) > size) + return size; + + offs = find_next_bit(map, size, start); + + if ((offs - start) >= nr) + return start; + + start = offs + 1; + } + + return size; +} + +unsigned long bitmap_find_next_zero_area(unsigned long *map, + unsigned long size, + unsigned long start, + unsigned int nr, + unsigned long align_mask) +{ + return bitmap_find_next_zero_area_off(map, size, start, nr, + align_mask, 0); +} + +bool test_bit(int nr, const volatile unsigned long *addr) +{ + return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1))); +} + +bool test_and_set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + volatile unsigned long *p = addr + BIT_WORD(nr); + + return !!(__sync_fetch_and_or(p, mask) & mask); +} + +bool test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + return !!(__sync_fetch_and_and(p, ~mask) & mask); +} + +void set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + __atomic_or(p, mask); +} + +void clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + __atomic_and(p, ~mask); +} diff --git a/include/os/posix/bug.c b/include/os/posix/bug.c new file mode 100644 index 0000000..64f4a6f --- /dev/null +++ b/include/os/posix/bug.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include + +__attribute__ ((noreturn)) +static void __hang(void) +{ + nvgpu_err(NULL, "Hanging!"); + + while (1) + ; +} + +static void __dump_stack(unsigned int skip_frames) +{ + return; +} + +void dump_stack(void) +{ + __dump_stack(0); +} + +/* + * Ahhh! A bug! + */ +void __bug(const char *fmt, ...) +{ + nvgpu_err(NULL, "BUG detected!"); + + __hang(); +} + +bool __warn(bool cond, const char *fmt, ...) +{ + if (!cond) + goto done; + + nvgpu_warn(NULL, "WARNING detected!"); + + dump_stack(); + +done: + return cond; +} diff --git a/include/os/posix/clk_arb.c b/include/os/posix/clk_arb.c new file mode 100644 index 0000000..fcba0a2 --- /dev/null +++ b/include/os/posix/clk_arb.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +/** + * Stub imlementation of the clk_arb code. Yikes. Much of this probably could be + * commonized if one were to think through the implementation but that is + * probably weeks of work at a minimum. + * + * So for POSIX it will be stubbed. + */ + +int nvgpu_clk_arb_init_arbiter(struct gk20a *g) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, + u16 *min_mhz, u16 *max_mhz) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_worker_init(struct gk20a *g) +{ + return -ENOSYS; +} + +bool nvgpu_clk_arb_has_active_req(struct gk20a *g) +{ + return false; +} + +int nvgpu_clk_arb_get_arbiter_actual_mhz(struct gk20a *g, + u32 api_domain, u16 *actual_mhz) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_get_arbiter_effective_mhz(struct gk20a *g, + u32 api_domain, u16 *effective_mhz) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_get_arbiter_clk_f_points(struct gk20a *g, + u32 api_domain, + u32 *max_points, u16 *fpoints) +{ + return -ENOSYS; +} + +u32 nvgpu_clk_arb_get_arbiter_clk_domains(struct gk20a *g) +{ + return 0; +} + +bool nvgpu_clk_arb_is_valid_domain(struct gk20a *g, u32 api_domain) +{ + return false; +} + +void nvgpu_clk_arb_cleanup_arbiter(struct gk20a *g) +{ +} + +int nvgpu_clk_arb_install_session_fd(struct gk20a *g, + struct nvgpu_clk_session *session) +{ + return -ENOSYS; +} + + +int nvgpu_clk_arb_init_session(struct gk20a *g, + struct nvgpu_clk_session **_session) +{ + return -ENOSYS; +} + +void nvgpu_clk_arb_release_session(struct gk20a *g, + struct nvgpu_clk_session *session) +{ +} + +int nvgpu_clk_arb_commit_request_fd(struct gk20a *g, + struct nvgpu_clk_session *session, + int request_fd) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_set_session_target_mhz(struct nvgpu_clk_session *session, + int fd, u32 api_domain, u16 target_mhz) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_get_session_target_mhz(struct nvgpu_clk_session *session, + u32 api_domain, u16 *target_mhz) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_install_event_fd(struct gk20a *g, + struct nvgpu_clk_session *session, + int *event_fd, u32 alarm_mask) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_install_request_fd(struct gk20a *g, + struct nvgpu_clk_session *session, + int *event_fd) +{ + return -ENOSYS; +} + +u32 nvgpu_clk_arb_notify(struct nvgpu_clk_dev *dev, + struct nvgpu_clk_arb_target *target, + u32 alarm) +{ + return 0; +} + +void nvgpu_clk_arb_free_fd(struct nvgpu_ref *refcount) +{ +} + +void nvgpu_clk_arb_schedule_vf_table_update(struct gk20a *g) +{ +} + +int nvgpu_clk_arb_get_current_pstate(struct gk20a *g) +{ + return -ENOSYS; +} + +void nvgpu_clk_arb_pstate_change_lock(struct gk20a *g, bool lock) +{ +} + +void nvgpu_clk_arb_send_thermal_alarm(struct gk20a *g) +{ +} + +void nvgpu_clk_arb_schedule_alarm(struct gk20a *g, u32 alarm) +{ +} + +void nvgpu_clk_arb_set_global_alarm(struct gk20a *g, u32 alarm) +{ +} + +void nvgpu_clk_arb_clear_global_alarm(struct gk20a *g, u32 alarm) +{ +} + +void nvgpu_clk_arb_event_post_event(struct nvgpu_clk_dev *dev) +{ +} + +void nvgpu_clk_arb_worker_enqueue(struct gk20a *g, + struct nvgpu_clk_arb_work_item *work_item) +{ +} + +int nvgpu_clk_notification_queue_alloc(struct gk20a *g, + struct nvgpu_clk_notification_queue *queue, + size_t events_number) +{ + return -ENOSYS; +} diff --git a/include/os/posix/cond.c b/include/os/posix/cond.c new file mode 100644 index 0000000..ca8a2c4 --- /dev/null +++ b/include/os/posix/cond.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include + +int nvgpu_cond_init(struct nvgpu_cond *cond) +{ + return -ENOSYS; +} + +int nvgpu_cond_signal(struct nvgpu_cond *cond) +{ + return -ENOSYS; +} + +int nvgpu_cond_signal_interruptible(struct nvgpu_cond *cond) +{ + return -ENOSYS; +} + +int nvgpu_cond_broadcast(struct nvgpu_cond *cond) +{ + return -ENOSYS; +} + +int nvgpu_cond_broadcast_interruptible(struct nvgpu_cond *cond) +{ + return -ENOSYS; +} + +void nvgpu_cond_destroy(struct nvgpu_cond *cond) +{ + +} diff --git a/include/os/posix/error_notifier.c b/include/os/posix/error_notifier.c new file mode 100644 index 0000000..50b4f25 --- /dev/null +++ b/include/os/posix/error_notifier.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +void nvgpu_set_error_notifier_locked(struct channel_gk20a *ch, u32 error) +{ +} + +void nvgpu_set_error_notifier(struct channel_gk20a *ch, u32 error) +{ +} + +void nvgpu_set_error_notifier_if_empty(struct channel_gk20a *ch, u32 error) +{ +} + +bool nvgpu_is_error_notifier_set(struct channel_gk20a *ch, u32 error_notifier) +{ + return false; +} diff --git a/include/os/posix/firmware.c b/include/os/posix/firmware.c new file mode 100644 index 0000000..aedfef9 --- /dev/null +++ b/include/os/posix/firmware.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +struct nvgpu_firmware *nvgpu_request_firmware(struct gk20a *g, + const char *fw_name, + int flags) +{ + return NULL; +} + +void nvgpu_release_firmware(struct gk20a *g, struct nvgpu_firmware *fw) +{ + /* Noop. */ +} diff --git a/include/os/posix/fuse.c b/include/os/posix/fuse.c new file mode 100644 index 0000000..09ec36d --- /dev/null +++ b/include/os/posix/fuse.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017, 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 + +int nvgpu_tegra_get_gpu_speedo_id(struct gk20a *g) +{ + return 0; +} + +void nvgpu_tegra_fuse_write_bypass(struct gk20a *g, u32 val) +{ +} + +void nvgpu_tegra_fuse_write_access_sw(struct gk20a *g, u32 val) +{ +} + +void nvgpu_tegra_fuse_write_opt_gpu_tpc0_disable(struct gk20a *g, u32 val) +{ +} + +void nvgpu_tegra_fuse_write_opt_gpu_tpc1_disable(struct gk20a *g, u32 val) +{ +} + +int nvgpu_tegra_fuse_read_gcplex_config_fuse(struct gk20a *g, u32 *val) +{ + return -ENODEV; +} + +int nvgpu_tegra_fuse_read_reserved_calib(struct gk20a *g, u32 *val) +{ + return -ENODEV; +} diff --git a/include/os/posix/io.c b/include/os/posix/io.c new file mode 100644 index 0000000..8369e73 --- /dev/null +++ b/include/os/posix/io.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include + +#include "os_posix.h" + + +/* + * This function sets the IO callbacks to the passed set of callbacks. It + * returns the value of the old IO callback struct pointer. This function + * cannot fail. + * + * This is expected to be called from modules to set up their IO interaction. + */ +struct nvgpu_posix_io_callbacks *nvgpu_posix_register_io( + struct gk20a *g, + struct nvgpu_posix_io_callbacks *io_callbacks) +{ + struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g); + struct nvgpu_posix_io_callbacks *old_io = p->callbacks; + + p->callbacks = io_callbacks; + + return old_io; +} + +void nvgpu_writel(struct gk20a *g, u32 r, u32 v) +{ + struct nvgpu_posix_io_callbacks *callbacks = + nvgpu_os_posix_from_gk20a(g)->callbacks; + + struct nvgpu_reg_access access = { + .addr = r, + .value = v + }; + + if (callbacks == NULL || callbacks->writel == NULL) { + BUG(); + } + + callbacks->writel(g, &access); +} + +void nvgpu_writel_relaxed(struct gk20a *g, u32 r, u32 v) +{ + BUG(); +} + +u32 nvgpu_readl(struct gk20a *g, u32 r) +{ + struct nvgpu_posix_io_callbacks *callbacks = + nvgpu_os_posix_from_gk20a(g)->callbacks; + + struct nvgpu_reg_access access = { + .addr = r, + .value = 0L + }; + + if (callbacks == NULL || callbacks->readl == NULL) { + BUG(); + } + + callbacks->readl(g, &access); + + return access.value; +} + +void nvgpu_writel_loop(struct gk20a *g, u32 r, u32 v) +{ + BUG(); +} + +u32 __nvgpu_readl(struct gk20a *g, u32 r) +{ + struct nvgpu_posix_io_callbacks *callbacks = + nvgpu_os_posix_from_gk20a(g)->callbacks; + + struct nvgpu_reg_access access = { + .addr = r, + .value = 0L + }; + + if (callbacks == NULL || callbacks->__readl == NULL) { + BUG(); + } + + callbacks->__readl(g, &access); + + return access.value; +} + +void nvgpu_bar1_writel(struct gk20a *g, u32 b, u32 v) +{ + struct nvgpu_posix_io_callbacks *callbacks = + nvgpu_os_posix_from_gk20a(g)->callbacks; + + struct nvgpu_reg_access access = { + .addr = b, + .value = v + }; + + if (callbacks == NULL || callbacks->bar1_writel == NULL) { + BUG(); + } + + callbacks->bar1_writel(g, &access); +} + +u32 nvgpu_bar1_readl(struct gk20a *g, u32 b) +{ + struct nvgpu_posix_io_callbacks *callbacks = + nvgpu_os_posix_from_gk20a(g)->callbacks; + + struct nvgpu_reg_access access = { + .addr = b, + .value = 0L + }; + + if (callbacks == NULL || callbacks->bar1_readl == NULL) { + BUG(); + } + + callbacks->bar1_readl(g, &access); + + return access.value; +} + +void nvgpu_usermode_writel(struct gk20a *g, u32 r, u32 v) +{ + struct nvgpu_posix_io_callbacks *callbacks = + nvgpu_os_posix_from_gk20a(g)->callbacks; + + struct nvgpu_reg_access access = { + .addr = r, + .value = v + }; + + if (callbacks == NULL || callbacks->usermode_writel == NULL) { + BUG(); + } + + callbacks->usermode_writel(g, &access); +} + +bool nvgpu_io_exists(struct gk20a *g) +{ + return false; +} + +bool nvgpu_io_valid_reg(struct gk20a *g, u32 r) +{ + return false; +} + +void nvgpu_posix_io_init_reg_space(struct gk20a *g) +{ + struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g); + + p->recording = false; + p->error_code = 0; + nvgpu_init_list_node(&p->reg_space_head); + nvgpu_init_list_node(&p->recorder_head); +} + +int nvgpu_posix_io_get_error_code(struct gk20a *g) +{ + struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g); + + return p->error_code; +} + +void nvgpu_posix_io_reset_error_code(struct gk20a *g) +{ + struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g); + + p->error_code = 0; +} + +/* + * Add a new register space to the list of spaces, defined by a base + * address and a size. + */ +int nvgpu_posix_io_add_reg_space(struct gk20a *g, u32 base, u32 size) +{ + struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g); + struct nvgpu_posix_io_reg_space *new_reg_space = + nvgpu_kzalloc(g, sizeof(struct nvgpu_posix_io_reg_space)); + + if (new_reg_space == NULL) { + return -ENOMEM; + } + + new_reg_space->base = base; + new_reg_space->size = size; + + new_reg_space->data = nvgpu_vzalloc(g, size); + if (new_reg_space->data == NULL) { + return -ENOMEM; + } + + nvgpu_list_add_tail(&new_reg_space->link, &p->reg_space_head); + return 0; +} + +void nvgpu_posix_io_delete_reg_space(struct gk20a *g, u32 base) +{ + struct nvgpu_posix_io_reg_space *reg_space = + nvgpu_posix_io_get_reg_space(g, base); + if (reg_space == NULL) { + /* Invalid space, or already de-allocated */ + return; + } + nvgpu_list_del(®_space->link); + nvgpu_vfree(g, reg_space->data); + nvgpu_kfree(g, reg_space); +} + +/* + * Lookup a register space from a given address. If no register space is found + * this is a bug similar to a translation fault. + */ +struct nvgpu_posix_io_reg_space *nvgpu_posix_io_get_reg_space(struct gk20a *g, + u32 addr) +{ + struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g); + struct nvgpu_posix_io_reg_space *reg_space; + + nvgpu_list_for_each_entry(reg_space, &p->reg_space_head, + nvgpu_posix_io_reg_space, link) { + u32 offset = addr - reg_space->base; + + if ((addr >= reg_space->base) && (offset <= reg_space->size)) { + return reg_space; + } + } + p->error_code = -EFAULT; + nvgpu_err(g, "ABORT for address 0x%x", addr); + return NULL; +} + +void nvgpu_posix_io_writel_reg_space(struct gk20a *g, u32 addr, u32 data) +{ + struct nvgpu_posix_io_reg_space *space = + nvgpu_posix_io_get_reg_space(g, addr); + + if (space != NULL) { + u32 offset = (addr - space->base) / ((u32) sizeof(u32)); + + *(space->data + offset) = data; + } +} + +u32 nvgpu_posix_io_readl_reg_space(struct gk20a *g, u32 addr) +{ + struct nvgpu_posix_io_reg_space *space = + nvgpu_posix_io_get_reg_space(g, addr); + + if (space != NULL) { + u32 offset = (addr - space->base) / ((u32) sizeof(u32)); + + return *(space->data + offset); + } else { + return 0; + } +} + +/* + * Start recording register writes. If this function is called again, + * it will free all previously recorded events. + */ +void nvgpu_posix_io_start_recorder(struct gk20a *g) +{ + struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g); + struct nvgpu_posix_io_reg_access *ptr; + + /* If list already has events, delete them all */ + if (p->recording == true) { + while (!nvgpu_list_empty(&p->recorder_head)) { + ptr = nvgpu_list_first_entry(&p->recorder_head, + nvgpu_posix_io_reg_access, link); + nvgpu_list_del(&ptr->link); + nvgpu_kfree(g, ptr); + } + } + p->recording = true; +} + +void nvgpu_posix_io_record_access(struct gk20a *g, + struct nvgpu_reg_access *access) +{ + struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g); + + if (p->recording == true) { + struct nvgpu_posix_io_reg_access *new_event = nvgpu_kzalloc(g, + sizeof(struct nvgpu_posix_io_reg_access)); + (void) memcpy(&(new_event->access), access, + sizeof(struct nvgpu_reg_access)); + nvgpu_list_add_tail(&new_event->link, &p->recorder_head); + } +} + +/* + * Take an array of accesses and compare to the recorded sequence. Returns true + * if the array matches the recorded sequence. + * If strict mode is false, this function allows extra accesses to be present + * in the recording. + */ +bool nvgpu_posix_io_check_sequence(struct gk20a *g, + struct nvgpu_reg_access *sequence, u32 size, bool strict) +{ + struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g); + struct nvgpu_posix_io_reg_access *ptr; + u32 i = 0; + + if (p->recording == false) { + return false; + } + + nvgpu_list_for_each_entry(ptr, &p->recorder_head, + nvgpu_posix_io_reg_access, link) { + if ((sequence[i].addr == ptr->access.addr) && + (sequence[i].value == ptr->access.value)) { + i++; + } else { + if (strict == true) { + return false; + } + } + } + + if (i != size) { + /* Either missing or too many accesses */ + return false; + } + + if (&ptr->link == &p->recorder_head) { + /* Identical match */ + return true; + } + + /* Not an identical match */ + if (strict) { + return false; + } else { + return true; + } +} diff --git a/include/os/posix/kmem.c b/include/os/posix/kmem.c new file mode 100644 index 0000000..5fe0aeb --- /dev/null +++ b/include/os/posix/kmem.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include +#include + +#include + +struct nvgpu_kmem_cache { + size_t alloc_size; +}; + +/* + * kmem cache emulation: basically just do a regular malloc(). This is slower + * but should not affect a user of kmem cache in the slightest bit. + */ +struct nvgpu_kmem_cache *nvgpu_kmem_cache_create(struct gk20a *g, size_t size) +{ + struct nvgpu_kmem_cache *cache = + malloc(sizeof(struct nvgpu_kmem_cache)); + + if (cache != NULL) + return NULL; + + cache->alloc_size = size; + + return cache; +} + +void nvgpu_kmem_cache_destroy(struct nvgpu_kmem_cache *cache) +{ + free(cache); +} + +void *nvgpu_kmem_cache_alloc(struct nvgpu_kmem_cache *cache) +{ + return malloc(cache->alloc_size); +} + +void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr) +{ + free(ptr); +} + +void *__nvgpu_kmalloc(struct gk20a *g, size_t size, void *ip) +{ + return malloc(size); +} + +void *__nvgpu_kzalloc(struct gk20a *g, size_t size, void *ip) +{ + return calloc(1, size); +} + +void *__nvgpu_kcalloc(struct gk20a *g, size_t n, size_t size, void *ip) +{ + /* + * calloc() implicitly zeros mem. So calloc a single member size bytes + * long. + */ + return calloc(n, size); +} + +void __nvgpu_kfree(struct gk20a *g, void *addr) +{ + free(addr); +} + +/* + * The concept of vmalloc() does not exist in userspace. + */ +void *__nvgpu_vmalloc(struct gk20a *g, unsigned long size, void *ip) +{ + return __nvgpu_kmalloc(g, size, ip); +} + +void *__nvgpu_vzalloc(struct gk20a *g, unsigned long size, void *ip) +{ + return __nvgpu_kzalloc(g, size, ip); +} + +void __nvgpu_vfree(struct gk20a *g, void *addr) +{ + __nvgpu_kfree(g, addr); +} + +void *__nvgpu_big_alloc(struct gk20a *g, size_t size, bool clear) +{ + /* + * Since in userspace vmalloc() == kmalloc() == malloc() we can just + * reuse k[zm]alloc() for this. + */ + return clear ? + __nvgpu_kzalloc(g, size, _NVGPU_GET_IP_) : + __nvgpu_kmalloc(g, size, _NVGPU_GET_IP_); +} + +void nvgpu_big_free(struct gk20a *g, void *p) +{ + __nvgpu_kfree(g, p); +} + +int nvgpu_kmem_init(struct gk20a *g) +{ + /* Nothing to init at the moment. */ + return 0; +} + +void nvgpu_kmem_fini(struct gk20a *g, int flags) +{ + +} diff --git a/include/os/posix/lock.c b/include/os/posix/lock.c new file mode 100644 index 0000000..bca0f04 --- /dev/null +++ b/include/os/posix/lock.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +int nvgpu_mutex_init(struct nvgpu_mutex *mutex) +{ + return pthread_mutex_init(&mutex->lock.mutex, NULL); +} + +void nvgpu_mutex_acquire(struct nvgpu_mutex *mutex) +{ + __nvgpu_posix_lock_acquire(&mutex->lock); +} + +void nvgpu_mutex_release(struct nvgpu_mutex *mutex) +{ + __nvgpu_posix_lock_release(&mutex->lock); +} + +int nvgpu_mutex_tryacquire(struct nvgpu_mutex *mutex) +{ + return __nvgpu_posix_lock_try_acquire(&mutex->lock); +} + +void nvgpu_mutex_destroy(struct nvgpu_mutex *mutex) +{ + pthread_mutex_destroy(&mutex->lock.mutex); +} + +void nvgpu_spinlock_init(struct nvgpu_spinlock *spinlock) +{ + pthread_mutex_init(&spinlock->lock.mutex, NULL); +} + +void nvgpu_spinlock_acquire(struct nvgpu_spinlock *spinlock) +{ + __nvgpu_posix_lock_acquire(&spinlock->lock); +} + +void nvgpu_spinlock_release(struct nvgpu_spinlock *spinlock) +{ + __nvgpu_posix_lock_release(&spinlock->lock); +} + +void nvgpu_raw_spinlock_init(struct nvgpu_raw_spinlock *spinlock) +{ + pthread_mutex_init(&spinlock->lock.mutex, NULL); +} + +void nvgpu_raw_spinlock_acquire(struct nvgpu_raw_spinlock *spinlock) +{ + __nvgpu_posix_lock_acquire(&spinlock->lock); +} + +void nvgpu_raw_spinlock_release(struct nvgpu_raw_spinlock *spinlock) +{ + __nvgpu_posix_lock_release(&spinlock->lock); +} diff --git a/include/os/posix/log.c b/include/os/posix/log.c new file mode 100644 index 0000000..35d2626 --- /dev/null +++ b/include/os/posix/log.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include + +/* + * Define a length for log buffers. This is the buffer that the 'fmt, ...' part + * of __nvgpu_do_log_print() prints into. + */ +#define LOG_BUFFER_LENGTH 160 + +/* + * Keep this roughly the same as the kernel log format. + */ +#define LOG_FMT "nvgpu: %s %33s:%-4d [%-4s] %s\n" + +u64 nvgpu_dbg_mask = NVGPU_DEFAULT_DBG_MASK; + +static const char *log_types[] = { + "ERR", + "WRN", + "DBG", + "INFO", +}; + +static inline const char *nvgpu_log_name(struct gk20a *g) +{ + return "gpu.USS"; +} + +static void __nvgpu_really_print_log(const char *gpu_name, + const char *func_name, int line, + enum nvgpu_log_type type, const char *log) +{ + const char *name = gpu_name ? gpu_name : ""; + const char *log_type = log_types[type]; + + printf(LOG_FMT, name, func_name, line, log_type, log); +} + +__attribute__((format (printf, 5, 6))) +void __nvgpu_log_msg(struct gk20a *g, const char *func_name, int line, + enum nvgpu_log_type type, const char *fmt, ...) +{ + char log[LOG_BUFFER_LENGTH]; + va_list args; + + va_start(args, fmt); + vsnprintf(log, LOG_BUFFER_LENGTH, fmt, args); + va_end(args); + + __nvgpu_really_print_log(nvgpu_log_name(g), + func_name, line, type, log); +} + +__attribute__((format (printf, 5, 6))) +void __nvgpu_log_dbg(struct gk20a *g, u64 log_mask, + const char *func_name, int line, + const char *fmt, ...) +{ + char log[LOG_BUFFER_LENGTH]; + va_list args; + + if ((log_mask & g->log_mask) == 0) + return; + + va_start(args, fmt); + vsnprintf(log, LOG_BUFFER_LENGTH, fmt, args); + va_end(args); + + __nvgpu_really_print_log(nvgpu_log_name(g), + func_name, line, NVGPU_DEBUG, log); +} diff --git a/include/os/posix/nvgpu.c b/include/os/posix/nvgpu.c new file mode 100644 index 0000000..e485ed7 --- /dev/null +++ b/include/os/posix/nvgpu.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "os_posix.h" + +void nvgpu_wait_for_deferred_interrupts(struct gk20a *g) +{ + /* + * No interrupts in userspace so nothing to wait for. + */ +} + +int nvgpu_current_pid(struct gk20a *g) +{ + /* + * In the kernel this gets us the PID of the calling process for IOCTLs. + * But since we are in userspace this doesn't quite mean the same thing. + * This simply returns the PID of the currently running process. + */ + return (int)getpid(); +} + +int nvgpu_current_tid(struct gk20a *g) +{ + /* + * In POSIX thread ID is not the same as a process ID. In Linux threads + * and processes are represented by the same thing, but userspace can't + * really rely on that. + * + * We can, however, get a pthread_t for a given thread. But this + * pthread_t need not have any relation to the underlying system's + * representation of "threads". + */ + return (int)pthread_self(); +} + +void __nvgpu_print_current(struct gk20a *g, const char *func_name, int line, + void *ctx, enum nvgpu_log_type type) +{ + __nvgpu_log_msg(g, func_name, line, type, + "Current process: (nvgpu userspace)"); +} + +/* + * Somewhat meaningless in userspace... + */ +void nvgpu_kernel_restart(void *cmd) +{ + BUG(); +} + +/* + * We have no runtime PM stuff in userspace so these are really just noops. + */ +void gk20a_busy_noresume(struct gk20a *g) +{ +} + +void gk20a_idle_nosuspend(struct gk20a *g) +{ +} + +bool gk20a_check_poweron(struct gk20a *g) +{ + return false; +} + +int gk20a_busy(struct gk20a *g) +{ + nvgpu_atomic_inc(&g->usage_count); + + return 0; +} + +void gk20a_idle(struct gk20a *g) +{ + nvgpu_atomic_dec(&g->usage_count); +} + +/* + * This function aims to initialize enough stuff to make unit testing worth + * while. There are several interfaces and APIs that rely on the struct gk20a's + * state in order to function: logging, for example, but there are many other + * things, too. + * + * Initialize as much of that as possible here. This is meant to be equivalent + * to the kernel space driver's probe function. + */ +struct gk20a *nvgpu_posix_probe(void) +{ + struct gk20a *g; + struct nvgpu_os_posix *p; + int err; + + p = malloc(sizeof(*p)); + if (p == NULL) + return NULL; + + g = &p->g; + + err = nvgpu_kmem_init(g); + if (err != 0) + goto fail; + + return g; + +fail: + free(p); + + return NULL; +} + +void nvgpu_posix_cleanup(struct gk20a *g) +{ + nvgpu_kmem_fini(g, 0); +} diff --git a/include/os/posix/nvlink.c b/include/os/posix/nvlink.c new file mode 100644 index 0000000..c830d6e --- /dev/null +++ b/include/os/posix/nvlink.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +int nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off) +{ + return -ENOSYS; +} + +int nvgpu_nvlink_enumerate(struct gk20a *g) +{ + return -ENOSYS; +} diff --git a/include/os/posix/os_posix.h b/include/os/posix/os_posix.h new file mode 100644 index 0000000..d403ad5 --- /dev/null +++ b/include/os/posix/os_posix.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_OS_POSIX_H__ +#define __NVGPU_OS_POSIX_H__ + +#include + +struct nvgpu_posix_io_callbacks; + +struct nvgpu_os_posix { + struct gk20a g; + + + /* + * IO callbacks for handling the nvgpu IO accessors. + */ + struct nvgpu_posix_io_callbacks *callbacks; + + /* + * Memory-mapped register space for unit tests. + */ + struct nvgpu_list_node reg_space_head; + int error_code; + + + /* + * List to record sequence of register writes. + */ + struct nvgpu_list_node recorder_head; + bool recording; +}; + +static inline struct nvgpu_os_posix *nvgpu_os_posix_from_gk20a(struct gk20a *g) +{ + return container_of(g, struct nvgpu_os_posix, g); +} + +#endif diff --git a/include/os/posix/posix-channel.c b/include/os/posix/posix-channel.c new file mode 100644 index 0000000..5e10b1e --- /dev/null +++ b/include/os/posix/posix-channel.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +u32 nvgpu_get_gpfifo_entry_size(void) +{ + /* + * There is no struct nvgpu_gpfifo for us to use yet. But when it's + * defined in userspace this is how big it will be. + */ + return 8; +} diff --git a/include/os/posix/posix-comptags.c b/include/os/posix/posix-comptags.c new file mode 100644 index 0000000..a00246d --- /dev/null +++ b/include/os/posix/posix-comptags.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include + +void gk20a_get_comptags(struct nvgpu_os_buffer *buf, + struct gk20a_comptags *comptags) +{ +} + +int gk20a_alloc_or_get_comptags(struct gk20a *g, + struct nvgpu_os_buffer *buf, + struct gk20a_comptag_allocator *allocator, + struct gk20a_comptags *comptags) +{ + return -ENODEV; +} + +bool gk20a_comptags_start_clear(struct nvgpu_os_buffer *buf) +{ + return false; +} + +void gk20a_comptags_finish_clear(struct nvgpu_os_buffer *buf, + bool clear_successful) +{ +} diff --git a/include/os/posix/posix-dma.c b/include/os/posix/posix-dma.c new file mode 100644 index 0000000..e8c5c9d --- /dev/null +++ b/include/os/posix/posix-dma.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * In userspace vidmem vs sysmem is just a difference in what is placed in the + * aperture field. + */ +static int __nvgpu_do_dma_alloc(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem, + enum nvgpu_aperture ap) +{ + void *memory = malloc(mem->aligned_size); + + if (memory == NULL) + return -ENOMEM; + + mem->cpu_va = memory; + mem->aperture = ap; + mem->size = size; + mem->aligned_size = PAGE_ALIGN(size); + mem->gpu_va = 0ULL; + mem->skip_wmb = true; + mem->vidmem_alloc = NULL; + mem->allocator = NULL; + + return 0; +} + +bool nvgpu_iommuable(struct gk20a *g) +{ + return false; +} + +int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem) +{ + return __nvgpu_do_dma_alloc(g, flags, size, mem, APERTURE_SYSMEM); +} + +int nvgpu_dma_alloc_flags_vid_at(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem, u64 at) +{ + BUG(); + + return 0; +} + +void nvgpu_dma_free_sys(struct gk20a *g, struct nvgpu_mem *mem) +{ + if (!(mem->mem_flags & NVGPU_MEM_FLAG_SHADOW_COPY)) + free(mem->cpu_va); + + memset(mem, 0, sizeof(*mem)); +} + +void nvgpu_dma_free_vid(struct gk20a *g, struct nvgpu_mem *mem) +{ + BUG(); +} diff --git a/include/os/posix/posix-nvgpu_mem.c b/include/os/posix/posix-nvgpu_mem.c new file mode 100644 index 0000000..26770e4 --- /dev/null +++ b/include/os/posix/posix-nvgpu_mem.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include + +/* + * These functions are somewhat meaningless. + */ +u64 nvgpu_mem_get_addr(struct gk20a *g, struct nvgpu_mem *mem) +{ + return (u64)(uintptr_t)mem->cpu_va; +} + +u64 nvgpu_mem_get_phys_addr(struct gk20a *g, struct nvgpu_mem *mem) +{ + return (u64)(uintptr_t)mem->cpu_va; +} + +static struct nvgpu_sgl *nvgpu_mem_sgl_next(struct nvgpu_sgl *sgl) +{ + return NULL; +} + +static u64 nvgpu_mem_sgl_phys(struct gk20a *g, struct nvgpu_sgl *sgl) +{ + struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl; + + return (u64)(uintptr_t)mem->cpu_va; +} + +static u64 nvgpu_mem_sgl_dma(struct nvgpu_sgl *sgl) +{ + struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl; + + return (u64)(uintptr_t)mem->cpu_va; +} + +static u64 nvgpu_mem_sgl_length(struct nvgpu_sgl *sgl) +{ + struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl; + + return (u64)mem->aligned_size; +} + +static u64 nvgpu_mem_sgl_gpu_addr(struct gk20a *g, struct nvgpu_sgl *sgl, + struct nvgpu_gmmu_attrs *attrs) +{ + struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl; + + return mem->gpu_va; +} + +static bool nvgpu_mem_sgt_iommuable(struct gk20a *g, struct nvgpu_sgt *sgt) +{ + return nvgpu_iommuable(g); +} + +static void nvgpu_mem_sgt_free(struct gk20a *g, struct nvgpu_sgt *sgt) +{ + nvgpu_kfree(g, sgt); +} + +static struct nvgpu_sgt_ops nvgpu_sgt_posix_ops = { + .sgl_next = nvgpu_mem_sgl_next, + .sgl_phys = nvgpu_mem_sgl_phys, + .sgl_dma = nvgpu_mem_sgl_dma, + .sgl_length = nvgpu_mem_sgl_length, + .sgl_gpu_addr = nvgpu_mem_sgl_gpu_addr, + .sgt_iommuable = nvgpu_mem_sgt_iommuable, + .sgt_free = nvgpu_mem_sgt_free, +}; + +struct nvgpu_sgt *nvgpu_sgt_create_from_mem(struct gk20a *g, + struct nvgpu_mem *mem) +{ + struct nvgpu_sgt *sgt = nvgpu_kzalloc(g, sizeof(*sgt)); + + if (sgt == NULL) + return NULL; + + /* + * The userspace implementation is simple: a single 'entry' (which we + * only need the mem struct to describe). Maybe this could be expanded + * to be more interesting some day. + */ + sgt->sgl = (struct nvgpu_sgl *)mem; + sgt->ops = &nvgpu_sgt_posix_ops; + + return sgt; +} + +int nvgpu_mem_create_from_mem(struct gk20a *g, + struct nvgpu_mem *dest, struct nvgpu_mem *src, + u64 start_page, int nr_pages) +{ + u64 start = start_page * PAGE_SIZE; + u64 size = nr_pages * PAGE_SIZE; + + if (src->aperture != APERTURE_SYSMEM) + return -EINVAL; + + /* Some silly things a caller might do... */ + if (size > src->size) + return -EINVAL; + if ((start + size) > src->size) + return -EINVAL; + + memset(dest, 0, sizeof(*dest)); + + dest->cpu_va = ((char *)src->cpu_va) + start; + dest->mem_flags = src->mem_flags | NVGPU_MEM_FLAG_SHADOW_COPY; + dest->aperture = src->aperture; + dest->skip_wmb = src->skip_wmb; + dest->size = size; + + return 0; +} diff --git a/include/os/posix/posix-tsg.c b/include/os/posix/posix-tsg.c new file mode 100644 index 0000000..d8e3f37 --- /dev/null +++ b/include/os/posix/posix-tsg.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +void gk20a_tsg_event_id_post_event(struct tsg_gk20a *tsg, + int __event_id) +{ +} diff --git a/include/os/posix/posix-vm.c b/include/os/posix/posix-vm.c new file mode 100644 index 0000000..588b956 --- /dev/null +++ b/include/os/posix/posix-vm.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include + +#include + +u64 nvgpu_os_buf_get_size(struct nvgpu_os_buffer *os_buf) +{ + return os_buf->size; +} + +struct nvgpu_mapped_buf *nvgpu_vm_find_mapping(struct vm_gk20a *vm, + struct nvgpu_os_buffer *os_buf, + u64 map_addr, + u32 flags, + int kind) +{ + BUG(); + + /* + * No map caching for now. + */ + return NULL; +} + +void nvgpu_vm_unmap_system(struct nvgpu_mapped_buf *mapped_buffer) +{ + free(mapped_buffer->os_priv.buf); +} diff --git a/include/os/posix/posix-vpr.c b/include/os/posix/posix-vpr.c new file mode 100644 index 0000000..07486b1 --- /dev/null +++ b/include/os/posix/posix-vpr.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include + +bool nvgpu_is_vpr_resize_enabled(void) +{ + return false; +} diff --git a/include/os/posix/rwsem.c b/include/os/posix/rwsem.c new file mode 100644 index 0000000..7a696b7 --- /dev/null +++ b/include/os/posix/rwsem.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include + +void nvgpu_rwsem_init(struct nvgpu_rwsem *rwsem) +{ + memset(rwsem, 0, sizeof(*rwsem)); + + nvgpu_spinlock_init(&rwsem->lock); +} + +/* + * Acquire. + */ +void nvgpu_rwsem_down_read(struct nvgpu_rwsem *rwsem) +{ + while (true) { + nvgpu_spinlock_acquire(&rwsem->lock); + + /* + * If there's a writer try again. + */ + if (rwsem->writers < 0) { + nvgpu_spinlock_release(&rwsem->lock); + nvgpu_msleep(10); + continue; + } + + /* + * Otherwise decrement the read counter and return. + */ + rwsem->readers -= 1; + nvgpu_spinlock_release(&rwsem->lock); + return; + } +} + +/* + * Release. + */ +void nvgpu_rwsem_up_read(struct nvgpu_rwsem *rwsem) +{ + nvgpu_spinlock_acquire(&rwsem->lock); + rwsem->readers += 1; + + /* + * Can't be any writers if there was a reader. Also can't be + * a positive number of readers. The increments are always + * downward so if we have a positive number then there is a + * balancing bug. + */ + BUG_ON(rwsem->writers < 0); + BUG_ON(rwsem->readers > 0); + + nvgpu_spinlock_release(&rwsem->lock); +} + +void nvgpu_rwsem_down_write(struct nvgpu_rwsem *rwsem) +{ + while (true) { + nvgpu_spinlock_acquire(&rwsem->lock); + + /* + * If there's a reader or a writer try again. Note: in this very + * simple implementation it's possible for readers to + * indefinitely starve writers. + */ + if (rwsem->writers < 0 || rwsem->readers < 0) { + nvgpu_spinlock_release(&rwsem->lock); + nvgpu_msleep(10); + continue; + } + + rwsem->writers -= 1; + nvgpu_spinlock_release(&rwsem->lock); + return; + } +} + +void nvgpu_rwsem_up_write(struct nvgpu_rwsem *rwsem) +{ + nvgpu_spinlock_acquire(&rwsem->lock); + rwsem->writers += 1; + + /* + * Writers can't be positive: that would be an unbalanced free. Readers + * must be zero - otherwise this writer should never have had access! + */ + BUG_ON(rwsem->writers > 0); + BUG_ON(rwsem->readers != 0); + + nvgpu_spinlock_release(&rwsem->lock); +} diff --git a/include/os/posix/soc.c b/include/os/posix/soc.c new file mode 100644 index 0000000..2346d61 --- /dev/null +++ b/include/os/posix/soc.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +bool nvgpu_platform_is_silicon(struct gk20a *g) +{ + return false; +} + +bool nvgpu_platform_is_simulation(struct gk20a *g) +{ + return false; +} + +bool nvgpu_platform_is_fpga(struct gk20a *g) +{ + return false; +} + +bool nvgpu_is_hypervisor_mode(struct gk20a *g) +{ + return false; +} + +bool nvgpu_is_bpmp_running(struct gk20a *g) +{ + return false; +} + +bool nvgpu_is_soc_t194_a01(struct gk20a *g) +{ + return false; +} diff --git a/include/os/posix/stubs.c b/include/os/posix/stubs.c new file mode 100644 index 0000000..279f4da --- /dev/null +++ b/include/os/posix/stubs.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Here lie OS stubs that do not have an implementation yet nor has any plans + * for an implementation. + */ + +#include +#include + +#include "gk20a/dbg_gpu_gk20a.h" + +void nvgpu_dbg_session_post_event(struct dbg_session_gk20a *dbg_s) +{ +} + +int nvgpu_ecc_sysfs_init(struct gk20a *g) +{ + return 0; +} + +void nvgpu_ecc_sysfs_remove(struct gk20a *g) +{ +} + +int nvgpu_ltc_alloc_cbc(struct gk20a *g, size_t compbit_backing_size, + bool vidmem_alloc) +{ + return 0; +} diff --git a/include/os/posix/thread.c b/include/os/posix/thread.c new file mode 100644 index 0000000..6fdce13 --- /dev/null +++ b/include/os/posix/thread.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include + +/** + * Use pthreads to mostly emulate the Linux kernel APIs. There are some things + * that are quite different - especially the stop/should_stop notions. In user + * space threads can send signals to one another but of course within the kernel + * that is not as simple. + * + * This could use some nice debugging some day as well. + */ + +/* + * nvgpu thread functions return int. POSIX threads return void *. This little + * wrapper takes the int returning nvgpu thread and instead passes that int back + * through the void * pointer. + */ +static void *__nvgpu_posix_thread_wrapper(void *data) +{ + struct nvgpu_posix_thread_data *nvgpu = data; + + return ERR_PTR(nvgpu->fn(nvgpu->data)); +} + +int nvgpu_thread_create(struct nvgpu_thread *thread, + void *data, + int (*threadfn)(void *data), const char *name) +{ + int ret; + + BUG_ON(thread->running); + + memset(thread, 0, sizeof(*thread)); + + /* + * By subtracting 1 the above memset ensures that we have a zero + * terminated string. + */ + strncpy(thread->tname, name, NVGPU_THREAD_POSIX_MAX_NAMELEN - 1); + + thread->nvgpu.data = data; + thread->nvgpu.fn = threadfn; + + ret = pthread_create(&thread->thread, NULL, + __nvgpu_posix_thread_wrapper, + &thread->nvgpu); + if (ret != 0) + return ret; + +#ifdef _GNU_SOURCE + pthread_setname_np(thread->thread, thread->tname); +#endif + + thread->running = true; + + return 0; +} + +void nvgpu_thread_stop(struct nvgpu_thread *thread) +{ + thread->should_stop = true; +} + +bool nvgpu_thread_should_stop(struct nvgpu_thread *thread) +{ + return thread->should_stop; +} + +bool nvgpu_thread_is_running(struct nvgpu_thread *thread) +{ + return thread->running; +} + +void nvgpu_thread_join(struct nvgpu_thread *thread) +{ + (void) pthread_join(thread->thread, NULL); +} diff --git a/include/os/posix/timers.c b/include/os/posix/timers.c new file mode 100644 index 0000000..c84b0de --- /dev/null +++ b/include/os/posix/timers.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include +#include + +static s64 now(void) +{ + return nvgpu_current_time_ms(); +} + +/* + * Returns true if a > b; + */ +static bool time_after(s64 a, s64 b) +{ + return a - b > 0; +} + +int nvgpu_timeout_init(struct gk20a *g, struct nvgpu_timeout *timeout, + u32 duration, unsigned long flags) +{ + if (flags & ~NVGPU_TIMER_FLAG_MASK) + return -EINVAL; + + memset(timeout, 0, sizeof(*timeout)); + + timeout->g = g; + timeout->flags = flags; + + if (flags & NVGPU_TIMER_RETRY_TIMER) + timeout->retries.max = duration; + else + timeout->time = nvgpu_current_time_ms() + (s64)duration; + + return 0; +} + +static int __nvgpu_timeout_expired_msg_cpu(struct nvgpu_timeout *timeout, + void *caller, + const char *fmt, va_list args) +{ + struct gk20a *g = timeout->g; + + if (time_after(now(), timeout->time)) { + if (!(timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT)) { + char buf[128]; + + vsnprintf(buf, sizeof(buf), fmt, args); + + nvgpu_err(g, "Timeout detected @ %p %s", caller, buf); + } + + return -ETIMEDOUT; + } + + return 0; +} + +static int __nvgpu_timeout_expired_msg_retry(struct nvgpu_timeout *timeout, + void *caller, + const char *fmt, va_list args) +{ + struct gk20a *g = timeout->g; + + if (timeout->retries.attempted >= timeout->retries.max) { + if (!(timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT)) { + char buf[128]; + + vsnprintf(buf, sizeof(buf), fmt, args); + + nvgpu_err(g, "No more retries @ %p %s", caller, buf); + } + + return -ETIMEDOUT; + } + + timeout->retries.attempted++; + + return 0; +} + +int __nvgpu_timeout_expired_msg(struct nvgpu_timeout *timeout, + void *caller, const char *fmt, ...) +{ + int ret; + va_list args; + + va_start(args, fmt); + if (timeout->flags & NVGPU_TIMER_RETRY_TIMER) + ret = __nvgpu_timeout_expired_msg_retry(timeout, caller, fmt, + args); + else + ret = __nvgpu_timeout_expired_msg_cpu(timeout, caller, fmt, + args); + va_end(args); + + return ret; +} + +int nvgpu_timeout_peek_expired(struct nvgpu_timeout *timeout) +{ + if (timeout->flags & NVGPU_TIMER_RETRY_TIMER) + return timeout->retries.attempted >= timeout->retries.max; + else + return time_after(now(), timeout->time); +} + +void nvgpu_udelay(unsigned int usecs) +{ + BUG(); +} + +void nvgpu_usleep_range(unsigned int min_us, unsigned int max_us) +{ + BUG(); +} + +void nvgpu_msleep(unsigned int msecs) +{ + BUG(); +} + +static inline s64 __nvgpu_current_time_us(void) +{ + struct timeval now; + s64 time_now; + int ret; + + ret = gettimeofday(&now, NULL); + if (ret != 0) + BUG(); + + time_now = ((s64)now.tv_sec * (s64)1000000) + (s64)now.tv_usec; + + return time_now; +} + +s64 nvgpu_current_time_ms(void) +{ + return __nvgpu_current_time_us() / (s64)1000; +} + +u64 nvgpu_hr_timestamp(void) +{ + return __nvgpu_current_time_us(); +} diff --git a/include/pmgr/pmgr.c b/include/pmgr/pmgr.c new file mode 100644 index 0000000..f5be01b --- /dev/null +++ b/include/pmgr/pmgr.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "pwrdev.h" +#include "pmgrpmu.h" + +int pmgr_pwr_devices_get_power(struct gk20a *g, u32 *val) +{ + struct nv_pmu_pmgr_pwr_devices_query_payload payload; + int status; + + status = pmgr_pmu_pwr_devices_query_blocking(g, 1, &payload); + if (status) { + nvgpu_err(g, "pmgr_pwr_devices_get_current_power failed %x", + status); + } + + *val = payload.devices[0].powerm_w; + + return status; +} + +int pmgr_pwr_devices_get_current(struct gk20a *g, u32 *val) +{ + struct nv_pmu_pmgr_pwr_devices_query_payload payload; + int status; + + status = pmgr_pmu_pwr_devices_query_blocking(g, 1, &payload); + if (status) { + nvgpu_err(g, "pmgr_pwr_devices_get_current failed %x", + status); + } + + *val = payload.devices[0].currentm_a; + + return status; +} + +int pmgr_pwr_devices_get_voltage(struct gk20a *g, u32 *val) +{ + struct nv_pmu_pmgr_pwr_devices_query_payload payload; + int status; + + status = pmgr_pmu_pwr_devices_query_blocking(g, 1, &payload); + if (status) { + nvgpu_err(g, "pmgr_pwr_devices_get_current_voltage failed %x", + status); + } + + *val = payload.devices[0].voltageu_v; + + return status; +} + +u32 pmgr_domain_sw_setup(struct gk20a *g) +{ + u32 status; + + status = pmgr_device_sw_setup(g); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for pmgr devices, status - 0x%x", + status); + goto exit; + } + + status = pmgr_monitor_sw_setup(g); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for pmgr monitor, status - 0x%x", + status); + goto exit; + } + + status = pmgr_policy_sw_setup(g); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for pmgr policy, status - 0x%x", + status); + goto exit; + } + +exit: + return status; +} + +int pmgr_domain_pmu_setup(struct gk20a *g) +{ + return pmgr_send_pmgr_tables_to_pmu(g); +} diff --git a/include/pmgr/pmgr.h b/include/pmgr/pmgr.h new file mode 100644 index 0000000..9b142de --- /dev/null +++ b/include/pmgr/pmgr.h @@ -0,0 +1,43 @@ +/* + * general power device structures & definitions + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMGR_H +#define NVGPU_PMGR_H + +#include "pwrdev.h" +#include "pwrmonitor.h" +#include "pwrpolicy.h" + +struct pmgr_pmupstate { + struct pwr_devices pmgr_deviceobjs; + struct pmgr_pwr_monitor pmgr_monitorobjs; + struct pmgr_pwr_policy pmgr_policyobjs; +}; + +u32 pmgr_domain_sw_setup(struct gk20a *g); +int pmgr_domain_pmu_setup(struct gk20a *g); +int pmgr_pwr_devices_get_current(struct gk20a *g, u32 *val); +int pmgr_pwr_devices_get_voltage(struct gk20a *g, u32 *val); +int pmgr_pwr_devices_get_power(struct gk20a *g, u32 *val); + +#endif /* NVGPU_PMGR_H */ diff --git a/include/pmgr/pmgrpmu.c b/include/pmgr/pmgrpmu.c new file mode 100644 index 0000000..b6947f2 --- /dev/null +++ b/include/pmgr/pmgrpmu.c @@ -0,0 +1,546 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "gp106/bios_gp106.h" + +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" + +#include "pwrdev.h" +#include "pmgrpmu.h" + +struct pmgr_pmucmdhandler_params { + u32 success; +}; + +static void pmgr_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg, + void *param, u32 handle, u32 status) +{ + struct pmgr_pmucmdhandler_params *phandlerparams = + (struct pmgr_pmucmdhandler_params *)param; + + if ((msg->msg.pmgr.msg_type != NV_PMU_PMGR_MSG_ID_SET_OBJECT) && + (msg->msg.pmgr.msg_type != NV_PMU_PMGR_MSG_ID_QUERY) && + (msg->msg.pmgr.msg_type != NV_PMU_PMGR_MSG_ID_LOAD)) { + nvgpu_err(g, "unknow msg %x", msg->msg.pmgr.msg_type); + return; + } + + if (msg->msg.pmgr.msg_type == NV_PMU_PMGR_MSG_ID_SET_OBJECT) { + if ((msg->msg.pmgr.set_object.b_success != 1) || + (msg->msg.pmgr.set_object.flcnstatus != 0U)) { + nvgpu_err(g, "pmgr msg failed %x %x %x %x", + msg->msg.pmgr.set_object.msg_type, + msg->msg.pmgr.set_object.b_success, + msg->msg.pmgr.set_object.flcnstatus, + msg->msg.pmgr.set_object.object_type); + return; + } + } else if (msg->msg.pmgr.msg_type == NV_PMU_PMGR_MSG_ID_QUERY) { + if ((msg->msg.pmgr.query.b_success != 1) || + (msg->msg.pmgr.query.flcnstatus != 0U)) { + nvgpu_err(g, "pmgr msg failed %x %x %x %x", + msg->msg.pmgr.query.msg_type, + msg->msg.pmgr.query.b_success, + msg->msg.pmgr.query.flcnstatus, + msg->msg.pmgr.query.cmd_type); + return; + } + } else if (msg->msg.pmgr.msg_type == NV_PMU_PMGR_MSG_ID_LOAD) { + if ((msg->msg.pmgr.query.b_success != 1) || + (msg->msg.pmgr.query.flcnstatus != 0U)) { + nvgpu_err(g, "pmgr msg failed %x %x %x", + msg->msg.pmgr.load.msg_type, + msg->msg.pmgr.load.b_success, + msg->msg.pmgr.load.flcnstatus); + return; + } + } + + phandlerparams->success = 1; +} + +static u32 pmgr_pmu_set_object(struct gk20a *g, + u8 type, + u16 dmem_size, + u16 fb_size, + void *pobj) +{ + struct pmu_cmd cmd; + struct pmu_payload payload; + struct nv_pmu_pmgr_cmd_set_object *pcmd; + u32 status; + u32 seqdesc; + struct pmgr_pmucmdhandler_params handlerparams; + + memset(&payload, 0, sizeof(struct pmu_payload)); + memset(&cmd, 0, sizeof(struct pmu_cmd)); + memset(&handlerparams, 0, sizeof(struct pmgr_pmucmdhandler_params)); + + cmd.hdr.unit_id = PMU_UNIT_PMGR; + cmd.hdr.size = (u32)sizeof(struct nv_pmu_pmgr_cmd_set_object) + + (u32)sizeof(struct pmu_hdr);; + + pcmd = &cmd.cmd.pmgr.set_object; + pcmd->cmd_type = NV_PMU_PMGR_CMD_ID_SET_OBJECT; + pcmd->object_type = type; + + payload.in.buf = pobj; + payload.in.size = dmem_size; + payload.in.fb_size = fb_size; + payload.in.offset = NV_PMU_PMGR_SET_OBJECT_ALLOC_OFFSET; + + /* Setup the handler params to communicate back results.*/ + handlerparams.success = 0; + + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + pmgr_pmucmdhandler, + (void *)&handlerparams, + &seqdesc, ~0); + if (status) { + nvgpu_err(g, + "unable to post pmgr cmd for unit %x cmd id %x obj type %x", + cmd.hdr.unit_id, pcmd->cmd_type, pcmd->object_type); + goto exit; + } + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handlerparams.success, 1); + + if (handlerparams.success == 0U) { + nvgpu_err(g, "could not process cmd"); + status = -ETIMEDOUT; + goto exit; + } + +exit: + return status; +} + +static u32 pmgr_send_i2c_device_topology_to_pmu(struct gk20a *g) +{ + struct nv_pmu_pmgr_i2c_device_desc_table i2c_desc_table; + u32 idx = g->ina3221_dcb_index; + u32 status = 0; + + /* INA3221 I2C device info */ + i2c_desc_table.dev_mask = (1UL << idx); + + /* INA3221 */ + i2c_desc_table.devices[idx].super.type = 0x4E; + + i2c_desc_table.devices[idx].dcb_index = idx; + i2c_desc_table.devices[idx].i2c_address = g->ina3221_i2c_address; + i2c_desc_table.devices[idx].i2c_flags = 0xC2F; + i2c_desc_table.devices[idx].i2c_port = g->ina3221_i2c_port; + + /* Pass the table down the PMU as an object */ + status = pmgr_pmu_set_object( + g, + NV_PMU_PMGR_OBJECT_I2C_DEVICE_DESC_TABLE, + (u16)sizeof(struct nv_pmu_pmgr_i2c_device_desc_table), + PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED, + &i2c_desc_table); + + if (status) { + nvgpu_err(g, "pmgr_pmu_set_object failed %x", + status); + } + + return status; +} + +static int pmgr_send_pwr_device_topology_to_pmu(struct gk20a *g) +{ + struct nv_pmu_pmgr_pwr_device_desc_table *pwr_desc_table; + struct nv_pmu_pmgr_pwr_device_desc_table_header *ppwr_desc_header; + int status = 0; + + /* Set the BA-device-independent HW information */ + pwr_desc_table = nvgpu_kzalloc(g, sizeof(*pwr_desc_table)); + if (!pwr_desc_table) { + return -ENOMEM; + } + + ppwr_desc_header = &(pwr_desc_table->hdr.data); + ppwr_desc_header->ba_info.b_initialized_and_used = false; + + /* populate the table */ + boardobjgrpe32hdrset((struct nv_pmu_boardobjgrp *)&ppwr_desc_header->super, + g->pmgr_pmu.pmgr_deviceobjs.super.super.objmask); + + status = boardobjgrp_pmudatainit_legacy(g, + &g->pmgr_pmu.pmgr_deviceobjs.super.super, + (struct nv_pmu_boardobjgrp_super *)pwr_desc_table); + + if (status) { + nvgpu_err(g, "boardobjgrp_pmudatainit_legacy failed %x", + status); + goto exit; + } + + /* Pass the table down the PMU as an object */ + status = pmgr_pmu_set_object( + g, + NV_PMU_PMGR_OBJECT_PWR_DEVICE_DESC_TABLE, + (u16)sizeof( + union nv_pmu_pmgr_pwr_device_dmem_size), + (u16)sizeof(struct nv_pmu_pmgr_pwr_device_desc_table), + pwr_desc_table); + + if (status) { + nvgpu_err(g, "pmgr_pmu_set_object failed %x", + status); + } + +exit: + nvgpu_kfree(g, pwr_desc_table); + return status; +} + +static int pmgr_send_pwr_mointer_to_pmu(struct gk20a *g) +{ + struct nv_pmu_pmgr_pwr_monitor_pack *pwr_monitor_pack = NULL; + struct nv_pmu_pmgr_pwr_channel_header *pwr_channel_hdr; + struct nv_pmu_pmgr_pwr_chrelationship_header *pwr_chrelationship_header; + u32 max_dmem_size; + int status = 0; + + pwr_monitor_pack = nvgpu_kzalloc(g, sizeof(*pwr_monitor_pack)); + if (!pwr_monitor_pack) { + return -ENOMEM; + } + + /* Copy all the global settings from the RM copy */ + pwr_channel_hdr = &(pwr_monitor_pack->channels.hdr.data); + *pwr_monitor_pack = g->pmgr_pmu.pmgr_monitorobjs.pmu_data; + + boardobjgrpe32hdrset((struct nv_pmu_boardobjgrp *)&pwr_channel_hdr->super, + g->pmgr_pmu.pmgr_monitorobjs.pwr_channels.super.objmask); + + /* Copy in each channel */ + status = boardobjgrp_pmudatainit_legacy(g, + &g->pmgr_pmu.pmgr_monitorobjs.pwr_channels.super, + (struct nv_pmu_boardobjgrp_super *)&(pwr_monitor_pack->channels)); + + if (status) { + nvgpu_err(g, "boardobjgrp_pmudatainit_legacy failed %x", + status); + goto exit; + } + + /* Copy in each channel relationship */ + pwr_chrelationship_header = &(pwr_monitor_pack->ch_rels.hdr.data); + + boardobjgrpe32hdrset((struct nv_pmu_boardobjgrp *)&pwr_chrelationship_header->super, + g->pmgr_pmu.pmgr_monitorobjs.pwr_ch_rels.super.objmask); + + pwr_channel_hdr->physical_channel_mask = g->pmgr_pmu.pmgr_monitorobjs.physical_channel_mask; + pwr_channel_hdr->type = NV_PMU_PMGR_PWR_MONITOR_TYPE_NO_POLLING; + + status = boardobjgrp_pmudatainit_legacy(g, + &g->pmgr_pmu.pmgr_monitorobjs.pwr_ch_rels.super, + (struct nv_pmu_boardobjgrp_super *)&(pwr_monitor_pack->ch_rels)); + + if (status) { + nvgpu_err(g, "boardobjgrp_pmudatainit_legacy failed %x", + status); + goto exit; + } + + /* Calculate the max Dmem buffer size */ + max_dmem_size = sizeof(union nv_pmu_pmgr_pwr_monitor_dmem_size); + + /* Pass the table down the PMU as an object */ + status = pmgr_pmu_set_object( + g, + NV_PMU_PMGR_OBJECT_PWR_MONITOR, + (u16)max_dmem_size, + (u16)sizeof(struct nv_pmu_pmgr_pwr_monitor_pack), + pwr_monitor_pack); + + if (status) { + nvgpu_err(g, "pmgr_pmu_set_object failed %x", + status); + } + +exit: + nvgpu_kfree(g, pwr_monitor_pack); + return status; +} + +static int pmgr_send_pwr_policy_to_pmu(struct gk20a *g) +{ + struct nv_pmu_pmgr_pwr_policy_pack *ppwrpack = NULL; + struct pwr_policy *ppolicy = NULL; + int status = 0; + u8 indx; + u32 max_dmem_size; + + ppwrpack = nvgpu_kzalloc(g, sizeof(struct nv_pmu_pmgr_pwr_policy_pack)); + if (!ppwrpack) { + nvgpu_err(g, "pwr policy alloc failed %x", + status); + status = -ENOMEM; + goto exit; + } + + ppwrpack->policies.hdr.data.version = g->pmgr_pmu.pmgr_policyobjs.version; + ppwrpack->policies.hdr.data.b_enabled = g->pmgr_pmu.pmgr_policyobjs.b_enabled; + + boardobjgrpe32hdrset((struct nv_pmu_boardobjgrp *) + &ppwrpack->policies.hdr.data.super, + g->pmgr_pmu.pmgr_policyobjs.pwr_policies.super.objmask); + + memset(&ppwrpack->policies.hdr.data.reserved_pmu_policy_mask, + 0, + sizeof(ppwrpack->policies.hdr.data.reserved_pmu_policy_mask)); + + ppwrpack->policies.hdr.data.base_sample_period = + g->pmgr_pmu.pmgr_policyobjs.base_sample_period; + ppwrpack->policies.hdr.data.min_client_sample_period = + g->pmgr_pmu.pmgr_policyobjs.min_client_sample_period; + ppwrpack->policies.hdr.data.low_sampling_mult = + g->pmgr_pmu.pmgr_policyobjs.low_sampling_mult; + + memcpy(&ppwrpack->policies.hdr.data.global_ceiling, + &g->pmgr_pmu.pmgr_policyobjs.global_ceiling, + sizeof(struct nv_pmu_perf_domain_group_limits)); + + memcpy(&ppwrpack->policies.hdr.data.semantic_policy_tbl, + &g->pmgr_pmu.pmgr_policyobjs.policy_idxs, + sizeof(g->pmgr_pmu.pmgr_policyobjs.policy_idxs)); + + BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK(32, indx, + ppwrpack->policies.hdr.data.super.obj_mask.super.data[0]) { + ppolicy = PMGR_GET_PWR_POLICY(g, indx); + + status = ((struct boardobj *)ppolicy)->pmudatainit(g, (struct boardobj *)ppolicy, + (struct nv_pmu_boardobj *)&(ppwrpack->policies.policies[indx].data)); + if (status) { + nvgpu_err(g, "pmudatainit failed %x indx %x", + status, indx); + status = -ENOMEM; + goto exit; + } + } + BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK_END; + + boardobjgrpe32hdrset((struct nv_pmu_boardobjgrp *) + &ppwrpack->policy_rels.hdr.data.super, + g->pmgr_pmu.pmgr_policyobjs.pwr_policy_rels.super.objmask); + + boardobjgrpe32hdrset((struct nv_pmu_boardobjgrp *) + &ppwrpack->violations.hdr.data.super, + g->pmgr_pmu.pmgr_policyobjs.pwr_violations.super.objmask); + + max_dmem_size = sizeof(union nv_pmu_pmgr_pwr_policy_dmem_size); + + /* Pass the table down the PMU as an object */ + status = pmgr_pmu_set_object( + g, + NV_PMU_PMGR_OBJECT_PWR_POLICY, + (u16)max_dmem_size, + (u16)sizeof(struct nv_pmu_pmgr_pwr_policy_pack), + ppwrpack); + + if (status) { + nvgpu_err(g, "pmgr_pmu_set_object failed %x", + status); + } + +exit: + if (ppwrpack) { + nvgpu_kfree(g, ppwrpack); + } + + return status; +} + +u32 pmgr_pmu_pwr_devices_query_blocking( + struct gk20a *g, + u32 pwr_dev_mask, + struct nv_pmu_pmgr_pwr_devices_query_payload *ppayload) +{ + struct pmu_cmd cmd; + struct pmu_payload payload; + struct nv_pmu_pmgr_cmd_pwr_devices_query *pcmd; + u32 status; + u32 seqdesc; + struct pmgr_pmucmdhandler_params handlerparams; + + memset(&payload, 0, sizeof(struct pmu_payload)); + memset(&cmd, 0, sizeof(struct pmu_cmd)); + memset(&handlerparams, 0, sizeof(struct pmgr_pmucmdhandler_params)); + + cmd.hdr.unit_id = PMU_UNIT_PMGR; + cmd.hdr.size = (u32)sizeof(struct nv_pmu_pmgr_cmd_pwr_devices_query) + + (u32)sizeof(struct pmu_hdr); + + pcmd = &cmd.cmd.pmgr.pwr_dev_query; + pcmd->cmd_type = NV_PMU_PMGR_CMD_ID_PWR_DEVICES_QUERY; + pcmd->dev_mask = pwr_dev_mask; + + payload.out.buf = ppayload; + payload.out.size = sizeof(struct nv_pmu_pmgr_pwr_devices_query_payload); + payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.out.offset = NV_PMU_PMGR_PWR_DEVICES_QUERY_ALLOC_OFFSET; + + /* Setup the handler params to communicate back results.*/ + handlerparams.success = 0; + + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + pmgr_pmucmdhandler, + (void *)&handlerparams, + &seqdesc, ~0); + if (status) { + nvgpu_err(g, + "unable to post pmgr query cmd for unit %x cmd id %x dev mask %x", + cmd.hdr.unit_id, pcmd->cmd_type, pcmd->dev_mask); + goto exit; + } + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handlerparams.success, 1); + + if (handlerparams.success == 0U) { + nvgpu_err(g, "could not process cmd"); + status = -ETIMEDOUT; + goto exit; + } + +exit: + return status; +} + +static u32 pmgr_pmu_load_blocking(struct gk20a *g) +{ + struct pmu_cmd cmd = { {0} }; + struct nv_pmu_pmgr_cmd_load *pcmd; + u32 status; + u32 seqdesc; + struct pmgr_pmucmdhandler_params handlerparams = {0}; + + cmd.hdr.unit_id = PMU_UNIT_PMGR; + cmd.hdr.size = (u32)sizeof(struct nv_pmu_pmgr_cmd_load) + + (u32)sizeof(struct pmu_hdr); + + pcmd = &cmd.cmd.pmgr.load; + pcmd->cmd_type = NV_PMU_PMGR_CMD_ID_LOAD; + + /* Setup the handler params to communicate back results.*/ + handlerparams.success = 0; + + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, + PMU_COMMAND_QUEUE_LPQ, + pmgr_pmucmdhandler, + (void *)&handlerparams, + &seqdesc, ~0); + if (status) { + nvgpu_err(g, + "unable to post pmgr load cmd for unit %x cmd id %x", + cmd.hdr.unit_id, pcmd->cmd_type); + goto exit; + } + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handlerparams.success, 1); + + if (handlerparams.success == 0U) { + nvgpu_err(g, "could not process cmd"); + status = -ETIMEDOUT; + goto exit; + } + +exit: + return status; +} + +int pmgr_send_pmgr_tables_to_pmu(struct gk20a *g) +{ + int status = 0; + + status = pmgr_send_i2c_device_topology_to_pmu(g); + + if (status) { + nvgpu_err(g, + "pmgr_send_i2c_device_topology_to_pmu failed %x", + status); + goto exit; + } + + if (!BOARDOBJGRP_IS_EMPTY(&g->pmgr_pmu.pmgr_deviceobjs.super.super)) { + status = pmgr_send_pwr_device_topology_to_pmu(g); + if (status) { + nvgpu_err(g, + "pmgr_send_pwr_device_topology_to_pmu failed %x", + status); + goto exit; + } + } + + if (!(BOARDOBJGRP_IS_EMPTY( + &g->pmgr_pmu.pmgr_monitorobjs.pwr_channels.super)) || + !(BOARDOBJGRP_IS_EMPTY( + &g->pmgr_pmu.pmgr_monitorobjs.pwr_ch_rels.super))) { + status = pmgr_send_pwr_mointer_to_pmu(g); + if (status) { + nvgpu_err(g, + "pmgr_send_pwr_mointer_to_pmu failed %x", status); + goto exit; + } + } + + if (!(BOARDOBJGRP_IS_EMPTY( + &g->pmgr_pmu.pmgr_policyobjs.pwr_policies.super)) || + !(BOARDOBJGRP_IS_EMPTY( + &g->pmgr_pmu.pmgr_policyobjs.pwr_policy_rels.super)) || + !(BOARDOBJGRP_IS_EMPTY( + &g->pmgr_pmu.pmgr_policyobjs.pwr_violations.super))) { + status = pmgr_send_pwr_policy_to_pmu(g); + if (status) { + nvgpu_err(g, + "pmgr_send_pwr_policy_to_pmu failed %x", status); + goto exit; + } + } + + status = pmgr_pmu_load_blocking(g); + if (status) { + nvgpu_err(g, + "pmgr_send_pwr_mointer_to_pmu failed %x", status); + goto exit; + } + +exit: + return status; +} diff --git a/include/pmgr/pmgrpmu.h b/include/pmgr/pmgrpmu.h new file mode 100644 index 0000000..f4ffaef --- /dev/null +++ b/include/pmgr/pmgrpmu.h @@ -0,0 +1,39 @@ +/* + * general power device control structures & definitions + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMGRPMU_H +#define NVGPU_PMGRPMU_H + +#include + +#include "pwrdev.h" +#include "pwrmonitor.h" + +int pmgr_send_pmgr_tables_to_pmu(struct gk20a *g); + +u32 pmgr_pmu_pwr_devices_query_blocking( + struct gk20a *g, + u32 pwr_dev_mask, + struct nv_pmu_pmgr_pwr_devices_query_payload *ppayload); + +#endif /* NVGPU_PMGRPMU_H */ diff --git a/include/pmgr/pwrdev.c b/include/pmgr/pwrdev.c new file mode 100644 index 0000000..c1bf084 --- /dev/null +++ b/include/pmgr/pwrdev.c @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "pwrdev.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "gp106/bios_gp106.h" + +static int _pwr_device_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_pmgr_pwr_device_desc_table *ppmgrdevice = + (struct nv_pmu_pmgr_pwr_device_desc_table *)pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + ppmgrdevice->hdr.data.super.obj_mask.super.data[0]) == 0U) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &ppmgrdevice->devices[idx].data.board_obj; + + nvgpu_log_info(g, " Done"); + + return 0; +} + +static int _pwr_domains_pmudatainit_ina3221(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + struct nv_pmu_pmgr_pwr_device_desc_ina3221 *ina3221_desc; + struct pwr_device_ina3221 *ina3221; + int status = 0; + u32 indx; + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status) { + nvgpu_err(g, + "error updating pmu boardobjgrp for pwr domain 0x%x", + status); + goto done; + } + + ina3221 = (struct pwr_device_ina3221 *)board_obj_ptr; + ina3221_desc = (struct nv_pmu_pmgr_pwr_device_desc_ina3221 *) ppmudata; + + ina3221_desc->super.power_corr_factor = ina3221->super.power_corr_factor; + ina3221_desc->i2c_dev_idx = ina3221->super.i2c_dev_idx; + ina3221_desc->configuration = ina3221->configuration; + ina3221_desc->mask_enable = ina3221->mask_enable; + /* configure NV_PMU_THERM_EVENT_EXT_OVERT */ + ina3221_desc->event_mask = (1 << 0); + ina3221_desc->curr_correct_m = ina3221->curr_correct_m; + ina3221_desc->curr_correct_b = ina3221->curr_correct_b; + + for (indx = 0; indx < NV_PMU_PMGR_PWR_DEVICE_INA3221_CH_NUM; indx++) { + ina3221_desc->r_shuntm_ohm[indx] = ina3221->r_shuntm_ohm[indx]; + } + +done: + return status; +} + +static struct boardobj *construct_pwr_device(struct gk20a *g, + void *pargs, u16 pargs_size, u8 type) +{ + struct boardobj *board_obj_ptr = NULL; + int status; + u32 indx; + struct pwr_device_ina3221 *pwrdev; + struct pwr_device_ina3221 *ina3221 = (struct pwr_device_ina3221*)pargs; + + status = boardobj_construct_super(g, &board_obj_ptr, + pargs_size, pargs); + if (status) { + return NULL; + } + + pwrdev = (struct pwr_device_ina3221*)board_obj_ptr; + + /* Set Super class interfaces */ + board_obj_ptr->pmudatainit = _pwr_domains_pmudatainit_ina3221; + pwrdev->super.power_rail = ina3221->super.power_rail; + pwrdev->super.i2c_dev_idx = ina3221->super.i2c_dev_idx; + pwrdev->super.power_corr_factor = (1 << 12); + pwrdev->super.bIs_inforom_config = false; + + /* Set INA3221-specific information */ + pwrdev->configuration = ina3221->configuration; + pwrdev->mask_enable = ina3221->mask_enable; + pwrdev->gpio_function = ina3221->gpio_function; + pwrdev->curr_correct_m = ina3221->curr_correct_m; + pwrdev->curr_correct_b = ina3221->curr_correct_b; + + for (indx = 0; indx < NV_PMU_PMGR_PWR_DEVICE_INA3221_CH_NUM; indx++) { + pwrdev->r_shuntm_ohm[indx] = ina3221->r_shuntm_ohm[indx]; + } + + nvgpu_log_info(g, " Done"); + + return board_obj_ptr; +} + +static int devinit_get_pwr_device_table(struct gk20a *g, + struct pwr_devices *ppwrdeviceobjs) +{ + int status = 0; + u8 *pwr_device_table_ptr = NULL; + u8 *curr_pwr_device_table_ptr = NULL; + struct boardobj *boardobj; + struct pwr_sensors_2x_header pwr_sensor_table_header = { 0 }; + struct pwr_sensors_2x_entry pwr_sensor_table_entry = { 0 }; + u32 index; + u32 obj_index = 0; + u16 pwr_device_size; + union { + struct boardobj boardobj; + struct pwr_device pwrdev; + struct pwr_device_ina3221 ina3221; + } pwr_device_data; + + nvgpu_log_info(g, " "); + + pwr_device_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, POWER_SENSORS_TABLE); + if (pwr_device_table_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&pwr_sensor_table_header, pwr_device_table_ptr, + VBIOS_POWER_SENSORS_2X_HEADER_SIZE_08); + + if (pwr_sensor_table_header.version != + VBIOS_POWER_SENSORS_VERSION_2X) { + status = -EINVAL; + goto done; + } + + if (pwr_sensor_table_header.header_size < + VBIOS_POWER_SENSORS_2X_HEADER_SIZE_08) { + status = -EINVAL; + goto done; + } + + if (pwr_sensor_table_header.table_entry_size != + VBIOS_POWER_SENSORS_2X_ENTRY_SIZE_15) { + status = -EINVAL; + goto done; + } + + curr_pwr_device_table_ptr = (pwr_device_table_ptr + + VBIOS_POWER_SENSORS_2X_HEADER_SIZE_08); + + for (index = 0; index < pwr_sensor_table_header.num_table_entries; index++) { + bool use_fxp8_8 = false; + u8 i2c_dev_idx; + u8 device_type; + + curr_pwr_device_table_ptr += (pwr_sensor_table_header.table_entry_size * index); + + pwr_sensor_table_entry.flags0 = *curr_pwr_device_table_ptr; + + memcpy(&pwr_sensor_table_entry.class_param0, + (curr_pwr_device_table_ptr + 1), + (VBIOS_POWER_SENSORS_2X_ENTRY_SIZE_15 - 1U)); + + device_type = (u8)BIOS_GET_FIELD( + pwr_sensor_table_entry.flags0, + NV_VBIOS_POWER_SENSORS_2X_ENTRY_FLAGS0_CLASS); + + if (device_type == NV_VBIOS_POWER_SENSORS_2X_ENTRY_FLAGS0_CLASS_I2C) { + i2c_dev_idx = (u8)BIOS_GET_FIELD( + pwr_sensor_table_entry.class_param0, + NV_VBIOS_POWER_SENSORS_2X_ENTRY_CLASS_PARAM0_I2C_INDEX); + use_fxp8_8 = (u8)BIOS_GET_FIELD( + pwr_sensor_table_entry.class_param0, + NV_VBIOS_POWER_SENSORS_2X_ENTRY_CLASS_PARAM0_I2C_USE_FXP8_8); + + pwr_device_data.ina3221.super.i2c_dev_idx = i2c_dev_idx; + pwr_device_data.ina3221.r_shuntm_ohm[0].use_fxp8_8 = use_fxp8_8; + pwr_device_data.ina3221.r_shuntm_ohm[1].use_fxp8_8 = use_fxp8_8; + pwr_device_data.ina3221.r_shuntm_ohm[2].use_fxp8_8 = use_fxp8_8; + pwr_device_data.ina3221.r_shuntm_ohm[0].rshunt_value = + (u16)BIOS_GET_FIELD( + pwr_sensor_table_entry.sensor_param0, + NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM0_INA3221_RSHUNT0_MOHM); + + pwr_device_data.ina3221.r_shuntm_ohm[1].rshunt_value = + (u16)BIOS_GET_FIELD( + pwr_sensor_table_entry.sensor_param0, + NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM0_INA3221_RSHUNT1_MOHM); + + pwr_device_data.ina3221.r_shuntm_ohm[2].rshunt_value = + (u16)BIOS_GET_FIELD( + pwr_sensor_table_entry.sensor_param1, + NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM1_INA3221_RSHUNT2_MOHM); + pwr_device_data.ina3221.configuration = + (u16)BIOS_GET_FIELD( + pwr_sensor_table_entry.sensor_param1, + NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM1_INA3221_CONFIGURATION); + + pwr_device_data.ina3221.mask_enable = + (u16)BIOS_GET_FIELD( + pwr_sensor_table_entry.sensor_param2, + NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM2_INA3221_MASKENABLE); + + pwr_device_data.ina3221.gpio_function = + (u8)BIOS_GET_FIELD( + pwr_sensor_table_entry.sensor_param2, + NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM2_INA3221_GPIOFUNCTION); + + pwr_device_data.ina3221.curr_correct_m = + (u16)BIOS_GET_FIELD( + pwr_sensor_table_entry.sensor_param3, + NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM3_INA3221_CURR_CORRECT_M); + + pwr_device_data.ina3221.curr_correct_b = + (u16)BIOS_GET_FIELD( + pwr_sensor_table_entry.sensor_param3, + NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM3_INA3221_CURR_CORRECT_B); + + if (!pwr_device_data.ina3221.curr_correct_m) { + pwr_device_data.ina3221.curr_correct_m = (1 << 12); + } + pwr_device_size = sizeof(struct pwr_device_ina3221); + } else { + continue; + } + + pwr_device_data.boardobj.type = CTRL_PMGR_PWR_DEVICE_TYPE_INA3221; + pwr_device_data.pwrdev.power_rail = (u8)0; + + boardobj = construct_pwr_device(g, &pwr_device_data, + pwr_device_size, pwr_device_data.boardobj.type); + + if (!boardobj) { + nvgpu_err(g, + "unable to create pwr device for %d type %d", index, pwr_device_data.boardobj.type); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert(&ppwrdeviceobjs->super.super, + boardobj, obj_index); + + if (status) { + nvgpu_err(g, + "unable to insert pwr device boardobj for %d", index); + status = -EINVAL; + goto done; + } + + ++obj_index; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int pmgr_device_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + struct pwr_devices *ppwrdeviceobjs; + + /* Construct the Super Class and override the Interfaces */ + status = boardobjgrpconstruct_e32(g, &g->pmgr_pmu.pmgr_deviceobjs.super); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for pmgr devices, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->pmgr_pmu.pmgr_deviceobjs.super.super; + ppwrdeviceobjs = &(g->pmgr_pmu.pmgr_deviceobjs); + + /* Override the Interfaces */ + pboardobjgrp->pmudatainstget = _pwr_device_pmudata_instget; + + status = devinit_get_pwr_device_table(g, ppwrdeviceobjs); + if (status) { + goto done; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} diff --git a/include/pmgr/pwrdev.h b/include/pmgr/pwrdev.h new file mode 100644 index 0000000..4bcf65a --- /dev/null +++ b/include/pmgr/pwrdev.h @@ -0,0 +1,60 @@ +/* + * general power device structures & definitions + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMGR_PWRDEV_H +#define NVGPU_PMGR_PWRDEV_H + +#include "boardobj/boardobj.h" +#include +#include "ctrl/ctrlpmgr.h" + +#define PWRDEV_I2CDEV_DEVICE_INDEX_NONE (0xFF) + +#define PWR_DEVICE_PROV_NUM_DEFAULT 1 + +struct pwr_device { + struct boardobj super; + u8 power_rail; + u8 i2c_dev_idx; + bool bIs_inforom_config; + u32 power_corr_factor; +}; + +struct pwr_devices { + struct boardobjgrp_e32 super; +}; + +struct pwr_device_ina3221 { + struct pwr_device super; + struct ctrl_pmgr_pwr_device_info_rshunt + r_shuntm_ohm[NV_PMU_PMGR_PWR_DEVICE_INA3221_CH_NUM]; + u16 configuration; + u16 mask_enable; + u8 gpio_function; + u16 curr_correct_m; + s16 curr_correct_b; +} ; + +int pmgr_device_sw_setup(struct gk20a *g); + +#endif /* NVGPU_PMGR_PWRDEV_H */ diff --git a/include/pmgr/pwrmonitor.c b/include/pmgr/pwrmonitor.c new file mode 100644 index 0000000..710ae85 --- /dev/null +++ b/include/pmgr/pwrmonitor.c @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "pwrdev.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "gp106/bios_gp106.h" + +static int _pwr_channel_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_pmgr_pwr_channel_desc *ppmgrchannel = + (struct nv_pmu_pmgr_pwr_channel_desc *)pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + ppmgrchannel->hdr.data.super.obj_mask.super.data[0]) == 0U) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &ppmgrchannel->channels[idx].data.board_obj; + + /* handle Global/common data here as we need index */ + ppmgrchannel->channels[idx].data.pwr_channel.ch_idx = idx; + + nvgpu_log_info(g, " Done"); + + return 0; +} + +static int _pwr_channel_rels_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_pmgr_pwr_chrelationship_desc *ppmgrchrels = + (struct nv_pmu_pmgr_pwr_chrelationship_desc *)pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + ppmgrchrels->hdr.data.super.obj_mask.super.data[0]) == 0U) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &ppmgrchrels->ch_rels[idx].data.board_obj; + + nvgpu_log_info(g, " Done"); + + return 0; +} + +static u32 _pwr_channel_state_init(struct gk20a *g) +{ + u8 indx = 0; + struct pwr_channel *pchannel; + u32 objmask = + g->pmgr_pmu.pmgr_monitorobjs.pwr_channels.super.objmask; + + /* Initialize each PWR_CHANNEL's dependent channel mask */ + BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK(32, indx, objmask) { + pchannel = PMGR_PWR_MONITOR_GET_PWR_CHANNEL(g, indx); + if (pchannel == NULL) { + nvgpu_err(g, + "PMGR_PWR_MONITOR_GET_PWR_CHANNEL-failed %d", indx); + return -EINVAL; + } + pchannel->dependent_ch_mask =0; + } + BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK_END + + return 0; +} + +static bool _pwr_channel_implements(struct pwr_channel *pchannel, + u8 type) +{ + return (type == BOARDOBJ_GET_TYPE(pchannel)); +} + +static int _pwr_domains_pmudatainit_sensor(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + struct nv_pmu_pmgr_pwr_channel_sensor *pmu_sensor_data; + struct pwr_channel_sensor *sensor; + int status = 0; + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status) { + nvgpu_err(g, + "error updating pmu boardobjgrp for pwr sensor 0x%x", + status); + goto done; + } + + sensor = (struct pwr_channel_sensor *)board_obj_ptr; + pmu_sensor_data = (struct nv_pmu_pmgr_pwr_channel_sensor *) ppmudata; + + pmu_sensor_data->super.pwr_rail = sensor->super.pwr_rail; + pmu_sensor_data->super.volt_fixedu_v = sensor->super.volt_fixed_uv; + pmu_sensor_data->super.pwr_corr_slope = sensor->super.pwr_corr_slope; + pmu_sensor_data->super.pwr_corr_offsetm_w = sensor->super.pwr_corr_offset_mw; + pmu_sensor_data->super.curr_corr_slope = sensor->super.curr_corr_slope; + pmu_sensor_data->super.curr_corr_offsetm_a = sensor->super.curr_corr_offset_ma; + pmu_sensor_data->super.dependent_ch_mask = sensor->super.dependent_ch_mask; + pmu_sensor_data->super.ch_idx = 0; + + pmu_sensor_data->pwr_dev_idx = sensor->pwr_dev_idx; + pmu_sensor_data->pwr_dev_prov_idx = sensor->pwr_dev_prov_idx; + +done: + return status; +} + +static struct boardobj *construct_pwr_topology(struct gk20a *g, + void *pargs, u16 pargs_size, u8 type) +{ + struct boardobj *board_obj_ptr = NULL; + int status; + struct pwr_channel_sensor *pwrchannel; + struct pwr_channel_sensor *sensor = (struct pwr_channel_sensor*)pargs; + + status = boardobj_construct_super(g, &board_obj_ptr, + pargs_size, pargs); + if (status) { + return NULL; + } + + pwrchannel = (struct pwr_channel_sensor*)board_obj_ptr; + + /* Set Super class interfaces */ + board_obj_ptr->pmudatainit = _pwr_domains_pmudatainit_sensor; + + pwrchannel->super.pwr_rail = sensor->super.pwr_rail; + pwrchannel->super.volt_fixed_uv = sensor->super.volt_fixed_uv; + pwrchannel->super.pwr_corr_slope = sensor->super.pwr_corr_slope; + pwrchannel->super.pwr_corr_offset_mw = sensor->super.pwr_corr_offset_mw; + pwrchannel->super.curr_corr_slope = sensor->super.curr_corr_slope; + pwrchannel->super.curr_corr_offset_ma = sensor->super.curr_corr_offset_ma; + pwrchannel->super.dependent_ch_mask = 0; + + pwrchannel->pwr_dev_idx = sensor->pwr_dev_idx; + pwrchannel->pwr_dev_prov_idx = sensor->pwr_dev_prov_idx; + + nvgpu_log_info(g, " Done"); + + return board_obj_ptr; +} + +static int devinit_get_pwr_topology_table(struct gk20a *g, + struct pmgr_pwr_monitor *ppwrmonitorobjs) +{ + int status = 0; + u8 *pwr_topology_table_ptr = NULL; + u8 *curr_pwr_topology_table_ptr = NULL; + struct boardobj *boardobj; + struct pwr_topology_2x_header pwr_topology_table_header = { 0 }; + struct pwr_topology_2x_entry pwr_topology_table_entry = { 0 }; + u32 index; + u32 obj_index = 0; + u16 pwr_topology_size; + union { + struct boardobj boardobj; + struct pwr_channel pwrchannel; + struct pwr_channel_sensor sensor; + } pwr_topology_data; + + nvgpu_log_info(g, " "); + + pwr_topology_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, POWER_TOPOLOGY_TABLE); + if (pwr_topology_table_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&pwr_topology_table_header, pwr_topology_table_ptr, + VBIOS_POWER_TOPOLOGY_2X_HEADER_SIZE_06); + + if (pwr_topology_table_header.version != + VBIOS_POWER_TOPOLOGY_VERSION_2X) { + status = -EINVAL; + goto done; + } + + g->pmgr_pmu.pmgr_monitorobjs.b_is_topology_tbl_ver_1x = false; + + if (pwr_topology_table_header.header_size < + VBIOS_POWER_TOPOLOGY_2X_HEADER_SIZE_06) { + status = -EINVAL; + goto done; + } + + if (pwr_topology_table_header.table_entry_size != + VBIOS_POWER_TOPOLOGY_2X_ENTRY_SIZE_16) { + status = -EINVAL; + goto done; + } + + curr_pwr_topology_table_ptr = (pwr_topology_table_ptr + + VBIOS_POWER_TOPOLOGY_2X_HEADER_SIZE_06); + + for (index = 0; index < pwr_topology_table_header.num_table_entries; + index++) { + u8 class_type; + + curr_pwr_topology_table_ptr += (pwr_topology_table_header.table_entry_size * index); + + pwr_topology_table_entry.flags0 = *curr_pwr_topology_table_ptr; + pwr_topology_table_entry.pwr_rail = *(curr_pwr_topology_table_ptr + 1); + + memcpy(&pwr_topology_table_entry.param0, + (curr_pwr_topology_table_ptr + 2), + (VBIOS_POWER_TOPOLOGY_2X_ENTRY_SIZE_16 - 2U)); + + class_type = (u8)BIOS_GET_FIELD( + pwr_topology_table_entry.flags0, + NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_FLAGS0_CLASS); + + if (class_type == NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_FLAGS0_CLASS_SENSOR) { + pwr_topology_data.sensor.pwr_dev_idx = (u8)BIOS_GET_FIELD( + pwr_topology_table_entry.param1, + NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_PARAM1_SENSOR_INDEX); + pwr_topology_data.sensor.pwr_dev_prov_idx = (u8)BIOS_GET_FIELD( + pwr_topology_table_entry.param1, + NV_VBIOS_POWER_TOPOLOGY_2X_ENTRY_PARAM1_SENSOR_PROVIDER_INDEX); + + pwr_topology_size = sizeof(struct pwr_channel_sensor); + } else { + continue; + } + + /* Initialize data for the parent class */ + pwr_topology_data.boardobj.type = CTRL_PMGR_PWR_CHANNEL_TYPE_SENSOR; + pwr_topology_data.pwrchannel.pwr_rail = (u8)pwr_topology_table_entry.pwr_rail; + pwr_topology_data.pwrchannel.volt_fixed_uv = pwr_topology_table_entry.param0; + pwr_topology_data.pwrchannel.pwr_corr_slope = (1 << 12); + pwr_topology_data.pwrchannel.pwr_corr_offset_mw = 0; + pwr_topology_data.pwrchannel.curr_corr_slope = + (u32)pwr_topology_table_entry.curr_corr_slope; + pwr_topology_data.pwrchannel.curr_corr_offset_ma = + (s32)pwr_topology_table_entry.curr_corr_offset; + + boardobj = construct_pwr_topology(g, &pwr_topology_data, + pwr_topology_size, pwr_topology_data.boardobj.type); + + if (!boardobj) { + nvgpu_err(g, + "unable to create pwr topology for %d type %d", + index, pwr_topology_data.boardobj.type); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert(&ppwrmonitorobjs->pwr_channels.super, + boardobj, obj_index); + + if (status) { + nvgpu_err(g, + "unable to insert pwr topology boardobj for %d", index); + status = -EINVAL; + goto done; + } + + ++obj_index; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int pmgr_monitor_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + struct pwr_channel *pchannel; + struct pmgr_pwr_monitor *ppwrmonitorobjs; + u8 indx = 0; + + /* Construct the Super Class and override the Interfaces */ + status = boardobjgrpconstruct_e32(g, + &g->pmgr_pmu.pmgr_monitorobjs.pwr_channels); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for pmgr channel, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &(g->pmgr_pmu.pmgr_monitorobjs.pwr_channels.super); + + /* Override the Interfaces */ + pboardobjgrp->pmudatainstget = _pwr_channel_pmudata_instget; + + /* Construct the Super Class and override the Interfaces */ + status = boardobjgrpconstruct_e32(g, + &g->pmgr_pmu.pmgr_monitorobjs.pwr_ch_rels); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for pmgr channel relationship, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &(g->pmgr_pmu.pmgr_monitorobjs.pwr_ch_rels.super); + + /* Override the Interfaces */ + pboardobjgrp->pmudatainstget = _pwr_channel_rels_pmudata_instget; + + /* Initialize the Total GPU Power Channel Mask to 0 */ + g->pmgr_pmu.pmgr_monitorobjs.pmu_data.channels.hdr.data.total_gpu_power_channel_mask = 0; + g->pmgr_pmu.pmgr_monitorobjs.total_gpu_channel_idx = + CTRL_PMGR_PWR_CHANNEL_INDEX_INVALID; + + /* Supported topology table version 1.0 */ + g->pmgr_pmu.pmgr_monitorobjs.b_is_topology_tbl_ver_1x = true; + + ppwrmonitorobjs = &(g->pmgr_pmu.pmgr_monitorobjs); + + status = devinit_get_pwr_topology_table(g, ppwrmonitorobjs); + if (status) { + goto done; + } + + status = _pwr_channel_state_init(g); + if (status) { + goto done; + } + + /* Initialise physicalChannelMask */ + g->pmgr_pmu.pmgr_monitorobjs.physical_channel_mask = 0; + + pboardobjgrp = &g->pmgr_pmu.pmgr_monitorobjs.pwr_channels.super; + + BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct pwr_channel *, pchannel, indx) { + if (_pwr_channel_implements(pchannel, + CTRL_PMGR_PWR_CHANNEL_TYPE_SENSOR)) { + g->pmgr_pmu.pmgr_monitorobjs.physical_channel_mask |= BIT(indx); + } + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} diff --git a/include/pmgr/pwrmonitor.h b/include/pmgr/pwrmonitor.h new file mode 100644 index 0000000..bf4c76f --- /dev/null +++ b/include/pmgr/pwrmonitor.h @@ -0,0 +1,69 @@ +/* + * general power channel structures & definitions + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMGR_PWRMONITOR_H +#define NVGPU_PMGR_PWRMONITOR_H + +#include +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobj.h" +#include "ctrl/ctrlpmgr.h" + +struct pwr_channel { + struct boardobj super; + u8 pwr_rail; + u32 volt_fixed_uv; + u32 pwr_corr_slope; + s32 pwr_corr_offset_mw; + u32 curr_corr_slope; + s32 curr_corr_offset_ma; + u32 dependent_ch_mask; +}; + +struct pwr_chrelationship { + struct boardobj super; + u8 chIdx; +}; + +struct pwr_channel_sensor { + struct pwr_channel super; + u8 pwr_dev_idx; + u8 pwr_dev_prov_idx; +}; + +struct pmgr_pwr_monitor { + bool b_is_topology_tbl_ver_1x; + struct boardobjgrp_e32 pwr_channels; + struct boardobjgrp_e32 pwr_ch_rels; + u8 total_gpu_channel_idx; + u32 physical_channel_mask; + struct nv_pmu_pmgr_pwr_monitor_pack pmu_data; +}; + +#define PMGR_PWR_MONITOR_GET_PWR_CHANNEL(g, channel_idx) \ + ((struct pwr_channel *)BOARDOBJGRP_OBJ_GET_BY_IDX( \ + &(g->pmgr_pmu.pmgr_monitorobjs.pwr_channels.super), (channel_idx))) + +int pmgr_monitor_sw_setup(struct gk20a *g); + +#endif /* NVGPU_PMGR_PWRMONITOR_H */ diff --git a/include/pmgr/pwrpolicy.c b/include/pmgr/pwrpolicy.c new file mode 100644 index 0000000..3bf6f32 --- /dev/null +++ b/include/pmgr/pwrpolicy.c @@ -0,0 +1,782 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "pwrpolicy.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "gp106/bios_gp106.h" + +#define _pwr_policy_limitarboutputget_helper(p_limit_arb) (p_limit_arb)->output +#define _pwr_policy_limitdeltaapply(limit, delta) ((u32)max(((s32)limit) + (delta), 0)) + +static u32 _pwr_policy_limitarbinputset_helper(struct gk20a *g, + struct ctrl_pmgr_pwr_policy_limit_arbitration *p_limit_arb, + u8 client_idx, + u32 limit_value) +{ + u8 indx; + bool b_found = false; + u32 status = 0; + u32 output = limit_value; + + for (indx = 0; indx< p_limit_arb->num_inputs; indx++) { + if (p_limit_arb->inputs[indx].pwr_policy_idx == client_idx) { + p_limit_arb->inputs[indx].limit_value = limit_value; + b_found = true; + } else if (p_limit_arb->b_arb_max) { + output = max(output, p_limit_arb->inputs[indx].limit_value); + } else { + output = min(output, p_limit_arb->inputs[indx].limit_value); + } + } + + if (!b_found) { + if (p_limit_arb->num_inputs < + CTRL_PMGR_PWR_POLICY_MAX_LIMIT_INPUTS) { + p_limit_arb->inputs[ + p_limit_arb->num_inputs].pwr_policy_idx = client_idx; + p_limit_arb->inputs[ + p_limit_arb->num_inputs].limit_value = limit_value; + p_limit_arb->num_inputs++; + } else { + nvgpu_err(g, "No entries remaining for clientIdx=%d", + client_idx); + status = -EINVAL; + } + } + + if (!status) { + p_limit_arb->output = output; + } + + return status; +} + +static u32 _pwr_policy_limitid_translate(struct gk20a *g, + struct pwr_policy *ppolicy, + enum pwr_policy_limit_id limit_id, + struct ctrl_pmgr_pwr_policy_limit_arbitration **p_limit_arb, + struct ctrl_pmgr_pwr_policy_limit_arbitration **p_limit_arb_sec) +{ + u32 status = 0; + + switch (limit_id) { + case PWR_POLICY_LIMIT_ID_MIN: + *p_limit_arb = &ppolicy->limit_arb_min; + break; + + case PWR_POLICY_LIMIT_ID_RATED: + *p_limit_arb = &ppolicy->limit_arb_rated; + + if (p_limit_arb_sec != NULL) { + *p_limit_arb_sec = &ppolicy->limit_arb_curr; + } + break; + + case PWR_POLICY_LIMIT_ID_MAX: + *p_limit_arb = &ppolicy->limit_arb_max; + break; + + case PWR_POLICY_LIMIT_ID_CURR: + *p_limit_arb = &ppolicy->limit_arb_curr; + break; + + case PWR_POLICY_LIMIT_ID_BATT: + *p_limit_arb = &ppolicy->limit_arb_batt; + break; + + default: + nvgpu_err(g, "Unsupported limitId=%d", + limit_id); + status = -EINVAL; + break; + } + + return status; +} + +static u32 _pwr_policy_limitarbinputset(struct gk20a *g, + struct pwr_policy *ppolicy, + enum pwr_policy_limit_id limit_id, + u8 client_idx, + u32 limit) +{ + u32 status = 0; + struct ctrl_pmgr_pwr_policy_limit_arbitration *p_limit_arb = NULL; + struct ctrl_pmgr_pwr_policy_limit_arbitration *p_limit_arb_sec = NULL; + + status = _pwr_policy_limitid_translate(g, + ppolicy, + limit_id, + &p_limit_arb, + &p_limit_arb_sec); + if (status) { + goto exit; + } + + status = _pwr_policy_limitarbinputset_helper(g, p_limit_arb, client_idx, limit); + if (status) { + nvgpu_err(g, + "Error setting client limit value: status=0x%08x, limitId=0x%x, clientIdx=0x%x, limit=%d", + status, limit_id, client_idx, limit); + goto exit; + } + + if (NULL != p_limit_arb_sec) { + status = _pwr_policy_limitarbinputset_helper(g, p_limit_arb_sec, + CTRL_PMGR_PWR_POLICY_LIMIT_INPUT_CLIENT_IDX_RM, + _pwr_policy_limitarboutputget_helper(p_limit_arb)); + } + +exit: + return status; +} + +static inline void _pwr_policy_limitarbconstruct( + struct ctrl_pmgr_pwr_policy_limit_arbitration *p_limit_arb, + bool b_arb_max) +{ + p_limit_arb->num_inputs = 0; + p_limit_arb->b_arb_max = b_arb_max; +} + +static u32 _pwr_policy_limitarboutputget(struct gk20a *g, + struct pwr_policy *ppolicy, + enum pwr_policy_limit_id limit_id) +{ + u32 status = 0; + struct ctrl_pmgr_pwr_policy_limit_arbitration *p_limit_arb = NULL; + + status = _pwr_policy_limitid_translate(g, + ppolicy, + limit_id, + &p_limit_arb, + NULL); + if (status) { + return 0; + } + + return _pwr_policy_limitarboutputget_helper(p_limit_arb); +} + +static int _pwr_domains_pmudatainit_hw_threshold(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + struct nv_pmu_pmgr_pwr_policy_hw_threshold *pmu_hw_threshold_data; + struct pwr_policy_hw_threshold *p_hw_threshold; + struct pwr_policy *p_pwr_policy; + struct nv_pmu_pmgr_pwr_policy *pmu_pwr_policy; + int status = 0; + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status) { + nvgpu_err(g, + "error updating pmu boardobjgrp for pwr sensor 0x%x", + status); + status = -ENOMEM; + goto done; + } + + p_hw_threshold = (struct pwr_policy_hw_threshold *)board_obj_ptr; + pmu_hw_threshold_data = (struct nv_pmu_pmgr_pwr_policy_hw_threshold *) ppmudata; + pmu_pwr_policy = (struct nv_pmu_pmgr_pwr_policy *) ppmudata; + p_pwr_policy = (struct pwr_policy *)&(p_hw_threshold->super.super); + + pmu_pwr_policy->ch_idx = 0; + pmu_pwr_policy->limit_unit = p_pwr_policy->limit_unit; + pmu_pwr_policy->num_limit_inputs = p_pwr_policy->num_limit_inputs; + + pmu_pwr_policy->limit_min = _pwr_policy_limitdeltaapply( + _pwr_policy_limitarboutputget(g, p_pwr_policy, + PWR_POLICY_LIMIT_ID_MIN), + p_pwr_policy->limit_delta); + + pmu_pwr_policy->limit_max = _pwr_policy_limitdeltaapply( + _pwr_policy_limitarboutputget(g, p_pwr_policy, + PWR_POLICY_LIMIT_ID_MAX), + p_pwr_policy->limit_delta); + + pmu_pwr_policy->limit_curr = _pwr_policy_limitdeltaapply( + _pwr_policy_limitarboutputget(g, p_pwr_policy, + PWR_POLICY_LIMIT_ID_CURR), + p_pwr_policy->limit_delta); + + memcpy(&pmu_pwr_policy->integral, &p_pwr_policy->integral, + sizeof(struct ctrl_pmgr_pwr_policy_info_integral)); + + pmu_pwr_policy->sample_mult = p_pwr_policy->sample_mult; + pmu_pwr_policy->filter_type = p_pwr_policy->filter_type; + pmu_pwr_policy->filter_param = p_pwr_policy->filter_param; + + pmu_hw_threshold_data->threshold_idx = p_hw_threshold->threshold_idx; + pmu_hw_threshold_data->low_threshold_idx = p_hw_threshold->low_threshold_idx; + pmu_hw_threshold_data->b_use_low_threshold = p_hw_threshold->b_use_low_threshold; + pmu_hw_threshold_data->low_threshold_value = p_hw_threshold->low_threshold_value; + + if (BOARDOBJ_GET_TYPE(board_obj_ptr) == + CTRL_PMGR_PWR_POLICY_TYPE_SW_THRESHOLD) { + struct nv_pmu_pmgr_pwr_policy_sw_threshold *pmu_sw_threshold_data; + struct pwr_policy_sw_threshold *p_sw_threshold; + + p_sw_threshold = (struct pwr_policy_sw_threshold *)board_obj_ptr; + pmu_sw_threshold_data = + (struct nv_pmu_pmgr_pwr_policy_sw_threshold *) ppmudata; + pmu_sw_threshold_data->event_id = + p_sw_threshold->event_id; + } +done: + return status; +} + +static struct boardobj *construct_pwr_policy(struct gk20a *g, + void *pargs, u16 pargs_size, u8 type) +{ + struct boardobj *board_obj_ptr = NULL; + int status; + struct pwr_policy_hw_threshold *pwrpolicyhwthreshold; + struct pwr_policy *pwrpolicy; + struct pwr_policy *pwrpolicyparams = (struct pwr_policy*)pargs; + struct pwr_policy_hw_threshold *hwthreshold = (struct pwr_policy_hw_threshold*)pargs; + + status = boardobj_construct_super(g, &board_obj_ptr, + pargs_size, pargs); + if (status) { + return NULL; + } + + pwrpolicyhwthreshold = (struct pwr_policy_hw_threshold*)board_obj_ptr; + pwrpolicy = (struct pwr_policy *)board_obj_ptr; + + nvgpu_log_fn(g, "min=%u rated=%u max=%u", + pwrpolicyparams->limit_min, + pwrpolicyparams->limit_rated, + pwrpolicyparams->limit_max); + + /* Set Super class interfaces */ + board_obj_ptr->pmudatainit = _pwr_domains_pmudatainit_hw_threshold; + + pwrpolicy->ch_idx = pwrpolicyparams->ch_idx; + pwrpolicy->num_limit_inputs = 0; + pwrpolicy->limit_unit = pwrpolicyparams->limit_unit; + pwrpolicy->filter_type = (enum ctrl_pmgr_pwr_policy_filter_type)(pwrpolicyparams->filter_type); + pwrpolicy->sample_mult = pwrpolicyparams->sample_mult; + switch (pwrpolicy->filter_type) + { + case CTRL_PMGR_PWR_POLICY_FILTER_TYPE_NONE: + break; + + case CTRL_PMGR_PWR_POLICY_FILTER_TYPE_BLOCK: + pwrpolicy->filter_param.block.block_size = + pwrpolicyparams->filter_param.block.block_size; + break; + + case CTRL_PMGR_PWR_POLICY_FILTER_TYPE_MOVING_AVERAGE: + pwrpolicy->filter_param.moving_avg.window_size = + pwrpolicyparams->filter_param.moving_avg.window_size; + break; + + case CTRL_PMGR_PWR_POLICY_FILTER_TYPE_IIR: + pwrpolicy->filter_param.iir.divisor = pwrpolicyparams->filter_param.iir.divisor; + break; + + default: + nvgpu_err(g, "Error: unrecognized Power Policy filter type: %d", + pwrpolicy->filter_type); + } + + _pwr_policy_limitarbconstruct(&pwrpolicy->limit_arb_curr, false); + + pwrpolicy->limit_delta = 0; + + _pwr_policy_limitarbconstruct(&pwrpolicy->limit_arb_min, true); + status = _pwr_policy_limitarbinputset(g, + pwrpolicy, + PWR_POLICY_LIMIT_ID_MIN, + CTRL_PMGR_PWR_POLICY_LIMIT_INPUT_CLIENT_IDX_RM, + pwrpolicyparams->limit_min); + + _pwr_policy_limitarbconstruct(&pwrpolicy->limit_arb_max, false); + status = _pwr_policy_limitarbinputset(g, + pwrpolicy, + PWR_POLICY_LIMIT_ID_MAX, + CTRL_PMGR_PWR_POLICY_LIMIT_INPUT_CLIENT_IDX_RM, + pwrpolicyparams->limit_max); + + _pwr_policy_limitarbconstruct(&pwrpolicy->limit_arb_rated, false); + status = _pwr_policy_limitarbinputset(g, + pwrpolicy, + PWR_POLICY_LIMIT_ID_RATED, + CTRL_PMGR_PWR_POLICY_LIMIT_INPUT_CLIENT_IDX_RM, + pwrpolicyparams->limit_rated); + + _pwr_policy_limitarbconstruct(&pwrpolicy->limit_arb_batt, false); + status = _pwr_policy_limitarbinputset(g, + pwrpolicy, + PWR_POLICY_LIMIT_ID_BATT, + CTRL_PMGR_PWR_POLICY_LIMIT_INPUT_CLIENT_IDX_RM, + ((pwrpolicyparams->limit_batt != 0U) ? + pwrpolicyparams->limit_batt: + CTRL_PMGR_PWR_POLICY_LIMIT_MAX)); + + memcpy(&pwrpolicy->integral, &pwrpolicyparams->integral, + sizeof(struct ctrl_pmgr_pwr_policy_info_integral)); + + pwrpolicyhwthreshold->threshold_idx = hwthreshold->threshold_idx; + pwrpolicyhwthreshold->b_use_low_threshold = hwthreshold->b_use_low_threshold; + pwrpolicyhwthreshold->low_threshold_idx = hwthreshold->low_threshold_idx; + pwrpolicyhwthreshold->low_threshold_value = hwthreshold->low_threshold_value; + + if (type == CTRL_PMGR_PWR_POLICY_TYPE_SW_THRESHOLD) { + struct pwr_policy_sw_threshold *pwrpolicyswthreshold; + struct pwr_policy_sw_threshold *swthreshold = + (struct pwr_policy_sw_threshold*)pargs; + + pwrpolicyswthreshold = (struct pwr_policy_sw_threshold*)board_obj_ptr; + pwrpolicyswthreshold->event_id = swthreshold->event_id; + } + + nvgpu_log_info(g, " Done"); + + return board_obj_ptr; +} + +static int _pwr_policy_construct_WAR_SW_Threshold_policy(struct gk20a *g, + struct pmgr_pwr_policy *ppwrpolicyobjs, + union pwr_policy_data_union *ppwrpolicydata, + u16 pwr_policy_size, + u32 obj_index) +{ + int status = 0; + struct boardobj *boardobj; + + /* WARN policy */ + ppwrpolicydata->pwrpolicy.limit_unit = 0; + ppwrpolicydata->pwrpolicy.limit_min = 10000; + ppwrpolicydata->pwrpolicy.limit_rated = 100000; + ppwrpolicydata->pwrpolicy.limit_max = 100000; + ppwrpolicydata->sw_threshold.threshold_idx = 1; + ppwrpolicydata->pwrpolicy.filter_type = + CTRL_PMGR_PWR_POLICY_FILTER_TYPE_MOVING_AVERAGE; + ppwrpolicydata->pwrpolicy.sample_mult = 5; + + /* Filled the entry.filterParam value in the filterParam */ + ppwrpolicydata->pwrpolicy.filter_param.moving_avg.window_size = 10; + + ppwrpolicydata->sw_threshold.event_id = 0x01; + + ppwrpolicydata->boardobj.type = CTRL_PMGR_PWR_POLICY_TYPE_SW_THRESHOLD; + + boardobj = construct_pwr_policy(g, ppwrpolicydata, + pwr_policy_size, ppwrpolicydata->boardobj.type); + + if (!boardobj) { + nvgpu_err(g, + "unable to create pwr policy for type %d", ppwrpolicydata->boardobj.type); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert(&ppwrpolicyobjs->pwr_policies.super, + boardobj, obj_index); + + if (status) { + nvgpu_err(g, + "unable to insert pwr policy boardobj for %d", obj_index); + status = -EINVAL; + goto done; + } +done: + return status; +} + +struct pwr_policy_3x_header_unpacked { + u8 version; + u8 header_size; + u8 table_entry_size; + u8 num_table_entries; + u16 base_sample_period; + u16 min_client_sample_period; + u8 table_rel_entry_size; + u8 num_table_rel_entries; + u8 tgp_policy_idx; + u8 rtp_policy_idx; + u8 mxm_policy_idx; + u8 dnotifier_policy_idx; + u32 d2_limit; + u32 d3_limit; + u32 d4_limit; + u32 d5_limit; + u8 low_sampling_mult; + u8 pwr_tgt_policy_idx; + u8 pwr_tgt_floor_policy_idx; + u8 sm_bus_policy_idx; + u8 table_viol_entry_size; + u8 num_table_viol_entries; +}; + +#define __UNPACK_FIELD(unpacked, packed, field) \ + __builtin_memcpy(&unpacked->field, &packed->field, \ + sizeof(unpacked->field)) + +static inline void devinit_unpack_pwr_policy_header( + struct pwr_policy_3x_header_unpacked *unpacked, + struct pwr_policy_3x_header_struct *packed) +{ + __UNPACK_FIELD(unpacked, packed, version); + __UNPACK_FIELD(unpacked, packed, header_size); + __UNPACK_FIELD(unpacked, packed, table_entry_size); + __UNPACK_FIELD(unpacked, packed, num_table_entries); + __UNPACK_FIELD(unpacked, packed, base_sample_period); + __UNPACK_FIELD(unpacked, packed, min_client_sample_period); + __UNPACK_FIELD(unpacked, packed, table_rel_entry_size); + __UNPACK_FIELD(unpacked, packed, num_table_rel_entries); + __UNPACK_FIELD(unpacked, packed, tgp_policy_idx); + __UNPACK_FIELD(unpacked, packed, rtp_policy_idx); + __UNPACK_FIELD(unpacked, packed, mxm_policy_idx); + __UNPACK_FIELD(unpacked, packed, dnotifier_policy_idx); + __UNPACK_FIELD(unpacked, packed, d2_limit); + __UNPACK_FIELD(unpacked, packed, d3_limit); + __UNPACK_FIELD(unpacked, packed, d4_limit); + __UNPACK_FIELD(unpacked, packed, d5_limit); + __UNPACK_FIELD(unpacked, packed, low_sampling_mult); + __UNPACK_FIELD(unpacked, packed, pwr_tgt_policy_idx); + __UNPACK_FIELD(unpacked, packed, pwr_tgt_floor_policy_idx); + __UNPACK_FIELD(unpacked, packed, sm_bus_policy_idx); + __UNPACK_FIELD(unpacked, packed, table_viol_entry_size); + __UNPACK_FIELD(unpacked, packed, num_table_viol_entries); +} + +struct pwr_policy_3x_entry_unpacked { + u8 flags0; + u8 ch_idx; + u32 limit_min; + u32 limit_rated; + u32 limit_max; + u32 param0; + u32 param1; + u32 param2; + u32 param3; + u32 limit_batt; + u8 flags1; + u8 past_length; + u8 next_length; + u16 ratio_min; + u16 ratio_max; + u8 sample_mult; + u32 filter_param; +}; + +static inline void devinit_unpack_pwr_policy_entry( + struct pwr_policy_3x_entry_unpacked *unpacked, + struct pwr_policy_3x_entry_struct *packed) +{ + __UNPACK_FIELD(unpacked, packed, flags0); + __UNPACK_FIELD(unpacked, packed, ch_idx); + __UNPACK_FIELD(unpacked, packed, limit_min); + __UNPACK_FIELD(unpacked, packed, limit_rated); + __UNPACK_FIELD(unpacked, packed, limit_max); + __UNPACK_FIELD(unpacked, packed, param0); + __UNPACK_FIELD(unpacked, packed, param1); + __UNPACK_FIELD(unpacked, packed, param2); + __UNPACK_FIELD(unpacked, packed, param3); + __UNPACK_FIELD(unpacked, packed, limit_batt); + __UNPACK_FIELD(unpacked, packed, flags1); + __UNPACK_FIELD(unpacked, packed, past_length); + __UNPACK_FIELD(unpacked, packed, next_length); + __UNPACK_FIELD(unpacked, packed, ratio_min); + __UNPACK_FIELD(unpacked, packed, ratio_max); + __UNPACK_FIELD(unpacked, packed, sample_mult); + __UNPACK_FIELD(unpacked, packed, filter_param); +} + +static int devinit_get_pwr_policy_table(struct gk20a *g, + struct pmgr_pwr_policy *ppwrpolicyobjs) +{ + int status = 0; + u8 *ptr = NULL; + struct boardobj *boardobj; + struct pwr_policy_3x_header_struct *packed_hdr; + struct pwr_policy_3x_header_unpacked hdr; + u32 index; + u32 obj_index = 0; + u16 pwr_policy_size; + bool integral_control = false; + u32 hw_threshold_policy_index = 0; + union pwr_policy_data_union pwr_policy_data; + + nvgpu_log_info(g, " "); + + ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, POWER_CAPPING_TABLE); + if (ptr == NULL) { + status = -EINVAL; + goto done; + } + + packed_hdr = (struct pwr_policy_3x_header_struct *)ptr; + + if (packed_hdr->version != + VBIOS_POWER_POLICY_VERSION_3X) { + status = -EINVAL; + goto done; + } + + if (packed_hdr->header_size < + VBIOS_POWER_POLICY_3X_HEADER_SIZE_25) { + status = -EINVAL; + goto done; + } + + if (packed_hdr->table_entry_size < + VBIOS_POWER_POLICY_3X_ENTRY_SIZE_2E) { + status = -EINVAL; + goto done; + } + + /* unpack power policy table header */ + devinit_unpack_pwr_policy_header(&hdr, packed_hdr); + + ptr += (u32)hdr.header_size; + + for (index = 0; index < hdr.num_table_entries; + index++, ptr += (u32)hdr.table_entry_size) { + + struct pwr_policy_3x_entry_struct *packed_entry; + struct pwr_policy_3x_entry_unpacked entry; + + u8 class_type; + + packed_entry = (struct pwr_policy_3x_entry_struct *)ptr; + + class_type = (u8)BIOS_GET_FIELD( + packed_entry->flags0, + NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS); + + if (class_type != NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_CLASS_HW_THRESHOLD) { + continue; + } + + /* unpack power policy table entry */ + devinit_unpack_pwr_policy_entry(&entry, packed_entry); + + ppwrpolicyobjs->version = + CTRL_PMGR_PWR_POLICY_TABLE_VERSION_3X; + ppwrpolicyobjs->base_sample_period = hdr.base_sample_period; + ppwrpolicyobjs->min_client_sample_period = + hdr.min_client_sample_period; + ppwrpolicyobjs->low_sampling_mult = hdr.low_sampling_mult; + + ppwrpolicyobjs->policy_idxs[1] = hdr.tgp_policy_idx; + ppwrpolicyobjs->policy_idxs[0] = hdr.rtp_policy_idx; + ppwrpolicyobjs->policy_idxs[2] = hdr.mxm_policy_idx; + ppwrpolicyobjs->policy_idxs[3] = hdr.dnotifier_policy_idx; + ppwrpolicyobjs->ext_limits[0].limit = hdr.d2_limit; + ppwrpolicyobjs->ext_limits[1].limit = hdr.d3_limit; + ppwrpolicyobjs->ext_limits[2].limit = hdr.d4_limit; + ppwrpolicyobjs->ext_limits[3].limit = hdr.d5_limit; + ppwrpolicyobjs->policy_idxs[4] = hdr.pwr_tgt_policy_idx; + ppwrpolicyobjs->policy_idxs[5] = hdr.pwr_tgt_floor_policy_idx; + ppwrpolicyobjs->policy_idxs[6] = hdr.sm_bus_policy_idx; + + integral_control = (bool)BIOS_GET_FIELD(entry.flags1, + NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_INTEGRAL_CONTROL); + + if (integral_control == 0x01) { + pwr_policy_data.pwrpolicy.integral.past_sample_count = + entry.past_length; + pwr_policy_data.pwrpolicy.integral.next_sample_count = + entry.next_length; + pwr_policy_data.pwrpolicy.integral.ratio_limit_max = + entry.ratio_max; + pwr_policy_data.pwrpolicy.integral.ratio_limit_min = + entry.ratio_min; + } else { + memset(&(pwr_policy_data.pwrpolicy.integral), 0x0, + sizeof(struct ctrl_pmgr_pwr_policy_info_integral)); + } + pwr_policy_data.hw_threshold.threshold_idx = (u8) + BIOS_GET_FIELD(entry.param0, + NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_THRES_IDX); + + pwr_policy_data.hw_threshold.b_use_low_threshold = + BIOS_GET_FIELD(entry.param0, + NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_LOW_THRESHOLD_USE); + + if (pwr_policy_data.hw_threshold.b_use_low_threshold) { + pwr_policy_data.hw_threshold.low_threshold_idx = (u8) + BIOS_GET_FIELD(entry.param0, + NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM0_HW_THRESHOLD_LOW_THRESHOLD_IDX); + + pwr_policy_data.hw_threshold.low_threshold_value = (u16) + BIOS_GET_FIELD(entry.param1, + NV_VBIOS_POWER_POLICY_3X_ENTRY_PARAM1_HW_THRESHOLD_LOW_THRESHOLD_VAL); + } + + pwr_policy_size = sizeof(struct pwr_policy_hw_threshold); + + /* Initialize data for the parent class */ + pwr_policy_data.boardobj.type = + CTRL_PMGR_PWR_POLICY_TYPE_HW_THRESHOLD; + pwr_policy_data.pwrpolicy.ch_idx = entry.ch_idx; + pwr_policy_data.pwrpolicy.limit_unit = (u8) + BIOS_GET_FIELD(entry.flags0, + NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS0_LIMIT_UNIT); + pwr_policy_data.pwrpolicy.filter_type = + (enum ctrl_pmgr_pwr_policy_filter_type) + BIOS_GET_FIELD(entry.flags1, + NV_VBIOS_POWER_POLICY_3X_ENTRY_FLAGS1_FILTER_TYPE); + + pwr_policy_data.pwrpolicy.limit_min = entry.limit_min; + pwr_policy_data.pwrpolicy.limit_rated = entry.limit_rated; + pwr_policy_data.pwrpolicy.limit_max = entry.limit_max; + pwr_policy_data.pwrpolicy.limit_batt = entry.limit_batt; + + pwr_policy_data.pwrpolicy.sample_mult = (u8)entry.sample_mult; + + /* Filled the entry.filterParam value in the filterParam */ + pwr_policy_data.pwrpolicy.filter_param.block.block_size = 0; + pwr_policy_data.pwrpolicy.filter_param.moving_avg.window_size = 0; + pwr_policy_data.pwrpolicy.filter_param.iir.divisor = 0; + + hw_threshold_policy_index |= + BIT(pwr_policy_data.hw_threshold.threshold_idx); + + boardobj = construct_pwr_policy(g, &pwr_policy_data, + pwr_policy_size, pwr_policy_data.boardobj.type); + + if (!boardobj) { + nvgpu_err(g, + "unable to create pwr policy for %d type %d", + index, pwr_policy_data.boardobj.type); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert(&ppwrpolicyobjs->pwr_policies.super, + boardobj, obj_index); + + if (status) { + nvgpu_err(g, + "unable to insert pwr policy boardobj for %d", + index); + status = -EINVAL; + goto done; + } + + ++obj_index; + } + + if (g->hardcode_sw_threshold) { + status = _pwr_policy_construct_WAR_SW_Threshold_policy(g, + ppwrpolicyobjs, + &pwr_policy_data, + sizeof(struct pwr_policy_sw_threshold), + obj_index); + if (status) { + nvgpu_err(g, "unable to construct_WAR_policy"); + status = -EINVAL; + goto done; + } + ++obj_index; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int pmgr_policy_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + struct pwr_policy *ppolicy; + struct pmgr_pwr_policy *ppwrpolicyobjs; + u8 indx = 0; + + /* Construct the Super Class and override the Interfaces */ + status = boardobjgrpconstruct_e32(g, + &g->pmgr_pmu.pmgr_policyobjs.pwr_policies); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for pmgr policy, status - 0x%x", + status); + goto done; + } + + status = boardobjgrpconstruct_e32(g, + &g->pmgr_pmu.pmgr_policyobjs.pwr_policy_rels); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for pmgr policy rels, status - 0x%x", + status); + goto done; + } + + status = boardobjgrpconstruct_e32(g, + &g->pmgr_pmu.pmgr_policyobjs.pwr_violations); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for pmgr violations, status - 0x%x", + status); + goto done; + } + + memset(g->pmgr_pmu.pmgr_policyobjs.policy_idxs, CTRL_PMGR_PWR_POLICY_INDEX_INVALID, + sizeof(u8) * CTRL_PMGR_PWR_POLICY_IDX_NUM_INDEXES); + + /* Initialize external power limit policy indexes to _INVALID/0xFF */ + for (indx = 0; indx < PWR_POLICY_EXT_POWER_STATE_ID_COUNT; indx++) { + g->pmgr_pmu.pmgr_policyobjs.ext_limits[indx].policy_table_idx = + CTRL_PMGR_PWR_POLICY_INDEX_INVALID; + } + + /* Initialize external power state to _D1 */ + g->pmgr_pmu.pmgr_policyobjs.ext_power_state = 0xFFFFFFFF; + + ppwrpolicyobjs = &(g->pmgr_pmu.pmgr_policyobjs); + pboardobjgrp = &(g->pmgr_pmu.pmgr_policyobjs.pwr_policies.super); + + status = devinit_get_pwr_policy_table(g, ppwrpolicyobjs); + if (status) { + goto done; + } + + g->pmgr_pmu.pmgr_policyobjs.b_enabled = true; + + BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct pwr_policy *, ppolicy, indx) { + PMGR_PWR_POLICY_INCREMENT_LIMIT_INPUT_COUNT(ppolicy); + } + + g->pmgr_pmu.pmgr_policyobjs.global_ceiling.values[0] = + 0xFF; + + g->pmgr_pmu.pmgr_policyobjs.client_work_item.b_pending = false; + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} diff --git a/include/pmgr/pwrpolicy.h b/include/pmgr/pwrpolicy.h new file mode 100644 index 0000000..74f4937 --- /dev/null +++ b/include/pmgr/pwrpolicy.h @@ -0,0 +1,136 @@ +/* + * general power channel structures & definitions + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PMGR_PWRPOLICY_H +#define NVGPU_PMGR_PWRPOLICY_H + +#include +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobj.h" +#include "ctrl/ctrlpmgr.h" + +#define PWR_POLICY_EXT_POWER_STATE_ID_COUNT 0x4U + +enum pwr_policy_limit_id { + PWR_POLICY_LIMIT_ID_MIN = 0x00000000, + PWR_POLICY_LIMIT_ID_RATED, + PWR_POLICY_LIMIT_ID_MAX, + PWR_POLICY_LIMIT_ID_CURR, + PWR_POLICY_LIMIT_ID_BATT, +}; + +struct pwr_policy { + struct boardobj super; + u8 ch_idx; + u8 num_limit_inputs; + u8 limit_unit; + s32 limit_delta; + u32 limit_min; + u32 limit_rated; + u32 limit_max; + u32 limit_batt; + struct ctrl_pmgr_pwr_policy_info_integral integral; + struct ctrl_pmgr_pwr_policy_limit_arbitration limit_arb_min; + struct ctrl_pmgr_pwr_policy_limit_arbitration limit_arb_rated; + struct ctrl_pmgr_pwr_policy_limit_arbitration limit_arb_max; + struct ctrl_pmgr_pwr_policy_limit_arbitration limit_arb_batt; + struct ctrl_pmgr_pwr_policy_limit_arbitration limit_arb_curr; + u8 sample_mult; + enum ctrl_pmgr_pwr_policy_filter_type filter_type; + union ctrl_pmgr_pwr_policy_filter_param filter_param; +}; + +struct pwr_policy_ext_limit { + u8 policy_table_idx; + u32 limit; +}; + +struct pwr_policy_batt_workitem { + u32 power_state; + bool b_full_deflection; +}; + +struct pwr_policy_client_workitem { + u32 limit; + bool b_pending; +}; + +struct pwr_policy_relationship { + struct boardobj super; + u8 policy_idx; +}; + +struct pmgr_pwr_policy { + u8 version; + bool b_enabled; + struct nv_pmu_perf_domain_group_limits global_ceiling; + u8 policy_idxs[CTRL_PMGR_PWR_POLICY_IDX_NUM_INDEXES]; + struct pwr_policy_ext_limit ext_limits[PWR_POLICY_EXT_POWER_STATE_ID_COUNT]; + s32 ext_power_state; + u16 base_sample_period; + u16 min_client_sample_period; + u8 low_sampling_mult; + struct boardobjgrp_e32 pwr_policies; + struct boardobjgrp_e32 pwr_policy_rels; + struct boardobjgrp_e32 pwr_violations; + struct pwr_policy_client_workitem client_work_item; +}; + +struct pwr_policy_limit { + struct pwr_policy super; +}; + +struct pwr_policy_hw_threshold { + struct pwr_policy_limit super; + u8 threshold_idx; + u8 low_threshold_idx; + bool b_use_low_threshold; + u16 low_threshold_value; +}; + +struct pwr_policy_sw_threshold { + struct pwr_policy_limit super; + u8 threshold_idx; + u8 low_threshold_idx; + bool b_use_low_threshold; + u16 low_threshold_value; + u8 event_id; +}; + +union pwr_policy_data_union { + struct boardobj boardobj; + struct pwr_policy pwrpolicy; + struct pwr_policy_hw_threshold hw_threshold; + struct pwr_policy_sw_threshold sw_threshold; +} ; + +#define PMGR_GET_PWR_POLICY(g, policy_idx) \ + ((struct pwr_policy *)BOARDOBJGRP_OBJ_GET_BY_IDX( \ + &(g->pmgr_pmu.pmgr_policyobjs.pwr_policies.super), (policy_idx))) + +#define PMGR_PWR_POLICY_INCREMENT_LIMIT_INPUT_COUNT(ppolicy) \ + ((ppolicy)->num_limit_inputs++) + +int pmgr_policy_sw_setup(struct gk20a *g); + +#endif /* NVGPU_PMGR_PWRPOLICY_H */ diff --git a/include/pmu_perf/pmu_perf.c b/include/pmu_perf/pmu_perf.c new file mode 100644 index 0000000..a3b94ce --- /dev/null +++ b/include/pmu_perf/pmu_perf.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "pmu_perf.h" + +struct perfrpc_pmucmdhandler_params { + struct nv_pmu_perf_rpc *prpccall; + u32 success; +}; + +static void perfrpc_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg, + void *param, u32 handle, u32 status) +{ + struct perfrpc_pmucmdhandler_params *phandlerparams = + (struct perfrpc_pmucmdhandler_params *)param; + + nvgpu_log_info(g, " "); + + if (msg->msg.perf.msg_type != NV_PMU_PERF_MSG_ID_RPC) { + nvgpu_err(g, "unsupported msg for VFE LOAD RPC %x", + msg->msg.perf.msg_type); + return; + } + + if (phandlerparams->prpccall->b_supported) { + phandlerparams->success = 1; + } +} + +static int pmu_handle_perf_event(struct gk20a *g, void *pmu_msg) +{ + struct nv_pmu_perf_msg *msg = (struct nv_pmu_perf_msg *)pmu_msg; + + nvgpu_log_fn(g, " "); + switch (msg->msg_type) { + case NV_PMU_PERF_MSG_ID_VFE_CALLBACK: + nvgpu_clk_arb_schedule_vf_table_update(g); + break; + default: + WARN_ON(1); + break; + } + return 0; +} + +u32 perf_pmu_vfe_load(struct gk20a *g) +{ + struct pmu_cmd cmd; + struct pmu_payload payload; + u32 status; + u32 seqdesc; + struct nv_pmu_perf_rpc rpccall; + struct perfrpc_pmucmdhandler_params handler; + + memset(&payload, 0, sizeof(struct pmu_payload)); + memset(&rpccall, 0, sizeof(struct nv_pmu_perf_rpc)); + memset(&handler, 0, sizeof(struct perfrpc_pmucmdhandler_params)); + + /*register call back for future VFE updates*/ + g->ops.pmu_perf.handle_pmu_perf_event = pmu_handle_perf_event; + + rpccall.function = NV_PMU_PERF_RPC_ID_VFE_LOAD; + rpccall.params.vfe_load.b_load = true; + cmd.hdr.unit_id = PMU_UNIT_PERF; + cmd.hdr.size = (u32)sizeof(struct nv_pmu_perf_cmd) + + (u32)sizeof(struct pmu_hdr); + + cmd.cmd.perf.cmd_type = NV_PMU_PERF_CMD_ID_RPC; + + payload.in.buf = (u8 *)&rpccall; + payload.in.size = (u32)sizeof(struct nv_pmu_perf_rpc); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = NV_PMU_PERF_CMD_RPC_ALLOC_OFFSET; + + payload.out.buf = (u8 *)&rpccall; + payload.out.size = (u32)sizeof(struct nv_pmu_perf_rpc); + payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.out.offset = NV_PMU_PERF_MSG_RPC_ALLOC_OFFSET; + + handler.prpccall = &rpccall; + handler.success = 0; + + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + perfrpc_pmucmdhandler, (void *)&handler, + &seqdesc, ~0); + + if (status) { + nvgpu_err(g, "unable to post perf RPC cmd %x", + cmd.cmd.perf.cmd_type); + goto done; + } + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handler.success, 1); + + if (handler.success == 0) { + status = -EINVAL; + nvgpu_err(g, "rpc call to load VFE failed"); + } +done: + return status; +} diff --git a/include/pmu_perf/pmu_perf.h b/include/pmu_perf/pmu_perf.h new file mode 100644 index 0000000..71c8086 --- /dev/null +++ b/include/pmu_perf/pmu_perf.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PERF_H +#define NVGPU_PERF_H + +#include +#include "vfe_equ.h" +#include "vfe_var.h" +#include "pstate/pstate.h" +#include "volt/volt.h" +#include "lpwr/lpwr.h" +#include "boardobj/boardobjgrp_e255.h" + +#define CTRL_PERF_VFE_VAR_TYPE_INVALID 0x00 +#define CTRL_PERF_VFE_VAR_TYPE_DERIVED 0x01 +#define CTRL_PERF_VFE_VAR_TYPE_DERIVED_PRODUCT 0x02 +#define CTRL_PERF_VFE_VAR_TYPE_DERIVED_SUM 0x03 +#define CTRL_PERF_VFE_VAR_TYPE_SINGLE 0x04 +#define CTRL_PERF_VFE_VAR_TYPE_SINGLE_FREQUENCY 0x05 +#define CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED 0x06 +#define CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_FUSE 0x07 +#define CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_TEMP 0x08 +#define CTRL_PERF_VFE_VAR_TYPE_SINGLE_VOLTAGE 0x09 + +#define CTRL_PERF_VFE_VAR_SINGLE_OVERRIDE_TYPE_NONE 0x00 +#define CTRL_PERF_VFE_VAR_SINGLE_OVERRIDE_TYPE_VALUE 0x01 +#define CTRL_PERF_VFE_VAR_SINGLE_OVERRIDE_TYPE_OFFSET 0x02 +#define CTRL_PERF_VFE_VAR_SINGLE_OVERRIDE_TYPE_SCALE 0x03 + +#define CTRL_PERF_VFE_EQU_TYPE_INVALID 0x00 +#define CTRL_PERF_VFE_EQU_TYPE_COMPARE 0x01 +#define CTRL_PERF_VFE_EQU_TYPE_MINMAX 0x02 +#define CTRL_PERF_VFE_EQU_TYPE_QUADRATIC 0x03 + +#define CTRL_PERF_VFE_EQU_OUTPUT_TYPE_UNITLESS 0x00 +#define CTRL_PERF_VFE_EQU_OUTPUT_TYPE_FREQ_MHZ 0x01 +#define CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VOLT_UV 0x02 +#define CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VF_GAIN 0x03 +#define CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VOLT_DELTA_UV 0x04 + +#define CTRL_PERF_VFE_EQU_QUADRATIC_COEFF_COUNT 0x03 + +#define CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_EQUAL 0x00 +#define CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_GREATER_EQ 0x01 +#define CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_GREATER 0x02 + +struct gk20a; + +struct nvgpu_vfe_invalidate { + bool state_change; + struct nvgpu_cond wq; + struct nvgpu_thread state_task; +}; + +struct perf_pmupstate { + struct vfe_vars vfe_varobjs; + struct vfe_equs vfe_equobjs; + struct pstates pstatesobjs; + struct obj_volt volt; + struct obj_lwpr lpwr; + struct nvgpu_vfe_invalidate vfe_init; +}; + +u32 perf_pmu_vfe_load(struct gk20a *g); + +#endif /* NVGPU_PERF_H */ diff --git a/include/pmu_perf/vfe_equ.c b/include/pmu_perf/vfe_equ.c new file mode 100644 index 0000000..5b479d7 --- /dev/null +++ b/include/pmu_perf/vfe_equ.c @@ -0,0 +1,607 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "pmu_perf.h" +#include "vfe_equ.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e255.h" +#include "ctrl/ctrlclk.h" +#include "ctrl/ctrlvolt.h" + +static struct vfe_equ *construct_vfe_equ(struct gk20a *g, void *pargs); +static int devinit_get_vfe_equ_table(struct gk20a *g, + struct vfe_equs *pequobjs); + +static int _vfe_equs_pmudatainit(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + int status = 0; + + status = boardobjgrp_pmudatainit_e255(g, pboardobjgrp, pboardobjgrppmu); + if (status) { + nvgpu_err(g, "error updating pmu boardobjgrp for vfe equ 0x%x", + status); + goto done; + } + +done: + return status; +} + +static int _vfe_equs_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_perf_vfe_equ_boardobj_grp_set *pgrp_set = + (struct nv_pmu_perf_vfe_equ_boardobj_grp_set *)pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /* check whether pmuboardobjgrp has a valid boardobj in index */ + if (idx >= CTRL_BOARDOBJGRP_E255_MAX_OBJECTS) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + nvgpu_log_info(g, " Done"); + return 0; +} + +int vfe_equ_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + struct vfe_equs *pvfeequobjs; + + nvgpu_log_info(g, " "); + + status = boardobjgrpconstruct_e255(g, &g->perf_pmu.vfe_equobjs.super); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for clk domain, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->perf_pmu.vfe_equobjs.super.super; + pvfeequobjs = &(g->perf_pmu.vfe_equobjs); + + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, PERF, VFE_EQU); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + perf, PERF, vfe_equ, VFE_EQU); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + pboardobjgrp->pmudatainit = _vfe_equs_pmudatainit; + pboardobjgrp->pmudatainstget = _vfe_equs_pmudata_instget; + + status = devinit_get_vfe_equ_table(g, pvfeequobjs); + if (status) { + goto done; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int vfe_equ_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + pboardobjgrp = &g->perf_pmu.vfe_equobjs.super.super; + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + nvgpu_log_info(g, "Done"); + return status; +} + +static int devinit_get_vfe_equ_table(struct gk20a *g, + struct vfe_equs *pvfeequobjs) +{ + int status = 0; + u8 *vfeequs_tbl_ptr = NULL; + struct vbios_vfe_3x_header_struct vfeequs_tbl_header = { 0 }; + struct vbios_vfe_3x_equ_entry_struct equ = { 0 }; + u8 *vfeequs_tbl_entry_ptr = NULL; + u8 *rd_offset_ptr = NULL; + u32 index = 0; + struct vfe_equ *pequ; + u8 equ_type = 0; + u32 szfmt; + union { + struct boardobj board_obj; + struct vfe_equ super; + struct vfe_equ_compare compare; + struct vfe_equ_minmax minmax; + struct vfe_equ_quadratic quadratic; + } equ_data; + + nvgpu_log_info(g, " "); + + vfeequs_tbl_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, + CONTINUOUS_VIRTUAL_BINNING_TABLE); + + if (vfeequs_tbl_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&vfeequs_tbl_header, vfeequs_tbl_ptr, + VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07); + if (vfeequs_tbl_header.header_size != VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07) { + status = -EINVAL; + goto done; + } + + if (vfeequs_tbl_header.vfe_equ_entry_size == + VBIOS_VFE_3X_EQU_ENTRY_SIZE_17) { + szfmt = VBIOS_VFE_3X_EQU_ENTRY_SIZE_17; + } else if (vfeequs_tbl_header.vfe_equ_entry_size == + VBIOS_VFE_3X_EQU_ENTRY_SIZE_18) { + szfmt = VBIOS_VFE_3X_EQU_ENTRY_SIZE_18; + } else { + status = -EINVAL; + goto done; + } + + vfeequs_tbl_entry_ptr = vfeequs_tbl_ptr + + vfeequs_tbl_header.header_size + + (vfeequs_tbl_header.vfe_var_entry_count * + vfeequs_tbl_header.vfe_var_entry_size); + + for (index = 0; + index < vfeequs_tbl_header.vfe_equ_entry_count; + index++) { + memset(&equ, 0, sizeof(struct vbios_vfe_3x_equ_entry_struct)); + + rd_offset_ptr = vfeequs_tbl_entry_ptr + + (index * vfeequs_tbl_header.vfe_equ_entry_size); + + memcpy(&equ, rd_offset_ptr, szfmt); + + equ_data.super.var_idx = (u8)equ.var_idx; + equ_data.super.equ_idx_next = + (equ.equ_idx_next == VBIOS_VFE_3X_EQU_ENTRY_IDX_INVALID) ? + CTRL_BOARDOBJ_IDX_INVALID : (u8)equ.equ_idx_next; + equ_data.super.out_range_min = equ.out_range_min; + equ_data.super.out_range_max = equ.out_range_max; + + switch (BIOS_GET_FIELD(equ.param3, VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE)) { + case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_UNITLESS: + equ_data.super.output_type = + CTRL_PERF_VFE_EQU_OUTPUT_TYPE_UNITLESS; + break; + + case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_FREQ_MHZ: + equ_data.super.output_type = + CTRL_PERF_VFE_EQU_OUTPUT_TYPE_FREQ_MHZ; + break; + + case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VOLT_UV: + equ_data.super.output_type = + CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VOLT_UV; + break; + + case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VF_GAIN: + equ_data.super.output_type = + CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VF_GAIN; + break; + + case VBIOS_VFE_3X_EQU_ENTRY_PAR3_OUTPUT_TYPE_VOLT_DELTA_UV: + equ_data.super.output_type = + CTRL_PERF_VFE_EQU_OUTPUT_TYPE_VOLT_DELTA_UV; + break; + + default: + nvgpu_err(g, "unrecognized output id @vfeequ index %d", + index); + goto done; + } + + switch ((u8)equ.type) { + case VBIOS_VFE_3X_EQU_ENTRY_TYPE_DISABLED: + case VBIOS_VFE_3X_EQU_ENTRY_TYPE_QUADRATIC_FXP: + case VBIOS_VFE_3X_EQU_ENTRY_TYPE_MINMAX_FXP: + continue; + break; + + case VBIOS_VFE_3X_EQU_ENTRY_TYPE_QUADRATIC: + equ_type = CTRL_PERF_VFE_EQU_TYPE_QUADRATIC; + equ_data.quadratic.coeffs[0] = equ.param0; + equ_data.quadratic.coeffs[1] = equ.param1; + equ_data.quadratic.coeffs[2] = equ.param2; + break; + + case VBIOS_VFE_3X_EQU_ENTRY_TYPE_MINMAX: + equ_type = CTRL_PERF_VFE_EQU_TYPE_MINMAX; + equ_data.minmax.b_max = BIOS_GET_FIELD(equ.param0, + VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_CRIT) && + VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_CRIT_MAX; + equ_data.minmax.equ_idx0 = (u8)BIOS_GET_FIELD( + equ.param0, + VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_VFE_EQU_IDX_0); + equ_data.minmax.equ_idx1 = (u8)BIOS_GET_FIELD( + equ.param0, + VBIOS_VFE_3X_EQU_ENTRY_PAR0_MINMAX_VFE_EQU_IDX_1); + break; + + case VBIOS_VFE_3X_EQU_ENTRY_TYPE_COMPARE: + { + u8 cmp_func = (u8)BIOS_GET_FIELD( + equ.param1, + VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION); + equ_type = CTRL_PERF_VFE_EQU_TYPE_COMPARE; + + switch (cmp_func) { + case VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_EQUAL: + equ_data.compare.func_id = + CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_EQUAL; + break; + + case VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_GREATER_EQ: + equ_data.compare.func_id = + CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_GREATER_EQ; + break; + case VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_FUNCTION_GREATER: + equ_data.compare.func_id = + CTRL_PERF_VFE_EQU_COMPARE_FUNCTION_GREATER; + break; + default: + nvgpu_err(g, + "invalid vfe compare index %x type %x ", + index, cmp_func); + status = -EINVAL; + goto done; + } + equ_data.compare.equ_idx_true = (u8)BIOS_GET_FIELD( + equ.param1, + VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_VFE_EQU_IDX_TRUE); + equ_data.compare.equ_idx_false = (u8)BIOS_GET_FIELD( + equ.param1, + VBIOS_VFE_3X_EQU_ENTRY_PAR1_COMPARE_VFE_EQU_IDX_FALSE); + equ_data.compare.criteria = equ.param0; + break; + } + default: + status = -EINVAL; + nvgpu_err(g, "Invalid equ[%d].type = 0x%x.", + index, (u8)equ.type); + goto done; + } + + equ_data.board_obj.type = equ_type; + pequ = construct_vfe_equ(g, (void *)&equ_data); + + if (pequ == NULL) { + nvgpu_err(g, + "error constructing vfe_equ boardobj %d", index); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert(&pvfeequobjs->super.super, + (struct boardobj *)pequ, index); + if (status) { + nvgpu_err(g, "error adding vfe_equ boardobj %d", index); + status = -EINVAL; + goto done; + } + } +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +static int _vfe_equ_pmudatainit_super(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + u32 status = 0; + struct vfe_equ *pvfe_equ; + struct nv_pmu_vfe_equ *pset; + + nvgpu_log_info(g, " "); + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvfe_equ = (struct vfe_equ *)board_obj_ptr; + + pset = (struct nv_pmu_vfe_equ *) + ppmudata; + + pset->var_idx = pvfe_equ->var_idx; + pset->equ_idx_next = pvfe_equ->equ_idx_next; + pset->output_type = pvfe_equ->output_type; + pset->out_range_min = pvfe_equ->out_range_min; + pset->out_range_max = pvfe_equ->out_range_max; + + return status; +} + +static int vfe_equ_construct_super(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct vfe_equ *pvfeequ; + struct vfe_equ *ptmpequ = (struct vfe_equ *)pargs; + int status = 0; + + status = boardobj_construct_super(g, ppboardobj, + size, pargs); + if (status) { + return -EINVAL; + } + + pvfeequ = (struct vfe_equ *)*ppboardobj; + + pvfeequ->super.pmudatainit = + _vfe_equ_pmudatainit_super; + + pvfeequ->var_idx = ptmpequ->var_idx; + pvfeequ->equ_idx_next = ptmpequ->equ_idx_next; + pvfeequ->output_type = ptmpequ->output_type; + pvfeequ->out_range_min = ptmpequ->out_range_min; + pvfeequ->out_range_max = ptmpequ->out_range_max; + + return status; +} + +static int _vfe_equ_pmudatainit_compare(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vfe_equ_compare *pvfe_equ_compare; + struct nv_pmu_vfe_equ_compare *pset; + + nvgpu_log_info(g, " "); + + status = _vfe_equ_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvfe_equ_compare = (struct vfe_equ_compare *)board_obj_ptr; + + pset = (struct nv_pmu_vfe_equ_compare *) ppmudata; + + pset->func_id = pvfe_equ_compare->func_id; + pset->equ_idx_true = pvfe_equ_compare->equ_idx_true; + pset->equ_idx_false = pvfe_equ_compare->equ_idx_false; + pset->criteria = pvfe_equ_compare->criteria; + + return status; +} + + +static int vfe_equ_construct_compare(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vfe_equ_compare *pvfeequ; + struct vfe_equ_compare *ptmpequ = + (struct vfe_equ_compare *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_EQU_TYPE_COMPARE) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_EQU_TYPE_COMPARE); + status = vfe_equ_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfeequ = (struct vfe_equ_compare *)*ppboardobj; + + pvfeequ->super.super.pmudatainit = + _vfe_equ_pmudatainit_compare; + + pvfeequ->func_id = ptmpequ->func_id; + pvfeequ->equ_idx_true = ptmpequ->equ_idx_true; + pvfeequ->equ_idx_false = ptmpequ->equ_idx_false; + pvfeequ->criteria = ptmpequ->criteria; + + + return status; +} + +static int _vfe_equ_pmudatainit_minmax(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vfe_equ_minmax *pvfe_equ_minmax; + struct nv_pmu_vfe_equ_minmax *pset; + + nvgpu_log_info(g, " "); + + status = _vfe_equ_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvfe_equ_minmax = (struct vfe_equ_minmax *)board_obj_ptr; + + pset = (struct nv_pmu_vfe_equ_minmax *) + ppmudata; + + pset->b_max = pvfe_equ_minmax->b_max; + pset->equ_idx0 = pvfe_equ_minmax->equ_idx0; + pset->equ_idx1 = pvfe_equ_minmax->equ_idx1; + + return status; +} + +static int vfe_equ_construct_minmax(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vfe_equ_minmax *pvfeequ; + struct vfe_equ_minmax *ptmpequ = + (struct vfe_equ_minmax *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_EQU_TYPE_MINMAX) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_EQU_TYPE_MINMAX); + status = vfe_equ_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfeequ = (struct vfe_equ_minmax *)*ppboardobj; + + pvfeequ->super.super.pmudatainit = + _vfe_equ_pmudatainit_minmax; + pvfeequ->b_max = ptmpequ->b_max; + pvfeequ->equ_idx0 = ptmpequ->equ_idx0; + pvfeequ->equ_idx1 = ptmpequ->equ_idx1; + + return status; +} + +static int _vfe_equ_pmudatainit_quadratic(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vfe_equ_quadratic *pvfe_equ_quadratic; + struct nv_pmu_vfe_equ_quadratic *pset; + u32 i; + + nvgpu_log_info(g, " "); + + status = _vfe_equ_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvfe_equ_quadratic = (struct vfe_equ_quadratic *)board_obj_ptr; + + pset = (struct nv_pmu_vfe_equ_quadratic *) ppmudata; + + for (i = 0; i < CTRL_PERF_VFE_EQU_QUADRATIC_COEFF_COUNT; i++) { + pset->coeffs[i] = pvfe_equ_quadratic->coeffs[i]; + } + + return status; +} + +static int vfe_equ_construct_quadratic(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vfe_equ_quadratic *pvfeequ; + struct vfe_equ_quadratic *ptmpequ = + (struct vfe_equ_quadratic *)pargs; + int status = 0; + u32 i; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_EQU_TYPE_QUADRATIC) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_EQU_TYPE_QUADRATIC); + status = vfe_equ_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfeequ = (struct vfe_equ_quadratic *)*ppboardobj; + + pvfeequ->super.super.pmudatainit = + _vfe_equ_pmudatainit_quadratic; + + for (i = 0; i < CTRL_PERF_VFE_EQU_QUADRATIC_COEFF_COUNT; i++) { + pvfeequ->coeffs[i] = ptmpequ->coeffs[i]; + } + + return status; +} + +static struct vfe_equ *construct_vfe_equ(struct gk20a *g, void *pargs) +{ + struct boardobj *board_obj_ptr = NULL; + int status; + + nvgpu_log_info(g, " "); + + switch (BOARDOBJ_GET_TYPE(pargs)) { + case CTRL_PERF_VFE_EQU_TYPE_COMPARE: + status = vfe_equ_construct_compare(g, &board_obj_ptr, + sizeof(struct vfe_equ_compare), pargs); + break; + + case CTRL_PERF_VFE_EQU_TYPE_MINMAX: + status = vfe_equ_construct_minmax(g, &board_obj_ptr, + sizeof(struct vfe_equ_minmax), pargs); + break; + + case CTRL_PERF_VFE_EQU_TYPE_QUADRATIC: + status = vfe_equ_construct_quadratic(g, &board_obj_ptr, + sizeof(struct vfe_equ_quadratic), pargs); + break; + + default: + return NULL; + + } + + if (status) { + return NULL; + } + + nvgpu_log_info(g, " Done"); + + return (struct vfe_equ *)board_obj_ptr; +} diff --git a/include/pmu_perf/vfe_equ.h b/include/pmu_perf/vfe_equ.h new file mode 100644 index 0000000..6131d09 --- /dev/null +++ b/include/pmu_perf/vfe_equ.h @@ -0,0 +1,84 @@ +/* + * general perf structures & definitions + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PERF_VFE_EQU_H +#define NVGPU_PERF_VFE_EQU_H + +#include "boardobj/boardobjgrp.h" +#include "vfe_var.h" +#include + +int vfe_equ_sw_setup(struct gk20a *g); +int vfe_equ_pmu_setup(struct gk20a *g); + +#define VFE_EQU_GET(_pperf, _idx) \ + ((struct vfe_equ *)BOARDOBJGRP_OBJ_GET_BY_IDX( \ + &((_pperf)->vfe.equs.super.super), (_idx))) + +#define VFE_EQU_IDX_IS_VALID(_pperf, _idx) \ + boardobjgrp_idxisvalid(&((_pperf)->vfe.equs.super.super), (_idx)) + +#define VFE_EQU_OUTPUT_TYPE_IS_VALID(_pperf, _idx, _outputtype) \ + (VFE_EQU_IDX_IS_VALID((_pperf), (_idx)) && \ + ((_outputtype) != CTRL_PERF_VFE_EQU_OUTPUT_TYPE_UNITLESS) && \ + ((VFE_EQU_GET((_pperf), (_idx))->outputtype == (_outputtype)) || \ + (VFE_EQU_GET((_pperf), (_idx))->outputtype == \ + CTRL_PERF_VFE_EQU_OUTPUT_TYPE_UNITLESS))) + +struct vfe_equ { + struct boardobj super; + u8 var_idx; + u8 equ_idx_next; + u8 output_type; + u32 out_range_min; + u32 out_range_max; + + bool b_is_dynamic_valid; + bool b_is_dynamic; +}; + +struct vfe_equs { + struct boardobjgrp_e255 super; +}; + +struct vfe_equ_compare { + struct vfe_equ super; + u8 func_id; + u8 equ_idx_true; + u8 equ_idx_false; + u32 criteria; +}; + +struct vfe_equ_minmax { + struct vfe_equ super; + bool b_max; + u8 equ_idx0; + u8 equ_idx1; +}; + +struct vfe_equ_quadratic { + struct vfe_equ super; + u32 coeffs[CTRL_PERF_VFE_EQU_QUADRATIC_COEFF_COUNT]; +}; + +#endif /* NVGPU_PERF_VFE_EQU_H */ diff --git a/include/pmu_perf/vfe_var.c b/include/pmu_perf/vfe_var.c new file mode 100644 index 0000000..a94c2d9 --- /dev/null +++ b/include/pmu_perf/vfe_var.c @@ -0,0 +1,1091 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "pmu_perf.h" +#include "vfe_var.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "ctrl/ctrlclk.h" +#include "ctrl/ctrlvolt.h" +#include "ctrl/ctrlperf.h" + +static int devinit_get_vfe_var_table(struct gk20a *g, + struct vfe_vars *pvarobjs); +static int vfe_var_construct_single(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs); + +static int _vfe_vars_pmudatainit(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + struct nv_pmu_perf_vfe_var_boardobjgrp_set_header *pset = + (struct nv_pmu_perf_vfe_var_boardobjgrp_set_header *) + pboardobjgrppmu; + struct vfe_vars *pvars = (struct vfe_vars *)pboardobjgrp; + int status = 0; + + status = boardobjgrp_pmudatainit_e32(g, pboardobjgrp, pboardobjgrppmu); + if (status) { + nvgpu_err(g, + "error updating pmu boardobjgrp for vfe var 0x%x", + status); + goto done; + } + pset->polling_periodms = pvars->polling_periodms; + +done: + return status; +} + +static int _vfe_vars_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_perf_vfe_var_boardobj_grp_set *pgrp_set = + (struct nv_pmu_perf_vfe_var_boardobj_grp_set *) + pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (idx >= CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + + nvgpu_log_info(g, " Done"); + return 0; +} + +static int _vfe_vars_pmustatus_instget(struct gk20a *g, void *pboardobjgrppmu, + struct nv_pmu_boardobj_query **ppboardobjpmustatus, u8 idx) +{ + struct nv_pmu_perf_vfe_var_boardobj_grp_get_status *pgrp_get_status = + (struct nv_pmu_perf_vfe_var_boardobj_grp_get_status *) + pboardobjgrppmu; + + if (((u32)BIT(idx) & + pgrp_get_status->hdr.data.super.obj_mask.super.data[0]) == 0) { + return -EINVAL; + } + + *ppboardobjpmustatus = (struct nv_pmu_boardobj_query *) + &pgrp_get_status->objects[idx].data.board_obj; + return 0; +} + + +int vfe_var_sw_setup(struct gk20a *g) +{ + u32 status; + struct boardobjgrp *pboardobjgrp = NULL; + struct vfe_vars *pvfevarobjs; + + nvgpu_log_info(g, " "); + + status = boardobjgrpconstruct_e32(g, &g->perf_pmu.vfe_varobjs.super); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for clk domain, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->perf_pmu.vfe_varobjs.super.super; + pvfevarobjs = &g->perf_pmu.vfe_varobjs; + + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, PERF, VFE_VAR); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + perf, PERF, vfe_var, VFE_VAR); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + pboardobjgrp->pmudatainit = _vfe_vars_pmudatainit; + pboardobjgrp->pmudatainstget = _vfe_vars_pmudata_instget; + pboardobjgrp->pmustatusinstget = _vfe_vars_pmustatus_instget; + + status = devinit_get_vfe_var_table(g, pvfevarobjs); + if (status) { + goto done; + } + + status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, + &g->perf_pmu.vfe_varobjs.super.super, + perf, PERF, vfe_var, VFE_VAR); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_GET_STATUS interface - 0x%x", + status); + goto done; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int vfe_var_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + pboardobjgrp = &g->perf_pmu.vfe_varobjs.super.super; + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + nvgpu_log_info(g, "Done"); + return status; +} + +static u32 dev_init_get_vfield_info(struct gk20a *g, + struct vfe_var_single_sensed_fuse *pvfevar) +{ + u8 *vfieldtableptr = NULL; + u32 vfieldheadersize = VFIELD_HEADER_SIZE; + u8 *vfieldregtableptr = NULL; + u32 vfieldregheadersize = VFIELD_REG_HEADER_SIZE; + u32 i; + u32 oldindex = 0xFFFFFFFF; + u32 currindex; + struct vfield_reg_header vregheader; + struct vfield_reg_entry vregentry; + struct vfield_header vheader; + struct vfield_entry ventry; + struct ctrl_bios_vfield_register_segment *psegment = NULL; + u8 *psegmentcount = NULL; + u32 status = 0; + + vfieldregtableptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.virt_token, VP_FIELD_REGISTER); + if (vfieldregtableptr == NULL) { + status = -EINVAL; + goto done; + } + + vfieldtableptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.virt_token, VP_FIELD_TABLE); + if (vfieldtableptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&vregheader, vfieldregtableptr, VFIELD_REG_HEADER_SIZE); + + if (vregheader.version != VBIOS_VFIELD_REG_TABLE_VERSION_1_0) { + nvgpu_err(g, "invalid vreg header version"); + goto done; + } + + memcpy(&vheader, vfieldtableptr, VFIELD_HEADER_SIZE); + + if (vregheader.version != VBIOS_VFIELD_TABLE_VERSION_1_0) { + nvgpu_err(g, "invalid vfield header version"); + goto done; + } + + pvfevar->vfield_info.fuse.segment_count = 0; + pvfevar->vfield_ver_info.fuse.segment_count = 0; + for (i = 0; i < (u32)vheader.count; i++) { + memcpy(&ventry, vfieldtableptr + vfieldheadersize + + (i * vheader.entry_size), + vheader.entry_size); + + currindex = VFIELD_BIT_REG(ventry); + if (currindex != oldindex) { + + memcpy(&vregentry, vfieldregtableptr + + vfieldregheadersize + + (currindex * vregheader.entry_size), + vregheader.entry_size); + oldindex = currindex; + } + + if (pvfevar->vfield_info.v_field_id == ventry.strap_id) { + psegmentcount = + &(pvfevar->vfield_info.fuse.segment_count); + psegment = + &(pvfevar->vfield_info.fuse.segments[*psegmentcount]); + if (*psegmentcount > NV_PMU_VFE_VAR_SINGLE_SENSED_FUSE_SEGMENTS_MAX) { + status = -EINVAL; + goto done; + } + } else if (pvfevar->vfield_ver_info.v_field_id_ver == ventry.strap_id) { + psegmentcount = + &(pvfevar->vfield_ver_info.fuse.segment_count); + psegment = + &(pvfevar->vfield_ver_info.fuse.segments[*psegmentcount]); + if (*psegmentcount > NV_PMU_VFE_VAR_SINGLE_SENSED_FUSE_SEGMENTS_MAX) { + status = -EINVAL; + goto done; + } + } else { + continue; + } + + switch (VFIELD_CODE((&vregentry))) { + case NV_VFIELD_DESC_CODE_REG: + psegment->type = + NV_PMU_BIOS_VFIELD_DESC_CODE_REG; + psegment->data.reg.addr = vregentry.reg; + psegment->data.reg.super.high_bit = (u8)(VFIELD_BIT_STOP(ventry)); + psegment->data.reg.super.low_bit = (u8)(VFIELD_BIT_START(ventry)); + break; + + case NV_VFIELD_DESC_CODE_INDEX_REG: + psegment->type = + NV_PMU_BIOS_VFIELD_DESC_CODE_INDEX_REG; + psegment->data.index_reg.addr = vregentry.reg; + psegment->data.index_reg.index = vregentry.index; + psegment->data.index_reg.reg_index = vregentry.reg_index; + psegment->data.index_reg.super.high_bit = (u8)(VFIELD_BIT_STOP(ventry)); + psegment->data.index_reg.super.low_bit = (u8)(VFIELD_BIT_START(ventry)); + break; + + default: + psegment->type = + NV_PMU_BIOS_VFIELD_DESC_CODE_INVALID; + status = -EINVAL; + goto done; + } + + if (VFIELD_SIZE((&vregentry)) != NV_VFIELD_DESC_SIZE_DWORD) { + psegment->type = + NV_PMU_BIOS_VFIELD_DESC_CODE_INVALID; + return -EINVAL; + } + (*psegmentcount)++; + } + +done: + return status; +} + +static int _vfe_var_pmudatainit_super(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vfe_var *pvfe_var; + struct nv_pmu_vfe_var *pset; + + nvgpu_log_info(g, " "); + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvfe_var = (struct vfe_var *)board_obj_ptr; + pset = (struct nv_pmu_vfe_var *) ppmudata; + + pset->out_range_min = pvfe_var->out_range_min; + pset->out_range_max = pvfe_var->out_range_max; + status = boardobjgrpmask_export(&pvfe_var->mask_dependent_vars.super, + pvfe_var->mask_dependent_vars.super.bitcount, + &pset->mask_dependent_vars.super); + status = boardobjgrpmask_export(&pvfe_var->mask_dependent_equs.super, + pvfe_var->mask_dependent_equs.super.bitcount, + &pset->mask_dependent_equs.super); + return status; +} + +static int vfe_var_construct_super(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct vfe_var *pvfevar; + struct vfe_var *ptmpvar = (struct vfe_var *)pargs; + int status = 0; + + nvgpu_log_info(g, " "); + + status = boardobj_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfevar = (struct vfe_var *)*ppboardobj; + + pvfevar->super.pmudatainit = + _vfe_var_pmudatainit_super; + + pvfevar->out_range_min = ptmpvar->out_range_min; + pvfevar->out_range_max = ptmpvar->out_range_max; + pvfevar->b_is_dynamic_valid = false; + status = boardobjgrpmask_e32_init(&pvfevar->mask_dependent_vars, NULL); + status = boardobjgrpmask_e255_init(&pvfevar->mask_dependent_equs, NULL); + nvgpu_log_info(g, " "); + + return status; +} + +static int _vfe_var_pmudatainit_derived(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + + nvgpu_log_info(g, " "); + + status = _vfe_var_pmudatainit_super(g, board_obj_ptr, ppmudata); + + return status; +} + +static int vfe_var_construct_derived(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + int status = 0; + struct vfe_var_derived *pvfevar; + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_DERIVED); + status = vfe_var_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfevar = (struct vfe_var_derived *)*ppboardobj; + + pvfevar->super.super.pmudatainit = + _vfe_var_pmudatainit_derived; + + return status; +} + +static int _vfe_var_pmudatainit_derived_product(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vfe_var_derived_product *pvfe_var_derived_product; + struct nv_pmu_vfe_var_derived_product *pset; + + nvgpu_log_info(g, " "); + + status = _vfe_var_pmudatainit_derived(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvfe_var_derived_product = + (struct vfe_var_derived_product *)board_obj_ptr; + pset = (struct nv_pmu_vfe_var_derived_product *)ppmudata; + + pset->var_idx0 = pvfe_var_derived_product->var_idx0; + pset->var_idx1 = pvfe_var_derived_product->var_idx1; + + return status; +} + +static int vfe_var_construct_derived_product(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vfe_var_derived_product *pvfevar; + struct vfe_var_derived_product *ptmpvar = + (struct vfe_var_derived_product *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_DERIVED_PRODUCT) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_DERIVED_PRODUCT); + status = vfe_var_construct_derived(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfevar = (struct vfe_var_derived_product *)*ppboardobj; + + pvfevar->super.super.super.pmudatainit = + _vfe_var_pmudatainit_derived_product; + + pvfevar->var_idx0 = ptmpvar->var_idx0; + pvfevar->var_idx1 = ptmpvar->var_idx1; + + + return status; +} + +static int _vfe_var_pmudatainit_derived_sum(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vfe_var_derived_sum *pvfe_var_derived_sum; + struct nv_pmu_vfe_var_derived_sum *pset; + + nvgpu_log_info(g, " "); + + status = _vfe_var_pmudatainit_derived(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvfe_var_derived_sum = (struct vfe_var_derived_sum *)board_obj_ptr; + pset = (struct nv_pmu_vfe_var_derived_sum *)ppmudata; + + pset->var_idx0 = pvfe_var_derived_sum->var_idx0; + pset->var_idx1 = pvfe_var_derived_sum->var_idx1; + + return status; +} + +static int vfe_var_construct_derived_sum(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vfe_var_derived_sum *pvfevar; + struct vfe_var_derived_sum *ptmpvar = + (struct vfe_var_derived_sum *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_DERIVED_SUM) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_DERIVED_SUM); + status = vfe_var_construct_derived(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfevar = (struct vfe_var_derived_sum *)*ppboardobj; + + pvfevar->super.super.super.pmudatainit = + _vfe_var_pmudatainit_derived_sum; + + pvfevar->var_idx0 = ptmpvar->var_idx0; + pvfevar->var_idx1 = ptmpvar->var_idx1; + + return status; +} + +static int _vfe_var_pmudatainit_single(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vfe_var_single *pvfe_var_single; + struct nv_pmu_vfe_var_single *pset; + + nvgpu_log_info(g, " "); + + status = _vfe_var_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvfe_var_single = (struct vfe_var_single *)board_obj_ptr; + pset = (struct nv_pmu_vfe_var_single *) + ppmudata; + + pset->override_type = pvfe_var_single->override_type; + pset->override_value = pvfe_var_single->override_value; + + return status; +} + +static int _vfe_var_pmudatainit_single_frequency(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + + nvgpu_log_info(g, " "); + + status = _vfe_var_pmudatainit_single(g, board_obj_ptr, ppmudata); + + return status; +} + +static u32 vfe_var_construct_single_frequency(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vfe_var_single_frequency *pvfevar; + u32 status = 0; + + nvgpu_log_info(g, " "); + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_SINGLE_FREQUENCY) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE_FREQUENCY); + status = vfe_var_construct_single(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfevar = (struct vfe_var_single_frequency *)*ppboardobj; + + pvfevar->super.super.super.pmudatainit = + _vfe_var_pmudatainit_single_frequency; + + pvfevar->super.super.b_is_dynamic = false; + pvfevar->super.super.b_is_dynamic_valid = true; + + nvgpu_log_info(g, "Done"); + return status; +} + +static int _vfe_var_pmudatainit_single_sensed(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + + nvgpu_log_info(g, " "); + + status = _vfe_var_pmudatainit_single(g, board_obj_ptr, ppmudata); + + return status; +} + +static int _vfe_var_pmudatainit_single_sensed_fuse(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vfe_var_single_sensed_fuse *pvfe_var_single_sensed_fuse; + struct nv_pmu_vfe_var_single_sensed_fuse *pset; + + nvgpu_log_info(g, " "); + + status = _vfe_var_pmudatainit_single_sensed(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvfe_var_single_sensed_fuse = + (struct vfe_var_single_sensed_fuse *)board_obj_ptr; + + pset = (struct nv_pmu_vfe_var_single_sensed_fuse *) + ppmudata; + + memcpy(&pset->vfield_info, &pvfe_var_single_sensed_fuse->vfield_info, + sizeof(struct ctrl_perf_vfe_var_single_sensed_fuse_vfield_info)); + + memcpy(&pset->vfield_ver_info, + &pvfe_var_single_sensed_fuse->vfield_ver_info, + sizeof(struct ctrl_perf_vfe_var_single_sensed_fuse_ver_vfield_info)); + + memcpy(&pset->override_info, + &pvfe_var_single_sensed_fuse->override_info, + sizeof(struct ctrl_perf_vfe_var_single_sensed_fuse_override_info)); + + pset->b_fuse_value_signed = pvfe_var_single_sensed_fuse->b_fuse_value_signed; + return status; +} + +static u32 vfe_var_construct_single_sensed(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vfe_var_single_sensed *pvfevar; + + u32 status = 0; + + nvgpu_log_info(g, " "); + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED); + status = vfe_var_construct_single(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfevar = (struct vfe_var_single_sensed *)*ppboardobj; + + pvfevar->super.super.super.pmudatainit = + _vfe_var_pmudatainit_single_sensed; + + nvgpu_log_info(g, "Done"); + + return status; +} + +static u32 vfe_var_construct_single_sensed_fuse(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vfe_var_single_sensed_fuse *pvfevar; + struct vfe_var_single_sensed_fuse *ptmpvar = + (struct vfe_var_single_sensed_fuse *)pargs; + u32 status = 0; + + nvgpu_log_info(g, " "); + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_FUSE) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_FUSE); + status = vfe_var_construct_single_sensed(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfevar = (struct vfe_var_single_sensed_fuse *)*ppboardobj; + + pvfevar->super.super.super.super.pmudatainit = + _vfe_var_pmudatainit_single_sensed_fuse; + + pvfevar->vfield_info.v_field_id = ptmpvar->vfield_info.v_field_id; + pvfevar->vfield_info.fuse_val_default = + ptmpvar->vfield_info.fuse_val_default; + pvfevar->vfield_info.hw_correction_scale = + ptmpvar->vfield_info.hw_correction_scale; + pvfevar->vfield_info.hw_correction_offset = + ptmpvar->vfield_info.hw_correction_offset; + pvfevar->vfield_ver_info.v_field_id_ver = + ptmpvar->vfield_ver_info.v_field_id_ver; + pvfevar->vfield_ver_info.ver_expected = + ptmpvar->vfield_ver_info.ver_expected; + pvfevar->vfield_ver_info.b_use_default_on_ver_check_fail = + ptmpvar->vfield_ver_info.b_use_default_on_ver_check_fail; + pvfevar->b_version_check_done = false; + pvfevar->b_fuse_value_signed = + ptmpvar->b_fuse_value_signed; + pvfevar->super.super.super.b_is_dynamic = false; + pvfevar->super.super.super.b_is_dynamic_valid = true; + + dev_init_get_vfield_info(g, pvfevar); + /*check whether fuse segment got initialized*/ + if (pvfevar->vfield_info.fuse.segment_count == 0) { + nvgpu_err(g, "unable to get fuse reg info %x", + pvfevar->vfield_info.v_field_id); + status = -EINVAL; + goto exit; + } + if (pvfevar->vfield_ver_info.fuse.segment_count == 0) { + nvgpu_err(g, "unable to get fuse reg info %x", + pvfevar->vfield_ver_info.v_field_id_ver); + status = -EINVAL; + goto exit; + } +exit: + if (status) { + (*ppboardobj)->destruct(*ppboardobj); + } + + return status; +} + +static int _vfe_var_pmudatainit_single_sensed_temp(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct vfe_var_single_sensed_temp *pvfe_var_single_sensed_temp; + struct nv_pmu_vfe_var_single_sensed_temp *pset; + + nvgpu_log_info(g, " "); + + status = _vfe_var_pmudatainit_single_sensed(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pvfe_var_single_sensed_temp = + (struct vfe_var_single_sensed_temp *)board_obj_ptr; + + pset = (struct nv_pmu_vfe_var_single_sensed_temp *) + ppmudata; + pset->therm_channel_index = + pvfe_var_single_sensed_temp->therm_channel_index; + pset->temp_hysteresis_positive = + pvfe_var_single_sensed_temp->temp_hysteresis_positive; + pset->temp_hysteresis_negative = + pvfe_var_single_sensed_temp->temp_hysteresis_negative; + pset->temp_default = + pvfe_var_single_sensed_temp->temp_default; + return status; +} + +static u32 vfe_var_construct_single_sensed_temp(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vfe_var_single_sensed_temp *pvfevar; + struct vfe_var_single_sensed_temp *ptmpvar = + (struct vfe_var_single_sensed_temp *)pargs; + u32 status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_TEMP) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_TEMP); + status = vfe_var_construct_single_sensed(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfevar = (struct vfe_var_single_sensed_temp *)*ppboardobj; + + pvfevar->super.super.super.super.pmudatainit = + _vfe_var_pmudatainit_single_sensed_temp; + + pvfevar->therm_channel_index = + ptmpvar->therm_channel_index; + pvfevar->temp_hysteresis_positive = + ptmpvar->temp_hysteresis_positive; + pvfevar->temp_hysteresis_negative = + ptmpvar->temp_hysteresis_negative; + pvfevar->temp_default = + ptmpvar->temp_default; + pvfevar->super.super.super.b_is_dynamic = false; + pvfevar->super.super.super.b_is_dynamic_valid = true; + + return status; +} + +static int _vfe_var_pmudatainit_single_voltage(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + + nvgpu_log_info(g, " "); + + status = _vfe_var_pmudatainit_single(g, board_obj_ptr, ppmudata); + + return status; +} + +static int vfe_var_construct_single_voltage(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vfe_var_single_voltage *pvfevar; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_PERF_VFE_VAR_TYPE_SINGLE_VOLTAGE) { + return -EINVAL; + } + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE_VOLTAGE); + status = vfe_var_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfevar = (struct vfe_var_single_voltage *)*ppboardobj; + + pvfevar->super.super.super.pmudatainit = + _vfe_var_pmudatainit_single_voltage; + + pvfevar->super.super.b_is_dynamic = false; + pvfevar->super.super.b_is_dynamic_valid = true; + + return status; +} + +static struct vfe_var *construct_vfe_var(struct gk20a *g, void *pargs) +{ + struct boardobj *board_obj_ptr = NULL; + int status; + + nvgpu_log_info(g, " "); + switch (BOARDOBJ_GET_TYPE(pargs)) { + case CTRL_PERF_VFE_VAR_TYPE_DERIVED_PRODUCT: + status = vfe_var_construct_derived_product(g, &board_obj_ptr, + sizeof(struct vfe_var_derived_product), pargs); + break; + + case CTRL_PERF_VFE_VAR_TYPE_DERIVED_SUM: + status = vfe_var_construct_derived_sum(g, &board_obj_ptr, + sizeof(struct vfe_var_derived_sum), pargs); + break; + + case CTRL_PERF_VFE_VAR_TYPE_SINGLE_FREQUENCY: + status = vfe_var_construct_single_frequency(g, &board_obj_ptr, + sizeof(struct vfe_var_single_frequency), pargs); + break; + + case CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_FUSE: + status = vfe_var_construct_single_sensed_fuse(g, &board_obj_ptr, + sizeof(struct vfe_var_single_sensed_fuse), pargs); + break; + + case CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_TEMP: + status = vfe_var_construct_single_sensed_temp(g, &board_obj_ptr, + sizeof(struct vfe_var_single_sensed_temp), pargs); + break; + + case CTRL_PERF_VFE_VAR_TYPE_SINGLE_VOLTAGE: + status = vfe_var_construct_single_voltage(g, &board_obj_ptr, + sizeof(struct vfe_var_single_voltage), pargs); + break; + + case CTRL_PERF_VFE_VAR_TYPE_DERIVED: + case CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED: + case CTRL_PERF_VFE_VAR_TYPE_SINGLE: + default: + return NULL; + } + + if (status) { + return NULL; + } + + nvgpu_log_info(g, "done"); + + return (struct vfe_var *)board_obj_ptr; +} + +static int devinit_get_vfe_var_table(struct gk20a *g, + struct vfe_vars *pvfevarobjs) +{ + int status = 0; + u8 *vfevars_tbl_ptr = NULL; + struct vbios_vfe_3x_header_struct vfevars_tbl_header = { 0 }; + struct vbios_vfe_3x_var_entry_struct var = { 0 }; + u8 *vfevars_tbl_entry_ptr = NULL; + u8 *rd_offset_ptr = NULL; + u32 index = 0; + struct vfe_var *pvar; + u8 var_type; + u32 szfmt; + union { + struct boardobj board_obj; + struct vfe_var super; + struct vfe_var_derived_product derived_product; + struct vfe_var_derived_sum derived_sum; + struct vfe_var_single_sensed_fuse single_sensed_fuse; + struct vfe_var_single_sensed_temp single_sensed_temp; + } var_data; + + nvgpu_log_info(g, " "); + + vfevars_tbl_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, + CONTINUOUS_VIRTUAL_BINNING_TABLE); + if (vfevars_tbl_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&vfevars_tbl_header, vfevars_tbl_ptr, + VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07); + if (vfevars_tbl_header.header_size != + VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07){ + status = -EINVAL; + goto done; + } + + if (vfevars_tbl_header.vfe_var_entry_size == + VBIOS_VFE_3X_VAR_ENTRY_SIZE_19) { + szfmt = VBIOS_VFE_3X_VAR_ENTRY_SIZE_19; + } else if (vfevars_tbl_header.vfe_var_entry_size == + VBIOS_VFE_3X_VAR_ENTRY_SIZE_11) { + szfmt = VBIOS_VFE_3X_VAR_ENTRY_SIZE_11; + } else { + status = -EINVAL; + goto done; + } + + /* Read table entries*/ + vfevars_tbl_entry_ptr = vfevars_tbl_ptr + + vfevars_tbl_header.header_size; + for (index = 0; + index < vfevars_tbl_header.vfe_var_entry_count; + index++) { + rd_offset_ptr = vfevars_tbl_entry_ptr + + (index * vfevars_tbl_header.vfe_var_entry_size); + memcpy(&var, rd_offset_ptr, szfmt); + + var_data.super.out_range_min = var.out_range_min; + var_data.super.out_range_max = var.out_range_max; + + switch ((u8)var.type) { + case VBIOS_VFE_3X_VAR_ENTRY_TYPE_DISABLED: + continue; + break; + + case VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_FREQUENCY: + var_type = CTRL_PERF_VFE_VAR_TYPE_SINGLE_FREQUENCY; + break; + + case VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_VOLTAGE: + var_type = CTRL_PERF_VFE_VAR_TYPE_SINGLE_VOLTAGE; + break; + + case VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_SENSED_TEMP: + var_type = CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_TEMP; + var_data.single_sensed_temp.temp_default = 0x9600; + var_data.single_sensed_temp.therm_channel_index = + (u8)BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_TH_CH_IDX); + var_data.single_sensed_temp.temp_hysteresis_positive = + (u8)BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_HYS_POS) << 5; + var_data.single_sensed_temp.temp_hysteresis_negative = + (u8)BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSTEMP_HYS_NEG) << 5; + break; + + case VBIOS_VFE_3X_VAR_ENTRY_TYPE_SINGLE_SENSED_FUSE: + var_type = CTRL_PERF_VFE_VAR_TYPE_SINGLE_SENSED_FUSE; + var_data.single_sensed_fuse.vfield_info.v_field_id = + (u8)BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VFIELD_ID); + var_data.single_sensed_fuse.vfield_ver_info.v_field_id_ver = + (u8)BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VFIELD_ID_VER); + var_data.single_sensed_fuse.vfield_ver_info.ver_expected = + (u8)BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_EXPECTED_VER); + var_data.single_sensed_fuse.vfield_ver_info.b_use_default_on_ver_check_fail = + (BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_USE_DEFAULT_ON_VER_CHECK_FAIL) && + VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_USE_DEFAULT_ON_VER_CHECK_FAIL_YES); + var_data.single_sensed_fuse.b_fuse_value_signed = + (u8)BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_SSFUSE_VALUE_SIGNED_INTEGER); + var_data.single_sensed_fuse.vfield_info.fuse_val_default = + var.param1; + if (szfmt >= VBIOS_VFE_3X_VAR_ENTRY_SIZE_19) { + var_data.single_sensed_fuse.vfield_info.hw_correction_scale = + (int)var.param2; + var_data.single_sensed_fuse.vfield_info.hw_correction_offset = + var.param3; + } else { + var_data.single_sensed_fuse.vfield_info.hw_correction_scale = + 1 << 12; + var_data.single_sensed_fuse.vfield_info.hw_correction_offset = + 0; + if ((var_data.single_sensed_fuse.vfield_info.v_field_id == + VFIELD_ID_STRAP_IDDQ) || + (var_data.single_sensed_fuse.vfield_info.v_field_id == + VFIELD_ID_STRAP_IDDQ_1)) { + var_data.single_sensed_fuse.vfield_info.hw_correction_scale = + 50 << 12; + } + } + break; + + case VBIOS_VFE_3X_VAR_ENTRY_TYPE_DERIVED_PRODUCT: + var_type = CTRL_PERF_VFE_VAR_TYPE_DERIVED_PRODUCT; + var_data.derived_product.var_idx0 = + (u8)BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_DPROD_VFE_VAR_IDX_0); + var_data.derived_product.var_idx1 = + (u8)BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_DPROD_VFE_VAR_IDX_1); + break; + + case VBIOS_VFE_3X_VAR_ENTRY_TYPE_DERIVED_SUM: + var_type = CTRL_PERF_VFE_VAR_TYPE_DERIVED_SUM; + var_data.derived_sum.var_idx0 = + (u8)BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_DSUM_VFE_VAR_IDX_0); + var_data.derived_sum.var_idx1 = + (u8)BIOS_GET_FIELD(var.param0, + VBIOS_VFE_3X_VAR_ENTRY_PAR0_DSUM_VFE_VAR_IDX_1); + break; + default: + status = -EINVAL; + goto done; + } + var_data.board_obj.type = var_type; + var_data.board_obj.type_mask = 0; + + pvar = construct_vfe_var(g, &var_data); + if (pvar == NULL) { + nvgpu_err(g, + "error constructing vfe_var boardobj %d", + index); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert(&pvfevarobjs->super.super, + (struct boardobj *)pvar, index); + if (status) { + nvgpu_err(g, "error adding vfe_var boardobj %d", index); + status = -EINVAL; + goto done; + } + } + pvfevarobjs->polling_periodms = vfevars_tbl_header.polling_periodms; +done: + nvgpu_log_info(g, "done status %x", status); + return status; +} + +static int vfe_var_construct_single(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct vfe_var_single *pvfevar; + int status = 0; + + nvgpu_log_info(g, " "); + + ptmpobj->type_mask |= BIT(CTRL_PERF_VFE_VAR_TYPE_SINGLE); + status = vfe_var_construct_super(g, ppboardobj, size, pargs); + if (status) { + return -EINVAL; + } + + pvfevar = (struct vfe_var_single *)*ppboardobj; + + pvfevar->super.super.pmudatainit = + _vfe_var_pmudatainit_single; + + pvfevar->override_type = CTRL_PERF_VFE_VAR_SINGLE_OVERRIDE_TYPE_NONE; + pvfevar->override_value = 0; + + nvgpu_log_info(g, "Done"); + return status; +} diff --git a/include/pmu_perf/vfe_var.h b/include/pmu_perf/vfe_var.h new file mode 100644 index 0000000..98b7c40 --- /dev/null +++ b/include/pmu_perf/vfe_var.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_PERF_VFE_VAR_H +#define NVGPU_PERF_VFE_VAR_H + +#include "boardobj/boardobjgrp.h" +#include + +int vfe_var_sw_setup(struct gk20a *g); +int vfe_var_pmu_setup(struct gk20a *g); + +#define VFE_VAR_GET(_pperf, _idx) \ + ((struct vfe_var)BOARDOBJGRP_OBJ_GET_BY_IDX( \ + &((_pperf)->vfe.vars.super.super), (_idx))) + +#define VFE_VAR_IDX_IS_VALID(_pperf, _idx) \ + boardobjgrp_idxisvalid(&((_pperf)->vfe.vars.super.super), (_idx)) + +struct vfe_var { + struct boardobj super; + u32 out_range_min; + u32 out_range_max; + struct boardobjgrpmask_e32 mask_dependent_vars; + struct boardobjgrpmask_e255 mask_dependent_equs; + bool b_is_dynamic_valid; + bool b_is_dynamic; +}; + +struct vfe_vars { + struct boardobjgrp_e32 super; + u8 polling_periodms; +}; + +struct vfe_var_derived { + struct vfe_var super; +}; + +struct vfe_var_derived_product { + struct vfe_var_derived super; + u8 var_idx0; + u8 var_idx1; +}; + +struct vfe_var_derived_sum { + struct vfe_var_derived super; + u8 var_idx0; + u8 var_idx1; +}; + +struct vfe_var_single { + struct vfe_var super; + u8 override_type; + u32 override_value; +}; + +struct vfe_var_single_frequency { + struct vfe_var_single super; +}; + +struct vfe_var_single_voltage { + struct vfe_var_single super; +}; + +struct vfe_var_single_sensed { + struct vfe_var_single super; +}; + +struct vfe_var_single_sensed_fuse { + struct vfe_var_single_sensed super; + struct ctrl_perf_vfe_var_single_sensed_fuse_override_info override_info; + struct ctrl_perf_vfe_var_single_sensed_fuse_vfield_info vfield_info; + struct ctrl_perf_vfe_var_single_sensed_fuse_ver_vfield_info vfield_ver_info; + struct ctrl_perf_vfe_var_single_sensed_fuse_value fuse_val_default; + bool b_fuse_value_signed; + u32 fuse_value_integer; + u32 fuse_value_hw_integer; + u8 fuse_version; + bool b_version_check_done; +}; + +struct vfe_var_single_sensed_temp { + struct vfe_var_single_sensed super; + u8 therm_channel_index; + int temp_hysteresis_positive; + int temp_hysteresis_negative; + int temp_default; +}; + +#endif /* NVGPU_PERF_VFE_VAR_H */ diff --git a/include/pstate/pstate.c b/include/pstate/pstate.c new file mode 100644 index 0000000..c1f696a --- /dev/null +++ b/include/pstate/pstate.c @@ -0,0 +1,488 @@ +/* + * general p state infrastructure + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "clk/clk.h" +#include "pmu_perf/pmu_perf.h" +#include "pmgr/pmgr.h" +#include "pstate/pstate.h" +#include "therm/thrm.h" + +static int pstate_sw_setup(struct gk20a *g); + +void gk20a_deinit_pstate_support(struct gk20a *g) +{ + if (g->ops.clk.mclk_deinit) { + g->ops.clk.mclk_deinit(g); + } + + nvgpu_mutex_destroy(&g->perf_pmu.pstatesobjs.pstate_mutex); +} + +/*sw setup for pstate components*/ +int gk20a_init_pstate_support(struct gk20a *g) +{ + int err; + + nvgpu_log_fn(g, " "); + + err = volt_rail_sw_setup(g); + if (err) { + return err; + } + + err = volt_dev_sw_setup(g); + if (err) { + return err; + } + + err = volt_policy_sw_setup(g); + if (err) { + return err; + } + + err = clk_vin_sw_setup(g); + if (err) { + return err; + } + + err = clk_fll_sw_setup(g); + if (err) { + return err; + } + + err = therm_domain_sw_setup(g); + if (err) { + return err; + } + + err = vfe_var_sw_setup(g); + if (err) { + return err; + } + + err = vfe_equ_sw_setup(g); + if (err) { + return err; + } + + err = clk_domain_sw_setup(g); + if (err) { + return err; + } + + err = clk_vf_point_sw_setup(g); + if (err) { + return err; + } + + err = clk_prog_sw_setup(g); + if (err) { + return err; + } + + err = pstate_sw_setup(g); + if (err) { + return err; + } + + if(g->ops.clk.support_pmgr_domain) { + err = pmgr_domain_sw_setup(g); + if (err) { + return err; + } + } + + if (g->ops.clk.support_clk_freq_controller) { + err = clk_freq_controller_sw_setup(g); + if (err) { + return err; + } + } + + if(g->ops.clk.support_lpwr_pg) { + err = nvgpu_lpwr_pg_setup(g); + if (err) { + return err; + } + } + + return err; +} + +/*sw setup for pstate components*/ +int gk20a_init_pstate_pmu_support(struct gk20a *g) +{ + u32 err; + + nvgpu_log_fn(g, " "); + + if (g->ops.clk.mclk_init) { + err = g->ops.clk.mclk_init(g); + if (err) { + nvgpu_err(g, "failed to set mclk"); + /* Indicate error and continue */ + } + } + + err = volt_rail_pmu_setup(g); + if (err) { + return err; + } + + err = volt_dev_pmu_setup(g); + if (err) { + return err; + } + + err = volt_policy_pmu_setup(g); + if (err) { + return err; + } + + err = g->ops.pmu_ver.volt.volt_send_load_cmd_to_pmu(g); + if (err) { + nvgpu_err(g, + "Failed to send VOLT LOAD CMD to PMU: status = 0x%08x.", + err); + return err; + } + + err = therm_domain_pmu_setup(g); + if (err) { + return err; + } + + err = vfe_var_pmu_setup(g); + if (err) { + return err; + } + + err = vfe_equ_pmu_setup(g); + if (err) { + return err; + } + + err = clk_domain_pmu_setup(g); + if (err) { + return err; + } + + err = clk_prog_pmu_setup(g); + if (err) { + return err; + } + + err = clk_vin_pmu_setup(g); + if (err) { + return err; + } + + err = clk_fll_pmu_setup(g); + if (err) { + return err; + } + + err = clk_vf_point_pmu_setup(g); + if (err) { + return err; + } + + if (g->ops.clk.support_clk_freq_controller) { + err = clk_freq_controller_pmu_setup(g); + if (err) { + return err; + } + } + err = clk_pmu_vin_load(g); + if (err) { + return err; + } + + err = g->ops.clk.perf_pmu_vfe_load(g); + if (err) { + return err; + } + + if (g->ops.clk.support_pmgr_domain) { + err = pmgr_domain_pmu_setup(g); + } + + return err; +} + +static int pstate_construct_super(struct gk20a *g, struct boardobj **ppboardobj, + u16 size, void *args) +{ + struct pstate *ptmppstate = (struct pstate *)args; + struct pstate *pstate; + int err; + + err = boardobj_construct_super(g, ppboardobj, size, args); + if (err) { + return err; + } + + pstate = (struct pstate *)*ppboardobj; + + pstate->num = ptmppstate->num; + pstate->clklist = ptmppstate->clklist; + pstate->lpwr_entry_idx = ptmppstate->lpwr_entry_idx; + + return 0; +} + +static int pstate_construct_3x(struct gk20a *g, struct boardobj **ppboardobj, + u16 size, void *args) +{ + struct boardobj *ptmpobj = (struct boardobj *)args; + + ptmpobj->type_mask |= BIT(CTRL_PERF_PSTATE_TYPE_3X); + return pstate_construct_super(g, ppboardobj, size, args); +} + +static struct pstate *pstate_construct(struct gk20a *g, void *args) +{ + struct pstate *pstate = NULL; + struct pstate *tmp = (struct pstate *)args; + + if ((tmp->super.type != CTRL_PERF_PSTATE_TYPE_3X) || + (pstate_construct_3x(g, (struct boardobj **)&pstate, + sizeof(struct pstate), args))) { + nvgpu_err(g, + "error constructing pstate num=%u", tmp->num); + } + + return pstate; +} + +static int pstate_insert(struct gk20a *g, struct pstate *pstate, int index) +{ + struct pstates *pstates = &(g->perf_pmu.pstatesobjs); + int err; + + err = boardobjgrp_objinsert(&pstates->super.super, + (struct boardobj *)pstate, index); + if (err) { + nvgpu_err(g, + "error adding pstate boardobj %d", index); + return err; + } + + pstates->num_levels++; + + return err; +} + +static int parse_pstate_entry_5x(struct gk20a *g, + struct vbios_pstate_header_5x *hdr, + struct vbios_pstate_entry_5x *entry, + struct pstate *pstate) +{ + u8 *p = (u8 *)entry; + u32 clkidx; + + p += hdr->base_entry_size; + + memset(pstate, 0, sizeof(struct pstate)); + pstate->super.type = CTRL_PERF_PSTATE_TYPE_3X; + pstate->num = 0x0F - entry->pstate_level; + pstate->clklist.num_info = hdr->clock_entry_count; + pstate->lpwr_entry_idx = entry->lpwr_entry_idx; + + nvgpu_log_info(g, "pstate P%u", pstate->num); + + for (clkidx = 0; clkidx < hdr->clock_entry_count; clkidx++) { + struct clk_set_info *pclksetinfo; + struct vbios_pstate_entry_clock_5x *clk_entry; + struct clk_domain *clk_domain; + + clk_domain = (struct clk_domain *)BOARDOBJGRP_OBJ_GET_BY_IDX( + &g->clk_pmu.clk_domainobjs.super.super, clkidx); + + pclksetinfo = &pstate->clklist.clksetinfo[clkidx]; + clk_entry = (struct vbios_pstate_entry_clock_5x *)p; + + pclksetinfo->clkwhich = clk_domain->domain; + pclksetinfo->nominal_mhz = + BIOS_GET_FIELD(clk_entry->param0, + VBIOS_PSTATE_5X_CLOCK_PROG_PARAM0_NOM_FREQ_MHZ); + pclksetinfo->min_mhz = + BIOS_GET_FIELD(clk_entry->param1, + VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MIN_FREQ_MHZ); + pclksetinfo->max_mhz = + BIOS_GET_FIELD(clk_entry->param1, + VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MAX_FREQ_MHZ); + + nvgpu_log_info(g, + "clk_domain=%u nominal_mhz=%u min_mhz=%u max_mhz=%u", + pclksetinfo->clkwhich, pclksetinfo->nominal_mhz, + pclksetinfo->min_mhz, pclksetinfo->max_mhz); + + p += hdr->clock_entry_size; + } + + return 0; +} + +static int parse_pstate_table_5x(struct gk20a *g, + struct vbios_pstate_header_5x *hdr) +{ + struct pstate _pstate, *pstate; + struct vbios_pstate_entry_5x *entry; + u32 entry_size; + u8 i; + u8 *p = (u8 *)hdr; + int err = 0; + + if ((hdr->header_size != VBIOS_PSTATE_HEADER_5X_SIZE_10) || + (hdr->base_entry_count == 0) || + ((hdr->base_entry_size != VBIOS_PSTATE_BASE_ENTRY_5X_SIZE_2) && + (hdr->base_entry_size != VBIOS_PSTATE_BASE_ENTRY_5X_SIZE_3)) || + (hdr->clock_entry_size != VBIOS_PSTATE_CLOCK_ENTRY_5X_SIZE_6) || + (hdr->clock_entry_count > CLK_SET_INFO_MAX_SIZE)) { + return -EINVAL; + } + + p += hdr->header_size; + + entry_size = hdr->base_entry_size + + hdr->clock_entry_count * hdr->clock_entry_size; + + for (i = 0; i < hdr->base_entry_count; i++, p += entry_size) { + entry = (struct vbios_pstate_entry_5x *)p; + + if (entry->pstate_level == VBIOS_PERFLEVEL_SKIP_ENTRY) { + continue; + } + + err = parse_pstate_entry_5x(g, hdr, entry, &_pstate); + if (err) { + goto done; + } + + pstate = pstate_construct(g, &_pstate); + if (!pstate) { + goto done; + } + + err = pstate_insert(g, pstate, i); + if (err) { + goto done; + } + } + +done: + return err; +} + +static int pstate_sw_setup(struct gk20a *g) +{ + struct vbios_pstate_header_5x *hdr = NULL; + int err = 0; + + nvgpu_log_fn(g, " "); + + nvgpu_cond_init(&g->perf_pmu.pstatesobjs.pstate_notifier_wq); + + err = nvgpu_mutex_init(&g->perf_pmu.pstatesobjs.pstate_mutex); + if (err) { + return err; + } + + err = boardobjgrpconstruct_e32(g, &g->perf_pmu.pstatesobjs.super); + if (err) { + nvgpu_err(g, + "error creating boardobjgrp for pstates, err=%d", + err); + goto done; + } + + hdr = (struct vbios_pstate_header_5x *) + nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, PERFORMANCE_TABLE); + + if (!hdr) { + nvgpu_err(g, "performance table not found"); + err = -EINVAL; + goto done; + } + + if (hdr->version != VBIOS_PSTATE_TABLE_VERSION_5X) { + nvgpu_err(g, "unknown/unsupported clocks table version=0x%02x", + hdr->version); + err = -EINVAL; + goto done; + } + + err = parse_pstate_table_5x(g, hdr); +done: + if (err) { + nvgpu_mutex_destroy(&g->perf_pmu.pstatesobjs.pstate_mutex); + } + return err; +} + +struct pstate *pstate_find(struct gk20a *g, u32 num) +{ + struct pstates *pstates = &(g->perf_pmu.pstatesobjs); + struct pstate *pstate; + u8 i; + + nvgpu_log_info(g, "pstates = %p", pstates); + + BOARDOBJGRP_FOR_EACH(&pstates->super.super, + struct pstate *, pstate, i) { + nvgpu_log_info(g, "pstate=%p num=%u (looking for num=%u)", + pstate, pstate->num, num); + if (pstate->num == num) { + return pstate; + } + } + return NULL; +} + +struct clk_set_info *pstate_get_clk_set_info(struct gk20a *g, + u32 pstate_num, enum nv_pmu_clk_clkwhich clkwhich) +{ + struct pstate *pstate = pstate_find(g, pstate_num); + struct clk_set_info *info; + u32 clkidx; + + nvgpu_log_info(g, "pstate = %p", pstate); + + if (!pstate) { + return NULL; + } + + for (clkidx = 0; clkidx < pstate->clklist.num_info; clkidx++) { + info = &pstate->clklist.clksetinfo[clkidx]; + if (info->clkwhich == clkwhich) { + return info; + } + } + return NULL; +} diff --git a/include/pstate/pstate.h b/include/pstate/pstate.h new file mode 100644 index 0000000..42b27ea --- /dev/null +++ b/include/pstate/pstate.h @@ -0,0 +1,74 @@ +/* + * general p state infrastructure + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_PSTATE_H +#define NVGPU_PSTATE_H + +#include "clk/clk.h" + +#define CTRL_PERF_PSTATE_TYPE_3X 0x3 + +#define CTRL_PERF_PSTATE_P0 0 +#define CTRL_PERF_PSTATE_P5 5 +#define CTRL_PERF_PSTATE_P8 8 + +#define CLK_SET_INFO_MAX_SIZE (32) + +struct gk20a; + +struct clk_set_info { + enum nv_pmu_clk_clkwhich clkwhich; + u32 nominal_mhz; + u16 min_mhz; + u16 max_mhz; +}; + +struct clk_set_info_list { + u32 num_info; + struct clk_set_info clksetinfo[CLK_SET_INFO_MAX_SIZE]; +}; + +struct pstate { + struct boardobj super; + u32 num; + u8 lpwr_entry_idx; + struct clk_set_info_list clklist; +}; + +struct pstates { + struct boardobjgrp_e32 super; + u32 num_levels; + struct nvgpu_cond pstate_notifier_wq; + u32 is_pstate_switch_on; + struct nvgpu_mutex pstate_mutex; /* protect is_pstate_switch_on */ +}; + +int gk20a_init_pstate_support(struct gk20a *g); +void gk20a_deinit_pstate_support(struct gk20a *g); +int gk20a_init_pstate_pmu_support(struct gk20a *g); + +struct clk_set_info *pstate_get_clk_set_info(struct gk20a *g, u32 pstate_num, + enum nv_pmu_clk_clkwhich clkwhich); +struct pstate *pstate_find(struct gk20a *g, u32 num); + +#endif /* NVGPU_PSTATE_H */ diff --git a/include/therm/thrm.c b/include/therm/thrm.c new file mode 100644 index 0000000..c4e2731 --- /dev/null +++ b/include/therm/thrm.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, 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 + +#include "thrm.h" +#include "thrmpmu.h" + +u32 therm_domain_sw_setup(struct gk20a *g) +{ + u32 status; + + status = therm_device_sw_setup(g); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for therm devices, status - 0x%x", + status); + goto exit; + } + + status = therm_channel_sw_setup(g); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for therm channel, status - 0x%x", + status); + goto exit; + } + +exit: + return status; +} + +u32 therm_domain_pmu_setup(struct gk20a *g) +{ + return therm_send_pmgr_tables_to_pmu(g); +} diff --git a/include/therm/thrm.h b/include/therm/thrm.h new file mode 100644 index 0000000..d9d73b7 --- /dev/null +++ b/include/therm/thrm.h @@ -0,0 +1,38 @@ +/* + * general thermal table structures & definitions + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_THERM_THRM_H +#define NVGPU_THERM_THRM_H + +#include "thrmdev.h" +#include "thrmchannel.h" + +struct therm_pmupstate { + struct therm_devices therm_deviceobjs; + struct therm_channels therm_channelobjs; +}; + +u32 therm_domain_sw_setup(struct gk20a *g); +u32 therm_domain_pmu_setup(struct gk20a *g); + +#endif /* NVGPU_THERM_THRM_H */ diff --git a/include/therm/thrmchannel.c b/include/therm/thrmchannel.c new file mode 100644 index 0000000..419ce0b --- /dev/null +++ b/include/therm/thrmchannel.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "thrmchannel.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "gp106/bios_gp106.h" + +static int _therm_channel_pmudatainit_device(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct therm_channel *pchannel; + struct therm_channel_device *ptherm_channel; + struct nv_pmu_therm_therm_channel_device_boardobj_set *pset; + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status) { + nvgpu_err(g, + "error updating pmu boardobjgrp for therm channel 0x%x", + status); + status = -ENOMEM; + goto done; + } + + pchannel = (struct therm_channel *)board_obj_ptr; + pset = (struct nv_pmu_therm_therm_channel_device_boardobj_set *)ppmudata; + ptherm_channel = (struct therm_channel_device *)board_obj_ptr; + + pset->super.scaling = pchannel->scaling; + pset->super.offset = pchannel->offset; + pset->super.temp_min = pchannel->temp_min; + pset->super.temp_max = pchannel->temp_max; + + pset->therm_dev_idx = ptherm_channel->therm_dev_idx; + pset->therm_dev_prov_idx = ptherm_channel->therm_dev_prov_idx; + +done: + return status; +} +static struct boardobj *construct_channel_device(struct gk20a *g, + void *pargs, u16 pargs_size, u8 type) +{ + struct boardobj *board_obj_ptr = NULL; + struct therm_channel *pchannel; + struct therm_channel_device *pchannel_device; + int status; + struct therm_channel_device *therm_device = (struct therm_channel_device*)pargs; + + status = boardobj_construct_super(g, &board_obj_ptr, + pargs_size, pargs); + if (status) { + return NULL; + } + + /* Set Super class interfaces */ + board_obj_ptr->pmudatainit = _therm_channel_pmudatainit_device; + + pchannel = (struct therm_channel *)board_obj_ptr; + pchannel_device = (struct therm_channel_device *)board_obj_ptr; + + g->ops.therm.get_internal_sensor_limits(&pchannel->temp_max, + &pchannel->temp_min); + pchannel->scaling = (1 << 8); + pchannel->offset = 0; + + pchannel_device->therm_dev_idx = therm_device->therm_dev_idx; + pchannel_device->therm_dev_prov_idx = therm_device->therm_dev_prov_idx; + + nvgpu_log_info(g, " Done"); + + return board_obj_ptr; +} + +static int _therm_channel_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_therm_therm_channel_boardobj_grp_set *pgrp_set = + (struct nv_pmu_therm_therm_channel_boardobj_grp_set *) + pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + + nvgpu_log_info(g, " Done"); + + return 0; +} + +static int devinit_get_therm_channel_table(struct gk20a *g, + struct therm_channels *pthermchannelobjs) +{ + int status = 0; + u8 *therm_channel_table_ptr = NULL; + u8 *curr_therm_channel_table_ptr = NULL; + struct boardobj *boardobj; + struct therm_channel_1x_header therm_channel_table_header = { 0 }; + struct therm_channel_1x_entry *therm_channel_table_entry = NULL; + u32 index; + u32 obj_index = 0; + u16 therm_channel_size = 0; + union { + struct boardobj boardobj; + struct therm_channel therm_channel; + struct therm_channel_device device; + } therm_channel_data; + + nvgpu_log_info(g, " "); + + therm_channel_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, THERMAL_CHANNEL_TABLE); + if (therm_channel_table_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&therm_channel_table_header, therm_channel_table_ptr, + VBIOS_THERM_CHANNEL_1X_HEADER_SIZE_09); + + if (therm_channel_table_header.version != + VBIOS_THERM_CHANNEL_VERSION_1X) { + status = -EINVAL; + goto done; + } + + if (therm_channel_table_header.header_size < + VBIOS_THERM_CHANNEL_1X_HEADER_SIZE_09) { + status = -EINVAL; + goto done; + } + + curr_therm_channel_table_ptr = (therm_channel_table_ptr + + VBIOS_THERM_CHANNEL_1X_HEADER_SIZE_09); + + for (index = 0; index < therm_channel_table_header.num_table_entries; + index++) { + therm_channel_table_entry = (struct therm_channel_1x_entry *) + (curr_therm_channel_table_ptr + + (therm_channel_table_header.table_entry_size * index)); + + if (therm_channel_table_entry->class_id != + NV_VBIOS_THERM_CHANNEL_1X_ENTRY_CLASS_DEVICE) { + continue; + } + + therm_channel_data.device.therm_dev_idx = therm_channel_table_entry->param0; + therm_channel_data.device.therm_dev_prov_idx = therm_channel_table_entry->param1; + + therm_channel_size = sizeof(struct therm_channel_device); + therm_channel_data.boardobj.type = CTRL_THERMAL_THERM_CHANNEL_CLASS_DEVICE; + + boardobj = construct_channel_device(g, &therm_channel_data, + therm_channel_size, therm_channel_data.boardobj.type); + + if (!boardobj) { + nvgpu_err(g, + "unable to create thermal device for %d type %d", + index, therm_channel_data.boardobj.type); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert(&pthermchannelobjs->super.super, + boardobj, obj_index); + + if (status) { + nvgpu_err(g, + "unable to insert thermal device boardobj for %d", index); + status = -EINVAL; + goto done; + } + + ++obj_index; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int therm_channel_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + struct therm_channels *pthermchannelobjs; + + /* Construct the Super Class and override the Interfaces */ + status = boardobjgrpconstruct_e32(g, + &g->therm_pmu.therm_channelobjs.super); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for therm devices, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->therm_pmu.therm_channelobjs.super.super; + pthermchannelobjs = &(g->therm_pmu.therm_channelobjs); + + /* Override the Interfaces */ + pboardobjgrp->pmudatainstget = _therm_channel_pmudata_instget; + + status = devinit_get_therm_channel_table(g, pthermchannelobjs); + if (status) { + goto done; + } + + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, THERM, THERM_CHANNEL); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + therm, THERM, therm_channel, THERM_CHANNEL); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} diff --git a/include/therm/thrmchannel.h b/include/therm/thrmchannel.h new file mode 100644 index 0000000..89be673 --- /dev/null +++ b/include/therm/thrmchannel.h @@ -0,0 +1,51 @@ +/* + * general thermal device structures & definitions + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_THERM_THRMCHANNEL_H +#define NVGPU_THERM_THRMCHANNEL_H + +#include "boardobj/boardobj.h" +#include "boardobj/boardobjgrp.h" +#include "ctrl/ctrltherm.h" + +struct therm_channel { + struct boardobj super; + s16 scaling; + s16 offset; + s32 temp_min; + s32 temp_max; +}; + +struct therm_channels { + struct boardobjgrp_e32 super; +}; + +struct therm_channel_device { + struct therm_channel super; + u8 therm_dev_idx; + u8 therm_dev_prov_idx; +}; + +int therm_channel_sw_setup(struct gk20a *g); + +#endif /* NVGPU_THERM_THRMCHANNEL_H */ diff --git a/include/therm/thrmdev.c b/include/therm/thrmdev.c new file mode 100644 index 0000000..63e1033 --- /dev/null +++ b/include/therm/thrmdev.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "thrmdev.h" +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "gp106/bios_gp106.h" +#include "ctrl/ctrltherm.h" + +static int _therm_device_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, + u8 idx) +{ + struct nv_pmu_therm_therm_device_boardobj_grp_set *pgrp_set = + (struct nv_pmu_therm_therm_device_boardobj_grp_set *) + pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data; + + nvgpu_log_info(g, " Done"); + + return 0; +} + +static int construct_therm_device(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pargs) +{ + return boardobj_construct_super(g, ppboardobj, size, pargs); +} + +static int construct_therm_device_gpu(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pargs) +{ + return construct_therm_device(g, ppboardobj, size, pargs); +} + +static int construct_therm_device_gpu_sci(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pargs) +{ + return construct_therm_device(g, ppboardobj, size, pargs); +} + + +static int therm_device_pmu_data_init_gpu_gpc_tsosc(struct gk20a *g, + struct boardobj *pboard_obj, struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct therm_device_gpu_gpc_tsosc *pdev = NULL; + struct nv_pmu_therm_therm_device_gpu_gpc_tsosc_boardobj_set *pset; + + status = boardobj_pmudatainit_super(g, pboard_obj, ppmudata); + if (status != 0) { + goto exit; + } + + pdev = (struct therm_device_gpu_gpc_tsosc *)(void *)pboard_obj; + pset = (struct nv_pmu_therm_therm_device_gpu_gpc_tsosc_boardobj_set *) + (void*) ppmudata; + + pset->gpc_tsosc_idx = pdev->gpc_tsosc_idx; + +exit: + return status; +} + +static int construct_therm_device_gpu_tsosc(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pargs) +{ + struct therm_device_gpu_gpc_tsosc *pdev = NULL; + struct therm_device_gpu_gpc_tsosc *ptmp_dev = + (struct therm_device_gpu_gpc_tsosc *)pargs; + int status = 0; + + status = construct_therm_device(g, ppboardobj, size, pargs); + if (status != 0) { + return status; + } + + pdev = (struct therm_device_gpu_gpc_tsosc *)(void *)*ppboardobj; + + pdev->super.super.pmudatainit = + therm_device_pmu_data_init_gpu_gpc_tsosc; + + pdev->gpc_tsosc_idx = ptmp_dev->gpc_tsosc_idx; + + return status; +} + +static int therm_device_pmu_data_init_hbm2_site(struct gk20a *g, + struct boardobj *pboard_obj, struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct therm_device_hbm2_site *pdev = NULL; + struct nv_pmu_therm_therm_device_hbm2_site_boardobj_set *pset; + + status = boardobj_pmudatainit_super(g, pboard_obj, ppmudata); + if (status != 0) { + goto exit; + } + + pdev = (struct therm_device_hbm2_site *)(void *)pboard_obj; + pset = (struct nv_pmu_therm_therm_device_hbm2_site_boardobj_set *) + (void *)ppmudata; + + pset->site_idx = pdev->site_idx; + +exit: + return status; +} + +static int construct_therm_device_hbm2_site(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pargs) +{ + struct therm_device_hbm2_site *pdev = NULL; + struct therm_device_hbm2_site *ptmp_dev = + (struct therm_device_hbm2_site *)pargs; + int status = 0; + + status = construct_therm_device(g, ppboardobj, size, pargs); + if (status != 0) { + return status; + } + + pdev = (struct therm_device_hbm2_site *)(void *)*ppboardobj; + + pdev->super.super.pmudatainit = + therm_device_pmu_data_init_hbm2_site; + + pdev->site_idx = ptmp_dev->site_idx; + + return status; +} + +static int construct_therm_device_hbm2_combined(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pargs) +{ + return construct_therm_device(g, ppboardobj, size, pargs); +} + + +static struct boardobj *therm_device_construct(struct gk20a *g, + void *pargs) +{ + struct boardobj *board_obj_ptr = NULL; + int status = 0; + + switch (BOARDOBJ_GET_TYPE(pargs)) { + case NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_GPU: + status = construct_therm_device_gpu(g, &board_obj_ptr, + sizeof(struct therm_device), pargs); + break; + case NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_GPU_GPC_SCI: + status = construct_therm_device_gpu_sci(g, &board_obj_ptr, + sizeof(struct therm_device_gpu_sci), pargs); + break; + case NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_GPU_GPC_TSOSC: + status = construct_therm_device_gpu_tsosc(g, &board_obj_ptr, + sizeof(struct therm_device_gpu_gpc_tsosc), pargs); + break; + case NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_HBM2_SITE: + status = construct_therm_device_hbm2_site(g, &board_obj_ptr, + sizeof(struct therm_device_hbm2_site), pargs); + break; + case NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_HBM2_COMBINED: + status = construct_therm_device_hbm2_combined(g, &board_obj_ptr, + sizeof(struct therm_device_hbm2_combined), pargs); + break; + default: + nvgpu_err(g, + "unsupported therm_device class - 0x%x", + BOARDOBJ_GET_TYPE(pargs)); + break; + } + + if(status) { + board_obj_ptr = NULL; + nvgpu_err(g, + "could not allocate memory for therm_device"); + if (board_obj_ptr != NULL) { + nvgpu_kfree(g, board_obj_ptr); + } + } + + + return board_obj_ptr; +} + +static int devinit_get_therm_device_table(struct gk20a *g, + struct therm_devices *pthermdeviceobjs) +{ + int status = 0; + u8 *therm_device_table_ptr = NULL; + u8 *curr_therm_device_table_ptr = NULL; + struct boardobj *boardobj; + struct therm_device_1x_header therm_device_table_header = { 0 }; + struct therm_device_1x_entry *therm_device_table_entry = NULL; + u32 index; + u32 obj_index = 0; + u8 class_id = 0; + union { + struct boardobj boardobj; + struct therm_device therm_device; + struct therm_device_gpu_sci gpu_sci; + struct therm_device_gpu_gpc_tsosc gpu_gpc_tsosc; + struct therm_device_hbm2_site hbm2_site; + struct therm_device_hbm2_combined hbm2_combined; + } therm_device_data; + + nvgpu_log_info(g, " "); + + therm_device_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, THERMAL_DEVICE_TABLE); + if (therm_device_table_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&therm_device_table_header, therm_device_table_ptr, + VBIOS_THERM_DEVICE_1X_HEADER_SIZE_04); + + if (therm_device_table_header.version != + VBIOS_THERM_DEVICE_VERSION_1X) { + status = -EINVAL; + goto done; + } + + if (therm_device_table_header.header_size < + VBIOS_THERM_DEVICE_1X_HEADER_SIZE_04) { + status = -EINVAL; + goto done; + } + + curr_therm_device_table_ptr = (therm_device_table_ptr + + VBIOS_THERM_DEVICE_1X_HEADER_SIZE_04); + + for (index = 0; index < therm_device_table_header.num_table_entries; + index++) { + therm_device_table_entry = (struct therm_device_1x_entry *) + (curr_therm_device_table_ptr + + (therm_device_table_header.table_entry_size * index)); + + class_id = therm_device_table_entry->class_id; + + switch (class_id) { + case NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_INVALID: + continue; + break; + case NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_GPU: + case NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_GPU_GPC_SCI: + break; + case NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_GPU_GPC_TSOSC: + therm_device_data.gpu_gpc_tsosc.gpc_tsosc_idx = + therm_device_table_entry->param0; + break; + case NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_HBM2_SITE: + therm_device_data.hbm2_site.site_idx = + therm_device_table_entry->param0; + break; + case NV_VBIOS_THERM_DEVICE_1X_ENTRY_CLASS_HBM2_COMBINED: + break; + default: + nvgpu_err(g, + "Unknown thermal device class i - %x, class - %x", + index, class_id); + goto done; + } + + therm_device_data.boardobj.type = class_id; + boardobj = therm_device_construct(g, &therm_device_data); + if (!boardobj) { + nvgpu_err(g, + "unable to create thermal device for %d type %d", + index, therm_device_data.boardobj.type); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert(&pthermdeviceobjs->super.super, + boardobj, obj_index); + + if (status) { + nvgpu_err(g, + "unable to insert thermal device boardobj for %d", index); + status = -EINVAL; + goto done; + } + + ++obj_index; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +int therm_device_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + struct therm_devices *pthermdeviceobjs; + + /* Construct the Super Class and override the Interfaces */ + status = boardobjgrpconstruct_e32(g, + &g->therm_pmu.therm_deviceobjs.super); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for therm devices, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->therm_pmu.therm_deviceobjs.super.super; + pthermdeviceobjs = &(g->therm_pmu.therm_deviceobjs); + + /* Override the Interfaces */ + pboardobjgrp->pmudatainstget = _therm_device_pmudata_instget; + + status = devinit_get_therm_device_table(g, pthermdeviceobjs); + if (status) { + goto done; + } + + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, THERM, THERM_DEVICE); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + therm, THERM, therm_device, THERM_DEVICE); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} diff --git a/include/therm/thrmdev.h b/include/therm/thrmdev.h new file mode 100644 index 0000000..151e96f --- /dev/null +++ b/include/therm/thrmdev.h @@ -0,0 +1,58 @@ +/* + * general thermal device structures & definitions + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_THERM_THRMDEV_H +#define NVGPU_THERM_THRMDEV_H + +#include "boardobj/boardobj.h" +#include "boardobj/boardobjgrp.h" + +struct therm_devices { + struct boardobjgrp_e32 super; +}; + +struct therm_device { + struct boardobj super; +}; + +struct therm_device_gpu_sci { + struct therm_device super; +}; + +struct therm_device_gpu_gpc_tsosc { + struct therm_device super; + u8 gpc_tsosc_idx; +}; + +struct therm_device_hbm2_site { + struct therm_device super; + u8 site_idx; +}; + +struct therm_device_hbm2_combined { + struct therm_device super; +}; + +int therm_device_sw_setup(struct gk20a *g); + +#endif /* NVGPU_THERM_THRMDEV_H */ diff --git a/include/therm/thrmpmu.c b/include/therm/thrmpmu.c new file mode 100644 index 0000000..65587ab --- /dev/null +++ b/include/therm/thrmpmu.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include + +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "thrmpmu.h" +#include + +struct therm_pmucmdhandler_params { + struct nv_pmu_therm_rpc *prpccall; + u32 success; +}; + +static void therm_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg, + void *param, u32 handle, u32 status) +{ + struct therm_pmucmdhandler_params *phandlerparams = + (struct therm_pmucmdhandler_params *)param; + + if (msg->msg.therm.msg_type != NV_PMU_THERM_MSG_ID_RPC) { + nvgpu_err(g, "unknow msg %x", + msg->msg.pmgr.msg_type); + return; + } + + if (!phandlerparams->prpccall->b_supported) { + nvgpu_err(g, "RPC msg %x failed", + msg->msg.pmgr.msg_type); + } else { + phandlerparams->success = 1; + } +} + +int therm_send_pmgr_tables_to_pmu(struct gk20a *g) +{ + int status = 0; + struct boardobjgrp *pboardobjgrp = NULL; + + if (!BOARDOBJGRP_IS_EMPTY(&g->therm_pmu.therm_deviceobjs.super.super)) { + pboardobjgrp = &g->therm_pmu.therm_deviceobjs.super.super; + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + if (status) { + nvgpu_err(g, + "therm_send_pmgr_tables_to_pmu - therm_device failed %x", + status); + goto exit; + } + } + + if (!BOARDOBJGRP_IS_EMPTY( + &g->therm_pmu.therm_channelobjs.super.super)) { + pboardobjgrp = &g->therm_pmu.therm_channelobjs.super.super; + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + if (status) { + nvgpu_err(g, + "therm_send_pmgr_tables_to_pmu - therm_channel failed %x", + status); + goto exit; + } + } + +exit: + return status; +} + +static u32 therm_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd, + struct pmu_msg *msg, struct pmu_payload *payload, + u32 queue_id, pmu_callback callback, void* cb_param, + u32 *seq_desc, unsigned long timeout) +{ + u32 status; + struct therm_pmucmdhandler_params *handlerparams = NULL; + + status = nvgpu_pmu_cmd_post(g, cmd, msg, payload, + queue_id, + callback, + cb_param, + seq_desc, + timeout); + if (status) { + nvgpu_err(g, + "unable to post therm cmd for unit %x cmd id %x size %x", + cmd->hdr.unit_id, cmd->cmd.therm.cmd_type, cmd->hdr.size); + goto exit; + } + + if (cb_param) { + handlerparams = (struct therm_pmucmdhandler_params*)cb_param; + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handlerparams->success, 1); + + if (handlerparams->success == 0) { + nvgpu_err(g, "could not process cmd"); + status = -ETIMEDOUT; + goto exit; + } + } + +exit: + return status; +} + +static u32 therm_set_warn_temp_limit(struct gk20a *g) +{ + u32 seqdesc = 0; + struct pmu_cmd cmd; + struct pmu_msg msg; + struct pmu_payload payload; + struct nv_pmu_therm_rpc rpccall; + struct therm_pmucmdhandler_params handlerparams; + + memset(&payload, 0, sizeof(struct pmu_payload)); + memset(&cmd, 0, sizeof(struct pmu_cmd)); + memset(&msg, 0, sizeof(struct pmu_msg)); + memset(&rpccall, 0, sizeof(struct nv_pmu_therm_rpc)); + memset(&handlerparams, 0, sizeof(struct therm_pmucmdhandler_params)); + + rpccall.function = NV_PMU_THERM_RPC_ID_SLCT_EVENT_TEMP_TH_SET; + rpccall.params.slct_event_temp_th_set.event_id = + NV_PMU_THERM_EVENT_THERMAL_1; + rpccall.params.slct_event_temp_th_set.temp_threshold = g->curr_warn_temp; + rpccall.b_supported = 0; + + cmd.hdr.unit_id = PMU_UNIT_THERM; + cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_rpc) + + (u32)sizeof(struct pmu_hdr)); + cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_RPC; + + msg.hdr.size = sizeof(struct pmu_msg); + + payload.in.buf = (u8 *)&rpccall; + payload.in.size = (u32)sizeof(struct nv_pmu_therm_rpc); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = NV_PMU_THERM_CMD_RPC_ALLOC_OFFSET; + + payload.out.buf = (u8 *)&rpccall; + payload.out.size = (u32)sizeof(struct nv_pmu_therm_rpc); + payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.out.offset = NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET; + + /* Setup the handler params to communicate back results.*/ + handlerparams.success = 0; + handlerparams.prpccall = &rpccall; + + return therm_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + therm_pmucmdhandler, + (void *)&handlerparams, + &seqdesc, ~0); +} + +static u32 therm_enable_slct_notification_request(struct gk20a *g) +{ + u32 seqdesc = 0; + struct pmu_cmd cmd = { {0} }; + + cmd.hdr.unit_id = PMU_UNIT_THERM; + cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_hw_slowdown_notification) + + (u32)sizeof(struct pmu_hdr)); + + cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_HW_SLOWDOWN_NOTIFICATION; + cmd.cmd.therm.hw_slct_notification.request = + NV_RM_PMU_THERM_HW_SLOWDOWN_NOTIFICATION_REQUEST_ENABLE; + + return therm_pmu_cmd_post(g, &cmd, NULL, NULL, + PMU_COMMAND_QUEUE_LPQ, + NULL, + NULL, + &seqdesc, ~0); +} + +static u32 therm_send_slct_configuration_to_pmu(struct gk20a *g) +{ + u32 seqdesc = 0; + struct pmu_cmd cmd; + struct pmu_msg msg; + struct pmu_payload payload; + struct nv_pmu_therm_rpc rpccall; + struct therm_pmucmdhandler_params handlerparams; + + memset(&payload, 0, sizeof(struct pmu_payload)); + memset(&cmd, 0, sizeof(struct pmu_cmd)); + memset(&msg, 0, sizeof(struct pmu_msg)); + memset(&rpccall, 0, sizeof(struct nv_pmu_therm_rpc)); + memset(&handlerparams, 0, sizeof(struct therm_pmucmdhandler_params)); + + rpccall.function = NV_PMU_THERM_RPC_ID_SLCT; + rpccall.params.slct.mask_enabled = + (1 << NV_PMU_THERM_EVENT_THERMAL_1); + rpccall.b_supported = 0; + + cmd.hdr.unit_id = PMU_UNIT_THERM; + cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_rpc) + + (u32)sizeof(struct pmu_hdr)); + cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_RPC; + + msg.hdr.size = sizeof(struct pmu_msg); + + payload.in.buf = (u8 *)&rpccall; + payload.in.size = (u32)sizeof(struct nv_pmu_therm_rpc); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = NV_PMU_THERM_CMD_RPC_ALLOC_OFFSET; + + payload.out.buf = (u8 *)&rpccall; + payload.out.size = (u32)sizeof(struct nv_pmu_therm_rpc); + payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.out.offset = NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET; + + /* Setup the handler params to communicate back results.*/ + handlerparams.success = 0; + handlerparams.prpccall = &rpccall; + + return therm_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + therm_pmucmdhandler, + (void *)&handlerparams, + &seqdesc, ~0); +} + +u32 therm_configure_therm_alert(struct gk20a *g) +{ + u32 status; + + status = therm_enable_slct_notification_request(g); + if (status) { + nvgpu_err(g, + "therm_enable_slct_notification_request-failed %d", + status); + goto exit; + } + + status = therm_send_slct_configuration_to_pmu(g); + if (status) { + nvgpu_err(g, + "therm_send_slct_configuration_to_pmu-failed %d", + status); + goto exit; + } + + status = therm_set_warn_temp_limit(g); + if (status) { + nvgpu_err(g, + "therm_set_warn_temp_limit-failed %d", + status); + goto exit; + } +exit: + return status; +} diff --git a/include/therm/thrmpmu.h b/include/therm/thrmpmu.h new file mode 100644 index 0000000..42d5caa --- /dev/null +++ b/include/therm/thrmpmu.h @@ -0,0 +1,31 @@ +/* + * general thermal pmu control structures & definitions + * + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef NVGPU_THERM_THRMPMU_H +#define NVGPU_THERM_THRMPMU_H + +int therm_send_pmgr_tables_to_pmu(struct gk20a *g); + +u32 therm_configure_therm_alert(struct gk20a *g); + +#endif /* NVGPU_THERM_THRMPMU_H */ diff --git a/include/volt/volt.h b/include/volt/volt.h new file mode 100644 index 0000000..8b4895f --- /dev/null +++ b/include/volt/volt.h @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_VOLT_H +#define NVGPU_VOLT_H + +#include "volt_rail.h" +#include "volt_dev.h" +#include "volt_policy.h" +#include "volt_pmu.h" + +#define VOLTAGE_DESCRIPTOR_TABLE_ENTRY_INVALID 0xFF + +struct obj_volt { + struct voltage_rail_metadata volt_rail_metadata; + struct voltage_device_metadata volt_dev_metadata; + struct voltage_policy_metadata volt_policy_metadata; +}; + +#endif /* NVGPU_VOLT_H */ diff --git a/include/volt/volt_dev.c b/include/volt/volt_dev.c new file mode 100644 index 0000000..bb5d182 --- /dev/null +++ b/include/volt/volt_dev.c @@ -0,0 +1,609 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "gp106/bios_gp106.h" + +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "ctrl/ctrlvolt.h" + +#include "volt.h" + +#define VOLT_DEV_PWM_VOLTAGE_STEPS_INVALID 0U +#define VOLT_DEV_PWM_VOLTAGE_STEPS_DEFAULT 1U + +static int volt_device_pmu_data_init_super(struct gk20a *g, + struct boardobj *pboard_obj, struct nv_pmu_boardobj *ppmudata) +{ + int status; + struct voltage_device *pdev; + struct nv_pmu_volt_volt_device_boardobj_set *pset; + + status = boardobj_pmudatainit_super(g, pboard_obj, ppmudata); + if (status) { + return status; + } + + pdev = (struct voltage_device *)pboard_obj; + pset = (struct nv_pmu_volt_volt_device_boardobj_set *)ppmudata; + + pset->switch_delay_us = pdev->switch_delay_us; + pset->voltage_min_uv = pdev->voltage_min_uv; + pset->voltage_max_uv = pdev->voltage_max_uv; + pset->volt_step_uv = pdev->volt_step_uv; + + return status; +} + +static int volt_device_pmu_data_init_pwm(struct gk20a *g, + struct boardobj *pboard_obj, struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct voltage_device_pwm *pdev; + struct nv_pmu_volt_volt_device_pwm_boardobj_set *pset; + + status = volt_device_pmu_data_init_super(g, pboard_obj, ppmudata); + if (status) { + return status; + } + + pdev = (struct voltage_device_pwm *)pboard_obj; + pset = (struct nv_pmu_volt_volt_device_pwm_boardobj_set *)ppmudata; + + pset->raw_period = pdev->raw_period; + pset->voltage_base_uv = pdev->voltage_base_uv; + pset->voltage_offset_scale_uv = pdev->voltage_offset_scale_uv; + pset->pwm_source = pdev->source; + + return status; +} + +static int construct_volt_device(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pargs) +{ + struct voltage_device *ptmp_dev = (struct voltage_device *)pargs; + struct voltage_device *pvolt_dev = NULL; + int status = 0; + + status = boardobj_construct_super(g, ppboardobj, size, pargs); + if (status) { + return status; + } + + pvolt_dev = (struct voltage_device *)*ppboardobj; + + pvolt_dev->volt_domain = ptmp_dev->volt_domain; + pvolt_dev->i2c_dev_idx = ptmp_dev->i2c_dev_idx; + pvolt_dev->switch_delay_us = ptmp_dev->switch_delay_us; + pvolt_dev->rsvd_0 = VOLTAGE_DESCRIPTOR_TABLE_ENTRY_INVALID; + pvolt_dev->rsvd_1 = + VOLTAGE_DESCRIPTOR_TABLE_ENTRY_INVALID; + pvolt_dev->operation_type = ptmp_dev->operation_type; + pvolt_dev->voltage_min_uv = ptmp_dev->voltage_min_uv; + pvolt_dev->voltage_max_uv = ptmp_dev->voltage_max_uv; + + pvolt_dev->super.pmudatainit = volt_device_pmu_data_init_super; + + return status; +} + +static int construct_pwm_volt_device(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *pboard_obj = NULL; + struct voltage_device_pwm *ptmp_dev = + (struct voltage_device_pwm *)pargs; + struct voltage_device_pwm *pdev = NULL; + int status = 0; + + status = construct_volt_device(g, ppboardobj, size, pargs); + if (status) { + return status; + } + + pboard_obj = (*ppboardobj); + pdev = (struct voltage_device_pwm *)*ppboardobj; + + pboard_obj->pmudatainit = volt_device_pmu_data_init_pwm; + + /* Set VOLTAGE_DEVICE_PWM-specific parameters */ + pdev->voltage_base_uv = ptmp_dev->voltage_base_uv; + pdev->voltage_offset_scale_uv = ptmp_dev->voltage_offset_scale_uv; + pdev->source = ptmp_dev->source; + pdev->raw_period = ptmp_dev->raw_period; + + return status; +} + + +static struct voltage_device_entry *volt_dev_construct_dev_entry_pwm( + struct gk20a *g, + u32 voltage_uv, void *pargs) +{ + struct voltage_device_pwm_entry *pentry = NULL; + struct voltage_device_pwm_entry *ptmp_entry = + (struct voltage_device_pwm_entry *)pargs; + + pentry = nvgpu_kzalloc(g, sizeof(struct voltage_device_pwm_entry)); + if (pentry == NULL) { + return NULL; + } + + memset(pentry, 0, sizeof(struct voltage_device_pwm_entry)); + + pentry->super.voltage_uv = voltage_uv; + pentry->duty_cycle = ptmp_entry->duty_cycle; + + return (struct voltage_device_entry *)pentry; +} + +static u8 volt_dev_operation_type_convert(u8 vbios_type) +{ + switch (vbios_type) { + case NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_OPERATION_TYPE_DEFAULT: + return CTRL_VOLT_DEVICE_OPERATION_TYPE_DEFAULT; + + case NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_OPERATION_TYPE_LPWR_STEADY_STATE: + return CTRL_VOLT_DEVICE_OPERATION_TYPE_LPWR_STEADY_STATE; + + case NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_OPERATION_TYPE_LPWR_SLEEP_STATE: + return CTRL_VOLT_DEVICE_OPERATION_TYPE_LPWR_SLEEP_STATE; + } + + return CTRL_VOLT_DEVICE_OPERATION_TYPE_INVALID; +} + +static struct voltage_device *volt_volt_device_construct(struct gk20a *g, + void *pargs) +{ + struct boardobj *pboard_obj = NULL; + + if (BOARDOBJ_GET_TYPE(pargs) == CTRL_VOLT_DEVICE_TYPE_PWM) { + int status = construct_pwm_volt_device(g, &pboard_obj, + sizeof(struct voltage_device_pwm), pargs); + if (status) { + nvgpu_err(g, + " Could not allocate memory for VOLTAGE_DEVICE type (%x).", + BOARDOBJ_GET_TYPE(pargs)); + pboard_obj = NULL; + } + } + + return (struct voltage_device *)pboard_obj; +} + +static int volt_get_voltage_device_table_1x_psv(struct gk20a *g, + struct vbios_voltage_device_table_1x_entry *p_bios_entry, + struct voltage_device_metadata *p_Volt_Device_Meta_Data, + u8 entry_Idx) +{ + int status = 0; + u32 entry_cnt = 0; + struct voltage_device *pvolt_dev = NULL; + struct voltage_device_pwm *pvolt_dev_pwm = NULL; + struct voltage_device_pwm *ptmp_dev = NULL; + u32 duty_cycle; + u32 frequency_hz; + u32 voltage_uv; + u8 ext_dev_idx; + u8 steps; + u8 volt_domain = 0; + struct voltage_device_pwm_entry pwm_entry = { { 0 } }; + + ptmp_dev = nvgpu_kzalloc(g, sizeof(struct voltage_device_pwm)); + if (ptmp_dev == NULL) { + return -ENOMEM; + } + + frequency_hz = (u32)BIOS_GET_FIELD(p_bios_entry->param0, + NV_VBIOS_VDT_1X_ENTRY_PARAM0_PSV_INPUT_FREQUENCY); + + ext_dev_idx = (u8)BIOS_GET_FIELD(p_bios_entry->param0, + NV_VBIOS_VDT_1X_ENTRY_PARAM0_PSV_EXT_DEVICE_INDEX); + + ptmp_dev->super.operation_type = volt_dev_operation_type_convert( + (u8)BIOS_GET_FIELD(p_bios_entry->param1, + NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_OPERATION_TYPE)); + + if (ptmp_dev->super.operation_type == + CTRL_VOLT_DEVICE_OPERATION_TYPE_INVALID) { + nvgpu_err(g, " Invalid Voltage Device Operation Type."); + + status = -EINVAL; + goto done; + } + + ptmp_dev->super.voltage_min_uv = + (u32)BIOS_GET_FIELD(p_bios_entry->param1, + NV_VBIOS_VDT_1X_ENTRY_PARAM1_PSV_VOLTAGE_MINIMUM); + + ptmp_dev->super.voltage_max_uv = + (u32)BIOS_GET_FIELD(p_bios_entry->param2, + NV_VBIOS_VDT_1X_ENTRY_PARAM2_PSV_VOLTAGE_MAXIMUM); + + ptmp_dev->voltage_base_uv = BIOS_GET_FIELD(p_bios_entry->param3, + NV_VBIOS_VDT_1X_ENTRY_PARAM3_PSV_VOLTAGE_BASE); + + steps = (u8)BIOS_GET_FIELD(p_bios_entry->param3, + NV_VBIOS_VDT_1X_ENTRY_PARAM3_PSV_VOLTAGE_STEPS); + if (steps == VOLT_DEV_PWM_VOLTAGE_STEPS_INVALID) { + steps = VOLT_DEV_PWM_VOLTAGE_STEPS_DEFAULT; + } + + ptmp_dev->voltage_offset_scale_uv = + BIOS_GET_FIELD(p_bios_entry->param4, + NV_VBIOS_VDT_1X_ENTRY_PARAM4_PSV_OFFSET_SCALE); + + volt_domain = volt_rail_vbios_volt_domain_convert_to_internal(g, + (u8)p_bios_entry->volt_domain); + if (volt_domain == CTRL_VOLT_DOMAIN_INVALID) { + nvgpu_err(g, "invalid voltage domain = %d", + (u8)p_bios_entry->volt_domain); + status = -EINVAL; + goto done; + } + + if (ptmp_dev->super.operation_type == + CTRL_VOLT_DEVICE_OPERATION_TYPE_DEFAULT) { + if (volt_domain == CTRL_VOLT_DOMAIN_LOGIC) { + ptmp_dev->source = + NV_PMU_PMGR_PWM_SOURCE_THERM_VID_PWM_0; + } + if (volt_domain == CTRL_VOLT_DOMAIN_SRAM) { + ptmp_dev->source = + NV_PMU_PMGR_PWM_SOURCE_THERM_VID_PWM_1; + } + ptmp_dev->raw_period = + g->ops.clk.get_crystal_clk_hz(g) / frequency_hz; + } else if (ptmp_dev->super.operation_type == + CTRL_VOLT_DEVICE_OPERATION_TYPE_LPWR_STEADY_STATE) { + ptmp_dev->source = NV_PMU_PMGR_PWM_SOURCE_RSVD_0; + ptmp_dev->raw_period = 0; + } else if (ptmp_dev->super.operation_type == + CTRL_VOLT_DEVICE_OPERATION_TYPE_LPWR_SLEEP_STATE) { + ptmp_dev->source = NV_PMU_PMGR_PWM_SOURCE_RSVD_1; + ptmp_dev->raw_period = 0; + } + + /* Initialize data for parent class. */ + ptmp_dev->super.super.type = CTRL_VOLT_DEVICE_TYPE_PWM; + ptmp_dev->super.volt_domain = volt_domain; + ptmp_dev->super.i2c_dev_idx = ext_dev_idx; + ptmp_dev->super.switch_delay_us = (u16)p_bios_entry->settle_time_us; + + pvolt_dev = volt_volt_device_construct(g, ptmp_dev); + if (pvolt_dev == NULL) { + nvgpu_err(g, " Failure to construct VOLTAGE_DEVICE object."); + + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert( + &p_Volt_Device_Meta_Data->volt_devices.super, + (struct boardobj *)pvolt_dev, entry_Idx); + if (status) { + nvgpu_err(g, + "could not add VOLTAGE_DEVICE for entry %d into boardobjgrp ", + entry_Idx); + goto done; + } + + pvolt_dev_pwm = (struct voltage_device_pwm *)pvolt_dev; + + duty_cycle = 0; + do { + voltage_uv = (u32)(pvolt_dev_pwm->voltage_base_uv + + (s32)((((s64)((s32)duty_cycle)) * + pvolt_dev_pwm->voltage_offset_scale_uv) + / ((s64)((s32) pvolt_dev_pwm->raw_period)))); + + /* Skip creating entry for invalid voltage. */ + if ((voltage_uv >= pvolt_dev_pwm->super.voltage_min_uv) && + (voltage_uv <= pvolt_dev_pwm->super.voltage_max_uv)) { + if (pvolt_dev_pwm->voltage_offset_scale_uv < 0) { + pwm_entry.duty_cycle = + pvolt_dev_pwm->raw_period - duty_cycle; + } else { + pwm_entry.duty_cycle = duty_cycle; + } + + /* Check if there is room left in the voltage table. */ + if (entry_cnt == VOLTAGE_TABLE_MAX_ENTRIES) { + nvgpu_err(g, "Voltage table is full"); + status = -EINVAL; + goto done; + } + + pvolt_dev->pentry[entry_cnt] = + volt_dev_construct_dev_entry_pwm(g, + voltage_uv, &pwm_entry); + if (pvolt_dev->pentry[entry_cnt] == NULL) { + nvgpu_err(g, + " Error creating voltage_device_pwm_entry!"); + status = -EINVAL; + goto done; + } + + entry_cnt++; + } + + /* Obtain next value after the specified steps. */ + duty_cycle = duty_cycle + (u32)steps; + + /* Cap duty cycle to PWM period. */ + if (duty_cycle > pvolt_dev_pwm->raw_period) { + duty_cycle = pvolt_dev_pwm->raw_period; + } + + } while (duty_cycle < pvolt_dev_pwm->raw_period); + +done: + if (pvolt_dev != NULL) { + pvolt_dev->num_entries = entry_cnt; + } + + nvgpu_kfree(g, ptmp_dev); + return status; +} + +static u32 volt_get_volt_devices_table(struct gk20a *g, + struct voltage_device_metadata *pvolt_device_metadata) +{ + u32 status = 0; + u8 *volt_device_table_ptr = NULL; + struct vbios_voltage_device_table_1x_header header = { 0 }; + struct vbios_voltage_device_table_1x_entry entry = { 0 }; + u8 entry_idx; + u8 *entry_offset; + + volt_device_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, VOLTAGE_DEVICE_TABLE); + if (volt_device_table_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&header, volt_device_table_ptr, + sizeof(struct vbios_voltage_device_table_1x_header)); + + /* Read in the entries. */ + for (entry_idx = 0; entry_idx < header.num_table_entries; entry_idx++) { + entry_offset = (volt_device_table_ptr + header.header_size + + (entry_idx * header.table_entry_size)); + + memcpy(&entry, entry_offset, + sizeof(struct vbios_voltage_device_table_1x_entry)); + + if (entry.type == NV_VBIOS_VOLTAGE_DEVICE_1X_ENTRY_TYPE_PSV) { + status = volt_get_voltage_device_table_1x_psv(g, + &entry, pvolt_device_metadata, + entry_idx); + } + } + +done: + return status; +} + +static int _volt_device_devgrp_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx) +{ + struct nv_pmu_volt_volt_device_boardobj_grp_set *pgrp_set = + (struct nv_pmu_volt_volt_device_boardobj_grp_set *) + pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0U) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + nvgpu_log_info(g, "Done"); + return 0; +} + +static int _volt_device_devgrp_pmustatus_instget(struct gk20a *g, + void *pboardobjgrppmu, + struct nv_pmu_boardobj_query **ppboardobjpmustatus, u8 idx) +{ + struct nv_pmu_volt_volt_device_boardobj_grp_get_status *pgrp_get_status + = (struct nv_pmu_volt_volt_device_boardobj_grp_get_status *) + pboardobjgrppmu; + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_get_status->hdr.data.super.obj_mask.super.data[0]) == 0U) { + return -EINVAL; + } + + *ppboardobjpmustatus = (struct nv_pmu_boardobj_query *) + &pgrp_get_status->objects[idx].data.board_obj; + return 0; +} + +static int volt_device_volt_cmp(const void *a, const void *b) +{ + const struct voltage_device_entry *a_entry = *(const struct voltage_device_entry **)a; + const struct voltage_device_entry *b_entry = *(const struct voltage_device_entry **)b; + + return (int)a_entry->voltage_uv - (int)b_entry->voltage_uv; +} + +static u32 volt_device_state_init(struct gk20a *g, + struct voltage_device *pvolt_dev) +{ + u32 status = 0; + struct voltage_rail *pRail = NULL; + u8 rail_idx = 0; + + sort(pvolt_dev->pentry, pvolt_dev->num_entries, + sizeof(*pvolt_dev->pentry), volt_device_volt_cmp, + NULL); + + /* Initialize VOLT_DEVICE step size. */ + if (pvolt_dev->num_entries <= VOLTAGE_TABLE_MAX_ENTRIES_ONE) { + pvolt_dev->volt_step_uv = NV_PMU_VOLT_VALUE_0V_IN_UV; + } else { + pvolt_dev->volt_step_uv = (pvolt_dev->pentry[1]->voltage_uv - + pvolt_dev->pentry[0]->voltage_uv); + } + + /* Build VOLT_RAIL SW state from VOLT_DEVICE SW state. */ + /* If VOLT_RAIL isn't supported, exit. */ + if (VOLT_RAIL_VOLT_3X_SUPPORTED(&g->perf_pmu.volt)) { + rail_idx = volt_rail_volt_domain_convert_to_idx(g, + pvolt_dev->volt_domain); + if (rail_idx == CTRL_BOARDOBJ_IDX_INVALID) { + nvgpu_err(g, + " could not convert voltage domain to rail index."); + status = -EINVAL; + goto done; + } + + pRail = VOLT_GET_VOLT_RAIL(&g->perf_pmu.volt, rail_idx); + if (pRail == NULL) { + nvgpu_err(g, + "could not obtain ptr to rail object from rail index"); + status = -EINVAL; + goto done; + } + + status = volt_rail_volt_dev_register(g, pRail, + BOARDOBJ_GET_IDX(pvolt_dev), pvolt_dev->operation_type); + if (status) { + nvgpu_err(g, + "Failed to register the device with rail obj"); + goto done; + } + } + +done: + if (status) { + nvgpu_err(g, "Error in building rail sw state device sw"); + } + + return status; +} + +int volt_dev_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + pboardobjgrp = &g->perf_pmu.volt.volt_dev_metadata.volt_devices.super; + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + nvgpu_log_info(g, "Done"); + return status; +} + +u32 volt_dev_sw_setup(struct gk20a *g) +{ + u32 status = 0; + struct boardobjgrp *pboardobjgrp = NULL; + struct voltage_device *pvolt_device; + u8 i; + + nvgpu_log_info(g, " "); + + status = boardobjgrpconstruct_e32(g, + &g->perf_pmu.volt.volt_dev_metadata.volt_devices); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for volt rail, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->perf_pmu.volt.volt_dev_metadata.volt_devices.super; + + pboardobjgrp->pmudatainstget = _volt_device_devgrp_pmudata_instget; + pboardobjgrp->pmustatusinstget = _volt_device_devgrp_pmustatus_instget; + + /* Obtain Voltage Rail Table from VBIOS */ + status = volt_get_volt_devices_table(g, &g->perf_pmu.volt. + volt_dev_metadata); + if (status) { + goto done; + } + + /* Populate data for the VOLT_RAIL PMU interface */ + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, VOLT, VOLT_DEVICE); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + volt, VOLT, volt_device, VOLT_DEVICE); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, + &g->perf_pmu.volt.volt_dev_metadata.volt_devices.super, + volt, VOLT, volt_device, VOLT_DEVICE); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + /* update calibration to fuse */ + BOARDOBJGRP_FOR_EACH(&(g->perf_pmu.volt.volt_dev_metadata.volt_devices. + super), + struct voltage_device *, pvolt_device, i) { + status = volt_device_state_init(g, pvolt_device); + if (status) { + nvgpu_err(g, + "failure while executing devices's state init interface"); + nvgpu_err(g, + " railIdx = %d, status = 0x%x", i, status); + goto done; + } + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} diff --git a/include/volt/volt_dev.h b/include/volt/volt_dev.h new file mode 100644 index 0000000..48d93ae --- /dev/null +++ b/include/volt/volt_dev.h @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_VOLT_DEV_H +#define NVGPU_VOLT_DEV_H + +#include "boardobj/boardobj.h" +#include "boardobj/boardobjgrp.h" +#include "ctrl/ctrlvolt.h" + +#define VOLTAGE_TABLE_MAX_ENTRIES_ONE 1U +#define VOLTAGE_TABLE_MAX_ENTRIES 256U + +struct voltage_device { + struct boardobj super; + u8 volt_domain; + u8 i2c_dev_idx; + u32 switch_delay_us; + u32 num_entries; + struct voltage_device_entry *pentry[VOLTAGE_TABLE_MAX_ENTRIES]; + struct voltage_device_entry *pcurr_entry; + u8 rsvd_0; + u8 rsvd_1; + u8 operation_type; + u32 voltage_min_uv; + u32 voltage_max_uv; + u32 volt_step_uv; +}; + +struct voltage_device_entry { + u32 voltage_uv; +}; + +struct voltage_device_metadata { + struct boardobjgrp_e32 volt_devices; +}; + +/*! + * Extends VOLTAGE_DEVICE providing attributes specific to PWM controllers. + */ +struct voltage_device_pwm { + struct voltage_device super; + s32 voltage_base_uv; + s32 voltage_offset_scale_uv; + enum nv_pmu_pmgr_pwm_source source; + u32 raw_period; +}; + +struct voltage_device_pwm_entry { + struct voltage_device_entry super; + u32 duty_cycle; +}; +/* PWM end */ + +u32 volt_dev_sw_setup(struct gk20a *g); +int volt_dev_pmu_setup(struct gk20a *g); + +#endif /* NVGPU_VOLT_DEV_H */ diff --git a/include/volt/volt_pmu.c b/include/volt/volt_pmu.c new file mode 100644 index 0000000..2249ae2 --- /dev/null +++ b/include/volt/volt_pmu.c @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "gp106/bios_gp106.h" +#include "ctrl/ctrlvolt.h" +#include "ctrl/ctrlperf.h" + +#include "volt.h" + +#define RAIL_COUNT_GP 2 +#define RAIL_COUNT_GV 1 + +struct volt_rpc_pmucmdhandler_params { + struct nv_pmu_volt_rpc *prpc_call; + u32 success; +}; + +static void volt_rpc_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg, + void *param, u32 handle, u32 status) +{ + struct volt_rpc_pmucmdhandler_params *phandlerparams = + (struct volt_rpc_pmucmdhandler_params *)param; + + nvgpu_log_info(g, " "); + + if (msg->msg.volt.msg_type != NV_PMU_VOLT_MSG_ID_RPC) { + nvgpu_err(g, "unsupported msg for VOLT RPC %x", + msg->msg.volt.msg_type); + return; + } + + if (phandlerparams->prpc_call->b_supported) { + phandlerparams->success = 1; + } +} + + +static u32 volt_pmu_rpc_execute(struct gk20a *g, + struct nv_pmu_volt_rpc *prpc_call) +{ + struct pmu_cmd cmd; + struct pmu_msg msg; + struct pmu_payload payload; + u32 status = 0; + u32 seqdesc; + struct volt_rpc_pmucmdhandler_params handler; + + memset(&payload, 0, sizeof(struct pmu_payload)); + memset(&cmd, 0, sizeof(struct pmu_cmd)); + memset(&msg, 0, sizeof(struct pmu_msg)); + memset(&handler, 0, sizeof(struct volt_rpc_pmucmdhandler_params)); + + cmd.hdr.unit_id = PMU_UNIT_VOLT; + cmd.hdr.size = (u32)sizeof(struct nv_pmu_volt_cmd) + + (u32)sizeof(struct pmu_hdr); + cmd.cmd.volt.cmd_type = NV_PMU_VOLT_CMD_ID_RPC; + msg.hdr.size = sizeof(struct pmu_msg); + + payload.in.buf = (u8 *)prpc_call; + payload.in.size = (u32)sizeof(struct nv_pmu_volt_rpc); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = NV_PMU_VOLT_CMD_RPC_ALLOC_OFFSET; + + payload.out.buf = (u8 *)prpc_call; + payload.out.size = (u32)sizeof(struct nv_pmu_volt_rpc); + payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.out.offset = NV_PMU_VOLT_MSG_RPC_ALLOC_OFFSET; + + handler.prpc_call = prpc_call; + handler.success = 0; + + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + volt_rpc_pmucmdhandler, (void *)&handler, + &seqdesc, ~0); + if (status) { + nvgpu_err(g, "unable to post volt RPC cmd %x", + cmd.cmd.volt.cmd_type); + goto volt_pmu_rpc_execute; + } + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handler.success, 1); + + if (handler.success == 0U) { + status = -EINVAL; + nvgpu_err(g, "rpc call to volt failed"); + } + +volt_pmu_rpc_execute: + return status; +} + +u32 nvgpu_volt_send_load_cmd_to_pmu_gp10x(struct gk20a *g) +{ + struct nv_pmu_volt_rpc rpc_call = { 0 }; + u32 status = 0; + + rpc_call.function = NV_PMU_VOLT_RPC_ID_LOAD; + + status = volt_pmu_rpc_execute(g, &rpc_call); + if (status) { + nvgpu_err(g, + "Error while executing LOAD RPC: status = 0x%08x.", + status); + } + + return status; +} + +u32 nvgpu_volt_send_load_cmd_to_pmu_gv10x(struct gk20a *g) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct nv_pmu_rpc_struct_volt_load rpc; + u32 status = 0; + + memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_volt_load)); + PMU_RPC_EXECUTE(status, pmu, VOLT, LOAD, &rpc, 0); + if (status) { + nvgpu_err(g, "Failed to execute RPC status=0x%x", + status); + } + + return status; +} + +u32 nvgpu_volt_rail_get_voltage_gp10x(struct gk20a *g, + u8 volt_domain, u32 *pvoltage_uv) +{ + struct nv_pmu_volt_rpc rpc_call = { 0 }; + u32 status = 0; + u8 rail_idx; + + rail_idx = volt_rail_volt_domain_convert_to_idx(g, volt_domain); + if ((rail_idx == CTRL_VOLT_RAIL_INDEX_INVALID) || + (!VOLT_RAIL_INDEX_IS_VALID(&g->perf_pmu.volt, rail_idx))) { + nvgpu_err(g, + "failed: volt_domain = %d, voltage rail table = %d.", + volt_domain, rail_idx); + return -EINVAL; + } + + /* Set RPC parameters. */ + rpc_call.function = NV_PMU_VOLT_RPC_ID_VOLT_RAIL_GET_VOLTAGE; + rpc_call.params.volt_rail_get_voltage.rail_idx = rail_idx; + + /* Execute the voltage get request via PMU RPC. */ + status = volt_pmu_rpc_execute(g, &rpc_call); + if (status) { + nvgpu_err(g, + "Error while executing volt_rail_get_voltage rpc"); + return status; + } + + /* Copy out the current voltage. */ + *pvoltage_uv = rpc_call.params.volt_rail_get_voltage.voltage_uv; + + return status; +} + +u32 nvgpu_volt_rail_get_voltage_gv10x(struct gk20a *g, + u8 volt_domain, u32 *pvoltage_uv) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct nv_pmu_rpc_struct_volt_volt_rail_get_voltage rpc; + u32 status = 0; + u8 rail_idx; + + rail_idx = volt_rail_volt_domain_convert_to_idx(g, volt_domain); + if ((rail_idx == CTRL_VOLT_RAIL_INDEX_INVALID) || + (!VOLT_RAIL_INDEX_IS_VALID(&g->perf_pmu.volt, rail_idx))) { + nvgpu_err(g, + "failed: volt_domain = %d, voltage rail table = %d.", + volt_domain, rail_idx); + return -EINVAL; + } + + memset(&rpc, 0, + sizeof(struct nv_pmu_rpc_struct_volt_volt_rail_get_voltage)); + rpc.rail_idx = rail_idx; + + PMU_RPC_EXECUTE_CPB(status, pmu, VOLT, VOLT_RAIL_GET_VOLTAGE, &rpc, 0); + if (status) { + nvgpu_err(g, "Failed to execute RPC status=0x%x", + status); + } + + *pvoltage_uv = rpc.voltage_uv; + + return status; +} + +static u32 volt_policy_set_voltage(struct gk20a *g, u8 client_id, + struct ctrl_perf_volt_rail_list *prail_list) +{ + struct nv_pmu_volt_rpc rpc_call = { 0 }; + struct obj_volt *pvolt = &g->perf_pmu.volt; + u32 status = 0; + u8 policy_idx = CTRL_VOLT_POLICY_INDEX_INVALID; + u8 i = 0; + + /* Sanity check input rail list. */ + for (i = 0; i < prail_list->num_rails; i++) { + if ((prail_list->rails[i].volt_domain == + CTRL_VOLT_DOMAIN_INVALID) || + (prail_list->rails[i].voltage_uv == + NV_PMU_VOLT_VALUE_0V_IN_UV)) { + nvgpu_err(g, "Invalid voltage domain or target"); + nvgpu_err(g, " client_id = %d, listEntry = %d", + client_id, i); + nvgpu_err(g, " volt_domain = %d, voltage_uv = %d uV.", + prail_list->rails[i].volt_domain, + prail_list->rails[i].voltage_uv); + status = -EINVAL; + goto exit; + } + } + + /* Convert the client ID to index. */ + if (client_id == CTRL_VOLT_POLICY_CLIENT_PERF_CORE_VF_SEQ) { + policy_idx = + pvolt->volt_policy_metadata.perf_core_vf_seq_policy_idx; + } + else { + status = -EINVAL; + goto exit; + } + + /* Set RPC parameters. */ + rpc_call.function = NV_PMU_VOLT_RPC_ID_VOLT_POLICY_SET_VOLTAGE; + rpc_call.params.volt_policy_voltage_data.policy_idx = policy_idx; + memcpy(&rpc_call.params.volt_policy_voltage_data.rail_list, prail_list, + (sizeof(struct ctrl_perf_volt_rail_list))); + + /* Execute the voltage change request via PMU RPC. */ + status = volt_pmu_rpc_execute(g, &rpc_call); + if (status) { + nvgpu_err(g, + "Error while executing VOLT_POLICY_SET_VOLTAGE RPC"); + } + +exit: + return status; +} + +static u32 volt_set_voltage_gv10x_rpc(struct gk20a *g, u8 client_id, + struct ctrl_volt_volt_rail_list_v1 *prail_list) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct nv_pmu_rpc_struct_volt_volt_set_voltage rpc; + int status = 0; + + memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_volt_volt_set_voltage)); + rpc.client_id = 0x1; + rpc.rail_list = *prail_list; + + PMU_RPC_EXECUTE_CPB(status, pmu, VOLT, VOLT_SET_VOLTAGE, &rpc, 0); + if (status) { + nvgpu_err(g, "Failed to execute RPC status=0x%x", + status); + } + + return status; +} + +u32 nvgpu_volt_set_voltage_gv10x(struct gk20a *g, u32 logic_voltage_uv, + u32 sram_voltage_uv) +{ + int status = 0; + struct ctrl_volt_volt_rail_list_v1 rail_list = { 0 }; + + rail_list.num_rails = RAIL_COUNT_GV; + rail_list.rails[0].rail_idx = + volt_rail_volt_domain_convert_to_idx(g, + CTRL_VOLT_DOMAIN_LOGIC); + rail_list.rails[0].voltage_uv = logic_voltage_uv; + rail_list.rails[0].voltage_min_noise_unaware_uv = logic_voltage_uv; + + status = volt_set_voltage_gv10x_rpc(g, + CTRL_VOLT_POLICY_CLIENT_PERF_CORE_VF_SEQ, &rail_list); + + return status; +} + +u32 nvgpu_volt_set_voltage_gp10x(struct gk20a *g, u32 logic_voltage_uv, + u32 sram_voltage_uv) +{ + int status = 0; + struct ctrl_perf_volt_rail_list rail_list = { 0 }; + + rail_list.num_rails = RAIL_COUNT_GP; + rail_list.rails[0].volt_domain = CTRL_VOLT_DOMAIN_LOGIC; + rail_list.rails[0].voltage_uv = logic_voltage_uv; + rail_list.rails[0].voltage_min_noise_unaware_uv = logic_voltage_uv; + rail_list.rails[1].volt_domain = CTRL_VOLT_DOMAIN_SRAM; + rail_list.rails[1].voltage_uv = sram_voltage_uv; + rail_list.rails[1].voltage_min_noise_unaware_uv = sram_voltage_uv; + + status = volt_policy_set_voltage(g, + CTRL_VOLT_POLICY_CLIENT_PERF_CORE_VF_SEQ, &rail_list); + + return status; +} + +u32 volt_set_voltage(struct gk20a *g, u32 logic_voltage_uv, u32 sram_voltage_uv) +{ + return g->ops.pmu_ver.volt.volt_set_voltage(g, + logic_voltage_uv, sram_voltage_uv); +} + +u32 volt_get_voltage(struct gk20a *g, u32 volt_domain, u32 *voltage_uv) +{ + return g->ops.pmu_ver.volt.volt_get_voltage(g, + volt_domain, voltage_uv); +} + +static int volt_policy_set_noiseaware_vmin(struct gk20a *g, + struct ctrl_volt_volt_rail_list *prail_list) +{ + struct nv_pmu_volt_rpc rpc_call = { 0 }; + u32 status = 0; + + /* Set RPC parameters. */ + rpc_call.function = NV_PMU_VOLT_RPC_ID_VOLT_RAIL_SET_NOISE_UNAWARE_VMIN; + rpc_call.params.volt_rail_set_noise_unaware_vmin.num_rails = + prail_list->num_rails; + memcpy(&rpc_call.params.volt_rail_set_noise_unaware_vmin.rail_list, + prail_list, (sizeof(struct ctrl_volt_volt_rail_list))); + + /* Execute the voltage change request via PMU RPC. */ + status = volt_pmu_rpc_execute(g, &rpc_call); + if (status) { + nvgpu_err(g, + "Error while executing VOLT_POLICY_SET_VOLTAGE RPC"); + return -EINVAL; + } + + return 0; +} + +int volt_set_noiseaware_vmin(struct gk20a *g, u32 logic_voltage_uv, + u32 sram_voltage_uv) +{ + int status = 0; + struct ctrl_volt_volt_rail_list rail_list = { 0 }; + + rail_list.num_rails = RAIL_COUNT_GP; + rail_list.rails[0].rail_idx = 0; + rail_list.rails[0].voltage_uv = logic_voltage_uv; + rail_list.rails[1].rail_idx = 1; + rail_list.rails[1].voltage_uv = sram_voltage_uv; + + status = volt_policy_set_noiseaware_vmin(g, &rail_list); + + return status; + +} + diff --git a/include/volt/volt_pmu.h b/include/volt/volt_pmu.h new file mode 100644 index 0000000..c9fb8bf --- /dev/null +++ b/include/volt/volt_pmu.h @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_VOLT_PMU_H +#define NVGPU_VOLT_PMU_H + +u32 volt_pmu_send_load_cmd_to_pmu(struct gk20a *g); +u32 volt_set_voltage(struct gk20a *g, u32 logic_voltage_uv, + u32 sram_voltage_uv); +u32 volt_get_voltage(struct gk20a *g, u32 volt_domain, u32 *voltage_uv); +int volt_set_noiseaware_vmin(struct gk20a *g, u32 logic_voltage_uv, + u32 sram_voltage_uv); + +u32 nvgpu_volt_set_voltage_gp10x(struct gk20a *g, u32 logic_voltage_uv, + u32 sram_voltage_uv); +u32 nvgpu_volt_rail_get_voltage_gp10x(struct gk20a *g, + u8 volt_domain, u32 *pvoltage_uv); +u32 nvgpu_volt_send_load_cmd_to_pmu_gp10x(struct gk20a *g); + +u32 nvgpu_volt_set_voltage_gv10x(struct gk20a *g, u32 logic_voltage_uv, + u32 sram_voltage_uv); +u32 nvgpu_volt_rail_get_voltage_gv10x(struct gk20a *g, + u8 volt_domain, u32 *pvoltage_uv); +u32 nvgpu_volt_send_load_cmd_to_pmu_gv10x(struct gk20a *g); + + +#endif /* NVGPU_VOLT_PMU_H */ diff --git a/include/volt/volt_policy.c b/include/volt/volt_policy.c new file mode 100644 index 0000000..cc60730 --- /dev/null +++ b/include/volt/volt_policy.c @@ -0,0 +1,513 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "gp106/bios_gp106.h" +#include "ctrl/ctrlvolt.h" + +#include "volt.h" + +static int volt_policy_pmu_data_init_super(struct gk20a *g, + struct boardobj *pboardobj, struct nv_pmu_boardobj *ppmudata) +{ + return boardobj_pmudatainit_super(g, pboardobj, ppmudata); +} + +static int construct_volt_policy(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pArgs) +{ + struct voltage_policy *pvolt_policy = NULL; + int status = 0; + + status = boardobj_construct_super(g, ppboardobj, size, pArgs); + if (status) { + return status; + } + + pvolt_policy = (struct voltage_policy *)*ppboardobj; + + pvolt_policy->super.pmudatainit = volt_policy_pmu_data_init_super; + + return status; +} + +static int construct_volt_policy_split_rail(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pArgs) +{ + struct voltage_policy_split_rail *ptmp_policy = + (struct voltage_policy_split_rail *)pArgs; + struct voltage_policy_split_rail *pvolt_policy = NULL; + int status = 0; + + status = construct_volt_policy(g, ppboardobj, size, pArgs); + if (status) { + return status; + } + + pvolt_policy = (struct voltage_policy_split_rail *)*ppboardobj; + + pvolt_policy->rail_idx_master = ptmp_policy->rail_idx_master; + pvolt_policy->rail_idx_slave = ptmp_policy->rail_idx_slave; + pvolt_policy->delta_min_vfe_equ_idx = + ptmp_policy->delta_min_vfe_equ_idx; + pvolt_policy->delta_max_vfe_equ_idx = + ptmp_policy->delta_max_vfe_equ_idx; + + return status; +} + +static int construct_volt_policy_single_rail(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pArgs) +{ + struct voltage_policy_single_rail *ptmp_policy = + (struct voltage_policy_single_rail *)pArgs; + struct voltage_policy_single_rail *pvolt_policy = NULL; + int status = 0; + + status = construct_volt_policy(g, ppboardobj, size, pArgs); + if (status) { + return status; + } + + pvolt_policy = (struct voltage_policy_single_rail *)*ppboardobj; + + pvolt_policy->rail_idx = ptmp_policy->rail_idx; + + return status; +} + +static int volt_policy_pmu_data_init_single_rail(struct gk20a *g, + struct boardobj *pboardobj, struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct voltage_policy_single_rail *ppolicy; + struct nv_pmu_volt_volt_policy_sr_boardobj_set *pset; + + status = volt_policy_pmu_data_init_super(g, pboardobj, ppmudata); + if (status) { + goto done; + } + + ppolicy = (struct voltage_policy_single_rail *)pboardobj; + pset = (struct nv_pmu_volt_volt_policy_sr_boardobj_set *) + ppmudata; + pset->rail_idx = ppolicy->rail_idx; + +done: + return status; +} + +static int volt_policy_pmu_data_init_sr_multi_step(struct gk20a *g, + struct boardobj *pboardobj, struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct voltage_policy_single_rail_multi_step *ppolicy; + struct nv_pmu_volt_volt_policy_sr_multi_step_boardobj_set *pset; + + status = volt_policy_pmu_data_init_single_rail(g, pboardobj, ppmudata); + if (status) { + goto done; + } + + ppolicy = (struct voltage_policy_single_rail_multi_step *)pboardobj; + pset = (struct nv_pmu_volt_volt_policy_sr_multi_step_boardobj_set *) + ppmudata; + + pset->ramp_up_step_size_uv = ppolicy->ramp_up_step_size_uv; + pset->ramp_down_step_size_uv = ppolicy->ramp_down_step_size_uv; + pset->inter_switch_delay_us = ppolicy->inter_switch_delay_us; + +done: + return status; +} + +static int volt_construct_volt_policy_single_rail_multi_step(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pargs) +{ + struct boardobj *pboardobj = NULL; + struct voltage_policy_single_rail_multi_step *p_volt_policy = NULL; + struct voltage_policy_single_rail_multi_step *tmp_policy = + (struct voltage_policy_single_rail_multi_step *)pargs; + int status = 0; + + status = construct_volt_policy_single_rail(g, ppboardobj, size, pargs); + if (status) { + return status; + } + + pboardobj = (*ppboardobj); + p_volt_policy = (struct voltage_policy_single_rail_multi_step *) + *ppboardobj; + + pboardobj->pmudatainit = volt_policy_pmu_data_init_sr_multi_step; + + p_volt_policy->ramp_up_step_size_uv = + tmp_policy->ramp_up_step_size_uv; + p_volt_policy->ramp_down_step_size_uv = + tmp_policy->ramp_down_step_size_uv; + p_volt_policy->inter_switch_delay_us = + tmp_policy->inter_switch_delay_us; + + return status; +} + +static int volt_policy_pmu_data_init_split_rail(struct gk20a *g, + struct boardobj *pboardobj, struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct voltage_policy_split_rail *ppolicy; + struct nv_pmu_volt_volt_policy_splt_r_boardobj_set *pset; + + status = volt_policy_pmu_data_init_super(g, pboardobj, ppmudata); + if (status) { + goto done; + } + + ppolicy = (struct voltage_policy_split_rail *)pboardobj; + pset = (struct nv_pmu_volt_volt_policy_splt_r_boardobj_set *) + ppmudata; + + pset->rail_idx_master = ppolicy->rail_idx_master; + pset->rail_idx_slave = ppolicy->rail_idx_slave; + pset->delta_min_vfe_equ_idx = ppolicy->delta_min_vfe_equ_idx; + pset->delta_max_vfe_equ_idx = ppolicy->delta_max_vfe_equ_idx; + pset->offset_delta_min_uv = ppolicy->offset_delta_min_uv; + pset->offset_delta_max_uv = ppolicy->offset_delta_max_uv; + +done: + return status; +} + +static int volt_construct_volt_policy_split_rail_single_step(struct gk20a *g, + struct boardobj **ppboardobj, u16 size, void *pargs) +{ + struct boardobj *pboardobj = NULL; + int status = 0; + + status = construct_volt_policy_split_rail(g, ppboardobj, size, pargs); + if (status) { + return status; + } + + pboardobj = (*ppboardobj); + pboardobj->pmudatainit = volt_policy_pmu_data_init_split_rail; + + return status; +} + +static struct voltage_policy *volt_volt_policy_construct(struct gk20a *g, void *pargs) +{ + struct boardobj *pboard_obj = NULL; + int status = 0; + + switch (BOARDOBJ_GET_TYPE(pargs)) { + case CTRL_VOLT_POLICY_TYPE_SR_SINGLE_STEP: + status = volt_construct_volt_policy_split_rail_single_step(g, + &pboard_obj, + sizeof(struct voltage_policy_split_rail_single_step), + pargs); + if (status) { + nvgpu_err(g, + "Could not allocate memory for voltage_policy"); + pboard_obj = NULL; + } + break; + case CTRL_VOLT_POLICY_TYPE_SINGLE_RAIL_MULTI_STEP: + status = volt_construct_volt_policy_single_rail_multi_step(g, + &pboard_obj, + sizeof(struct voltage_policy_single_rail_multi_step), + pargs); + if (status) { + nvgpu_err(g, + "Could not allocate memory for voltage_policy"); + pboard_obj = NULL; + } + break; + } + + return (struct voltage_policy *)pboard_obj; +} + +static u8 volt_policy_type_convert(u8 vbios_type) +{ + switch (vbios_type) { + case NV_VBIOS_VOLTAGE_POLICY_1X_ENTRY_TYPE_SINGLE_RAIL: + return CTRL_VOLT_POLICY_TYPE_SINGLE_RAIL; + + case NV_VBIOS_VOLTAGE_POLICY_1X_ENTRY_TYPE_SR_MULTI_STEP: + return CTRL_VOLT_POLICY_TYPE_SR_MULTI_STEP; + + case NV_VBIOS_VOLTAGE_POLICY_1X_ENTRY_TYPE_SR_SINGLE_STEP: + return CTRL_VOLT_POLICY_TYPE_SR_SINGLE_STEP; + case NV_VBIOS_VOLTAGE_POLICY_1X_ENTRY_TYPE_SINGLE_RAIL_MULTI_STEP: + return CTRL_VOLT_POLICY_TYPE_SINGLE_RAIL_MULTI_STEP; + } + + return CTRL_VOLT_POLICY_TYPE_INVALID; +} + +static int volt_get_volt_policy_table(struct gk20a *g, + struct voltage_policy_metadata *pvolt_policy_metadata) +{ + int status = 0; + u8 *voltage_policy_table_ptr = NULL; + struct voltage_policy *ppolicy = NULL; + struct vbios_voltage_policy_table_1x_header header = { 0 }; + struct vbios_voltage_policy_table_1x_entry entry = { 0 }; + u8 i; + u8 policy_type = 0; + u8 *entry_offset; + union policy_type { + struct boardobj board_obj; + struct voltage_policy volt_policy; + struct voltage_policy_split_rail split_rail; + struct voltage_policy_single_rail_multi_step single_rail_ms; + } policy_type_data; + + voltage_policy_table_ptr = + (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, VOLTAGE_POLICY_TABLE); + if (voltage_policy_table_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&header, voltage_policy_table_ptr, + sizeof(struct vbios_voltage_policy_table_1x_header)); + + /* Set Voltage Policy Table Index for Perf Core VF Sequence client. */ + pvolt_policy_metadata->perf_core_vf_seq_policy_idx = + (u8)header.perf_core_vf_seq_policy_idx; + + /* Read in the entries. */ + for (i = 0; i < header.num_table_entries; i++) { + entry_offset = (voltage_policy_table_ptr + header.header_size + + i * header.table_entry_size); + + memcpy(&entry, entry_offset, + sizeof(struct vbios_voltage_policy_table_1x_entry)); + + memset(&policy_type_data, 0x0, sizeof(policy_type_data)); + + policy_type = volt_policy_type_convert((u8)entry.type); + + switch (policy_type) { + case CTRL_VOLT_POLICY_TYPE_SR_SINGLE_STEP: + policy_type_data.split_rail.rail_idx_master = + (u8)BIOS_GET_FIELD(entry.param0, + NV_VBIOS_VPT_ENTRY_PARAM0_SR_VD_MASTER); + + policy_type_data.split_rail.rail_idx_slave = + (u8)BIOS_GET_FIELD(entry.param0, + NV_VBIOS_VPT_ENTRY_PARAM0_SR_VD_SLAVE); + + policy_type_data.split_rail.delta_min_vfe_equ_idx = + (u8)BIOS_GET_FIELD(entry.param0, + NV_VBIOS_VPT_ENTRY_PARAM0_SR_DELTA_SM_MIN); + + policy_type_data.split_rail.delta_max_vfe_equ_idx = + (u8)BIOS_GET_FIELD(entry.param0, + NV_VBIOS_VPT_ENTRY_PARAM0_SR_DELTA_SM_MAX); + break; + case CTRL_VOLT_POLICY_TYPE_SINGLE_RAIL_MULTI_STEP: + policy_type_data.single_rail_ms.inter_switch_delay_us = + (u16)BIOS_GET_FIELD(entry.param1, + NV_VBIOS_VPT_ENTRY_PARAM1_SR_SETTLE_TIME_INTERMEDIATE); + policy_type_data.single_rail_ms.ramp_up_step_size_uv = + (u32)BIOS_GET_FIELD(entry.param2, + NV_VBIOS_VPT_ENTRY_PARAM2_SR_RAMP_UP_STEP_SIZE_UV); + policy_type_data.single_rail_ms.ramp_down_step_size_uv = + (u32)BIOS_GET_FIELD(entry.param3, + NV_VBIOS_VPT_ENTRY_PARAM3_SR_RAMP_DOWN_STEP_SIZE_UV); + break; + } + + policy_type_data.board_obj.type = policy_type; + + ppolicy = volt_volt_policy_construct(g, + (void *)&policy_type_data); + if (ppolicy == NULL) { + nvgpu_err(g, + "Failure to construct VOLT_POLICY object."); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert( + &pvolt_policy_metadata->volt_policies.super, + (struct boardobj *)ppolicy, i); + if (status) { + nvgpu_err(g, + "could not add volt_policy for entry %d into boardobjgrp ", + i); + goto done; + } + } + +done: + return status; +} +static int _volt_policy_devgrp_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx) +{ + struct nv_pmu_volt_volt_policy_boardobj_grp_set *pgrp_set = + (struct nv_pmu_volt_volt_policy_boardobj_grp_set *) + pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0U) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + nvgpu_log_info(g, " Done"); + return 0; +} + +static int _volt_policy_devgrp_pmustatus_instget(struct gk20a *g, + void *pboardobjgrppmu, + struct nv_pmu_boardobj_query **ppboardobjpmustatus, u8 idx) +{ + struct nv_pmu_volt_volt_policy_boardobj_grp_get_status *p_get_status = + (struct nv_pmu_volt_volt_policy_boardobj_grp_get_status *) + pboardobjgrppmu; + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + p_get_status->hdr.data.super.obj_mask.super.data[0]) == 0U) { + return -EINVAL; + } + + *ppboardobjpmustatus = (struct nv_pmu_boardobj_query *) + &p_get_status->objects[idx].data.board_obj; + return 0; +} + +static int _volt_policy_grp_pmudatainit_super(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + struct nv_pmu_volt_volt_policy_boardobjgrp_set_header *pset = + (struct nv_pmu_volt_volt_policy_boardobjgrp_set_header *) + pboardobjgrppmu; + struct obj_volt *volt = (struct obj_volt *)pboardobjgrp; + int status = 0; + + status = boardobjgrp_pmudatainit_e32(g, pboardobjgrp, pboardobjgrppmu); + if (status) { + nvgpu_err(g, + "error updating pmu boardobjgrp for volt policy 0x%x", + status); + goto done; + } + pset->perf_core_vf_seq_policy_idx = + volt->volt_policy_metadata.perf_core_vf_seq_policy_idx; + +done: + return status; +} + +int volt_policy_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + pboardobjgrp = + &g->perf_pmu.volt.volt_policy_metadata.volt_policies.super; + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + nvgpu_log_info(g, "Done"); + return status; +} + +int volt_policy_sw_setup(struct gk20a *g) +{ + int status = 0; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + status = boardobjgrpconstruct_e32(g, + &g->perf_pmu.volt.volt_policy_metadata.volt_policies); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for volt rail, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = + &g->perf_pmu.volt.volt_policy_metadata.volt_policies.super; + + pboardobjgrp->pmudatainstget = _volt_policy_devgrp_pmudata_instget; + pboardobjgrp->pmustatusinstget = _volt_policy_devgrp_pmustatus_instget; + pboardobjgrp->pmudatainit = _volt_policy_grp_pmudatainit_super; + + /* Obtain Voltage Rail Table from VBIOS */ + status = volt_get_volt_policy_table(g, &g->perf_pmu.volt. + volt_policy_metadata); + if (status) { + goto done; + } + + /* Populate data for the VOLT_RAIL PMU interface */ + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, VOLT, VOLT_POLICY); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + volt, VOLT, volt_policy, VOLT_POLICY); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, + &g->perf_pmu.volt.volt_policy_metadata.volt_policies.super, + volt, VOLT, volt_policy, VOLT_POLICY); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} diff --git a/include/volt/volt_policy.h b/include/volt/volt_policy.h new file mode 100644 index 0000000..06f5aa3 --- /dev/null +++ b/include/volt/volt_policy.h @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVGPU_VOLT_POLICY_H +#define NVGPU_VOLT_POLICY_H + +#define VOLT_POLICY_INDEX_IS_VALID(pvolt, policy_idx) \ + (boardobjgrp_idxisvalid( \ + &((pvolt)->volt_policy_metadata.volt_policies.super), \ + (policy_idx))) + +/*! + * extends boardobj providing attributes common to all voltage_policies. + */ +struct voltage_policy { + struct boardobj super; +}; + +struct voltage_policy_metadata { + u8 perf_core_vf_seq_policy_idx; + struct boardobjgrp_e32 volt_policies; +}; + +/*! + * extends voltage_policy providing attributes + * common to all voltage_policy_split_rail. + */ +struct voltage_policy_split_rail { + struct voltage_policy super; + u8 rail_idx_master; + u8 rail_idx_slave; + u8 delta_min_vfe_equ_idx; + u8 delta_max_vfe_equ_idx; + s32 offset_delta_min_uv; + s32 offset_delta_max_uv; +}; + +struct voltage_policy_split_rail_single_step { + struct voltage_policy_split_rail super; +}; + +struct voltage_policy_split_rail_multi_step { + struct voltage_policy_split_rail super; + u16 inter_switch_delay_us; +}; + +struct voltage_policy_single_rail { + struct voltage_policy super; + u8 rail_idx; +}; + +struct voltage_policy_single_rail_multi_step { + struct voltage_policy_single_rail super; + u16 inter_switch_delay_us; + u32 ramp_up_step_size_uv; + u32 ramp_down_step_size_uv; +}; + +int volt_policy_sw_setup(struct gk20a *g); +int volt_policy_pmu_setup(struct gk20a *g); +#endif /* NVGPU_VOLT_POLICY_H */ diff --git a/include/volt/volt_rail.c b/include/volt/volt_rail.c new file mode 100644 index 0000000..caf297f --- /dev/null +++ b/include/volt/volt_rail.c @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "boardobj/boardobjgrp.h" +#include "boardobj/boardobjgrp_e32.h" +#include "gp106/bios_gp106.h" +#include "ctrl/ctrlvolt.h" + +#include "volt.h" + +u8 volt_rail_volt_domain_convert_to_idx(struct gk20a *g, u8 volt_domain) +{ + switch (g->perf_pmu.volt.volt_rail_metadata.volt_domain_hal) { + case CTRL_VOLT_DOMAIN_HAL_GP10X_SINGLE_RAIL: + switch (volt_domain) { + case CTRL_VOLT_DOMAIN_LOGIC: + return 0; + } + break; + case CTRL_VOLT_DOMAIN_HAL_GP10X_SPLIT_RAIL: + switch (volt_domain) { + case CTRL_VOLT_DOMAIN_LOGIC: + return 0; + case CTRL_VOLT_DOMAIN_SRAM: + return 1; + } + break; + } + + return CTRL_BOARDOBJ_IDX_INVALID; +} + +u32 volt_rail_volt_dev_register(struct gk20a *g, struct voltage_rail + *pvolt_rail, u8 volt_dev_idx, u8 operation_type) +{ + u32 status = 0; + + if (operation_type == CTRL_VOLT_DEVICE_OPERATION_TYPE_DEFAULT) { + if (pvolt_rail->volt_dev_idx_default == + CTRL_BOARDOBJ_IDX_INVALID) { + pvolt_rail->volt_dev_idx_default = volt_dev_idx; + } else { + status = -EINVAL; + goto exit; + } + } else if (operation_type == + CTRL_VOLT_VOLT_DEVICE_OPERATION_TYPE_IPC_VMIN) { + if (pvolt_rail->volt_dev_idx_ipc_vmin == + CTRL_BOARDOBJ_IDX_INVALID) { + pvolt_rail->volt_dev_idx_ipc_vmin = volt_dev_idx; + /* + * Exit on purpose as we do not want to register + * IPC_VMIN device against the rail to avoid + * setting current voltage instead of + * IPC Vmin voltage. + */ + goto exit; + } else { + status = -EINVAL; + goto exit; + } + } else { + goto exit; + } + + status = boardobjgrpmask_bitset(&pvolt_rail->volt_dev_mask.super, + volt_dev_idx); + +exit: + if (status) { + nvgpu_err(g, "Failed to register VOLTAGE_DEVICE"); + } + + return status; +} + +static u32 volt_rail_state_init(struct gk20a *g, + struct voltage_rail *pvolt_rail) +{ + u32 status = 0; + u32 i; + + pvolt_rail->volt_dev_idx_default = CTRL_BOARDOBJ_IDX_INVALID; + + for (i = 0; i < CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES; i++) { + pvolt_rail->volt_delta_uv[i] = (int)NV_PMU_VOLT_VALUE_0V_IN_UV; + g->perf_pmu.volt.volt_rail_metadata.ext_rel_delta_uv[i] = + NV_PMU_VOLT_VALUE_0V_IN_UV; + } + + pvolt_rail->volt_margin_limit_vfe_equ_mon_handle = + NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; + pvolt_rail->rel_limit_vfe_equ_mon_handle = + NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; + pvolt_rail->alt_rel_limit_vfe_equ_mon_handle = + NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; + pvolt_rail->ov_limit_vfe_equ_mon_handle = + NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; + + status = boardobjgrpmask_e32_init(&pvolt_rail->volt_dev_mask, NULL); + if (status) { + nvgpu_err(g, + "Failed to initialize BOARDOBJGRPMASK of VOLTAGE_DEVICEs"); + } + + return status; +} + +static int volt_rail_init_pmudata_super(struct gk20a *g, + struct boardobj *board_obj_ptr, struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct voltage_rail *prail; + struct nv_pmu_volt_volt_rail_boardobj_set *rail_pmu_data; + u32 i; + + nvgpu_log_info(g, " "); + + status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); + if (status) { + return status; + } + + prail = (struct voltage_rail *)board_obj_ptr; + rail_pmu_data = (struct nv_pmu_volt_volt_rail_boardobj_set *) + ppmudata; + + rail_pmu_data->rel_limit_vfe_equ_idx = prail->rel_limit_vfe_equ_idx; + rail_pmu_data->alt_rel_limit_vfe_equ_idx = + prail->alt_rel_limit_vfe_equ_idx; + rail_pmu_data->ov_limit_vfe_equ_idx = prail->ov_limit_vfe_equ_idx; + rail_pmu_data->vmin_limit_vfe_equ_idx = prail->vmin_limit_vfe_equ_idx; + rail_pmu_data->volt_margin_limit_vfe_equ_idx = + prail->volt_margin_limit_vfe_equ_idx; + rail_pmu_data->pwr_equ_idx = prail->pwr_equ_idx; + rail_pmu_data->volt_dev_idx_default = prail->volt_dev_idx_default; + rail_pmu_data->volt_scale_exp_pwr_equ_idx = + prail->volt_scale_exp_pwr_equ_idx; + rail_pmu_data->volt_dev_idx_ipc_vmin = prail->volt_dev_idx_ipc_vmin; + + for (i = 0; i < CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES; i++) { + rail_pmu_data->volt_delta_uv[i] = prail->volt_delta_uv[i] + + (int)g->perf_pmu.volt.volt_rail_metadata.ext_rel_delta_uv[i]; + } + + status = boardobjgrpmask_export(&prail->volt_dev_mask.super, + prail->volt_dev_mask.super.bitcount, + &rail_pmu_data->volt_dev_mask.super); + if (status) { + nvgpu_err(g, + "Failed to export BOARDOBJGRPMASK of VOLTAGE_DEVICEs"); + } + + nvgpu_log_info(g, "Done"); + + return status; +} + +static struct voltage_rail *construct_volt_rail(struct gk20a *g, void *pargs) +{ + struct boardobj *board_obj_ptr = NULL; + struct voltage_rail *ptemp_rail = (struct voltage_rail *)pargs; + struct voltage_rail *board_obj_volt_rail_ptr = NULL; + int status; + + nvgpu_log_info(g, " "); + status = boardobj_construct_super(g, &board_obj_ptr, + sizeof(struct voltage_rail), pargs); + if (status) { + return NULL; + } + + board_obj_volt_rail_ptr = (struct voltage_rail *)board_obj_ptr; + /* override super class interface */ + board_obj_ptr->pmudatainit = volt_rail_init_pmudata_super; + + board_obj_volt_rail_ptr->boot_voltage_uv = + ptemp_rail->boot_voltage_uv; + board_obj_volt_rail_ptr->rel_limit_vfe_equ_idx = + ptemp_rail->rel_limit_vfe_equ_idx; + board_obj_volt_rail_ptr->alt_rel_limit_vfe_equ_idx = + ptemp_rail->alt_rel_limit_vfe_equ_idx; + board_obj_volt_rail_ptr->ov_limit_vfe_equ_idx = + ptemp_rail->ov_limit_vfe_equ_idx; + board_obj_volt_rail_ptr->pwr_equ_idx = + ptemp_rail->pwr_equ_idx; + board_obj_volt_rail_ptr->boot_volt_vfe_equ_idx = + ptemp_rail->boot_volt_vfe_equ_idx; + board_obj_volt_rail_ptr->vmin_limit_vfe_equ_idx = + ptemp_rail->vmin_limit_vfe_equ_idx; + board_obj_volt_rail_ptr->volt_margin_limit_vfe_equ_idx = + ptemp_rail->volt_margin_limit_vfe_equ_idx; + board_obj_volt_rail_ptr->volt_scale_exp_pwr_equ_idx = + ptemp_rail->volt_scale_exp_pwr_equ_idx; + + nvgpu_log_info(g, "Done"); + + return (struct voltage_rail *)board_obj_ptr; +} + +u8 volt_rail_vbios_volt_domain_convert_to_internal(struct gk20a *g, + u8 vbios_volt_domain) +{ + switch (g->perf_pmu.volt.volt_rail_metadata.volt_domain_hal) { + case CTRL_VOLT_DOMAIN_HAL_GP10X_SINGLE_RAIL: + if (vbios_volt_domain == 0U) { + return CTRL_VOLT_DOMAIN_LOGIC; + } + break; + case CTRL_VOLT_DOMAIN_HAL_GP10X_SPLIT_RAIL: + switch (vbios_volt_domain) { + case 0: + return CTRL_VOLT_DOMAIN_LOGIC; + case 1: + return CTRL_VOLT_DOMAIN_SRAM; + } + break; + } + + return CTRL_VOLT_DOMAIN_INVALID; +} + +int volt_rail_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + nvgpu_log_info(g, " "); + + pboardobjgrp = &g->perf_pmu.volt.volt_rail_metadata.volt_rails.super; + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + nvgpu_log_info(g, "Done"); + return status; +} + +static int volt_get_volt_rail_table(struct gk20a *g, + struct voltage_rail_metadata *pvolt_rail_metadata) +{ + int status = 0; + u8 *volt_rail_table_ptr = NULL; + struct voltage_rail *prail = NULL; + struct vbios_voltage_rail_table_1x_header header = { 0 }; + struct vbios_voltage_rail_table_1x_entry entry = { 0 }; + u8 i; + u8 volt_domain; + u8 *entry_ptr; + union rail_type { + struct boardobj board_obj; + struct voltage_rail volt_rail; + } rail_type_data; + + volt_rail_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.perf_token, VOLTAGE_RAIL_TABLE); + if (volt_rail_table_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&header, volt_rail_table_ptr, + sizeof(struct vbios_voltage_rail_table_1x_header)); + + pvolt_rail_metadata->volt_domain_hal = (u8)header.volt_domain_hal; + + for (i = 0; i < header.num_table_entries; i++) { + entry_ptr = (volt_rail_table_ptr + header.header_size + + (i * header.table_entry_size)); + + memset(&rail_type_data, 0x0, sizeof(rail_type_data)); + + memcpy(&entry, entry_ptr, + sizeof(struct vbios_voltage_rail_table_1x_entry)); + + volt_domain = volt_rail_vbios_volt_domain_convert_to_internal(g, + i); + if (volt_domain == CTRL_VOLT_DOMAIN_INVALID) { + continue; + } + + rail_type_data.board_obj.type = volt_domain; + rail_type_data.volt_rail.boot_voltage_uv = + (u32)entry.boot_voltage_uv; + rail_type_data.volt_rail.rel_limit_vfe_equ_idx = + (u8)entry.rel_limit_vfe_equ_idx; + rail_type_data.volt_rail.alt_rel_limit_vfe_equ_idx = + (u8)entry.alt_rel_limit_vfe_equidx; + rail_type_data.volt_rail.ov_limit_vfe_equ_idx = + (u8)entry.ov_limit_vfe_equ_idx; + + if (header.table_entry_size >= + NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0C) { + rail_type_data.volt_rail.volt_scale_exp_pwr_equ_idx = + (u8)entry.volt_scale_exp_pwr_equ_idx; + } else { + rail_type_data.volt_rail.volt_scale_exp_pwr_equ_idx = + CTRL_BOARDOBJ_IDX_INVALID; + } + + if (header.table_entry_size >= + NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0B) { + rail_type_data.volt_rail.volt_margin_limit_vfe_equ_idx = + (u8)entry.volt_margin_limit_vfe_equ_idx; + } else { + rail_type_data.volt_rail.volt_margin_limit_vfe_equ_idx = + CTRL_BOARDOBJ_IDX_INVALID; + } + + if (header.table_entry_size >= + NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0A) { + rail_type_data.volt_rail.vmin_limit_vfe_equ_idx = + (u8)entry.vmin_limit_vfe_equ_idx; + } else { + rail_type_data.volt_rail.vmin_limit_vfe_equ_idx = + CTRL_BOARDOBJ_IDX_INVALID; + } + + if (header.table_entry_size >= + NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_09) { + rail_type_data.volt_rail.boot_volt_vfe_equ_idx = + (u8)entry.boot_volt_vfe_equ_idx; + } else { + rail_type_data.volt_rail.boot_volt_vfe_equ_idx = + CTRL_BOARDOBJ_IDX_INVALID; + } + + if (header.table_entry_size >= + NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_08) { + rail_type_data.volt_rail.pwr_equ_idx = + (u8)entry.pwr_equ_idx; + } else { + rail_type_data.volt_rail.pwr_equ_idx = + CTRL_PMGR_PWR_EQUATION_INDEX_INVALID; + } + + prail = construct_volt_rail(g, &rail_type_data); + + status = boardobjgrp_objinsert( + &pvolt_rail_metadata->volt_rails.super, + (struct boardobj *)prail, i); + } + +done: + return status; +} + +static int _volt_rail_devgrp_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, struct nv_pmu_boardobj + **ppboardobjpmudata, u8 idx) +{ + struct nv_pmu_volt_volt_rail_boardobj_grp_set *pgrp_set = + (struct nv_pmu_volt_volt_rail_boardobj_grp_set *) + pmuboardobjgrp; + + nvgpu_log_info(g, " "); + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0U) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.board_obj; + nvgpu_log_info(g, " Done"); + return 0; +} + +static int _volt_rail_devgrp_pmustatus_instget(struct gk20a *g, + void *pboardobjgrppmu, struct nv_pmu_boardobj_query + **ppboardobjpmustatus, u8 idx) +{ + struct nv_pmu_volt_volt_rail_boardobj_grp_get_status *pgrp_get_status = + (struct nv_pmu_volt_volt_rail_boardobj_grp_get_status *) + pboardobjgrppmu; + + /*check whether pmuboardobjgrp has a valid boardobj in index*/ + if (((u32)BIT(idx) & + pgrp_get_status->hdr.data.super.obj_mask.super.data[0]) == 0U) { + return -EINVAL; + } + + *ppboardobjpmustatus = (struct nv_pmu_boardobj_query *) + &pgrp_get_status->objects[idx].data.board_obj; + return 0; +} + +int volt_rail_sw_setup(struct gk20a *g) +{ + int status = 0; + struct boardobjgrp *pboardobjgrp = NULL; + struct voltage_rail *pvolt_rail; + u8 i; + + nvgpu_log_info(g, " "); + + status = boardobjgrpconstruct_e32(g, + &g->perf_pmu.volt.volt_rail_metadata.volt_rails); + if (status) { + nvgpu_err(g, + "error creating boardobjgrp for volt rail, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->perf_pmu.volt.volt_rail_metadata.volt_rails.super; + + pboardobjgrp->pmudatainstget = _volt_rail_devgrp_pmudata_instget; + pboardobjgrp->pmustatusinstget = _volt_rail_devgrp_pmustatus_instget; + + g->perf_pmu.volt.volt_rail_metadata.pct_delta = + NV_PMU_VOLT_VALUE_0V_IN_UV; + + /* Obtain Voltage Rail Table from VBIOS */ + status = volt_get_volt_rail_table(g, &g->perf_pmu.volt. + volt_rail_metadata); + if (status) { + goto done; + } + + /* Populate data for the VOLT_RAIL PMU interface */ + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, VOLT, VOLT_RAIL); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + volt, VOLT, volt_rail, VOLT_RAIL); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, + &g->perf_pmu.volt.volt_rail_metadata.volt_rails.super, + volt, VOLT, volt_rail, VOLT_RAIL); + if (status) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + /* update calibration to fuse */ + BOARDOBJGRP_FOR_EACH(&(g->perf_pmu.volt.volt_rail_metadata. + volt_rails.super), + struct voltage_rail *, pvolt_rail, i) { + status = volt_rail_state_init(g, pvolt_rail); + if (status) { + nvgpu_err(g, + "Failure while executing RAIL's state init railIdx = %d", + i); + goto done; + } + } + +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} diff --git a/include/volt/volt_rail.h b/include/volt/volt_rail.h new file mode 100644 index 0000000..72bb254 --- /dev/null +++ b/include/volt/volt_rail.h @@ -0,0 +1,90 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef NVGPU_VOLT_RAIL_H +#define NVGPU_VOLT_RAIL_H + +#include "boardobj/boardobj.h" +#include "boardobj/boardobjgrp.h" + +#define CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES 0x04U +#define CTRL_PMGR_PWR_EQUATION_INDEX_INVALID 0xFFU + +#define VOLT_GET_VOLT_RAIL(pvolt, rail_idx) \ + ((struct voltage_rail *)BOARDOBJGRP_OBJ_GET_BY_IDX( \ + &((pvolt)->volt_rail_metadata.volt_rails.super), (rail_idx))) + +#define VOLT_RAIL_INDEX_IS_VALID(pvolt, rail_idx) \ + (boardobjgrp_idxisvalid( \ + &((pvolt)->volt_rail_metadata.volt_rails.super), (rail_idx))) + +#define VOLT_RAIL_VOLT_3X_SUPPORTED(pvolt) \ + (!BOARDOBJGRP_IS_EMPTY(&((pvolt)->volt_rail_metadata.volt_rails.super))) + +/*! + * extends boardobj providing attributes common to all voltage_rails. + */ +struct voltage_rail { + struct boardobj super; + u32 boot_voltage_uv; + u8 rel_limit_vfe_equ_idx; + u8 alt_rel_limit_vfe_equ_idx; + u8 ov_limit_vfe_equ_idx; + u8 pwr_equ_idx; + u8 volt_scale_exp_pwr_equ_idx; + u8 volt_dev_idx_default; + u8 volt_dev_idx_ipc_vmin; + u8 boot_volt_vfe_equ_idx; + u8 vmin_limit_vfe_equ_idx; + u8 volt_margin_limit_vfe_equ_idx; + u32 volt_margin_limit_vfe_equ_mon_handle; + u32 rel_limit_vfe_equ_mon_handle; + u32 alt_rel_limit_vfe_equ_mon_handle; + u32 ov_limit_vfe_equ_mon_handle; + struct boardobjgrpmask_e32 volt_dev_mask; + s32 volt_delta_uv[CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES]; +}; + +/*! + * metadata of voltage rail functionality. + */ +struct voltage_rail_metadata { + u8 volt_domain_hal; + u8 pct_delta; + u32 ext_rel_delta_uv[CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES]; + u8 logic_rail_idx; + u8 sram_rail_idx; + struct boardobjgrp_e32 volt_rails; +}; + +u8 volt_rail_vbios_volt_domain_convert_to_internal + (struct gk20a *g, u8 vbios_volt_domain); + +u32 volt_rail_volt_dev_register(struct gk20a *g, struct voltage_rail + *pvolt_rail, u8 volt_dev_idx, u8 operation_type); + +u8 volt_rail_volt_domain_convert_to_idx(struct gk20a *g, u8 volt_domain); + +int volt_rail_sw_setup(struct gk20a *g); +int volt_rail_pmu_setup(struct gk20a *g); +#endif /* NVGPU_VOLT_RAIL_H */ -- cgit v1.2.2