summaryrefslogtreecommitdiff
path: root/arch/mips/mach-octeon/include/mach/cvmx-qlm.h
blob: 19915eb82c5149ca59f9f1220cf615ec9f08a4af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2020 Marvell International Ltd.
 */

#ifndef __CVMX_QLM_H__
#define __CVMX_QLM_H__

/*
 * Interface 0 on the 78xx can be connected to qlm 0 or qlm 2. When interface
 * 0 is connected to qlm 0, this macro must be set to 0. When interface 0 is
 * connected to qlm 2, this macro must be set to 1.
 */
#define MUX_78XX_IFACE0 0

/*
 * Interface 1 on the 78xx can be connected to qlm 1 or qlm 3. When interface
 * 1 is connected to qlm 1, this macro must be set to 0. When interface 1 is
 * connected to qlm 3, this macro must be set to 1.
 */
#define MUX_78XX_IFACE1 0

/* Uncomment this line to print QLM JTAG state */
/* #define CVMX_QLM_DUMP_STATE 1 */

typedef struct {
	const char *name;
	int stop_bit;
	int start_bit;
} __cvmx_qlm_jtag_field_t;

/**
 * Return the number of QLMs supported by the chip
 *
 * @return  Number of QLMs
 */
int cvmx_qlm_get_num(void);

/**
 * Return the qlm number based on the interface
 *
 * @param xiface  Interface to look
 */
int cvmx_qlm_interface(int xiface);

/**
 * Return the qlm number based for a port in the interface
 *
 * @param xiface  interface to look up
 * @param index  index in an interface
 *
 * @return the qlm number based on the xiface
 */
int cvmx_qlm_lmac(int xiface, int index);

/**
 * Return if only DLM5/DLM6/DLM5+DLM6 is used by BGX
 *
 * @param BGX  BGX to search for.
 *
 * @return muxes used 0 = DLM5+DLM6, 1 = DLM5, 2 = DLM6.
 */
int cvmx_qlm_mux_interface(int bgx);

/**
 * Return number of lanes for a given qlm
 *
 * @param qlm QLM block to query
 *
 * @return  Number of lanes
 */
int cvmx_qlm_get_lanes(int qlm);

/**
 * Get the QLM JTAG fields based on Octeon model on the supported chips.
 *
 * @return  qlm_jtag_field_t structure
 */
const __cvmx_qlm_jtag_field_t *cvmx_qlm_jtag_get_field(void);

/**
 * Get the QLM JTAG length by going through qlm_jtag_field for each
 * Octeon model that is supported
 *
 * @return return the length.
 */
int cvmx_qlm_jtag_get_length(void);

/**
 * Initialize the QLM layer
 */
void cvmx_qlm_init(void);

/**
 * Get a field in a QLM JTAG chain
 *
 * @param qlm    QLM to get
 * @param lane   Lane in QLM to get
 * @param name   String name of field
 *
 * @return JTAG field value
 */
u64 cvmx_qlm_jtag_get(int qlm, int lane, const char *name);

/**
 * Set a field in a QLM JTAG chain
 *
 * @param qlm    QLM to set
 * @param lane   Lane in QLM to set, or -1 for all lanes
 * @param name   String name of field
 * @param value  Value of the field
 */
void cvmx_qlm_jtag_set(int qlm, int lane, const char *name, u64 value);

/**
 * Errata G-16094: QLM Gen2 Equalizer Default Setting Change.
 * CN68XX pass 1.x and CN66XX pass 1.x QLM tweak. This function tweaks the
 * JTAG setting for a QLMs to run better at 5 and 6.25Ghz.
 */
void __cvmx_qlm_speed_tweak(void);

/**
 * Errata G-16174: QLM Gen2 PCIe IDLE DAC change.
 * CN68XX pass 1.x, CN66XX pass 1.x and CN63XX pass 1.0-2.2 QLM tweak.
 * This function tweaks the JTAG setting for a QLMs for PCIe to run better.
 */
void __cvmx_qlm_pcie_idle_dac_tweak(void);

void __cvmx_qlm_pcie_cfg_rxd_set_tweak(int qlm, int lane);

/**
 * Get the speed (Gbaud) of the QLM in Mhz.
 *
 * @param qlm    QLM to examine
 *
 * @return Speed in Mhz
 */
