blob: 25893a98fbd6d4208a4ccf8d195d7a56094bcc75 [file] [log] [blame]
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001/*
2 * Copyright (C) 2018 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
8/* Marvell CP110 SoC COMPHY unit driver */
9
10#include <debug.h>
11#include <delay_timer.h>
12#include <errno.h>
13#include <mmio.h>
14#include <mvebu_def.h>
15#include <spinlock.h>
16#include "mvebu.h"
17#include "comphy-cp110.h"
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020018#include "phy-comphy-cp110.h"
19#include "phy-comphy-common.h"
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030020
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020021#if __has_include("phy-porting-layer.h")
22#include "phy-porting-layer.h"
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030023#else
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020024#include "phy-default-porting-layer.h"
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030025#endif
26
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030027/* COMPHY speed macro */
28#define COMPHY_SPEED_1_25G 0 /* SGMII 1G */
29#define COMPHY_SPEED_2_5G 1
30#define COMPHY_SPEED_3_125G 2 /* SGMII 2.5G */
31#define COMPHY_SPEED_5G 3
32#define COMPHY_SPEED_5_15625G 4 /* XFI 5G */
33#define COMPHY_SPEED_6G 5
34#define COMPHY_SPEED_10_3125G 6 /* XFI 10G */
35#define COMPHY_SPEED_MAX 0x3F
36/* The default speed for IO with fixed known speed */
37#define COMPHY_SPEED_DEFAULT COMPHY_SPEED_MAX
38
39/* Commands for comphy driver */
40#define COMPHY_COMMAND_DIGITAL_PWR_OFF 0x00000001
41#define COMPHY_COMMAND_DIGITAL_PWR_ON 0x00000002
42
43#define COMPHY_PIPE_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + 0x120000)
44
45/* System controller registers */
46#define PCIE_MAC_RESET_MASK_PORT0 BIT(13)
47#define PCIE_MAC_RESET_MASK_PORT1 BIT(11)
48#define PCIE_MAC_RESET_MASK_PORT2 BIT(12)
49#define SYS_CTRL_UINIT_SOFT_RESET_REG 0x268
50#define SYS_CTRL_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + 0x440000)
51
52/* DFX register spaces */
53#define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET (0)
54#define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK (0x1 << \
55 SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET)
56#define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET (1)
57#define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK (0x1 << \
58 SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET)
59#define SAR_STATUS_0_REG 200
60#define DFX_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + DFX_BASE)
61
62/* The same Units Soft Reset Config register are accessed in all PCIe ports
63 * initialization, so a spin lock is defined in case when more than 1 CPUs
64 * resets PCIe MAC and need to access the register in the same time. The spin
65 * lock is shared by all CP110 units.
66 */
67spinlock_t cp110_mac_reset_lock;
68
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030069/* These values come from the PCI Express Spec */
70enum pcie_link_width {
71 PCIE_LNK_WIDTH_RESRV = 0x00,
72 PCIE_LNK_X1 = 0x01,
73 PCIE_LNK_X2 = 0x02,
74 PCIE_LNK_X4 = 0x04,
75 PCIE_LNK_X8 = 0x08,
76 PCIE_LNK_X12 = 0x0C,
77 PCIE_LNK_X16 = 0x10,
78 PCIE_LNK_X32 = 0x20,
79 PCIE_LNK_WIDTH_UNKNOWN = 0xFF,
80};
81
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020082_Bool rx_trainng_done[AP_NUM][CP_NUM][MAX_LANE_NR] = {0};
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030083
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020084static void mvebu_cp110_get_ap_and_cp_nr(uint8_t *ap_nr, uint8_t *cp_nr,
85 uint64_t comphy_base)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030086{
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020087#if (AP_NUM == 1)
88 *ap_nr = 0;
89#else
90 *ap_nr = (((comphy_base & ~0xffffff) - MVEBU_AP_IO_BASE(0)) /
91 AP_IO_OFFSET);
92#endif
93
94 *cp_nr = (((comphy_base & ~0xffffff) - MVEBU_AP_IO_BASE(*ap_nr)) /
95 MVEBU_CP_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030096
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020097 debug("cp_base 0x%llx, ap_io_base 0x%lx, cp_offset 0x%lx\n",
98 comphy_base, (unsigned long)MVEBU_AP_IO_BASE(*ap_nr),
99 (unsigned long)MVEBU_CP_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300100}
101
102/* Clear PIPE selector - avoid collision with previous configuration */
103static void mvebu_cp110_comphy_clr_pipe_selector(uint64_t comphy_base,
104 uint8_t comphy_index)
105{
106 uint32_t reg, mask, field;
107 uint32_t comphy_offset =
108 COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
109
110 mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
111 reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
112 field = reg & mask;
113
114 if (field) {
115 reg &= ~mask;
116 mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET,
117 reg);
118 }
119}
120
121/* Clear PHY selector - avoid collision with previous configuration */
122static void mvebu_cp110_comphy_clr_phy_selector(uint64_t comphy_base,
123 uint8_t comphy_index)
124{
125 uint32_t reg, mask, field;
126 uint32_t comphy_offset =
127 COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
128
129 mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
130 reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
131 field = reg & mask;
132
133 /* Clear comphy selector - if it was already configured.
134 * (might be that this comphy was configured as PCIe/USB,
135 * in such case, no need to clear comphy selector because PCIe/USB
136 * are controlled by hpipe selector).
137 */
138 if (field) {
139 reg &= ~mask;
140 mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET,
141 reg);
142 }
143}
144
145/* PHY selector configures SATA and Network modes */
146static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base,
147 uint8_t comphy_index, uint32_t comphy_mode)
148{
149 uint32_t reg, mask;
150 uint32_t comphy_offset =
151 COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
152 int mode;
153
154 /* If phy selector is used the pipe selector should be marked as
155 * unconnected.
156 */
157 mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
158
159 /* Comphy mode (compound of the IO mode and id). Here, only the IO mode
160 * is required to distinguish between SATA and network modes.
161 */
162 mode = COMPHY_GET_MODE(comphy_mode);
163
164 mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
165 reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
166 reg &= ~mask;
167
168 /* SATA port 0/1 require the same configuration */
169 if (mode == COMPHY_SATA_MODE) {
170 /* SATA selector values is always 4 */
171 reg |= COMMON_SELECTOR_COMPHYN_SATA << comphy_offset;
172 } else {
173 switch (comphy_index) {
174 case(0):
175 case(1):
176 case(2):
177 /* For comphy 0,1, and 2:
178 * Network selector value is always 1.
179 */
180 reg |= COMMON_SELECTOR_COMPHY0_1_2_NETWORK <<
181 comphy_offset;
182 break;
183 case(3):
184 /* For comphy 3:
185 * 0x1 = RXAUI_Lane1
186 * 0x2 = SGMII/HS-SGMII Port1
187 */
188 if (mode == COMPHY_RXAUI_MODE)
189 reg |= COMMON_SELECTOR_COMPHY3_RXAUI <<
190 comphy_offset;
191 else
192 reg |= COMMON_SELECTOR_COMPHY3_SGMII <<
193 comphy_offset;
194 break;
195 case(4):
196 /* For comphy 4:
197 * 0x1 = SGMII/HS-SGMII Port1, XFI1/SFI1
198 * 0x2 = SGMII/HS-SGMII Port0: XFI0/SFI0, RXAUI_Lane0
199 *
200 * We want to check if SGMII1/HS_SGMII1 is the
201 * requested mode in order to determine which value
202 * should be set (all other modes use the same value)
203 * so we need to strip the mode, and check the ID
204 * because we might handle SGMII0/HS_SGMII0 too.
205 */
206 /* TODO: need to distinguish between CP110 and CP115
207 * as SFI1/XFI1 available only for CP115.
208 */
209 if ((mode == COMPHY_SGMII_MODE ||
210 mode == COMPHY_HS_SGMII_MODE ||
211 mode == COMPHY_SFI_MODE) &&
212 COMPHY_GET_ID(comphy_mode) == 1)
213 reg |= COMMON_SELECTOR_COMPHY4_PORT1 <<
214 comphy_offset;
215 else
216 reg |= COMMON_SELECTOR_COMPHY4_ALL_OTHERS <<
217 comphy_offset;
218 break;
219 case(5):
220 /* For comphy 5:
221 * 0x1 = SGMII/HS-SGMII Port2
222 * 0x2 = RXAUI Lane1
223 */
224 if (mode == COMPHY_RXAUI_MODE)
225 reg |= COMMON_SELECTOR_COMPHY5_RXAUI <<
226 comphy_offset;
227 else
228 reg |= COMMON_SELECTOR_COMPHY5_SGMII <<
229 comphy_offset;
230 break;
231 }
232 }
233
234 mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET, reg);
235}
236
237/* PIPE selector configures for PCIe, USB 3.0 Host, and USB 3.0 Device mode */
238static void mvebu_cp110_comphy_set_pipe_selector(uint64_t comphy_base,
239 uint8_t comphy_index, uint32_t comphy_mode)
240{
241 uint32_t reg;
242 uint32_t shift = COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
243 int mode = COMPHY_GET_MODE(comphy_mode);
244 uint32_t mask = COMMON_SELECTOR_COMPHY_MASK << shift;
245 uint32_t pipe_sel = 0x0;
246
247 /* If pipe selector is used the phy selector should be marked as
248 * unconnected.
249 */
250 mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
251
252 reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
253 reg &= ~mask;
254
255 switch (mode) {
256 case (COMPHY_PCIE_MODE):
257 /* For lanes support PCIE, selector value are all same */
258 pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_PCIE;
259 break;
260
261 case (COMPHY_USB3H_MODE):
262 /* Only lane 1-4 support USB host, selector value is same */
263 if (comphy_index == COMPHY_LANE0 ||
264 comphy_index == COMPHY_LANE5)
265 ERROR("COMPHY[%d] mode[%d] is invalid\n",
266 comphy_index, mode);
267 else
268 pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBH;
269 break;
270
271 case (COMPHY_USB3D_MODE):
272 /* Lane 1 and 4 support USB device, selector value is same */
273 if (comphy_index == COMPHY_LANE1 ||
274 comphy_index == COMPHY_LANE4)
275 pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBD;
276 else
277 ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index,
278 mode);
279 break;
280
281 default:
282 ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode);
283 break;
284 }
285
286 mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET, reg |
287 (pipe_sel << shift));
288}
289
290int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index)
291{
292 uintptr_t sd_ip_addr, addr;
293 uint32_t mask, data;
294 int ret = 0;
295
296 debug_enter();
297
298 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
299 comphy_index);
300
301 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
302 data = SD_EXTERNAL_STATUS0_PLL_TX_MASK &
303 SD_EXTERNAL_STATUS0_PLL_RX_MASK;
304 mask = data;
305 data = polling_with_timeout(addr, data, mask,
306 PLL_LOCK_TIMEOUT, REG_32BIT);
307 if (data != 0) {
308 if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
309 ERROR("RX PLL is not locked\n");
310 if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
311 ERROR("TX PLL is not locked\n");
312
313 ret = -ETIMEDOUT;
314 }
315
316 debug_exit();
317
318 return ret;
319}
320
321static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base,
322 uint8_t comphy_index, uint32_t comphy_mode)
323{
324 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr;
325 uint32_t mask, data;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200326 uint8_t ap_nr, cp_nr;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300327 int ret = 0;
328
329 debug_enter();
330
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200331 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
332
333 const struct sata_params *sata_static_values =
334 &sata_static_values_tab[ap_nr][cp_nr][comphy_index];
335
336
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300337 /* configure phy selector for SATA */
338 mvebu_cp110_comphy_set_phy_selector(comphy_base,
339 comphy_index, comphy_mode);
340
341 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
342 comphy_index);
343 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
344 comphy_index);
345 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
346
347 debug(" add hpipe 0x%lx, sd 0x%lx, comphy 0x%lx\n",
348 hpipe_addr, sd_ip_addr, comphy_addr);
349 debug("stage: RFU configurations - hard reset comphy\n");
350 /* RFU configurations - hard reset comphy */
351 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
352 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
353 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
354 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
355 mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
356 data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
357 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
358 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
359 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
360
361 /* Set select data width 40Bit - SATA mode only */
362 reg_set(comphy_addr + COMMON_PHY_CFG6_REG,
363 0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET,
364 COMMON_PHY_CFG6_IF_40_SEL_MASK);
365
366 /* release from hard reset in SD external */
367 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
368 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
369 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
370 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
371 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
372
373 /* Wait 1ms - until band gap and ref clock ready */
374 mdelay(1);
375
376 debug("stage: Comphy configuration\n");
377 /* Start comphy Configuration */
378 /* Set reference clock to comes from group 1 - choose 25Mhz */
379 reg_set(hpipe_addr + HPIPE_MISC_REG,
380 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
381 HPIPE_MISC_REFCLK_SEL_MASK);
382 /* Reference frequency select set 1 (for SATA = 25Mhz) */
383 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
384 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
385 /* PHY mode select (set SATA = 0x0 */
386 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
387 data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
388 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
389 /* Set max PHY generation setting - 6Gbps */
390 reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
391 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
392 HPIPE_INTERFACE_GEN_MAX_MASK);
393 /* Set select data width 40Bit (SEL_BITS[2:0]) */
394 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
395 0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
396
397 debug("stage: Analog parameters from ETP(HW)\n");
398 /* G1 settings */
399 mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200400 data = sata_static_values->g1_rx_selmupi <<
401 HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +0200402 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200403 data |= sata_static_values->g1_rx_selmupf <<
404 HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300405 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200406 data |= sata_static_values->g1_rx_selmufi <<
407 HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300408 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200409 data |= sata_static_values->g1_rx_selmuff <<
410 HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300411 mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
412 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
413 reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
414
415 mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
416 data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
417 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
418 data |= 0x2 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
419 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
420 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
421 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_MASK;
422 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET;
423 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_MASK;
424 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET;
425 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
426
427 /* G2 settings */
428 mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200429 data = sata_static_values->g2_rx_selmupi <<
430 HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +0200431 mask |= HPIPE_G2_SET_1_G2_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200432 data |= sata_static_values->g2_rx_selmupf <<
433 HPIPE_G2_SET_1_G2_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300434 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200435 data |= sata_static_values->g2_rx_selmufi <<
436 HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300437 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200438 data |= sata_static_values->g2_rx_selmuff <<
439 HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300440 mask |= HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_MASK;
441 data |= 0x1 << HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET;
442 reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
443
444 /* G3 settings */
445 mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200446 data = sata_static_values->g3_rx_selmupi <<
447 HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300448 mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200449 data |= sata_static_values->g3_rx_selmupf <<
450 HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300451 mask |= HPIPE_G3_SET_1_G3_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200452 data |= sata_static_values->g3_rx_selmufi <<
453 HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300454 mask |= HPIPE_G3_SET_1_G3_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200455 data |= sata_static_values->g3_rx_selmuff <<
456 HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300457 mask |= HPIPE_G3_SET_1_G3_RX_DFE_EN_MASK;
458 data |= 0x1 << HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET;
459 mask |= HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_MASK;
460 data |= 0x2 << HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET;
461 mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
462 data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
463 reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
464
465 /* DTL Control */
466 mask = HPIPE_PWR_CTR_DTL_SQ_DET_EN_MASK;
467 data = 0x1 << HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET;
468 mask |= HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_MASK;
469 data |= 0x1 << HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET;
470 mask |= HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
471 data |= 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
472 mask |= HPIPE_PWR_CTR_DTL_CLAMPING_SEL_MASK;
473 data |= 0x1 << HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET;
474 mask |= HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_MASK;
475 data |= 0x1 << HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET;
476 mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_MASK;
477 data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET;
478 mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_MASK;
479 data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET;
480 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
481
482 /* Trigger sampler enable pulse */
483 mask = HPIPE_SMAPLER_MASK;
484 data = 0x1 << HPIPE_SMAPLER_OFFSET;
485 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
486 mask = HPIPE_SMAPLER_MASK;
487 data = 0x0 << HPIPE_SMAPLER_OFFSET;
488 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
489
490 /* VDD Calibration Control 3 */
491 mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
492 data = 0x10 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
493 reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
494
495 /* DFE Resolution Control */
496 mask = HPIPE_DFE_RES_FORCE_MASK;
497 data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
498 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
499
500 /* DFE F3-F5 Coefficient Control */
501 mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
502 data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
503 mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
504 data = 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
505 reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
506
507 /* G3 Setting 3 */
508 mask = HPIPE_G3_FFE_CAP_SEL_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200509 data = sata_static_values->g3_ffe_cap_sel <<
510 HPIPE_G3_FFE_CAP_SEL_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300511 mask |= HPIPE_G3_FFE_RES_SEL_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200512 data |= sata_static_values->g3_ffe_res_sel <<
513 HPIPE_G3_FFE_RES_SEL_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300514 mask |= HPIPE_G3_FFE_SETTING_FORCE_MASK;
515 data |= 0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET;
516 mask |= HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
517 data |= 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
518 mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
519 data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
520 reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
521
522 /* G3 Setting 4 */
523 mask = HPIPE_G3_DFE_RES_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200524 data = sata_static_values->g3_dfe_res << HPIPE_G3_DFE_RES_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300525 reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
526
527 /* Offset Phase Control */
528 mask = HPIPE_OS_PH_OFFSET_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200529 data = sata_static_values->align90 << HPIPE_OS_PH_OFFSET_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300530 mask |= HPIPE_OS_PH_OFFSET_FORCE_MASK;
531 data |= 0x1 << HPIPE_OS_PH_OFFSET_FORCE_OFFSET;
532 mask |= HPIPE_OS_PH_VALID_MASK;
533 data |= 0x0 << HPIPE_OS_PH_VALID_OFFSET;
534 reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
535 mask = HPIPE_OS_PH_VALID_MASK;
536 data = 0x1 << HPIPE_OS_PH_VALID_OFFSET;
537 reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
538 mask = HPIPE_OS_PH_VALID_MASK;
539 data = 0x0 << HPIPE_OS_PH_VALID_OFFSET;
540 reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
541
542 /* Set G1 TX amplitude and TX post emphasis value */
543 mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200544 data = sata_static_values->g1_amp << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300545 mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200546 data |= sata_static_values->g1_tx_amp_adj <<
547 HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300548 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200549 data |= sata_static_values->g1_emph <<
550 HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300551 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200552 data |= sata_static_values->g1_emph_en <<
553 HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300554 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
555
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200556 /* Set G1 emph */
557 mask = HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
558 data = sata_static_values->g1_tx_emph_en <<
559 HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
560 mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
561 data |= sata_static_values->g1_tx_emph <<
562 HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
563 reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
564
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300565 /* Set G2 TX amplitude and TX post emphasis value */
566 mask = HPIPE_G2_SET_0_G2_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200567 data = sata_static_values->g2_amp << HPIPE_G2_SET_0_G2_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300568 mask |= HPIPE_G2_SET_0_G2_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200569 data |= sata_static_values->g2_tx_amp_adj <<
570 HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300571 mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200572 data |= sata_static_values->g2_emph <<
573 HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300574 mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200575 data |= sata_static_values->g2_emph_en <<
576 HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300577 reg_set(hpipe_addr + HPIPE_G2_SET_0_REG, data, mask);
578
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200579 /* Set G2 emph */
580 mask = HPIPE_G2_SET_2_G2_TX_EMPH0_EN_MASK;
581 data = sata_static_values->g2_tx_emph_en <<
582 HPIPE_G2_SET_2_G2_TX_EMPH0_EN_OFFSET;
583 mask |= HPIPE_G2_SET_2_G2_TX_EMPH0_MASK;
584 data |= sata_static_values->g2_tx_emph <<
585 HPIPE_G2_SET_2_G2_TX_EMPH0_OFFSET;
586 reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
587
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300588 /* Set G3 TX amplitude and TX post emphasis value */
589 mask = HPIPE_G3_SET_0_G3_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200590 data = sata_static_values->g3_amp << HPIPE_G3_SET_0_G3_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300591 mask |= HPIPE_G3_SET_0_G3_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200592 data |= sata_static_values->g3_tx_amp_adj <<
593 HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300594 mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200595 data |= sata_static_values->g3_emph <<
596 HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300597 mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200598 data |= sata_static_values->g3_emph_en <<
599 HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300600 mask |= HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_MASK;
601 data |= 0x4 << HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET;
602 mask |= HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_MASK;
603 data |= 0x0 << HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET;
604 reg_set(hpipe_addr + HPIPE_G3_SET_0_REG, data, mask);
605
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200606 /* Set G3 emph */
607 mask = HPIPE_G3_SET_2_G3_TX_EMPH0_EN_MASK;
608 data = sata_static_values->g3_tx_emph_en <<
609 HPIPE_G3_SET_2_G3_TX_EMPH0_EN_OFFSET;
610 mask |= HPIPE_G3_SET_2_G3_TX_EMPH0_MASK;
611 data |= sata_static_values->g3_tx_emph <<
612 HPIPE_G3_SET_2_G3_TX_EMPH0_OFFSET;
613 reg_set(hpipe_addr + HPIPE_G3_SET_2_REG, data, mask);
614
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300615 /* SERDES External Configuration 2 register */
616 mask = SD_EXTERNAL_CONFIG2_SSC_ENABLE_MASK;
617 data = 0x1 << SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET;
618 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
619
620 /* DFE reset sequence */
621 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
622 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
623 HPIPE_PWR_CTR_RST_DFE_MASK);
624 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
625 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
626 HPIPE_PWR_CTR_RST_DFE_MASK);
627 /* SW reset for interrupt logic */
628 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
629 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
630 HPIPE_PWR_CTR_SFT_RST_MASK);
631 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
632 0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
633 HPIPE_PWR_CTR_SFT_RST_MASK);
634
635 debug_exit();
636
637 return ret;
638}
639
640static int mvebu_cp110_comphy_sgmii_power_on(uint64_t comphy_base,
641 uint8_t comphy_index, uint32_t comphy_mode)
642{
643 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
644 uint32_t mask, data, sgmii_speed = COMPHY_GET_SPEED(comphy_mode);
645 int ret = 0;
646
647 debug_enter();
648
649 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
650 comphy_index);
651 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
652 comphy_index);
653 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
654
655 /* configure phy selector for SGMII */
656 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
657 comphy_mode);
658
659 /* Confiugre the lane */
660 debug("stage: RFU configurations - hard reset comphy\n");
661 /* RFU configurations - hard reset comphy */
662 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
663 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
664 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
665 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
666 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
667
668 /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
669 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
670 data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
671 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
672 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
673
674 if (sgmii_speed == COMPHY_SPEED_1_25G) {
675 /* SGMII 1G, SerDes speed 1.25G */
676 data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
677 data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
678 } else if (sgmii_speed == COMPHY_SPEED_3_125G) {
679 /* HS SGMII (2.5G), SerDes speed 3.125G */
680 data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
681 data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
682 } else {
683 /* Other rates are not supported */
684 ERROR("unsupported SGMII speed on comphy%d\n", comphy_index);
685 return -EINVAL;
686 }
687
688 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
689 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
690 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
691 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
692 mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
693 data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
694 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
695
696 /* Set hard reset */
697 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
698 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
699 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
700 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
701 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
702 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
703 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
704
705 /* Release hard reset */
706 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
707 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
708 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
709 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
710 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
711
712 /* Wait 1ms - until band gap and ref clock ready */
713 mdelay(1);
714
715 /* Make sure that 40 data bits is disabled
716 * This bit is not cleared by reset
717 */
718 mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
719 data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
720 reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
721
722 /* Start comphy Configuration */
723 debug("stage: Comphy configuration\n");
724 /* set reference clock */
725 mask = HPIPE_MISC_REFCLK_SEL_MASK;
726 data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
727 reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
728 /* Power and PLL Control */
729 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
730 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
731 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
732 data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
733 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
734 /* Loopback register */
735 mask = HPIPE_LOOPBACK_SEL_MASK;
736 data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
737 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
738 /* rx control 1 */
739 mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
740 data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
741 mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
742 data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
743 reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
744 /* DTL Control */
745 mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
746 data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
747 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
748
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200749 /* Set analog parameters from ETP(HW) - for now use the default data */
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300750 debug("stage: Analog parameters from ETP(HW)\n");
751
752 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
753 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
754 HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
755
756 debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
757 /* SERDES External Configuration */
758 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
759 data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
760 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
761 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
762 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
763 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
764 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
765
766 ret = mvebu_cp110_comphy_is_pll_locked(comphy_base, comphy_index);
767 if (ret)
768 return ret;
769
770 /* RX init */
771 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
772 data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
773 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
774
775 /* check that RX init done */
776 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
777 data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
778 mask = data;
779 data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
780 if (data != 0) {
781 ERROR("RX init failed\n");
782 ret = -ETIMEDOUT;
783 }
784
785 debug("stage: RF Reset\n");
786 /* RF Reset */
787 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
788 data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
789 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
790 data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
791 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
792
793 debug_exit();
794
795 return ret;
796}
797
798static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base,
799 uint8_t comphy_index,
800 uint32_t comphy_mode)
801{
802 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
803 uint32_t mask, data, speed = COMPHY_GET_SPEED(comphy_mode);
804 int ret = 0;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200805 uint8_t ap_nr, cp_nr;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300806
807 debug_enter();
808
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200809 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
810
811 if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) {
812 debug("Skip %s for comphy[%d][%d][%d], due to rx training\n",
813 __func__, ap_nr, cp_nr, comphy_index);
814 return 0;
815 }
816
817 const struct xfi_params *xfi_static_values =
818 &xfi_static_values_tab[ap_nr][cp_nr][comphy_index];
819
820 debug("%s: the ap_nr = %d, cp_nr = %d, comphy_index %d\n",
821 __func__, ap_nr, cp_nr, comphy_index);
822
823 debug("g1_ffe_cap_sel= 0x%x, g1_ffe_res_sel= 0x%x, g1_dfe_res= 0x%x\n",
824 xfi_static_values->g1_ffe_cap_sel,
825 xfi_static_values->g1_ffe_res_sel,
826 xfi_static_values->g1_dfe_res);
827
828 if (!xfi_static_values->valid) {
829 ERROR("[ap%d][cp[%d][comphy:%d]: Has no valid static params\n",
830 ap_nr, cp_nr, comphy_index);
831 ERROR("[ap%d][cp[%d][comphy:%d]: porting layer needs update\n",
832 ap_nr, cp_nr, comphy_index);
833 return -EINVAL;
834 }
835
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300836 if ((speed != COMPHY_SPEED_5_15625G) &&
837 (speed != COMPHY_SPEED_10_3125G) &&
838 (speed != COMPHY_SPEED_DEFAULT)) {
839 ERROR("comphy:%d: unsupported sfi/xfi speed\n", comphy_index);
840 return -EINVAL;
841 }
842
843 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
844 comphy_index);
845 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
846 comphy_index);
847 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
848
849 /* configure phy selector for XFI/SFI */
850 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
851 comphy_mode);
852
853 debug("stage: RFU configurations - hard reset comphy\n");
854 /* RFU configurations - hard reset comphy */
855 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
856 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
857 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
858 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
859 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
860
861 /* Make sure that 40 data bits is disabled
862 * This bit is not cleared by reset
863 */
864 mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
865 data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
866 reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
867
868 /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
869 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
870 data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
871 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
872 data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
873 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
874 data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
875 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
876 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
877 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
878 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
879 mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
880 data |= 0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
881 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
882
883 /* release from hard reset */
884 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
885 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
886 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
887 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
888 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
889 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
890 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
891
892 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
893 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
894 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
895 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
896 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
897
898 /* Wait 1ms - until band gap and ref clock ready */
899 mdelay(1);
900
901 /* Start comphy Configuration */
902 debug("stage: Comphy configuration\n");
903 /* set reference clock */
904 mask = HPIPE_MISC_ICP_FORCE_MASK;
905 data = (speed == COMPHY_SPEED_5_15625G) ?
906 (0x0 << HPIPE_MISC_ICP_FORCE_OFFSET) :
907 (0x1 << HPIPE_MISC_ICP_FORCE_OFFSET);
908 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
909 data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
910 reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
911 /* Power and PLL Control */
912 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
913 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
914 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
915 data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
916 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
917 /* Loopback register */
918 mask = HPIPE_LOOPBACK_SEL_MASK;
919 data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
920 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
921 /* rx control 1 */
922 mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
923 data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
924 mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
925 data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
926 reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
927 /* DTL Control */
928 mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
929 data = 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
930 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
931
932 /* Transmitter/Receiver Speed Divider Force */
933 if (speed == COMPHY_SPEED_5_15625G) {
934 mask = HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_MASK;
935 data = 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET;
936 mask |= HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_MASK;
937 data |= 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET;
938 mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_MASK;
939 data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET;
940 mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_MASK;
941 data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET;
942 } else {
943 mask = HPIPE_TXDIGCK_DIV_FORCE_MASK;
944 data = 0x1 << HPIPE_TXDIGCK_DIV_FORCE_OFFSET;
945 }
946 reg_set(hpipe_addr + HPIPE_SPD_DIV_FORCE_REG, data, mask);
947
948 /* Set analog parameters from ETP(HW) */
949 debug("stage: Analog parameters from ETP(HW)\n");
950 /* SERDES External Configuration 2 */
951 mask = SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK;
952 data = 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET;
953 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
954 /* 0x7-DFE Resolution control */
955 mask = HPIPE_DFE_RES_FORCE_MASK;
956 data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
957 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
958 /* 0xd-G1_Setting_0 */
959 if (speed == COMPHY_SPEED_5_15625G) {
960 mask = HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
961 data = 0x6 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
962 } else {
963 mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200964 data = xfi_static_values->g1_amp <<
965 HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300966 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200967 data |= xfi_static_values->g1_emph <<
968 HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
969
970 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
971 data |= xfi_static_values->g1_emph_en <<
972 HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
973 mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
974 data |= xfi_static_values->g1_tx_amp_adj <<
975 HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300976 }
977 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
978 /* Genration 1 setting 2 (G1_Setting_2) */
979 mask = HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200980 data = xfi_static_values->g1_tx_emph <<
981 HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300982 mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200983 data |= xfi_static_values->g1_tx_emph_en <<
984 HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300985 reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
986 /* Transmitter Slew Rate Control register (tx_reg1) */
987 mask = HPIPE_TX_REG1_TX_EMPH_RES_MASK;
988 data = 0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET;
989 mask |= HPIPE_TX_REG1_SLC_EN_MASK;
990 data |= 0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET;
991 reg_set(hpipe_addr + HPIPE_TX_REG1_REG, data, mask);
992 /* Impedance Calibration Control register (cal_reg1) */
993 mask = HPIPE_CAL_REG_1_EXT_TXIMP_MASK;
994 data = 0xe << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
995 mask |= HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK;
996 data |= 0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET;
997 reg_set(hpipe_addr + HPIPE_CAL_REG1_REG, data, mask);
998 /* Generation 1 Setting 5 (g1_setting_5) */
999 mask = HPIPE_G1_SETTING_5_G1_ICP_MASK;
1000 data = 0 << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
1001 reg_set(hpipe_addr + HPIPE_G1_SETTING_5_REG, data, mask);
1002
1003 /* 0xE-G1_Setting_1 */
1004 mask = HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
1005 data = 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
1006 if (speed == COMPHY_SPEED_5_15625G) {
1007 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
1008 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001009 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
1010 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001011 } else {
1012 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001013 data |= xfi_static_values->g1_rx_selmupi <<
1014 HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001015 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001016 data |= xfi_static_values->g1_rx_selmupf <<
1017 HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001018 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001019 data |= xfi_static_values->g1_rx_selmufi <<
1020 HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001021 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001022 data |= xfi_static_values->g1_rx_selmuff <<
1023 HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001024 mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
1025 data |= 0x3 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
1026 }
1027 reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
1028
1029 /* 0xA-DFE_Reg3 */
1030 mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
1031 data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
1032 mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
1033 data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
1034 reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
1035
1036 /* 0x111-G1_Setting_4 */
1037 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1038 data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1039 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
1040 /* Genration 1 setting 3 (G1_Setting_3) */
1041 mask = HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK;
1042 data = 0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET;
1043 if (speed == COMPHY_SPEED_5_15625G) {
1044 /* Force FFE (Feed Forward Equalization) to 5G */
1045 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
1046 data |= 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
1047 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
1048 data |= 0x4 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
1049 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
1050 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001051 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
1052 } else {
1053 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
1054 data |= xfi_static_values->g1_ffe_cap_sel <<
1055 HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
1056 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
1057 data |= xfi_static_values->g1_ffe_res_sel <<
1058 HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
1059 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
1060 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
1061 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
1062
1063 /* Use the value from CAL_OS_PH_EXT */
1064 mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
1065 data = 1 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
1066 reg_set(hpipe_addr +
1067 HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
1068 data, mask);
1069
1070 /* Update align90 */
1071 mask = HPIPE_CAL_OS_PH_EXT_MASK;
1072 data = xfi_static_values->align90 << HPIPE_CAL_OS_PH_EXT_OFFSET;
1073 reg_set(hpipe_addr +
1074 HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
1075 data, mask);
1076
1077 /* Force DFE resolution (use gen table value) */
1078 mask = HPIPE_DFE_RES_FORCE_MASK;
1079 data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
1080 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
1081
1082 /* 0x111-G1 DFE_Setting_4 */
1083 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1084 data = xfi_static_values->g1_dfe_res <<
1085 HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1086 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001087 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001088
1089 /* Connfigure RX training timer */
1090 mask = HPIPE_RX_TRAIN_TIMER_MASK;
1091 data = 0x13 << HPIPE_RX_TRAIN_TIMER_OFFSET;
1092 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
1093
1094 /* Enable TX train peak to peak hold */
1095 mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
1096 data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
1097 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
1098
1099 /* Configure TX preset index */
1100 mask = HPIPE_TX_PRESET_INDEX_MASK;
1101 data = 0x2 << HPIPE_TX_PRESET_INDEX_OFFSET;
1102 reg_set(hpipe_addr + HPIPE_TX_PRESET_INDEX_REG, data, mask);
1103
1104 /* Disable pattern lock lost timeout */
1105 mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
1106 data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
1107 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
1108
1109 /* Configure TX training pattern and TX training 16bit auto */
1110 mask = HPIPE_TX_TRAIN_16BIT_AUTO_EN_MASK;
1111 data = 0x1 << HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET;
1112 mask |= HPIPE_TX_TRAIN_PAT_SEL_MASK;
1113 data |= 0x1 << HPIPE_TX_TRAIN_PAT_SEL_OFFSET;
1114 reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
1115
1116 /* Configure Training patten number */
1117 mask = HPIPE_TRAIN_PAT_NUM_MASK;
1118 data = 0x88 << HPIPE_TRAIN_PAT_NUM_OFFSET;
1119 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_0_REG, data, mask);
1120
1121 /* Configure differencial manchester encoter to ethernet mode */
1122 mask = HPIPE_DME_ETHERNET_MODE_MASK;
1123 data = 0x1 << HPIPE_DME_ETHERNET_MODE_OFFSET;
1124 reg_set(hpipe_addr + HPIPE_DME_REG, data, mask);
1125
1126 /* Configure VDD Continuous Calibration */
1127 mask = HPIPE_CAL_VDD_CONT_MODE_MASK;
1128 data = 0x1 << HPIPE_CAL_VDD_CONT_MODE_OFFSET;
1129 reg_set(hpipe_addr + HPIPE_VDD_CAL_0_REG, data, mask);
1130
1131 /* Trigger sampler enable pulse (by toggleing the bit) */
1132 mask = HPIPE_RX_SAMPLER_OS_GAIN_MASK;
1133 data = 0x3 << HPIPE_RX_SAMPLER_OS_GAIN_OFFSET;
1134 mask |= HPIPE_SMAPLER_MASK;
1135 data |= 0x1 << HPIPE_SMAPLER_OFFSET;
1136 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1137 mask = HPIPE_SMAPLER_MASK;
1138 data = 0x0 << HPIPE_SMAPLER_OFFSET;
1139 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1140
1141 /* Set External RX Regulator Control */
1142 mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
1143 data = 0x1A << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
1144 reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
1145
1146 debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
1147 /* SERDES External Configuration */
1148 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1149 data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1150 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1151 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1152 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1153 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1154 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1155
1156 /* check PLL rx & tx ready */
1157 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1158 data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
1159 SD_EXTERNAL_STATUS0_PLL_TX_MASK;
1160 mask = data;
1161 data = polling_with_timeout(addr, data, mask,
1162 PLL_LOCK_TIMEOUT, REG_32BIT);
1163 if (data != 0) {
1164 if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
1165 ERROR("RX PLL is not locked\n");
1166 if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
1167 ERROR("TX PLL is not locked\n");
1168
1169 ret = -ETIMEDOUT;
1170 }
1171
1172 /* RX init */
1173 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1174 data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1175 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1176
1177 /* check that RX init done */
1178 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1179 data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
1180 mask = data;
1181 data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
1182 if (data != 0) {
1183 ERROR("RX init failed\n");
1184 ret = -ETIMEDOUT;
1185 }
1186
1187 debug("stage: RF Reset\n");
1188 /* RF Reset */
1189 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1190 data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1191 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1192 data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1193 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1194
1195 debug_exit();
1196
1197 return ret;
1198}
1199
1200static int mvebu_cp110_comphy_pcie_power_on(uint64_t comphy_base,
1201 uint8_t comphy_index, uint32_t comphy_mode)
1202{
1203 int ret = 0;
1204 uint32_t reg, mask, data, pcie_width;
1205 uint32_t clk_dir;
1206 uintptr_t hpipe_addr, comphy_addr, addr;
1207 _Bool clk_src = COMPHY_GET_CLK_SRC(comphy_mode);
1208
1209 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1210 comphy_index);
1211 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1212 pcie_width = COMPHY_GET_PCIE_WIDTH(comphy_mode);
1213
1214 debug_enter();
1215
1216 spin_lock(&cp110_mac_reset_lock);
1217
1218 reg = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
1219 SYS_CTRL_UINIT_SOFT_RESET_REG);
1220 switch (comphy_index) {
1221 case COMPHY_LANE0:
1222 reg |= PCIE_MAC_RESET_MASK_PORT0;
1223 break;
1224 case COMPHY_LANE4:
1225 reg |= PCIE_MAC_RESET_MASK_PORT1;
1226 break;
1227 case COMPHY_LANE5:
1228 reg |= PCIE_MAC_RESET_MASK_PORT2;
1229 break;
1230 }
1231
1232 mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
1233 SYS_CTRL_UINIT_SOFT_RESET_REG, reg);
1234 spin_unlock(&cp110_mac_reset_lock);
1235
1236 /* Configure PIPE selector for PCIE */
1237 mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
1238 comphy_mode);
1239
1240 /*
1241 * Read SAR (Sample-At-Reset) configuration for the PCIe clock
1242 * direction.
1243 *
1244 * SerDes Lane 4/5 got the PCIe ref-clock #1,
1245 * and SerDes Lane 0 got PCIe ref-clock #0
1246 */
1247 reg = mmio_read_32(DFX_FROM_COMPHY_ADDR(comphy_base) +
1248 SAR_STATUS_0_REG);
1249 if (comphy_index == COMPHY_LANE4 || comphy_index == COMPHY_LANE5)
1250 clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK) >>
1251 SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET;
1252 else
1253 clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK) >>
1254 SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET;
1255
1256 debug("On lane %d\n", comphy_index);
1257 debug("PCIe clock direction = %x\n", clk_dir);
1258 debug("PCIe Width = %d\n", pcie_width);
1259
1260 /* enable PCIe X4 and X2 */
1261 if (comphy_index == COMPHY_LANE0) {
1262 if (pcie_width == PCIE_LNK_X4) {
1263 data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET;
1264 mask = COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK;
1265 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1266 data, mask);
1267 } else if (pcie_width == PCIE_LNK_X2) {
1268 data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET;
1269 mask = COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK;
1270 reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
1271 }
1272 }
1273
1274 /* If PCIe clock is output and clock source from SerDes lane 5,
1275 * need to configure the clock-source MUX.
1276 * By default, the clock source is from lane 4
1277 */
1278 if (clk_dir && clk_src && (comphy_index == COMPHY_LANE5)) {
1279 data = DFX_DEV_GEN_PCIE_CLK_SRC_MUX <<
1280 DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET;
1281 mask = DFX_DEV_GEN_PCIE_CLK_SRC_MASK;
1282 reg_set(DFX_FROM_COMPHY_ADDR(comphy_base) +
1283 DFX_DEV_GEN_CTRL12_REG, data, mask);
1284 }
1285
1286 debug("stage: RFU configurations - hard reset comphy\n");
1287 /* RFU configurations - hard reset comphy */
1288 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1289 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1290 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1291 data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1292 mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1293 data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1294 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1295 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1296 mask |= COMMON_PHY_PHY_MODE_MASK;
1297 data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET;
1298 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1299
1300 /* release from hard reset */
1301 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1302 data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1303 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1304 data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1305 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1306
1307 /* Wait 1ms - until band gap and ref clock ready */
1308 mdelay(1);
1309 /* Start comphy Configuration */
1310 debug("stage: Comphy configuration\n");
1311 /* Set PIPE soft reset */
1312 mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
1313 data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
1314 /* Set PHY datapath width mode for V0 */
1315 mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
1316 data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
1317 /* Set Data bus width USB mode for V0 */
1318 mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
1319 data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
1320 /* Set CORE_CLK output frequency for 250Mhz */
1321 mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
1322 data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
1323 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
1324 /* Set PLL ready delay for 0x2 */
1325 data = 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET;
1326 mask = HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK;
1327 if (pcie_width != PCIE_LNK_X1) {
1328 data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET;
1329 mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK;
1330 data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET;
1331 mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK;
1332 }
1333 reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, data, mask);
1334
1335 /* Set PIPE mode interface to PCIe3 - 0x1 & set lane order */
1336 data = 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET;
1337 mask = HPIPE_CLK_SRC_HI_MODE_PIPE_MASK;
1338 if (pcie_width != PCIE_LNK_X1) {
1339 mask |= HPIPE_CLK_SRC_HI_LANE_STRT_MASK;
1340 mask |= HPIPE_CLK_SRC_HI_LANE_MASTER_MASK;
1341 mask |= HPIPE_CLK_SRC_HI_LANE_BREAK_MASK;
1342 if (comphy_index == 0) {
1343 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET;
1344 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET;
1345 } else if (comphy_index == (pcie_width - 1)) {
1346 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET;
1347 }
1348 }
1349 reg_set(hpipe_addr + HPIPE_CLK_SRC_HI_REG, data, mask);
1350 /* Config update polarity equalization */
1351 data = 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET;
1352 mask = HPIPE_CFG_UPDATE_POLARITY_MASK;
1353 reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG1_REG, data, mask);
1354 /* Set PIPE version 4 to mode enable */
1355 data = 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET;
1356 mask = HPIPE_DFE_CTRL_28_PIPE4_MASK;
1357 reg_set(hpipe_addr + HPIPE_DFE_CTRL_28_REG, data, mask);
1358 /* TODO: check if pcie clock is output/input - for bringup use input*/
1359 /* Enable PIN clock 100M_125M */
1360 mask = 0;
1361 data = 0;
1362 /* Only if clock is output, configure the clock-source mux */
1363 if (clk_dir) {
1364 mask |= HPIPE_MISC_CLK100M_125M_MASK;
1365 data |= 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET;
1366 }
1367 /* Set PIN_TXDCLK_2X Clock Freq. Selection for outputs 500MHz clock */
1368 mask |= HPIPE_MISC_TXDCLK_2X_MASK;
1369 data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET;
1370 /* Enable 500MHz Clock */
1371 mask |= HPIPE_MISC_CLK500_EN_MASK;
1372 data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET;
1373 if (clk_dir) { /* output */
1374 /* Set reference clock comes from group 1 */
1375 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
1376 data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
1377 } else {
1378 /* Set reference clock comes from group 2 */
1379 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
1380 data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET;
1381 }
1382 mask |= HPIPE_MISC_ICP_FORCE_MASK;
1383 data |= 0x1 << HPIPE_MISC_ICP_FORCE_OFFSET;
1384 reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
1385 if (clk_dir) { /* output */
1386 /* Set reference frequcency select - 0x2 for 25MHz*/
1387 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1388 data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1389 } else {
1390 /* Set reference frequcency select - 0x0 for 100MHz*/
1391 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1392 data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1393 }
1394 /* Set PHY mode to PCIe */
1395 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1396 data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1397 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1398
1399 /* ref clock alignment */
1400 if (pcie_width != PCIE_LNK_X1) {
1401 mask = HPIPE_LANE_ALIGN_OFF_MASK;
1402 data = 0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET;
1403 reg_set(hpipe_addr + HPIPE_LANE_ALIGN_REG, data, mask);
1404 }
1405
1406 /* Set the amount of time spent in the LoZ state - set for 0x7 only if
1407 * the PCIe clock is output
1408 */
1409 if (clk_dir)
1410 reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
1411 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
1412 HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
1413
1414 /* Set Maximal PHY Generation Setting(8Gbps) */
1415 mask = HPIPE_INTERFACE_GEN_MAX_MASK;
1416 data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET;
1417 /* Bypass frame detection and sync detection for RX DATA */
1418 mask |= HPIPE_INTERFACE_DET_BYPASS_MASK;
1419 data |= 0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET;
1420 /* Set Link Train Mode (Tx training control pins are used) */
1421 mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK;
1422 data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET;
1423 reg_set(hpipe_addr + HPIPE_INTERFACE_REG, data, mask);
1424
1425 /* Set Idle_sync enable */
1426 mask = HPIPE_PCIE_IDLE_SYNC_MASK;
1427 data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET;
1428 /* Select bits for PCIE Gen3(32bit) */
1429 mask |= HPIPE_PCIE_SEL_BITS_MASK;
1430 data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET;
1431 reg_set(hpipe_addr + HPIPE_PCIE_REG0, data, mask);
1432
1433 /* Enable Tx_adapt_g1 */
1434 mask = HPIPE_TX_TRAIN_CTRL_G1_MASK;
1435 data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET;
1436 /* Enable Tx_adapt_gn1 */
1437 mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK;
1438 data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET;
1439 /* Disable Tx_adapt_g0 */
1440 mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK;
1441 data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
1442 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
1443
1444 /* Set reg_tx_train_chk_init */
1445 mask = HPIPE_TX_TRAIN_CHK_INIT_MASK;
1446 data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET;
1447 /* Enable TX_COE_FM_PIN_PCIE3_EN */
1448 mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK;
1449 data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET;
1450 reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
1451
1452 debug("stage: TRx training parameters\n");
1453 /* Set Preset sweep configurations */
1454 mask = HPIPE_TX_TX_STATUS_CHECK_MODE_MASK;
1455 data = 0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET;
1456 mask |= HPIPE_TX_NUM_OF_PRESET_MASK;
1457 data |= 0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET;
1458 mask |= HPIPE_TX_SWEEP_PRESET_EN_MASK;
1459 data |= 0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET;
1460 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_11_REG, data, mask);
1461
1462 /* Tx train start configuration */
1463 mask = HPIPE_TX_TRAIN_START_SQ_EN_MASK;
1464 data = 0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET;
1465 mask |= HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK;
1466 data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET;
1467 mask |= HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK;
1468 data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET;
1469 mask |= HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK;
1470 data |= 0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET;
1471 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
1472
1473 /* Enable Tx train P2P */
1474 mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
1475 data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
1476 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
1477
1478 /* Configure Tx train timeout */
1479 mask = HPIPE_TRX_TRAIN_TIMER_MASK;
1480 data = 0x17 << HPIPE_TRX_TRAIN_TIMER_OFFSET;
1481 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_4_REG, data, mask);
1482
1483 /* Disable G0/G1/GN1 adaptation */
1484 mask = HPIPE_TX_TRAIN_CTRL_G1_MASK | HPIPE_TX_TRAIN_CTRL_GN1_MASK
1485 | HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
1486 data = 0;
1487 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
1488
1489 /* Disable DTL frequency loop */
1490 mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
1491 data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
1492 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
1493
1494 /* Configure G3 DFE */
1495 mask = HPIPE_G3_DFE_RES_MASK;
1496 data = 0x3 << HPIPE_G3_DFE_RES_OFFSET;
1497 reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
1498
1499 /* Use TX/RX training result for DFE */
1500 mask = HPIPE_DFE_RES_FORCE_MASK;
1501 data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
1502 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
1503
1504 /* Configure initial and final coefficient value for receiver */
1505 mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
1506 data = 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
1507
1508 mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
1509 data |= 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
1510
1511 mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
1512 data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
1513 reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
1514
1515 /* Trigger sampler enable pulse */
1516 mask = HPIPE_SMAPLER_MASK;
1517 data = 0x1 << HPIPE_SMAPLER_OFFSET;
1518 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1519 udelay(5);
1520 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, 0, mask);
1521
1522 /* FFE resistor tuning for different bandwidth */
1523 mask = HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
1524 data = 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
1525 mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
1526 data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
1527 reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
1528
1529 /* Pattern lock lost timeout disable */
1530 mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
1531 data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
1532 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
1533
1534 /* Configure DFE adaptations */
1535 mask = HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK;
1536 data = 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET;
1537 mask |= HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK;
1538 data |= 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET;
1539 mask |= HPIPE_CDR_MAX_DFE_ADAPT_0_MASK;
1540 data |= 0x0 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET;
1541 mask |= HPIPE_CDR_MAX_DFE_ADAPT_1_MASK;
1542 data |= 0x1 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET;
1543 reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
1544
1545 mask = HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK;
1546 data = 0x0 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET;
1547 reg_set(hpipe_addr + HPIPE_DFE_CONTROL_REG, data, mask);
1548
1549 /* Genration 2 setting 1*/
1550 mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
1551 data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001552 mask |= HPIPE_G2_SET_1_G2_RX_SELMUPF_MASK;
1553 data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001554 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
1555 data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
1556 reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
1557
1558 /* DFE enable */
1559 mask = HPIPE_G2_DFE_RES_MASK;
1560 data = 0x3 << HPIPE_G2_DFE_RES_OFFSET;
1561 reg_set(hpipe_addr + HPIPE_G2_SETTINGS_4_REG, data, mask);
1562
1563 /* Configure DFE Resolution */
1564 mask = HPIPE_LANE_CFG4_DFE_EN_SEL_MASK;
1565 data = 0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET;
1566 reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
1567
1568 /* VDD calibration control */
1569 mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
1570 data = 0x16 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
1571 reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
1572
1573 /* Set PLL Charge-pump Current Control */
1574 mask = HPIPE_G3_SETTING_5_G3_ICP_MASK;
1575 data = 0x4 << HPIPE_G3_SETTING_5_G3_ICP_OFFSET;
1576 reg_set(hpipe_addr + HPIPE_G3_SETTING_5_REG, data, mask);
1577
1578 /* Set lane rqualization remote setting */
1579 mask = HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK;
1580 data = 0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET;
1581 mask |= HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK;
1582 data |= 0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET;
1583 mask |= HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK;
1584 data |= 0x6 << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET;
1585 reg_set(hpipe_addr + HPIPE_LANE_EQ_REMOTE_SETTING_REG, data, mask);
1586
1587 mask = HPIPE_CFG_EQ_BUNDLE_DIS_MASK;
1588 data = 0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET;
1589 reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG2_REG, data, mask);
1590
1591 debug("stage: Comphy power up\n");
1592
1593 /* For PCIe X4 or X2:
1594 * release from reset only after finish to configure all lanes
1595 */
1596 if ((pcie_width == PCIE_LNK_X1) || (comphy_index == (pcie_width - 1))) {
1597 uint32_t i, start_lane, end_lane;
1598
1599 if (pcie_width != PCIE_LNK_X1) {
1600 /* allows writing to all lanes in one write */
1601 data = 0x0;
1602 if (pcie_width == PCIE_LNK_X2)
1603 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
1604 else if (pcie_width == PCIE_LNK_X4)
1605 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
1606 reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
1607 start_lane = 0;
1608 end_lane = pcie_width;
1609
1610 /* Release from PIPE soft reset
1611 * For PCIe by4 or by2:
1612 * release from soft reset all lanes - can't use
1613 * read modify write
1614 */
1615 reg_set(HPIPE_ADDR(
1616 COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), 0) +
1617 HPIPE_RST_CLK_CTRL_REG, 0x24, 0xffffffff);
1618 } else {
1619 start_lane = comphy_index;
1620 end_lane = comphy_index + 1;
1621
1622 /* Release from PIPE soft reset
1623 * for PCIe by4 or by2:
1624 * release from soft reset all lanes
1625 */
1626 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
1627 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
1628 HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
1629 }
1630
1631 if (pcie_width != PCIE_LNK_X1) {
1632 /* disable writing to all lanes with one write */
1633 if (pcie_width == PCIE_LNK_X2) {
1634 data = (COMPHY_LANE0 <<
1635 COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
1636 (COMPHY_LANE1 <<
1637 COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET);
1638 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
1639 } else if (pcie_width == PCIE_LNK_X4) {
1640 data = (COMPHY_LANE0 <<
1641 COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
1642 (COMPHY_LANE1 <<
1643 COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET) |
1644 (COMPHY_LANE2 <<
1645 COMMON_PHY_SD_CTRL1_COMPHY_2_PORT_OFFSET) |
1646 (COMPHY_LANE3 <<
1647 COMMON_PHY_SD_CTRL1_COMPHY_3_PORT_OFFSET);
1648 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
1649 }
1650 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1651 data, mask);
1652 }
1653
1654 debug("stage: Check PLL\n");
1655 /* Read lane status */
1656 for (i = start_lane; i < end_lane; i++) {
1657 addr = HPIPE_ADDR(
1658 COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), i) +
1659 HPIPE_LANE_STATUS1_REG;
1660 data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
1661 mask = data;
1662 ret = polling_with_timeout(addr, data, mask,
1663 PLL_LOCK_TIMEOUT,
1664 REG_32BIT);
1665 if (ret)
1666 ERROR("Failed to lock PCIE PLL\n");
1667 }
1668 }
1669
1670 debug_exit();
1671
1672 return ret;
1673}
1674
1675static int mvebu_cp110_comphy_rxaui_power_on(uint64_t comphy_base,
1676 uint8_t comphy_index, uint32_t comphy_mode)
1677{
1678 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
1679 uint32_t mask, data;
1680 int ret = 0;
1681
1682 debug_enter();
1683
1684 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1685 comphy_index);
1686 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1687 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1688 comphy_index);
1689
1690 /* configure phy selector for RXAUI */
1691 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
1692 comphy_mode);
1693
1694 /* RFU configurations - hard reset comphy */
1695 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1696 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1697 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1698 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1699 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1700
1701 if (comphy_index == 2) {
1702 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1703 0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET,
1704 COMMON_PHY_SD_CTRL1_RXAUI0_MASK);
1705 }
1706 if (comphy_index == 4) {
1707 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1708 0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET,
1709 COMMON_PHY_SD_CTRL1_RXAUI1_MASK);
1710 }
1711
1712 /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
1713 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1714 data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1715 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
1716 data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
1717 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
1718 data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
1719 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1720 data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1721 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1722 data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1723 mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
1724 data |= 0x0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
1725 mask |= SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK;
1726 data |= 0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET;
1727 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1728
1729 /* release from hard reset */
1730 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
1731 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
1732 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
1733 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
1734 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1735 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1736 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1737
1738 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
1739 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
1740 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
1741 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
1742 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1743
1744 /* Wait 1ms - until band gap and ref clock ready */
1745 mdelay(1);
1746
1747 /* Start comphy Configuration */
1748 debug("stage: Comphy configuration\n");
1749 /* set reference clock */
1750 reg_set(hpipe_addr + HPIPE_MISC_REG,
1751 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
1752 HPIPE_MISC_REFCLK_SEL_MASK);
1753 /* Power and PLL Control */
1754 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1755 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1756 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1757 data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1758 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1759 /* Loopback register */
1760 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
1761 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
1762 /* rx control 1 */
1763 mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
1764 data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
1765 mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
1766 data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
1767 reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
1768 /* DTL Control */
1769 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG,
1770 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET,
1771 HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK);
1772
1773 /* Set analog parameters from ETP(HW) */
1774 debug("stage: Analog parameters from ETP(HW)\n");
1775 /* SERDES External Configuration 2 */
1776 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG,
1777 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET,
1778 SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK);
1779 /* 0x7-DFE Resolution control */
1780 reg_set(hpipe_addr + HPIPE_DFE_REG0, 0x1 << HPIPE_DFE_RES_FORCE_OFFSET,
1781 HPIPE_DFE_RES_FORCE_MASK);
1782 /* 0xd-G1_Setting_0 */
1783 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
1784 0xd << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
1785 HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
1786 /* 0xE-G1_Setting_1 */
1787 mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
1788 data = 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001789 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
1790 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001791 mask |= HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
1792 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
1793 reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
1794 /* 0xA-DFE_Reg3 */
1795 mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
1796 data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
1797 mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
1798 data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
1799 reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
1800
1801 /* 0x111-G1_Setting_4 */
1802 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1803 data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1804 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
1805
1806 debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
1807 /* SERDES External Configuration */
1808 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1809 data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1810 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1811 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1812 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1813 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1814 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1815
1816
1817 /* check PLL rx & tx ready */
1818 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1819 data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
1820 SD_EXTERNAL_STATUS0_PLL_TX_MASK;
1821 mask = data;
1822 data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
1823 if (data != 0) {
1824 debug("Read from reg = %lx - value = 0x%x\n",
1825 sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
1826 ERROR("SD_EXTERNAL_STATUS0_PLL_RX is %d, -\"-_PLL_TX is %d\n",
1827 (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK),
1828 (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK));
1829 ret = -ETIMEDOUT;
1830 }
1831
1832 /* RX init */
1833 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG,
1834 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET,
1835 SD_EXTERNAL_CONFIG1_RX_INIT_MASK);
1836
1837 /* check that RX init done */
1838 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1839 data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
1840 mask = data;
1841 data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
1842 if (data != 0) {
1843 debug("Read from reg = %lx - value = 0x%x\n",
1844 sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
1845 ERROR("SD_EXTERNAL_STATUS0_RX_INIT is 0\n");
1846 ret = -ETIMEDOUT;
1847 }
1848
1849 debug("stage: RF Reset\n");
1850 /* RF Reset */
1851 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1852 data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1853 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1854 data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1855 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1856
1857 debug_exit();
1858
1859 return ret;
1860}
1861
1862static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base,
1863 uint8_t comphy_index, uint32_t comphy_mode)
1864{
1865 uintptr_t hpipe_addr, comphy_addr, addr;
1866 uint32_t mask, data;
1867 int ret = 0;
1868
1869 debug_enter();
1870
1871 /* Configure PIPE selector for USB3 */
1872 mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
1873 comphy_mode);
1874
1875 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1876 comphy_index);
1877 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1878
1879 debug("stage: RFU configurations - hard reset comphy\n");
1880 /* RFU configurations - hard reset comphy */
1881 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1882 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1883 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1884 data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1885 mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1886 data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1887 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1888 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1889 mask |= COMMON_PHY_PHY_MODE_MASK;
1890 data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET;
1891 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1892
1893 /* release from hard reset */
1894 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1895 data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1896 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1897 data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1898 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1899
1900 /* Wait 1ms - until band gap and ref clock ready */
1901 mdelay(1);
1902
1903 /* Start comphy Configuration */
1904 debug("stage: Comphy configuration\n");
1905 /* Set PIPE soft reset */
1906 mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
1907 data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
1908 /* Set PHY datapath width mode for V0 */
1909 mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
1910 data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
1911 /* Set Data bus width USB mode for V0 */
1912 mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
1913 data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
1914 /* Set CORE_CLK output frequency for 250Mhz */
1915 mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
1916 data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
1917 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
1918 /* Set PLL ready delay for 0x2 */
1919 reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG,
1920 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
1921 HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
1922 /* Set reference clock to come from group 1 - 25Mhz */
1923 reg_set(hpipe_addr + HPIPE_MISC_REG,
1924 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
1925 HPIPE_MISC_REFCLK_SEL_MASK);
1926 /* Set reference frequcency select - 0x2 */
1927 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1928 data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1929 /* Set PHY mode to USB - 0x5 */
1930 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1931 data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1932 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1933 /* Set the amount of time spent in the LoZ state - set for 0x7 */
1934 reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
1935 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
1936 HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
1937 /* Set max PHY generation setting - 5Gbps */
1938 reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
1939 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
1940 HPIPE_INTERFACE_GEN_MAX_MASK);
1941 /* Set select data width 20Bit (SEL_BITS[2:0]) */
1942 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
1943 0x1 << HPIPE_LOOPBACK_SEL_OFFSET,
1944 HPIPE_LOOPBACK_SEL_MASK);
1945 /* select de-emphasize 3.5db */
1946 reg_set(hpipe_addr + HPIPE_LANE_CONFIG0_REG,
1947 0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET,
1948 HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK);
1949 /* override tx margining from the MAC */
1950 reg_set(hpipe_addr + HPIPE_TST_MODE_CTRL_REG,
1951 0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET,
1952 HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK);
1953
1954 /* Start analog parameters from ETP(HW) */
1955 debug("stage: Analog parameters from ETP(HW)\n");
1956 /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */
1957 mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK;
1958 data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET;
1959 /* Set Override PHY DFE control pins for 0x1 */
1960 mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK;
1961 data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET;
1962 /* Set Spread Spectrum Clock Enable fot 0x1 */
1963 mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK;
1964 data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET;
1965 reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
1966 /* Confifure SSC amplitude */
1967 mask = HPIPE_G2_TX_SSC_AMP_MASK;
1968 data = 0x1f << HPIPE_G2_TX_SSC_AMP_OFFSET;
1969 reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
1970 /* End of analog parameters */
1971
1972 debug("stage: Comphy power up\n");
1973 /* Release from PIPE soft reset */
1974 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
1975 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
1976 HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
1977
1978 /* wait 15ms - for comphy calibration done */
1979 debug("stage: Check PLL\n");
1980 /* Read lane status */
1981 addr = hpipe_addr + HPIPE_LANE_STATUS1_REG;
1982 data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
1983 mask = data;
1984 data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
1985 if (data != 0) {
1986 debug("Read from reg = %lx - value = 0x%x\n",
1987 hpipe_addr + HPIPE_LANE_STATUS1_REG, data);
1988 ERROR("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n");
1989 ret = -ETIMEDOUT;
1990 }
1991
1992 debug_exit();
1993
1994 return ret;
1995}
1996
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001997int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base,
1998 uint8_t comphy_index)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001999{
2000 uint32_t mask, data, timeout;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002001 uint32_t g1_ffe_cap_sel, g1_ffe_res_sel, align90, g1_dfe_res;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002002 uintptr_t hpipe_addr, sd_ip_addr;
2003
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002004 uint8_t ap_nr, cp_nr;
2005
2006 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
2007
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002008 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2009 comphy_index);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002010 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2011 comphy_index);
2012
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002013 debug_enter();
2014
2015 debug("stage: RF Reset\n");
2016
2017 /* Release from hard reset */
2018 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
2019 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
2020 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
2021 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
2022 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2023 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2024 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2025
2026 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
2027 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
2028 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
2029 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
2030 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2031
2032 /* Wait 50ms - until band gap and ref clock ready */
2033 mdelay(50);
2034
2035 debug("Preparation for rx_training\n\n");
2036
2037 /* Use the FFE table */
2038 mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
2039 data = 0 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
2040 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
2041
2042 /* Use auto-calibration value */
2043 mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
2044 data = 0 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
2045 reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
2046 data, mask);
2047
2048 /* Use Tx/Rx training results */
2049 mask = HPIPE_DFE_RES_FORCE_MASK;
2050 data = 0 << HPIPE_DFE_RES_FORCE_OFFSET;
2051 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
2052
2053 debug("PRBS31 loppback\n\n");
2054
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002055 /* Configure PRBS counters */
2056 mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK;
2057 data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET;
2058 reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
2059
2060 mask = HPIPE_PHY_TEST_DATA_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002061 data = 0xc4 << HPIPE_PHY_TEST_DATA_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002062 reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask);
2063
2064 mask = HPIPE_PHY_TEST_EN_MASK;
2065 data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET;
2066 reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
2067
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002068 mdelay(10);
2069 debug("Enable TX/RX training\n\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002070
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002071 mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
2072 data = 0x1 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
2073 mask |= HPIPE_TRX_RX_ANA_IF_CLK_ENE_MASK;
2074 data |= 0x1 << HPIPE_TRX_RX_ANA_IF_CLK_ENE_OFFSET;
2075 mask |= HPIPE_TRX_TX_CTRL_CLK_EN_MASK;
2076 data |= 0x1 << HPIPE_TRX_TX_CTRL_CLK_EN_OFFSET;
2077 mask |= HPIPE_TRX_UPDATE_THEN_HOLD_MASK;
2078 data |= 0x1 << HPIPE_TRX_UPDATE_THEN_HOLD_OFFSET;
2079 mask |= HPIPE_TRX_TX_F0T_EO_BASED_MASK;
2080 data |= 0x1 << HPIPE_TRX_TX_F0T_EO_BASED_OFFSET;
2081 reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002082
2083 /* Check the result of RX training */
2084 timeout = RX_TRAINING_TIMEOUT;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002085 mask = HPIPE_INTERRUPT_TRX_TRAIN_DONE_OFFSET |
2086 HPIPE_INTERRUPT_DFE_DONE_INT_OFFSET |
2087 HPIPE_INTERRUPT_RX_TRAIN_COMPLETE_INT_MASK;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002088 while (timeout) {
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002089 data = mmio_read_32(hpipe_addr + HPIPE_INTERRUPT_1_REGISTER);
2090 if (data & mask)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002091 break;
2092 mdelay(1);
2093 timeout--;
2094 }
2095
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002096 debug("RX training result: interrupt reg 0x%lx = 0x%x\n\n",
2097 hpipe_addr + HPIPE_INTERRUPT_1_REGISTER, data);
2098
2099 if (timeout == 0 || data & HPIPE_TRX_TRAIN_TIME_OUT_INT_MASK) {
2100 ERROR("Rx training timeout...\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002101 return -ETIMEDOUT;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002102 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002103
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002104 if (data & HPIPE_TRX_TRAIN_FAILED_MASK) {
2105 ERROR("Rx training failed...\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002106 return -EINVAL;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002107 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002108
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002109 mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
2110 data = 0x0 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
2111 reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002112
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002113 debug("Training done, reading results...\n\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002114
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002115 mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_MASK;
2116 g1_ffe_res_sel = ((mmio_read_32(hpipe_addr +
2117 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
2118 & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002119
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002120 mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_MASK;
2121 g1_ffe_cap_sel = ((mmio_read_32(hpipe_addr +
2122 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
2123 & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002124
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002125 mask = HPIPE_DATA_PHASE_ADAPTED_OS_PH_MASK;
2126 align90 = ((mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG)
2127 & mask) >> HPIPE_DATA_PHASE_ADAPTED_OS_PH_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002128
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002129 mask = HPIPE_ADAPTED_DFE_RES_MASK;
2130 g1_dfe_res = ((mmio_read_32(hpipe_addr +
2131 HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG)
2132 & mask) >> HPIPE_ADAPTED_DFE_RES_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002133
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002134 debug("================================================\n");
2135 debug("Switching to static configuration:\n");
2136 debug("FFE_RES = 0x%x FFE_CAP = 0x%x align90 = 0x%x g1_dfe_res 0x%x\n",
2137 g1_ffe_res_sel, g1_ffe_cap_sel, align90, g1_dfe_res);
2138 debug("Result after training: 0x%lx= 0x%x, 0x%lx= 0x%x, 0x%lx = 0x%x\n",
2139 (hpipe_addr + HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
2140 mmio_read_32(hpipe_addr +
2141 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
2142 (hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
2143 mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
2144 (hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG),
2145 mmio_read_32(hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG));
2146 debug("================================================\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002147
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002148 /* Update FFE_RES */
2149 mask = HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
2150 data = g1_ffe_res_sel << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
2151 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002152
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002153 /* Update FFE_CAP */
2154 mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
2155 data = g1_ffe_cap_sel << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
2156 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002157
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002158 /* Bypass the FFE table settings and use the FFE settings directly from
2159 * registers FFE_RES_SEL and FFE_CAP_SEL
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002160 */
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002161 mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
2162 data = 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
2163 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002164
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002165 /* Use the value from CAL_OS_PH_EXT */
2166 mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
2167 data = 1 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
2168 reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
2169 data, mask);
2170
2171 /* Update align90 */
2172 mask = HPIPE_CAL_OS_PH_EXT_MASK;
2173 data = align90 << HPIPE_CAL_OS_PH_EXT_OFFSET;
2174 reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
2175 data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002176
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002177 /* Force DFE resolution (use gen table value) */
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002178 mask = HPIPE_DFE_RES_FORCE_MASK;
2179 data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
2180 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
2181
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002182 /* 0x111-G1 DFE_Setting_4 */
2183 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
2184 data = g1_dfe_res << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
2185 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002186
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002187 debug("PRBS31 loppback\n\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002188
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002189 mask = HPIPE_PHY_TEST_PT_TESTMODE_MASK;
2190 data = 0x1 << HPIPE_PHY_TEST_PT_TESTMODE_OFFSET;
2191 reg_set(hpipe_addr + HPIPE_PHY_TEST_OOB_0_REGISTER, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002192
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002193 /* Configure PRBS counters */
2194 mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK;
2195 data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET;
2196 reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002197
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002198 mask = HPIPE_PHY_TEST_DATA_MASK;
2199 data = 0xc4 << HPIPE_PHY_TEST_DATA_OFFSET;
2200 reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002201
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002202 mask = HPIPE_PHY_TEST_EN_MASK;
2203 data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET;
2204 reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002205
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002206 /* Reset PRBS error counter */
2207 mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK;
2208 data = 0x1 << HPIPE_PHY_TEST_RESET_OFFSET;
2209 reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
2210
2211 mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK;
2212 data = 0x0 << HPIPE_PHY_TEST_RESET_OFFSET;
2213 reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
2214
2215 mask = HPIPE_PHY_TEST_PT_TESTMODE_MASK;
2216 data = 0x1 << HPIPE_PHY_TEST_PT_TESTMODE_OFFSET;
2217 reg_set(hpipe_addr + HPIPE_PHY_TEST_OOB_0_REGISTER, data, mask);
2218
2219 printf("########################################################\n");
2220 printf("# To use trained values update the ATF sources:\n");
2221 printf("# plat/marvell/a8k/<board_type>/board/phy-porting-layer.h ");
2222 printf("file\n# with new values as below (for appropriate AP nr %d",
2223 ap_nr);
2224 printf("and CP nr: %d comphy_index %d\n\n",
2225 cp_nr, comphy_index);
2226 printf("static struct xfi_params xfi_static_values_tab[AP_NUM]");
2227 printf("[CP_NUM][MAX_LANE_NR] = {\n");
2228 printf("\t...\n");
2229 printf("\t.g1_ffe_res_sel = 0x%x,\n", g1_ffe_res_sel);
2230 printf("\t.g1_ffe_cap_sel = 0x%x,\n", g1_ffe_cap_sel);
2231 printf("\t.align90 = 0x%x,\n", align90);
2232 printf("\t.g1_dfe_res = 0x%x\n", g1_dfe_res);
2233 printf("\t...\n");
2234 printf("};\n\n");
2235 printf("########################################################\n");
2236
2237 /* check */
2238 debug("PRBS error counter[0x%lx] 0x%x\n\n",
2239 hpipe_addr + HPIPE_PHY_TEST_PRBS_ERROR_COUNTER_1_REG,
2240 mmio_read_32(hpipe_addr +
2241 HPIPE_PHY_TEST_PRBS_ERROR_COUNTER_1_REG));
2242
2243 rx_trainng_done[ap_nr][cp_nr][comphy_index] = 1;
2244
2245 return 0;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002246}
2247
2248/* During AP the proper mode is auto-negotiated and the mac, pcs and serdes
2249 * configuration are done by the firmware loaded to the MG's CM3 for appropriate
2250 * negotiated mode. Therefore there is no need to configure the mac, pcs and
2251 * serdes from u-boot. The only thing that need to be setup is powering up
2252 * the comphy, which is done through Common PHY<n> Configuration 1 Register
2253 * (CP0: 0xF2441000, CP1: 0xF4441000). This step can't be done by MG's CM3,
2254 * since it doesn't have an access to this register-set (but it has access to
2255 * the network registers like: MG, AP, MAC, PCS, Serdes etc.)
2256 */
2257static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base,
2258 uint8_t comphy_index)
2259{
2260 uint32_t mask, data;
2261 uintptr_t comphy_addr = comphy_addr =
2262 COMPHY_ADDR(comphy_base, comphy_index);
2263
2264 debug_enter();
2265 debug("stage: RFU configurations - hard reset comphy\n");
2266 /* RFU configurations - hard reset comphy */
2267 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
2268 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
2269 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
2270 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
2271 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
2272 debug_exit();
2273
2274 return 0;
2275}
2276
2277/*
2278 * This function allows to reset the digital synchronizers between
2279 * the MAC and the PHY, it is required when the MAC changes its state.
2280 */
2281int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base,
2282 uint8_t comphy_index,
2283 uint32_t comphy_mode, uint32_t command)
2284{
2285 int mode = COMPHY_GET_MODE(comphy_mode);
2286 uintptr_t sd_ip_addr;
2287 uint32_t mask, data;
2288
2289 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2290 comphy_index);
2291
2292 switch (mode) {
2293 case (COMPHY_SGMII_MODE):
2294 case (COMPHY_HS_SGMII_MODE):
2295 case (COMPHY_XFI_MODE):
2296 case (COMPHY_SFI_MODE):
2297 case (COMPHY_RXAUI_MODE):
2298 mask = SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2299 data = ((command == COMPHY_COMMAND_DIGITAL_PWR_OFF) ?
2300 0x0 : 0x1) << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2301 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2302 break;
2303 default:
2304 ERROR("comphy%d: Digital PWR ON/OFF is not supported\n",
2305 comphy_index);
2306 return -EINVAL;
2307 }
2308
2309 return 0;
2310}
2311
Grzegorz Jaszczyk4cff3082018-07-12 07:40:34 +02002312int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint8_t comphy_index,
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002313 uint64_t comphy_mode)
2314{
2315 int mode = COMPHY_GET_MODE(comphy_mode);
2316 int err = 0;
2317
2318 debug_enter();
2319
2320 switch (mode) {
2321 case(COMPHY_SATA_MODE):
2322 err = mvebu_cp110_comphy_sata_power_on(comphy_base,
2323 comphy_index,
2324 comphy_mode);
2325 break;
2326 case(COMPHY_SGMII_MODE):
2327 case(COMPHY_HS_SGMII_MODE):
2328 err = mvebu_cp110_comphy_sgmii_power_on(comphy_base,
2329 comphy_index,
2330 comphy_mode);
2331 break;
2332 /* From comphy perspective, XFI and SFI are the same */
2333 case (COMPHY_XFI_MODE):
2334 case (COMPHY_SFI_MODE):
2335 err = mvebu_cp110_comphy_xfi_power_on(comphy_base,
2336 comphy_index,
2337 comphy_mode);
2338 break;
2339 case (COMPHY_PCIE_MODE):
2340 err = mvebu_cp110_comphy_pcie_power_on(comphy_base,
2341 comphy_index,
2342 comphy_mode);
2343 break;
2344 case (COMPHY_RXAUI_MODE):
2345 err = mvebu_cp110_comphy_rxaui_power_on(comphy_base,
2346 comphy_index,
2347 comphy_mode);
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002348 break;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002349 case (COMPHY_USB3H_MODE):
2350 case (COMPHY_USB3D_MODE):
2351 err = mvebu_cp110_comphy_usb3_power_on(comphy_base,
2352 comphy_index,
2353 comphy_mode);
2354 break;
2355 case (COMPHY_AP_MODE):
2356 err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index);
2357 break;
2358 default:
Grzegorz Jaszczyk4cff3082018-07-12 07:40:34 +02002359 ERROR("comphy%d: unsupported comphy mode\n", comphy_index);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002360 err = -EINVAL;
2361 break;
2362 }
2363
2364 debug_exit();
2365
2366 return err;
2367}
2368
Grzegorz Jaszczyk4cff3082018-07-12 07:40:34 +02002369int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint8_t comphy_index)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002370{
2371 uintptr_t sd_ip_addr, comphy_ip_addr;
2372 uint32_t mask, data;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002373 uint8_t ap_nr, cp_nr;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002374
2375 debug_enter();
2376
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002377 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
2378
2379 if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) {
2380 debug("Skip %s for comphy[%d][%d][%d], due to rx training\n",
2381 __func__, ap_nr, cp_nr, comphy_index);
2382 return 0;
2383 }
2384
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002385 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2386 comphy_index);
2387 comphy_ip_addr = COMPHY_ADDR(comphy_base, comphy_index);
2388
2389 /* Hard reset the comphy, for Ethernet modes and Sata */
2390 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
2391 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
2392 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
2393 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
2394 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2395 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2396 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2397
2398 /* PCIe reset */
2399 spin_lock(&cp110_mac_reset_lock);
2400
2401 /* The mvebu_cp110_comphy_power_off will be called only from Linux (to
2402 * override settings done by bootloader) and it will be relevant only
2403 * to PCIe (called before check if to skip pcie power off or not).
2404 */
2405 data = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2406 SYS_CTRL_UINIT_SOFT_RESET_REG);
2407 switch (comphy_index) {
2408 case COMPHY_LANE0:
2409 data &= ~PCIE_MAC_RESET_MASK_PORT0;
2410 break;
2411 case COMPHY_LANE4:
2412 data &= ~PCIE_MAC_RESET_MASK_PORT1;
2413 break;
2414 case COMPHY_LANE5:
2415 data &= ~PCIE_MAC_RESET_MASK_PORT2;
2416 break;
2417 }
2418
2419 mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2420 SYS_CTRL_UINIT_SOFT_RESET_REG, data);
2421 spin_unlock(&cp110_mac_reset_lock);
2422
2423 /* Hard reset the comphy, for PCIe and usb3 */
2424 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
2425 data = 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
2426 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
2427 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
2428 reg_set(comphy_ip_addr + COMMON_PHY_CFG1_REG, data, mask);
2429
2430 /* Clear comphy PHY and PIPE selector, can't rely on previous config. */
2431 mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
2432 mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
2433
2434 debug_exit();
2435
2436 return 0;
2437}