blob: 012197ebd9fedae0faaeffb3ef83881e75e959e5 [file] [log] [blame]
Konstantin Porotchkin0ade8cd2018-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 Porotchkin0ade8cd2018-04-24 19:23:09 +030010#include <errno.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000011
12#include <common/debug.h>
13#include <drivers/delay_timer.h>
Grzegorz Jaszczyk5a9e46e2019-04-12 16:57:14 +020014#include <mg_conf_cm3/mg_conf_cm3.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000015#include <lib/mmio.h>
16#include <lib/spinlock.h>
17
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +030018#include <mvebu_def.h>
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +030019#include "mvebu.h"
20#include "comphy-cp110.h"
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +020021#include "phy-comphy-cp110.h"
22#include "phy-comphy-common.h"
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +030023
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +020024#if __has_include("phy-porting-layer.h")
25#include "phy-porting-layer.h"
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +030026#else
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +020027#include "phy-default-porting-layer.h"
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +030028#endif
29
Konstantin Porotchkin0ade8cd2018-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 Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +020085_Bool rx_trainng_done[AP_NUM][CP_NUM][MAX_LANE_NR] = {0};
86
87static void mvebu_cp110_get_ap_and_cp_nr(uint8_t *ap_nr, uint8_t *cp_nr,
88 uint64_t comphy_base)
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +030089{
Grzegorz Jaszczyk42a29332018-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
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +030096
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +020097 *cp_nr = (((comphy_base & ~0xffffff) - MVEBU_AP_IO_BASE(*ap_nr)) /
98 MVEBU_CP_OFFSET);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +030099
Grzegorz Jaszczyk42a29332018-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 Porotchkin0ade8cd2018-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 Jaszczyk050eb192019-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 Jaszczyk05291062018-10-19 15:30:02 +0200217 && COMPHY_GET_ID(comphy_mode) == 1)
Konstantin Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200331 uint8_t ap_nr, cp_nr;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300332 int ret = 0;
333
334 debug_enter();
335
Grzegorz Jaszczyk42a29332018-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 Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200405 data = sata_static_values->g1_rx_selmupi <<
406 HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyk3c0024c2018-07-16 12:18:03 +0200407 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200408 data |= sata_static_values->g1_rx_selmupf <<
409 HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300410 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200411 data |= sata_static_values->g1_rx_selmufi <<
412 HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300413 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200414 data |= sata_static_values->g1_rx_selmuff <<
415 HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
Konstantin Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200434 data = sata_static_values->g2_rx_selmupi <<
435 HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyk3c0024c2018-07-16 12:18:03 +0200436 mask |= HPIPE_G2_SET_1_G2_RX_SELMUPF_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200437 data |= sata_static_values->g2_rx_selmupf <<
438 HPIPE_G2_SET_1_G2_RX_SELMUPF_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300439 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200440 data |= sata_static_values->g2_rx_selmufi <<
441 HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300442 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFF_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200443 data |= sata_static_values->g2_rx_selmuff <<
444 HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET;
Konstantin Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200451 data = sata_static_values->g3_rx_selmupi <<
452 HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300453 mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200454 data |= sata_static_values->g3_rx_selmupf <<
455 HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300456 mask |= HPIPE_G3_SET_1_G3_RX_SELMUFI_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200457 data |= sata_static_values->g3_rx_selmufi <<
458 HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300459 mask |= HPIPE_G3_SET_1_G3_RX_SELMUFF_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200460 data |= sata_static_values->g3_rx_selmuff <<
461 HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET;
Konstantin Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200514 data = sata_static_values->g3_ffe_cap_sel <<
515 HPIPE_G3_FFE_CAP_SEL_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300516 mask |= HPIPE_G3_FFE_RES_SEL_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200517 data |= sata_static_values->g3_ffe_res_sel <<
518 HPIPE_G3_FFE_RES_SEL_OFFSET;
Konstantin Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200529 data = sata_static_values->g3_dfe_res << HPIPE_G3_DFE_RES_OFFSET;
Konstantin Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200534 data = sata_static_values->align90 << HPIPE_OS_PH_OFFSET_OFFSET;
Konstantin Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200549 data = sata_static_values->g1_amp << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300550 mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk42a29332018-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 Porotchkin0ade8cd2018-04-24 19:23:09 +0300553 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200554 data |= sata_static_values->g1_emph <<
555 HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300556 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200557 data |= sata_static_values->g1_emph_en <<
558 HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300559 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
560
Grzegorz Jaszczyk42a29332018-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 Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200572 data = sata_static_values->g2_amp << HPIPE_G2_SET_0_G2_TX_AMP_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300573 mask |= HPIPE_G2_SET_0_G2_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk42a29332018-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 Porotchkin0ade8cd2018-04-24 19:23:09 +0300576 mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200577 data |= sata_static_values->g2_emph <<
578 HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300579 mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200580 data |= sata_static_values->g2_emph_en <<
581 HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300582 reg_set(hpipe_addr + HPIPE_G2_SET_0_REG, data, mask);
583
Grzegorz Jaszczyk42a29332018-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 Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200595 data = sata_static_values->g3_amp << HPIPE_G3_SET_0_G3_TX_AMP_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300596 mask |= HPIPE_G3_SET_0_G3_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk42a29332018-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 Porotchkin0ade8cd2018-04-24 19:23:09 +0300599 mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200600 data |= sata_static_values->g3_emph <<
601 HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300602 mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200603 data |= sata_static_values->g3_emph_en <<
604 HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-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 Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200754 /* Set analog parameters from ETP(HW) - for now use the default data */
Konstantin Porotchkin0ade8cd2018-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 Jaszczyk42a29332018-06-29 18:00:33 +0200810 uint8_t ap_nr, cp_nr;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300811
812 debug_enter();
813
Grzegorz Jaszczyk42a29332018-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 Porotchkin0ade8cd2018-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;
Marcin Wojtas8fa13402019-09-09 03:38:18 +0200901 mask |= SD_EXTERNAL_CONFIG1_TX_IDLE_MASK;
902 data |= 0x1 << SD_EXTERNAL_CONFIG1_TX_IDLE_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300903 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
904
905 /* Wait 1ms - until band gap and ref clock ready */
906 mdelay(1);
907
Marcin Wojtas8fa13402019-09-09 03:38:18 +0200908 /*
909 * Erratum IPCE_COMPHY-1353: toggle TX_IDLE bit in
910 * addition to the PHY reset
911 */
912 mask = SD_EXTERNAL_CONFIG1_TX_IDLE_MASK;
913 data = 0x0U;
914 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
915
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300916 /* Start comphy Configuration */
917 debug("stage: Comphy configuration\n");
918 /* set reference clock */
919 mask = HPIPE_MISC_ICP_FORCE_MASK;
920 data = (speed == COMPHY_SPEED_5_15625G) ?
921 (0x0 << HPIPE_MISC_ICP_FORCE_OFFSET) :
922 (0x1 << HPIPE_MISC_ICP_FORCE_OFFSET);
923 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
924 data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
925 reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
926 /* Power and PLL Control */
927 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
928 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
929 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
930 data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
931 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
932 /* Loopback register */
933 mask = HPIPE_LOOPBACK_SEL_MASK;
934 data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
935 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
936 /* rx control 1 */
937 mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
938 data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
939 mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
940 data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
941 reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
942 /* DTL Control */
943 mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
944 data = 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
945 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
946
947 /* Transmitter/Receiver Speed Divider Force */
948 if (speed == COMPHY_SPEED_5_15625G) {
949 mask = HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_MASK;
950 data = 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET;
951 mask |= HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_MASK;
952 data |= 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET;
953 mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_MASK;
954 data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET;
955 mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_MASK;
956 data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET;
957 } else {
958 mask = HPIPE_TXDIGCK_DIV_FORCE_MASK;
959 data = 0x1 << HPIPE_TXDIGCK_DIV_FORCE_OFFSET;
960 }
961 reg_set(hpipe_addr + HPIPE_SPD_DIV_FORCE_REG, data, mask);
962
963 /* Set analog parameters from ETP(HW) */
964 debug("stage: Analog parameters from ETP(HW)\n");
965 /* SERDES External Configuration 2 */
966 mask = SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK;
967 data = 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET;
968 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
969 /* 0x7-DFE Resolution control */
970 mask = HPIPE_DFE_RES_FORCE_MASK;
971 data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
972 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
973 /* 0xd-G1_Setting_0 */
974 if (speed == COMPHY_SPEED_5_15625G) {
975 mask = HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
976 data = 0x6 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
977 } else {
978 mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200979 data = xfi_static_values->g1_amp <<
980 HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300981 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200982 data |= xfi_static_values->g1_emph <<
983 HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
984
985 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
986 data |= xfi_static_values->g1_emph_en <<
987 HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
988 mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
989 data |= xfi_static_values->g1_tx_amp_adj <<
990 HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300991 }
992 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
993 /* Genration 1 setting 2 (G1_Setting_2) */
994 mask = HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200995 data = xfi_static_values->g1_tx_emph <<
996 HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +0300997 mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +0200998 data |= xfi_static_values->g1_tx_emph_en <<
999 HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03001000 reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
1001 /* Transmitter Slew Rate Control register (tx_reg1) */
1002 mask = HPIPE_TX_REG1_TX_EMPH_RES_MASK;
1003 data = 0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET;
1004 mask |= HPIPE_TX_REG1_SLC_EN_MASK;
1005 data |= 0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET;
1006 reg_set(hpipe_addr + HPIPE_TX_REG1_REG, data, mask);
1007 /* Impedance Calibration Control register (cal_reg1) */
1008 mask = HPIPE_CAL_REG_1_EXT_TXIMP_MASK;
1009 data = 0xe << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
1010 mask |= HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK;
1011 data |= 0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET;
1012 reg_set(hpipe_addr + HPIPE_CAL_REG1_REG, data, mask);
1013 /* Generation 1 Setting 5 (g1_setting_5) */
1014 mask = HPIPE_G1_SETTING_5_G1_ICP_MASK;
1015 data = 0 << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
1016 reg_set(hpipe_addr + HPIPE_G1_SETTING_5_REG, data, mask);
1017
1018 /* 0xE-G1_Setting_1 */
1019 mask = HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
1020 data = 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
1021 if (speed == COMPHY_SPEED_5_15625G) {
1022 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
1023 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyk3c0024c2018-07-16 12:18:03 +02001024 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
1025 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03001026 } else {
1027 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02001028 data |= xfi_static_values->g1_rx_selmupi <<
1029 HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyk3c0024c2018-07-16 12:18:03 +02001030 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02001031 data |= xfi_static_values->g1_rx_selmupf <<
1032 HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03001033 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02001034 data |= xfi_static_values->g1_rx_selmufi <<
1035 HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03001036 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02001037 data |= xfi_static_values->g1_rx_selmuff <<
1038 HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03001039 mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
1040 data |= 0x3 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
1041 }
1042 reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
1043
1044 /* 0xA-DFE_Reg3 */
1045 mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
1046 data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
1047 mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
1048 data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
1049 reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
1050
1051 /* 0x111-G1_Setting_4 */
1052 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1053 data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1054 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
1055 /* Genration 1 setting 3 (G1_Setting_3) */
1056 mask = HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK;
1057 data = 0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET;
1058 if (speed == COMPHY_SPEED_5_15625G) {
1059 /* Force FFE (Feed Forward Equalization) to 5G */
1060 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
1061 data |= 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
1062 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
1063 data |= 0x4 << 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;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02001066 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
1067 } else {
1068 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
1069 data |= xfi_static_values->g1_ffe_cap_sel <<
1070 HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
1071 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
1072 data |= xfi_static_values->g1_ffe_res_sel <<
1073 HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
1074 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
1075 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
1076 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
1077
1078 /* Use the value from CAL_OS_PH_EXT */
1079 mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
1080 data = 1 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
1081 reg_set(hpipe_addr +
1082 HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
1083 data, mask);
1084
1085 /* Update align90 */
1086 mask = HPIPE_CAL_OS_PH_EXT_MASK;
1087 data = xfi_static_values->align90 << HPIPE_CAL_OS_PH_EXT_OFFSET;
1088 reg_set(hpipe_addr +
1089 HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
1090 data, mask);
1091
1092 /* Force DFE resolution (use gen table value) */
1093 mask = HPIPE_DFE_RES_FORCE_MASK;
1094 data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
1095 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
1096
1097 /* 0x111-G1 DFE_Setting_4 */
1098 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1099 data = xfi_static_values->g1_dfe_res <<
1100 HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1101 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03001102 }
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03001103
1104 /* Connfigure RX training timer */
1105 mask = HPIPE_RX_TRAIN_TIMER_MASK;
1106 data = 0x13 << HPIPE_RX_TRAIN_TIMER_OFFSET;
1107 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
1108
1109 /* Enable TX train peak to peak hold */
1110 mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
1111 data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
1112 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
1113
1114 /* Configure TX preset index */
1115 mask = HPIPE_TX_PRESET_INDEX_MASK;
1116 data = 0x2 << HPIPE_TX_PRESET_INDEX_OFFSET;
1117 reg_set(hpipe_addr + HPIPE_TX_PRESET_INDEX_REG, data, mask);
1118
1119 /* Disable pattern lock lost timeout */
1120 mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
1121 data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
1122 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
1123
1124 /* Configure TX training pattern and TX training 16bit auto */
1125 mask = HPIPE_TX_TRAIN_16BIT_AUTO_EN_MASK;
1126 data = 0x1 << HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET;
1127 mask |= HPIPE_TX_TRAIN_PAT_SEL_MASK;
1128 data |= 0x1 << HPIPE_TX_TRAIN_PAT_SEL_OFFSET;
1129 reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
1130
1131 /* Configure Training patten number */
1132 mask = HPIPE_TRAIN_PAT_NUM_MASK;
1133 data = 0x88 << HPIPE_TRAIN_PAT_NUM_OFFSET;
1134 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_0_REG, data, mask);
1135
1136 /* Configure differencial manchester encoter to ethernet mode */
1137 mask = HPIPE_DME_ETHERNET_MODE_MASK;
1138 data = 0x1 << HPIPE_DME_ETHERNET_MODE_OFFSET;
1139 reg_set(hpipe_addr + HPIPE_DME_REG, data, mask);
1140
1141 /* Configure VDD Continuous Calibration */
1142 mask = HPIPE_CAL_VDD_CONT_MODE_MASK;
1143 data = 0x1 << HPIPE_CAL_VDD_CONT_MODE_OFFSET;
1144 reg_set(hpipe_addr + HPIPE_VDD_CAL_0_REG, data, mask);
1145
1146 /* Trigger sampler enable pulse (by toggleing the bit) */
1147 mask = HPIPE_RX_SAMPLER_OS_GAIN_MASK;
1148 data = 0x3 << HPIPE_RX_SAMPLER_OS_GAIN_OFFSET;
1149 mask |= HPIPE_SMAPLER_MASK;
1150 data |= 0x1 << HPIPE_SMAPLER_OFFSET;
1151 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1152 mask = HPIPE_SMAPLER_MASK;
1153 data = 0x0 << HPIPE_SMAPLER_OFFSET;
1154 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1155
1156 /* Set External RX Regulator Control */
1157 mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
1158 data = 0x1A << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
1159 reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
1160
1161 debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
1162 /* SERDES External Configuration */
1163 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1164 data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1165 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1166 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1167 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1168 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1169 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1170
1171 /* check PLL rx & tx ready */
1172 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1173 data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
1174 SD_EXTERNAL_STATUS0_PLL_TX_MASK;
1175 mask = data;
1176 data = polling_with_timeout(addr, data, mask,
1177 PLL_LOCK_TIMEOUT, REG_32BIT);
1178 if (data != 0) {
1179 if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
1180 ERROR("RX PLL is not locked\n");
1181 if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
1182 ERROR("TX PLL is not locked\n");
1183
1184 ret = -ETIMEDOUT;
1185 }
1186
1187 /* RX init */
1188 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1189 data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1190 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1191
1192 /* check that RX init done */
1193 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1194 data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
1195 mask = data;
1196 data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
1197 if (data != 0) {
1198 ERROR("RX init failed\n");
1199 ret = -ETIMEDOUT;
1200 }
1201
1202 debug("stage: RF Reset\n");
1203 /* RF Reset */
1204 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1205 data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1206 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1207 data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1208 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1209
1210 debug_exit();
1211
1212 return ret;
1213}
1214
1215static int mvebu_cp110_comphy_pcie_power_on(uint64_t comphy_base,
1216 uint8_t comphy_index, uint32_t comphy_mode)
1217{
1218 int ret = 0;
1219 uint32_t reg, mask, data, pcie_width;
1220 uint32_t clk_dir;
1221 uintptr_t hpipe_addr, comphy_addr, addr;
1222 _Bool clk_src = COMPHY_GET_CLK_SRC(comphy_mode);
Igal Liberman55df84f2018-11-15 16:13:11 +02001223 _Bool called_from_uboot = COMPHY_GET_CALLER(comphy_mode);
1224
1225 /* In Armada 8K DB boards, PCIe initialization can be executed
1226 * only once (PCIe reset performed during chip power on and
1227 * it cannot be executed via GPIO later).
1228 * This means that power on can be executed only once, so let's
1229 * mark if the caller is bootloader or Linux.
1230 * If bootloader -> run power on.
1231 * If Linux -> exit.
1232 *
1233 * TODO: In MacciatoBIN, PCIe reset is connected via GPIO,
1234 * so after GPIO reset is added to Linux Kernel, it can be
1235 * powered-on by Linux.
1236 */
1237 if (!called_from_uboot)
1238 return ret;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03001239
1240 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1241 comphy_index);
1242 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1243 pcie_width = COMPHY_GET_PCIE_WIDTH(comphy_mode);
1244
1245 debug_enter();
1246
1247 spin_lock(&cp110_mac_reset_lock);
1248
1249 reg = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
1250 SYS_CTRL_UINIT_SOFT_RESET_REG);
1251 switch (comphy_index) {
1252 case COMPHY_LANE0:
1253 reg |= PCIE_MAC_RESET_MASK_PORT0;
1254 break;
1255 case COMPHY_LANE4:
1256 reg |= PCIE_MAC_RESET_MASK_PORT1;
1257 break;
1258 case COMPHY_LANE5:
1259 reg |= PCIE_MAC_RESET_MASK_PORT2;
1260 break;
1261 }
1262
1263 mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
1264 SYS_CTRL_UINIT_SOFT_RESET_REG, reg);
1265 spin_unlock(&cp110_mac_reset_lock);
1266
1267 /* Configure PIPE selector for PCIE */
1268 mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
1269 comphy_mode);
1270
1271 /*
1272 * Read SAR (Sample-At-Reset) configuration for the PCIe clock
1273 * direction.
1274 *
1275 * SerDes Lane 4/5 got the PCIe ref-clock #1,
1276 * and SerDes Lane 0 got PCIe ref-clock #0
1277 */
1278 reg = mmio_read_32(DFX_FROM_COMPHY_ADDR(comphy_base) +
1279 SAR_STATUS_0_REG);
1280 if (comphy_index == COMPHY_LANE4 || comphy_index == COMPHY_LANE5)
1281 clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK) >>
1282 SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET;
1283 else
1284 clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK) >>
1285 SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET;
1286
1287 debug("On lane %d\n", comphy_index);
1288 debug("PCIe clock direction = %x\n", clk_dir);
1289 debug("PCIe Width = %d\n", pcie_width);
1290
1291 /* enable PCIe X4 and X2 */
1292 if (comphy_index == COMPHY_LANE0) {
1293 if (pcie_width == PCIE_LNK_X4) {
1294 data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET;
1295 mask = COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK;
1296 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1297 data, mask);
1298 } else if (pcie_width == PCIE_LNK_X2) {
1299 data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET;
1300 mask = COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK;
1301 reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
1302 }
1303 }
1304
1305 /* If PCIe clock is output and clock source from SerDes lane 5,
1306 * need to configure the clock-source MUX.
1307 * By default, the clock source is from lane 4
1308 */
1309 if (clk_dir && clk_src && (comphy_index == COMPHY_LANE5)) {
1310 data = DFX_DEV_GEN_PCIE_CLK_SRC_MUX <<
1311 DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET;
1312 mask = DFX_DEV_GEN_PCIE_CLK_SRC_MASK;
1313 reg_set(DFX_FROM_COMPHY_ADDR(comphy_base) +
1314 DFX_DEV_GEN_CTRL12_REG, data, mask);
1315 }
1316
1317 debug("stage: RFU configurations - hard reset comphy\n");
1318 /* RFU configurations - hard reset comphy */
1319 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1320 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1321 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1322 data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1323 mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1324 data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1325 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1326 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1327 mask |= COMMON_PHY_PHY_MODE_MASK;
1328 data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET;
1329 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1330
1331 /* release from hard reset */
1332 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1333 data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1334 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1335 data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1336 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1337
1338 /* Wait 1ms - until band gap and ref clock ready */
1339 mdelay(1);
1340 /* Start comphy Configuration */
1341 debug("stage: Comphy configuration\n");
1342 /* Set PIPE soft reset */
1343 mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
1344 data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
1345 /* Set PHY datapath width mode for V0 */
1346 mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
1347 data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
1348 /* Set Data bus width USB mode for V0 */
1349 mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
1350 data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
1351 /* Set CORE_CLK output frequency for 250Mhz */
1352 mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
1353 data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
1354 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
1355 /* Set PLL ready delay for 0x2 */
1356 data = 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET;
1357 mask = HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK;
1358 if (pcie_width != PCIE_LNK_X1) {
1359 data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET;
1360 mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK;
1361 data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET;
1362 mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK;
1363 }
1364 reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, data, mask);
1365
1366 /* Set PIPE mode interface to PCIe3 - 0x1 & set lane order */
1367 data = 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET;
1368 mask = HPIPE_CLK_SRC_HI_MODE_PIPE_MASK;
1369 if (pcie_width != PCIE_LNK_X1) {
1370 mask |= HPIPE_CLK_SRC_HI_LANE_STRT_MASK;
1371 mask |= HPIPE_CLK_SRC_HI_LANE_MASTER_MASK;
1372 mask |= HPIPE_CLK_SRC_HI_LANE_BREAK_MASK;
1373 if (comphy_index == 0) {
1374 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET;
1375 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET;
1376 } else if (comphy_index == (pcie_width - 1)) {
1377 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET;
1378 }
1379 }
1380 reg_set(hpipe_addr + HPIPE_CLK_SRC_HI_REG, data, mask);
1381 /* Config update polarity equalization */
1382 data = 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET;
1383 mask = HPIPE_CFG_UPDATE_POLARITY_MASK;
1384 reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG1_REG, data, mask);
1385 /* Set PIPE version 4 to mode enable */
1386 data = 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET;
1387 mask = HPIPE_DFE_CTRL_28_PIPE4_MASK;
1388 reg_set(hpipe_addr + HPIPE_DFE_CTRL_28_REG, data, mask);
1389 /* TODO: check if pcie clock is output/input - for bringup use input*/
1390 /* Enable PIN clock 100M_125M */
1391 mask = 0;
1392 data = 0;
1393 /* Only if clock is output, configure the clock-source mux */
1394 if (clk_dir) {
1395 mask |= HPIPE_MISC_CLK100M_125M_MASK;
1396 data |= 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET;
1397 }
1398 /* Set PIN_TXDCLK_2X Clock Freq. Selection for outputs 500MHz clock */
1399 mask |= HPIPE_MISC_TXDCLK_2X_MASK;
1400 data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET;
1401 /* Enable 500MHz Clock */
1402 mask |= HPIPE_MISC_CLK500_EN_MASK;
1403 data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET;
1404 if (clk_dir) { /* output */
1405 /* Set reference clock comes from group 1 */
1406 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
1407 data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
1408 } else {
1409 /* Set reference clock comes from group 2 */
1410 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
1411 data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET;
1412 }
1413 mask |= HPIPE_MISC_ICP_FORCE_MASK;
1414 data |= 0x1 << HPIPE_MISC_ICP_FORCE_OFFSET;
1415 reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
1416 if (clk_dir) { /* output */
1417 /* Set reference frequcency select - 0x2 for 25MHz*/
1418 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1419 data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1420 } else {
1421 /* Set reference frequcency select - 0x0 for 100MHz*/
1422 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1423 data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1424 }
1425 /* Set PHY mode to PCIe */
1426 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1427 data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1428 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1429
1430 /* ref clock alignment */
1431 if (pcie_width != PCIE_LNK_X1) {
1432 mask = HPIPE_LANE_ALIGN_OFF_MASK;
1433 data = 0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET;
1434 reg_set(hpipe_addr + HPIPE_LANE_ALIGN_REG, data, mask);
1435 }
1436
1437 /* Set the amount of time spent in the LoZ state - set for 0x7 only if
1438 * the PCIe clock is output
1439 */
1440 if (clk_dir)
1441 reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
1442 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
1443 HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
1444
1445 /* Set Maximal PHY Generation Setting(8Gbps) */
1446 mask = HPIPE_INTERFACE_GEN_MAX_MASK;
1447 data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET;
1448 /* Bypass frame detection and sync detection for RX DATA */
1449 mask |= HPIPE_INTERFACE_DET_BYPASS_MASK;
1450 data |= 0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET;
1451 /* Set Link Train Mode (Tx training control pins are used) */
1452 mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK;
1453 data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET;
1454 reg_set(hpipe_addr + HPIPE_INTERFACE_REG, data, mask);
1455
1456 /* Set Idle_sync enable */
1457 mask = HPIPE_PCIE_IDLE_SYNC_MASK;
1458 data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET;
1459 /* Select bits for PCIE Gen3(32bit) */
1460 mask |= HPIPE_PCIE_SEL_BITS_MASK;
1461 data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET;
1462 reg_set(hpipe_addr + HPIPE_PCIE_REG0, data, mask);
1463
1464 /* Enable Tx_adapt_g1 */
1465 mask = HPIPE_TX_TRAIN_CTRL_G1_MASK;
1466 data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET;
1467 /* Enable Tx_adapt_gn1 */
1468 mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK;
1469 data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET;
1470 /* Disable Tx_adapt_g0 */
1471 mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK;
1472 data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
1473 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
1474
1475 /* Set reg_tx_train_chk_init */
1476 mask = HPIPE_TX_TRAIN_CHK_INIT_MASK;
1477 data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET;
1478 /* Enable TX_COE_FM_PIN_PCIE3_EN */
1479 mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK;
1480 data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET;
1481 reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
1482
1483 debug("stage: TRx training parameters\n");
1484 /* Set Preset sweep configurations */
1485 mask = HPIPE_TX_TX_STATUS_CHECK_MODE_MASK;
1486 data = 0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET;
1487 mask |= HPIPE_TX_NUM_OF_PRESET_MASK;
1488 data |= 0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET;
1489 mask |= HPIPE_TX_SWEEP_PRESET_EN_MASK;
1490 data |= 0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET;
1491 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_11_REG, data, mask);
1492
1493 /* Tx train start configuration */
1494 mask = HPIPE_TX_TRAIN_START_SQ_EN_MASK;
1495 data = 0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET;
1496 mask |= HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK;
1497 data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET;
1498 mask |= HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK;
1499 data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET;
1500 mask |= HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK;
1501 data |= 0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET;
1502 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
1503
1504 /* Enable Tx train P2P */
1505 mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
1506 data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
1507 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
1508
1509 /* Configure Tx train timeout */
1510 mask = HPIPE_TRX_TRAIN_TIMER_MASK;
1511 data = 0x17 << HPIPE_TRX_TRAIN_TIMER_OFFSET;
1512 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_4_REG, data, mask);
1513
1514 /* Disable G0/G1/GN1 adaptation */
1515 mask = HPIPE_TX_TRAIN_CTRL_G1_MASK | HPIPE_TX_TRAIN_CTRL_GN1_MASK
1516 | HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
1517 data = 0;
1518 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
1519
1520 /* Disable DTL frequency loop */
1521 mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
1522 data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
1523 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
1524
1525 /* Configure G3 DFE */
1526 mask = HPIPE_G3_DFE_RES_MASK;
1527 data = 0x3 << HPIPE_G3_DFE_RES_OFFSET;
1528 reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
1529
1530 /* Use TX/RX training result for DFE */
1531 mask = HPIPE_DFE_RES_FORCE_MASK;
1532 data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
1533 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
1534
1535 /* Configure initial and final coefficient value for receiver */
1536 mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
1537 data = 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
1538
1539 mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
1540 data |= 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
1541
1542 mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
1543 data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
1544 reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
1545
1546 /* Trigger sampler enable pulse */
1547 mask = HPIPE_SMAPLER_MASK;
1548 data = 0x1 << HPIPE_SMAPLER_OFFSET;
1549 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1550 udelay(5);
1551 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, 0, mask);
1552
1553 /* FFE resistor tuning for different bandwidth */
1554 mask = HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
1555 data = 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
1556 mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
1557 data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
1558 reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
1559
1560 /* Pattern lock lost timeout disable */
1561 mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
1562 data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
1563 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
1564
1565 /* Configure DFE adaptations */
1566 mask = HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK;
1567 data = 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET;
1568 mask |= HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK;
1569 data |= 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET;
1570 mask |= HPIPE_CDR_MAX_DFE_ADAPT_0_MASK;
1571 data |= 0x0 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET;
1572 mask |= HPIPE_CDR_MAX_DFE_ADAPT_1_MASK;
1573 data |= 0x1 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET;
1574 reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
1575
1576 mask = HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK;
1577 data = 0x0 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET;
1578 reg_set(hpipe_addr + HPIPE_DFE_CONTROL_REG, data, mask);
1579
1580 /* Genration 2 setting 1*/
1581 mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
1582 data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyk3c0024c2018-07-16 12:18:03 +02001583 mask |= HPIPE_G2_SET_1_G2_RX_SELMUPF_MASK;
1584 data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPF_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03001585 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
1586 data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
1587 reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
1588
1589 /* DFE enable */
1590 mask = HPIPE_G2_DFE_RES_MASK;
1591 data = 0x3 << HPIPE_G2_DFE_RES_OFFSET;
1592 reg_set(hpipe_addr + HPIPE_G2_SETTINGS_4_REG, data, mask);
1593
1594 /* Configure DFE Resolution */
1595 mask = HPIPE_LANE_CFG4_DFE_EN_SEL_MASK;
1596 data = 0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET;
1597 reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
1598
1599 /* VDD calibration control */
1600 mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
1601 data = 0x16 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
1602 reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
1603
1604 /* Set PLL Charge-pump Current Control */
1605 mask = HPIPE_G3_SETTING_5_G3_ICP_MASK;
1606 data = 0x4 << HPIPE_G3_SETTING_5_G3_ICP_OFFSET;
1607 reg_set(hpipe_addr + HPIPE_G3_SETTING_5_REG, data, mask);
1608
1609 /* Set lane rqualization remote setting */
1610 mask = HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK;
1611 data = 0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET;
1612 mask |= HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK;
1613 data |= 0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET;
1614 mask |= HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK;
1615 data |= 0x6 << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET;
1616 reg_set(hpipe_addr + HPIPE_LANE_EQ_REMOTE_SETTING_REG, data, mask);
1617
1618 mask = HPIPE_CFG_EQ_BUNDLE_DIS_MASK;
1619 data = 0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET;
1620 reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG2_REG, data, mask);
1621
1622 debug("stage: Comphy power up\n");
1623
1624 /* For PCIe X4 or X2:
1625 * release from reset only after finish to configure all lanes
1626 */
1627 if ((pcie_width == PCIE_LNK_X1) || (comphy_index == (pcie_width - 1))) {
1628 uint32_t i, start_lane, end_lane;
1629
1630 if (pcie_width != PCIE_LNK_X1) {
1631 /* allows writing to all lanes in one write */
1632 data = 0x0;
1633 if (pcie_width == PCIE_LNK_X2)
1634 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
1635 else if (pcie_width == PCIE_LNK_X4)
1636 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
1637 reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
1638 start_lane = 0;
1639 end_lane = pcie_width;
1640
1641 /* Release from PIPE soft reset
1642 * For PCIe by4 or by2:
1643 * release from soft reset all lanes - can't use
1644 * read modify write
1645 */
1646 reg_set(HPIPE_ADDR(
1647 COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), 0) +
1648 HPIPE_RST_CLK_CTRL_REG, 0x24, 0xffffffff);
1649 } else {
1650 start_lane = comphy_index;
1651 end_lane = comphy_index + 1;
1652
1653 /* Release from PIPE soft reset
1654 * for PCIe by4 or by2:
1655 * release from soft reset all lanes
1656 */
1657 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
1658 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
1659 HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
1660 }
1661
1662 if (pcie_width != PCIE_LNK_X1) {
1663 /* disable writing to all lanes with one write */
1664 if (pcie_width == PCIE_LNK_X2) {
1665 data = (COMPHY_LANE0 <<
1666 COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
1667 (COMPHY_LANE1 <<
1668 COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET);
1669 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
1670 } else if (pcie_width == PCIE_LNK_X4) {
1671 data = (COMPHY_LANE0 <<
1672 COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
1673 (COMPHY_LANE1 <<
1674 COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET) |
1675 (COMPHY_LANE2 <<
1676 COMMON_PHY_SD_CTRL1_COMPHY_2_PORT_OFFSET) |
1677 (COMPHY_LANE3 <<
1678 COMMON_PHY_SD_CTRL1_COMPHY_3_PORT_OFFSET);
1679 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
1680 }
1681 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1682 data, mask);
1683 }
1684
1685 debug("stage: Check PLL\n");
1686 /* Read lane status */
1687 for (i = start_lane; i < end_lane; i++) {
1688 addr = HPIPE_ADDR(
1689 COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), i) +
1690 HPIPE_LANE_STATUS1_REG;
1691 data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
1692 mask = data;
1693 ret = polling_with_timeout(addr, data, mask,
1694 PLL_LOCK_TIMEOUT,
1695 REG_32BIT);
1696 if (ret)
1697 ERROR("Failed to lock PCIE PLL\n");
1698 }
1699 }
1700
1701 debug_exit();
1702
1703 return ret;
1704}
1705
1706static int mvebu_cp110_comphy_rxaui_power_on(uint64_t comphy_base,
1707 uint8_t comphy_index, uint32_t comphy_mode)
1708{
1709 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
1710 uint32_t mask, data;
1711 int ret = 0;
1712
1713 debug_enter();
1714
1715 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1716 comphy_index);
1717 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1718 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1719 comphy_index);
1720
1721 /* configure phy selector for RXAUI */
1722 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
1723 comphy_mode);
1724
1725 /* RFU configurations - hard reset comphy */
1726 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1727 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1728 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1729 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1730 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1731
1732 if (comphy_index == 2) {
1733 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1734 0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET,
1735 COMMON_PHY_SD_CTRL1_RXAUI0_MASK);
1736 }
1737 if (comphy_index == 4) {
1738 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1739 0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET,
1740 COMMON_PHY_SD_CTRL1_RXAUI1_MASK);
1741 }
1742
1743 /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
1744 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1745 data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1746 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
1747 data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
1748 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
1749 data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
1750 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1751 data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1752 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1753 data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1754 mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
1755 data |= 0x0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
1756 mask |= SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK;
1757 data |= 0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET;
1758 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1759
1760 /* release from hard reset */
1761 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
1762 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
1763 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
1764 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
1765 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1766 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1767 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1768
1769 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
1770 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
1771 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
1772 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
1773 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1774
1775 /* Wait 1ms - until band gap and ref clock ready */
1776 mdelay(1);
1777
1778 /* Start comphy Configuration */
1779 debug("stage: Comphy configuration\n");
1780 /* set reference clock */
1781 reg_set(hpipe_addr + HPIPE_MISC_REG,
1782 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
1783 HPIPE_MISC_REFCLK_SEL_MASK);
1784 /* Power and PLL Control */
1785 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1786 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1787 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1788 data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1789 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1790 /* Loopback register */
1791 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
1792 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
1793 /* rx control 1 */
1794 mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
1795 data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
1796 mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
1797 data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
1798 reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
1799 /* DTL Control */
1800 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG,
1801 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET,
1802 HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK);
1803
1804 /* Set analog parameters from ETP(HW) */
1805 debug("stage: Analog parameters from ETP(HW)\n");
1806 /* SERDES External Configuration 2 */
1807 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG,
1808 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET,
1809 SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK);
1810 /* 0x7-DFE Resolution control */
1811 reg_set(hpipe_addr + HPIPE_DFE_REG0, 0x1 << HPIPE_DFE_RES_FORCE_OFFSET,
1812 HPIPE_DFE_RES_FORCE_MASK);
1813 /* 0xd-G1_Setting_0 */
1814 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
1815 0xd << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
1816 HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
1817 /* 0xE-G1_Setting_1 */
1818 mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
1819 data = 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyk3c0024c2018-07-16 12:18:03 +02001820 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
1821 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03001822 mask |= HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
1823 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
1824 reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
1825 /* 0xA-DFE_Reg3 */
1826 mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
1827 data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
1828 mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
1829 data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
1830 reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
1831
1832 /* 0x111-G1_Setting_4 */
1833 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1834 data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1835 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
1836
1837 debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
1838 /* SERDES External Configuration */
1839 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1840 data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1841 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1842 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1843 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1844 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1845 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1846
1847
1848 /* check PLL rx & tx ready */
1849 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1850 data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
1851 SD_EXTERNAL_STATUS0_PLL_TX_MASK;
1852 mask = data;
1853 data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
1854 if (data != 0) {
1855 debug("Read from reg = %lx - value = 0x%x\n",
1856 sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
1857 ERROR("SD_EXTERNAL_STATUS0_PLL_RX is %d, -\"-_PLL_TX is %d\n",
1858 (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK),
1859 (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK));
1860 ret = -ETIMEDOUT;
1861 }
1862
1863 /* RX init */
1864 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG,
1865 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET,
1866 SD_EXTERNAL_CONFIG1_RX_INIT_MASK);
1867
1868 /* check that RX init done */
1869 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1870 data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
1871 mask = data;
1872 data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
1873 if (data != 0) {
1874 debug("Read from reg = %lx - value = 0x%x\n",
1875 sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
1876 ERROR("SD_EXTERNAL_STATUS0_RX_INIT is 0\n");
1877 ret = -ETIMEDOUT;
1878 }
1879
1880 debug("stage: RF Reset\n");
1881 /* RF Reset */
1882 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1883 data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1884 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1885 data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1886 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1887
1888 debug_exit();
1889
1890 return ret;
1891}
1892
1893static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base,
1894 uint8_t comphy_index, uint32_t comphy_mode)
1895{
1896 uintptr_t hpipe_addr, comphy_addr, addr;
1897 uint32_t mask, data;
1898 int ret = 0;
1899
1900 debug_enter();
1901
1902 /* Configure PIPE selector for USB3 */
1903 mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
1904 comphy_mode);
1905
1906 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1907 comphy_index);
1908 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1909
1910 debug("stage: RFU configurations - hard reset comphy\n");
1911 /* RFU configurations - hard reset comphy */
1912 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1913 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1914 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1915 data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1916 mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1917 data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1918 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1919 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1920 mask |= COMMON_PHY_PHY_MODE_MASK;
1921 data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET;
1922 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1923
1924 /* release from hard reset */
1925 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1926 data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1927 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1928 data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1929 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1930
1931 /* Wait 1ms - until band gap and ref clock ready */
1932 mdelay(1);
1933
1934 /* Start comphy Configuration */
1935 debug("stage: Comphy configuration\n");
1936 /* Set PIPE soft reset */
1937 mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
1938 data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
1939 /* Set PHY datapath width mode for V0 */
1940 mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
1941 data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
1942 /* Set Data bus width USB mode for V0 */
1943 mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
1944 data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
1945 /* Set CORE_CLK output frequency for 250Mhz */
1946 mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
1947 data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
1948 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
1949 /* Set PLL ready delay for 0x2 */
1950 reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG,
1951 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
1952 HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
1953 /* Set reference clock to come from group 1 - 25Mhz */
1954 reg_set(hpipe_addr + HPIPE_MISC_REG,
1955 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
1956 HPIPE_MISC_REFCLK_SEL_MASK);
1957 /* Set reference frequcency select - 0x2 */
1958 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1959 data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1960 /* Set PHY mode to USB - 0x5 */
1961 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1962 data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1963 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1964 /* Set the amount of time spent in the LoZ state - set for 0x7 */
1965 reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
1966 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
1967 HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
1968 /* Set max PHY generation setting - 5Gbps */
1969 reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
1970 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
1971 HPIPE_INTERFACE_GEN_MAX_MASK);
1972 /* Set select data width 20Bit (SEL_BITS[2:0]) */
1973 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
1974 0x1 << HPIPE_LOOPBACK_SEL_OFFSET,
1975 HPIPE_LOOPBACK_SEL_MASK);
1976 /* select de-emphasize 3.5db */
1977 reg_set(hpipe_addr + HPIPE_LANE_CONFIG0_REG,
1978 0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET,
1979 HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK);
1980 /* override tx margining from the MAC */
1981 reg_set(hpipe_addr + HPIPE_TST_MODE_CTRL_REG,
1982 0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET,
1983 HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK);
1984
1985 /* Start analog parameters from ETP(HW) */
1986 debug("stage: Analog parameters from ETP(HW)\n");
1987 /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */
1988 mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK;
1989 data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET;
1990 /* Set Override PHY DFE control pins for 0x1 */
1991 mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK;
1992 data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET;
1993 /* Set Spread Spectrum Clock Enable fot 0x1 */
1994 mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK;
1995 data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET;
1996 reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
1997 /* Confifure SSC amplitude */
1998 mask = HPIPE_G2_TX_SSC_AMP_MASK;
1999 data = 0x1f << HPIPE_G2_TX_SSC_AMP_OFFSET;
2000 reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
2001 /* End of analog parameters */
2002
2003 debug("stage: Comphy power up\n");
2004 /* Release from PIPE soft reset */
2005 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
2006 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
2007 HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
2008
2009 /* wait 15ms - for comphy calibration done */
2010 debug("stage: Check PLL\n");
2011 /* Read lane status */
2012 addr = hpipe_addr + HPIPE_LANE_STATUS1_REG;
2013 data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
2014 mask = data;
2015 data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
2016 if (data != 0) {
2017 debug("Read from reg = %lx - value = 0x%x\n",
2018 hpipe_addr + HPIPE_LANE_STATUS1_REG, data);
2019 ERROR("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n");
2020 ret = -ETIMEDOUT;
2021 }
2022
2023 debug_exit();
2024
2025 return ret;
2026}
2027
Grzegorz Jaszczyk8e8ec8c2019-03-08 19:51:21 +01002028static void rx_pre_train(uint64_t comphy_base, uint8_t comphy_index)
2029{
2030 uintptr_t hpipe_addr;
2031 uint32_t mask, data;
2032
2033 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2034 comphy_index);
2035
2036 debug("rx_training preparation\n\n");
2037
2038 mask = HPIPE_TRX0_GAIN_TRAIN_WITH_C_MASK;
2039 data = (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF);
2040 mask |= HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_MASK;
2041 data |= (0x0 << HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF);
2042 reg_set(hpipe_addr + HPIPE_TRX0_REG, data, mask);
2043
2044
2045 mask = HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK;
2046 data = (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF);
2047 mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_MASK;
2048 data |= (0x0 << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF);
2049 reg_set(hpipe_addr + HPIPE_TRX_REG2, data, mask);
2050
2051 mask = HPIPE_TRX_REG1_MIN_BOOST_MODE_MASK;
2052 data = (0x1 << HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF);
2053 reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask);
2054
2055 mask = HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_MASK;
2056 data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF);
2057 reg_set(hpipe_addr + HPIPE_CDR_CONTROL1_REG, data, mask);
2058
2059 mask = HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_MASK;
2060 data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF);
2061 reg_set(hpipe_addr + HPIPE_CDR_CONTROL2_REG, data, mask);
2062
2063 mask = HPIPE_CRD_MIDPOINT_PHASE_OS_MASK;
2064 data = (0x0 << HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET);
2065 reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
2066
2067 mask = HPIPE_TRX_REG1_SUMFTAP_EN_MASK;
2068 data = (0x38 << HPIPE_TRX_REG1_SUMFTAP_EN_OFF);
2069 mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK;
2070 data |= (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF);
2071 reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask);
2072}
2073
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002074int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base,
2075 uint8_t comphy_index)
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002076{
2077 uint32_t mask, data, timeout;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002078 uint32_t g1_ffe_cap_sel, g1_ffe_res_sel, align90, g1_dfe_res;
Grzegorz Jaszczyk8e8ec8c2019-03-08 19:51:21 +01002079 uintptr_t hpipe_addr;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002080
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002081 uint8_t ap_nr, cp_nr;
2082
2083 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
2084
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002085 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2086 comphy_index);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002087
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002088 debug_enter();
2089
Grzegorz Jaszczyk8e8ec8c2019-03-08 19:51:21 +01002090 rx_pre_train(comphy_base, comphy_index);
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002091
2092 debug("Preparation for rx_training\n\n");
2093
2094 /* Use the FFE table */
2095 mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
2096 data = 0 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
2097 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
2098
2099 /* Use auto-calibration value */
2100 mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
2101 data = 0 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
2102 reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
2103 data, mask);
2104
2105 /* Use Tx/Rx training results */
2106 mask = HPIPE_DFE_RES_FORCE_MASK;
2107 data = 0 << HPIPE_DFE_RES_FORCE_OFFSET;
2108 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
2109
Grzegorz Jaszczyk8e8ec8c2019-03-08 19:51:21 +01002110 debug("Enable RX training\n\n");
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002111
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002112 mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
2113 data = 0x1 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002114 reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002115
2116 /* Check the result of RX training */
2117 timeout = RX_TRAINING_TIMEOUT;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002118 mask = HPIPE_INTERRUPT_TRX_TRAIN_DONE_OFFSET |
2119 HPIPE_INTERRUPT_DFE_DONE_INT_OFFSET |
2120 HPIPE_INTERRUPT_RX_TRAIN_COMPLETE_INT_MASK;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002121 while (timeout) {
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002122 data = mmio_read_32(hpipe_addr + HPIPE_INTERRUPT_1_REGISTER);
2123 if (data & mask)
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002124 break;
2125 mdelay(1);
2126 timeout--;
2127 }
2128
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002129 debug("RX training result: interrupt reg 0x%lx = 0x%x\n\n",
2130 hpipe_addr + HPIPE_INTERRUPT_1_REGISTER, data);
2131
2132 if (timeout == 0 || data & HPIPE_TRX_TRAIN_TIME_OUT_INT_MASK) {
2133 ERROR("Rx training timeout...\n");
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002134 return -ETIMEDOUT;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002135 }
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002136
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002137 if (data & HPIPE_TRX_TRAIN_FAILED_MASK) {
2138 ERROR("Rx training failed...\n");
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002139 return -EINVAL;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002140 }
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002141
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002142 mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
2143 data = 0x0 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
2144 reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002145
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002146 debug("Training done, reading results...\n\n");
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002147
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002148 mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_MASK;
2149 g1_ffe_res_sel = ((mmio_read_32(hpipe_addr +
2150 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
2151 & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_OFFSET);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002152
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002153 mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_MASK;
2154 g1_ffe_cap_sel = ((mmio_read_32(hpipe_addr +
2155 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
2156 & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_OFFSET);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002157
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002158 mask = HPIPE_DATA_PHASE_ADAPTED_OS_PH_MASK;
2159 align90 = ((mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG)
2160 & mask) >> HPIPE_DATA_PHASE_ADAPTED_OS_PH_OFFSET);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002161
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002162 mask = HPIPE_ADAPTED_DFE_RES_MASK;
2163 g1_dfe_res = ((mmio_read_32(hpipe_addr +
2164 HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG)
2165 & mask) >> HPIPE_ADAPTED_DFE_RES_OFFSET);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002166
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002167 debug("================================================\n");
2168 debug("Switching to static configuration:\n");
2169 debug("FFE_RES = 0x%x FFE_CAP = 0x%x align90 = 0x%x g1_dfe_res 0x%x\n",
2170 g1_ffe_res_sel, g1_ffe_cap_sel, align90, g1_dfe_res);
2171 debug("Result after training: 0x%lx= 0x%x, 0x%lx= 0x%x, 0x%lx = 0x%x\n",
2172 (hpipe_addr + HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
2173 mmio_read_32(hpipe_addr +
2174 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
2175 (hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
2176 mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
2177 (hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG),
2178 mmio_read_32(hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG));
2179 debug("================================================\n");
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002180
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002181 /* Update FFE_RES */
2182 mask = HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
2183 data = g1_ffe_res_sel << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
2184 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002185
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002186 /* Update FFE_CAP */
2187 mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
2188 data = g1_ffe_cap_sel << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
2189 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002190
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002191 /* Bypass the FFE table settings and use the FFE settings directly from
2192 * registers FFE_RES_SEL and FFE_CAP_SEL
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002193 */
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002194 mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
2195 data = 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
2196 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002197
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002198 /* Force DFE resolution (use gen table value) */
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002199 mask = HPIPE_DFE_RES_FORCE_MASK;
Grzegorz Jaszczyk8e8ec8c2019-03-08 19:51:21 +01002200 data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002201 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
2202
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002203 /* 0x111-G1 DFE_Setting_4 */
2204 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
2205 data = g1_dfe_res << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
2206 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002207
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002208 printf("########################################################\n");
2209 printf("# To use trained values update the ATF sources:\n");
Grzegorz Jaszczyka2847172019-11-05 13:14:59 +01002210 printf("# plat/marvell/armada/a8k/<board_type>/board/phy-porting-layer.h ");
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002211 printf("file\n# with new values as below (for appropriate AP nr %d",
2212 ap_nr);
2213 printf("and CP nr: %d comphy_index %d\n\n",
2214 cp_nr, comphy_index);
2215 printf("static struct xfi_params xfi_static_values_tab[AP_NUM]");
2216 printf("[CP_NUM][MAX_LANE_NR] = {\n");
2217 printf("\t...\n");
2218 printf("\t.g1_ffe_res_sel = 0x%x,\n", g1_ffe_res_sel);
2219 printf("\t.g1_ffe_cap_sel = 0x%x,\n", g1_ffe_cap_sel);
2220 printf("\t.align90 = 0x%x,\n", align90);
2221 printf("\t.g1_dfe_res = 0x%x\n", g1_dfe_res);
2222 printf("\t...\n");
2223 printf("};\n\n");
2224 printf("########################################################\n");
2225
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002226 rx_trainng_done[ap_nr][cp_nr][comphy_index] = 1;
2227
2228 return 0;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002229}
2230
2231/* During AP the proper mode is auto-negotiated and the mac, pcs and serdes
2232 * configuration are done by the firmware loaded to the MG's CM3 for appropriate
2233 * negotiated mode. Therefore there is no need to configure the mac, pcs and
2234 * serdes from u-boot. The only thing that need to be setup is powering up
2235 * the comphy, which is done through Common PHY<n> Configuration 1 Register
2236 * (CP0: 0xF2441000, CP1: 0xF4441000). This step can't be done by MG's CM3,
2237 * since it doesn't have an access to this register-set (but it has access to
2238 * the network registers like: MG, AP, MAC, PCS, Serdes etc.)
2239 */
2240static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base,
Grzegorz Jaszczyk050eb192019-03-28 13:02:42 +01002241 uint8_t comphy_index,
2242 uint32_t comphy_mode)
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002243{
2244 uint32_t mask, data;
Grzegorz Jaszczyk5a9e46e2019-04-12 16:57:14 +02002245 uint8_t ap_nr, cp_nr;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002246 uintptr_t comphy_addr = comphy_addr =
2247 COMPHY_ADDR(comphy_base, comphy_index);
2248
Grzegorz Jaszczyk050eb192019-03-28 13:02:42 +01002249 /* configure phy selector for XFI/SFI */
2250 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
2251 comphy_mode);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002252 debug_enter();
2253 debug("stage: RFU configurations - hard reset comphy\n");
2254 /* RFU configurations - hard reset comphy */
2255 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
2256 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
2257 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
2258 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
2259 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
2260 debug_exit();
2261
Grzegorz Jaszczyk5a9e46e2019-04-12 16:57:14 +02002262 /* Start AP Firmware */
2263 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
Grzegorz Jaszczyk2cae4a82019-06-18 14:43:02 +02002264 mg_start_ap_fw(cp_nr, comphy_index);
Grzegorz Jaszczyk5a9e46e2019-04-12 16:57:14 +02002265
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002266 return 0;
2267}
2268
2269/*
2270 * This function allows to reset the digital synchronizers between
2271 * the MAC and the PHY, it is required when the MAC changes its state.
2272 */
2273int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base,
2274 uint8_t comphy_index,
2275 uint32_t comphy_mode, uint32_t command)
2276{
2277 int mode = COMPHY_GET_MODE(comphy_mode);
2278 uintptr_t sd_ip_addr;
2279 uint32_t mask, data;
2280
2281 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2282 comphy_index);
2283
2284 switch (mode) {
2285 case (COMPHY_SGMII_MODE):
2286 case (COMPHY_HS_SGMII_MODE):
2287 case (COMPHY_XFI_MODE):
2288 case (COMPHY_SFI_MODE):
2289 case (COMPHY_RXAUI_MODE):
2290 mask = SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2291 data = ((command == COMPHY_COMMAND_DIGITAL_PWR_OFF) ?
2292 0x0 : 0x1) << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2293 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2294 break;
2295 default:
2296 ERROR("comphy%d: Digital PWR ON/OFF is not supported\n",
2297 comphy_index);
2298 return -EINVAL;
2299 }
2300
2301 return 0;
2302}
2303
Grzegorz Jaszczykf858e982018-07-12 07:40:34 +02002304int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint8_t comphy_index,
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002305 uint64_t comphy_mode)
2306{
2307 int mode = COMPHY_GET_MODE(comphy_mode);
2308 int err = 0;
2309
2310 debug_enter();
2311
2312 switch (mode) {
2313 case(COMPHY_SATA_MODE):
2314 err = mvebu_cp110_comphy_sata_power_on(comphy_base,
2315 comphy_index,
2316 comphy_mode);
2317 break;
2318 case(COMPHY_SGMII_MODE):
2319 case(COMPHY_HS_SGMII_MODE):
2320 err = mvebu_cp110_comphy_sgmii_power_on(comphy_base,
2321 comphy_index,
2322 comphy_mode);
2323 break;
2324 /* From comphy perspective, XFI and SFI are the same */
2325 case (COMPHY_XFI_MODE):
2326 case (COMPHY_SFI_MODE):
2327 err = mvebu_cp110_comphy_xfi_power_on(comphy_base,
2328 comphy_index,
2329 comphy_mode);
2330 break;
2331 case (COMPHY_PCIE_MODE):
2332 err = mvebu_cp110_comphy_pcie_power_on(comphy_base,
2333 comphy_index,
2334 comphy_mode);
2335 break;
2336 case (COMPHY_RXAUI_MODE):
2337 err = mvebu_cp110_comphy_rxaui_power_on(comphy_base,
2338 comphy_index,
2339 comphy_mode);
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002340 break;
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002341 case (COMPHY_USB3H_MODE):
2342 case (COMPHY_USB3D_MODE):
2343 err = mvebu_cp110_comphy_usb3_power_on(comphy_base,
2344 comphy_index,
2345 comphy_mode);
2346 break;
2347 case (COMPHY_AP_MODE):
Grzegorz Jaszczyk050eb192019-03-28 13:02:42 +01002348 err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index,
2349 comphy_mode);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002350 break;
2351 default:
Grzegorz Jaszczykf858e982018-07-12 07:40:34 +02002352 ERROR("comphy%d: unsupported comphy mode\n", comphy_index);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002353 err = -EINVAL;
2354 break;
2355 }
2356
2357 debug_exit();
2358
2359 return err;
2360}
2361
Igal Liberman55df84f2018-11-15 16:13:11 +02002362int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint8_t comphy_index,
2363 uint64_t comphy_mode)
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002364{
2365 uintptr_t sd_ip_addr, comphy_ip_addr;
2366 uint32_t mask, data;
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002367 uint8_t ap_nr, cp_nr;
Igal Liberman55df84f2018-11-15 16:13:11 +02002368 _Bool called_from_uboot = COMPHY_GET_CALLER(comphy_mode);
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002369
2370 debug_enter();
2371
Igal Liberman55df84f2018-11-15 16:13:11 +02002372 /* Power-off might happen because of 2 things:
2373 * 1. Bootloader turns off unconnected lanes
2374 * 2. Linux turns off all lanes during boot
2375 * (and then reconfigure it).
2376 *
2377 * For PCIe, there's a problem:
2378 * In Armada 8K DB boards, PCIe initialization can be executed
2379 * only once (PCIe reset performed during chip power on and
2380 * it cannot be executed via GPIO later) so a lane configured to
2381 * PCIe should not be powered off by Linux.
2382 *
2383 * So, check 2 things:
2384 * 1. Is Linux called for power-off?
2385 * 2. Is the comphy configured to PCIe?
2386 * If the answer is YES for both 1 and 2, skip the power-off.
2387 *
2388 * TODO: In MacciatoBIN, PCIe reset is connected via GPIO,
2389 * so after GPIO reset is added to Linux Kernel, it can be
2390 * powered-off.
2391 */
2392 if (!called_from_uboot) {
2393 data = mmio_read_32(comphy_base +
2394 COMMON_SELECTOR_PIPE_REG_OFFSET);
2395 data >>= (COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index);
2396 data &= COMMON_SELECTOR_COMPHY_MASK;
2397 if (data == COMMON_SELECTOR_PIPE_COMPHY_PCIE)
2398 return 0;
2399 }
2400
Grzegorz Jaszczyk42a29332018-06-29 18:00:33 +02002401 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
2402
2403 if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) {
2404 debug("Skip %s for comphy[%d][%d][%d], due to rx training\n",
2405 __func__, ap_nr, cp_nr, comphy_index);
2406 return 0;
2407 }
2408
Konstantin Porotchkin0ade8cd2018-04-24 19:23:09 +03002409 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2410 comphy_index);
2411 comphy_ip_addr = COMPHY_ADDR(comphy_base, comphy_index);
2412
2413 /* Hard reset the comphy, for Ethernet modes and Sata */
2414 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
2415 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
2416 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
2417 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
2418 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2419 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2420 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2421
2422 /* PCIe reset */
2423 spin_lock(&cp110_mac_reset_lock);
2424
2425 /* The mvebu_cp110_comphy_power_off will be called only from Linux (to
2426 * override settings done by bootloader) and it will be relevant only
2427 * to PCIe (called before check if to skip pcie power off or not).
2428 */
2429 data = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2430 SYS_CTRL_UINIT_SOFT_RESET_REG);
2431 switch (comphy_index) {
2432 case COMPHY_LANE0:
2433 data &= ~PCIE_MAC_RESET_MASK_PORT0;
2434 break;
2435 case COMPHY_LANE4:
2436 data &= ~PCIE_MAC_RESET_MASK_PORT1;
2437 break;
2438 case COMPHY_LANE5:
2439 data &= ~PCIE_MAC_RESET_MASK_PORT2;
2440 break;
2441 }
2442
2443 mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2444 SYS_CTRL_UINIT_SOFT_RESET_REG, data);
2445 spin_unlock(&cp110_mac_reset_lock);
2446
2447 /* Hard reset the comphy, for PCIe and usb3 */
2448 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
2449 data = 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
2450 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
2451 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
2452 reg_set(comphy_ip_addr + COMMON_PHY_CFG1_REG, data, mask);
2453
2454 /* Clear comphy PHY and PIPE selector, can't rely on previous config. */
2455 mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
2456 mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
2457
2458 debug_exit();
2459
2460 return 0;
2461}