int cvmx_qlm_get_gbaud_mhz(int qlm);
/**
 * Get the speed (Gbaud) of the QLM in Mhz on specific node.
 *
 * @param node   Target QLM node
 * @param qlm    QLM to examine
 *
 * @return Speed in Mhz
 */
int cvmx_qlm_get_gbaud_mhz_node(int node, int qlm);

enum cvmx_qlm_mode {
	CVMX_QLM_MODE_DISABLED = -1,
	CVMX_QLM_MODE_SGMII = 1,
	CVMX_QLM_MODE_XAUI,
	CVMX_QLM_MODE_RXAUI,
	CVMX_QLM_MODE_PCIE,	/* gen3 / gen2 / gen1 */
	CVMX_QLM_MODE_PCIE_1X2, /* 1x2 gen2 / gen1 */
	CVMX_QLM_MODE_PCIE_2X1, /* 2x1 gen2 / gen1 */
	CVMX_QLM_MODE_PCIE_1X1, /* 1x1 gen2 / gen1 */
	CVMX_QLM_MODE_SRIO_1X4, /* 1x4 short / long */
	CVMX_QLM_MODE_SRIO_2X2, /* 2x2 short / long */
	CVMX_QLM_MODE_SRIO_4X1, /* 4x1 short / long */
	CVMX_QLM_MODE_ILK,
	CVMX_QLM_MODE_QSGMII,
	CVMX_QLM_MODE_SGMII_SGMII,
	CVMX_QLM_MODE_SGMII_DISABLED,
	CVMX_QLM_MODE_DISABLED_SGMII,
	CVMX_QLM_MODE_SGMII_QSGMII,
	CVMX_QLM_MODE_QSGMII_QSGMII,
	CVMX_QLM_MODE_QSGMII_DISABLED,
	CVMX_QLM_MODE_DISABLED_QSGMII,
	CVMX_QLM_MODE_QSGMII_SGMII,
	CVMX_QLM_MODE_RXAUI_1X2,
	CVMX_QLM_MODE_SATA_2X1,
	CVMX_QLM_MODE_XLAUI,
	CVMX_QLM_MODE_XFI,
	CVMX_QLM_MODE_10G_KR,
	CVMX_QLM_MODE_40G_KR4,
	CVMX_QLM_MODE_PCIE_1X8, /* 1x8 gen3 / gen2 / gen1 */
	CVMX_QLM_MODE_RGMII_SGMII,
	CVMX_QLM_MODE_RGMII_XFI,
	CVMX_QLM_MODE_RGMII_10G_KR,
	CVMX_QLM_MODE_RGMII_RXAUI,
	CVMX_QLM_MODE_RGMII_XAUI,
	CVMX_QLM_MODE_RGMII_XLAUI,
	CVMX_QLM_MODE_RGMII_40G_KR4,
	CVMX_QLM_MODE_MIXED,		/* BGX2 is mixed mode, DLM5(SGMII) & DLM6(XFI) */
	CVMX_QLM_MODE_SGMII_2X1,	/* Configure BGX2 separate for DLM5 & DLM6 */
	CVMX_QLM_MODE_10G_KR_1X2,	/* Configure BGX2 separate for DLM5 & DLM6 */
	CVMX_QLM_MODE_XFI_1X2,		/* Configure BGX2 separate for DLM5 & DLM6 */
	CVMX_QLM_MODE_RGMII_SGMII_1X1,	/* Configure BGX2, applies to DLM5 */
	CVMX_QLM_MODE_RGMII_SGMII_2X1,	/* Configure BGX2, applies to DLM6 */
	CVMX_QLM_MODE_RGMII_10G_KR_1X1, /* Configure BGX2, applies to DLM6 */
	CVMX_QLM_MODE_RGMII_XFI_1X1,	/* Configure BGX2, applies to DLM6 */
	CVMX_QLM_MODE_SDL,		/* RMAC Pipe */
	CVMX_QLM_MODE_CPRI,		/* RMAC */
	CVMX_QLM_MODE_OCI
};

enum cvmx_gmx_inf_mode {
	CVMX_GMX_INF_MODE_DISABLED = 0,
	CVMX_GMX_INF_MODE_SGMII = 1,  /* Other interface can be SGMII or QSGMII */
	CVMX_GMX_INF_MODE_QSGMII = 2, /* Other interface can be SGMII or QSGMII */
	CVMX_GMX_INF_MODE_RXAUI = 3,  /* Only interface 0, interface 1 must be DISABLED */
};

