blob: fa9fe410070325f9200e76093f363f3160cf5315 [file] [log] [blame]
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001/*
2 * Copyright (C) 2018 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
8/* Marvell CP110 SoC COMPHY unit driver */
9
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030010#include <errno.h>
Scott Brandene5dcf982020-08-25 13:49:32 -070011#include <inttypes.h>
12#include <stdint.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000013
14#include <common/debug.h>
15#include <drivers/delay_timer.h>
Grzegorz Jaszczyk1540ffb2019-04-12 16:57:14 +020016#include <mg_conf_cm3/mg_conf_cm3.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000017#include <lib/mmio.h>
18#include <lib/spinlock.h>
19
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030020#include <mvebu_def.h>
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030021#include "mvebu.h"
22#include "comphy-cp110.h"
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020023#include "phy-comphy-cp110.h"
24#include "phy-comphy-common.h"
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030025
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020026#if __has_include("phy-porting-layer.h")
27#include "phy-porting-layer.h"
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030028#else
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020029#include "phy-default-porting-layer.h"
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030030#endif
31
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030032/* COMPHY speed macro */
33#define COMPHY_SPEED_1_25G 0 /* SGMII 1G */
34#define COMPHY_SPEED_2_5G 1
Pali Rohár51974d22021-08-27 11:16:43 +020035#define COMPHY_SPEED_3_125G 2 /* 2500Base-X */
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030036#define COMPHY_SPEED_5G 3
37#define COMPHY_SPEED_5_15625G 4 /* XFI 5G */
38#define COMPHY_SPEED_6G 5
39#define COMPHY_SPEED_10_3125G 6 /* XFI 10G */
40#define COMPHY_SPEED_MAX 0x3F
41/* The default speed for IO with fixed known speed */
42#define COMPHY_SPEED_DEFAULT COMPHY_SPEED_MAX
43
44/* Commands for comphy driver */
45#define COMPHY_COMMAND_DIGITAL_PWR_OFF 0x00000001
46#define COMPHY_COMMAND_DIGITAL_PWR_ON 0x00000002
47
48#define COMPHY_PIPE_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + 0x120000)
49
50/* System controller registers */
51#define PCIE_MAC_RESET_MASK_PORT0 BIT(13)
52#define PCIE_MAC_RESET_MASK_PORT1 BIT(11)
53#define PCIE_MAC_RESET_MASK_PORT2 BIT(12)
54#define SYS_CTRL_UINIT_SOFT_RESET_REG 0x268
55#define SYS_CTRL_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + 0x440000)
56
57/* DFX register spaces */
Guo Yi4ad43132020-12-17 22:30:54 +000058#define SAR_RST_PCIE0_CLOCK_CONFIG_CP0_OFFSET (30)
59#define SAR_RST_PCIE0_CLOCK_CONFIG_CP0_MASK (0x1UL << \
60 SAR_RST_PCIE0_CLOCK_CONFIG_CP0_OFFSET)
61#define SAR_RST_PCIE1_CLOCK_CONFIG_CP0_OFFSET (31)
62#define SAR_RST_PCIE1_CLOCK_CONFIG_CP0_MASK (0x1UL << \
63 SAR_RST_PCIE1_CLOCK_CONFIG_CP0_OFFSET)
64#define SAR_STATUS_0_REG 0x40600
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030065#define DFX_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + DFX_BASE)
Alex Evraevb0a74302020-06-24 22:24:56 +030066/* Common Phy training */
67#define COMPHY_TRX_TRAIN_COMPHY_OFFS 0x1000
68#define COMPHY_TRX_TRAIN_RX_TRAIN_ENABLE 0x1
69#define COMPHY_TRX_RELATIVE_ADDR(comphy_index) (comphy_train_base + \
70 (comphy_index) * COMPHY_TRX_TRAIN_COMPHY_OFFS)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030071
72/* The same Units Soft Reset Config register are accessed in all PCIe ports
73 * initialization, so a spin lock is defined in case when more than 1 CPUs
74 * resets PCIe MAC and need to access the register in the same time. The spin
75 * lock is shared by all CP110 units.
76 */
77spinlock_t cp110_mac_reset_lock;
78
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030079/* These values come from the PCI Express Spec */
80enum pcie_link_width {
81 PCIE_LNK_WIDTH_RESRV = 0x00,
82 PCIE_LNK_X1 = 0x01,
83 PCIE_LNK_X2 = 0x02,
84 PCIE_LNK_X4 = 0x04,
85 PCIE_LNK_X8 = 0x08,
86 PCIE_LNK_X12 = 0x0C,
87 PCIE_LNK_X16 = 0x10,
88 PCIE_LNK_X32 = 0x20,
89 PCIE_LNK_WIDTH_UNKNOWN = 0xFF,
90};
91
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020092_Bool rx_trainng_done[AP_NUM][CP_NUM][MAX_LANE_NR] = {0};
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030093
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020094static void mvebu_cp110_get_ap_and_cp_nr(uint8_t *ap_nr, uint8_t *cp_nr,
95 uint64_t comphy_base)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +030096{
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +020097#if (AP_NUM == 1)
98 *ap_nr = 0;
99#else
100 *ap_nr = (((comphy_base & ~0xffffff) - MVEBU_AP_IO_BASE(0)) /
101 AP_IO_OFFSET);
102#endif
103
104 *cp_nr = (((comphy_base & ~0xffffff) - MVEBU_AP_IO_BASE(*ap_nr)) /
105 MVEBU_CP_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300106
Scott Brandene5dcf982020-08-25 13:49:32 -0700107 debug("cp_base 0x%" PRIx64 ", ap_io_base 0x%lx, cp_offset 0x%lx\n",
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200108 comphy_base, (unsigned long)MVEBU_AP_IO_BASE(*ap_nr),
109 (unsigned long)MVEBU_CP_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300110}
111
112/* Clear PIPE selector - avoid collision with previous configuration */
113static void mvebu_cp110_comphy_clr_pipe_selector(uint64_t comphy_base,
114 uint8_t comphy_index)
115{
116 uint32_t reg, mask, field;
117 uint32_t comphy_offset =
118 COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
119
120 mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
121 reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
122 field = reg & mask;
123
124 if (field) {
125 reg &= ~mask;
126 mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET,
127 reg);
128 }
129}
130
131/* Clear PHY selector - avoid collision with previous configuration */
132static void mvebu_cp110_comphy_clr_phy_selector(uint64_t comphy_base,
133 uint8_t comphy_index)
134{
135 uint32_t reg, mask, field;
136 uint32_t comphy_offset =
137 COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
138
139 mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
140 reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
141 field = reg & mask;
142
143 /* Clear comphy selector - if it was already configured.
144 * (might be that this comphy was configured as PCIe/USB,
145 * in such case, no need to clear comphy selector because PCIe/USB
146 * are controlled by hpipe selector).
147 */
148 if (field) {
149 reg &= ~mask;
150 mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET,
151 reg);
152 }
153}
154
155/* PHY selector configures SATA and Network modes */
156static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base,
157 uint8_t comphy_index, uint32_t comphy_mode)
158{
159 uint32_t reg, mask;
160 uint32_t comphy_offset =
161 COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
162 int mode;
163
164 /* If phy selector is used the pipe selector should be marked as
165 * unconnected.
166 */
167 mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
168
169 /* Comphy mode (compound of the IO mode and id). Here, only the IO mode
170 * is required to distinguish between SATA and network modes.
171 */
172 mode = COMPHY_GET_MODE(comphy_mode);
173
174 mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
175 reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
176 reg &= ~mask;
177
178 /* SATA port 0/1 require the same configuration */
179 if (mode == COMPHY_SATA_MODE) {
180 /* SATA selector values is always 4 */
181 reg |= COMMON_SELECTOR_COMPHYN_SATA << comphy_offset;
182 } else {
183 switch (comphy_index) {
184 case(0):
185 case(1):
186 case(2):
187 /* For comphy 0,1, and 2:
188 * Network selector value is always 1.
189 */
190 reg |= COMMON_SELECTOR_COMPHY0_1_2_NETWORK <<
191 comphy_offset;
192 break;
193 case(3):
194 /* For comphy 3:
195 * 0x1 = RXAUI_Lane1
Pali Rohár51974d22021-08-27 11:16:43 +0200196 * 0x2 = SGMII/Base-X Port1
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300197 */
198 if (mode == COMPHY_RXAUI_MODE)
199 reg |= COMMON_SELECTOR_COMPHY3_RXAUI <<
200 comphy_offset;
201 else
202 reg |= COMMON_SELECTOR_COMPHY3_SGMII <<
203 comphy_offset;
204 break;
205 case(4):
206 /* For comphy 4:
Pali Rohár51974d22021-08-27 11:16:43 +0200207 * 0x1 = SGMII/Base-X Port1, XFI1/SFI1
208 * 0x2 = SGMII/Base-X Port0: XFI0/SFI0, RXAUI_Lane0
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300209 *
Pali Rohár51974d22021-08-27 11:16:43 +0200210 * We want to check if SGMII1 is the
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300211 * requested mode in order to determine which value
212 * should be set (all other modes use the same value)
213 * so we need to strip the mode, and check the ID
Pali Rohár51974d22021-08-27 11:16:43 +0200214 * because we might handle SGMII0 too.
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300215 */
216 /* TODO: need to distinguish between CP110 and CP115
217 * as SFI1/XFI1 available only for CP115.
218 */
219 if ((mode == COMPHY_SGMII_MODE ||
Pali Rohár51974d22021-08-27 11:16:43 +0200220 mode == COMPHY_2500BASEX_MODE ||
Grzegorz Jaszczyk7a61f162019-03-28 13:02:42 +0100221 mode == COMPHY_SFI_MODE ||
222 mode == COMPHY_XFI_MODE ||
223 mode == COMPHY_AP_MODE)
Grzegorz Jaszczyk05b17732018-10-19 15:30:02 +0200224 && COMPHY_GET_ID(comphy_mode) == 1)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300225 reg |= COMMON_SELECTOR_COMPHY4_PORT1 <<
226 comphy_offset;
227 else
228 reg |= COMMON_SELECTOR_COMPHY4_ALL_OTHERS <<
229 comphy_offset;
230 break;
231 case(5):
232 /* For comphy 5:
Pali Rohár51974d22021-08-27 11:16:43 +0200233 * 0x1 = SGMII/Base-X Port2
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300234 * 0x2 = RXAUI Lane1
235 */
236 if (mode == COMPHY_RXAUI_MODE)
237 reg |= COMMON_SELECTOR_COMPHY5_RXAUI <<
238 comphy_offset;
239 else
240 reg |= COMMON_SELECTOR_COMPHY5_SGMII <<
241 comphy_offset;
242 break;
243 }
244 }
245
246 mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET, reg);
247}
248
249/* PIPE selector configures for PCIe, USB 3.0 Host, and USB 3.0 Device mode */
250static void mvebu_cp110_comphy_set_pipe_selector(uint64_t comphy_base,
251 uint8_t comphy_index, uint32_t comphy_mode)
252{
253 uint32_t reg;
254 uint32_t shift = COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
255 int mode = COMPHY_GET_MODE(comphy_mode);
256 uint32_t mask = COMMON_SELECTOR_COMPHY_MASK << shift;
257 uint32_t pipe_sel = 0x0;
258
259 /* If pipe selector is used the phy selector should be marked as
260 * unconnected.
261 */
262 mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
263
264 reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
265 reg &= ~mask;
266
267 switch (mode) {
268 case (COMPHY_PCIE_MODE):
269 /* For lanes support PCIE, selector value are all same */
270 pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_PCIE;
271 break;
272
273 case (COMPHY_USB3H_MODE):
274 /* Only lane 1-4 support USB host, selector value is same */
275 if (comphy_index == COMPHY_LANE0 ||
276 comphy_index == COMPHY_LANE5)
277 ERROR("COMPHY[%d] mode[%d] is invalid\n",
278 comphy_index, mode);
279 else
280 pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBH;
281 break;
282
283 case (COMPHY_USB3D_MODE):
284 /* Lane 1 and 4 support USB device, selector value is same */
285 if (comphy_index == COMPHY_LANE1 ||
286 comphy_index == COMPHY_LANE4)
287 pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBD;
288 else
289 ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index,
290 mode);
291 break;
292
293 default:
294 ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode);
295 break;
296 }
297
298 mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET, reg |
299 (pipe_sel << shift));
300}
301
302int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index)
303{
304 uintptr_t sd_ip_addr, addr;
305 uint32_t mask, data;
306 int ret = 0;
307
308 debug_enter();
309
310 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
311 comphy_index);
312
313 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
314 data = SD_EXTERNAL_STATUS0_PLL_TX_MASK &
315 SD_EXTERNAL_STATUS0_PLL_RX_MASK;
316 mask = data;
317 data = polling_with_timeout(addr, data, mask,
318 PLL_LOCK_TIMEOUT, REG_32BIT);
319 if (data != 0) {
320 if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
321 ERROR("RX PLL is not locked\n");
322 if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
323 ERROR("TX PLL is not locked\n");
324
325 ret = -ETIMEDOUT;
326 }
327
328 debug_exit();
329
330 return ret;
331}
332
Grzegorz Jaszczykff9311b2020-01-21 17:02:10 +0100333static void mvebu_cp110_polarity_invert(uintptr_t addr, uint8_t phy_polarity_invert)
334{
335 uint32_t mask, data;
336
337 /* Set RX / TX polarity */
338 data = mask = 0x0U;
339 if ((phy_polarity_invert & COMPHY_POLARITY_TXD_INVERT) != 0) {
340 data |= (1 << HPIPE_SYNC_PATTERN_TXD_INV_OFFSET);
341 mask |= HPIPE_SYNC_PATTERN_TXD_INV_MASK;
342 debug("%s: inverting TX polarity\n", __func__);
343 }
344
345 if ((phy_polarity_invert & COMPHY_POLARITY_RXD_INVERT) != 0) {
346 data |= (1 << HPIPE_SYNC_PATTERN_RXD_INV_OFFSET);
347 mask |= HPIPE_SYNC_PATTERN_RXD_INV_MASK;
348 debug("%s: inverting RX polarity\n", __func__);
349 }
350
351 reg_set(addr, data, mask);
352}
353
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300354static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base,
355 uint8_t comphy_index, uint32_t comphy_mode)
356{
357 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr;
358 uint32_t mask, data;
Grzegorz Jaszczykff9311b2020-01-21 17:02:10 +0100359 uint8_t ap_nr, cp_nr, phy_polarity_invert;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300360 int ret = 0;
361
362 debug_enter();
363
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200364 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
365
366 const struct sata_params *sata_static_values =
367 &sata_static_values_tab[ap_nr][cp_nr][comphy_index];
368
Grzegorz Jaszczykff9311b2020-01-21 17:02:10 +0100369 phy_polarity_invert = sata_static_values->polarity_invert;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200370
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300371 /* configure phy selector for SATA */
372 mvebu_cp110_comphy_set_phy_selector(comphy_base,
373 comphy_index, comphy_mode);
374
375 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
376 comphy_index);
377 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
378 comphy_index);
379 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
380
381 debug(" add hpipe 0x%lx, sd 0x%lx, comphy 0x%lx\n",
382 hpipe_addr, sd_ip_addr, comphy_addr);
383 debug("stage: RFU configurations - hard reset comphy\n");
384 /* RFU configurations - hard reset comphy */
385 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
386 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
387 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
388 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
389 mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
390 data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
391 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
392 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
393 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
394
395 /* Set select data width 40Bit - SATA mode only */
396 reg_set(comphy_addr + COMMON_PHY_CFG6_REG,
397 0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET,
398 COMMON_PHY_CFG6_IF_40_SEL_MASK);
399
400 /* release from hard reset in SD external */
401 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
402 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
403 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
404 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
405 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
406
407 /* Wait 1ms - until band gap and ref clock ready */
408 mdelay(1);
409
410 debug("stage: Comphy configuration\n");
411 /* Start comphy Configuration */
412 /* Set reference clock to comes from group 1 - choose 25Mhz */
413 reg_set(hpipe_addr + HPIPE_MISC_REG,
414 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
415 HPIPE_MISC_REFCLK_SEL_MASK);
416 /* Reference frequency select set 1 (for SATA = 25Mhz) */
417 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
418 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
419 /* PHY mode select (set SATA = 0x0 */
420 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
421 data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
422 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
423 /* Set max PHY generation setting - 6Gbps */
424 reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
425 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
426 HPIPE_INTERFACE_GEN_MAX_MASK);
427 /* Set select data width 40Bit (SEL_BITS[2:0]) */
428 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
429 0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
430
431 debug("stage: Analog parameters from ETP(HW)\n");
432 /* G1 settings */
433 mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200434 data = sata_static_values->g1_rx_selmupi <<
435 HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +0200436 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200437 data |= sata_static_values->g1_rx_selmupf <<
438 HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300439 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200440 data |= sata_static_values->g1_rx_selmufi <<
441 HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300442 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200443 data |= sata_static_values->g1_rx_selmuff <<
444 HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300445 mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
446 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
447 reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
448
449 mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
450 data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
451 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
452 data |= 0x2 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
453 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
454 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
455 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_MASK;
456 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET;
457 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_MASK;
458 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET;
459 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
460
461 /* G2 settings */
462 mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200463 data = sata_static_values->g2_rx_selmupi <<
464 HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +0200465 mask |= HPIPE_G2_SET_1_G2_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200466 data |= sata_static_values->g2_rx_selmupf <<
467 HPIPE_G2_SET_1_G2_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300468 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200469 data |= sata_static_values->g2_rx_selmufi <<
470 HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300471 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200472 data |= sata_static_values->g2_rx_selmuff <<
473 HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300474 mask |= HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_MASK;
475 data |= 0x1 << HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET;
476 reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
477
478 /* G3 settings */
479 mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200480 data = sata_static_values->g3_rx_selmupi <<
481 HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300482 mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200483 data |= sata_static_values->g3_rx_selmupf <<
484 HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300485 mask |= HPIPE_G3_SET_1_G3_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200486 data |= sata_static_values->g3_rx_selmufi <<
487 HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300488 mask |= HPIPE_G3_SET_1_G3_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200489 data |= sata_static_values->g3_rx_selmuff <<
490 HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300491 mask |= HPIPE_G3_SET_1_G3_RX_DFE_EN_MASK;
492 data |= 0x1 << HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET;
493 mask |= HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_MASK;
494 data |= 0x2 << HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET;
495 mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
496 data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
497 reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
498
499 /* DTL Control */
500 mask = HPIPE_PWR_CTR_DTL_SQ_DET_EN_MASK;
501 data = 0x1 << HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET;
502 mask |= HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_MASK;
503 data |= 0x1 << HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET;
504 mask |= HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
505 data |= 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
506 mask |= HPIPE_PWR_CTR_DTL_CLAMPING_SEL_MASK;
507 data |= 0x1 << HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET;
508 mask |= HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_MASK;
509 data |= 0x1 << HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET;
510 mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_MASK;
511 data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET;
512 mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_MASK;
513 data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET;
514 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
515
516 /* Trigger sampler enable pulse */
517 mask = HPIPE_SMAPLER_MASK;
518 data = 0x1 << HPIPE_SMAPLER_OFFSET;
519 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
520 mask = HPIPE_SMAPLER_MASK;
521 data = 0x0 << HPIPE_SMAPLER_OFFSET;
522 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
523
524 /* VDD Calibration Control 3 */
525 mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
526 data = 0x10 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
527 reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
528
529 /* DFE Resolution Control */
530 mask = HPIPE_DFE_RES_FORCE_MASK;
531 data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
532 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
533
534 /* DFE F3-F5 Coefficient Control */
535 mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
536 data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
537 mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
538 data = 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
539 reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
540
541 /* G3 Setting 3 */
542 mask = HPIPE_G3_FFE_CAP_SEL_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200543 data = sata_static_values->g3_ffe_cap_sel <<
544 HPIPE_G3_FFE_CAP_SEL_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300545 mask |= HPIPE_G3_FFE_RES_SEL_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200546 data |= sata_static_values->g3_ffe_res_sel <<
547 HPIPE_G3_FFE_RES_SEL_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300548 mask |= HPIPE_G3_FFE_SETTING_FORCE_MASK;
549 data |= 0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET;
550 mask |= HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
551 data |= 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
552 mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
553 data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
554 reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
555
556 /* G3 Setting 4 */
557 mask = HPIPE_G3_DFE_RES_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200558 data = sata_static_values->g3_dfe_res << HPIPE_G3_DFE_RES_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300559 reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
560
561 /* Offset Phase Control */
562 mask = HPIPE_OS_PH_OFFSET_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200563 data = sata_static_values->align90 << HPIPE_OS_PH_OFFSET_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300564 mask |= HPIPE_OS_PH_OFFSET_FORCE_MASK;
565 data |= 0x1 << HPIPE_OS_PH_OFFSET_FORCE_OFFSET;
566 mask |= HPIPE_OS_PH_VALID_MASK;
567 data |= 0x0 << HPIPE_OS_PH_VALID_OFFSET;
568 reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
569 mask = HPIPE_OS_PH_VALID_MASK;
570 data = 0x1 << HPIPE_OS_PH_VALID_OFFSET;
571 reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
572 mask = HPIPE_OS_PH_VALID_MASK;
573 data = 0x0 << HPIPE_OS_PH_VALID_OFFSET;
574 reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
575
576 /* Set G1 TX amplitude and TX post emphasis value */
577 mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200578 data = sata_static_values->g1_amp << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300579 mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200580 data |= sata_static_values->g1_tx_amp_adj <<
581 HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300582 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200583 data |= sata_static_values->g1_emph <<
584 HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300585 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200586 data |= sata_static_values->g1_emph_en <<
587 HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300588 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
589
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200590 /* Set G1 emph */
591 mask = HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
592 data = sata_static_values->g1_tx_emph_en <<
593 HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
594 mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
595 data |= sata_static_values->g1_tx_emph <<
596 HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
597 reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
598
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300599 /* Set G2 TX amplitude and TX post emphasis value */
600 mask = HPIPE_G2_SET_0_G2_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200601 data = sata_static_values->g2_amp << HPIPE_G2_SET_0_G2_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300602 mask |= HPIPE_G2_SET_0_G2_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200603 data |= sata_static_values->g2_tx_amp_adj <<
604 HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300605 mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200606 data |= sata_static_values->g2_emph <<
607 HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300608 mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200609 data |= sata_static_values->g2_emph_en <<
610 HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300611 reg_set(hpipe_addr + HPIPE_G2_SET_0_REG, data, mask);
612
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200613 /* Set G2 emph */
614 mask = HPIPE_G2_SET_2_G2_TX_EMPH0_EN_MASK;
615 data = sata_static_values->g2_tx_emph_en <<
616 HPIPE_G2_SET_2_G2_TX_EMPH0_EN_OFFSET;
617 mask |= HPIPE_G2_SET_2_G2_TX_EMPH0_MASK;
618 data |= sata_static_values->g2_tx_emph <<
619 HPIPE_G2_SET_2_G2_TX_EMPH0_OFFSET;
620 reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
621
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300622 /* Set G3 TX amplitude and TX post emphasis value */
623 mask = HPIPE_G3_SET_0_G3_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200624 data = sata_static_values->g3_amp << HPIPE_G3_SET_0_G3_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300625 mask |= HPIPE_G3_SET_0_G3_TX_AMP_ADJ_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200626 data |= sata_static_values->g3_tx_amp_adj <<
627 HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300628 mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200629 data |= sata_static_values->g3_emph <<
630 HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300631 mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200632 data |= sata_static_values->g3_emph_en <<
633 HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300634 mask |= HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_MASK;
635 data |= 0x4 << HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET;
636 mask |= HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_MASK;
637 data |= 0x0 << HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET;
638 reg_set(hpipe_addr + HPIPE_G3_SET_0_REG, data, mask);
639
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200640 /* Set G3 emph */
641 mask = HPIPE_G3_SET_2_G3_TX_EMPH0_EN_MASK;
642 data = sata_static_values->g3_tx_emph_en <<
643 HPIPE_G3_SET_2_G3_TX_EMPH0_EN_OFFSET;
644 mask |= HPIPE_G3_SET_2_G3_TX_EMPH0_MASK;
645 data |= sata_static_values->g3_tx_emph <<
646 HPIPE_G3_SET_2_G3_TX_EMPH0_OFFSET;
647 reg_set(hpipe_addr + HPIPE_G3_SET_2_REG, data, mask);
648
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300649 /* SERDES External Configuration 2 register */
650 mask = SD_EXTERNAL_CONFIG2_SSC_ENABLE_MASK;
651 data = 0x1 << SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET;
652 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
653
654 /* DFE reset sequence */
655 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
656 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
657 HPIPE_PWR_CTR_RST_DFE_MASK);
658 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
659 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
660 HPIPE_PWR_CTR_RST_DFE_MASK);
Grzegorz Jaszczykff9311b2020-01-21 17:02:10 +0100661
662 if (phy_polarity_invert != 0)
663 mvebu_cp110_polarity_invert(hpipe_addr + HPIPE_SYNC_PATTERN_REG,
664 phy_polarity_invert);
665
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300666 /* SW reset for interrupt logic */
667 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
668 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
669 HPIPE_PWR_CTR_SFT_RST_MASK);
670 reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
671 0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
672 HPIPE_PWR_CTR_SFT_RST_MASK);
673
674 debug_exit();
675
676 return ret;
677}
678
679static int mvebu_cp110_comphy_sgmii_power_on(uint64_t comphy_base,
680 uint8_t comphy_index, uint32_t comphy_mode)
681{
682 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
683 uint32_t mask, data, sgmii_speed = COMPHY_GET_SPEED(comphy_mode);
684 int ret = 0;
685
686 debug_enter();
687
688 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
689 comphy_index);
690 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
691 comphy_index);
692 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
693
694 /* configure phy selector for SGMII */
695 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
696 comphy_mode);
697
698 /* Confiugre the lane */
699 debug("stage: RFU configurations - hard reset comphy\n");
700 /* RFU configurations - hard reset comphy */
701 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
702 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
703 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
704 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
705 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
706
707 /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
708 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
709 data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
710 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
711 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
712
713 if (sgmii_speed == COMPHY_SPEED_1_25G) {
714 /* SGMII 1G, SerDes speed 1.25G */
715 data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
716 data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
717 } else if (sgmii_speed == COMPHY_SPEED_3_125G) {
Pali Rohár51974d22021-08-27 11:16:43 +0200718 /* 2500Base-X, SerDes speed 3.125G */
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300719 data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
720 data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
721 } else {
722 /* Other rates are not supported */
723 ERROR("unsupported SGMII speed on comphy%d\n", comphy_index);
724 return -EINVAL;
725 }
726
727 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
728 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
729 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
730 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
731 mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
732 data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
733 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
734
735 /* Set hard reset */
736 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
737 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
738 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
739 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
740 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
741 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
742 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
743
744 /* Release hard reset */
745 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
746 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
747 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
748 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
749 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
750
751 /* Wait 1ms - until band gap and ref clock ready */
752 mdelay(1);
753
754 /* Make sure that 40 data bits is disabled
755 * This bit is not cleared by reset
756 */
757 mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
758 data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
759 reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
760
761 /* Start comphy Configuration */
762 debug("stage: Comphy configuration\n");
763 /* set reference clock */
764 mask = HPIPE_MISC_REFCLK_SEL_MASK;
765 data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
766 reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
767 /* Power and PLL Control */
768 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
769 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
770 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
771 data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
772 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
773 /* Loopback register */
774 mask = HPIPE_LOOPBACK_SEL_MASK;
775 data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
776 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
777 /* rx control 1 */
778 mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
779 data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
780 mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
781 data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
782 reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
783 /* DTL Control */
784 mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
785 data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
786 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
787
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200788 /* Set analog parameters from ETP(HW) - for now use the default data */
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300789 debug("stage: Analog parameters from ETP(HW)\n");
790
791 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
792 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
793 HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
794
795 debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
796 /* SERDES External Configuration */
797 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
798 data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
799 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
800 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
801 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
802 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
803 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
804
805 ret = mvebu_cp110_comphy_is_pll_locked(comphy_base, comphy_index);
806 if (ret)
807 return ret;
808
809 /* RX init */
810 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
811 data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
812 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
813
814 /* check that RX init done */
815 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
816 data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
817 mask = data;
818 data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
819 if (data != 0) {
820 ERROR("RX init failed\n");
821 ret = -ETIMEDOUT;
822 }
823
824 debug("stage: RF Reset\n");
825 /* RF Reset */
826 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
827 data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
828 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
829 data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
830 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
831
832 debug_exit();
833
834 return ret;
835}
836
837static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base,
838 uint8_t comphy_index,
Alex Evraevb0a74302020-06-24 22:24:56 +0300839 uint32_t comphy_mode,
840 uint64_t comphy_train_base)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300841{
842 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
843 uint32_t mask, data, speed = COMPHY_GET_SPEED(comphy_mode);
844 int ret = 0;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200845 uint8_t ap_nr, cp_nr;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300846
847 debug_enter();
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +0200848 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
849
850 if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) {
851 debug("Skip %s for comphy[%d][%d][%d], due to rx training\n",
852 __func__, ap_nr, cp_nr, comphy_index);
853 return 0;
854 }
855
856 const struct xfi_params *xfi_static_values =
857 &xfi_static_values_tab[ap_nr][cp_nr][comphy_index];
858
859 debug("%s: the ap_nr = %d, cp_nr = %d, comphy_index %d\n",
860 __func__, ap_nr, cp_nr, comphy_index);
861
862 debug("g1_ffe_cap_sel= 0x%x, g1_ffe_res_sel= 0x%x, g1_dfe_res= 0x%x\n",
863 xfi_static_values->g1_ffe_cap_sel,
864 xfi_static_values->g1_ffe_res_sel,
865 xfi_static_values->g1_dfe_res);
866
867 if (!xfi_static_values->valid) {
868 ERROR("[ap%d][cp[%d][comphy:%d]: Has no valid static params\n",
869 ap_nr, cp_nr, comphy_index);
870 ERROR("[ap%d][cp[%d][comphy:%d]: porting layer needs update\n",
871 ap_nr, cp_nr, comphy_index);
872 return -EINVAL;
873 }
874
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300875 if ((speed != COMPHY_SPEED_5_15625G) &&
876 (speed != COMPHY_SPEED_10_3125G) &&
877 (speed != COMPHY_SPEED_DEFAULT)) {
878 ERROR("comphy:%d: unsupported sfi/xfi speed\n", comphy_index);
879 return -EINVAL;
880 }
881
882 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
883 comphy_index);
884 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
885 comphy_index);
886 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
887
888 /* configure phy selector for XFI/SFI */
889 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
890 comphy_mode);
891
892 debug("stage: RFU configurations - hard reset comphy\n");
893 /* RFU configurations - hard reset comphy */
894 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
895 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
896 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
897 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
898 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
899
900 /* Make sure that 40 data bits is disabled
901 * This bit is not cleared by reset
902 */
903 mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
904 data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
905 reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
906
907 /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
908 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
909 data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
910 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
911 data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
912 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
913 data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
914 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
915 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
916 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
917 data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
918 mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
919 data |= 0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
920 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
921
922 /* release from hard reset */
923 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
924 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
925 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
926 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
927 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
928 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
929 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
930
931 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
932 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
933 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
934 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
Marcin Wojtas779fd462019-09-09 03:38:18 +0200935 mask |= SD_EXTERNAL_CONFIG1_TX_IDLE_MASK;
936 data |= 0x1 << SD_EXTERNAL_CONFIG1_TX_IDLE_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300937 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
938
939 /* Wait 1ms - until band gap and ref clock ready */
940 mdelay(1);
941
Marcin Wojtas779fd462019-09-09 03:38:18 +0200942 /*
943 * Erratum IPCE_COMPHY-1353: toggle TX_IDLE bit in
944 * addition to the PHY reset
945 */
946 mask = SD_EXTERNAL_CONFIG1_TX_IDLE_MASK;
947 data = 0x0U;
948 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
949
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +0300950 /* Start comphy Configuration */
951 debug("stage: Comphy configuration\n");
952 /* set reference clock */
953 mask = HPIPE_MISC_ICP_FORCE_MASK;
954 data = (speed == COMPHY_SPEED_5_15625G) ?
955 (0x0 << HPIPE_MISC_ICP_FORCE_OFFSET) :
956 (0x1 << HPIPE_MISC_ICP_FORCE_OFFSET);
957 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
958 data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
959 reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
960 /* Power and PLL Control */
961 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
962 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
963 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
964 data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
965 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
966 /* Loopback register */
967 mask = HPIPE_LOOPBACK_SEL_MASK;
968 data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
969 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
970 /* rx control 1 */
971 mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
972 data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
973 mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
974 data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
975 reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
976 /* DTL Control */
977 mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
978 data = 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
979 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
980
981 /* Transmitter/Receiver Speed Divider Force */
982 if (speed == COMPHY_SPEED_5_15625G) {
983 mask = HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_MASK;
984 data = 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET;
985 mask |= HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_MASK;
986 data |= 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET;
987 mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_MASK;
988 data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET;
989 mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_MASK;
990 data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET;
991 } else {
992 mask = HPIPE_TXDIGCK_DIV_FORCE_MASK;
993 data = 0x1 << HPIPE_TXDIGCK_DIV_FORCE_OFFSET;
994 }
995 reg_set(hpipe_addr + HPIPE_SPD_DIV_FORCE_REG, data, mask);
996
997 /* Set analog parameters from ETP(HW) */
998 debug("stage: Analog parameters from ETP(HW)\n");
999 /* SERDES External Configuration 2 */
1000 mask = SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK;
1001 data = 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET;
1002 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
1003 /* 0x7-DFE Resolution control */
1004 mask = HPIPE_DFE_RES_FORCE_MASK;
1005 data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
1006 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
1007 /* 0xd-G1_Setting_0 */
1008 if (speed == COMPHY_SPEED_5_15625G) {
1009 mask = HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
1010 data = 0x6 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
1011 } else {
1012 mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001013 data = xfi_static_values->g1_amp <<
1014 HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001015 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001016 data |= xfi_static_values->g1_emph <<
1017 HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
1018
1019 mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
1020 data |= xfi_static_values->g1_emph_en <<
1021 HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
1022 mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
1023 data |= xfi_static_values->g1_tx_amp_adj <<
1024 HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001025 }
1026 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
1027 /* Genration 1 setting 2 (G1_Setting_2) */
1028 mask = HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001029 data = xfi_static_values->g1_tx_emph <<
1030 HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001031 mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001032 data |= xfi_static_values->g1_tx_emph_en <<
1033 HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001034 reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
1035 /* Transmitter Slew Rate Control register (tx_reg1) */
1036 mask = HPIPE_TX_REG1_TX_EMPH_RES_MASK;
1037 data = 0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET;
1038 mask |= HPIPE_TX_REG1_SLC_EN_MASK;
1039 data |= 0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET;
1040 reg_set(hpipe_addr + HPIPE_TX_REG1_REG, data, mask);
1041 /* Impedance Calibration Control register (cal_reg1) */
1042 mask = HPIPE_CAL_REG_1_EXT_TXIMP_MASK;
1043 data = 0xe << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
1044 mask |= HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK;
1045 data |= 0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET;
1046 reg_set(hpipe_addr + HPIPE_CAL_REG1_REG, data, mask);
1047 /* Generation 1 Setting 5 (g1_setting_5) */
1048 mask = HPIPE_G1_SETTING_5_G1_ICP_MASK;
1049 data = 0 << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
1050 reg_set(hpipe_addr + HPIPE_G1_SETTING_5_REG, data, mask);
1051
1052 /* 0xE-G1_Setting_1 */
1053 mask = HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
1054 data = 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
1055 if (speed == COMPHY_SPEED_5_15625G) {
1056 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
1057 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001058 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
1059 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001060 } else {
1061 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001062 data |= xfi_static_values->g1_rx_selmupi <<
1063 HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001064 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001065 data |= xfi_static_values->g1_rx_selmupf <<
1066 HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001067 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001068 data |= xfi_static_values->g1_rx_selmufi <<
1069 HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001070 mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001071 data |= xfi_static_values->g1_rx_selmuff <<
1072 HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001073 mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
1074 data |= 0x3 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
1075 }
1076 reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
1077
1078 /* 0xA-DFE_Reg3 */
1079 mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
1080 data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
1081 mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
1082 data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
1083 reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
1084
1085 /* 0x111-G1_Setting_4 */
1086 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1087 data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1088 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
1089 /* Genration 1 setting 3 (G1_Setting_3) */
1090 mask = HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK;
1091 data = 0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET;
1092 if (speed == COMPHY_SPEED_5_15625G) {
1093 /* Force FFE (Feed Forward Equalization) to 5G */
1094 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
1095 data |= 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
1096 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
1097 data |= 0x4 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
1098 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
1099 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02001100 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
1101 } else {
1102 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
1103 data |= xfi_static_values->g1_ffe_cap_sel <<
1104 HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
1105 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
1106 data |= xfi_static_values->g1_ffe_res_sel <<
1107 HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
1108 mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
1109 data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
1110 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
1111
1112 /* Use the value from CAL_OS_PH_EXT */
1113 mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
1114 data = 1 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
1115 reg_set(hpipe_addr +
1116 HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
1117 data, mask);
1118
1119 /* Update align90 */
1120 mask = HPIPE_CAL_OS_PH_EXT_MASK;
1121 data = xfi_static_values->align90 << HPIPE_CAL_OS_PH_EXT_OFFSET;
1122 reg_set(hpipe_addr +
1123 HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
1124 data, mask);
1125
1126 /* Force DFE resolution (use gen table value) */
1127 mask = HPIPE_DFE_RES_FORCE_MASK;
1128 data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
1129 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
1130
1131 /* 0x111-G1 DFE_Setting_4 */
1132 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1133 data = xfi_static_values->g1_dfe_res <<
1134 HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1135 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001136 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001137
1138 /* Connfigure RX training timer */
1139 mask = HPIPE_RX_TRAIN_TIMER_MASK;
1140 data = 0x13 << HPIPE_RX_TRAIN_TIMER_OFFSET;
1141 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
1142
1143 /* Enable TX train peak to peak hold */
1144 mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
1145 data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
1146 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
1147
1148 /* Configure TX preset index */
1149 mask = HPIPE_TX_PRESET_INDEX_MASK;
1150 data = 0x2 << HPIPE_TX_PRESET_INDEX_OFFSET;
1151 reg_set(hpipe_addr + HPIPE_TX_PRESET_INDEX_REG, data, mask);
1152
1153 /* Disable pattern lock lost timeout */
1154 mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
1155 data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
1156 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
1157
1158 /* Configure TX training pattern and TX training 16bit auto */
1159 mask = HPIPE_TX_TRAIN_16BIT_AUTO_EN_MASK;
1160 data = 0x1 << HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET;
1161 mask |= HPIPE_TX_TRAIN_PAT_SEL_MASK;
1162 data |= 0x1 << HPIPE_TX_TRAIN_PAT_SEL_OFFSET;
1163 reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
1164
1165 /* Configure Training patten number */
1166 mask = HPIPE_TRAIN_PAT_NUM_MASK;
1167 data = 0x88 << HPIPE_TRAIN_PAT_NUM_OFFSET;
1168 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_0_REG, data, mask);
1169
1170 /* Configure differencial manchester encoter to ethernet mode */
1171 mask = HPIPE_DME_ETHERNET_MODE_MASK;
1172 data = 0x1 << HPIPE_DME_ETHERNET_MODE_OFFSET;
1173 reg_set(hpipe_addr + HPIPE_DME_REG, data, mask);
1174
1175 /* Configure VDD Continuous Calibration */
1176 mask = HPIPE_CAL_VDD_CONT_MODE_MASK;
1177 data = 0x1 << HPIPE_CAL_VDD_CONT_MODE_OFFSET;
1178 reg_set(hpipe_addr + HPIPE_VDD_CAL_0_REG, data, mask);
1179
1180 /* Trigger sampler enable pulse (by toggleing the bit) */
1181 mask = HPIPE_RX_SAMPLER_OS_GAIN_MASK;
1182 data = 0x3 << HPIPE_RX_SAMPLER_OS_GAIN_OFFSET;
1183 mask |= HPIPE_SMAPLER_MASK;
1184 data |= 0x1 << HPIPE_SMAPLER_OFFSET;
1185 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1186 mask = HPIPE_SMAPLER_MASK;
1187 data = 0x0 << HPIPE_SMAPLER_OFFSET;
1188 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1189
1190 /* Set External RX Regulator Control */
1191 mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
1192 data = 0x1A << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
1193 reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
1194
1195 debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
1196 /* SERDES External Configuration */
1197 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1198 data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1199 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1200 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1201 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1202 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1203 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1204
1205 /* check PLL rx & tx ready */
1206 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1207 data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
1208 SD_EXTERNAL_STATUS0_PLL_TX_MASK;
1209 mask = data;
1210 data = polling_with_timeout(addr, data, mask,
1211 PLL_LOCK_TIMEOUT, REG_32BIT);
1212 if (data != 0) {
1213 if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
1214 ERROR("RX PLL is not locked\n");
1215 if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
1216 ERROR("TX PLL is not locked\n");
1217
1218 ret = -ETIMEDOUT;
1219 }
1220
1221 /* RX init */
1222 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1223 data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1224 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1225
1226 /* check that RX init done */
1227 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1228 data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
1229 mask = data;
1230 data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
1231 if (data != 0) {
1232 ERROR("RX init failed\n");
1233 ret = -ETIMEDOUT;
1234 }
1235
1236 debug("stage: RF Reset\n");
1237 /* RF Reset */
1238 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1239 data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1240 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1241 data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1242 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1243
Alex Evraevb0a74302020-06-24 22:24:56 +03001244 /* Force rx training on 10G port */
1245 data = mmio_read_32(COMPHY_TRX_RELATIVE_ADDR(comphy_index));
1246 data |= COMPHY_TRX_TRAIN_RX_TRAIN_ENABLE;
1247 mmio_write_32(COMPHY_TRX_RELATIVE_ADDR(comphy_index), data);
1248 mdelay(200);
1249 data &= ~COMPHY_TRX_TRAIN_RX_TRAIN_ENABLE;
1250 mmio_write_32(COMPHY_TRX_RELATIVE_ADDR(comphy_index), data);
1251
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001252 debug_exit();
1253
1254 return ret;
1255}
1256
1257static int mvebu_cp110_comphy_pcie_power_on(uint64_t comphy_base,
1258 uint8_t comphy_index, uint32_t comphy_mode)
1259{
1260 int ret = 0;
1261 uint32_t reg, mask, data, pcie_width;
1262 uint32_t clk_dir;
1263 uintptr_t hpipe_addr, comphy_addr, addr;
1264 _Bool clk_src = COMPHY_GET_CLK_SRC(comphy_mode);
Igal Libermanbd51efd2018-11-15 16:13:11 +02001265 _Bool called_from_uboot = COMPHY_GET_CALLER(comphy_mode);
1266
1267 /* In Armada 8K DB boards, PCIe initialization can be executed
1268 * only once (PCIe reset performed during chip power on and
1269 * it cannot be executed via GPIO later).
1270 * This means that power on can be executed only once, so let's
1271 * mark if the caller is bootloader or Linux.
1272 * If bootloader -> run power on.
1273 * If Linux -> exit.
1274 *
1275 * TODO: In MacciatoBIN, PCIe reset is connected via GPIO,
1276 * so after GPIO reset is added to Linux Kernel, it can be
1277 * powered-on by Linux.
1278 */
1279 if (!called_from_uboot)
1280 return ret;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001281
1282 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1283 comphy_index);
1284 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1285 pcie_width = COMPHY_GET_PCIE_WIDTH(comphy_mode);
1286
1287 debug_enter();
1288
1289 spin_lock(&cp110_mac_reset_lock);
1290
1291 reg = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
1292 SYS_CTRL_UINIT_SOFT_RESET_REG);
1293 switch (comphy_index) {
1294 case COMPHY_LANE0:
1295 reg |= PCIE_MAC_RESET_MASK_PORT0;
1296 break;
1297 case COMPHY_LANE4:
1298 reg |= PCIE_MAC_RESET_MASK_PORT1;
1299 break;
1300 case COMPHY_LANE5:
1301 reg |= PCIE_MAC_RESET_MASK_PORT2;
1302 break;
1303 }
1304
1305 mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
1306 SYS_CTRL_UINIT_SOFT_RESET_REG, reg);
1307 spin_unlock(&cp110_mac_reset_lock);
1308
1309 /* Configure PIPE selector for PCIE */
1310 mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
1311 comphy_mode);
1312
1313 /*
1314 * Read SAR (Sample-At-Reset) configuration for the PCIe clock
1315 * direction.
1316 *
1317 * SerDes Lane 4/5 got the PCIe ref-clock #1,
1318 * and SerDes Lane 0 got PCIe ref-clock #0
1319 */
1320 reg = mmio_read_32(DFX_FROM_COMPHY_ADDR(comphy_base) +
1321 SAR_STATUS_0_REG);
1322 if (comphy_index == COMPHY_LANE4 || comphy_index == COMPHY_LANE5)
Guo Yi4ad43132020-12-17 22:30:54 +00001323 clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP0_MASK) >>
1324 SAR_RST_PCIE1_CLOCK_CONFIG_CP0_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001325 else
Guo Yi4ad43132020-12-17 22:30:54 +00001326 clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP0_MASK) >>
1327 SAR_RST_PCIE0_CLOCK_CONFIG_CP0_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001328
1329 debug("On lane %d\n", comphy_index);
1330 debug("PCIe clock direction = %x\n", clk_dir);
1331 debug("PCIe Width = %d\n", pcie_width);
1332
1333 /* enable PCIe X4 and X2 */
1334 if (comphy_index == COMPHY_LANE0) {
1335 if (pcie_width == PCIE_LNK_X4) {
1336 data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET;
1337 mask = COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK;
1338 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1339 data, mask);
1340 } else if (pcie_width == PCIE_LNK_X2) {
1341 data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET;
1342 mask = COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK;
1343 reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
1344 }
1345 }
1346
1347 /* If PCIe clock is output and clock source from SerDes lane 5,
1348 * need to configure the clock-source MUX.
1349 * By default, the clock source is from lane 4
1350 */
1351 if (clk_dir && clk_src && (comphy_index == COMPHY_LANE5)) {
1352 data = DFX_DEV_GEN_PCIE_CLK_SRC_MUX <<
1353 DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET;
1354 mask = DFX_DEV_GEN_PCIE_CLK_SRC_MASK;
1355 reg_set(DFX_FROM_COMPHY_ADDR(comphy_base) +
1356 DFX_DEV_GEN_CTRL12_REG, data, mask);
1357 }
1358
1359 debug("stage: RFU configurations - hard reset comphy\n");
1360 /* RFU configurations - hard reset comphy */
1361 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1362 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1363 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1364 data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1365 mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1366 data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1367 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1368 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1369 mask |= COMMON_PHY_PHY_MODE_MASK;
1370 data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET;
1371 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1372
1373 /* release from hard reset */
1374 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1375 data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1376 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1377 data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1378 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1379
1380 /* Wait 1ms - until band gap and ref clock ready */
1381 mdelay(1);
1382 /* Start comphy Configuration */
1383 debug("stage: Comphy configuration\n");
1384 /* Set PIPE soft reset */
1385 mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
1386 data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
1387 /* Set PHY datapath width mode for V0 */
1388 mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
1389 data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
1390 /* Set Data bus width USB mode for V0 */
1391 mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
1392 data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
1393 /* Set CORE_CLK output frequency for 250Mhz */
1394 mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
1395 data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
1396 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
1397 /* Set PLL ready delay for 0x2 */
1398 data = 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET;
1399 mask = HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK;
1400 if (pcie_width != PCIE_LNK_X1) {
1401 data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET;
1402 mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK;
1403 data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET;
1404 mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK;
1405 }
1406 reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, data, mask);
1407
1408 /* Set PIPE mode interface to PCIe3 - 0x1 & set lane order */
1409 data = 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET;
1410 mask = HPIPE_CLK_SRC_HI_MODE_PIPE_MASK;
1411 if (pcie_width != PCIE_LNK_X1) {
1412 mask |= HPIPE_CLK_SRC_HI_LANE_STRT_MASK;
1413 mask |= HPIPE_CLK_SRC_HI_LANE_MASTER_MASK;
1414 mask |= HPIPE_CLK_SRC_HI_LANE_BREAK_MASK;
1415 if (comphy_index == 0) {
1416 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET;
1417 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET;
1418 } else if (comphy_index == (pcie_width - 1)) {
1419 data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET;
1420 }
1421 }
1422 reg_set(hpipe_addr + HPIPE_CLK_SRC_HI_REG, data, mask);
1423 /* Config update polarity equalization */
1424 data = 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET;
1425 mask = HPIPE_CFG_UPDATE_POLARITY_MASK;
1426 reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG1_REG, data, mask);
1427 /* Set PIPE version 4 to mode enable */
1428 data = 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET;
1429 mask = HPIPE_DFE_CTRL_28_PIPE4_MASK;
1430 reg_set(hpipe_addr + HPIPE_DFE_CTRL_28_REG, data, mask);
1431 /* TODO: check if pcie clock is output/input - for bringup use input*/
1432 /* Enable PIN clock 100M_125M */
1433 mask = 0;
1434 data = 0;
1435 /* Only if clock is output, configure the clock-source mux */
1436 if (clk_dir) {
1437 mask |= HPIPE_MISC_CLK100M_125M_MASK;
1438 data |= 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET;
1439 }
1440 /* Set PIN_TXDCLK_2X Clock Freq. Selection for outputs 500MHz clock */
1441 mask |= HPIPE_MISC_TXDCLK_2X_MASK;
1442 data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET;
1443 /* Enable 500MHz Clock */
1444 mask |= HPIPE_MISC_CLK500_EN_MASK;
1445 data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET;
1446 if (clk_dir) { /* output */
1447 /* Set reference clock comes from group 1 */
1448 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
1449 data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
1450 } else {
1451 /* Set reference clock comes from group 2 */
1452 mask |= HPIPE_MISC_REFCLK_SEL_MASK;
1453 data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET;
1454 }
1455 mask |= HPIPE_MISC_ICP_FORCE_MASK;
1456 data |= 0x1 << HPIPE_MISC_ICP_FORCE_OFFSET;
1457 reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
1458 if (clk_dir) { /* output */
1459 /* Set reference frequcency select - 0x2 for 25MHz*/
1460 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1461 data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1462 } else {
1463 /* Set reference frequcency select - 0x0 for 100MHz*/
1464 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1465 data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1466 }
1467 /* Set PHY mode to PCIe */
1468 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1469 data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1470 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1471
1472 /* ref clock alignment */
1473 if (pcie_width != PCIE_LNK_X1) {
1474 mask = HPIPE_LANE_ALIGN_OFF_MASK;
1475 data = 0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET;
1476 reg_set(hpipe_addr + HPIPE_LANE_ALIGN_REG, data, mask);
1477 }
1478
1479 /* Set the amount of time spent in the LoZ state - set for 0x7 only if
1480 * the PCIe clock is output
1481 */
1482 if (clk_dir)
1483 reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
1484 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
1485 HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
1486
1487 /* Set Maximal PHY Generation Setting(8Gbps) */
1488 mask = HPIPE_INTERFACE_GEN_MAX_MASK;
1489 data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET;
1490 /* Bypass frame detection and sync detection for RX DATA */
1491 mask |= HPIPE_INTERFACE_DET_BYPASS_MASK;
1492 data |= 0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET;
1493 /* Set Link Train Mode (Tx training control pins are used) */
1494 mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK;
1495 data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET;
1496 reg_set(hpipe_addr + HPIPE_INTERFACE_REG, data, mask);
1497
1498 /* Set Idle_sync enable */
1499 mask = HPIPE_PCIE_IDLE_SYNC_MASK;
1500 data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET;
1501 /* Select bits for PCIE Gen3(32bit) */
1502 mask |= HPIPE_PCIE_SEL_BITS_MASK;
1503 data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET;
1504 reg_set(hpipe_addr + HPIPE_PCIE_REG0, data, mask);
1505
1506 /* Enable Tx_adapt_g1 */
1507 mask = HPIPE_TX_TRAIN_CTRL_G1_MASK;
1508 data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET;
1509 /* Enable Tx_adapt_gn1 */
1510 mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK;
1511 data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET;
1512 /* Disable Tx_adapt_g0 */
1513 mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK;
1514 data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
1515 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
1516
1517 /* Set reg_tx_train_chk_init */
1518 mask = HPIPE_TX_TRAIN_CHK_INIT_MASK;
1519 data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET;
1520 /* Enable TX_COE_FM_PIN_PCIE3_EN */
1521 mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK;
1522 data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET;
1523 reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
1524
1525 debug("stage: TRx training parameters\n");
1526 /* Set Preset sweep configurations */
1527 mask = HPIPE_TX_TX_STATUS_CHECK_MODE_MASK;
1528 data = 0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET;
1529 mask |= HPIPE_TX_NUM_OF_PRESET_MASK;
1530 data |= 0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET;
1531 mask |= HPIPE_TX_SWEEP_PRESET_EN_MASK;
1532 data |= 0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET;
1533 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_11_REG, data, mask);
1534
1535 /* Tx train start configuration */
1536 mask = HPIPE_TX_TRAIN_START_SQ_EN_MASK;
1537 data = 0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET;
1538 mask |= HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK;
1539 data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET;
1540 mask |= HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK;
1541 data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET;
1542 mask |= HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK;
1543 data |= 0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET;
1544 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
1545
1546 /* Enable Tx train P2P */
1547 mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
1548 data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
1549 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
1550
1551 /* Configure Tx train timeout */
1552 mask = HPIPE_TRX_TRAIN_TIMER_MASK;
1553 data = 0x17 << HPIPE_TRX_TRAIN_TIMER_OFFSET;
1554 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_4_REG, data, mask);
1555
1556 /* Disable G0/G1/GN1 adaptation */
1557 mask = HPIPE_TX_TRAIN_CTRL_G1_MASK | HPIPE_TX_TRAIN_CTRL_GN1_MASK
1558 | HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
1559 data = 0;
1560 reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
1561
1562 /* Disable DTL frequency loop */
1563 mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
1564 data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
1565 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
1566
1567 /* Configure G3 DFE */
1568 mask = HPIPE_G3_DFE_RES_MASK;
1569 data = 0x3 << HPIPE_G3_DFE_RES_OFFSET;
1570 reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
1571
1572 /* Use TX/RX training result for DFE */
1573 mask = HPIPE_DFE_RES_FORCE_MASK;
1574 data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
1575 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
1576
1577 /* Configure initial and final coefficient value for receiver */
1578 mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
1579 data = 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
1580
1581 mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
1582 data |= 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
1583
1584 mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
1585 data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
1586 reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
1587
1588 /* Trigger sampler enable pulse */
1589 mask = HPIPE_SMAPLER_MASK;
1590 data = 0x1 << HPIPE_SMAPLER_OFFSET;
1591 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1592 udelay(5);
1593 reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, 0, mask);
1594
1595 /* FFE resistor tuning for different bandwidth */
1596 mask = HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
1597 data = 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
1598 mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
1599 data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
1600 reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
1601
1602 /* Pattern lock lost timeout disable */
1603 mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
1604 data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
1605 reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
1606
1607 /* Configure DFE adaptations */
1608 mask = HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK;
1609 data = 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET;
1610 mask |= HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK;
1611 data |= 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET;
1612 mask |= HPIPE_CDR_MAX_DFE_ADAPT_0_MASK;
1613 data |= 0x0 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET;
1614 mask |= HPIPE_CDR_MAX_DFE_ADAPT_1_MASK;
1615 data |= 0x1 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET;
1616 reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
1617
1618 mask = HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK;
1619 data = 0x0 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET;
1620 reg_set(hpipe_addr + HPIPE_DFE_CONTROL_REG, data, mask);
1621
1622 /* Genration 2 setting 1*/
1623 mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
1624 data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001625 mask |= HPIPE_G2_SET_1_G2_RX_SELMUPF_MASK;
1626 data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001627 mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
1628 data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
1629 reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
1630
1631 /* DFE enable */
1632 mask = HPIPE_G2_DFE_RES_MASK;
1633 data = 0x3 << HPIPE_G2_DFE_RES_OFFSET;
1634 reg_set(hpipe_addr + HPIPE_G2_SETTINGS_4_REG, data, mask);
1635
1636 /* Configure DFE Resolution */
1637 mask = HPIPE_LANE_CFG4_DFE_EN_SEL_MASK;
1638 data = 0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET;
1639 reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
1640
1641 /* VDD calibration control */
1642 mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
1643 data = 0x16 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
1644 reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
1645
1646 /* Set PLL Charge-pump Current Control */
1647 mask = HPIPE_G3_SETTING_5_G3_ICP_MASK;
1648 data = 0x4 << HPIPE_G3_SETTING_5_G3_ICP_OFFSET;
1649 reg_set(hpipe_addr + HPIPE_G3_SETTING_5_REG, data, mask);
1650
1651 /* Set lane rqualization remote setting */
1652 mask = HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK;
1653 data = 0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET;
1654 mask |= HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK;
1655 data |= 0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET;
1656 mask |= HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK;
1657 data |= 0x6 << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET;
1658 reg_set(hpipe_addr + HPIPE_LANE_EQ_REMOTE_SETTING_REG, data, mask);
1659
1660 mask = HPIPE_CFG_EQ_BUNDLE_DIS_MASK;
1661 data = 0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET;
1662 reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG2_REG, data, mask);
1663
1664 debug("stage: Comphy power up\n");
1665
1666 /* For PCIe X4 or X2:
1667 * release from reset only after finish to configure all lanes
1668 */
1669 if ((pcie_width == PCIE_LNK_X1) || (comphy_index == (pcie_width - 1))) {
1670 uint32_t i, start_lane, end_lane;
1671
1672 if (pcie_width != PCIE_LNK_X1) {
1673 /* allows writing to all lanes in one write */
1674 data = 0x0;
1675 if (pcie_width == PCIE_LNK_X2)
1676 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
1677 else if (pcie_width == PCIE_LNK_X4)
1678 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
1679 reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
1680 start_lane = 0;
1681 end_lane = pcie_width;
1682
1683 /* Release from PIPE soft reset
1684 * For PCIe by4 or by2:
1685 * release from soft reset all lanes - can't use
1686 * read modify write
1687 */
1688 reg_set(HPIPE_ADDR(
1689 COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), 0) +
1690 HPIPE_RST_CLK_CTRL_REG, 0x24, 0xffffffff);
1691 } else {
1692 start_lane = comphy_index;
1693 end_lane = comphy_index + 1;
1694
1695 /* Release from PIPE soft reset
1696 * for PCIe by4 or by2:
1697 * release from soft reset all lanes
1698 */
1699 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
1700 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
1701 HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
1702 }
1703
1704 if (pcie_width != PCIE_LNK_X1) {
1705 /* disable writing to all lanes with one write */
1706 if (pcie_width == PCIE_LNK_X2) {
1707 data = (COMPHY_LANE0 <<
1708 COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
1709 (COMPHY_LANE1 <<
1710 COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET);
1711 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
1712 } else if (pcie_width == PCIE_LNK_X4) {
1713 data = (COMPHY_LANE0 <<
1714 COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
1715 (COMPHY_LANE1 <<
1716 COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET) |
1717 (COMPHY_LANE2 <<
1718 COMMON_PHY_SD_CTRL1_COMPHY_2_PORT_OFFSET) |
1719 (COMPHY_LANE3 <<
1720 COMMON_PHY_SD_CTRL1_COMPHY_3_PORT_OFFSET);
1721 mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
1722 }
1723 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1724 data, mask);
1725 }
1726
1727 debug("stage: Check PLL\n");
1728 /* Read lane status */
1729 for (i = start_lane; i < end_lane; i++) {
1730 addr = HPIPE_ADDR(
1731 COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), i) +
1732 HPIPE_LANE_STATUS1_REG;
1733 data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
1734 mask = data;
Pali Rohár2f4d69d2021-09-24 14:43:54 +02001735 data = polling_with_timeout(addr, data, mask,
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001736 PLL_LOCK_TIMEOUT,
1737 REG_32BIT);
Pali Rohár2f4d69d2021-09-24 14:43:54 +02001738 if (data) {
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001739 ERROR("Failed to lock PCIE PLL\n");
Pali Rohár2f4d69d2021-09-24 14:43:54 +02001740 ret = -ETIMEDOUT;
1741 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001742 }
1743 }
1744
1745 debug_exit();
1746
1747 return ret;
1748}
1749
1750static int mvebu_cp110_comphy_rxaui_power_on(uint64_t comphy_base,
1751 uint8_t comphy_index, uint32_t comphy_mode)
1752{
1753 uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
1754 uint32_t mask, data;
1755 int ret = 0;
1756
1757 debug_enter();
1758
1759 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1760 comphy_index);
1761 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1762 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1763 comphy_index);
1764
1765 /* configure phy selector for RXAUI */
1766 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
1767 comphy_mode);
1768
1769 /* RFU configurations - hard reset comphy */
1770 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1771 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1772 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1773 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1774 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1775
1776 if (comphy_index == 2) {
1777 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1778 0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET,
1779 COMMON_PHY_SD_CTRL1_RXAUI0_MASK);
1780 }
1781 if (comphy_index == 4) {
1782 reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1783 0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET,
1784 COMMON_PHY_SD_CTRL1_RXAUI1_MASK);
1785 }
1786
1787 /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
1788 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1789 data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1790 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
1791 data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
1792 mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
1793 data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
1794 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1795 data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1796 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1797 data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1798 mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
1799 data |= 0x0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
1800 mask |= SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK;
1801 data |= 0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET;
1802 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1803
1804 /* release from hard reset */
1805 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
1806 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
1807 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
1808 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
1809 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1810 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1811 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1812
1813 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
1814 data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
1815 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
1816 data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
1817 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1818
1819 /* Wait 1ms - until band gap and ref clock ready */
1820 mdelay(1);
1821
1822 /* Start comphy Configuration */
1823 debug("stage: Comphy configuration\n");
1824 /* set reference clock */
1825 reg_set(hpipe_addr + HPIPE_MISC_REG,
1826 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
1827 HPIPE_MISC_REFCLK_SEL_MASK);
1828 /* Power and PLL Control */
1829 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1830 data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1831 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1832 data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1833 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1834 /* Loopback register */
1835 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
1836 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
1837 /* rx control 1 */
1838 mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
1839 data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
1840 mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
1841 data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
1842 reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
1843 /* DTL Control */
1844 reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG,
1845 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET,
1846 HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK);
1847
1848 /* Set analog parameters from ETP(HW) */
1849 debug("stage: Analog parameters from ETP(HW)\n");
1850 /* SERDES External Configuration 2 */
1851 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG,
1852 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET,
1853 SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK);
1854 /* 0x7-DFE Resolution control */
1855 reg_set(hpipe_addr + HPIPE_DFE_REG0, 0x1 << HPIPE_DFE_RES_FORCE_OFFSET,
1856 HPIPE_DFE_RES_FORCE_MASK);
1857 /* 0xd-G1_Setting_0 */
1858 reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
1859 0xd << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
1860 HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
1861 /* 0xE-G1_Setting_1 */
1862 mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
1863 data = 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
Grzegorz Jaszczyka91ea622018-07-16 12:18:03 +02001864 mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
1865 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001866 mask |= HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
1867 data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
1868 reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
1869 /* 0xA-DFE_Reg3 */
1870 mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
1871 data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
1872 mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
1873 data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
1874 reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
1875
1876 /* 0x111-G1_Setting_4 */
1877 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1878 data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1879 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
1880
1881 debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
1882 /* SERDES External Configuration */
1883 mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1884 data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1885 mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1886 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1887 mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1888 data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1889 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1890
1891
1892 /* check PLL rx & tx ready */
1893 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1894 data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
1895 SD_EXTERNAL_STATUS0_PLL_TX_MASK;
1896 mask = data;
1897 data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
1898 if (data != 0) {
1899 debug("Read from reg = %lx - value = 0x%x\n",
1900 sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
1901 ERROR("SD_EXTERNAL_STATUS0_PLL_RX is %d, -\"-_PLL_TX is %d\n",
1902 (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK),
1903 (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK));
1904 ret = -ETIMEDOUT;
1905 }
1906
1907 /* RX init */
1908 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG,
1909 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET,
1910 SD_EXTERNAL_CONFIG1_RX_INIT_MASK);
1911
1912 /* check that RX init done */
1913 addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1914 data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
1915 mask = data;
1916 data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
1917 if (data != 0) {
1918 debug("Read from reg = %lx - value = 0x%x\n",
1919 sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
1920 ERROR("SD_EXTERNAL_STATUS0_RX_INIT is 0\n");
1921 ret = -ETIMEDOUT;
1922 }
1923
1924 debug("stage: RF Reset\n");
1925 /* RF Reset */
1926 mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1927 data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1928 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1929 data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1930 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1931
1932 debug_exit();
1933
1934 return ret;
1935}
1936
1937static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base,
1938 uint8_t comphy_index, uint32_t comphy_mode)
1939{
1940 uintptr_t hpipe_addr, comphy_addr, addr;
1941 uint32_t mask, data;
Grzegorz Jaszczyk78f8bec2020-01-21 17:02:29 +01001942 uint8_t ap_nr, cp_nr, phy_polarity_invert;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001943 int ret = 0;
1944
1945 debug_enter();
1946
1947 /* Configure PIPE selector for USB3 */
1948 mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
1949 comphy_mode);
1950
Grzegorz Jaszczyk78f8bec2020-01-21 17:02:29 +01001951 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
1952
1953 const struct usb_params *usb_static_values =
1954 &usb_static_values_tab[ap_nr][cp_nr][comphy_index];
1955
1956 phy_polarity_invert = usb_static_values->polarity_invert;
1957
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03001958 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1959 comphy_index);
1960 comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1961
1962 debug("stage: RFU configurations - hard reset comphy\n");
1963 /* RFU configurations - hard reset comphy */
1964 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1965 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1966 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1967 data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1968 mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1969 data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1970 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1971 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1972 mask |= COMMON_PHY_PHY_MODE_MASK;
1973 data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET;
1974 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1975
1976 /* release from hard reset */
1977 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1978 data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1979 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1980 data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1981 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1982
1983 /* Wait 1ms - until band gap and ref clock ready */
1984 mdelay(1);
1985
1986 /* Start comphy Configuration */
1987 debug("stage: Comphy configuration\n");
1988 /* Set PIPE soft reset */
1989 mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
1990 data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
1991 /* Set PHY datapath width mode for V0 */
1992 mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
1993 data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
1994 /* Set Data bus width USB mode for V0 */
1995 mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
1996 data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
1997 /* Set CORE_CLK output frequency for 250Mhz */
1998 mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
1999 data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
2000 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
2001 /* Set PLL ready delay for 0x2 */
2002 reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG,
2003 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
2004 HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
2005 /* Set reference clock to come from group 1 - 25Mhz */
2006 reg_set(hpipe_addr + HPIPE_MISC_REG,
2007 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
2008 HPIPE_MISC_REFCLK_SEL_MASK);
2009 /* Set reference frequcency select - 0x2 */
2010 mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
2011 data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
2012 /* Set PHY mode to USB - 0x5 */
2013 mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
2014 data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
2015 reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
2016 /* Set the amount of time spent in the LoZ state - set for 0x7 */
2017 reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
2018 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
2019 HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
2020 /* Set max PHY generation setting - 5Gbps */
2021 reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
2022 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
2023 HPIPE_INTERFACE_GEN_MAX_MASK);
2024 /* Set select data width 20Bit (SEL_BITS[2:0]) */
2025 reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
2026 0x1 << HPIPE_LOOPBACK_SEL_OFFSET,
2027 HPIPE_LOOPBACK_SEL_MASK);
2028 /* select de-emphasize 3.5db */
2029 reg_set(hpipe_addr + HPIPE_LANE_CONFIG0_REG,
2030 0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET,
2031 HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK);
2032 /* override tx margining from the MAC */
2033 reg_set(hpipe_addr + HPIPE_TST_MODE_CTRL_REG,
2034 0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET,
2035 HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK);
2036
Grzegorz Jaszczyk78f8bec2020-01-21 17:02:29 +01002037 /* The polarity inversion for USB was not tested due to lack of hw
2038 * design which requires it. Support is added for customer needs.
2039 */
2040 if (phy_polarity_invert)
2041 mvebu_cp110_polarity_invert(hpipe_addr + HPIPE_SYNC_PATTERN_REG,
2042 phy_polarity_invert);
2043
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002044 /* Start analog parameters from ETP(HW) */
2045 debug("stage: Analog parameters from ETP(HW)\n");
2046 /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */
2047 mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK;
2048 data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET;
2049 /* Set Override PHY DFE control pins for 0x1 */
2050 mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK;
2051 data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET;
2052 /* Set Spread Spectrum Clock Enable fot 0x1 */
2053 mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK;
2054 data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET;
2055 reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
2056 /* Confifure SSC amplitude */
2057 mask = HPIPE_G2_TX_SSC_AMP_MASK;
2058 data = 0x1f << HPIPE_G2_TX_SSC_AMP_OFFSET;
2059 reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
2060 /* End of analog parameters */
2061
2062 debug("stage: Comphy power up\n");
2063 /* Release from PIPE soft reset */
2064 reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
2065 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
2066 HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
2067
2068 /* wait 15ms - for comphy calibration done */
2069 debug("stage: Check PLL\n");
2070 /* Read lane status */
2071 addr = hpipe_addr + HPIPE_LANE_STATUS1_REG;
2072 data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
2073 mask = data;
2074 data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
2075 if (data != 0) {
2076 debug("Read from reg = %lx - value = 0x%x\n",
2077 hpipe_addr + HPIPE_LANE_STATUS1_REG, data);
2078 ERROR("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n");
2079 ret = -ETIMEDOUT;
2080 }
2081
2082 debug_exit();
2083
2084 return ret;
2085}
2086
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002087static void rx_pre_train(uint64_t comphy_base, uint8_t comphy_index)
2088{
2089 uintptr_t hpipe_addr;
2090 uint32_t mask, data;
2091
2092 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2093 comphy_index);
2094
2095 debug("rx_training preparation\n\n");
2096
2097 mask = HPIPE_TRX0_GAIN_TRAIN_WITH_C_MASK;
2098 data = (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF);
2099 mask |= HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_MASK;
2100 data |= (0x0 << HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF);
2101 reg_set(hpipe_addr + HPIPE_TRX0_REG, data, mask);
2102
2103
2104 mask = HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK;
2105 data = (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF);
2106 mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_MASK;
2107 data |= (0x0 << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF);
2108 reg_set(hpipe_addr + HPIPE_TRX_REG2, data, mask);
2109
2110 mask = HPIPE_TRX_REG1_MIN_BOOST_MODE_MASK;
2111 data = (0x1 << HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF);
2112 reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask);
2113
2114 mask = HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_MASK;
2115 data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF);
2116 reg_set(hpipe_addr + HPIPE_CDR_CONTROL1_REG, data, mask);
2117
2118 mask = HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_MASK;
2119 data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF);
2120 reg_set(hpipe_addr + HPIPE_CDR_CONTROL2_REG, data, mask);
2121
2122 mask = HPIPE_CRD_MIDPOINT_PHASE_OS_MASK;
2123 data = (0x0 << HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET);
2124 reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
2125
2126 mask = HPIPE_TRX_REG1_SUMFTAP_EN_MASK;
2127 data = (0x38 << HPIPE_TRX_REG1_SUMFTAP_EN_OFF);
2128 mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK;
2129 data |= (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF);
2130 reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask);
2131}
2132
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002133int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base,
2134 uint8_t comphy_index)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002135{
2136 uint32_t mask, data, timeout;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002137 uint32_t g1_ffe_cap_sel, g1_ffe_res_sel, align90, g1_dfe_res;
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002138 uintptr_t hpipe_addr;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002139
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002140 uint8_t ap_nr, cp_nr;
2141
2142 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
2143
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002144 hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2145 comphy_index);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002146
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002147 debug_enter();
2148
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002149 rx_pre_train(comphy_base, comphy_index);
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002150
2151 debug("Preparation for rx_training\n\n");
2152
2153 /* Use the FFE table */
2154 mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
2155 data = 0 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
2156 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
2157
2158 /* Use auto-calibration value */
2159 mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
2160 data = 0 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
2161 reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
2162 data, mask);
2163
2164 /* Use Tx/Rx training results */
2165 mask = HPIPE_DFE_RES_FORCE_MASK;
2166 data = 0 << HPIPE_DFE_RES_FORCE_OFFSET;
2167 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
2168
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002169 debug("Enable RX training\n\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002170
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002171 mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
2172 data = 0x1 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002173 reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002174
2175 /* Check the result of RX training */
2176 timeout = RX_TRAINING_TIMEOUT;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002177 mask = HPIPE_INTERRUPT_TRX_TRAIN_DONE_OFFSET |
2178 HPIPE_INTERRUPT_DFE_DONE_INT_OFFSET |
2179 HPIPE_INTERRUPT_RX_TRAIN_COMPLETE_INT_MASK;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002180 while (timeout) {
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002181 data = mmio_read_32(hpipe_addr + HPIPE_INTERRUPT_1_REGISTER);
2182 if (data & mask)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002183 break;
2184 mdelay(1);
2185 timeout--;
2186 }
2187
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002188 debug("RX training result: interrupt reg 0x%lx = 0x%x\n\n",
2189 hpipe_addr + HPIPE_INTERRUPT_1_REGISTER, data);
2190
2191 if (timeout == 0 || data & HPIPE_TRX_TRAIN_TIME_OUT_INT_MASK) {
2192 ERROR("Rx training timeout...\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002193 return -ETIMEDOUT;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002194 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002195
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002196 if (data & HPIPE_TRX_TRAIN_FAILED_MASK) {
2197 ERROR("Rx training failed...\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002198 return -EINVAL;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002199 }
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002200
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002201 mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
2202 data = 0x0 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
2203 reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002204
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002205 debug("Training done, reading results...\n\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002206
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002207 mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_MASK;
2208 g1_ffe_res_sel = ((mmio_read_32(hpipe_addr +
2209 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
2210 & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002211
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002212 mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_MASK;
2213 g1_ffe_cap_sel = ((mmio_read_32(hpipe_addr +
2214 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
2215 & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002216
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002217 mask = HPIPE_DATA_PHASE_ADAPTED_OS_PH_MASK;
2218 align90 = ((mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG)
2219 & mask) >> HPIPE_DATA_PHASE_ADAPTED_OS_PH_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002220
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002221 mask = HPIPE_ADAPTED_DFE_RES_MASK;
2222 g1_dfe_res = ((mmio_read_32(hpipe_addr +
2223 HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG)
2224 & mask) >> HPIPE_ADAPTED_DFE_RES_OFFSET);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002225
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002226 debug("================================================\n");
2227 debug("Switching to static configuration:\n");
2228 debug("FFE_RES = 0x%x FFE_CAP = 0x%x align90 = 0x%x g1_dfe_res 0x%x\n",
2229 g1_ffe_res_sel, g1_ffe_cap_sel, align90, g1_dfe_res);
2230 debug("Result after training: 0x%lx= 0x%x, 0x%lx= 0x%x, 0x%lx = 0x%x\n",
2231 (hpipe_addr + HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
2232 mmio_read_32(hpipe_addr +
2233 HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
2234 (hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
2235 mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
2236 (hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG),
2237 mmio_read_32(hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG));
2238 debug("================================================\n");
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002239
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002240 /* Update FFE_RES */
2241 mask = HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
2242 data = g1_ffe_res_sel << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
2243 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002244
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002245 /* Update FFE_CAP */
2246 mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
2247 data = g1_ffe_cap_sel << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
2248 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002249
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002250 /* Bypass the FFE table settings and use the FFE settings directly from
2251 * registers FFE_RES_SEL and FFE_CAP_SEL
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002252 */
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002253 mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
2254 data = 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
2255 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002256
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002257 /* Force DFE resolution (use gen table value) */
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002258 mask = HPIPE_DFE_RES_FORCE_MASK;
Grzegorz Jaszczyk3eb5e402019-03-08 19:51:21 +01002259 data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002260 reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
2261
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002262 /* 0x111-G1 DFE_Setting_4 */
2263 mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
2264 data = g1_dfe_res << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
2265 reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002266
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002267 printf("########################################################\n");
2268 printf("# To use trained values update the ATF sources:\n");
Grzegorz Jaszczyk3039bce2019-11-05 13:14:59 +01002269 printf("# plat/marvell/armada/a8k/<board_type>/board/phy-porting-layer.h ");
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002270 printf("file\n# with new values as below (for appropriate AP nr %d",
2271 ap_nr);
2272 printf("and CP nr: %d comphy_index %d\n\n",
2273 cp_nr, comphy_index);
2274 printf("static struct xfi_params xfi_static_values_tab[AP_NUM]");
2275 printf("[CP_NUM][MAX_LANE_NR] = {\n");
2276 printf("\t...\n");
2277 printf("\t.g1_ffe_res_sel = 0x%x,\n", g1_ffe_res_sel);
2278 printf("\t.g1_ffe_cap_sel = 0x%x,\n", g1_ffe_cap_sel);
2279 printf("\t.align90 = 0x%x,\n", align90);
2280 printf("\t.g1_dfe_res = 0x%x\n", g1_dfe_res);
2281 printf("\t...\n");
2282 printf("};\n\n");
2283 printf("########################################################\n");
2284
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002285 rx_trainng_done[ap_nr][cp_nr][comphy_index] = 1;
2286
2287 return 0;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002288}
2289
2290/* During AP the proper mode is auto-negotiated and the mac, pcs and serdes
2291 * configuration are done by the firmware loaded to the MG's CM3 for appropriate
2292 * negotiated mode. Therefore there is no need to configure the mac, pcs and
2293 * serdes from u-boot. The only thing that need to be setup is powering up
2294 * the comphy, which is done through Common PHY<n> Configuration 1 Register
2295 * (CP0: 0xF2441000, CP1: 0xF4441000). This step can't be done by MG's CM3,
2296 * since it doesn't have an access to this register-set (but it has access to
2297 * the network registers like: MG, AP, MAC, PCS, Serdes etc.)
2298 */
2299static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base,
Grzegorz Jaszczyk7a61f162019-03-28 13:02:42 +01002300 uint8_t comphy_index,
2301 uint32_t comphy_mode)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002302{
2303 uint32_t mask, data;
2304 uintptr_t comphy_addr = comphy_addr =
2305 COMPHY_ADDR(comphy_base, comphy_index);
2306
Grzegorz Jaszczyk7a61f162019-03-28 13:02:42 +01002307 /* configure phy selector for XFI/SFI */
2308 mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
2309 comphy_mode);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002310 debug_enter();
2311 debug("stage: RFU configurations - hard reset comphy\n");
2312 /* RFU configurations - hard reset comphy */
2313 mask = COMMON_PHY_CFG1_PWR_UP_MASK;
2314 data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
2315 mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
2316 data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
2317 reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
2318 debug_exit();
2319
Konstantin Porotchkin23099612020-10-12 18:13:07 +03002320#if MSS_SUPPORT
2321 do {
2322 uint8_t ap_nr, cp_nr;
2323
2324 /* start ap fw */
2325 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
2326 mg_start_ap_fw(cp_nr, comphy_index);
Grzegorz Jaszczyk1540ffb2019-04-12 16:57:14 +02002327
Konstantin Porotchkin23099612020-10-12 18:13:07 +03002328 } while (0);
2329#endif
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002330 return 0;
2331}
2332
2333/*
2334 * This function allows to reset the digital synchronizers between
2335 * the MAC and the PHY, it is required when the MAC changes its state.
2336 */
2337int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base,
2338 uint8_t comphy_index,
2339 uint32_t comphy_mode, uint32_t command)
2340{
2341 int mode = COMPHY_GET_MODE(comphy_mode);
2342 uintptr_t sd_ip_addr;
2343 uint32_t mask, data;
2344
2345 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2346 comphy_index);
2347
2348 switch (mode) {
2349 case (COMPHY_SGMII_MODE):
Pali Rohár51974d22021-08-27 11:16:43 +02002350 case (COMPHY_2500BASEX_MODE):
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002351 case (COMPHY_XFI_MODE):
2352 case (COMPHY_SFI_MODE):
2353 case (COMPHY_RXAUI_MODE):
2354 mask = SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2355 data = ((command == COMPHY_COMMAND_DIGITAL_PWR_OFF) ?
2356 0x0 : 0x1) << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2357 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2358 break;
2359 default:
2360 ERROR("comphy%d: Digital PWR ON/OFF is not supported\n",
2361 comphy_index);
2362 return -EINVAL;
2363 }
2364
2365 return 0;
2366}
2367
Alex Evraevb0a74302020-06-24 22:24:56 +03002368int mvebu_cp110_comphy_power_on(uint64_t comphy_base,
2369 uint8_t comphy_index,
2370 uint64_t comphy_mode,
2371 uint64_t comphy_train_base)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002372{
2373 int mode = COMPHY_GET_MODE(comphy_mode);
2374 int err = 0;
2375
2376 debug_enter();
2377
2378 switch (mode) {
2379 case(COMPHY_SATA_MODE):
2380 err = mvebu_cp110_comphy_sata_power_on(comphy_base,
2381 comphy_index,
2382 comphy_mode);
2383 break;
2384 case(COMPHY_SGMII_MODE):
Pali Rohár51974d22021-08-27 11:16:43 +02002385 case(COMPHY_2500BASEX_MODE):
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002386 err = mvebu_cp110_comphy_sgmii_power_on(comphy_base,
2387 comphy_index,
2388 comphy_mode);
2389 break;
2390 /* From comphy perspective, XFI and SFI are the same */
2391 case (COMPHY_XFI_MODE):
2392 case (COMPHY_SFI_MODE):
2393 err = mvebu_cp110_comphy_xfi_power_on(comphy_base,
2394 comphy_index,
Alex Evraevb0a74302020-06-24 22:24:56 +03002395 comphy_mode,
2396 comphy_train_base);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002397 break;
2398 case (COMPHY_PCIE_MODE):
2399 err = mvebu_cp110_comphy_pcie_power_on(comphy_base,
2400 comphy_index,
2401 comphy_mode);
2402 break;
2403 case (COMPHY_RXAUI_MODE):
2404 err = mvebu_cp110_comphy_rxaui_power_on(comphy_base,
2405 comphy_index,
2406 comphy_mode);
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002407 break;
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002408 case (COMPHY_USB3H_MODE):
2409 case (COMPHY_USB3D_MODE):
2410 err = mvebu_cp110_comphy_usb3_power_on(comphy_base,
2411 comphy_index,
2412 comphy_mode);
2413 break;
2414 case (COMPHY_AP_MODE):
Grzegorz Jaszczyk7a61f162019-03-28 13:02:42 +01002415 err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index,
2416 comphy_mode);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002417 break;
2418 default:
Grzegorz Jaszczyk4cff3082018-07-12 07:40:34 +02002419 ERROR("comphy%d: unsupported comphy mode\n", comphy_index);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002420 err = -EINVAL;
2421 break;
2422 }
2423
2424 debug_exit();
2425
2426 return err;
2427}
2428
Igal Libermanbd51efd2018-11-15 16:13:11 +02002429int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint8_t comphy_index,
2430 uint64_t comphy_mode)
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002431{
2432 uintptr_t sd_ip_addr, comphy_ip_addr;
2433 uint32_t mask, data;
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002434 uint8_t ap_nr, cp_nr;
Igal Libermanbd51efd2018-11-15 16:13:11 +02002435 _Bool called_from_uboot = COMPHY_GET_CALLER(comphy_mode);
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002436
2437 debug_enter();
2438
Igal Libermanbd51efd2018-11-15 16:13:11 +02002439 /* Power-off might happen because of 2 things:
2440 * 1. Bootloader turns off unconnected lanes
2441 * 2. Linux turns off all lanes during boot
2442 * (and then reconfigure it).
2443 *
2444 * For PCIe, there's a problem:
2445 * In Armada 8K DB boards, PCIe initialization can be executed
2446 * only once (PCIe reset performed during chip power on and
2447 * it cannot be executed via GPIO later) so a lane configured to
2448 * PCIe should not be powered off by Linux.
2449 *
2450 * So, check 2 things:
2451 * 1. Is Linux called for power-off?
2452 * 2. Is the comphy configured to PCIe?
2453 * If the answer is YES for both 1 and 2, skip the power-off.
2454 *
2455 * TODO: In MacciatoBIN, PCIe reset is connected via GPIO,
2456 * so after GPIO reset is added to Linux Kernel, it can be
2457 * powered-off.
2458 */
2459 if (!called_from_uboot) {
2460 data = mmio_read_32(comphy_base +
2461 COMMON_SELECTOR_PIPE_REG_OFFSET);
2462 data >>= (COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index);
2463 data &= COMMON_SELECTOR_COMPHY_MASK;
2464 if (data == COMMON_SELECTOR_PIPE_COMPHY_PCIE)
2465 return 0;
2466 }
2467
Grzegorz Jaszczyk2ed16f52018-06-29 18:00:33 +02002468 mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
2469
2470 if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) {
2471 debug("Skip %s for comphy[%d][%d][%d], due to rx training\n",
2472 __func__, ap_nr, cp_nr, comphy_index);
2473 return 0;
2474 }
2475
Konstantin Porotchkin5d93d082018-04-24 19:23:09 +03002476 sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2477 comphy_index);
2478 comphy_ip_addr = COMPHY_ADDR(comphy_base, comphy_index);
2479
2480 /* Hard reset the comphy, for Ethernet modes and Sata */
2481 mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
2482 data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
2483 mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
2484 data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
2485 mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2486 data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2487 reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2488
2489 /* PCIe reset */
2490 spin_lock(&cp110_mac_reset_lock);
2491
2492 /* The mvebu_cp110_comphy_power_off will be called only from Linux (to
2493 * override settings done by bootloader) and it will be relevant only
2494 * to PCIe (called before check if to skip pcie power off or not).
2495 */
2496 data = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2497 SYS_CTRL_UINIT_SOFT_RESET_REG);
2498 switch (comphy_index) {
2499 case COMPHY_LANE0:
2500 data &= ~PCIE_MAC_RESET_MASK_PORT0;
2501 break;
2502 case COMPHY_LANE4:
2503 data &= ~PCIE_MAC_RESET_MASK_PORT1;
2504 break;
2505 case COMPHY_LANE5:
2506 data &= ~PCIE_MAC_RESET_MASK_PORT2;
2507 break;
2508 }
2509
2510 mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2511 SYS_CTRL_UINIT_SOFT_RESET_REG, data);
2512 spin_unlock(&cp110_mac_reset_lock);
2513
2514 /* Hard reset the comphy, for PCIe and usb3 */
2515 mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
2516 data = 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
2517 mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
2518 data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
2519 reg_set(comphy_ip_addr + COMMON_PHY_CFG1_REG, data, mask);
2520
2521 /* Clear comphy PHY and PIPE selector, can't rely on previous config. */
2522 mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
2523 mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
2524
2525 debug_exit();
2526
2527 return 0;
2528}