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