/**
 * Eye diagram captures are stored in the following structure
 */
typedef struct {
	int width;	   /* Width in the x direction (time) */
	int height;	   /* Height in the y direction (voltage) */
	u32 data[64][128]; /* Error count at location, saturates as max */
} cvmx_qlm_eye_t;

/**
 * These apply to DLM1 and DLM2 if its not in SATA mode
 * Manual refers to lanes as follows:
 *  DML 0 lane 0 == GSER0 lane 0
 *  DML 0 lane 1 == GSER0 lane 1
 *  DML 1 lane 2 == GSER1 lane 0
 *  DML 1 lane 3 == GSER1 lane 1
 *  DML 2 lane 4 == GSER2 lane 0
 *  DML 2 lane 5 == GSER2 lane 1
 */
enum cvmx_pemx_cfg_mode {
	CVMX_PEM_MD_GEN2_2LANE = 0, /* Valid for PEM0(DLM1), PEM1(DLM2) */
	CVMX_PEM_MD_GEN2_1LANE = 1, /* Valid for PEM0(DLM1.0), PEM1(DLM1.1,DLM2.0), PEM2(DLM2.1) */
	CVMX_PEM_MD_GEN2_4LANE = 2, /* Valid for PEM0(DLM1-2) */
	/* Reserved */
	CVMX_PEM_MD_GEN1_2LANE = 4, /* Valid for PEM0(DLM1), PEM1(DLM2) */
	CVMX_PEM_MD_GEN1_1LANE = 5, /* Valid for PEM0(DLM1.0), PEM1(DLM1.1,DLM2.0), PEM2(DLM2.1) */
	CVMX_PEM_MD_GEN1_4LANE = 6, /* Valid for PEM0(DLM1-2) */
	/* Reserved */
};

/*
 * Read QLM and return mode.
 */
enum cvmx_qlm_mode cvmx_qlm_get_mode(int qlm);
enum cvmx_qlm_mode cvmx_qlm_get_mode_cn78xx(int node, int qlm);
enum cvmx_qlm_mode cvmx_qlm_get_dlm_mode(int dlm_mode, int interface);
void __cvmx_qlm_set_mult(int qlm, int baud_mhz, int old_multiplier);

void cvmx_qlm_display_registers(int qlm);

int cvmx_qlm_measure_clock(int qlm);

/**
 * Measure the reference clock of a QLM on a multi-node setup
 *
 * @param node   node to measure
 * @param qlm    QLM to measure
 *
 * @return Clock rate in Hz
 */
int cvmx_qlm_measure_clock_node(int node, int qlm);

/*
 * Perform RX equalization on a QLM
 *
 * @param node	Node the QLM is on
 * @param qlm	QLM to perform RX equalization on
 * @param lane	Lane to use, or -1 for all lanes
 *
 * @return Zero on success, negative if any lane failed RX equalization
 */
int __cvmx_qlm_rx_equalization(int node, int qlm, int lane);

/**
 * Errata GSER-27882 -GSER 10GBASE-KR Transmit Equalizer
 * Training may not update PHY Tx Taps. This function is not static
 * so we can share it with BGX KR
 *
 * @param node	Node to apply errata workaround
 * @param qlm	QLM to apply errata workaround
 * @param lane	Lane to apply the errata
 */
int cvmx_qlm_gser_errata_27882(int node, int qlm, int lane);

void cvmx_qlm_gser_errata_25992(int node, int qlm);

#ifdef CVMX_DUMP_GSER
/**
 * Dump GSER configuration for node 0
 */
int cvmx_dump_gser_config(unsigned int gser);
/**
 * Dump GSER status for node 0
 */
int cvmx_dump_gser_status(unsigned int gser);
/**
 * Dump GSER configuration
 */
int cvmx_dump_gser_config_node(unsigned int node, unsigned int gser);
/**
 * Dump GSER status
 */
int cvmx_dump_gser_status_node(unsigned int node, unsigned int gser);
#endif

int cvmx_qlm_eye_display(int node, int qlm, int qlm_lane, int format, const cvmx_qlm_eye_t *eye);

void cvmx_prbs_process_cmd(int node, int qlm, int mode);

#endif /* __CVMX_QLM_H__ */