Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 35 | * Return: Number of QLMs |
Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 52 | * Return: the qlm number based on the xiface |
Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 61 | * Return: muxes used 0 = DLM5+DLM6, 1 = DLM5, 2 = DLM6. |
Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 70 | * Return: Number of lanes |
Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 77 | * Return: qlm_jtag_field_t structure |
Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 85 | * Return: return the length. |
Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 101 | * Return: JTAG field value |
Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 136 | * Return: Speed in Mhz |
Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 145 | * Return: Speed in Mhz |
Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 253 | * Return: Clock rate in Hz |
Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 264 | * Return: Zero on success, negative if any lane failed RX equalization |
Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame] | 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__ */ |