xref: /aosp_15_r20/external/coreboot/src/vendorcode/cavium/include/bdk/libbdk-hal/bdk-qlm.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 #ifndef __CB_BDK_QLM_H__
2 #define __CB_BDK_QLM_H__
3 /***********************license start***********************************
4 * Copyright (c) 2003-2017  Cavium Inc. ([email protected]). All rights
5 * reserved.
6 *
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 *   * Redistributions of source code must retain the above copyright
13 *     notice, this list of conditions and the following disclaimer.
14 *
15 *   * Redistributions in binary form must reproduce the above
16 *     copyright notice, this list of conditions and the following
17 *     disclaimer in the documentation and/or other materials provided
18 *     with the distribution.
19 *
20 *   * Neither the name of Cavium Inc. nor the names of
21 *     its contributors may be used to endorse or promote products
22 *     derived from this software without specific prior written
23 *     permission.
24 *
25 * This Software, including technical data, may be subject to U.S. export
26 * control laws, including the U.S. Export Administration Act and its
27 * associated regulations, and may be subject to export or import
28 * regulations in other countries.
29 *
30 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
31 * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
32 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT
33 * TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
34 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
35 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
36 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
37 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT,
38 * QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK
39 * ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
40 ***********************license end**************************************/
41 
42 /**
43  * @file
44  *
45  * Function and structure definitions for QLM manipulation
46  *
47  * <hr>$Revision: 49448 $<hr>
48  *
49  * @addtogroup hal
50  * @{
51  */
52 #include <bdk.h>
53 #include <libbdk-hal/if/bdk-if.h>
54 
55 typedef enum
56 {
57     BDK_QLM_MODE_DISABLED,  /* QLM is disabled (all chips) */
58     BDK_QLM_MODE_PCIE_1X1,  /* 1 PCIe, 1 lane. Other lanes unused */
59     BDK_QLM_MODE_PCIE_2X1,  /* 2 PCIe, 1 lane each */
60     BDK_QLM_MODE_PCIE_1X2,  /* 1 PCIe, 2 lanes */
61     BDK_QLM_MODE_PCIE_1X4,  /* 1 PCIe, 4 lanes */
62     BDK_QLM_MODE_PCIE_1X8,  /* 1 PCIe, 8 lanes */
63     BDK_QLM_MODE_PCIE_1X16,  /* 1 PCIe, 16 lanes (CN93XX) */
64 
65     BDK_QLM_MODE_SATA_4X1,  /* SATA, each lane independent (cn88xx) */
66     BDK_QLM_MODE_SATA_2X1,  /* SATA, each lane independent (cn83xx) */
67 
68     BDK_QLM_MODE_ILK,           /* ILK 4 lanes (cn78xx) */
69     BDK_QLM_MODE_SGMII_4X1,     /* SGMII, each lane independent (cn88xx) */
70     BDK_QLM_MODE_SGMII_2X1,     /* SGMII, each lane independent (cn83xx) */
71     BDK_QLM_MODE_SGMII_1X1,     /* SGMII, single lane (cn80xx) */
72     BDK_QLM_MODE_XAUI_1X4,      /* 1 XAUI or DXAUI, 4 lanes (cn88xx), use gbaud to tell difference */
73     BDK_QLM_MODE_RXAUI_2X2,     /* 2 RXAUI, 2 lanes each (cn88xx) */
74     BDK_QLM_MODE_RXAUI_1X2,     /* 1 RXAUI, 2 lanes each (cn83xx) */
75     BDK_QLM_MODE_OCI,           /* OCI Multichip interconnect (cn88xx) */
76     BDK_QLM_MODE_XFI_4X1,       /* 4 XFI, 1 lane each (cn88xx) */
77     BDK_QLM_MODE_XFI_2X1,       /* 2 XFI, 1 lane each (cn83xx) */
78     BDK_QLM_MODE_XFI_1X1,       /* 1 XFI, single lane (cn80xx) */
79     BDK_QLM_MODE_XLAUI_1X4,     /* 1 XLAUI, 4 lanes each (cn88xx) */
80     BDK_QLM_MODE_10G_KR_4X1,    /* 4 10GBASE-KR, 1 lane each (cn88xx) */
81     BDK_QLM_MODE_10G_KR_2X1,    /* 2 10GBASE-KR, 1 lane each (cn83xx) */
82     BDK_QLM_MODE_10G_KR_1X1,    /* 1 10GBASE-KR, single lane (cn80xx) */
83     BDK_QLM_MODE_40G_KR4_1X4,   /* 1 40GBASE-KR4, 4 lanes each (cn88xx) */
84     BDK_QLM_MODE_QSGMII_4X1,    /* QSGMII is 4 SGMII on one lane (cn81xx, cn83xx) */
85     BDK_QLM_MODE_25G_4X1,       /* 25G, 1 lane each (CN93XX QLMs) */
86     BDK_QLM_MODE_25G_2X1,       /* 25G, 1 lane each (CN93XX DLMs) */
87     BDK_QLM_MODE_50G_2X2,       /* 50G, 2 lanes each (CN93XX QLMs) */
88     BDK_QLM_MODE_50G_1X2,       /* 50G, 2 lanes each (CN93XX DLMs) */
89     BDK_QLM_MODE_100G_1X4,      /* 100G, 4 lanes each (CN93XX) */
90     BDK_QLM_MODE_25G_KR_4X1,    /* 25G-KR, 1 lane each (CN93XX QLMs) */
91     BDK_QLM_MODE_25G_KR_2X1,    /* 25G-KR, 1 lane each (CN93XX DLMs) */
92     BDK_QLM_MODE_50G_KR_2X2,    /* 50G-KR, 2 lanes each (CN93XX QLMs) */
93     BDK_QLM_MODE_50G_KR_1X2,    /* 50G-KR, 2 lanes each (CN93XX DLMs) */
94     BDK_QLM_MODE_100G_KR4_1X4,  /* 100G-KR4, 4 lanes each (CN93XX) */
95     BDK_QLM_MODE_USXGMII_4X1,   /* USXGMII, 1 lane each, 10M, 100M, 1G, 2.5G, 5G, 10G, 20G (CN93XX QLMs) */
96     BDK_QLM_MODE_USXGMII_2X1,   /* USXGMII, 1 lane each, 10M, 100M, 1G, 2.5G, 5G, 10G, 20G (CN93XX QLMs) */
97     BDK_QLM_MODE_LAST,
98 } bdk_qlm_modes_t;
99 
100 typedef enum
101 {
102     BDK_QLM_CLK_COMMON_0,
103     BDK_QLM_CLK_COMMON_1,
104     BDK_QLM_CLK_EXTERNAL,
105     BDK_QLM_CLK_COMMON_2, /* Must be after EXTERNAL as device trees have hard coded values */
106     BDK_QLM_CLK_LAST,
107 } bdk_qlm_clock_t;
108 
109 typedef enum
110 {
111     BDK_QLM_MODE_FLAG_ENDPOINT = 1, /* PCIe in EP instead of RC */
112 } bdk_qlm_mode_flags_t;
113 
114 typedef enum
115 {
116     BDK_QLM_LOOP_DISABLED,  /* No shallow loopback */
117 } bdk_qlm_loop_t;
118 
119 typedef enum
120 {
121     BDK_QLM_DIRECTION_TX = 1,
122     BDK_QLM_DIRECTION_RX = 2,
123     BDK_QLM_DIRECTION_BOTH = 3,
124 } bdk_qlm_direction_t;
125 
126 /**
127  * Types of QLM margining supported
128  */
129 typedef enum
130 {
131     BDK_QLM_MARGIN_VERTICAL,
132     BDK_QLM_MARGIN_HORIZONTAL,
133 } bdk_qlm_margin_t;
134 
135 /**
136  * Eye diagram captures are stored in the following structure
137  */
138 typedef struct
139 {
140     int width;              /* Width in the x direction (time) */
141     int height;             /* Height in the y direction (voltage) */
142     uint32_t data[64][128]; /* Error count at location, saturates as max */
143 } bdk_qlm_eye_t;
144 
145 /**
146  * Initialize the QLM layer
147  */
148 extern void bdk_qlm_init(bdk_node_t node) BDK_WEAK;
149 
150 /**
151  * Return the number of QLMs supported for the chip
152  *
153  * @return Number of QLMs
154  */
155 extern int bdk_qlm_get_num(bdk_node_t node);
156 
157 /**
158  * Return the number of lanes in a QLM. QLMs normally contain
159  * 4 lanes, except for chips which only have half of a QLM.
160  *
161  * @param node   Node to use in a Numa setup. Can be an exact ID or a special
162  *               value.
163  * @param qlm    QLM to get lanes number for
164  *
165  * @return Number of lanes on the QLM
166  */
167 extern int bdk_qlm_get_lanes(bdk_node_t node, int qlm);
168 
169 /**
170  * Lookup the hardware QLM number for a given interface type and index. This
171  * function will fail with a fatal error if called on invalid interfaces for
172  * a chip. It returns the QLM number for an interface without checking to
173  * see if the QLM is in the correct mode.
174  *
175  * @param iftype    Interface type
176  * @param interface Interface index number
177  *
178  * @return QLM number. Dies on a fatal error on failure.
179  */
180 int bdk_qlm_get_qlm_num(bdk_node_t node, bdk_if_t iftype, int interface, int index);
181 
182 /**
183  * Convert a mode into a configuration variable string value
184  *
185  * @param mode   Mode to convert
186  *
187  * @return configuration value string
188  */
189 extern const char *bdk_qlm_mode_to_cfg_str(bdk_qlm_modes_t mode);
190 
191 /**
192  * Convert a mode into a human understandable string
193  *
194  * @param mode   Mode to convert
195  *
196  * @return Easy to read string
197  */
198 extern const char *bdk_qlm_mode_tostring(bdk_qlm_modes_t mode);
199 
200 /**
201  * Convert a configuration variable value string into a mode
202  *
203  * @param val  Configuration variable value
204  *
205  * @return mode
206  */
207 extern bdk_qlm_modes_t bdk_qlm_cfg_string_to_mode(const char *val);
208 
209 /**
210  * Get the mode of a QLM as a human readable string
211  *
212  * @param node   Node to use in a Numa setup. Can be an exact ID or a special
213  *               value.
214  * @param qlm    QLM to examine
215  *
216  * @return String mode
217  */
218 extern bdk_qlm_modes_t bdk_qlm_get_mode(bdk_node_t node, int qlm);
219 
220 /**
221  * For chips that don't use pin strapping, this function programs
222  * the QLM to the specified mode
223  *
224  * @param node     Node to use in a Numa setup
225  * @param qlm      QLM to configure
226  * @param mode     Desired mode
227  * @param baud_mhz Desired speed
228  * @param flags    Flags to specify mode specific options
229  *
230  * @return Zero on success, negative on failure
231  */
232 extern int bdk_qlm_set_mode(bdk_node_t node, int qlm, bdk_qlm_modes_t mode, int baud_mhz, bdk_qlm_mode_flags_t flags);
233 
234 /**
235  * Set the QLM's clock source.
236  *
237  * @param node     Node to use in a Numa setup
238  * @param qlm      QLM to configure
239  * @param clk      Clock source for QLM
240  *
241  * @return Zero on success, negative on failure
242  */
243 extern int bdk_qlm_set_clock(bdk_node_t node, int qlm, bdk_qlm_clock_t clk);
244 
245 /**
246  * Get the speed (Gbaud) of the QLM in Mhz.
247  *
248  * @param node   Node to use in a Numa setup. Can be an exact ID or a special
249  *               value.
250  * @param qlm    QLM to examine
251  *
252  * @return Speed in Mhz
253  */
254 extern int bdk_qlm_get_gbaud_mhz(bdk_node_t node, int qlm);
255 
256 /**
257  * Measure the reference clock of a QLM
258  *
259  * @param node   Node to use in a Numa setup. Can be an exact ID or a special
260  *               value.
261  * @param qlm    QLM to measure
262  *
263  * @return Clock rate in Hz
264  */
265 extern int bdk_qlm_measure_clock(bdk_node_t node, int qlm);
266 
267 /**
268  * Reset a QLM to its initial state
269  *
270  * @param node   Node to use in a numa setup
271  * @param qlm    QLM to use
272  *
273  * @return Zero on success, negative on failure
274  */
275 extern int bdk_qlm_reset(bdk_node_t node, int qlm);
276 
277 /**
278  * Enable PRBS on a QLM
279  *
280  * @param node   Node to use in a numa setup
281  * @param qlm    QLM to use
282  * @param prbs   PRBS mode (31, etc)
283  * @param dir    Directions to enable. This is so you can enable TX and later
284  *               enable RX after TX has run for a time
285  *
286  * @return Zero on success, negative on failure
287  */
288 extern int bdk_qlm_enable_prbs(bdk_node_t node, int qlm, int prbs, bdk_qlm_direction_t dir);
289 
290 /**
291  * Disable PRBS on a QLM
292  *
293  * @param node   Node to use in a numa setup
294  * @param qlm    QLM to use
295  *
296  * @return Zero on success, negative on failure
297  */
298 extern int bdk_qlm_disable_prbs(bdk_node_t node, int qlm);
299 
300 /**
301  * Return the number of PRBS errors since PRBS started running
302  *
303  * @param node   Node to use in numa setup
304  * @param qlm    QLM to use
305  * @param lane   Which lane
306  * @param clear  Clear the counter after returning its value
307  *
308  * @return Number of errors
309  */
310 extern uint64_t bdk_qlm_get_prbs_errors(bdk_node_t node, int qlm, int lane, int clear);
311 
312 /**
313  * Inject an error into PRBS
314  *
315  * @param node   Node to use in numa setup
316  * @param qlm    QLM to use
317  * @param lane   Which lane
318  */
319 extern void bdk_qlm_inject_prbs_error(bdk_node_t node, int qlm, int lane);
320 
321 /**
322  * Enable shallow loopback on a QLM
323  *
324  * @param node   Node to use in a numa setup
325  * @param qlm    QLM to use
326  * @param loop   Type of loopback. Not all QLMs support all modes
327  *
328  * @return Zero on success, negative on failure
329  */
330 extern int bdk_qlm_enable_loop(bdk_node_t node, int qlm, bdk_qlm_loop_t loop);
331 
332 /**
333  * Configure the TX tuning parameters for a QLM lane. The tuning parameters can
334  * be specified as -1 to maintain their current value
335  *
336  * @param node      Node to configure
337  * @param qlm       QLM to configure
338  * @param lane      Lane to configure
339  * @param tx_swing  Transmit swing (coef 0) Range 0-31
340  * @param tx_pre    Pre cursor emphasis (Coef -1). Range 0-15
341  * @param tx_post   Post cursor emphasis (Coef +1). Range 0-31
342  * @param tx_gain   Transmit gain. Range 0-7
343  * @param tx_vboost Transmit voltage boost. Range 0-1
344  *
345  * @return Zero on success, negative on failure
346  */
347 extern int bdk_qlm_tune_lane_tx(bdk_node_t node, int qlm, int lane, int tx_swing, int tx_pre, int tx_post, int tx_gain, int tx_vboost);
348 
349 /**
350  * Perform RX equalization on a QLM
351  *
352  * @param node   Node the QLM is on
353  * @param qlm    QLM to perform RX equalization on
354  * @param lane   Lane to use, or -1 for all lanes
355  *
356  * @return Zero on success, negative if any lane failed RX equalization
357  */
358 extern int bdk_qlm_rx_equalization(bdk_node_t node, int qlm, int lane);
359 
360 /**
361  * Capture an eye diagram for the given QLM lane. The output data is written
362  * to "eye".
363  *
364  * @param node     Node to use in numa setup
365  * @param qlm      QLM to use
366  * @param qlm_lane Which lane
367  * @param eye      Output eye data
368  *
369  * @return Zero on success, negative on failure
370  */
371 extern int bdk_qlm_eye_capture(bdk_node_t node, int qlm, int qlm_lane, bdk_qlm_eye_t *eye);
372 
373 /**
374  * Display an eye diagram for the given QLM lane. The eye data can be in "eye", or
375  * captured during the call if "eye" is NULL.
376  *
377  * @param node     Node to use in numa setup
378  * @param qlm      QLM to use
379  * @param qlm_lane Which lane
380  * @param format   Display format. 0 = raw, 1 = Color ASCII
381  * @param eye      Eye data to display, or NULL if the data should be captured.
382  *
383  * @return Zero on success, negative on failure
384  */
385 extern int bdk_qlm_eye_display(bdk_node_t node, int qlm, int qlm_lane, int format, const bdk_qlm_eye_t *eye);
386 
387 /**
388  * Call the board specific method of determining the required QLM configuration
389  * and automatically settign up the QLMs to match. For example, on the EBB8800
390  * this function queries the MCU for the current setup.
391  *
392  * @param node   Node to configure
393  *
394  * @return Zero on success, negative on failure
395  */
396 extern int bdk_qlm_auto_config(bdk_node_t node);
397 
398 /**
399  * Get the current RX margining parameter
400  *
401  * @param node     Node to read margin value from
402  * @param qlm      QLM to read from
403  * @param qlm_lane Lane to read
404  * @param margin_type
405  *                 Type of margining parameter to read
406  *
407  * @return Current margining parameter value
408  */
409 extern int64_t bdk_qlm_margin_rx_get(bdk_node_t node, int qlm, int qlm_lane, bdk_qlm_margin_t margin_type);
410 
411 /**
412  * Get the current RX margining parameter minimum value
413  *
414  * @param node     Node to read margin value from
415  * @param qlm      QLM to read from
416  * @param qlm_lane Lane to read
417  * @param margin_type
418  *                 Type of margining parameter to read
419  *
420  * @return Current margining parameter minimum value
421  */
422 extern int64_t bdk_qlm_margin_rx_get_min(bdk_node_t node, int qlm, int qlm_lane, bdk_qlm_margin_t margin_type);
423 
424 /**
425  * Get the current RX margining parameter maximum value
426  *
427  * @param node     Node to read margin value from
428  * @param qlm      QLM to read from
429  * @param qlm_lane Lane to read
430  * @param margin_type
431  *                 Type of margining parameter to read
432  *
433  * @return Current margining parameter maximum value
434  */
435 extern int64_t bdk_qlm_margin_rx_get_max(bdk_node_t node, int qlm, int qlm_lane, bdk_qlm_margin_t margin_type);
436 
437 /**
438  * Set the current RX margining parameter value
439  *
440  * @param node     Node to set margin value on
441  * @param qlm      QLM to set
442  * @param qlm_lane Lane to set
443  * @param margin_type
444  *                 Type of margining parameter to set
445  * @param value    Value of margining parameter
446  *
447  * @return Zero on success, negative on failure
448  */
449 extern int bdk_qlm_margin_rx_set(bdk_node_t node, int qlm, int qlm_lane, bdk_qlm_margin_t margin_type, int value);
450 
451 /**
452  * Restore the supplied RX margining parameter value as if it was never set. This
453  * disables any overrides in the SERDES need to perform margining
454  *
455  * @param node     Node to restore margin value on
456  * @param qlm      QLM to restore
457  * @param qlm_lane Lane to restore
458  * @param margin_type
459  *                 Type of margining parameter to restore
460  * @param value    Value of margining parameter
461  *
462  * @return Zero on success, negative on failure
463  */
464 extern int bdk_qlm_margin_rx_restore(bdk_node_t node, int qlm, int qlm_lane, bdk_qlm_margin_t margin_type, int value);
465 
466 /**
467  * For Cavium SFF  query the dip switches to determine the QLM setup. Applying
468  * any configuration found.
469  *
470  * @param node   Node to configure
471  *
472  * @return Zero on success, negative on failure
473  */
474 
475 extern int bdk_qlm_dip_auto_config(bdk_node_t node);
476 
477 #endif /* __CB_BDK_QLM_H__ */
478 /** @} */
479