1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 2017-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 * SPDX-License-Identifier: MIT 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24 #include "core/core.h" 25 #include "g_kern_mem_sys_nvoc.h" 26 #include "gpu/gpu.h" 27 #include "gpu/mem_sys/kern_mem_sys.h" 28 #include "gpu/bus/kern_bus.h" 29 #include "gpu/bif/kernel_bif.h" 30 31 #include "nvtypes.h" 32 #include "published/turing/tu102/dev_vm.h" 33 #include "published/turing/tu102/hwproject.h" 34 #include "published/turing/tu102/dev_fbpa.h" 35 #include "published/turing/tu102/dev_fb.h" 36 #include "published/turing/tu102/dev_ltc.h" 37 38 void 39 kmemsysWriteL2SysmemInvalidateReg_TU102 40 ( 41 OBJGPU *pGpu, 42 KernelMemorySystem *pKernelMemorySystem, 43 NvU32 value 44 ) 45 { 46 GPU_VREG_WR32(pGpu, NV_VIRTUAL_FUNCTION_PRIV_L2_SYSMEM_INVALIDATE, value); 47 } 48 49 NvU32 50 kmemsysReadL2SysmemInvalidateReg_TU102 51 ( 52 OBJGPU *pGpu, 53 KernelMemorySystem *pKernelMemorySystem 54 ) 55 { 56 return GPU_VREG_RD32(pGpu, NV_VIRTUAL_FUNCTION_PRIV_L2_SYSMEM_INVALIDATE); 57 } 58 59 void 60 kmemsysWriteL2PeermemInvalidateReg_TU102 61 ( 62 OBJGPU *pGpu, 63 KernelMemorySystem *pKernelMemorySystem, 64 NvU32 value 65 ) 66 { 67 GPU_VREG_WR32(pGpu, NV_VIRTUAL_FUNCTION_PRIV_L2_PEERMEM_INVALIDATE, value); 68 } 69 70 NvU32 71 kmemsysReadL2PeermemInvalidateReg_TU102 72 ( 73 OBJGPU *pGpu, 74 KernelMemorySystem *pKernelMemorySystem 75 ) 76 { 77 return GPU_VREG_RD32(pGpu, NV_VIRTUAL_FUNCTION_PRIV_L2_PEERMEM_INVALIDATE); 78 } 79 80 NvU32 81 kmemsysGetMaxFbpas_TU102 82 ( 83 OBJGPU *pGpu, 84 KernelMemorySystem *pKernelMemorySystem 85 ) 86 { 87 return NV_SCAL_LITTER_NUM_FBPAS; 88 } 89 90 NvU32 kmemsysGetEccDedCountSize_TU102 91 ( 92 OBJGPU *pGpu, 93 KernelMemorySystem *pKernelMemorySystem 94 ) 95 { 96 return NV_PFB_FBPA_0_ECC_DED_COUNT__SIZE_1; 97 } 98 99 NvU32 kmemsysGetEccDedCountRegAddr_TU102 100 ( 101 OBJGPU *pGpu, 102 KernelMemorySystem *pKernelMemorySystem, 103 NvU32 fbpa, 104 NvU32 subp 105 ) 106 { 107 return NV_PFB_FBPA_0_ECC_DED_COUNT(fbpa) + (subp * NV_FBPA_PRI_STRIDE); 108 } 109 110 /*! 111 * Utility function used to read registers and ignore PRI errors 112 */ 113 static NvU32 114 _kmemsysReadRegAndMaskPriError 115 ( 116 OBJGPU *pGpu, 117 NvU32 regAddr 118 ) 119 { 120 NvU32 regVal; 121 122 regVal = osGpuReadReg032(pGpu, regAddr); 123 if ((regVal & GPU_READ_PRI_ERROR_MASK) == GPU_READ_PRI_ERROR_CODE) 124 { 125 return 0; 126 } 127 128 return regVal; 129 } 130 131 void 132 kmemsysGetEccCounts_TU102 133 ( 134 OBJGPU *pGpu, 135 KernelMemorySystem *pKernelMemorySystem, 136 NvU32 *dramCount, 137 NvU32 *ltcCount 138 ) 139 { 140 NvU32 maxFbpas = kmemsysGetMaxFbpas_HAL(pGpu, pKernelMemorySystem); 141 NvU32 dedCountSize = kmemsysGetEccDedCountSize_HAL(pGpu, pKernelMemorySystem); 142 NvU32 fbpaDedCountRegAddr = 0; 143 NvU32 regVal; 144 145 if (dramCount == NULL || ltcCount == NULL) 146 { 147 return; 148 } 149 150 *dramCount = 0; 151 *ltcCount = 0; 152 153 for (NvU32 i = 0; i < maxFbpas; i++) 154 { 155 for (NvU32 j = 0; j < dedCountSize; j++) 156 { 157 // DRAM count read 158 fbpaDedCountRegAddr = kmemsysGetEccDedCountRegAddr_HAL(pGpu, pKernelMemorySystem, i, j); 159 *dramCount += _kmemsysReadRegAndMaskPriError(pGpu, fbpaDedCountRegAddr); 160 161 // LTC count read 162 regVal = _kmemsysReadRegAndMaskPriError(pGpu, NV_PLTCG_LTC0_LTS0_L2_CACHE_ECC_UNCORRECTED_ERR_COUNT + 163 (i * NV_LTC_PRI_STRIDE) + (j * NV_LTS_PRI_STRIDE)); 164 *ltcCount += DRF_VAL(_PLTCG_LTC0_LTS0, _L2_CACHE_ECC, _UNCORRECTED_ERR_COUNT_UNIQUE, regVal); 165 } 166 } 167 } 168 169 void 170 kmemsysClearEccCounts_TU102 171 ( 172 OBJGPU *pGpu, 173 KernelMemorySystem *pKernelMemorySystem 174 ) 175 { 176 NvU32 maxFbpas = kmemsysGetMaxFbpas_HAL(pGpu, pKernelMemorySystem); 177 NvU32 dedCountSize = kmemsysGetEccDedCountSize_HAL(pGpu, pKernelMemorySystem); 178 NvU32 fbpaDedCountRegAddr = 0; 179 180 for (NvU32 i = 0; i < maxFbpas; i++) 181 { 182 for (NvU32 j = 0; j < dedCountSize; j++) 183 { 184 fbpaDedCountRegAddr = kmemsysGetEccDedCountRegAddr_HAL(pGpu, pKernelMemorySystem, i, j); 185 osGpuWriteReg032(pGpu, fbpaDedCountRegAddr, 0); 186 osGpuWriteReg032(pGpu, NV_PLTCG_LTC0_LTS0_L2_CACHE_ECC_UNCORRECTED_ERR_COUNT + (i * NV_LTC_PRI_STRIDE) + (j * NV_LTS_PRI_STRIDE), 0); 187 } 188 } 189 } 190