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