1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020 Marvell International Ltd.
4  */
5 
6 #ifndef __CVMX_QLM_H__
7 #define __CVMX_QLM_H__
8 
9 /*
10  * Interface 0 on the 78xx can be connected to qlm 0 or qlm 2. When interface
11  * 0 is connected to qlm 0, this macro must be set to 0. When interface 0 is
12  * connected to qlm 2, this macro must be set to 1.
13  */
14 #define MUX_78XX_IFACE0 0
15 
16 /*
17  * Interface 1 on the 78xx can be connected to qlm 1 or qlm 3. When interface
18  * 1 is connected to qlm 1, this macro must be set to 0. When interface 1 is
19  * connected to qlm 3, this macro must be set to 1.
20  */
21 #define MUX_78XX_IFACE1 0
22 
23 /* Uncomment this line to print QLM JTAG state */
24 /* #define CVMX_QLM_DUMP_STATE 1 */
25 
26 typedef struct {
27 	const char *name;
28 	int stop_bit;
29 	int start_bit;
30 } __cvmx_qlm_jtag_field_t;
31 
32 /**
33  * Return the number of QLMs supported by the chip
34  *
35  * @return  Number of QLMs
36  */
37 int cvmx_qlm_get_num(void);
38 
39 /**
40  * Return the qlm number based on the interface
41  *
42  * @param xiface  Interface to look
43  */
44 int cvmx_qlm_interface(int xiface);
45 
46 /**
47  * Return the qlm number based for a port in the interface
48  *
49  * @param xiface  interface to look up
50  * @param index  index in an interface
51  *
52  * @return the qlm number based on the xiface
53  */
54 int cvmx_qlm_lmac(int xiface, int index);
55 
56 /**
57  * Return if only DLM5/DLM6/DLM5+DLM6 is used by BGX
58  *
59  * @param BGX  BGX to search for.
60  *
61  * @return muxes used 0 = DLM5+DLM6, 1 = DLM5, 2 = DLM6.
62  */
63 int cvmx_qlm_mux_interface(int bgx);
64 
65 /**
66  * Return number of lanes for a given qlm
67  *
68  * @param qlm QLM block to query
69  *
70  * @return  Number of lanes
71  */
72 int cvmx_qlm_get_lanes(int qlm);
73 
74 /**
75  * Get the QLM JTAG fields based on Octeon model on the supported chips.
76  *
77  * @return  qlm_jtag_field_t structure
78  */
79 const __cvmx_qlm_jtag_field_t *cvmx_qlm_jtag_get_field(void);
80 
81 /**
82  * Get the QLM JTAG length by going through qlm_jtag_field for each
83  * Octeon model that is supported
84  *
85  * @return return the length.
86  */
87 int cvmx_qlm_jtag_get_length(void);
88 
89 /**
90  * Initialize the QLM layer
91  */
92 void cvmx_qlm_init(void);
93 
94 /**
95  * Get a field in a QLM JTAG chain
96  *
97  * @param qlm    QLM to get
98  * @param lane   Lane in QLM to get
99  * @param name   String name of field
100  *
101  * @return JTAG field value
102  */
103 u64 cvmx_qlm_jtag_get(int qlm, int lane, const char *name);
104 
105 /**
106  * Set a field in a QLM JTAG chain
107  *
108  * @param qlm    QLM to set
109  * @param lane   Lane in QLM to set, or -1 for all lanes
110  * @param name   String name of field
111  * @param value  Value of the field
112  */
113 void cvmx_qlm_jtag_set(int qlm, int lane, const char *name, u64 value);
114 
115 /**
116  * Errata G-16094: QLM Gen2 Equalizer Default Setting Change.
117  * CN68XX pass 1.x and CN66XX pass 1.x QLM tweak. This function tweaks the
118  * JTAG setting for a QLMs to run better at 5 and 6.25Ghz.
119  */
120 void __cvmx_qlm_speed_tweak(void);
121 
122 /**
123  * Errata G-16174: QLM Gen2 PCIe IDLE DAC change.
124  * CN68XX pass 1.x, CN66XX pass 1.x and CN63XX pass 1.0-2.2 QLM tweak.
125  * This function tweaks the JTAG setting for a QLMs for PCIe to run better.
126  */
127 void __cvmx_qlm_pcie_idle_dac_tweak(void);
128 
129 void __cvmx_qlm_pcie_cfg_rxd_set_tweak(int qlm, int lane);
130 
131 /**
132  * Get the speed (Gbaud) of the QLM in Mhz.
133  *
134  * @param qlm    QLM to examine
135  *
136  * @return Speed in Mhz
137  */
138 int cvmx_qlm_get_gbaud_mhz(int qlm);
139 /**
140  * Get the speed (Gbaud) of the QLM in Mhz on specific node.
141  *
142  * @param node   Target QLM node
143  * @param qlm    QLM to examine
144  *
145  * @return Speed in Mhz
146  */
147 int cvmx_qlm_get_gbaud_mhz_node(int node, int qlm);
148 
149 enum cvmx_qlm_mode {
150 	CVMX_QLM_MODE_DISABLED = -1,
151 	CVMX_QLM_MODE_SGMII = 1,
152 	CVMX_QLM_MODE_XAUI,
153 	CVMX_QLM_MODE_RXAUI,
154 	CVMX_QLM_MODE_PCIE,	/* gen3 / gen2 / gen1 */
155 	CVMX_QLM_MODE_PCIE_1X2, /* 1x2 gen2 / gen1 */
156 	CVMX_QLM_MODE_PCIE_2X1, /* 2x1 gen2 / gen1 */
157 	CVMX_QLM_MODE_PCIE_1X1, /* 1x1 gen2 / gen1 */
158 	CVMX_QLM_MODE_SRIO_1X4, /* 1x4 short / long */
159 	CVMX_QLM_MODE_SRIO_2X2, /* 2x2 short / long */
160 	CVMX_QLM_MODE_SRIO_4X1, /* 4x1 short / long */
161 	CVMX_QLM_MODE_ILK,
162 	CVMX_QLM_MODE_QSGMII,
163 	CVMX_QLM_MODE_SGMII_SGMII,
164 	CVMX_QLM_MODE_SGMII_DISABLED,
165 	CVMX_QLM_MODE_DISABLED_SGMII,
166 	CVMX_QLM_MODE_SGMII_QSGMII,
167 	CVMX_QLM_MODE_QSGMII_QSGMII,
168 	CVMX_QLM_MODE_QSGMII_DISABLED,
169 	CVMX_QLM_MODE_DISABLED_QSGMII,
170 	CVMX_QLM_MODE_QSGMII_SGMII,
171 	CVMX_QLM_MODE_RXAUI_1X2,
172 	CVMX_QLM_MODE_SATA_2X1,
173 	CVMX_QLM_MODE_XLAUI,
174 	CVMX_QLM_MODE_XFI,
175 	CVMX_QLM_MODE_10G_KR,
176 	CVMX_QLM_MODE_40G_KR4,
177 	CVMX_QLM_MODE_PCIE_1X8, /* 1x8 gen3 / gen2 / gen1 */
178 	CVMX_QLM_MODE_RGMII_SGMII,
179 	CVMX_QLM_MODE_RGMII_XFI,
180 	CVMX_QLM_MODE_RGMII_10G_KR,
181 	CVMX_QLM_MODE_RGMII_RXAUI,
182 	CVMX_QLM_MODE_RGMII_XAUI,
183 	CVMX_QLM_MODE_RGMII_XLAUI,
184 	CVMX_QLM_MODE_RGMII_40G_KR4,
185 	CVMX_QLM_MODE_MIXED,		/* BGX2 is mixed mode, DLM5(SGMII) & DLM6(XFI) */
186 	CVMX_QLM_MODE_SGMII_2X1,	/* Configure BGX2 separate for DLM5 & DLM6 */
187 	CVMX_QLM_MODE_10G_KR_1X2,	/* Configure BGX2 separate for DLM5 & DLM6 */
188 	CVMX_QLM_MODE_XFI_1X2,		/* Configure BGX2 separate for DLM5 & DLM6 */
189 	CVMX_QLM_MODE_RGMII_SGMII_1X1,	/* Configure BGX2, applies to DLM5 */
190 	CVMX_QLM_MODE_RGMII_SGMII_2X1,	/* Configure BGX2, applies to DLM6 */
191 	CVMX_QLM_MODE_RGMII_10G_KR_1X1, /* Configure BGX2, applies to DLM6 */
192 	CVMX_QLM_MODE_RGMII_XFI_1X1,	/* Configure BGX2, applies to DLM6 */
193 	CVMX_QLM_MODE_SDL,		/* RMAC Pipe */
194 	CVMX_QLM_MODE_CPRI,		/* RMAC */
195 	CVMX_QLM_MODE_OCI
196 };
197 
198 enum cvmx_gmx_inf_mode {
199 	CVMX_GMX_INF_MODE_DISABLED = 0,
200 	CVMX_GMX_INF_MODE_SGMII = 1,  /* Other interface can be SGMII or QSGMII */
201 	CVMX_GMX_INF_MODE_QSGMII = 2, /* Other interface can be SGMII or QSGMII */
202 	CVMX_GMX_INF_MODE_RXAUI = 3,  /* Only interface 0, interface 1 must be DISABLED */
203 };
204 
205 /**
206  * Eye diagram captures are stored in the following structure
207  */
208 typedef struct {
209 	int width;	   /* Width in the x direction (time) */
210 	int height;	   /* Height in the y direction (voltage) */
211 	u32 data[64][128]; /* Error count at location, saturates as max */
212 } cvmx_qlm_eye_t;
213 
214 /**
215  * These apply to DLM1 and DLM2 if its not in SATA mode
216  * Manual refers to lanes as follows:
217  *  DML 0 lane 0 == GSER0 lane 0
218  *  DML 0 lane 1 == GSER0 lane 1
219  *  DML 1 lane 2 == GSER1 lane 0
220  *  DML 1 lane 3 == GSER1 lane 1
221  *  DML 2 lane 4 == GSER2 lane 0
222  *  DML 2 lane 5 == GSER2 lane 1
223  */
224 enum cvmx_pemx_cfg_mode {
225 	CVMX_PEM_MD_GEN2_2LANE = 0, /* Valid for PEM0(DLM1), PEM1(DLM2) */
226 	CVMX_PEM_MD_GEN2_1LANE = 1, /* Valid for PEM0(DLM1.0), PEM1(DLM1.1,DLM2.0), PEM2(DLM2.1) */
227 	CVMX_PEM_MD_GEN2_4LANE = 2, /* Valid for PEM0(DLM1-2) */
228 	/* Reserved */
229 	CVMX_PEM_MD_GEN1_2LANE = 4, /* Valid for PEM0(DLM1), PEM1(DLM2) */
230 	CVMX_PEM_MD_GEN1_1LANE = 5, /* Valid for PEM0(DLM1.0), PEM1(DLM1.1,DLM2.0), PEM2(DLM2.1) */
231 	CVMX_PEM_MD_GEN1_4LANE = 6, /* Valid for PEM0(DLM1-2) */
232 	/* Reserved */
233 };
234 
235 /*
236  * Read QLM and return mode.
237  */
238 enum cvmx_qlm_mode cvmx_qlm_get_mode(int qlm);
239 enum cvmx_qlm_mode cvmx_qlm_get_mode_cn78xx(int node, int qlm);
240 enum cvmx_qlm_mode cvmx_qlm_get_dlm_mode(int dlm_mode, int interface);
241 void __cvmx_qlm_set_mult(int qlm, int baud_mhz, int old_multiplier);
242 
243 void cvmx_qlm_display_registers(int qlm);
244 
245 int cvmx_qlm_measure_clock(int qlm);
246 
247 /**
248  * Measure the reference clock of a QLM on a multi-node setup
249  *
250  * @param node   node to measure
251  * @param qlm    QLM to measure
252  *
253  * @return Clock rate in Hz
254  */
255 int cvmx_qlm_measure_clock_node(int node, int qlm);
256 
257 /*
258  * Perform RX equalization on a QLM
259  *
260  * @param node	Node the QLM is on
261  * @param qlm	QLM to perform RX equalization on
262  * @param lane	Lane to use, or -1 for all lanes
263  *
264  * @return Zero on success, negative if any lane failed RX equalization
265  */
266 int __cvmx_qlm_rx_equalization(int node, int qlm, int lane);
267 
268 /**
269  * Errata GSER-27882 -GSER 10GBASE-KR Transmit Equalizer
270  * Training may not update PHY Tx Taps. This function is not static
271  * so we can share it with BGX KR
272  *
273  * @param node	Node to apply errata workaround
274  * @param qlm	QLM to apply errata workaround
275  * @param lane	Lane to apply the errata
276  */
277 int cvmx_qlm_gser_errata_27882(int node, int qlm, int lane);
278 
279 void cvmx_qlm_gser_errata_25992(int node, int qlm);
280 
281 #ifdef CVMX_DUMP_GSER
282 /**
283  * Dump GSER configuration for node 0
284  */
285 int cvmx_dump_gser_config(unsigned int gser);
286 /**
287  * Dump GSER status for node 0
288  */
289 int cvmx_dump_gser_status(unsigned int gser);
290 /**
291  * Dump GSER configuration
292  */
293 int cvmx_dump_gser_config_node(unsigned int node, unsigned int gser);
294 /**
295  * Dump GSER status
296  */
297 int cvmx_dump_gser_status_node(unsigned int node, unsigned int gser);
298 #endif
299 
300 int cvmx_qlm_eye_display(int node, int qlm, int qlm_lane, int format, const cvmx_qlm_eye_t *eye);
301 
302 void cvmx_prbs_process_cmd(int node, int qlm, int mode);
303 
304 #endif /* __CVMX_QLM_H__ */
305