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, ¶ms);
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