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