blob: 2760f460383d073db93e2ff166eb735bbe628c6d [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 ||
Grzegorz Jaszczyk7a61f162019-03-28 13:02:42 +0100212 mode == COMPHY_HS_SGMII_MODE ||
213 mode == COMPHY_SFI_MODE ||
214 mode == COMPHY_XFI_MODE ||
215 mode == COMPHY_AP_MODE)
Grzegorz Jaszczyk05b17732018-10-19 15:30:02 +0200216 && COMPHY_GET_ID(comphy_mode) == 1)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300217 reg |= COMMON_SELECTOR_COMPHY4_PORT1 <<
218 comphy_offset;
219 else
220 reg |= COMMON_SELECTOR_COMPHY4_ALL_OTHERS <<
221 comphy_offset;
222 break;
223 case(5):
224 /* For comphy 5:
225 * 0x1 = SGMII/HS-SGMII Port2
226 * 0x2 = RXAUI Lane1
227 */
228 if (mode == COMPHY_RXAUI_MODE)
229 reg |= COMMON_SELECTOR_COMPHY5_RXAUI <<
230 comphy_offset;
231 else
232 reg |= COMMON_SELECTOR_COMPHY5_SGMII <<
233 comphy_offset;
234 break;
235 }
236 }
237
238 mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET, reg);
239}
240
241/* PIPE selector configures for PCIe, USB 3.0 Host, and USB 3.0 Device mode */
242static void mvebu_cp110_comphy_set_pipe_selector(uint64_t comphy_base,
243 uint8_t comphy_index, uint32_t comphy_mode)
244{
245 uint32_t reg;
246 uint32_t shift = COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
247 int mode = COMPHY_GET_MODE(comphy_mode);
248 uint32_t mask = COMMON_SELECTOR_COMPHY_MASK << shift;
249 uint32_t pipe_sel = 0x0;
250
251 /* If pipe selector is used the phy selector should be marked as
252 * unconnected.
253 */
254 mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
255
256 reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
257 reg &= ~mask;
258
259 switch (mode) {
260 case (COMPHY_PCIE_MODE):
261 /* For lanes support PCIE, selector value are all same */
262 pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_PCIE;
263 break;
264
265 case (COMPHY_USB3H_MODE):
266 /* Only lane 1-4 support USB host, selector value is same */
267 if (comphy_index == COMPHY_LANE0 ||
268 comphy_index == COMPHY_LANE5)
269 ERROR("COMPHY[%d] mode[%d] is invalid\n",
270 comphy_index, mode);
271 else
272 pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBH;
273 break;
274
275 case (COMPHY_USB3D_MODE):
276 /* Lane 1 and 4 support USB device, selector value is same */
277 if (comphy_index == COMPHY_LANE1 ||
278 comphy_index == COMPHY_LANE4)
279 pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBD;
280 else
281 ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index,
282 mode);
283 break;
284
285 default:
286 ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode);
287 break;
288 }
289
290 mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET, reg |
291 (pipe_sel << shift));
292}
293
294int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index)
295{
296 uintptr_t sd_ip_addr, addr;
297 uint32_t mask, data;
298 int ret = 0;
299
300 debug_enter();
301
302 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
303 comphy_index);
304
305 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
306 data = SD_EXTERNAL_STATUS0_PLL_TX_MASK &
307 SD_EXTERNAL_STATUS0_PLL_RX_MASK;
308 mask = data;
309 data = polling_with_timeout(addr, data, mask,
310 PLL_LOCK_TIMEOUT, REG_32BIT);
311 if (data != 0) {
312 if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
313 ERROR("RX PLL is not locked\n");
314 if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
315 ERROR("TX PLL is not locked\n");
316
317 ret = -ETIMEDOUT;
318 }
319
320 debug_exit();
321
322 return ret;
323}
324
325static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base,
326 uint8_t comphy_index, uint32_t comphy_mode)
327{
328 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr;
329 uint32_t mask, data;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200330 uint8_t ap_nr, cp_nr;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300331 int ret = 0;
332
333 debug_enter();
334
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200335 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
336
337 const struct sata_params *sata_static_values =
338 &sata_static_values_tab[ap_nr][cp_nr][comphy_index];
339
340
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300341 /* configure phy selector for SATA */
342 mvebu_cp110_comphy_set_phy_selector(comphy_base,
343 comphy_index, comphy_mode);
344
345 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
346 comphy_index);
347 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
348 comphy_index);
349 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
350
351 debug(" add hpipe 0x%lx, sd 0x%lx, comphy 0x%lx\n",
352 hpipe_addr, sd_ip_addr, comphy_addr);
353 debug("stage: RFU configurations - hard reset comphy\n");
354 /* RFU configurations - hard reset comphy */
355 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
356 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
357 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
358 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
359 mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
360 data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
361 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
362 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
363 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
364
365 /* Set select data width 40Bit - SATA mode only */
366 reg_set(comphy_addr + COMMON_PHY_CFG6_REG,
367 0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET,
368 COMMON_PHY_CFG6_IF_40_SEL_MASK);
369
370 /* release from hard reset in SD external */
371 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
372 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
373 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
374 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
375 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
376
377 /* Wait 1ms - until band gap and ref clock ready */
378 mdelay(1);
379
380 debug("stage: Comphy configuration\n");
381 /* Start comphy Configuration */
382 /* Set reference clock to comes from group 1 - choose 25Mhz */
383 reg_set(hpipe_addr + HPIPE_MISC_REG,
384 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
385 HPIPE_MISC_REFCLK_SEL_MASK);
386 /* Reference frequency select set 1 (for SATA = 25Mhz) */
387 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
388 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
389 /* PHY mode select (set SATA = 0x0 */
390 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
391 data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
392 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
393 /* Set max PHY generation setting - 6Gbps */
394 reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
395 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
396 HPIPE_INTERFACE_GEN_MAX_MASK);
397 /* Set select data width 40Bit (SEL_BITS[2:0]) */
398 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
399 0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
400
401 debug("stage: Analog parameters from ETP(HW)\n");
402 /* G1 settings */
403 mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200404 data = sata_static_values->g1_rx_selmupi <<
405 HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +0200406 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200407 data |= sata_static_values->g1_rx_selmupf <<
408 HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300409 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200410 data |= sata_static_values->g1_rx_selmufi <<
411 HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300412 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200413 data |= sata_static_values->g1_rx_selmuff <<
414 HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300415 mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
416 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
417 reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
418
419 mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
420 data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
421 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
422 data |= 0x2 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
423 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
424 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
425 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_MASK;
426 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET;
427 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_MASK;
428 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET;
429 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
430
431 /* G2 settings */
432 mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200433 data = sata_static_values->g2_rx_selmupi <<
434 HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +0200435 mask |= HPIPE_G2_SET_1_G2_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200436 data |= sata_static_values->g2_rx_selmupf <<
437 HPIPE_G2_SET_1_G2_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300438 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200439 data |= sata_static_values->g2_rx_selmufi <<
440 HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300441 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200442 data |= sata_static_values->g2_rx_selmuff <<
443 HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300444 mask |= HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_MASK;
445 data |= 0x1 << HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET;
446 reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
447
448 /* G3 settings */
449 mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200450 data = sata_static_values->g3_rx_selmupi <<
451 HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300452 mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200453 data |= sata_static_values->g3_rx_selmupf <<
454 HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300455 mask |= HPIPE_G3_SET_1_G3_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200456 data |= sata_static_values->g3_rx_selmufi <<
457 HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300458 mask |= HPIPE_G3_SET_1_G3_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200459 data |= sata_static_values->g3_rx_selmuff <<
460 HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300461 mask |= HPIPE_G3_SET_1_G3_RX_DFE_EN_MASK;
462 data |= 0x1 << HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET;
463 mask |= HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_MASK;
464 data |= 0x2 << HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET;
465 mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
466 data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
467 reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
468
469 /* DTL Control */
470 mask = HPIPE_PWR_CTR_DTL_SQ_DET_EN_MASK;
471 data = 0x1 << HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET;
472 mask |= HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_MASK;
473 data |= 0x1 << HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET;
474 mask |= HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
475 data |= 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
476 mask |= HPIPE_PWR_CTR_DTL_CLAMPING_SEL_MASK;
477 data |= 0x1 << HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET;
478 mask |= HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_MASK;
479 data |= 0x1 << HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET;
480 mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_MASK;
481 data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET;
482 mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_MASK;
483 data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET;
484 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
485
486 /* Trigger sampler enable pulse */
487 mask = HPIPE_SMAPLER_MASK;
488 data = 0x1 << HPIPE_SMAPLER_OFFSET;
489 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
490 mask = HPIPE_SMAPLER_MASK;
491 data = 0x0 << HPIPE_SMAPLER_OFFSET;
492 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
493
494 /* VDD Calibration Control 3 */
495 mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
496 data = 0x10 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
497 reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
498
499 /* DFE Resolution Control */
500 mask = HPIPE_DFE_RES_FORCE_MASK;
501 data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
502 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
503
504 /* DFE F3-F5 Coefficient Control */
505 mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
506 data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
507 mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
508 data = 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
509 reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
510
511 /* G3 Setting 3 */
512 mask = HPIPE_G3_FFE_CAP_SEL_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200513 data = sata_static_values->g3_ffe_cap_sel <<
514 HPIPE_G3_FFE_CAP_SEL_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300515 mask |= HPIPE_G3_FFE_RES_SEL_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200516 data |= sata_static_values->g3_ffe_res_sel <<
517 HPIPE_G3_FFE_RES_SEL_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300518 mask |= HPIPE_G3_FFE_SETTING_FORCE_MASK;
519 data |= 0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET;
520 mask |= HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
521 data |= 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
522 mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
523 data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
524 reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
525
526 /* G3 Setting 4 */
527 mask = HPIPE_G3_DFE_RES_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200528 data = sata_static_values->g3_dfe_res << HPIPE_G3_DFE_RES_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300529 reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
530
531 /* Offset Phase Control */
532 mask = HPIPE_OS_PH_OFFSET_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200533 data = sata_static_values->align90 << HPIPE_OS_PH_OFFSET_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300534 mask |= HPIPE_OS_PH_OFFSET_FORCE_MASK;
535 data |= 0x1 << HPIPE_OS_PH_OFFSET_FORCE_OFFSET;
536 mask |= HPIPE_OS_PH_VALID_MASK;
537 data |= 0x0 << HPIPE_OS_PH_VALID_OFFSET;
538 reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
539 mask = HPIPE_OS_PH_VALID_MASK;
540 data = 0x1 << HPIPE_OS_PH_VALID_OFFSET;
541 reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
542 mask = HPIPE_OS_PH_VALID_MASK;
543 data = 0x0 << HPIPE_OS_PH_VALID_OFFSET;
544 reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
545
546 /* Set G1 TX amplitude and TX post emphasis value */
547 mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200548 data = sata_static_values->g1_amp << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300549 mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200550 data |= sata_static_values->g1_tx_amp_adj <<
551 HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300552 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200553 data |= sata_static_values->g1_emph <<
554 HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300555 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200556 data |= sata_static_values->g1_emph_en <<
557 HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300558 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
559
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200560 /* Set G1 emph */
561 mask = HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
562 data = sata_static_values->g1_tx_emph_en <<
563 HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
564 mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
565 data |= sata_static_values->g1_tx_emph <<
566 HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
567 reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
568
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300569 /* Set G2 TX amplitude and TX post emphasis value */
570 mask = HPIPE_G2_SET_0_G2_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200571 data = sata_static_values->g2_amp << HPIPE_G2_SET_0_G2_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300572 mask |= HPIPE_G2_SET_0_G2_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200573 data |= sata_static_values->g2_tx_amp_adj <<
574 HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300575 mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200576 data |= sata_static_values->g2_emph <<
577 HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300578 mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200579 data |= sata_static_values->g2_emph_en <<
580 HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300581 reg_set(hpipe_addr + HPIPE_G2_SET_0_REG, data, mask);
582
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200583 /* Set G2 emph */
584 mask = HPIPE_G2_SET_2_G2_TX_EMPH0_EN_MASK;
585 data = sata_static_values->g2_tx_emph_en <<
586 HPIPE_G2_SET_2_G2_TX_EMPH0_EN_OFFSET;
587 mask |= HPIPE_G2_SET_2_G2_TX_EMPH0_MASK;
588 data |= sata_static_values->g2_tx_emph <<
589 HPIPE_G2_SET_2_G2_TX_EMPH0_OFFSET;
590 reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
591
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300592 /* Set G3 TX amplitude and TX post emphasis value */
593 mask = HPIPE_G3_SET_0_G3_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200594 data = sata_static_values->g3_amp << HPIPE_G3_SET_0_G3_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300595 mask |= HPIPE_G3_SET_0_G3_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200596 data |= sata_static_values->g3_tx_amp_adj <<
597 HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300598 mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200599 data |= sata_static_values->g3_emph <<
600 HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300601 mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200602 data |= sata_static_values->g3_emph_en <<
603 HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300604 mask |= HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_MASK;
605 data |= 0x4 << HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET;
606 mask |= HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_MASK;
607 data |= 0x0 << HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET;
608 reg_set(hpipe_addr + HPIPE_G3_SET_0_REG, data, mask);
609
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200610 /* Set G3 emph */
611 mask = HPIPE_G3_SET_2_G3_TX_EMPH0_EN_MASK;
612 data = sata_static_values->g3_tx_emph_en <<
613 HPIPE_G3_SET_2_G3_TX_EMPH0_EN_OFFSET;
614 mask |= HPIPE_G3_SET_2_G3_TX_EMPH0_MASK;
615 data |= sata_static_values->g3_tx_emph <<
616 HPIPE_G3_SET_2_G3_TX_EMPH0_OFFSET;
617 reg_set(hpipe_addr + HPIPE_G3_SET_2_REG, data, mask);
618
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300619 /* SERDES External Configuration 2 register */
620 mask = SD_EXTERNAL_CONFIG2_SSC_ENABLE_MASK;
621 data = 0x1 << SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET;
622 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
623
624 /* DFE reset sequence */
625 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
626 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
627 HPIPE_PWR_CTR_RST_DFE_MASK);
628 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
629 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
630 HPIPE_PWR_CTR_RST_DFE_MASK);
631 /* SW reset for interrupt logic */
632 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
633 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
634 HPIPE_PWR_CTR_SFT_RST_MASK);
635 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
636 0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
637 HPIPE_PWR_CTR_SFT_RST_MASK);
638
639 debug_exit();
640
641 return ret;
642}
643
644static int mvebu_cp110_comphy_sgmii_power_on(uint64_t comphy_base,
645 uint8_t comphy_index, uint32_t comphy_mode)
646{
647 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
648 uint32_t mask, data, sgmii_speed = COMPHY_GET_SPEED(comphy_mode);
649 int ret = 0;
650
651 debug_enter();
652
653 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
654 comphy_index);
655 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
656 comphy_index);
657 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
658
659 /* configure phy selector for SGMII */
660 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
661 comphy_mode);
662
663 /* Confiugre the lane */
664 debug("stage: RFU configurations - hard reset comphy\n");
665 /* RFU configurations - hard reset comphy */
666 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
667 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
668 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
669 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
670 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
671
672 /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
673 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
674 data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
675 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
676 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
677
678 if (sgmii_speed == COMPHY_SPEED_1_25G) {
679 /* SGMII 1G, SerDes speed 1.25G */
680 data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
681 data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
682 } else if (sgmii_speed == COMPHY_SPEED_3_125G) {
683 /* HS SGMII (2.5G), SerDes speed 3.125G */
684 data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
685 data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
686 } else {
687 /* Other rates are not supported */
688 ERROR("unsupported SGMII speed on comphy%d\n", comphy_index);
689 return -EINVAL;
690 }
691
692 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
693 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
694 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
695 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
696 mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
697 data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
698 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
699
700 /* Set hard reset */
701 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
702 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
703 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
704 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
705 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
706 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
707 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
708
709 /* Release hard reset */
710 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
711 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
712 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
713 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
714 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
715
716 /* Wait 1ms - until band gap and ref clock ready */
717 mdelay(1);
718
719 /* Make sure that 40 data bits is disabled
720 * This bit is not cleared by reset
721 */
722 mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
723 data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
724 reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
725
726 /* Start comphy Configuration */
727 debug("stage: Comphy configuration\n");
728 /* set reference clock */
729 mask = HPIPE_MISC_REFCLK_SEL_MASK;
730 data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
731 reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
732 /* Power and PLL Control */
733 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
734 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
735 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
736 data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
737 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
738 /* Loopback register */
739 mask = HPIPE_LOOPBACK_SEL_MASK;
740 data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
741 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
742 /* rx control 1 */
743 mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
744 data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
745 mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
746 data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
747 reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
748 /* DTL Control */
749 mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
750 data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
751 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
752
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200753 /* Set analog parameters from ETP(HW) - for now use the default data */
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300754 debug("stage: Analog parameters from ETP(HW)\n");
755
756 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
757 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
758 HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
759
760 debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
761 /* SERDES External Configuration */
762 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
763 data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
764 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
765 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
766 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
767 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
768 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
769
770 ret = mvebu_cp110_comphy_is_pll_locked(comphy_base, comphy_index);
771 if (ret)
772 return ret;
773
774 /* RX init */
775 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
776 data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
777 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
778
779 /* check that RX init done */
780 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
781 data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
782 mask = data;
783 data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
784 if (data != 0) {
785 ERROR("RX init failed\n");
786 ret = -ETIMEDOUT;
787 }
788
789 debug("stage: RF Reset\n");
790 /* RF Reset */
791 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
792 data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
793 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
794 data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
795 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
796
797 debug_exit();
798
799 return ret;
800}
801
802static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base,
803 uint8_t comphy_index,
804 uint32_t comphy_mode)
805{
806 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
807 uint32_t mask, data, speed = COMPHY_GET_SPEED(comphy_mode);
808 int ret = 0;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200809 uint8_t ap_nr, cp_nr;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300810
811 debug_enter();
812
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200813 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
814
815 if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) {
816 debug("Skip %s for comphy[%d][%d][%d], due to rx training\n",
817 __func__, ap_nr, cp_nr, comphy_index);
818 return 0;
819 }
820
821 const struct xfi_params *xfi_static_values =
822 &xfi_static_values_tab[ap_nr][cp_nr][comphy_index];
823
824 debug("%s: the ap_nr = %d, cp_nr = %d, comphy_index %d\n",
825 __func__, ap_nr, cp_nr, comphy_index);
826
827 debug("g1_ffe_cap_sel= 0x%x, g1_ffe_res_sel= 0x%x, g1_dfe_res= 0x%x\n",
828 xfi_static_values->g1_ffe_cap_sel,
829 xfi_static_values->g1_ffe_res_sel,
830 xfi_static_values->g1_dfe_res);
831
832 if (!xfi_static_values->valid) {
833 ERROR("[ap%d][cp[%d][comphy:%d]: Has no valid static params\n",
834 ap_nr, cp_nr, comphy_index);
835 ERROR("[ap%d][cp[%d][comphy:%d]: porting layer needs update\n",
836 ap_nr, cp_nr, comphy_index);
837 return -EINVAL;
838 }
839
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300840 if ((speed != COMPHY_SPEED_5_15625G) &&
841 (speed != COMPHY_SPEED_10_3125G) &&
842 (speed != COMPHY_SPEED_DEFAULT)) {
843 ERROR("comphy:%d: unsupported sfi/xfi speed\n", comphy_index);
844 return -EINVAL;
845 }
846
847 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
848 comphy_index);
849 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
850 comphy_index);
851 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
852
853 /* configure phy selector for XFI/SFI */
854 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
855 comphy_mode);
856
857 debug("stage: RFU configurations - hard reset comphy\n");
858 /* RFU configurations - hard reset comphy */
859 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
860 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
861 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
862 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
863 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
864
865 /* Make sure that 40 data bits is disabled
866 * This bit is not cleared by reset
867 */
868 mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
869 data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
870 reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
871
872 /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
873 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
874 data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
875 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
876 data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
877 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
878 data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
879 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
880 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
881 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
882 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
883 mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
884 data |= 0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
885 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
886
887 /* release from hard reset */
888 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
889 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
890 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
891 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
892 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
893 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
894 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
895
896 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
897 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
898 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
899 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
900 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
901
902 /* Wait 1ms - until band gap and ref clock ready */
903 mdelay(1);
904
905 /* Start comphy Configuration */
906 debug("stage: Comphy configuration\n");
907 /* set reference clock */
908 mask = HPIPE_MISC_ICP_FORCE_MASK;
909 data = (speed == COMPHY_SPEED_5_15625G) ?
910 (0x0 << HPIPE_MISC_ICP_FORCE_OFFSET) :
911 (0x1 << HPIPE_MISC_ICP_FORCE_OFFSET);
912 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
913 data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
914 reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
915 /* Power and PLL Control */
916 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
917 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
918 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
919 data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
920 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
921 /* Loopback register */
922 mask = HPIPE_LOOPBACK_SEL_MASK;
923 data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
924 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
925 /* rx control 1 */
926 mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
927 data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
928 mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
929 data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
930 reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
931 /* DTL Control */
932 mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
933 data = 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
934 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
935
936 /* Transmitter/Receiver Speed Divider Force */
937 if (speed == COMPHY_SPEED_5_15625G) {
938 mask = HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_MASK;
939 data = 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET;
940 mask |= HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_MASK;
941 data |= 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET;
942 mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_MASK;
943 data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET;
944 mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_MASK;
945 data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET;
946 } else {
947 mask = HPIPE_TXDIGCK_DIV_FORCE_MASK;
948 data = 0x1 << HPIPE_TXDIGCK_DIV_FORCE_OFFSET;
949 }
950 reg_set(hpipe_addr + HPIPE_SPD_DIV_FORCE_REG, data, mask);
951
952 /* Set analog parameters from ETP(HW) */
953 debug("stage: Analog parameters from ETP(HW)\n");
954 /* SERDES External Configuration 2 */
955 mask = SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK;
956 data = 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET;
957 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
958 /* 0x7-DFE Resolution control */
959 mask = HPIPE_DFE_RES_FORCE_MASK;
960 data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
961 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
962 /* 0xd-G1_Setting_0 */
963 if (speed == COMPHY_SPEED_5_15625G) {
964 mask = HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
965 data = 0x6 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
966 } else {
967 mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200968 data = xfi_static_values->g1_amp <<
969 HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300970 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200971 data |= xfi_static_values->g1_emph <<
972 HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
973
974 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
975 data |= xfi_static_values->g1_emph_en <<
976 HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
977 mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
978 data |= xfi_static_values->g1_tx_amp_adj <<
979 HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300980 }
981 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
982 /* Genration 1 setting 2 (G1_Setting_2) */
983 mask = HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200984 data = xfi_static_values->g1_tx_emph <<
985 HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300986 mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200987 data |= xfi_static_values->g1_tx_emph_en <<
988 HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300989 reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
990 /* Transmitter Slew Rate Control register (tx_reg1) */
991 mask = HPIPE_TX_REG1_TX_EMPH_RES_MASK;
992 data = 0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET;
993 mask |= HPIPE_TX_REG1_SLC_EN_MASK;
994 data |= 0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET;
995 reg_set(hpipe_addr + HPIPE_TX_REG1_REG, data, mask);
996 /* Impedance Calibration Control register (cal_reg1) */
997 mask = HPIPE_CAL_REG_1_EXT_TXIMP_MASK;
998 data = 0xe << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
999 mask |= HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK;
1000 data |= 0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET;
1001 reg_set(hpipe_addr + HPIPE_CAL_REG1_REG, data, mask);
1002 /* Generation 1 Setting 5 (g1_setting_5) */
1003 mask = HPIPE_G1_SETTING_5_G1_ICP_MASK;
1004 data = 0 << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
1005 reg_set(hpipe_addr + HPIPE_G1_SETTING_5_REG, data, mask);
1006
1007 /* 0xE-G1_Setting_1 */
1008 mask = HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
1009 data = 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
1010 if (speed == COMPHY_SPEED_5_15625G) {
1011 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
1012 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001013 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
1014 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001015 } else {
1016 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001017 data |= xfi_static_values->g1_rx_selmupi <<
1018 HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001019 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001020 data |= xfi_static_values->g1_rx_selmupf <<
1021 HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001022 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001023 data |= xfi_static_values->g1_rx_selmufi <<
1024 HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001025 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001026 data |= xfi_static_values->g1_rx_selmuff <<
1027 HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001028 mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
1029 data |= 0x3 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
1030 }
1031 reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
1032
1033 /* 0xA-DFE_Reg3 */
1034 mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
1035 data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
1036 mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
1037 data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
1038 reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
1039
1040 /* 0x111-G1_Setting_4 */
1041 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1042 data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1043 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
1044 /* Genration 1 setting 3 (G1_Setting_3) */
1045 mask = HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK;
1046 data = 0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET;
1047 if (speed == COMPHY_SPEED_5_15625G) {
1048 /* Force FFE (Feed Forward Equalization) to 5G */
1049 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
1050 data |= 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
1051 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
1052 data |= 0x4 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
1053 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
1054 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001055 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
1056 } else {
1057 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
1058 data |= xfi_static_values->g1_ffe_cap_sel <<
1059 HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
1060 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
1061 data |= xfi_static_values->g1_ffe_res_sel <<
1062 HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
1063 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
1064 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
1065 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
1066
1067 /* Use the value from CAL_OS_PH_EXT */
1068 mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
1069 data = 1 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
1070 reg_set(hpipe_addr +
1071 HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
1072 data, mask);
1073
1074 /* Update align90 */
1075 mask = HPIPE_CAL_OS_PH_EXT_MASK;
1076 data = xfi_static_values->align90 << HPIPE_CAL_OS_PH_EXT_OFFSET;
1077 reg_set(hpipe_addr +
1078 HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
1079 data, mask);
1080
1081 /* Force DFE resolution (use gen table value) */
1082 mask = HPIPE_DFE_RES_FORCE_MASK;
1083 data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
1084 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
1085
1086 /* 0x111-G1 DFE_Setting_4 */
1087 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1088 data = xfi_static_values->g1_dfe_res <<
1089 HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1090 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001091 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001092
1093 /* Connfigure RX training timer */
1094 mask = HPIPE_RX_TRAIN_TIMER_MASK;
1095 data = 0x13 << HPIPE_RX_TRAIN_TIMER_OFFSET;
1096 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
1097
1098 /* Enable TX train peak to peak hold */
1099 mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
1100 data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
1101 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
1102
1103 /* Configure TX preset index */
1104 mask = HPIPE_TX_PRESET_INDEX_MASK;
1105 data = 0x2 << HPIPE_TX_PRESET_INDEX_OFFSET;
1106 reg_set(hpipe_addr + HPIPE_TX_PRESET_INDEX_REG, data, mask);
1107
1108 /* Disable pattern lock lost timeout */
1109 mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
1110 data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
1111 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
1112
1113 /* Configure TX training pattern and TX training 16bit auto */
1114 mask = HPIPE_TX_TRAIN_16BIT_AUTO_EN_MASK;
1115 data = 0x1 << HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET;
1116 mask |= HPIPE_TX_TRAIN_PAT_SEL_MASK;
1117 data |= 0x1 << HPIPE_TX_TRAIN_PAT_SEL_OFFSET;
1118 reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
1119
1120 /* Configure Training patten number */
1121 mask = HPIPE_TRAIN_PAT_NUM_MASK;
1122 data = 0x88 << HPIPE_TRAIN_PAT_NUM_OFFSET;
1123 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_0_REG, data, mask);
1124
1125 /* Configure differencial manchester encoter to ethernet mode */
1126 mask = HPIPE_DME_ETHERNET_MODE_MASK;
1127 data = 0x1 << HPIPE_DME_ETHERNET_MODE_OFFSET;
1128 reg_set(hpipe_addr + HPIPE_DME_REG, data, mask);
1129
1130 /* Configure VDD Continuous Calibration */
1131 mask = HPIPE_CAL_VDD_CONT_MODE_MASK;
1132 data = 0x1 << HPIPE_CAL_VDD_CONT_MODE_OFFSET;
1133 reg_set(hpipe_addr + HPIPE_VDD_CAL_0_REG, data, mask);
1134
1135 /* Trigger sampler enable pulse (by toggleing the bit) */
1136 mask = HPIPE_RX_SAMPLER_OS_GAIN_MASK;
1137 data = 0x3 << HPIPE_RX_SAMPLER_OS_GAIN_OFFSET;
1138 mask |= HPIPE_SMAPLER_MASK;
1139 data |= 0x1 << HPIPE_SMAPLER_OFFSET;
1140 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1141 mask = HPIPE_SMAPLER_MASK;
1142 data = 0x0 << HPIPE_SMAPLER_OFFSET;
1143 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1144
1145 /* Set External RX Regulator Control */
1146 mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
1147 data = 0x1A << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
1148 reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
1149
1150 debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
1151 /* SERDES External Configuration */
1152 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1153 data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1154 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1155 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1156 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1157 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1158 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1159
1160 /* check PLL rx & tx ready */
1161 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1162 data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
1163 SD_EXTERNAL_STATUS0_PLL_TX_MASK;
1164 mask = data;
1165 data = polling_with_timeout(addr, data, mask,
1166 PLL_LOCK_TIMEOUT, REG_32BIT);
1167 if (data != 0) {
1168 if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
1169 ERROR("RX PLL is not locked\n");
1170 if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
1171 ERROR("TX PLL is not locked\n");
1172
1173 ret = -ETIMEDOUT;
1174 }
1175
1176 /* RX init */
1177 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1178 data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1179 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1180
1181 /* check that RX init done */
1182 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1183 data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
1184 mask = data;
1185 data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
1186 if (data != 0) {
1187 ERROR("RX init failed\n");
1188 ret = -ETIMEDOUT;
1189 }
1190
1191 debug("stage: RF Reset\n");
1192 /* RF Reset */
1193 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1194 data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1195 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1196 data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1197 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1198
1199 debug_exit();
1200
1201 return ret;
1202}
1203
1204static int mvebu_cp110_comphy_pcie_power_on(uint64_t comphy_base,
1205 uint8_t comphy_index, uint32_t comphy_mode)
1206{
1207 int ret = 0;
1208 uint32_t reg, mask, data, pcie_width;
1209 uint32_t clk_dir;
1210 uintptr_t hpipe_addr, comphy_addr, addr;
1211 _Bool clk_src = COMPHY_GET_CLK_SRC(comphy_mode);
Igal Libermanbd51efd2018-11-15 16:13:11 +02001212 _Bool called_from_uboot = COMPHY_GET_CALLER(comphy_mode);
1213
1214 /* In Armada 8K DB boards, PCIe initialization can be executed
1215 * only once (PCIe reset performed during chip power on and
1216 * it cannot be executed via GPIO later).
1217 * This means that power on can be executed only once, so let's
1218 * mark if the caller is bootloader or Linux.
1219 * If bootloader -> run power on.
1220 * If Linux -> exit.
1221 *
1222 * TODO: In MacciatoBIN, PCIe reset is connected via GPIO,
1223 * so after GPIO reset is added to Linux Kernel, it can be
1224 * powered-on by Linux.
1225 */
1226 if (!called_from_uboot)
1227 return ret;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001228
1229 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1230 comphy_index);
1231 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1232 pcie_width = COMPHY_GET_PCIE_WIDTH(comphy_mode);
1233
1234 debug_enter();
1235
1236 spin_lock(&cp110_mac_reset_lock);
1237
1238 reg = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
1239 SYS_CTRL_UINIT_SOFT_RESET_REG);
1240 switch (comphy_index) {
1241 case COMPHY_LANE0:
1242 reg |= PCIE_MAC_RESET_MASK_PORT0;
1243 break;
1244 case COMPHY_LANE4:
1245 reg |= PCIE_MAC_RESET_MASK_PORT1;
1246 break;
1247 case COMPHY_LANE5:
1248 reg |= PCIE_MAC_RESET_MASK_PORT2;
1249 break;
1250 }
1251
1252 mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
1253 SYS_CTRL_UINIT_SOFT_RESET_REG, reg);
1254 spin_unlock(&cp110_mac_reset_lock);
1255
1256 /* Configure PIPE selector for PCIE */
1257 mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
1258 comphy_mode);
1259
1260 /*
1261 * Read SAR (Sample-At-Reset) configuration for the PCIe clock
1262 * direction.
1263 *
1264 * SerDes Lane 4/5 got the PCIe ref-clock #1,
1265 * and SerDes Lane 0 got PCIe ref-clock #0
1266 */
1267 reg = mmio_read_32(DFX_FROM_COMPHY_ADDR(comphy_base) +
1268 SAR_STATUS_0_REG);
1269 if (comphy_index == COMPHY_LANE4 || comphy_index == COMPHY_LANE5)
1270 clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK) >>
1271 SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET;
1272 else
1273 clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK) >>
1274 SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET;
1275
1276 debug("On lane %d\n", comphy_index);
1277 debug("PCIe clock direction = %x\n", clk_dir);
1278 debug("PCIe Width = %d\n", pcie_width);
1279
1280 /* enable PCIe X4 and X2 */
1281 if (comphy_index == COMPHY_LANE0) {
1282 if (pcie_width == PCIE_LNK_X4) {
1283 data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET;
1284 mask = COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK;
1285 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1286 data, mask);
1287 } else if (pcie_width == PCIE_LNK_X2) {
1288 data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET;
1289 mask = COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK;
1290 reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
1291 }
1292 }
1293
1294 /* If PCIe clock is output and clock source from SerDes lane 5,
1295 * need to configure the clock-source MUX.
1296 * By default, the clock source is from lane 4
1297 */
1298 if (clk_dir && clk_src && (comphy_index == COMPHY_LANE5)) {
1299 data = DFX_DEV_GEN_PCIE_CLK_SRC_MUX <<
1300 DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET;
1301 mask = DFX_DEV_GEN_PCIE_CLK_SRC_MASK;
1302 reg_set(DFX_FROM_COMPHY_ADDR(comphy_base) +
1303 DFX_DEV_GEN_CTRL12_REG, data, mask);
1304 }
1305
1306 debug("stage: RFU configurations - hard reset comphy\n");
1307 /* RFU configurations - hard reset comphy */
1308 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1309 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1310 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1311 data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1312 mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1313 data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1314 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1315 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1316 mask |= COMMON_PHY_PHY_MODE_MASK;
1317 data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET;
1318 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1319
1320 /* release from hard reset */
1321 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1322 data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1323 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1324 data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1325 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1326
1327 /* Wait 1ms - until band gap and ref clock ready */
1328 mdelay(1);
1329 /* Start comphy Configuration */
1330 debug("stage: Comphy configuration\n");
1331 /* Set PIPE soft reset */
1332 mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
1333 data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
1334 /* Set PHY datapath width mode for V0 */
1335 mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
1336 data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
1337 /* Set Data bus width USB mode for V0 */
1338 mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
1339 data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
1340 /* Set CORE_CLK output frequency for 250Mhz */
1341 mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
1342 data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
1343 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
1344 /* Set PLL ready delay for 0x2 */
1345 data = 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET;
1346 mask = HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK;
1347 if (pcie_width != PCIE_LNK_X1) {
1348 data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET;
1349 mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK;
1350 data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET;
1351 mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK;
1352 }
1353 reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, data, mask);
1354
1355 /* Set PIPE mode interface to PCIe3 - 0x1 & set lane order */
1356 data = 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET;
1357 mask = HPIPE_CLK_SRC_HI_MODE_PIPE_MASK;
1358 if (pcie_width != PCIE_LNK_X1) {
1359 mask |= HPIPE_CLK_SRC_HI_LANE_STRT_MASK;
1360 mask |= HPIPE_CLK_SRC_HI_LANE_MASTER_MASK;
1361 mask |= HPIPE_CLK_SRC_HI_LANE_BREAK_MASK;
1362 if (comphy_index == 0) {
1363 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET;
1364 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET;
1365 } else if (comphy_index == (pcie_width - 1)) {
1366 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET;
1367 }
1368 }
1369 reg_set(hpipe_addr + HPIPE_CLK_SRC_HI_REG, data, mask);
1370 /* Config update polarity equalization */
1371 data = 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET;
1372 mask = HPIPE_CFG_UPDATE_POLARITY_MASK;
1373 reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG1_REG, data, mask);
1374 /* Set PIPE version 4 to mode enable */
1375 data = 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET;
1376 mask = HPIPE_DFE_CTRL_28_PIPE4_MASK;
1377 reg_set(hpipe_addr + HPIPE_DFE_CTRL_28_REG, data, mask);
1378 /* TODO: check if pcie clock is output/input - for bringup use input*/
1379 /* Enable PIN clock 100M_125M */
1380 mask = 0;
1381 data = 0;
1382 /* Only if clock is output, configure the clock-source mux */
1383 if (clk_dir) {
1384 mask |= HPIPE_MISC_CLK100M_125M_MASK;
1385 data |= 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET;
1386 }
1387 /* Set PIN_TXDCLK_2X Clock Freq. Selection for outputs 500MHz clock */
1388 mask |= HPIPE_MISC_TXDCLK_2X_MASK;
1389 data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET;
1390 /* Enable 500MHz Clock */
1391 mask |= HPIPE_MISC_CLK500_EN_MASK;
1392 data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET;
1393 if (clk_dir) { /* output */
1394 /* Set reference clock comes from group 1 */
1395 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
1396 data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
1397 } else {
1398 /* Set reference clock comes from group 2 */
1399 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
1400 data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET;
1401 }
1402 mask |= HPIPE_MISC_ICP_FORCE_MASK;
1403 data |= 0x1 << HPIPE_MISC_ICP_FORCE_OFFSET;
1404 reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
1405 if (clk_dir) { /* output */
1406 /* Set reference frequcency select - 0x2 for 25MHz*/
1407 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1408 data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1409 } else {
1410 /* Set reference frequcency select - 0x0 for 100MHz*/
1411 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1412 data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1413 }
1414 /* Set PHY mode to PCIe */
1415 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1416 data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1417 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1418
1419 /* ref clock alignment */
1420 if (pcie_width != PCIE_LNK_X1) {
1421 mask = HPIPE_LANE_ALIGN_OFF_MASK;
1422 data = 0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET;
1423 reg_set(hpipe_addr + HPIPE_LANE_ALIGN_REG, data, mask);
1424 }
1425
1426 /* Set the amount of time spent in the LoZ state - set for 0x7 only if
1427 * the PCIe clock is output
1428 */
1429 if (clk_dir)
1430 reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
1431 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
1432 HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
1433
1434 /* Set Maximal PHY Generation Setting(8Gbps) */
1435 mask = HPIPE_INTERFACE_GEN_MAX_MASK;
1436 data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET;
1437 /* Bypass frame detection and sync detection for RX DATA */
1438 mask |= HPIPE_INTERFACE_DET_BYPASS_MASK;
1439 data |= 0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET;
1440 /* Set Link Train Mode (Tx training control pins are used) */
1441 mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK;
1442 data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET;
1443 reg_set(hpipe_addr + HPIPE_INTERFACE_REG, data, mask);
1444
1445 /* Set Idle_sync enable */
1446 mask = HPIPE_PCIE_IDLE_SYNC_MASK;
1447 data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET;
1448 /* Select bits for PCIE Gen3(32bit) */
1449 mask |= HPIPE_PCIE_SEL_BITS_MASK;
1450 data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET;
1451 reg_set(hpipe_addr + HPIPE_PCIE_REG0, data, mask);
1452
1453 /* Enable Tx_adapt_g1 */
1454 mask = HPIPE_TX_TRAIN_CTRL_G1_MASK;
1455 data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET;
1456 /* Enable Tx_adapt_gn1 */
1457 mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK;
1458 data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET;
1459 /* Disable Tx_adapt_g0 */
1460 mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK;
1461 data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
1462 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
1463
1464 /* Set reg_tx_train_chk_init */
1465 mask = HPIPE_TX_TRAIN_CHK_INIT_MASK;
1466 data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET;
1467 /* Enable TX_COE_FM_PIN_PCIE3_EN */
1468 mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK;
1469 data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET;
1470 reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
1471
1472 debug("stage: TRx training parameters\n");
1473 /* Set Preset sweep configurations */
1474 mask = HPIPE_TX_TX_STATUS_CHECK_MODE_MASK;
1475 data = 0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET;
1476 mask |= HPIPE_TX_NUM_OF_PRESET_MASK;
1477 data |= 0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET;
1478 mask |= HPIPE_TX_SWEEP_PRESET_EN_MASK;
1479 data |= 0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET;
1480 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_11_REG, data, mask);
1481
1482 /* Tx train start configuration */
1483 mask = HPIPE_TX_TRAIN_START_SQ_EN_MASK;
1484 data = 0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET;
1485 mask |= HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK;
1486 data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET;
1487 mask |= HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK;
1488 data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET;
1489 mask |= HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK;
1490 data |= 0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET;
1491 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
1492
1493 /* Enable Tx train P2P */
1494 mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
1495 data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
1496 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
1497
1498 /* Configure Tx train timeout */
1499 mask = HPIPE_TRX_TRAIN_TIMER_MASK;
1500 data = 0x17 << HPIPE_TRX_TRAIN_TIMER_OFFSET;
1501 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_4_REG, data, mask);
1502
1503 /* Disable G0/G1/GN1 adaptation */
1504 mask = HPIPE_TX_TRAIN_CTRL_G1_MASK | HPIPE_TX_TRAIN_CTRL_GN1_MASK
1505 | HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
1506 data = 0;
1507 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
1508
1509 /* Disable DTL frequency loop */
1510 mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
1511 data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
1512 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
1513
1514 /* Configure G3 DFE */
1515 mask = HPIPE_G3_DFE_RES_MASK;
1516 data = 0x3 << HPIPE_G3_DFE_RES_OFFSET;
1517 reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
1518
1519 /* Use TX/RX training result for DFE */
1520 mask = HPIPE_DFE_RES_FORCE_MASK;
1521 data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
1522 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
1523
1524 /* Configure initial and final coefficient value for receiver */
1525 mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
1526 data = 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
1527
1528 mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
1529 data |= 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
1530
1531 mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
1532 data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
1533 reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
1534
1535 /* Trigger sampler enable pulse */
1536 mask = HPIPE_SMAPLER_MASK;
1537 data = 0x1 << HPIPE_SMAPLER_OFFSET;
1538 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1539 udelay(5);
1540 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, 0, mask);
1541
1542 /* FFE resistor tuning for different bandwidth */
1543 mask = HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
1544 data = 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
1545 mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
1546 data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
1547 reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
1548
1549 /* Pattern lock lost timeout disable */
1550 mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
1551 data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
1552 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
1553
1554 /* Configure DFE adaptations */
1555 mask = HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK;
1556 data = 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET;
1557 mask |= HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK;
1558 data |= 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET;
1559 mask |= HPIPE_CDR_MAX_DFE_ADAPT_0_MASK;
1560 data |= 0x0 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET;
1561 mask |= HPIPE_CDR_MAX_DFE_ADAPT_1_MASK;
1562 data |= 0x1 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET;
1563 reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
1564
1565 mask = HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK;
1566 data = 0x0 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET;
1567 reg_set(hpipe_addr + HPIPE_DFE_CONTROL_REG, data, mask);
1568
1569 /* Genration 2 setting 1*/
1570 mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
1571 data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001572 mask |= HPIPE_G2_SET_1_G2_RX_SELMUPF_MASK;
1573 data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001574 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
1575 data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
1576 reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
1577
1578 /* DFE enable */
1579 mask = HPIPE_G2_DFE_RES_MASK;
1580 data = 0x3 << HPIPE_G2_DFE_RES_OFFSET;
1581 reg_set(hpipe_addr + HPIPE_G2_SETTINGS_4_REG, data, mask);
1582
1583 /* Configure DFE Resolution */
1584 mask = HPIPE_LANE_CFG4_DFE_EN_SEL_MASK;
1585 data = 0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET;
1586 reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
1587
1588 /* VDD calibration control */
1589 mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
1590 data = 0x16 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
1591 reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
1592
1593 /* Set PLL Charge-pump Current Control */
1594 mask = HPIPE_G3_SETTING_5_G3_ICP_MASK;
1595 data = 0x4 << HPIPE_G3_SETTING_5_G3_ICP_OFFSET;
1596 reg_set(hpipe_addr + HPIPE_G3_SETTING_5_REG, data, mask);
1597
1598 /* Set lane rqualization remote setting */
1599 mask = HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK;
1600 data = 0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET;
1601 mask |= HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK;
1602 data |= 0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET;
1603 mask |= HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK;
1604 data |= 0x6 << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET;
1605 reg_set(hpipe_addr + HPIPE_LANE_EQ_REMOTE_SETTING_REG, data, mask);
1606
1607 mask = HPIPE_CFG_EQ_BUNDLE_DIS_MASK;
1608 data = 0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET;
1609 reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG2_REG, data, mask);
1610
1611 debug("stage: Comphy power up\n");
1612
1613 /* For PCIe X4 or X2:
1614 * release from reset only after finish to configure all lanes
1615 */
1616 if ((pcie_width == PCIE_LNK_X1) || (comphy_index == (pcie_width - 1))) {
1617 uint32_t i, start_lane, end_lane;
1618
1619 if (pcie_width != PCIE_LNK_X1) {
1620 /* allows writing to all lanes in one write */
1621 data = 0x0;
1622 if (pcie_width == PCIE_LNK_X2)
1623 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
1624 else if (pcie_width == PCIE_LNK_X4)
1625 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
1626 reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
1627 start_lane = 0;
1628 end_lane = pcie_width;
1629
1630 /* Release from PIPE soft reset
1631 * For PCIe by4 or by2:
1632 * release from soft reset all lanes - can't use
1633 * read modify write
1634 */
1635 reg_set(HPIPE_ADDR(
1636 COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), 0) +
1637 HPIPE_RST_CLK_CTRL_REG, 0x24, 0xffffffff);
1638 } else {
1639 start_lane = comphy_index;
1640 end_lane = comphy_index + 1;
1641
1642 /* Release from PIPE soft reset
1643 * for PCIe by4 or by2:
1644 * release from soft reset all lanes
1645 */
1646 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
1647 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
1648 HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
1649 }
1650
1651 if (pcie_width != PCIE_LNK_X1) {
1652 /* disable writing to all lanes with one write */
1653 if (pcie_width == PCIE_LNK_X2) {
1654 data = (COMPHY_LANE0 <<
1655 COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
1656 (COMPHY_LANE1 <<
1657 COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET);
1658 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
1659 } else if (pcie_width == PCIE_LNK_X4) {
1660 data = (COMPHY_LANE0 <<
1661 COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
1662 (COMPHY_LANE1 <<
1663 COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET) |
1664 (COMPHY_LANE2 <<
1665 COMMON_PHY_SD_CTRL1_COMPHY_2_PORT_OFFSET) |
1666 (COMPHY_LANE3 <<
1667 COMMON_PHY_SD_CTRL1_COMPHY_3_PORT_OFFSET);
1668 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
1669 }
1670 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1671 data, mask);
1672 }
1673
1674 debug("stage: Check PLL\n");
1675 /* Read lane status */
1676 for (i = start_lane; i < end_lane; i++) {
1677 addr = HPIPE_ADDR(
1678 COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), i) +
1679 HPIPE_LANE_STATUS1_REG;
1680 data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
1681 mask = data;
1682 ret = polling_with_timeout(addr, data, mask,
1683 PLL_LOCK_TIMEOUT,
1684 REG_32BIT);
1685 if (ret)
1686 ERROR("Failed to lock PCIE PLL\n");
1687 }
1688 }
1689
1690 debug_exit();
1691
1692 return ret;
1693}
1694
1695static int mvebu_cp110_comphy_rxaui_power_on(uint64_t comphy_base,
1696 uint8_t comphy_index, uint32_t comphy_mode)
1697{
1698 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
1699 uint32_t mask, data;
1700 int ret = 0;
1701
1702 debug_enter();
1703
1704 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1705 comphy_index);
1706 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1707 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1708 comphy_index);
1709
1710 /* configure phy selector for RXAUI */
1711 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
1712 comphy_mode);
1713
1714 /* RFU configurations - hard reset comphy */
1715 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1716 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1717 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1718 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1719 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1720
1721 if (comphy_index == 2) {
1722 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1723 0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET,
1724 COMMON_PHY_SD_CTRL1_RXAUI0_MASK);
1725 }
1726 if (comphy_index == 4) {
1727 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1728 0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET,
1729 COMMON_PHY_SD_CTRL1_RXAUI1_MASK);
1730 }
1731
1732 /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
1733 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1734 data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1735 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
1736 data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
1737 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
1738 data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
1739 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1740 data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1741 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1742 data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1743 mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
1744 data |= 0x0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
1745 mask |= SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK;
1746 data |= 0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET;
1747 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1748
1749 /* release from hard reset */
1750 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
1751 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
1752 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
1753 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
1754 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1755 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1756 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1757
1758 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
1759 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
1760 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
1761 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
1762 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1763
1764 /* Wait 1ms - until band gap and ref clock ready */
1765 mdelay(1);
1766
1767 /* Start comphy Configuration */
1768 debug("stage: Comphy configuration\n");
1769 /* set reference clock */
1770 reg_set(hpipe_addr + HPIPE_MISC_REG,
1771 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
1772 HPIPE_MISC_REFCLK_SEL_MASK);
1773 /* Power and PLL Control */
1774 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1775 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1776 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1777 data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1778 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1779 /* Loopback register */
1780 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
1781 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
1782 /* rx control 1 */
1783 mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
1784 data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
1785 mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
1786 data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
1787 reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
1788 /* DTL Control */
1789 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG,
1790 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET,
1791 HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK);
1792
1793 /* Set analog parameters from ETP(HW) */
1794 debug("stage: Analog parameters from ETP(HW)\n");
1795 /* SERDES External Configuration 2 */
1796 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG,
1797 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET,
1798 SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK);
1799 /* 0x7-DFE Resolution control */
1800 reg_set(hpipe_addr + HPIPE_DFE_REG0, 0x1 << HPIPE_DFE_RES_FORCE_OFFSET,
1801 HPIPE_DFE_RES_FORCE_MASK);
1802 /* 0xd-G1_Setting_0 */
1803 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
1804 0xd << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
1805 HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
1806 /* 0xE-G1_Setting_1 */
1807 mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
1808 data = 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001809 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
1810 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001811 mask |= HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
1812 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
1813 reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
1814 /* 0xA-DFE_Reg3 */
1815 mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
1816 data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
1817 mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
1818 data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
1819 reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
1820
1821 /* 0x111-G1_Setting_4 */
1822 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1823 data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1824 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
1825
1826 debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
1827 /* SERDES External Configuration */
1828 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1829 data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1830 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1831 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1832 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1833 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1834 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1835
1836
1837 /* check PLL rx & tx ready */
1838 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1839 data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
1840 SD_EXTERNAL_STATUS0_PLL_TX_MASK;
1841 mask = data;
1842 data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
1843 if (data != 0) {
1844 debug("Read from reg = %lx - value = 0x%x\n",
1845 sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
1846 ERROR("SD_EXTERNAL_STATUS0_PLL_RX is %d, -\"-_PLL_TX is %d\n",
1847 (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK),
1848 (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK));
1849 ret = -ETIMEDOUT;
1850 }
1851
1852 /* RX init */
1853 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG,
1854 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET,
1855 SD_EXTERNAL_CONFIG1_RX_INIT_MASK);
1856
1857 /* check that RX init done */
1858 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1859 data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
1860 mask = data;
1861 data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
1862 if (data != 0) {
1863 debug("Read from reg = %lx - value = 0x%x\n",
1864 sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
1865 ERROR("SD_EXTERNAL_STATUS0_RX_INIT is 0\n");
1866 ret = -ETIMEDOUT;
1867 }
1868
1869 debug("stage: RF Reset\n");
1870 /* RF Reset */
1871 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1872 data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1873 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1874 data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1875 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1876
1877 debug_exit();
1878
1879 return ret;
1880}
1881
1882static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base,
1883 uint8_t comphy_index, uint32_t comphy_mode)
1884{
1885 uintptr_t hpipe_addr, comphy_addr, addr;
1886 uint32_t mask, data;
1887 int ret = 0;
1888
1889 debug_enter();
1890
1891 /* Configure PIPE selector for USB3 */
1892 mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
1893 comphy_mode);
1894
1895 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1896 comphy_index);
1897 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1898
1899 debug("stage: RFU configurations - hard reset comphy\n");
1900 /* RFU configurations - hard reset comphy */
1901 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1902 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1903 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1904 data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1905 mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1906 data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1907 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1908 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1909 mask |= COMMON_PHY_PHY_MODE_MASK;
1910 data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET;
1911 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1912
1913 /* release from hard reset */
1914 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1915 data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1916 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1917 data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1918 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1919
1920 /* Wait 1ms - until band gap and ref clock ready */
1921 mdelay(1);
1922
1923 /* Start comphy Configuration */
1924 debug("stage: Comphy configuration\n");
1925 /* Set PIPE soft reset */
1926 mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
1927 data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
1928 /* Set PHY datapath width mode for V0 */
1929 mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
1930 data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
1931 /* Set Data bus width USB mode for V0 */
1932 mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
1933 data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
1934 /* Set CORE_CLK output frequency for 250Mhz */
1935 mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
1936 data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
1937 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
1938 /* Set PLL ready delay for 0x2 */
1939 reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG,
1940 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
1941 HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
1942 /* Set reference clock to come from group 1 - 25Mhz */
1943 reg_set(hpipe_addr + HPIPE_MISC_REG,
1944 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
1945 HPIPE_MISC_REFCLK_SEL_MASK);
1946 /* Set reference frequcency select - 0x2 */
1947 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1948 data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1949 /* Set PHY mode to USB - 0x5 */
1950 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1951 data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1952 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1953 /* Set the amount of time spent in the LoZ state - set for 0x7 */
1954 reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
1955 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
1956 HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
1957 /* Set max PHY generation setting - 5Gbps */
1958 reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
1959 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
1960 HPIPE_INTERFACE_GEN_MAX_MASK);
1961 /* Set select data width 20Bit (SEL_BITS[2:0]) */
1962 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
1963 0x1 << HPIPE_LOOPBACK_SEL_OFFSET,
1964 HPIPE_LOOPBACK_SEL_MASK);
1965 /* select de-emphasize 3.5db */
1966 reg_set(hpipe_addr + HPIPE_LANE_CONFIG0_REG,
1967 0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET,
1968 HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK);
1969 /* override tx margining from the MAC */
1970 reg_set(hpipe_addr + HPIPE_TST_MODE_CTRL_REG,
1971 0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET,
1972 HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK);
1973
1974 /* Start analog parameters from ETP(HW) */
1975 debug("stage: Analog parameters from ETP(HW)\n");
1976 /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */
1977 mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK;
1978 data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET;
1979 /* Set Override PHY DFE control pins for 0x1 */
1980 mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK;
1981 data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET;
1982 /* Set Spread Spectrum Clock Enable fot 0x1 */
1983 mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK;
1984 data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET;
1985 reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
1986 /* Confifure SSC amplitude */
1987 mask = HPIPE_G2_TX_SSC_AMP_MASK;
1988 data = 0x1f << HPIPE_G2_TX_SSC_AMP_OFFSET;
1989 reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
1990 /* End of analog parameters */
1991
1992 debug("stage: Comphy power up\n");
1993 /* Release from PIPE soft reset */
1994 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
1995 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
1996 HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
1997
1998 /* wait 15ms - for comphy calibration done */
1999 debug("stage: Check PLL\n");
2000 /* Read lane status */
2001 addr = hpipe_addr + HPIPE_LANE_STATUS1_REG;
2002 data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
2003 mask = data;
2004 data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
2005 if (data != 0) {
2006 debug("Read from reg = %lx - value = 0x%x\n",
2007 hpipe_addr + HPIPE_LANE_STATUS1_REG, data);
2008 ERROR("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n");
2009 ret = -ETIMEDOUT;
2010 }
2011
2012 debug_exit();
2013
2014 return ret;
2015}
2016
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002017static void rx_pre_train(uint64_t comphy_base, uint8_t comphy_index)
2018{
2019 uintptr_t hpipe_addr;
2020 uint32_t mask, data;
2021
2022 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2023 comphy_index);
2024
2025 debug("rx_training preparation\n\n");
2026
2027 mask = HPIPE_TRX0_GAIN_TRAIN_WITH_C_MASK;
2028 data = (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF);
2029 mask |= HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_MASK;
2030 data |= (0x0 << HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF);
2031 reg_set(hpipe_addr + HPIPE_TRX0_REG, data, mask);
2032
2033
2034 mask = HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK;
2035 data = (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF);
2036 mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_MASK;
2037 data |= (0x0 << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF);
2038 reg_set(hpipe_addr + HPIPE_TRX_REG2, data, mask);
2039
2040 mask = HPIPE_TRX_REG1_MIN_BOOST_MODE_MASK;
2041 data = (0x1 << HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF);
2042 reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask);
2043
2044 mask = HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_MASK;
2045 data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF);
2046 reg_set(hpipe_addr + HPIPE_CDR_CONTROL1_REG, data, mask);
2047
2048 mask = HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_MASK;
2049 data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF);
2050 reg_set(hpipe_addr + HPIPE_CDR_CONTROL2_REG, data, mask);
2051
2052 mask = HPIPE_CRD_MIDPOINT_PHASE_OS_MASK;
2053 data = (0x0 << HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET);
2054 reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
2055
2056 mask = HPIPE_TRX_REG1_SUMFTAP_EN_MASK;
2057 data = (0x38 << HPIPE_TRX_REG1_SUMFTAP_EN_OFF);
2058 mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK;
2059 data |= (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF);
2060 reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask);
2061}
2062
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002063int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base,
2064 uint8_t comphy_index)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002065{
2066 uint32_t mask, data, timeout;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002067 uint32_t g1_ffe_cap_sel, g1_ffe_res_sel, align90, g1_dfe_res;
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002068 uintptr_t hpipe_addr;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002069
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002070 uint8_t ap_nr, cp_nr;
2071
2072 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
2073
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002074 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2075 comphy_index);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002076
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002077 debug_enter();
2078
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002079 rx_pre_train(comphy_base, comphy_index);
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002080
2081 debug("Preparation for rx_training\n\n");
2082
2083 /* Use the FFE table */
2084 mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
2085 data = 0 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
2086 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
2087
2088 /* Use auto-calibration value */
2089 mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
2090 data = 0 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
2091 reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
2092 data, mask);
2093
2094 /* Use Tx/Rx training results */
2095 mask = HPIPE_DFE_RES_FORCE_MASK;
2096 data = 0 << HPIPE_DFE_RES_FORCE_OFFSET;
2097 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
2098
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002099 debug("Enable RX training\n\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002100
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002101 mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
2102 data = 0x1 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002103 reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002104
2105 /* Check the result of RX training */
2106 timeout = RX_TRAINING_TIMEOUT;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002107 mask = HPIPE_INTERRUPT_TRX_TRAIN_DONE_OFFSET |
2108 HPIPE_INTERRUPT_DFE_DONE_INT_OFFSET |
2109 HPIPE_INTERRUPT_RX_TRAIN_COMPLETE_INT_MASK;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002110 while (timeout) {
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002111 data = mmio_read_32(hpipe_addr + HPIPE_INTERRUPT_1_REGISTER);
2112 if (data & mask)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002113 break;
2114 mdelay(1);
2115 timeout--;
2116 }
2117
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002118 debug("RX training result: interrupt reg 0x%lx = 0x%x\n\n",
2119 hpipe_addr + HPIPE_INTERRUPT_1_REGISTER, data);
2120
2121 if (timeout == 0 || data & HPIPE_TRX_TRAIN_TIME_OUT_INT_MASK) {
2122 ERROR("Rx training timeout...\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002123 return -ETIMEDOUT;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002124 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002125
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002126 if (data & HPIPE_TRX_TRAIN_FAILED_MASK) {
2127 ERROR("Rx training failed...\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002128 return -EINVAL;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002129 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002130
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002131 mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
2132 data = 0x0 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
2133 reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002134
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002135 debug("Training done, reading results...\n\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002136
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002137 mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_MASK;
2138 g1_ffe_res_sel = ((mmio_read_32(hpipe_addr +
2139 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
2140 & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002141
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002142 mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_MASK;
2143 g1_ffe_cap_sel = ((mmio_read_32(hpipe_addr +
2144 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
2145 & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002146
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002147 mask = HPIPE_DATA_PHASE_ADAPTED_OS_PH_MASK;
2148 align90 = ((mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG)
2149 & mask) >> HPIPE_DATA_PHASE_ADAPTED_OS_PH_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002150
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002151 mask = HPIPE_ADAPTED_DFE_RES_MASK;
2152 g1_dfe_res = ((mmio_read_32(hpipe_addr +
2153 HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG)
2154 & mask) >> HPIPE_ADAPTED_DFE_RES_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002155
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002156 debug("================================================\n");
2157 debug("Switching to static configuration:\n");
2158 debug("FFE_RES = 0x%x FFE_CAP = 0x%x align90 = 0x%x g1_dfe_res 0x%x\n",
2159 g1_ffe_res_sel, g1_ffe_cap_sel, align90, g1_dfe_res);
2160 debug("Result after training: 0x%lx= 0x%x, 0x%lx= 0x%x, 0x%lx = 0x%x\n",
2161 (hpipe_addr + HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
2162 mmio_read_32(hpipe_addr +
2163 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
2164 (hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
2165 mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
2166 (hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG),
2167 mmio_read_32(hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG));
2168 debug("================================================\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002169
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002170 /* Update FFE_RES */
2171 mask = HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
2172 data = g1_ffe_res_sel << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
2173 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002174
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002175 /* Update FFE_CAP */
2176 mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
2177 data = g1_ffe_cap_sel << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
2178 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002179
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002180 /* Bypass the FFE table settings and use the FFE settings directly from
2181 * registers FFE_RES_SEL and FFE_CAP_SEL
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002182 */
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002183 mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
2184 data = 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
2185 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002186
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002187 /* Force DFE resolution (use gen table value) */
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002188 mask = HPIPE_DFE_RES_FORCE_MASK;
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002189 data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002190 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
2191
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002192 /* 0x111-G1 DFE_Setting_4 */
2193 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
2194 data = g1_dfe_res << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
2195 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002196
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002197 printf("########################################################\n");
2198 printf("# To use trained values update the ATF sources:\n");
Grzegorz Jaszczyk3039bce2019-11-05 13:14:59 +01002199 printf("# plat/marvell/armada/a8k/<board_type>/board/phy-porting-layer.h ");
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002200 printf("file\n# with new values as below (for appropriate AP nr %d",
2201 ap_nr);
2202 printf("and CP nr: %d comphy_index %d\n\n",
2203 cp_nr, comphy_index);
2204 printf("static struct xfi_params xfi_static_values_tab[AP_NUM]");
2205 printf("[CP_NUM][MAX_LANE_NR] = {\n");
2206 printf("\t...\n");
2207 printf("\t.g1_ffe_res_sel = 0x%x,\n", g1_ffe_res_sel);
2208 printf("\t.g1_ffe_cap_sel = 0x%x,\n", g1_ffe_cap_sel);
2209 printf("\t.align90 = 0x%x,\n", align90);
2210 printf("\t.g1_dfe_res = 0x%x\n", g1_dfe_res);
2211 printf("\t...\n");
2212 printf("};\n\n");
2213 printf("########################################################\n");
2214
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002215 rx_trainng_done[ap_nr][cp_nr][comphy_index] = 1;
2216
2217 return 0;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002218}
2219
2220/* During AP the proper mode is auto-negotiated and the mac, pcs and serdes
2221 * configuration are done by the firmware loaded to the MG's CM3 for appropriate
2222 * negotiated mode. Therefore there is no need to configure the mac, pcs and
2223 * serdes from u-boot. The only thing that need to be setup is powering up
2224 * the comphy, which is done through Common PHY<n> Configuration 1 Register
2225 * (CP0: 0xF2441000, CP1: 0xF4441000). This step can't be done by MG's CM3,
2226 * since it doesn't have an access to this register-set (but it has access to
2227 * the network registers like: MG, AP, MAC, PCS, Serdes etc.)
2228 */
2229static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base,
Grzegorz Jaszczyk7a61f162019-03-28 13:02:42 +01002230 uint8_t comphy_index,
2231 uint32_t comphy_mode)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002232{
2233 uint32_t mask, data;
2234 uintptr_t comphy_addr = comphy_addr =
2235 COMPHY_ADDR(comphy_base, comphy_index);
2236
Grzegorz Jaszczyk7a61f162019-03-28 13:02:42 +01002237 /* configure phy selector for XFI/SFI */
2238 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
2239 comphy_mode);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002240 debug_enter();
2241 debug("stage: RFU configurations - hard reset comphy\n");
2242 /* RFU configurations - hard reset comphy */
2243 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
2244 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
2245 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
2246 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
2247 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
2248 debug_exit();
2249
2250 return 0;
2251}
2252
2253/*
2254 * This function allows to reset the digital synchronizers between
2255 * the MAC and the PHY, it is required when the MAC changes its state.
2256 */
2257int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base,
2258 uint8_t comphy_index,
2259 uint32_t comphy_mode, uint32_t command)
2260{
2261 int mode = COMPHY_GET_MODE(comphy_mode);
2262 uintptr_t sd_ip_addr;
2263 uint32_t mask, data;
2264
2265 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2266 comphy_index);
2267
2268 switch (mode) {
2269 case (COMPHY_SGMII_MODE):
2270 case (COMPHY_HS_SGMII_MODE):
2271 case (COMPHY_XFI_MODE):
2272 case (COMPHY_SFI_MODE):
2273 case (COMPHY_RXAUI_MODE):
2274 mask = SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2275 data = ((command == COMPHY_COMMAND_DIGITAL_PWR_OFF) ?
2276 0x0 : 0x1) << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2277 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2278 break;
2279 default:
2280 ERROR("comphy%d: Digital PWR ON/OFF is not supported\n",
2281 comphy_index);
2282 return -EINVAL;
2283 }
2284
2285 return 0;
2286}
2287
Grzegorz Jaszczyk4cff3082018-07-12 07:40:34 +02002288int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint8_t comphy_index,
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002289 uint64_t comphy_mode)
2290{
2291 int mode = COMPHY_GET_MODE(comphy_mode);
2292 int err = 0;
2293
2294 debug_enter();
2295
2296 switch (mode) {
2297 case(COMPHY_SATA_MODE):
2298 err = mvebu_cp110_comphy_sata_power_on(comphy_base,
2299 comphy_index,
2300 comphy_mode);
2301 break;
2302 case(COMPHY_SGMII_MODE):
2303 case(COMPHY_HS_SGMII_MODE):
2304 err = mvebu_cp110_comphy_sgmii_power_on(comphy_base,
2305 comphy_index,
2306 comphy_mode);
2307 break;
2308 /* From comphy perspective, XFI and SFI are the same */
2309 case (COMPHY_XFI_MODE):
2310 case (COMPHY_SFI_MODE):
2311 err = mvebu_cp110_comphy_xfi_power_on(comphy_base,
2312 comphy_index,
2313 comphy_mode);
2314 break;
2315 case (COMPHY_PCIE_MODE):
2316 err = mvebu_cp110_comphy_pcie_power_on(comphy_base,
2317 comphy_index,
2318 comphy_mode);
2319 break;
2320 case (COMPHY_RXAUI_MODE):
2321 err = mvebu_cp110_comphy_rxaui_power_on(comphy_base,
2322 comphy_index,
2323 comphy_mode);
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002324 break;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002325 case (COMPHY_USB3H_MODE):
2326 case (COMPHY_USB3D_MODE):
2327 err = mvebu_cp110_comphy_usb3_power_on(comphy_base,
2328 comphy_index,
2329 comphy_mode);
2330 break;
2331 case (COMPHY_AP_MODE):
Grzegorz Jaszczyk7a61f162019-03-28 13:02:42 +01002332 err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index,
2333 comphy_mode);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002334 break;
2335 default:
Grzegorz Jaszczyk4cff3082018-07-12 07:40:34 +02002336 ERROR("comphy%d: unsupported comphy mode\n", comphy_index);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002337 err = -EINVAL;
2338 break;
2339 }
2340
2341 debug_exit();
2342
2343 return err;
2344}
2345
Igal Libermanbd51efd2018-11-15 16:13:11 +02002346int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint8_t comphy_index,
2347 uint64_t comphy_mode)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002348{
2349 uintptr_t sd_ip_addr, comphy_ip_addr;
2350 uint32_t mask, data;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002351 uint8_t ap_nr, cp_nr;
Igal Libermanbd51efd2018-11-15 16:13:11 +02002352 _Bool called_from_uboot = COMPHY_GET_CALLER(comphy_mode);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002353
2354 debug_enter();
2355
Igal Libermanbd51efd2018-11-15 16:13:11 +02002356 /* Power-off might happen because of 2 things:
2357 * 1. Bootloader turns off unconnected lanes
2358 * 2. Linux turns off all lanes during boot
2359 * (and then reconfigure it).
2360 *
2361 * For PCIe, there's a problem:
2362 * In Armada 8K DB boards, PCIe initialization can be executed
2363 * only once (PCIe reset performed during chip power on and
2364 * it cannot be executed via GPIO later) so a lane configured to
2365 * PCIe should not be powered off by Linux.
2366 *
2367 * So, check 2 things:
2368 * 1. Is Linux called for power-off?
2369 * 2. Is the comphy configured to PCIe?
2370 * If the answer is YES for both 1 and 2, skip the power-off.
2371 *
2372 * TODO: In MacciatoBIN, PCIe reset is connected via GPIO,
2373 * so after GPIO reset is added to Linux Kernel, it can be
2374 * powered-off.
2375 */
2376 if (!called_from_uboot) {
2377 data = mmio_read_32(comphy_base +
2378 COMMON_SELECTOR_PIPE_REG_OFFSET);
2379 data >>= (COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index);
2380 data &= COMMON_SELECTOR_COMPHY_MASK;
2381 if (data == COMMON_SELECTOR_PIPE_COMPHY_PCIE)
2382 return 0;
2383 }
2384
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002385 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
2386
2387 if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) {
2388 debug("Skip %s for comphy[%d][%d][%d], due to rx training\n",
2389 __func__, ap_nr, cp_nr, comphy_index);
2390 return 0;
2391 }
2392
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002393 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2394 comphy_index);
2395 comphy_ip_addr = COMPHY_ADDR(comphy_base, comphy_index);
2396
2397 /* Hard reset the comphy, for Ethernet modes and Sata */
2398 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
2399 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
2400 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
2401 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
2402 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2403 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2404 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2405
2406 /* PCIe reset */
2407 spin_lock(&cp110_mac_reset_lock);
2408
2409 /* The mvebu_cp110_comphy_power_off will be called only from Linux (to
2410 * override settings done by bootloader) and it will be relevant only
2411 * to PCIe (called before check if to skip pcie power off or not).
2412 */
2413 data = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2414 SYS_CTRL_UINIT_SOFT_RESET_REG);
2415 switch (comphy_index) {
2416 case COMPHY_LANE0:
2417 data &= ~PCIE_MAC_RESET_MASK_PORT0;
2418 break;
2419 case COMPHY_LANE4:
2420 data &= ~PCIE_MAC_RESET_MASK_PORT1;
2421 break;
2422 case COMPHY_LANE5:
2423 data &= ~PCIE_MAC_RESET_MASK_PORT2;
2424 break;
2425 }
2426
2427 mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2428 SYS_CTRL_UINIT_SOFT_RESET_REG, data);
2429 spin_unlock(&cp110_mac_reset_lock);
2430
2431 /* Hard reset the comphy, for PCIe and usb3 */
2432 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
2433 data = 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
2434 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
2435 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
2436 reg_set(comphy_ip_addr + COMMON_PHY_CFG1_REG, data, mask);
2437
2438 /* Clear comphy PHY and PIPE selector, can't rely on previous config. */
2439 mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
2440 mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
2441
2442 debug_exit();
2443
2444 return 0;
2445}