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