1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2021-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 #define NVOC_KERNEL_NVLINK_H_PRIVATE_ACCESS_ALLOWED
25 
26 #include "os/os.h"
27 #include "kernel/gpu/nvlink/kernel_nvlink.h"
28 #include "kernel/gpu/nvlink/kernel_ioctrl.h"
29 #include "gpu/gpu.h"
30 
31 /*!
32  * Turing+ will use RXDET (receiver detect) feature to determine
33  * if a link is connected. Check bRxDetected field in nvlink_link
34  *
35  * @param[in] pGpu           OBJGPU ptr
36  * @param[in] pKernelNvlink  KernelNvlink ptr
37  *
38  * @return  returns NV_OK
39  */
40 NV_STATUS
knvlinkFilterBridgeLinks_TU102(OBJGPU * pGpu,KernelNvlink * pKernelNvlink)41 knvlinkFilterBridgeLinks_TU102
42 (
43     OBJGPU       *pGpu,
44     KernelNvlink *pKernelNvlink
45 )
46 {
47     NV_STATUS status = NV_OK;
48     NvU32     linkId;
49 
50     // All links from Turing+ are sensable by receiver detect
51     pKernelNvlink->bridgeSensableLinks = pKernelNvlink->discoveredLinks;
52 
53     // If connections are forced through chiplib, return enabled links
54     if (pKernelNvlink->bRegistryLinkOverride)
55     {
56         pKernelNvlink->connectedLinksMask = pKernelNvlink->enabledLinks;
57         pKernelNvlink->bridgedLinks       = pKernelNvlink->enabledLinks;
58 
59         NV_PRINTF(LEVEL_INFO,
60                   "Connections forced through chiplib. ConnectedLinksMask same as "
61                   "enabledLinks = 0x%x\n", pKernelNvlink->connectedLinksMask);
62 
63         goto knvlinkFilterBridgeLinks_end;
64     }
65 
66     // Mark the links as bridged if receiver detect has passed
67     FOR_EACH_INDEX_IN_MASK(32, linkId, pKernelNvlink->discoveredLinks)
68     {
69 #if defined(INCLUDE_NVLINK_LIB)
70 
71         // If the link has not been registered yet, continue
72         if (pKernelNvlink->nvlinkLinks[linkId].core_link == NULL)
73         {
74             // Link is not registered yet. Connectivity is absent
75             pKernelNvlink->connectedLinksMask &= ~NVBIT(linkId);
76             pKernelNvlink->bridgedLinks       &= ~NVBIT(linkId);
77 
78             NV_PRINTF(LEVEL_INFO,
79                       "GPU%d: Link%d not yet registered in core lib. Connectivity will be "
80                       "established after RXDET\n", pGpu->gpuInstance, linkId);
81             continue;
82         }
83 
84         if (pKernelNvlink->nvlinkLinks[linkId].core_link->bRxDetected)
85         {
86             pKernelNvlink->connectedLinksMask |= NVBIT(linkId);
87             pKernelNvlink->bridgedLinks       |= NVBIT(linkId);
88         }
89         else
90         {
91             pKernelNvlink->connectedLinksMask &= ~NVBIT(linkId);
92             pKernelNvlink->bridgedLinks       &= ~NVBIT(linkId);
93         }
94 #endif
95     }
96     FOR_EACH_INDEX_IN_MASK_END;
97 
98 knvlinkFilterBridgeLinks_end:
99 
100     // For GSP-CLIENTs, the link masks and vbios info need to synchronize with GSP
101     status = knvlinkSyncLinkMasksAndVbiosInfo(pGpu, pKernelNvlink);
102     if (status != NV_OK)
103     {
104         return status;
105     }
106 
107     return NV_OK;
108 }
109 
110 /*!
111  * @brief Return the mask of links that are connected
112  *
113  * @param[in] pGpu           OBJGPU ptr
114  * @param[in] pKernelNvlink  KernelNvlink ptr
115  */
116 NvU32
knvlinkGetConnectedLinksMask_TU102(OBJGPU * pGpu,KernelNvlink * pKernelNvlink)117 knvlinkGetConnectedLinksMask_TU102
118 (
119     OBJGPU       *pGpu,
120     KernelNvlink *pKernelNvlink
121 )
122 {
123     //
124     // On Turing, enabledLinks != connectedLinksMask
125     // This is because the connection cannot be sensed till receiver detect
126     // has reported whether or not the connection is present
127     //
128     return pKernelNvlink->connectedLinksMask;
129 }
130 
131 /*!
132  * @brief Is IOCTRL guaranteed to be powered up for D3
133  *
134  * @param[in] pGpu           OBJGPU ptr
135  * @param[in] pKernelNvlink  KernelNvlink ptr
136  *
137  * return NV_TRUE if IOCTRL guaranteed to be powered up
138  */
139 NvBool
knvlinkPoweredUpForD3_TU102(OBJGPU * pGpu,KernelNvlink * pKernelNvlink)140 knvlinkPoweredUpForD3_TU102
141 (
142     OBJGPU       *pGpu,
143     KernelNvlink *pKernelNvlink
144 )
145 {
146     //
147     // IOCTRL is guaranteed NOT to be reset if the D3 variant is
148     // RTD3 or FGC6 and if NVLink L2 is supported on the chip
149     //
150     if ((pGpu->getProperty(pGpu, PDB_PROP_GPU_RTD3_GC6_ACTIVE)  ||
151          pGpu->getProperty(pGpu, PDB_PROP_GPU_FAST_GC6_ACTIVE)) &&
152         pKernelNvlink->getProperty(pKernelNvlink, PDB_PROP_KNVLINK_L2_POWER_STATE_ENABLED))
153     {
154         //
155         // Bugs# 2274645, 2197144: On Turing, the NVLink clamps are broken. So,
156         // IOCTRL unit will see the reset signal when the GPU enters RTD3/FGC6.
157         //
158         if (!pKernelNvlink->getProperty(pKernelNvlink,
159                                         PDB_PROP_KNVLINK_BUG2274645_RESET_FOR_RTD3_FGC6))
160         {
161             return NV_TRUE;
162         }
163     }
164 
165     return NV_FALSE;
166 }
167