1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2020-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 "nvlink_export.h"
25 
26 #include "export_nvswitch.h"
27 #include "common_nvswitch.h"
28 #include "regkey_nvswitch.h"
29 #include "ls10/ls10.h"
30 #include "nvswitch/ls10/dev_nvldl_ip_addendum.h"
31 
32 #include "nvswitch/ls10/dev_nvldl_ip.h"
33 #include "nvswitch/ls10/dev_nvlipt_lnk_ip.h"
34 #include "nvswitch/ls10/dev_nvlphyctl_ip.h"
35 #include "nvswitch/ls10/dev_nvltlc_ip.h"
36 #include "nvswitch/ls10/dev_minion_ip.h"
37 #include "nvswitch/ls10/dev_minion_ip_addendum.h"
38 #include "nvswitch/ls10/dev_nvlipt_lnk_ip.h"
39 #include "nvswitch/ls10/dev_nvlipt_ip.h"
40 #include "nvswitch/ls10/dev_nport_ip.h"
41 #include "nvswitch/ls10/dev_minion_ip_addendum.h"
42 #include "ls10/minion_nvlink_defines_public_ls10.h"
43 
44 static void
45 _nvswitch_configure_reserved_throughput_counters
46 (
47     nvlink_link *link
48 )
49 {
50     nvswitch_device *device = link->dev->pDevInfo;
51     NvU32 linkNum = link->linkNumber;
52 
53     if (!NVSWITCH_IS_LINK_ENG_VALID_LS10(device, NVLTLC, link->linkNumber))
54     {
55         NVSWITCH_PRINT(device, INFO,
56                        "Invalid link, skipping NVLink throughput counter config for link %d\n",
57                        link->linkNumber);
58         return;
59     }
60 
61     //
62     // Counters 0 and 2 will be reserved for monitoring tools
63     // Counters 1 and 3 will be user-configurable and used by devtools
64     //
65 
66     // Rx0 config
67     NVSWITCH_LINK_WR32_IDX_LS10(device, linkNum, NVLTLC, _NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, 0,
68         DRF_DEF(_NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, _UNIT, _FLITS)           |
69         DRF_DEF(_NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, _FLITFILTER, _DATA)      |
70         DRF_DEF(_NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, _VCSETFILTERMODE, _INIT) |
71         DRF_DEF(_NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, _ENABLE, _ENABLE));
72 
73     // Tx0 config
74     NVSWITCH_LINK_WR32_IDX_LS10(device, linkNum, NVLTLC, _NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, 0,
75         DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _UNIT, _FLITS)           |
76         DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _FLITFILTER, _DATA)      |
77         DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _VCSETFILTERMODE, _INIT) |
78         DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _ENABLE, _ENABLE));
79 
80     // Rx2 config
81     NVSWITCH_LINK_WR32_IDX_LS10(device, linkNum, NVLTLC, _NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, 2,
82         DRF_DEF(_NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, _UNIT, _FLITS)           |
83         DRF_DEF(_NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, _FLITFILTER, _HEAD)      |
84         DRF_DEF(_NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, _FLITFILTER, _AE)        |
85         DRF_DEF(_NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, _FLITFILTER, _BE)        |
86         DRF_DEF(_NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, _FLITFILTER, _DATA)      |
87         DRF_DEF(_NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, _VCSETFILTERMODE, _INIT) |
88         DRF_DEF(_NVLTLC_RX_LNK, _DEBUG_TP_CNTR_CTRL_0, _ENABLE, _ENABLE));
89 
90     // Tx2 config
91     NVSWITCH_LINK_WR32_IDX_LS10(device, linkNum, NVLTLC, _NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, 2,
92         DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _UNIT, _FLITS)           |
93         DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _FLITFILTER, _HEAD)      |
94         DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _FLITFILTER, _AE)        |
95         DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _FLITFILTER, _BE)        |
96         DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _FLITFILTER, _DATA)      |
97         DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _VCSETFILTERMODE, _INIT) |
98         DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _ENABLE, _ENABLE));
99 }
100 
101 void
102 nvswitch_init_lpwr_regs_ls10
103 (
104     nvlink_link *link
105 )
106 {
107     nvswitch_device *device = link->dev->pDevInfo;
108     // NVSWITCH_BIOS_NVLINK_CONFIG *bios_config;
109     NvU32 linkNum = link->linkNumber;
110     NvU32 tempRegVal, lpEntryThreshold;
111     NvU8  softwareDesired;
112     NvBool bLpEnable;
113 
114     if (IS_RTLSIM(device) || IS_EMULATION(device) || IS_FMODEL(device))
115     {
116         return;
117     }
118 
119     if (device->regkeys.enable_pm == NV_SWITCH_REGKEY_ENABLE_PM_NO)
120     {
121         return;
122     }
123 
124     // bios_config = nvswitch_get_bios_nvlink_config(device);
125 
126     // IC Enter Threshold
127     if (device->regkeys.lp_threshold == NV_SWITCH_REGKEY_SET_LP_THRESHOLD_DEFAULT)
128     {
129         //
130         // Do nothing since VBIOS sets the default L1 threshold.
131         // Refer Bug 3797211 for more info.
132         //
133     }
134     else
135     {
136         lpEntryThreshold = device->regkeys.lp_threshold;
137     tempRegVal = 0;
138     tempRegVal = FLD_SET_DRF_NUM(_NVLIPT, _LNK_PWRM_L1_ENTER_THRESHOLD, _THRESHOLD, lpEntryThreshold, tempRegVal);
139     NVSWITCH_LINK_WR32_LS10(device, linkNum, NVLIPT_LNK, _NVLIPT_LNK, _PWRM_L1_ENTER_THRESHOLD, tempRegVal);
140     }
141 
142     //LP Entry Enable
143     bLpEnable = NV_TRUE;
144     softwareDesired = (bLpEnable) ? 0x1 : 0x0;
145 
146     tempRegVal = NVSWITCH_LINK_RD32_LS10(device, linkNum, NVLIPT_LNK, _NVLIPT_LNK, _PWRM_CTRL);
147     tempRegVal = FLD_SET_DRF_NUM(_NVLIPT, _LNK_PWRM_CTRL, _L1_SOFTWARE_DESIRED, softwareDesired, tempRegVal);
148     NVSWITCH_LINK_WR32_LS10(device, linkNum, NVLIPT_LNK, _NVLIPT_LNK, _PWRM_CTRL, tempRegVal);
149 }
150 
151 void
152 nvswitch_corelib_training_complete_ls10
153 (
154     nvlink_link *link
155 )
156 {
157     nvswitch_device *device = link->dev->pDevInfo;
158 
159     nvswitch_init_dlpl_interrupts(link);
160     _nvswitch_configure_reserved_throughput_counters(link);
161 
162     if (nvswitch_lib_notify_client_events(device,
163                 NVSWITCH_DEVICE_EVENT_PORT_UP) != NVL_SUCCESS)
164     {
165         NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify PORT_UP event\n",
166                      __FUNCTION__);
167     }
168     nvswitch_record_port_event(device, &(device->log_PORT_EVENTS), link->linkNumber, NVSWITCH_PORT_EVENT_TYPE_UP);
169 
170     return;
171 }
172 
173 NvlStatus
174 nvswitch_wait_for_tl_request_ready_ls10
175 (
176     nvlink_link *link
177 )
178 {
179     nvswitch_device *device = link->dev->pDevInfo;
180     NVSWITCH_MINION_ALI_DEBUG_REGISTERS params;
181     NvU32 nvldlErrCntl, nvldlTopLinkState, nvldlTopIntr, linkStateRequest;
182     NvlStatus status = nvswitch_wait_for_tl_request_ready_lr10(link);
183 
184 
185     if(status == -NVL_ERR_GENERIC)
186     {
187         linkStateRequest = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber,
188                 NVLIPT_LNK , _NVLIPT_LNK , _CTRL_LINK_STATE_REQUEST);
189         nvldlErrCntl  = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber,
190                 NVLDL, _NVLDL_RX_RXSLSM , _ERR_CNTL);
191         nvldlTopLinkState = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber,
192                 NVLDL, _NVLDL_TOP , _LINK_STATE);
193         nvldlTopIntr = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber,
194                 NVLDL, _NVLDL_TOP , _INTR);
195 
196         nvswitch_minion_get_ali_debug_registers_ls10(device, link, &params);
197 
198         NVSWITCH_PRINT(device, ERROR,
199             "%s: Ali Training failed on link #%d!:\n"
200                 "NV_NVLIPT_LNK_CTRL_LINK_STATE_REQUEST = 0x%x, "
201                 "NV_NVLDL_RXSLSM_ERR_CNTL = 0x%x,\n"
202                 "NV_NVLDL_TOP_LINK_STATE = 0x%x,\n"
203                 "NV_NVLDL_TOP_INTR = 0x%x,\n"
204                 "Minion DLSTAT MN00 = 0x%x\n"
205                 "Minion DLSTAT UC01 = 0x%x\n"
206                 "Minion DLSTAT UC01 = 0x%x\n",
207             __FUNCTION__, link->linkNumber,
208             linkStateRequest,
209             nvldlErrCntl, nvldlTopLinkState, nvldlTopIntr,
210             params.dlstatMn00, params.dlstatUc01, params.dlstatLinkIntr);
211 
212         NVSWITCH_PRINT_SXID(device, NVSWITCH_ERR_HW_NVLIPT_LNK_ALI_TRAINING_FAIL,
213                             "ALI Training failure. Info 0x%x%x%x%x%x%x%x\n",
214                             params.dlstatMn00, params.dlstatUc01, params.dlstatLinkIntr,
215                             nvldlTopLinkState, nvldlTopIntr, nvldlErrCntl, linkStateRequest);
216     }
217     return status;
218 }
219 
220 static NvlStatus
221 _nvswitch_init_dl_pll
222 (
223     nvlink_link *link
224 )
225 {
226     nvswitch_device *device = link->dev->pDevInfo;
227     NvlStatus status;
228 
229     status = nvswitch_minion_send_command(device, link->linkNumber, NV_MINION_NVLINK_DL_CMD_COMMAND_INITPLL, 0);
230     if (status != NVL_SUCCESS)
231     {
232         NVSWITCH_PRINT(device, ERROR,
233             "%s: INITPLL failed for link %d.\n",
234             __FUNCTION__, link->linkNumber);
235         NVSWITCH_ASSERT_INFO(NV_ERR_NVLINK_CLOCK_ERROR, NVBIT64(link->linkNumber), INITPLL_ERROR);
236         return NV_ERR_NVLINK_CLOCK_ERROR;
237     }
238 
239     status = nvswitch_minion_send_command(device, link->linkNumber, NV_MINION_NVLINK_DL_CMD_COMMAND_INITPHY, 0);
240     if (status != NVL_SUCCESS)
241     {
242         NVSWITCH_PRINT(device, ERROR,
243             "%s: INITPHY failed for link %d.\n",
244             __FUNCTION__, link->linkNumber);
245         NVSWITCH_ASSERT_INFO(NV_ERR_NVLINK_INIT_ERROR, NVBIT64(link->linkNumber), INITPHY_ERROR);
246         return NV_ERR_NVLINK_INIT_ERROR;
247     }
248 
249     return NVL_SUCCESS;
250 }
251 
252 NvlStatus
253 nvswitch_corelib_set_tx_mode_ls10
254 (
255     nvlink_link *link,
256     NvU64 mode,
257     NvU32 flags
258 )
259 {
260     nvswitch_device *device = link->dev->pDevInfo;
261     NvU32 val;
262     NvlStatus status = NVL_SUCCESS;
263 
264     if (!NVSWITCH_IS_LINK_ENG_VALID_LS10(device, NVLDL, link->linkNumber))
265     {
266         NVSWITCH_PRINT(device, ERROR,
267             "%s: link #%d invalid\n",
268             __FUNCTION__, link->linkNumber);
269         return -NVL_UNBOUND_DEVICE;
270     }
271 
272     // check if link is in reset
273     if (nvswitch_is_link_in_reset(device, link))
274     {
275         NVSWITCH_PRINT(device, ERROR,
276             "%s: link #%d is still in reset, cannot change sub-link state\n",
277             __FUNCTION__, link->linkNumber);
278         return -NVL_ERR_INVALID_STATE;
279     }
280 
281     val = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLDL, _NVLDL_TX, _SLSM_STATUS_TX);
282 
283     // Check if Sublink State Machine is ready to accept a sublink change request.
284     status = nvswitch_poll_sublink_state(device, link);
285     if (status != NVL_SUCCESS)
286     {
287         NVSWITCH_PRINT(device, ERROR,
288             "%s : SLSM not ready to accept a state change request for(%s):(%s).\n",
289             __FUNCTION__, device->name, link->linkName);
290         return status;
291     }
292 
293     switch (mode)
294     {
295         case NVLINK_SUBLINK_STATE_TX_COMMON_MODE:
296         {
297             val = _nvswitch_init_dl_pll(link);
298             if (val != NVL_SUCCESS)
299             {
300                 return val;
301             }
302 
303             break;
304         }
305 
306         default:
307         {
308            status = nvswitch_corelib_set_tx_mode_lr10(link, mode, flags);
309         }
310     }
311 
312     return status;
313 }
314 
315 NvU32
316 nvswitch_get_sublink_width_ls10
317 (
318     nvswitch_device *device,
319     NvU32            linkNumber
320 )
321 {
322     NvU32 data = NVSWITCH_LINK_RD32_LS10(device, linkNumber, NVLIPT,
323                                      _NVLIPT_COMMON, _TOPOLOGY_LOCAL_LINK_CONFIGURATION);
324     return DRF_VAL(_NVLIPT_COMMON, _TOPOLOGY_LOCAL_LINK_CONFIGURATION, _NUM_LANES_PER_LINK, data);
325 }
326 
327 void
328 nvswitch_corelib_get_uphy_load_ls10
329 (
330     nvlink_link *link,
331     NvBool *bUnlocked
332 )
333 {
334     *bUnlocked = NV_FALSE;
335 }
336 
337 NvlStatus
338 nvswitch_corelib_set_dl_link_mode_ls10
339 (
340     nvlink_link *link,
341     NvU64 mode,
342     NvU32 flags
343 )
344 {
345     nvswitch_device *device = link->dev->pDevInfo;
346     NvU32            val;
347     NvlStatus        status = NVL_SUCCESS;
348     NvBool           keepPolling;
349     NVSWITCH_TIMEOUT timeout;
350 
351     if (!NVSWITCH_IS_LINK_ENG_VALID_LS10(device, NVLDL, link->linkNumber))
352     {
353         NVSWITCH_PRINT(device, ERROR,
354             "%s: link #%d invalid\n",
355             __FUNCTION__, link->linkNumber);
356         return -NVL_UNBOUND_DEVICE;
357     }
358 
359     switch (mode)
360     {
361         case NVLINK_LINKSTATE_INITPHASE1:
362         {
363             // Apply appropriate SIMMODE settings
364             status = nvswitch_minion_set_sim_mode_ls10(device, link);
365             if (status != NVL_SUCCESS)
366             {
367                 return NV_ERR_NVLINK_CONFIGURATION_ERROR;
368             }
369 
370             // Apply appropriate SMF settings
371             status = nvswitch_minion_set_smf_settings_ls10(device, link);
372             if (status != NVL_SUCCESS)
373             {
374                 return NV_ERR_NVLINK_CONFIGURATION_ERROR;
375             }
376 
377             // Apply appropriate UPHY Table settings
378             status = nvswitch_minion_select_uphy_tables_ls10(device, link);
379             if (status != NVL_SUCCESS)
380             {
381                 return NV_ERR_NVLINK_CONFIGURATION_ERROR;
382             }
383 
384             // Before INITPHASE1, apply NEA setting
385             nvswitch_setup_link_loopback_mode(device, link->linkNumber);
386 
387             status = nvswitch_minion_send_command(device, link->linkNumber,
388                         NV_MINION_NVLINK_DL_CMD_COMMAND_INITPHASE1, 0);
389             if (status != NVL_SUCCESS)
390             {
391                 NVSWITCH_PRINT(device, ERROR,
392                     "%s : INITPHASE1 failed for link (%s):(%s).\n",
393                     __FUNCTION__, device->name, link->linkName);
394                 NVSWITCH_ASSERT_INFO(NV_ERR_NVLINK_CONFIGURATION_ERROR,
395                     NVBIT64(link->linkNumber), INITPHASE1_ERROR);
396                 return NV_ERR_NVLINK_CONFIGURATION_ERROR;
397             }
398 
399             break;
400         }
401 
402         case NVLINK_LINKSTATE_POST_INITOPTIMIZE:
403         {
404             // Poll for TRAINING_GOOD
405             status  = nvswitch_minion_get_initoptimize_status_ls10(device, link->linkNumber);
406             if (status != NVL_SUCCESS)
407             {
408                 NVSWITCH_PRINT(device, ERROR,
409                             "%s Error polling for INITOPTIMIZE TRAINING_GOOD. Link (%s):(%s)\n",
410                             __FUNCTION__, device->name, link->linkName);
411                 NVSWITCH_ASSERT_INFO(NV_ERR_NVLINK_TRAINING_ERROR, NVBIT64(link->linkNumber), INITOPTIMIZE_ERROR);
412                 return NV_ERR_NVLINK_TRAINING_ERROR;
413             }
414             break;
415         }
416 
417         case NVLINK_LINKSTATE_INITTL:
418         {
419              status = nvswitch_minion_send_command(device, link->linkNumber,
420                         NV_MINION_NVLINK_DL_CMD_COMMAND_INITTL, 0);
421             if (status != NVL_SUCCESS)
422             {
423                 NVSWITCH_PRINT(device, ERROR,
424                     "%s : INITTL failed for link (%s):(%s).\n",
425                     __FUNCTION__, device->name, link->linkName);
426                 NVSWITCH_ASSERT_INFO(NV_ERR_NVLINK_TRAINING_ERROR, NVBIT64(link->linkNumber), INITTL_ERROR);
427                 return NV_ERR_NVLINK_CONFIGURATION_ERROR;
428             }
429             break;
430         }
431         case NVLINK_LINKSTATE_INITOPTIMIZE:
432         {
433             return nvswitch_corelib_set_dl_link_mode_lr10(link, mode, flags);
434         }
435 
436         case NVLINK_LINKSTATE_INITPHASE5:
437         {
438             status = nvswitch_minion_send_command(device, link->linkNumber,
439                         NV_MINION_NVLINK_DL_CMD_COMMAND_INITPHASE5A, 0);
440             if (status != NVL_SUCCESS)
441             {
442                 NVSWITCH_PRINT(device, ERROR,
443                     "%s : INITPHASE5A failed to be called for link (%s):(%s).\n",
444                     __FUNCTION__, device->name, link->linkName);
445                 NVSWITCH_ASSERT_INFO(NV_ERR_NVLINK_TRAINING_ERROR, NVBIT64(link->linkNumber), INITPHASE5_ERROR);
446                 return NV_ERR_NVLINK_CONFIGURATION_ERROR;
447             }
448 
449             nvswitch_timeout_create(10 * NVSWITCH_INTERVAL_1MSEC_IN_NS, &timeout);
450 
451             do
452             {
453                 keepPolling = (nvswitch_timeout_check(&timeout)) ? NV_FALSE : NV_TRUE;
454 
455                 val =  NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLDL, _NVLPHYCTL_COMMON, _PSAVE_UCODE_CTRL_STS);
456                 if(FLD_TEST_DRF(_NVLPHYCTL_COMMON, _PSAVE_UCODE_CTRL_STS, _PMSTS, _PSL0, val))
457                 {
458                     break;
459                 }
460 
461                 if(!keepPolling)
462                 {
463                     NVSWITCH_PRINT(device, ERROR,
464                         "%s : Failed to poll for L0 on link (%s):(%s).\n",
465                         __FUNCTION__, device->name, link->linkName);
466                     NVSWITCH_ASSERT_INFO(NV_ERR_NVLINK_TRAINING_ERROR, NVBIT64(link->linkNumber), INITPHASE5_ERROR);
467                     return NV_ERR_NVLINK_CONFIGURATION_ERROR;
468 
469                 }
470             }
471             while (keepPolling);
472 
473             break;
474         }
475         default:
476         {
477             status = nvswitch_corelib_set_dl_link_mode_lr10(link, mode, flags);
478         }
479     }
480 
481     return status;
482 }
483 
484 NvlStatus
485 nvswitch_corelib_get_rx_detect_ls10
486 (
487     nvlink_link *link
488 )
489 {
490     NvlStatus status;
491     nvswitch_device *device = link->dev->pDevInfo;
492 
493     status = nvswitch_minion_get_rxdet_status_ls10(device, link->linkNumber);
494 
495     if (status != NVL_SUCCESS)
496     {
497         NVSWITCH_PRINT(device, WARN,
498             "%s: Get RXDET failed for link %d.\n",
499             __FUNCTION__, link->linkNumber);
500         return status;
501     }
502     return NVL_SUCCESS;
503 }
504 
505 void
506 nvswitch_reset_persistent_link_hw_state_ls10
507 (
508     nvswitch_device *device,
509     NvU32            linkNumber
510 )
511 {
512     NvU32 clocksMask = NVSWITCH_PER_LINK_CLOCK_SET(RXCLK)|NVSWITCH_PER_LINK_CLOCK_SET(TXCLK)|
513                             NVSWITCH_PER_LINK_CLOCK_SET(NCISOCCLK);
514     nvlink_link *link = nvswitch_get_link(device, linkNumber);
515     if ((link == NULL) || nvswitch_is_link_in_reset(device, link))
516     {
517         return;
518     }
519 
520     // clear DL error counters
521     (void)nvswitch_minion_send_command(device, linkNumber, NV_MINION_NVLINK_DL_CMD_COMMAND_DLSTAT_CLR_DLERRCNT, 0);
522 
523     // If TLC is not up then return
524 
525     if (!nvswitch_are_link_clocks_on_ls10(device, link, clocksMask))
526     {
527         return;
528     }
529 
530     // SETUPTC called to reset and setup throughput counters
531     (void)nvswitch_minion_send_command(device, linkNumber, NV_MINION_NVLINK_DL_CMD_COMMAND_SETUPTC , 0x4);
532 
533     // clear miscellaneous TLC counters and registers
534     (void)nvswitch_minion_send_command(device, linkNumber, NV_MINION_NVLINK_DL_CMD_COMMAND_CLR_TLC_MISC_REGS, 0);
535 
536 }
537 
538 NvlStatus
539 nvswitch_corelib_get_tl_link_mode_ls10
540 (
541     nvlink_link *link,
542     NvU64 *mode
543 )
544 {
545 #if defined(INCLUDE_NVLINK_LIB)
546 
547     nvswitch_device *device = link->dev->pDevInfo;
548     NvU32 link_state;
549     NvU32 val = 0;
550     NvlStatus status = NVL_SUCCESS;
551 
552     *mode = NVLINK_LINKSTATE_OFF;
553 
554     if (!NVSWITCH_IS_LINK_ENG_VALID_LS10(device, NVLDL, link->linkNumber))
555     {
556         NVSWITCH_PRINT(device, ERROR,
557             "%s: link #%d invalid\n",
558             __FUNCTION__, link->linkNumber);
559         return -NVL_UNBOUND_DEVICE;
560     }
561 
562     // check if links are in reset
563     if (nvswitch_is_link_in_reset(device, link))
564     {
565         *mode = NVLINK_LINKSTATE_RESET;
566         return NVL_SUCCESS;
567     }
568 
569     // Read state from NVLIPT HW
570     val = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLIPT_LNK,
571             _NVLIPT_LNK, _CTRL_LINK_STATE_STATUS);
572 
573     link_state = DRF_VAL(_NVLIPT_LNK, _CTRL_LINK_STATE_STATUS, _CURRENTLINKSTATE,
574             val);
575 
576     switch(link_state)
577     {
578         case NV_NVLIPT_LNK_CTRL_LINK_STATE_STATUS_CURRENTLINKSTATE_ACTIVE:
579 
580             // If using ALI, ensure that the request to active completed
581             if (link->dev->enableALI)
582             {
583                 status = nvswitch_wait_for_tl_request_ready_ls10(link);
584             }
585 
586             *mode = (status == NVL_SUCCESS) ? NVLINK_LINKSTATE_HS:NVLINK_LINKSTATE_OFF;
587             break;
588 
589         case NV_NVLIPT_LNK_CTRL_LINK_STATE_STATUS_CURRENTLINKSTATE_L2:
590             *mode = NVLINK_LINKSTATE_SLEEP;
591             break;
592 
593         case NV_NVLIPT_LNK_CTRL_LINK_STATE_STATUS_CURRENTLINKSTATE_CONTAIN:
594             *mode = NVLINK_LINKSTATE_CONTAIN;
595             break;
596 
597         case NV_NVLIPT_LNK_CTRL_LINK_STATE_STATUS_CURRENTLINKSTATE_ACTIVE_PENDING:
598             *mode = NVLINK_LINKSTATE_ACTIVE_PENDING;
599             break;
600 
601         default:
602             // Currently, only ACTIVE, L2 and CONTAIN states are supported
603             return NVL_ERR_INVALID_STATE;
604             break;
605     }
606 
607 #endif
608 
609     return status;
610 }
611 
612 NvBool
613 nvswitch_is_link_in_reset_ls10
614 (
615     nvswitch_device *device,
616     nvlink_link     *link
617 )
618 {
619     NvU32 clkStatus;
620     NvU32 resetRequestStatus;
621 
622     clkStatus = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber,
623             NVLIPT_LNK, _NVLIPT_LNK, _CTRL_CLK_CTRL);
624 
625     // Read the reset request register
626     resetRequestStatus = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber,
627                          NVLIPT_LNK, _NVLIPT_LNK, _RESET_RSTSEQ_LINK_RESET);
628 
629     //
630     // For link to be in reset either of 2 conditions should be true
631     // 1. On a cold-boot the RESET_RSTSEQ status should be ASSERTED reset
632     // 2. A link's current TL link state should be _RESET
633     // and all of the per link clocks, RXCLK, TXCLK and NCISOCCLK, should be off
634     //
635     if ((DRF_VAL(_NVLIPT_LNK, _RESET_RSTSEQ_LINK_RESET, _LINK_RESET_STATUS, resetRequestStatus) ==
636                NV_NVLIPT_LNK_RESET_RSTSEQ_LINK_RESET_LINK_RESET_STATUS_ASSERTED)     ||
637         (FLD_TEST_DRF(_NVLIPT_LNK, _CTRL_CLK_CTRL, _RXCLK_STS, _OFF, clkStatus)      &&
638         FLD_TEST_DRF(_NVLIPT_LNK, _CTRL_CLK_CTRL, _TXCLK_STS, _OFF, clkStatus)       &&
639         FLD_TEST_DRF(_NVLIPT_LNK, _CTRL_CLK_CTRL, _NCISOCCLK_STS, _OFF, clkStatus)))
640     {
641         return NV_TRUE;
642     }
643 
644     return NV_FALSE;
645 }
646 
647 void
648 nvswitch_init_buffer_ready_ls10
649 (
650     nvswitch_device *device,
651     nvlink_link *link,
652     NvBool bNportBufferReady
653 )
654 {
655     NvU32 val;
656     NvU32 linkNum = link->linkNumber;
657     NvU64 forcedConfigLinkMask;
658     NvU32 localLinkNumber = linkNum % NVSWITCH_LINKS_PER_MINION_LS10;
659     NvU32 regData;
660     regData = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber,
661             NVLTLC, _NVLTLC_TX_SYS, _CTRL_BUFFER_READY);
662 
663     // If buffer ready is set then return
664     if (FLD_TEST_DRF(_NVLTLC, _TX_SYS_CTRL_BUFFER_READY, _BUFFERRDY, _ENABLE, regData))
665     {
666         return;
667     }
668 
669     forcedConfigLinkMask = ((NvU64)device->regkeys.chiplib_forced_config_link_mask) +
670                 ((NvU64)device->regkeys.chiplib_forced_config_link_mask2 << 32);
671 
672     //
673     // Use legacy LS10 function to set buffer ready if
674     // running with forced config since MINION is not
675     // booted
676     //
677     if (forcedConfigLinkMask != 0)
678     {
679         nvswitch_init_buffer_ready_lr10(device, link, bNportBufferReady);
680     }
681 
682     if (FLD_TEST_DRF(_SWITCH_REGKEY, _SKIP_BUFFER_READY, _TLC, _NO,
683                      device->regkeys.skip_buffer_ready))
684     {
685         NVSWITCH_MINION_WR32_LS10(device,
686                 NVSWITCH_GET_LINK_ENG_INST(device, linkNum, MINION),
687                 _MINION, _NVLINK_DL_CMD_DATA(localLinkNumber),
688                 NV_MINION_NVLINK_DL_CMD_DATA_DATA_SET_BUFFER_READY_TX_AND_RX);
689 
690         nvswitch_minion_send_command(device, linkNum,
691             NV_MINION_NVLINK_DL_CMD_COMMAND_SET_BUFFER_READY, 0);
692     }
693 
694     if (bNportBufferReady &&
695         FLD_TEST_DRF(_SWITCH_REGKEY, _SKIP_BUFFER_READY, _NPORT, _NO,
696                      device->regkeys.skip_buffer_ready))
697     {
698         val = DRF_NUM(_NPORT, _CTRL_BUFFER_READY, _BUFFERRDY, 0x1);
699         NVSWITCH_LINK_WR32_LS10(device, linkNum, NPORT, _NPORT, _CTRL_BUFFER_READY, val);
700     }
701 }
702 
703 void
704 nvswitch_apply_recal_settings_ls10
705 (
706     nvswitch_device *device,
707     nvlink_link *link
708 )
709 {
710     NvU32 linkNumber = link->linkNumber;
711     NvU32 regVal;
712     NvU32 settingVal;
713 
714     // If no recal settings are set then return early
715     if (device->regkeys.link_recal_settings == NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS_NOP)
716     {
717         return;
718     }
719 
720     regVal = NVSWITCH_LINK_RD32_LS10(device, linkNumber, NVLIPT_LNK, _NVLIPT_LNK,
721                 _CTRL_SYSTEM_LINK_CHANNEL_CTRL2);
722 
723     settingVal = DRF_VAL(_SWITCH_REGKEY, _LINK_RECAL_SETTINGS, _MIN_RECAL_TIME_MANTISSA,
724                     device->regkeys.link_recal_settings);
725     if (settingVal != NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS_NOP)
726     {
727         regVal = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL2,
728                 _L1_MINIMUM_RECALIBRATION_TIME_MANTISSA, settingVal, regVal);
729     }
730 
731     settingVal = DRF_VAL(_SWITCH_REGKEY, _LINK_RECAL_SETTINGS, _MIN_RECAL_TIME_EXPONENT,
732                     device->regkeys.link_recal_settings);
733     if (settingVal != NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS_NOP)
734     {
735         regVal = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL2,
736                 _L1_MINIMUM_RECALIBRATION_TIME_EXPONENT, 0x2, regVal);
737     }
738 
739     settingVal = DRF_VAL(_SWITCH_REGKEY, _LINK_RECAL_SETTINGS, _MAX_RECAL_PERIOD_MANTISSA,
740                     device->regkeys.link_recal_settings);
741     if (settingVal != NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS_NOP)
742     {
743         regVal = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL2,
744                 _L1_MAXIMUM_RECALIBRATION_PERIOD_MANTISSA, 0xf, regVal);
745     }
746 
747     settingVal = DRF_VAL(_SWITCH_REGKEY, _LINK_RECAL_SETTINGS, _MAX_RECAL_PERIOD_EXPONENT,
748                     device->regkeys.link_recal_settings);
749     if (settingVal != NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS_NOP)
750     {
751         regVal = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL2,
752             _L1_MAXIMUM_RECALIBRATION_PERIOD_EXPONENT, 0x3, regVal);
753     }
754 
755     NVSWITCH_LINK_WR32_LS10(device, linkNumber, NVLIPT_LNK, _NVLIPT_LNK,
756             _CTRL_SYSTEM_LINK_CHANNEL_CTRL2, regVal);
757 
758     return;
759 }
760 
761 NvlStatus
762 nvswitch_corelib_get_dl_link_mode_ls10
763 (
764     nvlink_link *link,
765     NvU64 *mode
766 )
767 {
768     nvswitch_device *device = link->dev->pDevInfo;
769     NvU32 link_state;
770     NvU32 val = 0;
771     NvU64 tlLinkMode;
772 
773     *mode = NVLINK_LINKSTATE_OFF;
774 
775     if (!NVSWITCH_IS_LINK_ENG_VALID_LS10(device, NVLDL, link->linkNumber))
776     {
777         NVSWITCH_PRINT(device, ERROR,
778             "%s: link #%d invalid\n",
779             __FUNCTION__, link->linkNumber);
780         return -NVL_UNBOUND_DEVICE;
781     }
782 
783     // check if links are in reset
784     if (nvswitch_is_link_in_reset(device, link))
785     {
786         *mode = NVLINK_LINKSTATE_RESET;
787         return NVL_SUCCESS;
788     }
789 
790     val = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLDL, _NVLDL_TOP, _LINK_STATE);
791 
792     link_state = DRF_VAL(_NVLDL_TOP, _LINK_STATE, _STATE, val);
793 
794     switch (link_state)
795     {
796         case NV_NVLDL_TOP_LINK_STATE_STATE_INIT:
797             *mode = NVLINK_LINKSTATE_OFF;
798             break;
799         case NV_NVLDL_TOP_LINK_STATE_STATE_HWPCFG:
800         case NV_NVLDL_TOP_LINK_STATE_STATE_HWCFG:
801             *mode = NVLINK_LINKSTATE_DETECT;
802             break;
803         case NV_NVLDL_TOP_LINK_STATE_STATE_SWCFG:
804             *mode = NVLINK_LINKSTATE_SAFE;
805             break;
806         case NV_NVLDL_TOP_LINK_STATE_STATE_ACTIVE:
807             *mode = NVLINK_LINKSTATE_HS;
808             break;
809         case NV_NVLDL_TOP_LINK_STATE_STATE_SLEEP:
810             if (device->hal.nvswitch_corelib_get_tl_link_mode(link, &tlLinkMode) != NVL_SUCCESS ||
811                 tlLinkMode == NVLINK_LINKSTATE_SLEEP)
812             {
813                 *mode = NVLINK_LINKSTATE_SLEEP;
814             }
815             else
816             {
817                 *mode = NVLINK_LINKSTATE_HS;
818             }
819             break;
820         case NV_NVLDL_TOP_LINK_STATE_STATE_FAULT:
821             *mode = NVLINK_LINKSTATE_FAULT;
822             break;
823         case NV_NVLDL_TOP_LINK_STATE_STATE_RCVY_AC:
824         case NV_NVLDL_TOP_LINK_STATE_STATE_RCVY_RX:
825             *mode = NVLINK_LINKSTATE_RECOVERY;
826             break;
827         default:
828             *mode = NVLINK_LINKSTATE_OFF;
829             break;
830     }
831 
832     return NVL_SUCCESS;
833 }
834 
835 NvlStatus
836 nvswitch_corelib_get_rx_mode_ls10
837 (
838     nvlink_link *link,
839     NvU64 *mode,
840     NvU32 *subMode
841 )
842 {
843     nvswitch_device *device = link->dev->pDevInfo;
844     NvU32 rx_sublink_state;
845     NvU32 data = 0;
846     NvU64 dlLinkMode;
847     *mode = NVLINK_SUBLINK_STATE_RX_OFF;
848 
849     if (!NVSWITCH_IS_LINK_ENG_VALID_LS10(device, NVLDL, link->linkNumber))
850     {
851         NVSWITCH_PRINT(device, ERROR,
852             "%s: link #%d invalid\n",
853             __FUNCTION__, link->linkNumber);
854         return -NVL_UNBOUND_DEVICE;
855     }
856 
857     // check if link is in reset
858     if (nvswitch_is_link_in_reset(device, link))
859     {
860         *mode = NVLINK_SUBLINK_STATE_RX_OFF;
861         return NVL_SUCCESS;
862     }
863 
864     data = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLDL, _NVLDL_RX, _SLSM_STATUS_RX);
865 
866     rx_sublink_state = DRF_VAL(_NVLDL_RX, _SLSM_STATUS_RX, _PRIMARY_STATE, data);
867 
868     // Return NVLINK_SUBLINK_SUBSTATE_RX_STABLE for sub-state
869     *subMode = NVLINK_SUBLINK_SUBSTATE_RX_STABLE;
870 
871     switch (rx_sublink_state)
872     {
873         case NV_NVLDL_RX_SLSM_STATUS_RX_PRIMARY_STATE_HS:
874             *mode = NVLINK_SUBLINK_STATE_RX_HS;
875             break;
876 
877         case NV_NVLDL_RX_SLSM_STATUS_RX_PRIMARY_STATE_TRAIN:
878             *mode = NVLINK_SUBLINK_STATE_RX_TRAIN;
879             break;
880 
881         case NV_NVLDL_RX_SLSM_STATUS_RX_PRIMARY_STATE_SAFE:
882             *mode = NVLINK_SUBLINK_STATE_RX_SAFE;
883             break;
884         case NV_NVLDL_RX_SLSM_STATUS_RX_PRIMARY_STATE_OFF:
885             if (device->hal.nvswitch_corelib_get_dl_link_mode(link, &dlLinkMode) != NVL_SUCCESS ||
886                 dlLinkMode != NVLINK_LINKSTATE_HS)
887             {
888                 *mode = NVLINK_SUBLINK_STATE_RX_OFF;
889             }
890             else
891             {
892                 *mode = NVLINK_SUBLINK_STATE_RX_LOW_POWER;
893             }
894             break;
895 
896         default:
897             *mode = NVLINK_SUBLINK_STATE_RX_OFF;
898             break;
899     }
900 
901     return NVL_SUCCESS;
902 }
903 
904 NvlStatus
905 nvswitch_corelib_get_tx_mode_ls10
906 (
907     nvlink_link *link,
908     NvU64 *mode,
909     NvU32 *subMode
910 )
911 {
912     nvswitch_device *device = link->dev->pDevInfo;
913     NvU32 tx_sublink_state;
914     NvU64 dlLinkMode;
915     NvU32 data = 0;
916 
917     *mode = NVLINK_SUBLINK_STATE_TX_OFF;
918 
919     if (!NVSWITCH_IS_LINK_ENG_VALID_LS10(device, NVLDL, link->linkNumber))
920     {
921         NVSWITCH_PRINT(device, ERROR,
922             "%s: link #%d invalid\n",
923             __FUNCTION__, link->linkNumber);
924         return -NVL_UNBOUND_DEVICE;
925     }
926 
927     // check if link is in reset
928     if (nvswitch_is_link_in_reset(device, link))
929     {
930         *mode = NVLINK_SUBLINK_STATE_TX_OFF;
931         return NVL_SUCCESS;
932     }
933 
934     data = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLDL, _NVLDL_TX, _SLSM_STATUS_TX);
935 
936     tx_sublink_state = DRF_VAL(_NVLDL_TX, _SLSM_STATUS_TX, _PRIMARY_STATE, data);
937 
938     // Return NVLINK_SUBLINK_SUBSTATE_TX_STABLE for sub-state
939     *subMode = NVLINK_SUBLINK_SUBSTATE_TX_STABLE;
940 
941     switch (tx_sublink_state)
942     {
943         case NV_NVLDL_TX_SLSM_STATUS_TX_PRIMARY_STATE_HS:
944             *mode = NVLINK_SUBLINK_STATE_TX_HS;
945             break;
946 
947         case NV_NVLDL_TX_SLSM_STATUS_TX_PRIMARY_STATE_TRAIN:
948             *mode = NVLINK_SUBLINK_STATE_TX_TRAIN;
949             break;
950 
951         case NV_NVLDL_TX_SLSM_STATUS_TX_PRIMARY_STATE_SAFE:
952             *mode = NVLINK_SUBLINK_STATE_TX_SAFE;
953             break;
954 
955         case NV_NVLDL_TX_SLSM_STATUS_TX_PRIMARY_STATE_OFF:
956             if (device->hal.nvswitch_corelib_get_dl_link_mode(link, &dlLinkMode) != NVL_SUCCESS ||
957                 dlLinkMode != NVLINK_LINKSTATE_HS)
958             {
959                 *mode = NVLINK_SUBLINK_STATE_TX_OFF;
960             }
961             else
962             {
963                 *mode = NVLINK_SUBLINK_STATE_TX_LOW_POWER;
964             }
965             break;
966 
967         default:
968             *mode = NVLINK_SUBLINK_STATE_TX_OFF;
969             break;
970     }
971 
972     return NVL_SUCCESS;
973 }
974 
975 NvlStatus
976 nvswitch_launch_ALI_link_training_ls10
977 (
978     nvswitch_device *device,
979     nvlink_link     *link,
980     NvBool           bSync
981 )
982 {
983     NvlStatus status = NVL_SUCCESS;
984 
985     if ((link == NULL) ||
986         !NVSWITCH_IS_LINK_ENG_VALID_LS10(device, NVLIPT_LNK, link->linkNumber) ||
987         (link->linkNumber >= NVSWITCH_NVLINK_MAX_LINKS))
988     {
989         return -NVL_UNBOUND_DEVICE;
990     }
991 
992     if (!nvswitch_is_link_in_reset(device, link))
993     {
994         return NVL_SUCCESS;
995     }
996 
997     NVSWITCH_PRINT(device, INFO,
998             "%s: ALI launching on link: 0x%x\n",
999             __FUNCTION__, link->linkNumber);
1000 
1001     // Apply appropriate SIMMODE settings
1002     status = nvswitch_minion_set_sim_mode_ls10(device, link);
1003     if (status != NVL_SUCCESS)
1004     {
1005         return NV_ERR_NVLINK_CONFIGURATION_ERROR;
1006     }
1007 
1008     // Apply appropriate SMF settings
1009     status = nvswitch_minion_set_smf_settings_ls10(device, link);
1010     if (status != NVL_SUCCESS)
1011     {
1012         return NV_ERR_NVLINK_CONFIGURATION_ERROR;
1013     }
1014 
1015     // Apply appropriate UPHY Table settings
1016     status = nvswitch_minion_select_uphy_tables_ls10(device, link);
1017     if (status != NVL_SUCCESS)
1018     {
1019         return NV_ERR_NVLINK_CONFIGURATION_ERROR;
1020     }
1021 
1022     // Before INITPHASE1, apply NEA setting
1023     nvswitch_setup_link_loopback_mode(device, link->linkNumber);
1024 
1025     //
1026     // Request active, but don't block. FM will come back and check
1027     // active link status by blocking on this TLREQ's completion
1028     //
1029     status = nvswitch_request_tl_link_state_ls10(link,
1030             NV_NVLIPT_LNK_CTRL_LINK_STATE_REQUEST_REQUEST_ACTIVE,
1031             bSync);
1032 
1033     if (status != NVL_SUCCESS)
1034     {
1035         NVSWITCH_PRINT(device, ERROR,
1036             "%s: TL link state request to active for ALI failed for link: 0x%x\n",
1037             __FUNCTION__, link->linkNumber);
1038     }
1039 
1040     return status;
1041 }
1042 
1043 void
1044 nvswitch_store_topology_information_ls10
1045 (
1046     nvswitch_device *device,
1047     nvlink_link *link
1048 )
1049 {
1050     NvU32            tempval;
1051 
1052     link->bInitnegotiateConfigGood = NV_TRUE;
1053     link->remoteSid = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLIPT_LNK,
1054                                              _NVLIPT_LNK, _TOPOLOGY_REMOTE_CHIP_SID_HI);
1055     link->remoteSid = link->remoteSid << 32;
1056     link->remoteSid |= NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLIPT_LNK,
1057                                              _NVLIPT_LNK, _TOPOLOGY_REMOTE_CHIP_SID_LO);
1058 
1059     tempval = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLIPT_LNK, _NVLIPT_LNK, _TOPOLOGY_REMOTE_LINK_INFO);
1060     link->remoteLinkId = DRF_VAL(_NVLIPT_LNK, _TOPOLOGY_REMOTE_LINK_INFO, _LINK_NUMBER, tempval);
1061 
1062     link->localSid = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLIPT,
1063                                             _NVLIPT_COMMON, _TOPOLOGY_LOCAL_CHIP_SID_HI);
1064     link->localSid = link->localSid << 32;
1065     link->localSid |= NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLIPT,
1066                                              _NVLIPT_COMMON, _TOPOLOGY_LOCAL_CHIP_SID_LO);
1067 
1068     tempval = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLIPT_LNK,
1069                                              _NVLIPT_LNK, _TOPOLOGY_REMOTE_CHIP_TYPE);
1070 
1071     // Update the remoteDeviceType with NV2080_CTRL_NVLINK_DEVICE_INFO_DEVICE_TYPE values.
1072     switch(tempval)
1073     {
1074         case NV_NVLIPT_LNK_TOPOLOGY_REMOTE_CHIP_TYPE_TYPE_NV3P0AMP:
1075         case NV_NVLIPT_LNK_TOPOLOGY_REMOTE_CHIP_TYPE_TYPE_NV4P0HOP:
1076             link->remoteDeviceType = NVSWITCH_NVLINK_DEVICE_INFO_DEVICE_TYPE_GPU;
1077         break;
1078         case NV_NVLIPT_LNK_TOPOLOGY_REMOTE_CHIP_TYPE_TYPE_NV3P0LRK:
1079         case NV_NVLIPT_LNK_TOPOLOGY_REMOTE_CHIP_TYPE_TYPE_NV4P0LAG:
1080             link->remoteDeviceType = NVSWITCH_NVLINK_DEVICE_INFO_DEVICE_TYPE_SWITCH;
1081         break;
1082         default:
1083             link->remoteDeviceType = NVSWITCH_NVLINK_DEVICE_INFO_DEVICE_TYPE_NONE;
1084         break;
1085     }
1086 }
1087 
1088 void
1089 nvswitch_get_error_rate_threshold_ls10
1090 (
1091     nvlink_link *link
1092 )
1093 {
1094     nvswitch_device *device = link->dev->pDevInfo;
1095     NvU32 linkNumber = link->linkNumber;
1096     NvU32 crcRegVal;
1097 
1098     crcRegVal = NVSWITCH_LINK_RD32_LS10(device, linkNumber, NVLDL,
1099                                          _NVLDL_RX, _ERROR_RATE_CTRL);
1100 
1101     link->errorThreshold.thresholdMan = DRF_VAL(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_THRESHOLD_MAN,
1102                                                 crcRegVal);
1103     link->errorThreshold.thresholdExp = DRF_VAL(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_THRESHOLD_EXP,
1104                                                 crcRegVal);
1105     link->errorThreshold.timescaleMan = DRF_VAL(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_TIMESCALE_MAN,
1106                                                 crcRegVal);
1107     link->errorThreshold.timescaleExp = DRF_VAL(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_TIMESCALE_EXP,
1108                                                 crcRegVal);
1109 }
1110 
1111 void
1112 nvswitch_set_error_rate_threshold_ls10
1113 (
1114     nvlink_link *link,
1115     NvBool bSetDefault
1116 )
1117 {
1118     nvswitch_device *device = link->dev->pDevInfo;
1119     NvU32 linkNumber = link->linkNumber;
1120     NvU32 crcShortRegkeyVal = device->regkeys.crc_bit_error_rate_short;
1121     NvU32 crcRegVal;
1122 
1123     ct_assert(DRF_BASE(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_MAN)   ==
1124               DRF_BASE(NV_NVLDL_RX_ERROR_RATE_CTRL_SHORT_THRESHOLD_MAN));
1125     ct_assert(DRF_EXTENT(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_MAN) ==
1126               DRF_EXTENT(NV_NVLDL_RX_ERROR_RATE_CTRL_SHORT_THRESHOLD_MAN));
1127     ct_assert(DRF_BASE(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_EXP)   ==
1128               DRF_BASE(NV_NVLDL_RX_ERROR_RATE_CTRL_SHORT_THRESHOLD_EXP));
1129     ct_assert(DRF_EXTENT(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_EXP) ==
1130               DRF_EXTENT(NV_NVLDL_RX_ERROR_RATE_CTRL_SHORT_THRESHOLD_EXP));
1131     ct_assert(DRF_BASE(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_TIMESCALE_MAN)   ==
1132               DRF_BASE(NV_NVLDL_RX_ERROR_RATE_CTRL_SHORT_TIMESCALE_MAN));
1133     ct_assert(DRF_EXTENT(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_TIMESCALE_MAN) ==
1134               DRF_EXTENT(NV_NVLDL_RX_ERROR_RATE_CTRL_SHORT_TIMESCALE_MAN));
1135     ct_assert(DRF_BASE(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_TIMESCALE_EXP)   ==
1136               DRF_BASE(NV_NVLDL_RX_ERROR_RATE_CTRL_SHORT_TIMESCALE_EXP));
1137     ct_assert(DRF_EXTENT(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_TIMESCALE_EXP) ==
1138               DRF_EXTENT(NV_NVLDL_RX_ERROR_RATE_CTRL_SHORT_TIMESCALE_EXP));
1139 
1140     crcRegVal  = NVSWITCH_LINK_RD32_LS10(device, linkNumber, NVLDL,
1141                                          _NVLDL_RX, _ERROR_RATE_CTRL);
1142 
1143     //
1144     // Case 1: When a Regkey is provided. We use it to calculate crcRegVal.
1145     //
1146     // Case 2: When the bSetDefault variable is set to NV_FALSE. This can happen
1147     // when any client/application like NSCQ would provide specific values for
1148     // the error threshold. In this case we use those values to calculate crcRegVal.
1149     //
1150     // Case 3: In all other cases, we want the default values to be used, which are
1151     // provided in Bug 3365481.
1152     //
1153     if(crcShortRegkeyVal != NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_DEFAULT)
1154     {
1155         NvU32 shortRateMask;
1156         shortRateMask = DRF_SHIFTMASK(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_MAN)     |
1157                             DRF_SHIFTMASK(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_EXP) |
1158                             DRF_SHIFTMASK(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_TIMESCALE_MAN) |
1159                             DRF_SHIFTMASK(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_TIMESCALE_EXP);
1160 
1161         crcRegVal  &= ~shortRateMask;
1162         crcRegVal  |= crcShortRegkeyVal;
1163 
1164         link->errorThreshold.bUserConfig = NV_FALSE;
1165         link->errorThreshold.bInterruptTrigerred = NV_FALSE;
1166     }
1167     else if (!bSetDefault)
1168     {
1169         crcRegVal = FLD_SET_DRF_NUM(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_THRESHOLD_MAN,
1170                                      link->errorThreshold.thresholdMan,
1171                                      crcRegVal);
1172         crcRegVal = FLD_SET_DRF_NUM(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_THRESHOLD_EXP,
1173                                      link->errorThreshold.thresholdExp,
1174                                      crcRegVal);
1175         crcRegVal = FLD_SET_DRF_NUM(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_TIMESCALE_MAN,
1176                                      link->errorThreshold.timescaleMan,
1177                                      crcRegVal);
1178         crcRegVal = FLD_SET_DRF_NUM(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_TIMESCALE_EXP,
1179                                      link->errorThreshold.timescaleExp,
1180                                      crcRegVal);
1181     }
1182     else
1183     {
1184         //
1185         // Please refer to Bug 3365481 for details about the CRC_BIT_ERROR_RATE_SHORT
1186         // default values used below.
1187         //
1188         link->errorThreshold.thresholdMan =
1189             NV_NVLDL_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_MAN_DEFAULT;
1190         link->errorThreshold.thresholdExp =
1191             NV_NVLDL_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_EXP_DEFAULT;
1192         link->errorThreshold.timescaleMan =
1193             NV_NVLDL_CRC_BIT_ERROR_RATE_SHORT_TIMESCALE_MAN_DEFAULT;
1194         link->errorThreshold.timescaleExp =
1195             NV_NVLDL_CRC_BIT_ERROR_RATE_SHORT_TIMESCALE_EXP_DEFAULT;
1196         link->errorThreshold.bUserConfig = NV_FALSE;
1197         link->errorThreshold.bInterruptTrigerred = NV_FALSE;
1198 
1199         crcRegVal = FLD_SET_DRF_NUM(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_THRESHOLD_MAN,
1200                                      link->errorThreshold.thresholdMan,
1201                                      crcRegVal);
1202         crcRegVal = FLD_SET_DRF_NUM(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_THRESHOLD_EXP,
1203                                      link->errorThreshold.thresholdExp,
1204                                      crcRegVal);
1205         crcRegVal = FLD_SET_DRF_NUM(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_TIMESCALE_MAN,
1206                                      link->errorThreshold.timescaleMan,
1207                                      crcRegVal);
1208         crcRegVal = FLD_SET_DRF_NUM(_NVLDL_RX, _ERROR_RATE_CTRL, _SHORT_TIMESCALE_EXP,
1209                                      link->errorThreshold.timescaleExp,
1210                                      crcRegVal);
1211     }
1212 
1213     NVSWITCH_LINK_WR32_LS10(device, linkNumber, NVLDL,
1214                             _NVLDL_RX, _ERROR_RATE_CTRL, crcRegVal);
1215 }
1216 
1217 void
1218 nvswitch_configure_error_rate_threshold_interrupt_ls10
1219 (
1220     nvlink_link *link,
1221     NvBool bEnable
1222 )
1223 {
1224     nvswitch_device *device = link->dev->pDevInfo;
1225     NvU32 linkNumber = link->linkNumber;
1226     NvU32 intrRegVal;
1227     link->errorThreshold.bInterruptEn = bEnable;
1228 
1229     intrRegVal = NVSWITCH_LINK_RD32_LS10(device, linkNumber, NVLDL,
1230                                          _NVLDL_TOP, _INTR_NONSTALL_EN);
1231 
1232     if (bEnable)
1233     {
1234         link->errorThreshold.bInterruptTrigerred = NV_FALSE;
1235         intrRegVal = FLD_SET_DRF_NUM(_NVLDL_TOP, _INTR_NONSTALL_EN, _RX_SHORT_ERROR_RATE, 1,
1236                                      intrRegVal);
1237     }
1238     else
1239     {
1240         intrRegVal = FLD_SET_DRF_NUM(_NVLDL_TOP, _INTR_NONSTALL_EN, _RX_SHORT_ERROR_RATE, 0,
1241                                      intrRegVal);
1242     }
1243 
1244     NVSWITCH_LINK_WR32_LS10(device, linkNumber, NVLDL,
1245                             _NVLDL_TOP, _INTR_NONSTALL_EN, intrRegVal);
1246 }
1247 
1248 void
1249 nvswitch_init_dlpl_interrupts_ls10
1250 (
1251     nvlink_link *link
1252 )
1253 {
1254     nvswitch_device *device            = link->dev->pDevInfo;
1255     NvU32            linkNumber        = link->linkNumber;
1256 
1257     // W1C any stale state.
1258     NVSWITCH_LINK_WR32_LS10(device, linkNumber, NVLDL, _NVLDL_TOP, _INTR, 0xffffffff);
1259     NVSWITCH_LINK_WR32_LS10(device, linkNumber, NVLDL, _NVLDL_TOP, _INTR_SW2, 0xffffffff);
1260 
1261     // Set the interrupt bits
1262     nvswitch_set_dlpl_interrupts_ls10(link);
1263 
1264     // Setup error rate thresholds
1265     nvswitch_set_error_rate_threshold_ls10(link, NV_TRUE);
1266     nvswitch_configure_error_rate_threshold_interrupt_ls10(link, NV_TRUE);
1267 }
1268 
1269 void
1270 nvswitch_set_dlpl_interrupts_ls10
1271 (
1272     nvlink_link *link
1273 )
1274 {
1275     nvswitch_device *device            = link->dev->pDevInfo;
1276     NvU32            linkNumber        = link->linkNumber;
1277     // Stall tree routes to INTR_A which is connected to NVLIPT fatal tree
1278 
1279     NVSWITCH_LINK_WR32_LS10(device, linkNumber, NVLDL, _NVLDL_TOP, _INTR_STALL_EN,
1280               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _TX_REPLAY, _DISABLE)               |
1281               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _TX_RECOVERY_SHORT, _DISABLE)       |
1282               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _LTSSM_FAULT_UP, _ENABLE)           |
1283               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _LTSSM_FAULT_DOWN, _ENABLE)         |
1284               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _TX_FAULT_RAM, _ENABLE)             |
1285               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _TX_FAULT_INTERFACE, _ENABLE)       |
1286               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _TX_FAULT_SUBLINK_CHANGE, _DISABLE) |
1287               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _RX_FAULT_SUBLINK_CHANGE, _DISABLE) |
1288               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _RX_FAULT_DL_PROTOCOL, _ENABLE)     |
1289               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _RX_SHORT_ERROR_RATE, _DISABLE)     |
1290               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _RX_ILA_TRIGGER, _DISABLE)          |
1291               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _RX_CRC_COUNTER, _DISABLE)          |
1292               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _LTSSM_PROTOCOL, _DISABLE)          |
1293               DRF_DEF(_NVLDL_TOP, _INTR_STALL_EN, _MINION_REQUEST, _DISABLE));
1294 
1295     // NONSTALL -> NONFATAL
1296     NVSWITCH_LINK_WR32_LS10(device, linkNumber, NVLDL, _NVLDL_TOP, _INTR_NONSTALL_EN,
1297               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _TX_REPLAY, _DISABLE)               |
1298               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _TX_RECOVERY_SHORT, _DISABLE)       |
1299               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _LTSSM_FAULT_UP, _DISABLE)          |
1300               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _TX_FAULT_RAM, _DISABLE)            |
1301               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _TX_FAULT_INTERFACE, _DISABLE)      |
1302               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _TX_FAULT_SUBLINK_CHANGE, _DISABLE) |
1303               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _RX_FAULT_SUBLINK_CHANGE, _DISABLE) |
1304               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _RX_FAULT_DL_PROTOCOL, _DISABLE)    |
1305               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _RX_SHORT_ERROR_RATE, _DISABLE)     |
1306               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _RX_ILA_TRIGGER, _DISABLE)          |
1307               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _RX_CRC_COUNTER, _ENABLE)           |
1308               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _LTSSM_PROTOCOL, _DISABLE)          |
1309               DRF_DEF(_NVLDL_TOP, _INTR_NONSTALL_EN, _MINION_REQUEST, _DISABLE));
1310 }
1311 
1312 static NvU32
1313 _nvswitch_get_nvlink_linerate_ls10
1314 (
1315     nvswitch_device *device,
1316     NvU32            val
1317 )
1318 {
1319     NvU32  lineRate = 0;
1320     switch (val)
1321     {
1322         case NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_100_00000G:
1323             lineRate = NV_NVLIPT_LNK_CTRL_SYSTEM_LINK_CLK_CTRL_LINE_RATE_100_00000_GBPS;
1324             break;
1325         case NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_106_25000G:
1326             lineRate = NV_NVLIPT_LNK_CTRL_SYSTEM_LINK_CLK_CTRL_LINE_RATE_106_25000_GBPS;
1327             break;
1328         default:
1329             NVSWITCH_PRINT(device, SETUP, "%s:ERROR LINE_RATE = 0x%x requested by regkey\n",
1330                        __FUNCTION__, lineRate);
1331             lineRate = NV_NVLIPT_LNK_CTRL_SYSTEM_LINK_CLK_CTRL_LINE_RATE_ILLEGAL_LINE_RATE;
1332     }
1333     return lineRate;
1334 }
1335 
1336 void
1337 nvswitch_setup_link_system_registers_ls10
1338 (
1339     nvswitch_device *device,
1340     nvlink_link *link
1341 )
1342 {
1343     NvU32 regval, fldval;
1344     NvU32 lineRate = 0;
1345 
1346     // LINE_RATE SYSTEM register
1347     if (device->regkeys.nvlink_speed_control != NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_DEFAULT)
1348     {
1349         regval   = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLIPT_LNK,
1350                                            _NVLIPT_LNK_CTRL_SYSTEM_LINK, _CLK_CTRL);
1351         lineRate = _nvswitch_get_nvlink_linerate_ls10(device, device->regkeys.nvlink_speed_control);
1352         regval   = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CLK_CTRL,
1353                                     _LINE_RATE, lineRate, regval);
1354         NVSWITCH_PRINT(device, SETUP, "%s: LINE_RATE = 0x%x requested by regkey\n",
1355                        __FUNCTION__, lineRate);
1356         NVSWITCH_LINK_WR32_LS10(device, link->linkNumber, NVLIPT_LNK,
1357                             _NVLIPT_LNK_CTRL_SYSTEM_LINK, _CLK_CTRL, regval);
1358     }
1359 
1360     // TXTRAIN SYSTEM register
1361     regval = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLIPT_LNK,
1362                                      _NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL);
1363 
1364     fldval = DRF_VAL(_SWITCH_REGKEY, _TXTRAIN_CONTROL, _FOM_FORMAT,
1365                      device->regkeys.txtrain_control);
1366     if (fldval != NV_SWITCH_REGKEY_TXTRAIN_CONTROL_FOM_FORMAT_NOP)
1367     {
1368         NVSWITCH_PRINT(device, SETUP, "%s: FOM_FORMAT = 0x%x requested by regkey\n",
1369                        __FUNCTION__, fldval);
1370         regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
1371                                  _TXTRAIN_FOM_FORMAT, fldval, regval);
1372     }
1373 
1374     fldval = DRF_VAL(_SWITCH_REGKEY, _TXTRAIN_CONTROL, _OPTIMIZATION_ALGORITHM,
1375                      device->regkeys.txtrain_control);
1376     if (fldval != NV_SWITCH_REGKEY_TXTRAIN_CONTROL_OPTIMIZATION_ALGORITHM_NOP)
1377     {
1378         NVSWITCH_PRINT(device, SETUP, "%s: OPTIMIZATION_ALGORITHM = 0x%x requested by regkey\n",
1379                        __FUNCTION__, fldval);
1380         regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
1381                                  _TXTRAIN_OPTIMIZATION_ALGORITHM, fldval, regval);
1382     }
1383 
1384     fldval = DRF_VAL(_SWITCH_REGKEY, _TXTRAIN_CONTROL, _ADJUSTMENT_ALGORITHM,
1385                      device->regkeys.txtrain_control);
1386     if (fldval != NV_SWITCH_REGKEY_TXTRAIN_CONTROL_ADJUSTMENT_ALGORITHM_NOP)
1387     {
1388         NVSWITCH_PRINT(device, SETUP, "%s: ADJUSTMENT_ALGORITHM = 0x%x requested by regkey\n",
1389                        __FUNCTION__, fldval);
1390         regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
1391                                  _TXTRAIN_ADJUSTMENT_ALGORITHM, fldval, regval);
1392     }
1393 
1394     fldval = DRF_VAL(_SWITCH_REGKEY, _TXTRAIN_CONTROL, _MINIMUM_TRAIN_TIME_MANTISSA,
1395                      device->regkeys.txtrain_control);
1396     if (fldval != NV_SWITCH_REGKEY_TXTRAIN_CONTROL_MINIMUM_TRAIN_TIME_MANTISSA_NOP)
1397     {
1398         NVSWITCH_PRINT(device, SETUP, "%s: MINIMUM_TRAIN_TIME_MANTISSA = 0x%x requested by regkey\n",
1399                        __FUNCTION__, fldval);
1400         regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
1401                                  _TXTRAIN_MINIMUM_TRAIN_TIME_MANTISSA, fldval, regval);
1402     }
1403 
1404     fldval = DRF_VAL(_SWITCH_REGKEY, _TXTRAIN_CONTROL, _MINIMUM_TRAIN_TIME_EXPONENT,
1405                      device->regkeys.txtrain_control);
1406     if (fldval != NV_SWITCH_REGKEY_TXTRAIN_CONTROL_MINIMUM_TRAIN_TIME_EXPONENT_NOP)
1407     {
1408         NVSWITCH_PRINT(device, SETUP, "%s: MINIMUM_TRAIN_TIME_EXPONENT = 0x%x requested by regkey\n",
1409                        __FUNCTION__, fldval);
1410         regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
1411                                  _TXTRAIN_MINIMUM_TRAIN_TIME_EXPONENT, fldval, regval);
1412     }
1413 
1414     NVSWITCH_LINK_WR32_LS10(device, link->linkNumber, NVLIPT_LNK,
1415                             _NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL, regval);
1416 
1417     nvswitch_apply_recal_settings(device, link);
1418 
1419     return;
1420 }
1421 
1422 void
1423 nvswitch_load_link_disable_settings_ls10
1424 (
1425     nvswitch_device *device,
1426     nvlink_link *link
1427 )
1428 {
1429     NvU32 regVal;
1430 
1431     // Read state from NVLIPT HW
1432     regVal = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber, NVLIPT_LNK,
1433              _NVLIPT_LNK, _CTRL_LINK_STATE_STATUS);
1434 
1435     if (FLD_TEST_DRF(_NVLIPT_LNK, _CTRL_LINK_STATE_STATUS, _CURRENTLINKSTATE, _DISABLE, regVal))
1436     {
1437 
1438         // Set link to invalid and unregister from corelib
1439         device->link[link->linkNumber].valid = NV_FALSE;
1440         nvlink_lib_unregister_link(link);
1441         nvswitch_destroy_link(link);
1442     }
1443 
1444     return;
1445 }
1446 
1447 void
1448 nvswitch_execute_unilateral_link_shutdown_ls10
1449 (
1450     nvlink_link *link
1451 )
1452 {
1453     nvswitch_device *device = link->dev->pDevInfo;
1454     NvlStatus status = NVL_SUCCESS;
1455     NvU32 retry_count = 3;
1456     NvU32 link_state_request;
1457     NvU32 link_state;
1458     NvU32 stat_data = 0;
1459     NvU32 link_intr_subcode = MINION_OK;
1460 
1461     if (!NVSWITCH_IS_LINK_ENG_VALID_LS10(device, NVLDL, link->linkNumber))
1462     {
1463         NVSWITCH_PRINT(device, ERROR,
1464             "%s: link #%d invalid\n",
1465             __FUNCTION__, link->linkNumber);
1466         return;
1467     }
1468 
1469     do
1470     {
1471         //
1472         // Perform unilateral shutdown
1473         // This follows "Unilateral variant" from NVLink 4.x Shutdown
1474         //
1475         // Status is explicitly ignored here since we are required to soldier-on
1476         // in this scenario
1477         //
1478         status = nvswitch_request_tl_link_state_ls10(link,
1479                    NV_NVLIPT_LNK_CTRL_LINK_STATE_REQUEST_REQUEST_SHUTDOWN, NV_TRUE);
1480 
1481         if (status == NVL_SUCCESS)
1482         {
1483             return;
1484         }
1485 
1486 
1487         link_state_request = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber,
1488                                 NVLIPT_LNK , _NVLIPT_LNK , _CTRL_LINK_STATE_REQUEST);
1489 
1490         link_state = DRF_VAL(_NVLIPT_LNK, _CTRL_LINK_STATE_REQUEST, _STATUS, link_state_request);
1491 
1492         if (nvswitch_minion_get_dl_status(device, link->linkNumber,
1493                           NV_NVLSTAT_MN00, 0, &stat_data) == NVL_SUCCESS)
1494         {
1495             link_intr_subcode = DRF_VAL(_NVLSTAT, _MN00, _LINK_INTR_SUBCODE, stat_data);
1496 
1497             if ((link_state == NV_NVLIPT_LNK_CTRL_LINK_STATE_REQUEST_STATUS_MINION_REQUEST_FAIL) &&
1498                 (link_intr_subcode == MINION_ALARM_BUSY))
1499             {
1500                 NVSWITCH_PRINT(device, INFO,
1501                                "%s: Retrying shutdown due to Minion DLCMD Fault subcode = 0x%x\n",
1502                                __FUNCTION__, link_intr_subcode);
1503                 //
1504                 // We retry the shutdown sequence 3 times when we see a MINION_REQUEST_FAIL
1505                 // or MINION_ALARM_BUSY
1506                 //
1507                 retry_count--;
1508             }
1509             else
1510             {
1511                 break;
1512             }
1513         }
1514         else
1515         {
1516             // Querying MINION for link_intr_subcode failed so retry
1517             retry_count--;
1518         }
1519 
1520 
1521     } while (retry_count);
1522 
1523     NVSWITCH_PRINT(device, ERROR,
1524         "%s: NvLink Shutdown has failed for link %d\n",
1525         __FUNCTION__, link->linkNumber);
1526 
1527     return;
1528 }
1529 
1530 NvlStatus
1531 nvswitch_reset_and_train_link_ls10
1532 (
1533     nvswitch_device *device,
1534     nvlink_link     *link
1535 )
1536 {
1537     NvlStatus  status      = NVL_SUCCESS;
1538     NvU32      retry_count = 3;
1539     NvU32      link_state_request;
1540     NvU32      link_state;
1541     NvU32      stat_data;
1542     NvU32      link_intr_subcode = MINION_OK;
1543 
1544     nvswitch_execute_unilateral_link_shutdown_ls10(link);
1545     nvswitch_corelib_clear_link_state_ls10(link);
1546 
1547     //
1548     // When a link faults there could be a race between the driver requesting
1549     // reset and MINION processing Emergency Shutdown. Minion will notify if
1550     // such a collision happens and will deny the reset request, so try the
1551     // request up to 3 times
1552     //
1553     do
1554     {
1555         status = nvswitch_request_tl_link_state_ls10(link,
1556                  NV_NVLIPT_LNK_CTRL_LINK_STATE_REQUEST_REQUEST_RESET, NV_TRUE);
1557 
1558         if (status == NVL_SUCCESS)
1559         {
1560             break;
1561         }
1562         else
1563         {
1564 
1565             link_state_request = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber,
1566                                     NVLIPT_LNK , _NVLIPT_LNK , _CTRL_LINK_STATE_REQUEST);
1567 
1568             link_state = DRF_VAL(_NVLIPT_LNK, _CTRL_LINK_STATE_REQUEST, _STATUS,
1569                                     link_state_request);
1570 
1571             if (nvswitch_minion_get_dl_status(device, link->linkNumber,
1572                               NV_NVLSTAT_MN00, 0, &stat_data) == NVL_SUCCESS)
1573             {
1574                 link_intr_subcode = DRF_VAL(_NVLSTAT, _MN00, _LINK_INTR_SUBCODE, stat_data);
1575 
1576                 if ((link_state == NV_NVLIPT_LNK_CTRL_LINK_STATE_REQUEST_STATUS_MINION_REQUEST_FAIL) &&
1577                 (link_intr_subcode == MINION_ALARM_BUSY))
1578                 {
1579 
1580                     status = nvswitch_request_tl_link_state_ls10(link,
1581                              NV_NVLIPT_LNK_CTRL_LINK_STATE_REQUEST_REQUEST_RESET, NV_TRUE);
1582 
1583                     //
1584                     // We retry the shutdown sequence 3 times when we see a MINION_REQUEST_FAIL
1585                     // or MINION_ALARM_BUSY
1586                     //
1587                     retry_count--;
1588                 }
1589                 else
1590                 {
1591                     break;
1592                 }
1593             }
1594             else
1595             {
1596                 // failed to query minion for the link_intr_subcode so retry
1597                 retry_count--;
1598             }
1599         }
1600     } while(retry_count);
1601 
1602     if (status != NVL_SUCCESS)
1603     {
1604         NVSWITCH_PRINT(device, ERROR,
1605             "%s: NvLink Reset has failed for link %d\n",
1606             __FUNCTION__, link->linkNumber);
1607 
1608         return status;
1609     }
1610 
1611     status = nvswitch_launch_ALI_link_training(device, link, NV_FALSE);
1612     if (status != NVL_SUCCESS)
1613     {
1614         NVSWITCH_PRINT(device, ERROR,
1615             "%s: NvLink failed to request ACTIVE for link %d\n",
1616             __FUNCTION__, link->linkNumber);
1617         return status;
1618     }
1619 
1620     return NVL_SUCCESS;
1621 }
1622 
1623 NvBool
1624 nvswitch_are_link_clocks_on_ls10
1625 (
1626     nvswitch_device *device,
1627     nvlink_link *link,
1628     NvU32 clocksMask
1629 )
1630 {
1631     NvU32  clockStatus;
1632     NvU32  clk;
1633     NvBool bIsOff = NV_FALSE;
1634 
1635     clockStatus = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber,
1636                     NVLIPT_LNK, _NVLIPT_LNK, _CTRL_CLK_CTRL);
1637 
1638     FOR_EACH_INDEX_IN_MASK(32, clk, clocksMask)
1639     {
1640         switch(clk)
1641         {
1642             case NVSWITCH_PER_LINK_CLOCK_RXCLK:
1643             {
1644                 bIsOff = FLD_TEST_DRF(_NVLIPT_LNK, _CTRL_CLK_CTRL, _RXCLK_STS, _OFF, clockStatus);
1645                 break;
1646             }
1647             case NVSWITCH_PER_LINK_CLOCK_TXCLK:
1648             {
1649                 bIsOff = FLD_TEST_DRF(_NVLIPT_LNK, _CTRL_CLK_CTRL, _TXCLK_STS, _OFF, clockStatus);
1650                 break;
1651             }
1652             case NVSWITCH_PER_LINK_CLOCK_NCISOCCLK:
1653             {
1654                 bIsOff = FLD_TEST_DRF(_NVLIPT_LNK, _CTRL_CLK_CTRL, _NCISOCCLK_STS, _OFF, clockStatus);
1655                 break;
1656             }
1657             default:
1658                 return NV_FALSE;
1659         }
1660 
1661         if (bIsOff)
1662         {
1663             return NV_FALSE;
1664         }
1665     }
1666     FOR_EACH_INDEX_IN_MASK_END;
1667 
1668     return NV_TRUE;
1669 }
1670 
1671 NvlStatus
1672 nvswitch_request_tl_link_state_ls10
1673 (
1674     nvlink_link *link,
1675     NvU32        tlLinkState,
1676     NvBool       bSync
1677 )
1678 {
1679     nvswitch_device *device = link->dev->pDevInfo;
1680     NvlStatus status = NVL_SUCCESS;
1681     NvU32 linkStatus;
1682     NvU32 lnkErrStatus;
1683     NvU32 bit;
1684 
1685     if (!NVSWITCH_IS_LINK_ENG_VALID_LS10(device, NVLIPT_LNK, link->linkNumber))
1686     {
1687         NVSWITCH_PRINT(device, ERROR,
1688             "%s: link #%d invalid\n",
1689             __FUNCTION__, link->linkNumber);
1690         return -NVL_UNBOUND_DEVICE;
1691     }
1692 
1693     // Wait for the TL link state register to report ready
1694     status = nvswitch_wait_for_tl_request_ready_lr10(link);
1695     if (status != NVL_SUCCESS)
1696     {
1697         return status;
1698     }
1699 
1700     // Clear any pending FAILEDMINIONREQUEST status that maybe populated as it is stale now
1701     bit = DRF_NUM(_NVLIPT_LNK, _ERR_STATUS_0, _FAILEDMINIONREQUEST, 1);
1702     lnkErrStatus = NVSWITCH_LINK_RD32(device, link->linkNumber, NVLIPT_LNK, _NVLIPT_LNK, _ERR_STATUS_0);
1703     if (nvswitch_test_flags(lnkErrStatus, bit))
1704     {
1705         NVSWITCH_LINK_WR32(device, link->linkNumber, NVLIPT_LNK, _NVLIPT_LNK, _ERR_STATUS_0,
1706                 bit);
1707     }
1708 
1709 
1710     // Request state through CTRL_LINK_STATE_REQUEST
1711     NVSWITCH_LINK_WR32_LS10(device, link->linkNumber,
1712             NVLIPT_LNK, _NVLIPT_LNK, _CTRL_LINK_STATE_REQUEST,
1713             DRF_NUM(_NVLIPT_LNK, _CTRL_LINK_STATE_REQUEST, _REQUEST, tlLinkState));
1714 
1715     if (bSync)
1716     {
1717         // Wait for the TL link state register to complete
1718         status = nvswitch_wait_for_tl_request_ready_lr10(link);
1719         if (status != NVL_SUCCESS)
1720         {
1721             return status;
1722         }
1723 
1724         // Check for state requested
1725         linkStatus  = NVSWITCH_LINK_RD32_LS10(device, link->linkNumber,
1726                 NVLIPT_LNK , _NVLIPT_LNK , _CTRL_LINK_STATE_STATUS);
1727 
1728         if (DRF_VAL(_NVLIPT_LNK, _CTRL_LINK_STATE_STATUS, _CURRENTLINKSTATE, linkStatus) !=
1729                     tlLinkState)
1730         {
1731             NVSWITCH_PRINT(device, ERROR,
1732                 "%s: TL link state request to state 0x%x for link #%d did not complete!\n",
1733                 __FUNCTION__, tlLinkState, link->linkNumber);
1734             return -NVL_ERR_GENERIC;
1735         }
1736     }
1737 
1738     return status;
1739 }
1740 
1741 NvBool
1742 nvswitch_does_link_need_termination_enabled_ls10
1743 (
1744     nvswitch_device *device,
1745     nvlink_link *link
1746 )
1747 {
1748     // Not defined for LS10
1749     return NV_FALSE;
1750 }
1751 
1752 NvlStatus
1753 nvswitch_link_termination_setup_ls10
1754 (
1755     nvswitch_device *device,
1756     nvlink_link* link
1757 )
1758 {
1759     // Not supported for LS10
1760     return -NVL_ERR_NOT_SUPPORTED;
1761 }
1762