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