blob: 3313a42cb5fde5a72615d920f0083f760bc086d8 [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 Jaszczyk3eb5e402019-03-08 19:51:21 +01002015static void rx_pre_train(uint64_t comphy_base, uint8_t comphy_index)
2016{
2017 uintptr_t hpipe_addr;
2018 uint32_t mask, data;
2019
2020 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2021 comphy_index);
2022
2023 debug("rx_training preparation\n\n");
2024
2025 mask = HPIPE_TRX0_GAIN_TRAIN_WITH_C_MASK;
2026 data = (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF);
2027 mask |= HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_MASK;
2028 data |= (0x0 << HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF);
2029 reg_set(hpipe_addr + HPIPE_TRX0_REG, data, mask);
2030
2031
2032 mask = HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK;
2033 data = (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF);
2034 mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_MASK;
2035 data |= (0x0 << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF);
2036 reg_set(hpipe_addr + HPIPE_TRX_REG2, data, mask);
2037
2038 mask = HPIPE_TRX_REG1_MIN_BOOST_MODE_MASK;
2039 data = (0x1 << HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF);
2040 reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask);
2041
2042 mask = HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_MASK;
2043 data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF);
2044 reg_set(hpipe_addr + HPIPE_CDR_CONTROL1_REG, data, mask);
2045
2046 mask = HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_MASK;
2047 data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF);
2048 reg_set(hpipe_addr + HPIPE_CDR_CONTROL2_REG, data, mask);
2049
2050 mask = HPIPE_CRD_MIDPOINT_PHASE_OS_MASK;
2051 data = (0x0 << HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET);
2052 reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
2053
2054 mask = HPIPE_TRX_REG1_SUMFTAP_EN_MASK;
2055 data = (0x38 << HPIPE_TRX_REG1_SUMFTAP_EN_OFF);
2056 mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK;
2057 data |= (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF);
2058 reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask);
2059}
2060
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002061int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base,
2062 uint8_t comphy_index)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002063{
2064 uint32_t mask, data, timeout;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002065 uint32_t g1_ffe_cap_sel, g1_ffe_res_sel, align90, g1_dfe_res;
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002066 uintptr_t hpipe_addr;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002067
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002068 uint8_t ap_nr, cp_nr;
2069
2070 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
2071
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002072 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2073 comphy_index);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002074
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002075 debug_enter();
2076
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002077 rx_pre_train(comphy_base, comphy_index);
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002078
2079 debug("Preparation for rx_training\n\n");
2080
2081 /* Use the FFE table */
2082 mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
2083 data = 0 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
2084 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
2085
2086 /* Use auto-calibration value */
2087 mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
2088 data = 0 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
2089 reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
2090 data, mask);
2091
2092 /* Use Tx/Rx training results */
2093 mask = HPIPE_DFE_RES_FORCE_MASK;
2094 data = 0 << HPIPE_DFE_RES_FORCE_OFFSET;
2095 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
2096
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002097 debug("Enable RX training\n\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002098
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002099 mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
2100 data = 0x1 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002101 reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002102
2103 /* Check the result of RX training */
2104 timeout = RX_TRAINING_TIMEOUT;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002105 mask = HPIPE_INTERRUPT_TRX_TRAIN_DONE_OFFSET |
2106 HPIPE_INTERRUPT_DFE_DONE_INT_OFFSET |
2107 HPIPE_INTERRUPT_RX_TRAIN_COMPLETE_INT_MASK;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002108 while (timeout) {
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002109 data = mmio_read_32(hpipe_addr + HPIPE_INTERRUPT_1_REGISTER);
2110 if (data & mask)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002111 break;
2112 mdelay(1);
2113 timeout--;
2114 }
2115
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002116 debug("RX training result: interrupt reg 0x%lx = 0x%x\n\n",
2117 hpipe_addr + HPIPE_INTERRUPT_1_REGISTER, data);
2118
2119 if (timeout == 0 || data & HPIPE_TRX_TRAIN_TIME_OUT_INT_MASK) {
2120 ERROR("Rx training timeout...\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002121 return -ETIMEDOUT;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002122 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002123
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002124 if (data & HPIPE_TRX_TRAIN_FAILED_MASK) {
2125 ERROR("Rx training failed...\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002126 return -EINVAL;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002127 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002128
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002129 mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
2130 data = 0x0 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
2131 reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002132
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002133 debug("Training done, reading results...\n\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002134
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002135 mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_MASK;
2136 g1_ffe_res_sel = ((mmio_read_32(hpipe_addr +
2137 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
2138 & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002139
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002140 mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_MASK;
2141 g1_ffe_cap_sel = ((mmio_read_32(hpipe_addr +
2142 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
2143 & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002144
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002145 mask = HPIPE_DATA_PHASE_ADAPTED_OS_PH_MASK;
2146 align90 = ((mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG)
2147 & mask) >> HPIPE_DATA_PHASE_ADAPTED_OS_PH_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002148
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002149 mask = HPIPE_ADAPTED_DFE_RES_MASK;
2150 g1_dfe_res = ((mmio_read_32(hpipe_addr +
2151 HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG)
2152 & mask) >> HPIPE_ADAPTED_DFE_RES_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002153
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002154 debug("================================================\n");
2155 debug("Switching to static configuration:\n");
2156 debug("FFE_RES = 0x%x FFE_CAP = 0x%x align90 = 0x%x g1_dfe_res 0x%x\n",
2157 g1_ffe_res_sel, g1_ffe_cap_sel, align90, g1_dfe_res);
2158 debug("Result after training: 0x%lx= 0x%x, 0x%lx= 0x%x, 0x%lx = 0x%x\n",
2159 (hpipe_addr + HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
2160 mmio_read_32(hpipe_addr +
2161 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
2162 (hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
2163 mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
2164 (hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG),
2165 mmio_read_32(hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG));
2166 debug("================================================\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002167
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002168 /* Update FFE_RES */
2169 mask = HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
2170 data = g1_ffe_res_sel << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
2171 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002172
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002173 /* Update FFE_CAP */
2174 mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
2175 data = g1_ffe_cap_sel << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
2176 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002177
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002178 /* Bypass the FFE table settings and use the FFE settings directly from
2179 * registers FFE_RES_SEL and FFE_CAP_SEL
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002180 */
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002181 mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
2182 data = 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
2183 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002184
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002185 /* Force DFE resolution (use gen table value) */
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002186 mask = HPIPE_DFE_RES_FORCE_MASK;
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002187 data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002188 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
2189
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002190 /* 0x111-G1 DFE_Setting_4 */
2191 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
2192 data = g1_dfe_res << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
2193 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002194
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002195 printf("########################################################\n");
2196 printf("# To use trained values update the ATF sources:\n");
Grzegorz Jaszczyk3039bce2019-11-05 13:14:59 +01002197 printf("# plat/marvell/armada/a8k/<board_type>/board/phy-porting-layer.h ");
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002198 printf("file\n# with new values as below (for appropriate AP nr %d",
2199 ap_nr);
2200 printf("and CP nr: %d comphy_index %d\n\n",
2201 cp_nr, comphy_index);
2202 printf("static struct xfi_params xfi_static_values_tab[AP_NUM]");
2203 printf("[CP_NUM][MAX_LANE_NR] = {\n");
2204 printf("\t...\n");
2205 printf("\t.g1_ffe_res_sel = 0x%x,\n", g1_ffe_res_sel);
2206 printf("\t.g1_ffe_cap_sel = 0x%x,\n", g1_ffe_cap_sel);
2207 printf("\t.align90 = 0x%x,\n", align90);
2208 printf("\t.g1_dfe_res = 0x%x\n", g1_dfe_res);
2209 printf("\t...\n");
2210 printf("};\n\n");
2211 printf("########################################################\n");
2212
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002213 rx_trainng_done[ap_nr][cp_nr][comphy_index] = 1;
2214
2215 return 0;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002216}
2217
2218/* During AP the proper mode is auto-negotiated and the mac, pcs and serdes
2219 * configuration are done by the firmware loaded to the MG's CM3 for appropriate
2220 * negotiated mode. Therefore there is no need to configure the mac, pcs and
2221 * serdes from u-boot. The only thing that need to be setup is powering up
2222 * the comphy, which is done through Common PHY<n> Configuration 1 Register
2223 * (CP0: 0xF2441000, CP1: 0xF4441000). This step can't be done by MG's CM3,
2224 * since it doesn't have an access to this register-set (but it has access to
2225 * the network registers like: MG, AP, MAC, PCS, Serdes etc.)
2226 */
2227static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base,
2228 uint8_t comphy_index)
2229{
2230 uint32_t mask, data;
2231 uintptr_t comphy_addr = comphy_addr =
2232 COMPHY_ADDR(comphy_base, comphy_index);
2233
2234 debug_enter();
2235 debug("stage: RFU configurations - hard reset comphy\n");
2236 /* RFU configurations - hard reset comphy */
2237 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
2238 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
2239 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
2240 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
2241 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
2242 debug_exit();
2243
2244 return 0;
2245}
2246
2247/*
2248 * This function allows to reset the digital synchronizers between
2249 * the MAC and the PHY, it is required when the MAC changes its state.
2250 */
2251int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base,
2252 uint8_t comphy_index,
2253 uint32_t comphy_mode, uint32_t command)
2254{
2255 int mode = COMPHY_GET_MODE(comphy_mode);
2256 uintptr_t sd_ip_addr;
2257 uint32_t mask, data;
2258
2259 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2260 comphy_index);
2261
2262 switch (mode) {
2263 case (COMPHY_SGMII_MODE):
2264 case (COMPHY_HS_SGMII_MODE):
2265 case (COMPHY_XFI_MODE):
2266 case (COMPHY_SFI_MODE):
2267 case (COMPHY_RXAUI_MODE):
2268 mask = SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2269 data = ((command == COMPHY_COMMAND_DIGITAL_PWR_OFF) ?
2270 0x0 : 0x1) << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2271 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2272 break;
2273 default:
2274 ERROR("comphy%d: Digital PWR ON/OFF is not supported\n",
2275 comphy_index);
2276 return -EINVAL;
2277 }
2278
2279 return 0;
2280}
2281
Grzegorz Jaszczyk4cff3082018-07-12 07:40:34 +02002282int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint8_t comphy_index,
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002283 uint64_t comphy_mode)
2284{
2285 int mode = COMPHY_GET_MODE(comphy_mode);
2286 int err = 0;
2287
2288 debug_enter();
2289
2290 switch (mode) {
2291 case(COMPHY_SATA_MODE):
2292 err = mvebu_cp110_comphy_sata_power_on(comphy_base,
2293 comphy_index,
2294 comphy_mode);
2295 break;
2296 case(COMPHY_SGMII_MODE):
2297 case(COMPHY_HS_SGMII_MODE):
2298 err = mvebu_cp110_comphy_sgmii_power_on(comphy_base,
2299 comphy_index,
2300 comphy_mode);
2301 break;
2302 /* From comphy perspective, XFI and SFI are the same */
2303 case (COMPHY_XFI_MODE):
2304 case (COMPHY_SFI_MODE):
2305 err = mvebu_cp110_comphy_xfi_power_on(comphy_base,
2306 comphy_index,
2307 comphy_mode);
2308 break;
2309 case (COMPHY_PCIE_MODE):
2310 err = mvebu_cp110_comphy_pcie_power_on(comphy_base,
2311 comphy_index,
2312 comphy_mode);
2313 break;
2314 case (COMPHY_RXAUI_MODE):
2315 err = mvebu_cp110_comphy_rxaui_power_on(comphy_base,
2316 comphy_index,
2317 comphy_mode);
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002318 break;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002319 case (COMPHY_USB3H_MODE):
2320 case (COMPHY_USB3D_MODE):
2321 err = mvebu_cp110_comphy_usb3_power_on(comphy_base,
2322 comphy_index,
2323 comphy_mode);
2324 break;
2325 case (COMPHY_AP_MODE):
2326 err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index);
2327 break;
2328 default:
Grzegorz Jaszczyk4cff3082018-07-12 07:40:34 +02002329 ERROR("comphy%d: unsupported comphy mode\n", comphy_index);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002330 err = -EINVAL;
2331 break;
2332 }
2333
2334 debug_exit();
2335
2336 return err;
2337}
2338
Igal Libermanbd51efd2018-11-15 16:13:11 +02002339int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint8_t comphy_index,
2340 uint64_t comphy_mode)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002341{
2342 uintptr_t sd_ip_addr, comphy_ip_addr;
2343 uint32_t mask, data;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002344 uint8_t ap_nr, cp_nr;
Igal Libermanbd51efd2018-11-15 16:13:11 +02002345 _Bool called_from_uboot = COMPHY_GET_CALLER(comphy_mode);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002346
2347 debug_enter();
2348
Igal Libermanbd51efd2018-11-15 16:13:11 +02002349 /* Power-off might happen because of 2 things:
2350 * 1. Bootloader turns off unconnected lanes
2351 * 2. Linux turns off all lanes during boot
2352 * (and then reconfigure it).
2353 *
2354 * For PCIe, there's a problem:
2355 * In Armada 8K DB boards, PCIe initialization can be executed
2356 * only once (PCIe reset performed during chip power on and
2357 * it cannot be executed via GPIO later) so a lane configured to
2358 * PCIe should not be powered off by Linux.
2359 *
2360 * So, check 2 things:
2361 * 1. Is Linux called for power-off?
2362 * 2. Is the comphy configured to PCIe?
2363 * If the answer is YES for both 1 and 2, skip the power-off.
2364 *
2365 * TODO: In MacciatoBIN, PCIe reset is connected via GPIO,
2366 * so after GPIO reset is added to Linux Kernel, it can be
2367 * powered-off.
2368 */
2369 if (!called_from_uboot) {
2370 data = mmio_read_32(comphy_base +
2371 COMMON_SELECTOR_PIPE_REG_OFFSET);
2372 data >>= (COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index);
2373 data &= COMMON_SELECTOR_COMPHY_MASK;
2374 if (data == COMMON_SELECTOR_PIPE_COMPHY_PCIE)
2375 return 0;
2376 }
2377
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002378 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
2379
2380 if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) {
2381 debug("Skip %s for comphy[%d][%d][%d], due to rx training\n",
2382 __func__, ap_nr, cp_nr, comphy_index);
2383 return 0;
2384 }
2385
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002386 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2387 comphy_index);
2388 comphy_ip_addr = COMPHY_ADDR(comphy_base, comphy_index);
2389
2390 /* Hard reset the comphy, for Ethernet modes and Sata */
2391 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
2392 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
2393 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
2394 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
2395 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2396 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2397 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2398
2399 /* PCIe reset */
2400 spin_lock(&cp110_mac_reset_lock);
2401
2402 /* The mvebu_cp110_comphy_power_off will be called only from Linux (to
2403 * override settings done by bootloader) and it will be relevant only
2404 * to PCIe (called before check if to skip pcie power off or not).
2405 */
2406 data = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2407 SYS_CTRL_UINIT_SOFT_RESET_REG);
2408 switch (comphy_index) {
2409 case COMPHY_LANE0:
2410 data &= ~PCIE_MAC_RESET_MASK_PORT0;
2411 break;
2412 case COMPHY_LANE4:
2413 data &= ~PCIE_MAC_RESET_MASK_PORT1;
2414 break;
2415 case COMPHY_LANE5:
2416 data &= ~PCIE_MAC_RESET_MASK_PORT2;
2417 break;
2418 }
2419
2420 mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2421 SYS_CTRL_UINIT_SOFT_RESET_REG, data);
2422 spin_unlock(&cp110_mac_reset_lock);
2423
2424 /* Hard reset the comphy, for PCIe and usb3 */
2425 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
2426 data = 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
2427 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
2428 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
2429 reg_set(comphy_ip_addr + COMMON_PHY_CFG1_REG, data, mask);
2430
2431 /* Clear comphy PHY and PIPE selector, can't rely on previous config. */
2432 mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
2433 mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
2434
2435 debug_exit();
2436
2437 return 0;
2438}