xref: /rk3399_ARM-atf/drivers/marvell/comphy/phy-comphy-cp110.c (revision 0ade8cd892b0acd8129f52dea7b343dc9ab456ec)
1*0ade8cd8SKonstantin Porotchkin /*
2*0ade8cd8SKonstantin Porotchkin  * Copyright (C) 2018 Marvell International Ltd.
3*0ade8cd8SKonstantin Porotchkin  *
4*0ade8cd8SKonstantin Porotchkin  * SPDX-License-Identifier:     BSD-3-Clause
5*0ade8cd8SKonstantin Porotchkin  * https://spdx.org/licenses
6*0ade8cd8SKonstantin Porotchkin  */
7*0ade8cd8SKonstantin Porotchkin 
8*0ade8cd8SKonstantin Porotchkin /* Marvell CP110 SoC COMPHY unit driver */
9*0ade8cd8SKonstantin Porotchkin 
10*0ade8cd8SKonstantin Porotchkin #include <debug.h>
11*0ade8cd8SKonstantin Porotchkin #include <delay_timer.h>
12*0ade8cd8SKonstantin Porotchkin #include <errno.h>
13*0ade8cd8SKonstantin Porotchkin #include <mmio.h>
14*0ade8cd8SKonstantin Porotchkin #include <mvebu_def.h>
15*0ade8cd8SKonstantin Porotchkin #include <spinlock.h>
16*0ade8cd8SKonstantin Porotchkin #include "mvebu.h"
17*0ade8cd8SKonstantin Porotchkin #include "comphy-cp110.h"
18*0ade8cd8SKonstantin Porotchkin 
19*0ade8cd8SKonstantin Porotchkin /* #define DEBUG_COMPHY */
20*0ade8cd8SKonstantin Porotchkin #ifdef DEBUG_COMPHY
21*0ade8cd8SKonstantin Porotchkin #define debug(format...) printf(format)
22*0ade8cd8SKonstantin Porotchkin #else
23*0ade8cd8SKonstantin Porotchkin #define debug(format, arg...)
24*0ade8cd8SKonstantin Porotchkin #endif
25*0ade8cd8SKonstantin Porotchkin 
26*0ade8cd8SKonstantin Porotchkin /* A lane is described by 4 fields:
27*0ade8cd8SKonstantin Porotchkin  *      - bit 1~0 represent comphy polarity invert
28*0ade8cd8SKonstantin Porotchkin  *      - bit 7~2 represent comphy speed
29*0ade8cd8SKonstantin Porotchkin  *      - bit 11~8 represent unit index
30*0ade8cd8SKonstantin Porotchkin  *      - bit 16~12 represent mode
31*0ade8cd8SKonstantin Porotchkin  *      - bit 17 represent comphy indication of clock source
32*0ade8cd8SKonstantin Porotchkin  *      - bit 19-18 represents pcie width (in case of pcie comphy config.)
33*0ade8cd8SKonstantin Porotchkin  *      - bit 31~20 reserved
34*0ade8cd8SKonstantin Porotchkin  */
35*0ade8cd8SKonstantin Porotchkin 
36*0ade8cd8SKonstantin Porotchkin #define COMPHY_INVERT_OFFSET	0
37*0ade8cd8SKonstantin Porotchkin #define COMPHY_INVERT_LEN	2
38*0ade8cd8SKonstantin Porotchkin #define COMPHY_INVERT_MASK	COMPHY_MASK(COMPHY_INVERT_OFFSET, \
39*0ade8cd8SKonstantin Porotchkin 						COMPHY_INVERT_LEN)
40*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_OFFSET	(COMPHY_INVERT_OFFSET + COMPHY_INVERT_LEN)
41*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_LEN	6
42*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_MASK	COMPHY_MASK(COMPHY_SPEED_OFFSET, \
43*0ade8cd8SKonstantin Porotchkin 						COMPHY_SPEED_LEN)
44*0ade8cd8SKonstantin Porotchkin #define COMPHY_UNIT_ID_OFFSET	(COMPHY_SPEED_OFFSET + COMPHY_SPEED_LEN)
45*0ade8cd8SKonstantin Porotchkin #define COMPHY_UNIT_ID_LEN	4
46*0ade8cd8SKonstantin Porotchkin #define COMPHY_UNIT_ID_MASK	COMPHY_MASK(COMPHY_UNIT_ID_OFFSET, \
47*0ade8cd8SKonstantin Porotchkin 						COMPHY_UNIT_ID_LEN)
48*0ade8cd8SKonstantin Porotchkin #define COMPHY_MODE_OFFSET	(COMPHY_UNIT_ID_OFFSET + COMPHY_UNIT_ID_LEN)
49*0ade8cd8SKonstantin Porotchkin #define COMPHY_MODE_LEN		5
50*0ade8cd8SKonstantin Porotchkin #define COMPHY_MODE_MASK	COMPHY_MASK(COMPHY_MODE_OFFSET, COMPHY_MODE_LEN)
51*0ade8cd8SKonstantin Porotchkin #define COMPHY_CLK_SRC_OFFSET	(COMPHY_MODE_OFFSET + COMPHY_MODE_LEN)
52*0ade8cd8SKonstantin Porotchkin #define COMPHY_CLK_SRC_LEN	1
53*0ade8cd8SKonstantin Porotchkin #define COMPHY_CLK_SRC_MASK	COMPHY_MASK(COMPHY_CLK_SRC_OFFSET, \
54*0ade8cd8SKonstantin Porotchkin 						COMPHY_CLK_SRC_LEN)
55*0ade8cd8SKonstantin Porotchkin #define COMPHY_PCI_WIDTH_OFFSET	(COMPHY_CLK_SRC_OFFSET + COMPHY_CLK_SRC_LEN)
56*0ade8cd8SKonstantin Porotchkin #define COMPHY_PCI_WIDTH_LEN	3
57*0ade8cd8SKonstantin Porotchkin #define COMPHY_PCI_WIDTH_MASK	COMPHY_MASK(COMPHY_PCI_WIDTH_OFFSET, \
58*0ade8cd8SKonstantin Porotchkin 						COMPHY_PCI_WIDTH_LEN)
59*0ade8cd8SKonstantin Porotchkin 
60*0ade8cd8SKonstantin Porotchkin #define COMPHY_MASK(offset, len)	(((1 << (len)) - 1) << (offset))
61*0ade8cd8SKonstantin Porotchkin 
62*0ade8cd8SKonstantin Porotchkin /* Macro which extracts mode from lane description */
63*0ade8cd8SKonstantin Porotchkin #define COMPHY_GET_MODE(x)		(((x) & COMPHY_MODE_MASK) >> \
64*0ade8cd8SKonstantin Porotchkin 						COMPHY_MODE_OFFSET)
65*0ade8cd8SKonstantin Porotchkin /* Macro which extracts unit index from lane description */
66*0ade8cd8SKonstantin Porotchkin #define COMPHY_GET_ID(x)		(((x) & COMPHY_UNIT_ID_MASK) >> \
67*0ade8cd8SKonstantin Porotchkin 						COMPHY_UNIT_ID_OFFSET)
68*0ade8cd8SKonstantin Porotchkin /* Macro which extracts speed from lane description */
69*0ade8cd8SKonstantin Porotchkin #define COMPHY_GET_SPEED(x)		(((x) & COMPHY_SPEED_MASK) >> \
70*0ade8cd8SKonstantin Porotchkin 						COMPHY_SPEED_OFFSET)
71*0ade8cd8SKonstantin Porotchkin /* Macro which extracts clock source indication from lane description */
72*0ade8cd8SKonstantin Porotchkin #define COMPHY_GET_CLK_SRC(x)		(((x) & COMPHY_CLK_SRC_MASK) >> \
73*0ade8cd8SKonstantin Porotchkin 						COMPHY_CLK_SRC_OFFSET)
74*0ade8cd8SKonstantin Porotchkin /* Macro which extracts pcie width indication from lane description */
75*0ade8cd8SKonstantin Porotchkin #define COMPHY_GET_PCIE_WIDTH(x)	(((x) & COMPHY_PCI_WIDTH_MASK) >> \
76*0ade8cd8SKonstantin Porotchkin 						COMPHY_PCI_WIDTH_OFFSET)
77*0ade8cd8SKonstantin Porotchkin 
78*0ade8cd8SKonstantin Porotchkin #define COMPHY_SATA_MODE	0x1
79*0ade8cd8SKonstantin Porotchkin #define COMPHY_SGMII_MODE	0x2	/* SGMII 1G */
80*0ade8cd8SKonstantin Porotchkin #define COMPHY_HS_SGMII_MODE	0x3	/* SGMII 2.5G */
81*0ade8cd8SKonstantin Porotchkin #define COMPHY_USB3H_MODE	0x4
82*0ade8cd8SKonstantin Porotchkin #define COMPHY_USB3D_MODE	0x5
83*0ade8cd8SKonstantin Porotchkin #define COMPHY_PCIE_MODE	0x6
84*0ade8cd8SKonstantin Porotchkin #define COMPHY_RXAUI_MODE	0x7
85*0ade8cd8SKonstantin Porotchkin #define COMPHY_XFI_MODE		0x8
86*0ade8cd8SKonstantin Porotchkin #define COMPHY_SFI_MODE		0x9
87*0ade8cd8SKonstantin Porotchkin #define COMPHY_USB3_MODE	0xa
88*0ade8cd8SKonstantin Porotchkin #define COMPHY_AP_MODE		0xb
89*0ade8cd8SKonstantin Porotchkin 
90*0ade8cd8SKonstantin Porotchkin /* COMPHY speed macro */
91*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_1_25G		0 /* SGMII 1G */
92*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_2_5G		1
93*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_3_125G		2 /* SGMII 2.5G */
94*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_5G			3
95*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_5_15625G		4 /* XFI 5G */
96*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_6G			5
97*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_10_3125G		6 /* XFI 10G */
98*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_MAX		0x3F
99*0ade8cd8SKonstantin Porotchkin /* The  default speed for IO with fixed known speed */
100*0ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_DEFAULT		COMPHY_SPEED_MAX
101*0ade8cd8SKonstantin Porotchkin 
102*0ade8cd8SKonstantin Porotchkin /* Commands for comphy driver */
103*0ade8cd8SKonstantin Porotchkin #define COMPHY_COMMAND_DIGITAL_PWR_OFF		0x00000001
104*0ade8cd8SKonstantin Porotchkin #define COMPHY_COMMAND_DIGITAL_PWR_ON		0x00000002
105*0ade8cd8SKonstantin Porotchkin 
106*0ade8cd8SKonstantin Porotchkin #define COMPHY_PIPE_FROM_COMPHY_ADDR(x)	((x & ~0xffffff) + 0x120000)
107*0ade8cd8SKonstantin Porotchkin 
108*0ade8cd8SKonstantin Porotchkin /* System controller registers */
109*0ade8cd8SKonstantin Porotchkin #define PCIE_MAC_RESET_MASK_PORT0	BIT(13)
110*0ade8cd8SKonstantin Porotchkin #define PCIE_MAC_RESET_MASK_PORT1	BIT(11)
111*0ade8cd8SKonstantin Porotchkin #define PCIE_MAC_RESET_MASK_PORT2	BIT(12)
112*0ade8cd8SKonstantin Porotchkin #define SYS_CTRL_UINIT_SOFT_RESET_REG	0x268
113*0ade8cd8SKonstantin Porotchkin #define SYS_CTRL_FROM_COMPHY_ADDR(x)	((x & ~0xffffff) + 0x440000)
114*0ade8cd8SKonstantin Porotchkin 
115*0ade8cd8SKonstantin Porotchkin /* DFX register spaces */
116*0ade8cd8SKonstantin Porotchkin #define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET	(0)
117*0ade8cd8SKonstantin Porotchkin #define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK	(0x1 << \
118*0ade8cd8SKonstantin Porotchkin 					SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET)
119*0ade8cd8SKonstantin Porotchkin #define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET	(1)
120*0ade8cd8SKonstantin Porotchkin #define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK	(0x1 << \
121*0ade8cd8SKonstantin Porotchkin 					SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET)
122*0ade8cd8SKonstantin Porotchkin #define SAR_STATUS_0_REG			200
123*0ade8cd8SKonstantin Porotchkin #define DFX_FROM_COMPHY_ADDR(x)			((x & ~0xffffff) + DFX_BASE)
124*0ade8cd8SKonstantin Porotchkin 
125*0ade8cd8SKonstantin Porotchkin /* The same Units Soft Reset Config register are accessed in all PCIe ports
126*0ade8cd8SKonstantin Porotchkin  * initialization, so a spin lock is defined in case when more than 1 CPUs
127*0ade8cd8SKonstantin Porotchkin  * resets PCIe MAC and need to access the register in the same time. The spin
128*0ade8cd8SKonstantin Porotchkin  * lock is shared by all CP110 units.
129*0ade8cd8SKonstantin Porotchkin  */
130*0ade8cd8SKonstantin Porotchkin spinlock_t cp110_mac_reset_lock;
131*0ade8cd8SKonstantin Porotchkin 
132*0ade8cd8SKonstantin Porotchkin enum reg_width_type {
133*0ade8cd8SKonstantin Porotchkin 	REG_16BIT = 0,
134*0ade8cd8SKonstantin Porotchkin 	REG_32BIT,
135*0ade8cd8SKonstantin Porotchkin };
136*0ade8cd8SKonstantin Porotchkin 
137*0ade8cd8SKonstantin Porotchkin enum {
138*0ade8cd8SKonstantin Porotchkin 	COMPHY_LANE0 = 0,
139*0ade8cd8SKonstantin Porotchkin 	COMPHY_LANE1,
140*0ade8cd8SKonstantin Porotchkin 	COMPHY_LANE2,
141*0ade8cd8SKonstantin Porotchkin 	COMPHY_LANE3,
142*0ade8cd8SKonstantin Porotchkin 	COMPHY_LANE4,
143*0ade8cd8SKonstantin Porotchkin 	COMPHY_LANE5,
144*0ade8cd8SKonstantin Porotchkin 	COMPHY_LANE_MAX,
145*0ade8cd8SKonstantin Porotchkin };
146*0ade8cd8SKonstantin Porotchkin 
147*0ade8cd8SKonstantin Porotchkin /* These values come from the PCI Express Spec */
148*0ade8cd8SKonstantin Porotchkin enum pcie_link_width {
149*0ade8cd8SKonstantin Porotchkin 	PCIE_LNK_WIDTH_RESRV	= 0x00,
150*0ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X1		= 0x01,
151*0ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X2		= 0x02,
152*0ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X4		= 0x04,
153*0ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X8		= 0x08,
154*0ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X12		= 0x0C,
155*0ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X16		= 0x10,
156*0ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X32		= 0x20,
157*0ade8cd8SKonstantin Porotchkin 	PCIE_LNK_WIDTH_UNKNOWN  = 0xFF,
158*0ade8cd8SKonstantin Porotchkin };
159*0ade8cd8SKonstantin Porotchkin 
160*0ade8cd8SKonstantin Porotchkin static inline uint32_t polling_with_timeout(uintptr_t addr,
161*0ade8cd8SKonstantin Porotchkin 					    uint32_t val,
162*0ade8cd8SKonstantin Porotchkin 					    uint32_t mask,
163*0ade8cd8SKonstantin Porotchkin 					    uint32_t usec_timeout,
164*0ade8cd8SKonstantin Porotchkin 					    enum reg_width_type type)
165*0ade8cd8SKonstantin Porotchkin {
166*0ade8cd8SKonstantin Porotchkin 	uint32_t data;
167*0ade8cd8SKonstantin Porotchkin 
168*0ade8cd8SKonstantin Porotchkin 	do {
169*0ade8cd8SKonstantin Porotchkin 		udelay(1);
170*0ade8cd8SKonstantin Porotchkin 		if (type == REG_16BIT)
171*0ade8cd8SKonstantin Porotchkin 			data = mmio_read_16(addr) & mask;
172*0ade8cd8SKonstantin Porotchkin 		else
173*0ade8cd8SKonstantin Porotchkin 			data = mmio_read_32(addr) & mask;
174*0ade8cd8SKonstantin Porotchkin 	} while (data != val  && --usec_timeout > 0);
175*0ade8cd8SKonstantin Porotchkin 
176*0ade8cd8SKonstantin Porotchkin 	if (usec_timeout == 0)
177*0ade8cd8SKonstantin Porotchkin 		return data;
178*0ade8cd8SKonstantin Porotchkin 
179*0ade8cd8SKonstantin Porotchkin 	return 0;
180*0ade8cd8SKonstantin Porotchkin }
181*0ade8cd8SKonstantin Porotchkin 
182*0ade8cd8SKonstantin Porotchkin static inline void reg_set(uintptr_t addr, uint32_t data, uint32_t mask)
183*0ade8cd8SKonstantin Porotchkin {
184*0ade8cd8SKonstantin Porotchkin 	debug("<atf>: WR to addr = %#010lx, data = %#010x (mask = %#010x) - ",
185*0ade8cd8SKonstantin Porotchkin 	      addr, data, mask);
186*0ade8cd8SKonstantin Porotchkin 	debug("old value = %#010x ==> ", mmio_read_32(addr));
187*0ade8cd8SKonstantin Porotchkin 	mmio_clrsetbits_32(addr, mask, data);
188*0ade8cd8SKonstantin Porotchkin 
189*0ade8cd8SKonstantin Porotchkin 	debug("new val %#010x\n", mmio_read_32(addr));
190*0ade8cd8SKonstantin Porotchkin }
191*0ade8cd8SKonstantin Porotchkin 
192*0ade8cd8SKonstantin Porotchkin /* Clear PIPE selector - avoid collision with previous configuration */
193*0ade8cd8SKonstantin Porotchkin static void mvebu_cp110_comphy_clr_pipe_selector(uint64_t comphy_base,
194*0ade8cd8SKonstantin Porotchkin 						 uint8_t comphy_index)
195*0ade8cd8SKonstantin Porotchkin {
196*0ade8cd8SKonstantin Porotchkin 	uint32_t reg, mask, field;
197*0ade8cd8SKonstantin Porotchkin 	uint32_t comphy_offset =
198*0ade8cd8SKonstantin Porotchkin 			COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
199*0ade8cd8SKonstantin Porotchkin 
200*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
201*0ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
202*0ade8cd8SKonstantin Porotchkin 	field = reg & mask;
203*0ade8cd8SKonstantin Porotchkin 
204*0ade8cd8SKonstantin Porotchkin 	if (field) {
205*0ade8cd8SKonstantin Porotchkin 		reg &= ~mask;
206*0ade8cd8SKonstantin Porotchkin 		mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET,
207*0ade8cd8SKonstantin Porotchkin 			     reg);
208*0ade8cd8SKonstantin Porotchkin 	}
209*0ade8cd8SKonstantin Porotchkin }
210*0ade8cd8SKonstantin Porotchkin 
211*0ade8cd8SKonstantin Porotchkin /* Clear PHY selector - avoid collision with previous configuration */
212*0ade8cd8SKonstantin Porotchkin static void mvebu_cp110_comphy_clr_phy_selector(uint64_t comphy_base,
213*0ade8cd8SKonstantin Porotchkin 						uint8_t comphy_index)
214*0ade8cd8SKonstantin Porotchkin {
215*0ade8cd8SKonstantin Porotchkin 	uint32_t reg, mask, field;
216*0ade8cd8SKonstantin Porotchkin 	uint32_t comphy_offset =
217*0ade8cd8SKonstantin Porotchkin 			COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
218*0ade8cd8SKonstantin Porotchkin 
219*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
220*0ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
221*0ade8cd8SKonstantin Porotchkin 	field = reg & mask;
222*0ade8cd8SKonstantin Porotchkin 
223*0ade8cd8SKonstantin Porotchkin 	/* Clear comphy selector - if it was already configured.
224*0ade8cd8SKonstantin Porotchkin 	 * (might be that this comphy was configured as PCIe/USB,
225*0ade8cd8SKonstantin Porotchkin 	 * in such case, no need to clear comphy selector because PCIe/USB
226*0ade8cd8SKonstantin Porotchkin 	 * are controlled by hpipe selector).
227*0ade8cd8SKonstantin Porotchkin 	 */
228*0ade8cd8SKonstantin Porotchkin 	if (field) {
229*0ade8cd8SKonstantin Porotchkin 		reg &= ~mask;
230*0ade8cd8SKonstantin Porotchkin 		mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET,
231*0ade8cd8SKonstantin Porotchkin 			      reg);
232*0ade8cd8SKonstantin Porotchkin 	}
233*0ade8cd8SKonstantin Porotchkin }
234*0ade8cd8SKonstantin Porotchkin 
235*0ade8cd8SKonstantin Porotchkin /* PHY selector configures SATA and Network modes */
236*0ade8cd8SKonstantin Porotchkin static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base,
237*0ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
238*0ade8cd8SKonstantin Porotchkin {
239*0ade8cd8SKonstantin Porotchkin 	uint32_t reg, mask;
240*0ade8cd8SKonstantin Porotchkin 	uint32_t comphy_offset =
241*0ade8cd8SKonstantin Porotchkin 			COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
242*0ade8cd8SKonstantin Porotchkin 	int mode;
243*0ade8cd8SKonstantin Porotchkin 
244*0ade8cd8SKonstantin Porotchkin 	/* If phy selector is used the pipe selector should be marked as
245*0ade8cd8SKonstantin Porotchkin 	 * unconnected.
246*0ade8cd8SKonstantin Porotchkin 	 */
247*0ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
248*0ade8cd8SKonstantin Porotchkin 
249*0ade8cd8SKonstantin Porotchkin 	/* Comphy mode (compound of the IO mode and id). Here, only the IO mode
250*0ade8cd8SKonstantin Porotchkin 	 * is required to distinguish between SATA and network modes.
251*0ade8cd8SKonstantin Porotchkin 	 */
252*0ade8cd8SKonstantin Porotchkin 	mode = COMPHY_GET_MODE(comphy_mode);
253*0ade8cd8SKonstantin Porotchkin 
254*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
255*0ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
256*0ade8cd8SKonstantin Porotchkin 	reg &= ~mask;
257*0ade8cd8SKonstantin Porotchkin 
258*0ade8cd8SKonstantin Porotchkin 	/* SATA port 0/1 require the same configuration */
259*0ade8cd8SKonstantin Porotchkin 	if (mode == COMPHY_SATA_MODE) {
260*0ade8cd8SKonstantin Porotchkin 		/* SATA selector values is always 4 */
261*0ade8cd8SKonstantin Porotchkin 		reg |= COMMON_SELECTOR_COMPHYN_SATA << comphy_offset;
262*0ade8cd8SKonstantin Porotchkin 	} else {
263*0ade8cd8SKonstantin Porotchkin 		switch (comphy_index) {
264*0ade8cd8SKonstantin Porotchkin 		case(0):
265*0ade8cd8SKonstantin Porotchkin 		case(1):
266*0ade8cd8SKonstantin Porotchkin 		case(2):
267*0ade8cd8SKonstantin Porotchkin 			/* For comphy 0,1, and 2:
268*0ade8cd8SKonstantin Porotchkin 			 * Network selector value is always 1.
269*0ade8cd8SKonstantin Porotchkin 			 */
270*0ade8cd8SKonstantin Porotchkin 			reg |= COMMON_SELECTOR_COMPHY0_1_2_NETWORK <<
271*0ade8cd8SKonstantin Porotchkin 				comphy_offset;
272*0ade8cd8SKonstantin Porotchkin 			break;
273*0ade8cd8SKonstantin Porotchkin 		case(3):
274*0ade8cd8SKonstantin Porotchkin 			/* For comphy 3:
275*0ade8cd8SKonstantin Porotchkin 			 * 0x1 = RXAUI_Lane1
276*0ade8cd8SKonstantin Porotchkin 			 * 0x2 = SGMII/HS-SGMII Port1
277*0ade8cd8SKonstantin Porotchkin 			 */
278*0ade8cd8SKonstantin Porotchkin 			if (mode == COMPHY_RXAUI_MODE)
279*0ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY3_RXAUI <<
280*0ade8cd8SKonstantin Porotchkin 					comphy_offset;
281*0ade8cd8SKonstantin Porotchkin 			else
282*0ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY3_SGMII <<
283*0ade8cd8SKonstantin Porotchkin 					comphy_offset;
284*0ade8cd8SKonstantin Porotchkin 			break;
285*0ade8cd8SKonstantin Porotchkin 		case(4):
286*0ade8cd8SKonstantin Porotchkin 			 /* For comphy 4:
287*0ade8cd8SKonstantin Porotchkin 			  * 0x1 = SGMII/HS-SGMII Port1, XFI1/SFI1
288*0ade8cd8SKonstantin Porotchkin 			  * 0x2 = SGMII/HS-SGMII Port0: XFI0/SFI0, RXAUI_Lane0
289*0ade8cd8SKonstantin Porotchkin 			  *
290*0ade8cd8SKonstantin Porotchkin 			  * We want to check if SGMII1/HS_SGMII1 is the
291*0ade8cd8SKonstantin Porotchkin 			  * requested mode in order to determine which value
292*0ade8cd8SKonstantin Porotchkin 			  * should be set (all other modes use the same value)
293*0ade8cd8SKonstantin Porotchkin 			  * so we need to strip the mode, and check the ID
294*0ade8cd8SKonstantin Porotchkin 			  * because we might handle SGMII0/HS_SGMII0 too.
295*0ade8cd8SKonstantin Porotchkin 			  */
296*0ade8cd8SKonstantin Porotchkin 			  /* TODO: need to distinguish between CP110 and CP115
297*0ade8cd8SKonstantin Porotchkin 			   * as SFI1/XFI1 available only for CP115.
298*0ade8cd8SKonstantin Porotchkin 			   */
299*0ade8cd8SKonstantin Porotchkin 			if ((mode == COMPHY_SGMII_MODE ||
300*0ade8cd8SKonstantin Porotchkin 			    mode == COMPHY_HS_SGMII_MODE ||
301*0ade8cd8SKonstantin Porotchkin 			    mode == COMPHY_SFI_MODE) &&
302*0ade8cd8SKonstantin Porotchkin 			    COMPHY_GET_ID(comphy_mode) == 1)
303*0ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY4_PORT1 <<
304*0ade8cd8SKonstantin Porotchkin 					comphy_offset;
305*0ade8cd8SKonstantin Porotchkin 			else
306*0ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY4_ALL_OTHERS <<
307*0ade8cd8SKonstantin Porotchkin 					comphy_offset;
308*0ade8cd8SKonstantin Porotchkin 			break;
309*0ade8cd8SKonstantin Porotchkin 		case(5):
310*0ade8cd8SKonstantin Porotchkin 			/* For comphy 5:
311*0ade8cd8SKonstantin Porotchkin 			 * 0x1 = SGMII/HS-SGMII Port2
312*0ade8cd8SKonstantin Porotchkin 			 * 0x2 = RXAUI Lane1
313*0ade8cd8SKonstantin Porotchkin 			 */
314*0ade8cd8SKonstantin Porotchkin 			if (mode == COMPHY_RXAUI_MODE)
315*0ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY5_RXAUI <<
316*0ade8cd8SKonstantin Porotchkin 					comphy_offset;
317*0ade8cd8SKonstantin Porotchkin 			else
318*0ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY5_SGMII <<
319*0ade8cd8SKonstantin Porotchkin 					comphy_offset;
320*0ade8cd8SKonstantin Porotchkin 			break;
321*0ade8cd8SKonstantin Porotchkin 		}
322*0ade8cd8SKonstantin Porotchkin 	}
323*0ade8cd8SKonstantin Porotchkin 
324*0ade8cd8SKonstantin Porotchkin 	mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET, reg);
325*0ade8cd8SKonstantin Porotchkin }
326*0ade8cd8SKonstantin Porotchkin 
327*0ade8cd8SKonstantin Porotchkin /* PIPE selector configures for PCIe, USB 3.0 Host, and USB 3.0 Device mode */
328*0ade8cd8SKonstantin Porotchkin static void mvebu_cp110_comphy_set_pipe_selector(uint64_t comphy_base,
329*0ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
330*0ade8cd8SKonstantin Porotchkin {
331*0ade8cd8SKonstantin Porotchkin 	uint32_t reg;
332*0ade8cd8SKonstantin Porotchkin 	uint32_t shift = COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
333*0ade8cd8SKonstantin Porotchkin 	int mode = COMPHY_GET_MODE(comphy_mode);
334*0ade8cd8SKonstantin Porotchkin 	uint32_t mask = COMMON_SELECTOR_COMPHY_MASK << shift;
335*0ade8cd8SKonstantin Porotchkin 	uint32_t pipe_sel = 0x0;
336*0ade8cd8SKonstantin Porotchkin 
337*0ade8cd8SKonstantin Porotchkin 	/* If pipe selector is used the phy selector should be marked as
338*0ade8cd8SKonstantin Porotchkin 	 * unconnected.
339*0ade8cd8SKonstantin Porotchkin 	 */
340*0ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
341*0ade8cd8SKonstantin Porotchkin 
342*0ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
343*0ade8cd8SKonstantin Porotchkin 	reg &= ~mask;
344*0ade8cd8SKonstantin Porotchkin 
345*0ade8cd8SKonstantin Porotchkin 	switch (mode) {
346*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_PCIE_MODE):
347*0ade8cd8SKonstantin Porotchkin 		/* For lanes support PCIE, selector value are all same */
348*0ade8cd8SKonstantin Porotchkin 		pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_PCIE;
349*0ade8cd8SKonstantin Porotchkin 		break;
350*0ade8cd8SKonstantin Porotchkin 
351*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_USB3H_MODE):
352*0ade8cd8SKonstantin Porotchkin 		/* Only lane 1-4 support USB host, selector value is same */
353*0ade8cd8SKonstantin Porotchkin 		if (comphy_index == COMPHY_LANE0 ||
354*0ade8cd8SKonstantin Porotchkin 		    comphy_index == COMPHY_LANE5)
355*0ade8cd8SKonstantin Porotchkin 			ERROR("COMPHY[%d] mode[%d] is invalid\n",
356*0ade8cd8SKonstantin Porotchkin 			      comphy_index, mode);
357*0ade8cd8SKonstantin Porotchkin 		else
358*0ade8cd8SKonstantin Porotchkin 			pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBH;
359*0ade8cd8SKonstantin Porotchkin 		break;
360*0ade8cd8SKonstantin Porotchkin 
361*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_USB3D_MODE):
362*0ade8cd8SKonstantin Porotchkin 		/* Lane 1 and 4 support USB device, selector value is same */
363*0ade8cd8SKonstantin Porotchkin 		if (comphy_index == COMPHY_LANE1 ||
364*0ade8cd8SKonstantin Porotchkin 		    comphy_index == COMPHY_LANE4)
365*0ade8cd8SKonstantin Porotchkin 			pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBD;
366*0ade8cd8SKonstantin Porotchkin 		else
367*0ade8cd8SKonstantin Porotchkin 			ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index,
368*0ade8cd8SKonstantin Porotchkin 			      mode);
369*0ade8cd8SKonstantin Porotchkin 		break;
370*0ade8cd8SKonstantin Porotchkin 
371*0ade8cd8SKonstantin Porotchkin 	default:
372*0ade8cd8SKonstantin Porotchkin 		ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode);
373*0ade8cd8SKonstantin Porotchkin 		break;
374*0ade8cd8SKonstantin Porotchkin 	}
375*0ade8cd8SKonstantin Porotchkin 
376*0ade8cd8SKonstantin Porotchkin 	mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET, reg |
377*0ade8cd8SKonstantin Porotchkin 		      (pipe_sel << shift));
378*0ade8cd8SKonstantin Porotchkin }
379*0ade8cd8SKonstantin Porotchkin 
380*0ade8cd8SKonstantin Porotchkin int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index)
381*0ade8cd8SKonstantin Porotchkin {
382*0ade8cd8SKonstantin Porotchkin 	uintptr_t sd_ip_addr, addr;
383*0ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
384*0ade8cd8SKonstantin Porotchkin 	int ret = 0;
385*0ade8cd8SKonstantin Porotchkin 
386*0ade8cd8SKonstantin Porotchkin 	debug_enter();
387*0ade8cd8SKonstantin Porotchkin 
388*0ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
389*0ade8cd8SKonstantin Porotchkin 			     comphy_index);
390*0ade8cd8SKonstantin Porotchkin 
391*0ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
392*0ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_PLL_TX_MASK &
393*0ade8cd8SKonstantin Porotchkin 		SD_EXTERNAL_STATUS0_PLL_RX_MASK;
394*0ade8cd8SKonstantin Porotchkin 	mask = data;
395*0ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask,
396*0ade8cd8SKonstantin Porotchkin 				    PLL_LOCK_TIMEOUT, REG_32BIT);
397*0ade8cd8SKonstantin Porotchkin 	if (data != 0) {
398*0ade8cd8SKonstantin Porotchkin 		if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
399*0ade8cd8SKonstantin Porotchkin 			ERROR("RX PLL is not locked\n");
400*0ade8cd8SKonstantin Porotchkin 		if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
401*0ade8cd8SKonstantin Porotchkin 			ERROR("TX PLL is not locked\n");
402*0ade8cd8SKonstantin Porotchkin 
403*0ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
404*0ade8cd8SKonstantin Porotchkin 	}
405*0ade8cd8SKonstantin Porotchkin 
406*0ade8cd8SKonstantin Porotchkin 	debug_exit();
407*0ade8cd8SKonstantin Porotchkin 
408*0ade8cd8SKonstantin Porotchkin 	return ret;
409*0ade8cd8SKonstantin Porotchkin }
410*0ade8cd8SKonstantin Porotchkin 
411*0ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base,
412*0ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
413*0ade8cd8SKonstantin Porotchkin {
414*0ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, sd_ip_addr, comphy_addr;
415*0ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
416*0ade8cd8SKonstantin Porotchkin 	int ret = 0;
417*0ade8cd8SKonstantin Porotchkin 
418*0ade8cd8SKonstantin Porotchkin 	debug_enter();
419*0ade8cd8SKonstantin Porotchkin 
420*0ade8cd8SKonstantin Porotchkin 	/* configure phy selector for SATA */
421*0ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_phy_selector(comphy_base,
422*0ade8cd8SKonstantin Porotchkin 					    comphy_index, comphy_mode);
423*0ade8cd8SKonstantin Porotchkin 
424*0ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
425*0ade8cd8SKonstantin Porotchkin 				comphy_index);
426*0ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
427*0ade8cd8SKonstantin Porotchkin 			     comphy_index);
428*0ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
429*0ade8cd8SKonstantin Porotchkin 
430*0ade8cd8SKonstantin Porotchkin 	debug(" add hpipe 0x%lx, sd 0x%lx, comphy 0x%lx\n",
431*0ade8cd8SKonstantin Porotchkin 					   hpipe_addr, sd_ip_addr, comphy_addr);
432*0ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
433*0ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
434*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
435*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
436*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
437*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
438*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
439*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
440*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
441*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
442*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
443*0ade8cd8SKonstantin Porotchkin 
444*0ade8cd8SKonstantin Porotchkin 	/* Set select data  width 40Bit - SATA mode only */
445*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG6_REG,
446*0ade8cd8SKonstantin Porotchkin 		0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET,
447*0ade8cd8SKonstantin Porotchkin 		COMMON_PHY_CFG6_IF_40_SEL_MASK);
448*0ade8cd8SKonstantin Porotchkin 
449*0ade8cd8SKonstantin Porotchkin 	/* release from hard reset in SD external */
450*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
451*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
452*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
453*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
454*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
455*0ade8cd8SKonstantin Porotchkin 
456*0ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
457*0ade8cd8SKonstantin Porotchkin 	mdelay(1);
458*0ade8cd8SKonstantin Porotchkin 
459*0ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
460*0ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
461*0ade8cd8SKonstantin Porotchkin 	/* Set reference clock to comes from group 1 - choose 25Mhz */
462*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG,
463*0ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
464*0ade8cd8SKonstantin Porotchkin 		HPIPE_MISC_REFCLK_SEL_MASK);
465*0ade8cd8SKonstantin Porotchkin 	/* Reference frequency select set 1 (for SATA = 25Mhz) */
466*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
467*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
468*0ade8cd8SKonstantin Porotchkin 	/* PHY mode select (set SATA = 0x0 */
469*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
470*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
471*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
472*0ade8cd8SKonstantin Porotchkin 	/* Set max PHY generation setting - 6Gbps */
473*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
474*0ade8cd8SKonstantin Porotchkin 		0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
475*0ade8cd8SKonstantin Porotchkin 		HPIPE_INTERFACE_GEN_MAX_MASK);
476*0ade8cd8SKonstantin Porotchkin 	/* Set select data  width 40Bit (SEL_BITS[2:0]) */
477*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
478*0ade8cd8SKonstantin Porotchkin 		0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
479*0ade8cd8SKonstantin Porotchkin 
480*0ade8cd8SKonstantin Porotchkin 	debug("stage: Analog parameters from ETP(HW)\n");
481*0ade8cd8SKonstantin Porotchkin 	/* G1 settings */
482*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
483*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
484*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
485*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
486*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
487*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
488*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
489*0ade8cd8SKonstantin Porotchkin 	data |= 0x3 << HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
490*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
491*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
492*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
493*0ade8cd8SKonstantin Porotchkin 
494*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
495*0ade8cd8SKonstantin Porotchkin 	data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
496*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
497*0ade8cd8SKonstantin Porotchkin 	data |= 0x2 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
498*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
499*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
500*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_MASK;
501*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET;
502*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_MASK;
503*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET;
504*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
505*0ade8cd8SKonstantin Porotchkin 
506*0ade8cd8SKonstantin Porotchkin 	/* G2 settings */
507*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
508*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
509*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK;
510*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET;
511*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
512*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
513*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_1_G2_RX_SELMUFF_MASK;
514*0ade8cd8SKonstantin Porotchkin 	data |= 0x3 << HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET;
515*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_MASK;
516*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET;
517*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
518*0ade8cd8SKonstantin Porotchkin 
519*0ade8cd8SKonstantin Porotchkin 	/* G3 settings */
520*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
521*0ade8cd8SKonstantin Porotchkin 	data = 0x2 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
522*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
523*0ade8cd8SKonstantin Porotchkin 	data |= 0x2 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
524*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_SELMUFI_MASK;
525*0ade8cd8SKonstantin Porotchkin 	data |= 0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET;
526*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_SELMUFF_MASK;
527*0ade8cd8SKonstantin Porotchkin 	data |= 0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET;
528*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_DFE_EN_MASK;
529*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET;
530*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_MASK;
531*0ade8cd8SKonstantin Porotchkin 	data |= 0x2 << HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET;
532*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
533*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
534*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
535*0ade8cd8SKonstantin Porotchkin 
536*0ade8cd8SKonstantin Porotchkin 	/* DTL Control */
537*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_CTR_DTL_SQ_DET_EN_MASK;
538*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET;
539*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_MASK;
540*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET;
541*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
542*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
543*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_CLAMPING_SEL_MASK;
544*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET;
545*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_MASK;
546*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET;
547*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_MASK;
548*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET;
549*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_MASK;
550*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET;
551*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
552*0ade8cd8SKonstantin Porotchkin 
553*0ade8cd8SKonstantin Porotchkin 	/* Trigger sampler enable pulse */
554*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_SMAPLER_MASK;
555*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_SMAPLER_OFFSET;
556*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
557*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_SMAPLER_MASK;
558*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_SMAPLER_OFFSET;
559*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
560*0ade8cd8SKonstantin Porotchkin 
561*0ade8cd8SKonstantin Porotchkin 	/* VDD Calibration Control 3 */
562*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
563*0ade8cd8SKonstantin Porotchkin 	data = 0x10 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
564*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
565*0ade8cd8SKonstantin Porotchkin 
566*0ade8cd8SKonstantin Porotchkin 	/* DFE Resolution Control */
567*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_RES_FORCE_MASK;
568*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
569*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
570*0ade8cd8SKonstantin Porotchkin 
571*0ade8cd8SKonstantin Porotchkin 	/* DFE F3-F5 Coefficient Control */
572*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
573*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
574*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
575*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
576*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
577*0ade8cd8SKonstantin Porotchkin 
578*0ade8cd8SKonstantin Porotchkin 	/* G3 Setting 3 */
579*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_FFE_CAP_SEL_MASK;
580*0ade8cd8SKonstantin Porotchkin 	data = 0xf << HPIPE_G3_FFE_CAP_SEL_OFFSET;
581*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_FFE_RES_SEL_MASK;
582*0ade8cd8SKonstantin Porotchkin 	data |= 0x4 << HPIPE_G3_FFE_RES_SEL_OFFSET;
583*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_FFE_SETTING_FORCE_MASK;
584*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET;
585*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
586*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
587*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
588*0ade8cd8SKonstantin Porotchkin 	data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
589*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
590*0ade8cd8SKonstantin Porotchkin 
591*0ade8cd8SKonstantin Porotchkin 	/* G3 Setting 4 */
592*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_DFE_RES_MASK;
593*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G3_DFE_RES_OFFSET;
594*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
595*0ade8cd8SKonstantin Porotchkin 
596*0ade8cd8SKonstantin Porotchkin 	/* Offset Phase Control */
597*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_OS_PH_OFFSET_MASK;
598*0ade8cd8SKonstantin Porotchkin 	data = 0x61 << HPIPE_OS_PH_OFFSET_OFFSET;
599*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_OS_PH_OFFSET_FORCE_MASK;
600*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_OS_PH_OFFSET_FORCE_OFFSET;
601*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_OS_PH_VALID_MASK;
602*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_OS_PH_VALID_OFFSET;
603*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
604*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_OS_PH_VALID_MASK;
605*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_OS_PH_VALID_OFFSET;
606*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
607*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_OS_PH_VALID_MASK;
608*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_OS_PH_VALID_OFFSET;
609*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
610*0ade8cd8SKonstantin Porotchkin 
611*0ade8cd8SKonstantin Porotchkin 	/* Set G1 TX amplitude and TX post emphasis value */
612*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
613*0ade8cd8SKonstantin Porotchkin 	data = 0x8 << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
614*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
615*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
616*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
617*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
618*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
619*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
620*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
621*0ade8cd8SKonstantin Porotchkin 
622*0ade8cd8SKonstantin Porotchkin 	/* Set G2 TX amplitude and TX post emphasis value */
623*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G2_SET_0_G2_TX_AMP_MASK;
624*0ade8cd8SKonstantin Porotchkin 	data = 0xa << HPIPE_G2_SET_0_G2_TX_AMP_OFFSET;
625*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_0_G2_TX_AMP_ADJ_MASK;
626*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET;
627*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_MASK;
628*0ade8cd8SKonstantin Porotchkin 	data |= 0x2 << HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET;
629*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_EN_MASK;
630*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET;
631*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G2_SET_0_REG, data, mask);
632*0ade8cd8SKonstantin Porotchkin 
633*0ade8cd8SKonstantin Porotchkin 	/* Set G3 TX amplitude and TX post emphasis value */
634*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_SET_0_G3_TX_AMP_MASK;
635*0ade8cd8SKonstantin Porotchkin 	data = 0x1e << HPIPE_G3_SET_0_G3_TX_AMP_OFFSET;
636*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_0_G3_TX_AMP_ADJ_MASK;
637*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET;
638*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_MASK;
639*0ade8cd8SKonstantin Porotchkin 	data |= 0xe << HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET;
640*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_EN_MASK;
641*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET;
642*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_MASK;
643*0ade8cd8SKonstantin Porotchkin 	data |= 0x4 << HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET;
644*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_MASK;
645*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET;
646*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SET_0_REG, data, mask);
647*0ade8cd8SKonstantin Porotchkin 
648*0ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration 2 register */
649*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG2_SSC_ENABLE_MASK;
650*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET;
651*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
652*0ade8cd8SKonstantin Porotchkin 
653*0ade8cd8SKonstantin Porotchkin 	/* DFE reset sequence */
654*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
655*0ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
656*0ade8cd8SKonstantin Porotchkin 		HPIPE_PWR_CTR_RST_DFE_MASK);
657*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
658*0ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
659*0ade8cd8SKonstantin Porotchkin 		HPIPE_PWR_CTR_RST_DFE_MASK);
660*0ade8cd8SKonstantin Porotchkin 	/* SW reset for interrupt logic */
661*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
662*0ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
663*0ade8cd8SKonstantin Porotchkin 		HPIPE_PWR_CTR_SFT_RST_MASK);
664*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
665*0ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
666*0ade8cd8SKonstantin Porotchkin 		HPIPE_PWR_CTR_SFT_RST_MASK);
667*0ade8cd8SKonstantin Porotchkin 
668*0ade8cd8SKonstantin Porotchkin 	debug_exit();
669*0ade8cd8SKonstantin Porotchkin 
670*0ade8cd8SKonstantin Porotchkin 	return ret;
671*0ade8cd8SKonstantin Porotchkin }
672*0ade8cd8SKonstantin Porotchkin 
673*0ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_sgmii_power_on(uint64_t comphy_base,
674*0ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
675*0ade8cd8SKonstantin Porotchkin {
676*0ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
677*0ade8cd8SKonstantin Porotchkin 	uint32_t mask, data, sgmii_speed = COMPHY_GET_SPEED(comphy_mode);
678*0ade8cd8SKonstantin Porotchkin 	int ret = 0;
679*0ade8cd8SKonstantin Porotchkin 
680*0ade8cd8SKonstantin Porotchkin 	debug_enter();
681*0ade8cd8SKonstantin Porotchkin 
682*0ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
683*0ade8cd8SKonstantin Porotchkin 				comphy_index);
684*0ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
685*0ade8cd8SKonstantin Porotchkin 			     comphy_index);
686*0ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
687*0ade8cd8SKonstantin Porotchkin 
688*0ade8cd8SKonstantin Porotchkin 	/* configure phy selector for SGMII */
689*0ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
690*0ade8cd8SKonstantin Porotchkin 					    comphy_mode);
691*0ade8cd8SKonstantin Porotchkin 
692*0ade8cd8SKonstantin Porotchkin 	/* Confiugre the lane */
693*0ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
694*0ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
695*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
696*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
697*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
698*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
699*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
700*0ade8cd8SKonstantin Porotchkin 
701*0ade8cd8SKonstantin Porotchkin 	/* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
702*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
703*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
704*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
705*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
706*0ade8cd8SKonstantin Porotchkin 
707*0ade8cd8SKonstantin Porotchkin 	if (sgmii_speed == COMPHY_SPEED_1_25G) {
708*0ade8cd8SKonstantin Porotchkin 		/* SGMII 1G, SerDes speed 1.25G */
709*0ade8cd8SKonstantin Porotchkin 		data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
710*0ade8cd8SKonstantin Porotchkin 		data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
711*0ade8cd8SKonstantin Porotchkin 	} else if (sgmii_speed == COMPHY_SPEED_3_125G) {
712*0ade8cd8SKonstantin Porotchkin 		/* HS SGMII (2.5G), SerDes speed 3.125G */
713*0ade8cd8SKonstantin Porotchkin 		data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
714*0ade8cd8SKonstantin Porotchkin 		data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
715*0ade8cd8SKonstantin Porotchkin 	} else {
716*0ade8cd8SKonstantin Porotchkin 		/* Other rates are not supported */
717*0ade8cd8SKonstantin Porotchkin 		ERROR("unsupported SGMII speed on comphy%d\n", comphy_index);
718*0ade8cd8SKonstantin Porotchkin 		return -EINVAL;
719*0ade8cd8SKonstantin Porotchkin 	}
720*0ade8cd8SKonstantin Porotchkin 
721*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
722*0ade8cd8SKonstantin Porotchkin 	data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
723*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
724*0ade8cd8SKonstantin Porotchkin 	data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
725*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
726*0ade8cd8SKonstantin Porotchkin 	data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
727*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
728*0ade8cd8SKonstantin Porotchkin 
729*0ade8cd8SKonstantin Porotchkin 	/* Set hard reset */
730*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
731*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
732*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
733*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
734*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
735*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
736*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
737*0ade8cd8SKonstantin Porotchkin 
738*0ade8cd8SKonstantin Porotchkin 	/* Release hard reset */
739*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
740*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
741*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
742*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
743*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
744*0ade8cd8SKonstantin Porotchkin 
745*0ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
746*0ade8cd8SKonstantin Porotchkin 	mdelay(1);
747*0ade8cd8SKonstantin Porotchkin 
748*0ade8cd8SKonstantin Porotchkin 	/* Make sure that 40 data bits is disabled
749*0ade8cd8SKonstantin Porotchkin 	 * This bit is not cleared by reset
750*0ade8cd8SKonstantin Porotchkin 	 */
751*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
752*0ade8cd8SKonstantin Porotchkin 	data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
753*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
754*0ade8cd8SKonstantin Porotchkin 
755*0ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
756*0ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
757*0ade8cd8SKonstantin Porotchkin 	/* set reference clock */
758*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_MISC_REFCLK_SEL_MASK;
759*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
760*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
761*0ade8cd8SKonstantin Porotchkin 	/* Power and PLL Control */
762*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
763*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
764*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
765*0ade8cd8SKonstantin Porotchkin 	data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
766*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
767*0ade8cd8SKonstantin Porotchkin 	/* Loopback register */
768*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_LOOPBACK_SEL_MASK;
769*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
770*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
771*0ade8cd8SKonstantin Porotchkin 	/* rx control 1 */
772*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
773*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
774*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
775*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
776*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
777*0ade8cd8SKonstantin Porotchkin 	/* DTL Control */
778*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
779*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
780*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
781*0ade8cd8SKonstantin Porotchkin 
782*0ade8cd8SKonstantin Porotchkin 	/* Set analog parameters from ETP(HW) - for now use the default datas */
783*0ade8cd8SKonstantin Porotchkin 	debug("stage: Analog parameters from ETP(HW)\n");
784*0ade8cd8SKonstantin Porotchkin 
785*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
786*0ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
787*0ade8cd8SKonstantin Porotchkin 		HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
788*0ade8cd8SKonstantin Porotchkin 
789*0ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
790*0ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration */
791*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
792*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
793*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
794*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
795*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
796*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
797*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
798*0ade8cd8SKonstantin Porotchkin 
799*0ade8cd8SKonstantin Porotchkin 	ret = mvebu_cp110_comphy_is_pll_locked(comphy_base, comphy_index);
800*0ade8cd8SKonstantin Porotchkin 	if (ret)
801*0ade8cd8SKonstantin Porotchkin 		return ret;
802*0ade8cd8SKonstantin Porotchkin 
803*0ade8cd8SKonstantin Porotchkin 	/* RX init */
804*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
805*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
806*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
807*0ade8cd8SKonstantin Porotchkin 
808*0ade8cd8SKonstantin Porotchkin 	/* check that RX init done */
809*0ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
810*0ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
811*0ade8cd8SKonstantin Porotchkin 	mask = data;
812*0ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
813*0ade8cd8SKonstantin Porotchkin 	if (data != 0) {
814*0ade8cd8SKonstantin Porotchkin 		ERROR("RX init failed\n");
815*0ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
816*0ade8cd8SKonstantin Porotchkin 	}
817*0ade8cd8SKonstantin Porotchkin 
818*0ade8cd8SKonstantin Porotchkin 	debug("stage: RF Reset\n");
819*0ade8cd8SKonstantin Porotchkin 	/* RF Reset */
820*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
821*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
822*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
823*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
824*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
825*0ade8cd8SKonstantin Porotchkin 
826*0ade8cd8SKonstantin Porotchkin 	debug_exit();
827*0ade8cd8SKonstantin Porotchkin 
828*0ade8cd8SKonstantin Porotchkin 	return ret;
829*0ade8cd8SKonstantin Porotchkin }
830*0ade8cd8SKonstantin Porotchkin 
831*0ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base,
832*0ade8cd8SKonstantin Porotchkin 					   uint8_t comphy_index,
833*0ade8cd8SKonstantin Porotchkin 					   uint32_t comphy_mode)
834*0ade8cd8SKonstantin Porotchkin {
835*0ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
836*0ade8cd8SKonstantin Porotchkin 	uint32_t mask, data, speed = COMPHY_GET_SPEED(comphy_mode);
837*0ade8cd8SKonstantin Porotchkin 	int ret = 0;
838*0ade8cd8SKonstantin Porotchkin 
839*0ade8cd8SKonstantin Porotchkin 	debug_enter();
840*0ade8cd8SKonstantin Porotchkin 
841*0ade8cd8SKonstantin Porotchkin 	if ((speed != COMPHY_SPEED_5_15625G) &&
842*0ade8cd8SKonstantin Porotchkin 	     (speed != COMPHY_SPEED_10_3125G) &&
843*0ade8cd8SKonstantin Porotchkin 	     (speed != COMPHY_SPEED_DEFAULT)) {
844*0ade8cd8SKonstantin Porotchkin 		ERROR("comphy:%d: unsupported sfi/xfi speed\n", comphy_index);
845*0ade8cd8SKonstantin Porotchkin 		return -EINVAL;
846*0ade8cd8SKonstantin Porotchkin 	}
847*0ade8cd8SKonstantin Porotchkin 
848*0ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
849*0ade8cd8SKonstantin Porotchkin 				comphy_index);
850*0ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
851*0ade8cd8SKonstantin Porotchkin 			     comphy_index);
852*0ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
853*0ade8cd8SKonstantin Porotchkin 
854*0ade8cd8SKonstantin Porotchkin 	/* configure phy selector for XFI/SFI */
855*0ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
856*0ade8cd8SKonstantin Porotchkin 					    comphy_mode);
857*0ade8cd8SKonstantin Porotchkin 
858*0ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
859*0ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
860*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
861*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
862*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
863*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
864*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
865*0ade8cd8SKonstantin Porotchkin 
866*0ade8cd8SKonstantin Porotchkin 	/* Make sure that 40 data bits is disabled
867*0ade8cd8SKonstantin Porotchkin 	 * This bit is not cleared by reset
868*0ade8cd8SKonstantin Porotchkin 	 */
869*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
870*0ade8cd8SKonstantin Porotchkin 	data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
871*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
872*0ade8cd8SKonstantin Porotchkin 
873*0ade8cd8SKonstantin Porotchkin 	/* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
874*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
875*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
876*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
877*0ade8cd8SKonstantin Porotchkin 	data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
878*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
879*0ade8cd8SKonstantin Porotchkin 	data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
880*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
881*0ade8cd8SKonstantin Porotchkin 	data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
882*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
883*0ade8cd8SKonstantin Porotchkin 	data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
884*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
885*0ade8cd8SKonstantin Porotchkin 	data |= 0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
886*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
887*0ade8cd8SKonstantin Porotchkin 
888*0ade8cd8SKonstantin Porotchkin 	/* release from hard reset */
889*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
890*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
891*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
892*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
893*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
894*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
895*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
896*0ade8cd8SKonstantin Porotchkin 
897*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
898*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
899*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
900*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
901*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
902*0ade8cd8SKonstantin Porotchkin 
903*0ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
904*0ade8cd8SKonstantin Porotchkin 	mdelay(1);
905*0ade8cd8SKonstantin Porotchkin 
906*0ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
907*0ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
908*0ade8cd8SKonstantin Porotchkin 	/* set reference clock */
909*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_MISC_ICP_FORCE_MASK;
910*0ade8cd8SKonstantin Porotchkin 	data = (speed == COMPHY_SPEED_5_15625G) ?
911*0ade8cd8SKonstantin Porotchkin 		(0x0 << HPIPE_MISC_ICP_FORCE_OFFSET) :
912*0ade8cd8SKonstantin Porotchkin 		(0x1 << HPIPE_MISC_ICP_FORCE_OFFSET);
913*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_MISC_REFCLK_SEL_MASK;
914*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
915*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
916*0ade8cd8SKonstantin Porotchkin 	/* Power and PLL Control */
917*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
918*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
919*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
920*0ade8cd8SKonstantin Porotchkin 	data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
921*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
922*0ade8cd8SKonstantin Porotchkin 	/* Loopback register */
923*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_LOOPBACK_SEL_MASK;
924*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
925*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
926*0ade8cd8SKonstantin Porotchkin 	/* rx control 1 */
927*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
928*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
929*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
930*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
931*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
932*0ade8cd8SKonstantin Porotchkin 	/* DTL Control */
933*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
934*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
935*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
936*0ade8cd8SKonstantin Porotchkin 
937*0ade8cd8SKonstantin Porotchkin 	/* Transmitter/Receiver Speed Divider Force */
938*0ade8cd8SKonstantin Porotchkin 	if (speed == COMPHY_SPEED_5_15625G) {
939*0ade8cd8SKonstantin Porotchkin 		mask = HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_MASK;
940*0ade8cd8SKonstantin Porotchkin 		data = 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET;
941*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_MASK;
942*0ade8cd8SKonstantin Porotchkin 		data |= 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET;
943*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_MASK;
944*0ade8cd8SKonstantin Porotchkin 		data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET;
945*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_MASK;
946*0ade8cd8SKonstantin Porotchkin 		data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET;
947*0ade8cd8SKonstantin Porotchkin 	} else {
948*0ade8cd8SKonstantin Porotchkin 		mask = HPIPE_TXDIGCK_DIV_FORCE_MASK;
949*0ade8cd8SKonstantin Porotchkin 		data = 0x1 << HPIPE_TXDIGCK_DIV_FORCE_OFFSET;
950*0ade8cd8SKonstantin Porotchkin 	}
951*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SPD_DIV_FORCE_REG, data, mask);
952*0ade8cd8SKonstantin Porotchkin 
953*0ade8cd8SKonstantin Porotchkin 	/* Set analog parameters from ETP(HW) */
954*0ade8cd8SKonstantin Porotchkin 	debug("stage: Analog parameters from ETP(HW)\n");
955*0ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration 2 */
956*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK;
957*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET;
958*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
959*0ade8cd8SKonstantin Porotchkin 	/* 0x7-DFE Resolution control */
960*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_RES_FORCE_MASK;
961*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
962*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
963*0ade8cd8SKonstantin Porotchkin 	/* 0xd-G1_Setting_0 */
964*0ade8cd8SKonstantin Porotchkin 	if (speed == COMPHY_SPEED_5_15625G) {
965*0ade8cd8SKonstantin Porotchkin 		mask = HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
966*0ade8cd8SKonstantin Porotchkin 		data = 0x6 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
967*0ade8cd8SKonstantin Porotchkin 	} else {
968*0ade8cd8SKonstantin Porotchkin 		mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
969*0ade8cd8SKonstantin Porotchkin 		data = 0x1c << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
970*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
971*0ade8cd8SKonstantin Porotchkin 		data |= 0xe << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
972*0ade8cd8SKonstantin Porotchkin 	}
973*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
974*0ade8cd8SKonstantin Porotchkin 	/* Genration 1 setting 2 (G1_Setting_2) */
975*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
976*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
977*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
978*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
979*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
980*0ade8cd8SKonstantin Porotchkin 	/* Transmitter Slew Rate Control register (tx_reg1) */
981*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_REG1_TX_EMPH_RES_MASK;
982*0ade8cd8SKonstantin Porotchkin 	data = 0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET;
983*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_REG1_SLC_EN_MASK;
984*0ade8cd8SKonstantin Porotchkin 	data |= 0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET;
985*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_REG1_REG, data, mask);
986*0ade8cd8SKonstantin Porotchkin 	/* Impedance Calibration Control register (cal_reg1) */
987*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CAL_REG_1_EXT_TXIMP_MASK;
988*0ade8cd8SKonstantin Porotchkin 	data = 0xe << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
989*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK;
990*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET;
991*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_CAL_REG1_REG, data, mask);
992*0ade8cd8SKonstantin Porotchkin 	/* Generation 1 Setting 5 (g1_setting_5) */
993*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTING_5_G1_ICP_MASK;
994*0ade8cd8SKonstantin Porotchkin 	data = 0 << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
995*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SETTING_5_REG, data, mask);
996*0ade8cd8SKonstantin Porotchkin 
997*0ade8cd8SKonstantin Porotchkin 	/* 0xE-G1_Setting_1 */
998*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
999*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
1000*0ade8cd8SKonstantin Porotchkin 	if (speed == COMPHY_SPEED_5_15625G) {
1001*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
1002*0ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
1003*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
1004*0ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
1005*0ade8cd8SKonstantin Porotchkin 	} else {
1006*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
1007*0ade8cd8SKonstantin Porotchkin 		data |= 0x2 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
1008*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
1009*0ade8cd8SKonstantin Porotchkin 		data |= 0x2 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
1010*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
1011*0ade8cd8SKonstantin Porotchkin 		data |= 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
1012*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
1013*0ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
1014*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
1015*0ade8cd8SKonstantin Porotchkin 		data |= 0x3 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
1016*0ade8cd8SKonstantin Porotchkin 	}
1017*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
1018*0ade8cd8SKonstantin Porotchkin 
1019*0ade8cd8SKonstantin Porotchkin 	/* 0xA-DFE_Reg3 */
1020*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
1021*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
1022*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
1023*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
1024*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
1025*0ade8cd8SKonstantin Porotchkin 
1026*0ade8cd8SKonstantin Porotchkin 	/* 0x111-G1_Setting_4 */
1027*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1028*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1029*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
1030*0ade8cd8SKonstantin Porotchkin 	/* Genration 1 setting 3 (G1_Setting_3) */
1031*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK;
1032*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET;
1033*0ade8cd8SKonstantin Porotchkin 	if (speed == COMPHY_SPEED_5_15625G) {
1034*0ade8cd8SKonstantin Porotchkin 		/* Force FFE (Feed Forward Equalization) to 5G */
1035*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
1036*0ade8cd8SKonstantin Porotchkin 		data |= 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
1037*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
1038*0ade8cd8SKonstantin Porotchkin 		data |= 0x4 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
1039*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
1040*0ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
1041*0ade8cd8SKonstantin Porotchkin 	}
1042*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
1043*0ade8cd8SKonstantin Porotchkin 
1044*0ade8cd8SKonstantin Porotchkin 	/* Connfigure RX training timer */
1045*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RX_TRAIN_TIMER_MASK;
1046*0ade8cd8SKonstantin Porotchkin 	data = 0x13 << HPIPE_RX_TRAIN_TIMER_OFFSET;
1047*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
1048*0ade8cd8SKonstantin Porotchkin 
1049*0ade8cd8SKonstantin Porotchkin 	/* Enable TX train peak to peak hold */
1050*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
1051*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
1052*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
1053*0ade8cd8SKonstantin Porotchkin 
1054*0ade8cd8SKonstantin Porotchkin 	/* Configure TX preset index */
1055*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_PRESET_INDEX_MASK;
1056*0ade8cd8SKonstantin Porotchkin 	data = 0x2 << HPIPE_TX_PRESET_INDEX_OFFSET;
1057*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_PRESET_INDEX_REG, data, mask);
1058*0ade8cd8SKonstantin Porotchkin 
1059*0ade8cd8SKonstantin Porotchkin 	/* Disable pattern lock lost timeout */
1060*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
1061*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
1062*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
1063*0ade8cd8SKonstantin Porotchkin 
1064*0ade8cd8SKonstantin Porotchkin 	/* Configure TX training pattern and TX training 16bit auto */
1065*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_16BIT_AUTO_EN_MASK;
1066*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET;
1067*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_PAT_SEL_MASK;
1068*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_TX_TRAIN_PAT_SEL_OFFSET;
1069*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
1070*0ade8cd8SKonstantin Porotchkin 
1071*0ade8cd8SKonstantin Porotchkin 	/* Configure Training patten number */
1072*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TRAIN_PAT_NUM_MASK;
1073*0ade8cd8SKonstantin Porotchkin 	data = 0x88 << HPIPE_TRAIN_PAT_NUM_OFFSET;
1074*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_0_REG, data, mask);
1075*0ade8cd8SKonstantin Porotchkin 
1076*0ade8cd8SKonstantin Porotchkin 	/* Configure differencial manchester encoter to ethernet mode */
1077*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DME_ETHERNET_MODE_MASK;
1078*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_DME_ETHERNET_MODE_OFFSET;
1079*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DME_REG, data, mask);
1080*0ade8cd8SKonstantin Porotchkin 
1081*0ade8cd8SKonstantin Porotchkin 	/* Configure VDD Continuous Calibration */
1082*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CAL_VDD_CONT_MODE_MASK;
1083*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_CAL_VDD_CONT_MODE_OFFSET;
1084*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_VDD_CAL_0_REG, data, mask);
1085*0ade8cd8SKonstantin Porotchkin 
1086*0ade8cd8SKonstantin Porotchkin 	/* Trigger sampler enable pulse (by toggleing the bit) */
1087*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RX_SAMPLER_OS_GAIN_MASK;
1088*0ade8cd8SKonstantin Porotchkin 	data = 0x3 << HPIPE_RX_SAMPLER_OS_GAIN_OFFSET;
1089*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_SMAPLER_MASK;
1090*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_SMAPLER_OFFSET;
1091*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1092*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_SMAPLER_MASK;
1093*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_SMAPLER_OFFSET;
1094*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1095*0ade8cd8SKonstantin Porotchkin 
1096*0ade8cd8SKonstantin Porotchkin 	/* Set External RX Regulator Control */
1097*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
1098*0ade8cd8SKonstantin Porotchkin 	data = 0x1A << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
1099*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
1100*0ade8cd8SKonstantin Porotchkin 
1101*0ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
1102*0ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration */
1103*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1104*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1105*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1106*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1107*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1108*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1109*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1110*0ade8cd8SKonstantin Porotchkin 
1111*0ade8cd8SKonstantin Porotchkin 	/* check PLL rx & tx ready */
1112*0ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1113*0ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
1114*0ade8cd8SKonstantin Porotchkin 	       SD_EXTERNAL_STATUS0_PLL_TX_MASK;
1115*0ade8cd8SKonstantin Porotchkin 	mask = data;
1116*0ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask,
1117*0ade8cd8SKonstantin Porotchkin 				    PLL_LOCK_TIMEOUT, REG_32BIT);
1118*0ade8cd8SKonstantin Porotchkin 	if (data != 0) {
1119*0ade8cd8SKonstantin Porotchkin 		if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
1120*0ade8cd8SKonstantin Porotchkin 			ERROR("RX PLL is not locked\n");
1121*0ade8cd8SKonstantin Porotchkin 		if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
1122*0ade8cd8SKonstantin Porotchkin 			ERROR("TX PLL is not locked\n");
1123*0ade8cd8SKonstantin Porotchkin 
1124*0ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
1125*0ade8cd8SKonstantin Porotchkin 	}
1126*0ade8cd8SKonstantin Porotchkin 
1127*0ade8cd8SKonstantin Porotchkin 	/* RX init */
1128*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1129*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1130*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1131*0ade8cd8SKonstantin Porotchkin 
1132*0ade8cd8SKonstantin Porotchkin 	/* check that RX init done */
1133*0ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1134*0ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
1135*0ade8cd8SKonstantin Porotchkin 	mask = data;
1136*0ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
1137*0ade8cd8SKonstantin Porotchkin 	if (data != 0) {
1138*0ade8cd8SKonstantin Porotchkin 		ERROR("RX init failed\n");
1139*0ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
1140*0ade8cd8SKonstantin Porotchkin 	}
1141*0ade8cd8SKonstantin Porotchkin 
1142*0ade8cd8SKonstantin Porotchkin 	debug("stage: RF Reset\n");
1143*0ade8cd8SKonstantin Porotchkin 	/* RF Reset */
1144*0ade8cd8SKonstantin Porotchkin 	mask =  SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1145*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1146*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1147*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1148*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1149*0ade8cd8SKonstantin Porotchkin 
1150*0ade8cd8SKonstantin Porotchkin 	debug_exit();
1151*0ade8cd8SKonstantin Porotchkin 
1152*0ade8cd8SKonstantin Porotchkin 	return ret;
1153*0ade8cd8SKonstantin Porotchkin }
1154*0ade8cd8SKonstantin Porotchkin 
1155*0ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_pcie_power_on(uint64_t comphy_base,
1156*0ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
1157*0ade8cd8SKonstantin Porotchkin {
1158*0ade8cd8SKonstantin Porotchkin 	int ret = 0;
1159*0ade8cd8SKonstantin Porotchkin 	uint32_t reg, mask, data, pcie_width;
1160*0ade8cd8SKonstantin Porotchkin 	uint32_t clk_dir;
1161*0ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, comphy_addr, addr;
1162*0ade8cd8SKonstantin Porotchkin 	_Bool clk_src = COMPHY_GET_CLK_SRC(comphy_mode);
1163*0ade8cd8SKonstantin Porotchkin 
1164*0ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1165*0ade8cd8SKonstantin Porotchkin 				comphy_index);
1166*0ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1167*0ade8cd8SKonstantin Porotchkin 	pcie_width = COMPHY_GET_PCIE_WIDTH(comphy_mode);
1168*0ade8cd8SKonstantin Porotchkin 
1169*0ade8cd8SKonstantin Porotchkin 	debug_enter();
1170*0ade8cd8SKonstantin Porotchkin 
1171*0ade8cd8SKonstantin Porotchkin 	spin_lock(&cp110_mac_reset_lock);
1172*0ade8cd8SKonstantin Porotchkin 
1173*0ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
1174*0ade8cd8SKonstantin Porotchkin 						SYS_CTRL_UINIT_SOFT_RESET_REG);
1175*0ade8cd8SKonstantin Porotchkin 	switch (comphy_index) {
1176*0ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE0:
1177*0ade8cd8SKonstantin Porotchkin 		reg |= PCIE_MAC_RESET_MASK_PORT0;
1178*0ade8cd8SKonstantin Porotchkin 		break;
1179*0ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE4:
1180*0ade8cd8SKonstantin Porotchkin 		reg |= PCIE_MAC_RESET_MASK_PORT1;
1181*0ade8cd8SKonstantin Porotchkin 		break;
1182*0ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE5:
1183*0ade8cd8SKonstantin Porotchkin 		reg |= PCIE_MAC_RESET_MASK_PORT2;
1184*0ade8cd8SKonstantin Porotchkin 		break;
1185*0ade8cd8SKonstantin Porotchkin 	}
1186*0ade8cd8SKonstantin Porotchkin 
1187*0ade8cd8SKonstantin Porotchkin 	mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
1188*0ade8cd8SKonstantin Porotchkin 					    SYS_CTRL_UINIT_SOFT_RESET_REG, reg);
1189*0ade8cd8SKonstantin Porotchkin 	spin_unlock(&cp110_mac_reset_lock);
1190*0ade8cd8SKonstantin Porotchkin 
1191*0ade8cd8SKonstantin Porotchkin 	/* Configure PIPE selector for PCIE */
1192*0ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
1193*0ade8cd8SKonstantin Porotchkin 					     comphy_mode);
1194*0ade8cd8SKonstantin Porotchkin 
1195*0ade8cd8SKonstantin Porotchkin 	/*
1196*0ade8cd8SKonstantin Porotchkin 	 * Read SAR (Sample-At-Reset) configuration for the PCIe clock
1197*0ade8cd8SKonstantin Porotchkin 	 * direction.
1198*0ade8cd8SKonstantin Porotchkin 	 *
1199*0ade8cd8SKonstantin Porotchkin 	 * SerDes Lane 4/5 got the PCIe ref-clock #1,
1200*0ade8cd8SKonstantin Porotchkin 	 * and SerDes Lane 0 got PCIe ref-clock #0
1201*0ade8cd8SKonstantin Porotchkin 	 */
1202*0ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(DFX_FROM_COMPHY_ADDR(comphy_base) +
1203*0ade8cd8SKonstantin Porotchkin 			   SAR_STATUS_0_REG);
1204*0ade8cd8SKonstantin Porotchkin 	if (comphy_index == COMPHY_LANE4 || comphy_index == COMPHY_LANE5)
1205*0ade8cd8SKonstantin Porotchkin 		clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK) >>
1206*0ade8cd8SKonstantin Porotchkin 					  SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET;
1207*0ade8cd8SKonstantin Porotchkin 	else
1208*0ade8cd8SKonstantin Porotchkin 		clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK) >>
1209*0ade8cd8SKonstantin Porotchkin 					  SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET;
1210*0ade8cd8SKonstantin Porotchkin 
1211*0ade8cd8SKonstantin Porotchkin 	debug("On lane %d\n", comphy_index);
1212*0ade8cd8SKonstantin Porotchkin 	debug("PCIe clock direction = %x\n", clk_dir);
1213*0ade8cd8SKonstantin Porotchkin 	debug("PCIe Width = %d\n", pcie_width);
1214*0ade8cd8SKonstantin Porotchkin 
1215*0ade8cd8SKonstantin Porotchkin 	/* enable PCIe X4 and X2 */
1216*0ade8cd8SKonstantin Porotchkin 	if (comphy_index == COMPHY_LANE0) {
1217*0ade8cd8SKonstantin Porotchkin 		if (pcie_width == PCIE_LNK_X4) {
1218*0ade8cd8SKonstantin Porotchkin 			data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET;
1219*0ade8cd8SKonstantin Porotchkin 			mask = COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK;
1220*0ade8cd8SKonstantin Porotchkin 			reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1221*0ade8cd8SKonstantin Porotchkin 				data, mask);
1222*0ade8cd8SKonstantin Porotchkin 		} else if (pcie_width == PCIE_LNK_X2) {
1223*0ade8cd8SKonstantin Porotchkin 			data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET;
1224*0ade8cd8SKonstantin Porotchkin 			mask = COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK;
1225*0ade8cd8SKonstantin Porotchkin 			reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
1226*0ade8cd8SKonstantin Porotchkin 		}
1227*0ade8cd8SKonstantin Porotchkin 	}
1228*0ade8cd8SKonstantin Porotchkin 
1229*0ade8cd8SKonstantin Porotchkin 	/* If PCIe clock is output and clock source from SerDes lane 5,
1230*0ade8cd8SKonstantin Porotchkin 	 * need to configure the clock-source MUX.
1231*0ade8cd8SKonstantin Porotchkin 	 * By default, the clock source is from lane 4
1232*0ade8cd8SKonstantin Porotchkin 	 */
1233*0ade8cd8SKonstantin Porotchkin 	if (clk_dir && clk_src && (comphy_index == COMPHY_LANE5)) {
1234*0ade8cd8SKonstantin Porotchkin 		data = DFX_DEV_GEN_PCIE_CLK_SRC_MUX <<
1235*0ade8cd8SKonstantin Porotchkin 						DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET;
1236*0ade8cd8SKonstantin Porotchkin 		mask = DFX_DEV_GEN_PCIE_CLK_SRC_MASK;
1237*0ade8cd8SKonstantin Porotchkin 		reg_set(DFX_FROM_COMPHY_ADDR(comphy_base) +
1238*0ade8cd8SKonstantin Porotchkin 			DFX_DEV_GEN_CTRL12_REG, data, mask);
1239*0ade8cd8SKonstantin Porotchkin 	}
1240*0ade8cd8SKonstantin Porotchkin 
1241*0ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
1242*0ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
1243*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1244*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1245*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1246*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1247*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1248*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1249*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1250*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1251*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_PHY_MODE_MASK;
1252*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET;
1253*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1254*0ade8cd8SKonstantin Porotchkin 
1255*0ade8cd8SKonstantin Porotchkin 	/* release from hard reset */
1256*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1257*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1258*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1259*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1260*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1261*0ade8cd8SKonstantin Porotchkin 
1262*0ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
1263*0ade8cd8SKonstantin Porotchkin 	mdelay(1);
1264*0ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
1265*0ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
1266*0ade8cd8SKonstantin Porotchkin 	/* Set PIPE soft reset */
1267*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
1268*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
1269*0ade8cd8SKonstantin Porotchkin 	/* Set PHY datapath width mode for V0 */
1270*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
1271*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
1272*0ade8cd8SKonstantin Porotchkin 	/* Set Data bus width USB mode for V0 */
1273*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
1274*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
1275*0ade8cd8SKonstantin Porotchkin 	/* Set CORE_CLK output frequency for 250Mhz */
1276*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
1277*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
1278*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
1279*0ade8cd8SKonstantin Porotchkin 	/* Set PLL ready delay for 0x2 */
1280*0ade8cd8SKonstantin Porotchkin 	data = 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET;
1281*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK;
1282*0ade8cd8SKonstantin Porotchkin 	if (pcie_width != PCIE_LNK_X1) {
1283*0ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET;
1284*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK;
1285*0ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET;
1286*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK;
1287*0ade8cd8SKonstantin Porotchkin 	}
1288*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, data, mask);
1289*0ade8cd8SKonstantin Porotchkin 
1290*0ade8cd8SKonstantin Porotchkin 	/* Set PIPE mode interface to PCIe3 - 0x1  & set lane order */
1291*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET;
1292*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CLK_SRC_HI_MODE_PIPE_MASK;
1293*0ade8cd8SKonstantin Porotchkin 	if (pcie_width != PCIE_LNK_X1) {
1294*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_CLK_SRC_HI_LANE_STRT_MASK;
1295*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_CLK_SRC_HI_LANE_MASTER_MASK;
1296*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_CLK_SRC_HI_LANE_BREAK_MASK;
1297*0ade8cd8SKonstantin Porotchkin 		if (comphy_index == 0) {
1298*0ade8cd8SKonstantin Porotchkin 			data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET;
1299*0ade8cd8SKonstantin Porotchkin 			data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET;
1300*0ade8cd8SKonstantin Porotchkin 		} else if (comphy_index == (pcie_width - 1)) {
1301*0ade8cd8SKonstantin Porotchkin 			data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET;
1302*0ade8cd8SKonstantin Porotchkin 		}
1303*0ade8cd8SKonstantin Porotchkin 	}
1304*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_CLK_SRC_HI_REG, data, mask);
1305*0ade8cd8SKonstantin Porotchkin 	/* Config update polarity equalization */
1306*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET;
1307*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CFG_UPDATE_POLARITY_MASK;
1308*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG1_REG, data, mask);
1309*0ade8cd8SKonstantin Porotchkin 	/* Set PIPE version 4 to mode enable */
1310*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET;
1311*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_CTRL_28_PIPE4_MASK;
1312*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_CTRL_28_REG, data, mask);
1313*0ade8cd8SKonstantin Porotchkin 	/* TODO: check if pcie clock is output/input - for bringup use input*/
1314*0ade8cd8SKonstantin Porotchkin 	/* Enable PIN clock 100M_125M */
1315*0ade8cd8SKonstantin Porotchkin 	mask = 0;
1316*0ade8cd8SKonstantin Porotchkin 	data = 0;
1317*0ade8cd8SKonstantin Porotchkin 	/* Only if clock is output, configure the clock-source mux */
1318*0ade8cd8SKonstantin Porotchkin 	if (clk_dir) {
1319*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_MISC_CLK100M_125M_MASK;
1320*0ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET;
1321*0ade8cd8SKonstantin Porotchkin 	}
1322*0ade8cd8SKonstantin Porotchkin 	/* Set PIN_TXDCLK_2X Clock Freq. Selection for outputs 500MHz clock */
1323*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_MISC_TXDCLK_2X_MASK;
1324*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET;
1325*0ade8cd8SKonstantin Porotchkin 	/* Enable 500MHz Clock */
1326*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_MISC_CLK500_EN_MASK;
1327*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET;
1328*0ade8cd8SKonstantin Porotchkin 	if (clk_dir) { /* output */
1329*0ade8cd8SKonstantin Porotchkin 		/* Set reference clock comes from group 1 */
1330*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_MISC_REFCLK_SEL_MASK;
1331*0ade8cd8SKonstantin Porotchkin 		data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
1332*0ade8cd8SKonstantin Porotchkin 	} else {
1333*0ade8cd8SKonstantin Porotchkin 		/* Set reference clock comes from group 2 */
1334*0ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_MISC_REFCLK_SEL_MASK;
1335*0ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET;
1336*0ade8cd8SKonstantin Porotchkin 	}
1337*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_MISC_ICP_FORCE_MASK;
1338*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_MISC_ICP_FORCE_OFFSET;
1339*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
1340*0ade8cd8SKonstantin Porotchkin 	if (clk_dir) { /* output */
1341*0ade8cd8SKonstantin Porotchkin 		/* Set reference frequcency select - 0x2 for 25MHz*/
1342*0ade8cd8SKonstantin Porotchkin 		mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1343*0ade8cd8SKonstantin Porotchkin 		data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1344*0ade8cd8SKonstantin Porotchkin 	} else {
1345*0ade8cd8SKonstantin Porotchkin 		/* Set reference frequcency select - 0x0 for 100MHz*/
1346*0ade8cd8SKonstantin Porotchkin 		mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1347*0ade8cd8SKonstantin Porotchkin 		data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1348*0ade8cd8SKonstantin Porotchkin 	}
1349*0ade8cd8SKonstantin Porotchkin 	/* Set PHY mode to PCIe */
1350*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1351*0ade8cd8SKonstantin Porotchkin 	data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1352*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1353*0ade8cd8SKonstantin Porotchkin 
1354*0ade8cd8SKonstantin Porotchkin 	/* ref clock alignment */
1355*0ade8cd8SKonstantin Porotchkin 	if (pcie_width != PCIE_LNK_X1) {
1356*0ade8cd8SKonstantin Porotchkin 		mask = HPIPE_LANE_ALIGN_OFF_MASK;
1357*0ade8cd8SKonstantin Porotchkin 		data = 0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET;
1358*0ade8cd8SKonstantin Porotchkin 		reg_set(hpipe_addr + HPIPE_LANE_ALIGN_REG, data, mask);
1359*0ade8cd8SKonstantin Porotchkin 	}
1360*0ade8cd8SKonstantin Porotchkin 
1361*0ade8cd8SKonstantin Porotchkin 	/* Set the amount of time spent in the LoZ state - set for 0x7 only if
1362*0ade8cd8SKonstantin Porotchkin 	 * the PCIe clock is output
1363*0ade8cd8SKonstantin Porotchkin 	 */
1364*0ade8cd8SKonstantin Porotchkin 	if (clk_dir)
1365*0ade8cd8SKonstantin Porotchkin 		reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
1366*0ade8cd8SKonstantin Porotchkin 			0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
1367*0ade8cd8SKonstantin Porotchkin 			HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
1368*0ade8cd8SKonstantin Porotchkin 
1369*0ade8cd8SKonstantin Porotchkin 	/* Set Maximal PHY Generation Setting(8Gbps) */
1370*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_INTERFACE_GEN_MAX_MASK;
1371*0ade8cd8SKonstantin Porotchkin 	data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET;
1372*0ade8cd8SKonstantin Porotchkin 	/* Bypass frame detection and sync detection for RX DATA */
1373*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_INTERFACE_DET_BYPASS_MASK;
1374*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET;
1375*0ade8cd8SKonstantin Porotchkin 	/* Set Link Train Mode (Tx training control pins are used) */
1376*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK;
1377*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET;
1378*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_INTERFACE_REG, data, mask);
1379*0ade8cd8SKonstantin Porotchkin 
1380*0ade8cd8SKonstantin Porotchkin 	/* Set Idle_sync enable */
1381*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PCIE_IDLE_SYNC_MASK;
1382*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET;
1383*0ade8cd8SKonstantin Porotchkin 	/* Select bits for PCIE Gen3(32bit) */
1384*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PCIE_SEL_BITS_MASK;
1385*0ade8cd8SKonstantin Porotchkin 	data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET;
1386*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PCIE_REG0, data, mask);
1387*0ade8cd8SKonstantin Porotchkin 
1388*0ade8cd8SKonstantin Porotchkin 	/* Enable Tx_adapt_g1 */
1389*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_CTRL_G1_MASK;
1390*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET;
1391*0ade8cd8SKonstantin Porotchkin 	/* Enable Tx_adapt_gn1 */
1392*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK;
1393*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET;
1394*0ade8cd8SKonstantin Porotchkin 	/* Disable Tx_adapt_g0 */
1395*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK;
1396*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
1397*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
1398*0ade8cd8SKonstantin Porotchkin 
1399*0ade8cd8SKonstantin Porotchkin 	/* Set reg_tx_train_chk_init */
1400*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_CHK_INIT_MASK;
1401*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET;
1402*0ade8cd8SKonstantin Porotchkin 	/* Enable TX_COE_FM_PIN_PCIE3_EN */
1403*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK;
1404*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET;
1405*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
1406*0ade8cd8SKonstantin Porotchkin 
1407*0ade8cd8SKonstantin Porotchkin 	debug("stage: TRx training parameters\n");
1408*0ade8cd8SKonstantin Porotchkin 	/* Set Preset sweep configurations */
1409*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TX_STATUS_CHECK_MODE_MASK;
1410*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET;
1411*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_NUM_OF_PRESET_MASK;
1412*0ade8cd8SKonstantin Porotchkin 	data |= 0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET;
1413*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_SWEEP_PRESET_EN_MASK;
1414*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET;
1415*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_11_REG, data, mask);
1416*0ade8cd8SKonstantin Porotchkin 
1417*0ade8cd8SKonstantin Porotchkin 	/* Tx train start configuration */
1418*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_START_SQ_EN_MASK;
1419*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET;
1420*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK;
1421*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET;
1422*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK;
1423*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET;
1424*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK;
1425*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET;
1426*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
1427*0ade8cd8SKonstantin Porotchkin 
1428*0ade8cd8SKonstantin Porotchkin 	/* Enable Tx train P2P */
1429*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
1430*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
1431*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
1432*0ade8cd8SKonstantin Porotchkin 
1433*0ade8cd8SKonstantin Porotchkin 	/* Configure Tx train timeout */
1434*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TRX_TRAIN_TIMER_MASK;
1435*0ade8cd8SKonstantin Porotchkin 	data = 0x17 << HPIPE_TRX_TRAIN_TIMER_OFFSET;
1436*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_4_REG, data, mask);
1437*0ade8cd8SKonstantin Porotchkin 
1438*0ade8cd8SKonstantin Porotchkin 	/* Disable G0/G1/GN1 adaptation */
1439*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_CTRL_G1_MASK | HPIPE_TX_TRAIN_CTRL_GN1_MASK
1440*0ade8cd8SKonstantin Porotchkin 		| HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
1441*0ade8cd8SKonstantin Porotchkin 	data = 0;
1442*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
1443*0ade8cd8SKonstantin Porotchkin 
1444*0ade8cd8SKonstantin Porotchkin 	/* Disable DTL frequency loop */
1445*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
1446*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
1447*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
1448*0ade8cd8SKonstantin Porotchkin 
1449*0ade8cd8SKonstantin Porotchkin 	/* Configure G3 DFE */
1450*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_DFE_RES_MASK;
1451*0ade8cd8SKonstantin Porotchkin 	data = 0x3 << HPIPE_G3_DFE_RES_OFFSET;
1452*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
1453*0ade8cd8SKonstantin Porotchkin 
1454*0ade8cd8SKonstantin Porotchkin 	/* Use TX/RX training result for DFE */
1455*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_RES_FORCE_MASK;
1456*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
1457*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_REG0,  data, mask);
1458*0ade8cd8SKonstantin Porotchkin 
1459*0ade8cd8SKonstantin Porotchkin 	/* Configure initial and final coefficient value for receiver */
1460*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
1461*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
1462*0ade8cd8SKonstantin Porotchkin 
1463*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
1464*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
1465*0ade8cd8SKonstantin Porotchkin 
1466*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
1467*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
1468*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SET_1_REG,  data, mask);
1469*0ade8cd8SKonstantin Porotchkin 
1470*0ade8cd8SKonstantin Porotchkin 	/* Trigger sampler enable pulse */
1471*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_SMAPLER_MASK;
1472*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_SMAPLER_OFFSET;
1473*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
1474*0ade8cd8SKonstantin Porotchkin 	udelay(5);
1475*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, 0, mask);
1476*0ade8cd8SKonstantin Porotchkin 
1477*0ade8cd8SKonstantin Porotchkin 	/* FFE resistor tuning for different bandwidth  */
1478*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
1479*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
1480*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
1481*0ade8cd8SKonstantin Porotchkin 	data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
1482*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
1483*0ade8cd8SKonstantin Porotchkin 
1484*0ade8cd8SKonstantin Porotchkin 	/* Pattern lock lost timeout disable */
1485*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
1486*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
1487*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
1488*0ade8cd8SKonstantin Porotchkin 
1489*0ade8cd8SKonstantin Porotchkin 	/* Configure DFE adaptations */
1490*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK;
1491*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET;
1492*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK;
1493*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET;
1494*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_CDR_MAX_DFE_ADAPT_0_MASK;
1495*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET;
1496*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_CDR_MAX_DFE_ADAPT_1_MASK;
1497*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET;
1498*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
1499*0ade8cd8SKonstantin Porotchkin 
1500*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK;
1501*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET;
1502*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_CONTROL_REG, data, mask);
1503*0ade8cd8SKonstantin Porotchkin 
1504*0ade8cd8SKonstantin Porotchkin 	/* Genration 2 setting 1*/
1505*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
1506*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
1507*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK;
1508*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET;
1509*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
1510*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
1511*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
1512*0ade8cd8SKonstantin Porotchkin 
1513*0ade8cd8SKonstantin Porotchkin 	/* DFE enable */
1514*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G2_DFE_RES_MASK;
1515*0ade8cd8SKonstantin Porotchkin 	data = 0x3 << HPIPE_G2_DFE_RES_OFFSET;
1516*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G2_SETTINGS_4_REG, data, mask);
1517*0ade8cd8SKonstantin Porotchkin 
1518*0ade8cd8SKonstantin Porotchkin 	/* Configure DFE Resolution */
1519*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_LANE_CFG4_DFE_EN_SEL_MASK;
1520*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET;
1521*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
1522*0ade8cd8SKonstantin Porotchkin 
1523*0ade8cd8SKonstantin Porotchkin 	/* VDD calibration control */
1524*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
1525*0ade8cd8SKonstantin Porotchkin 	data = 0x16 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
1526*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
1527*0ade8cd8SKonstantin Porotchkin 
1528*0ade8cd8SKonstantin Porotchkin 	/* Set PLL Charge-pump Current Control */
1529*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_SETTING_5_G3_ICP_MASK;
1530*0ade8cd8SKonstantin Porotchkin 	data = 0x4 << HPIPE_G3_SETTING_5_G3_ICP_OFFSET;
1531*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SETTING_5_REG, data, mask);
1532*0ade8cd8SKonstantin Porotchkin 
1533*0ade8cd8SKonstantin Porotchkin 	/* Set lane rqualization remote setting */
1534*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK;
1535*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET;
1536*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK;
1537*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET;
1538*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK;
1539*0ade8cd8SKonstantin Porotchkin 	data |= 0x6 << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET;
1540*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_EQ_REMOTE_SETTING_REG, data, mask);
1541*0ade8cd8SKonstantin Porotchkin 
1542*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CFG_EQ_BUNDLE_DIS_MASK;
1543*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET;
1544*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG2_REG, data, mask);
1545*0ade8cd8SKonstantin Porotchkin 
1546*0ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy power up\n");
1547*0ade8cd8SKonstantin Porotchkin 
1548*0ade8cd8SKonstantin Porotchkin 	/* For PCIe X4 or X2:
1549*0ade8cd8SKonstantin Porotchkin 	 * release from reset only after finish to configure all lanes
1550*0ade8cd8SKonstantin Porotchkin 	 */
1551*0ade8cd8SKonstantin Porotchkin 	if ((pcie_width == PCIE_LNK_X1) || (comphy_index == (pcie_width - 1))) {
1552*0ade8cd8SKonstantin Porotchkin 		uint32_t i, start_lane, end_lane;
1553*0ade8cd8SKonstantin Porotchkin 
1554*0ade8cd8SKonstantin Porotchkin 		if (pcie_width != PCIE_LNK_X1) {
1555*0ade8cd8SKonstantin Porotchkin 			/* allows writing to all lanes in one write */
1556*0ade8cd8SKonstantin Porotchkin 			data = 0x0;
1557*0ade8cd8SKonstantin Porotchkin 			if (pcie_width == PCIE_LNK_X2)
1558*0ade8cd8SKonstantin Porotchkin 				mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
1559*0ade8cd8SKonstantin Porotchkin 			else if (pcie_width == PCIE_LNK_X4)
1560*0ade8cd8SKonstantin Porotchkin 				mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
1561*0ade8cd8SKonstantin Porotchkin 			reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
1562*0ade8cd8SKonstantin Porotchkin 			start_lane = 0;
1563*0ade8cd8SKonstantin Porotchkin 			end_lane = pcie_width;
1564*0ade8cd8SKonstantin Porotchkin 
1565*0ade8cd8SKonstantin Porotchkin 			/* Release from PIPE soft reset
1566*0ade8cd8SKonstantin Porotchkin 			 * For PCIe by4 or by2:
1567*0ade8cd8SKonstantin Porotchkin 			 * release from soft reset all lanes - can't use
1568*0ade8cd8SKonstantin Porotchkin 			 * read modify write
1569*0ade8cd8SKonstantin Porotchkin 			 */
1570*0ade8cd8SKonstantin Porotchkin 			reg_set(HPIPE_ADDR(
1571*0ade8cd8SKonstantin Porotchkin 				COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), 0) +
1572*0ade8cd8SKonstantin Porotchkin 				HPIPE_RST_CLK_CTRL_REG, 0x24, 0xffffffff);
1573*0ade8cd8SKonstantin Porotchkin 		} else {
1574*0ade8cd8SKonstantin Porotchkin 			start_lane = comphy_index;
1575*0ade8cd8SKonstantin Porotchkin 			end_lane = comphy_index + 1;
1576*0ade8cd8SKonstantin Porotchkin 
1577*0ade8cd8SKonstantin Porotchkin 			/* Release from PIPE soft reset
1578*0ade8cd8SKonstantin Porotchkin 			 * for PCIe by4 or by2:
1579*0ade8cd8SKonstantin Porotchkin 			 * release from soft reset all lanes
1580*0ade8cd8SKonstantin Porotchkin 			 */
1581*0ade8cd8SKonstantin Porotchkin 			reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
1582*0ade8cd8SKonstantin Porotchkin 				0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
1583*0ade8cd8SKonstantin Porotchkin 				HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
1584*0ade8cd8SKonstantin Porotchkin 		}
1585*0ade8cd8SKonstantin Porotchkin 
1586*0ade8cd8SKonstantin Porotchkin 		if (pcie_width != PCIE_LNK_X1) {
1587*0ade8cd8SKonstantin Porotchkin 			/* disable writing to all lanes with one write */
1588*0ade8cd8SKonstantin Porotchkin 			if (pcie_width == PCIE_LNK_X2) {
1589*0ade8cd8SKonstantin Porotchkin 				data = (COMPHY_LANE0 <<
1590*0ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
1591*0ade8cd8SKonstantin Porotchkin 				(COMPHY_LANE1 <<
1592*0ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET);
1593*0ade8cd8SKonstantin Porotchkin 				mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
1594*0ade8cd8SKonstantin Porotchkin 			} else if (pcie_width == PCIE_LNK_X4) {
1595*0ade8cd8SKonstantin Porotchkin 				data = (COMPHY_LANE0 <<
1596*0ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
1597*0ade8cd8SKonstantin Porotchkin 				(COMPHY_LANE1 <<
1598*0ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET) |
1599*0ade8cd8SKonstantin Porotchkin 				(COMPHY_LANE2 <<
1600*0ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_2_PORT_OFFSET) |
1601*0ade8cd8SKonstantin Porotchkin 				(COMPHY_LANE3 <<
1602*0ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_3_PORT_OFFSET);
1603*0ade8cd8SKonstantin Porotchkin 				mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
1604*0ade8cd8SKonstantin Porotchkin 			}
1605*0ade8cd8SKonstantin Porotchkin 			reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1606*0ade8cd8SKonstantin Porotchkin 				data, mask);
1607*0ade8cd8SKonstantin Porotchkin 		}
1608*0ade8cd8SKonstantin Porotchkin 
1609*0ade8cd8SKonstantin Porotchkin 		debug("stage: Check PLL\n");
1610*0ade8cd8SKonstantin Porotchkin 		/* Read lane status */
1611*0ade8cd8SKonstantin Porotchkin 		for (i = start_lane; i < end_lane; i++) {
1612*0ade8cd8SKonstantin Porotchkin 			addr = HPIPE_ADDR(
1613*0ade8cd8SKonstantin Porotchkin 				COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), i) +
1614*0ade8cd8SKonstantin Porotchkin 				HPIPE_LANE_STATUS1_REG;
1615*0ade8cd8SKonstantin Porotchkin 			data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
1616*0ade8cd8SKonstantin Porotchkin 			mask = data;
1617*0ade8cd8SKonstantin Porotchkin 			ret = polling_with_timeout(addr, data, mask,
1618*0ade8cd8SKonstantin Porotchkin 						   PLL_LOCK_TIMEOUT,
1619*0ade8cd8SKonstantin Porotchkin 						   REG_32BIT);
1620*0ade8cd8SKonstantin Porotchkin 			if (ret)
1621*0ade8cd8SKonstantin Porotchkin 				ERROR("Failed to lock PCIE PLL\n");
1622*0ade8cd8SKonstantin Porotchkin 		}
1623*0ade8cd8SKonstantin Porotchkin 	}
1624*0ade8cd8SKonstantin Porotchkin 
1625*0ade8cd8SKonstantin Porotchkin 	debug_exit();
1626*0ade8cd8SKonstantin Porotchkin 
1627*0ade8cd8SKonstantin Porotchkin 	return ret;
1628*0ade8cd8SKonstantin Porotchkin }
1629*0ade8cd8SKonstantin Porotchkin 
1630*0ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_rxaui_power_on(uint64_t comphy_base,
1631*0ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
1632*0ade8cd8SKonstantin Porotchkin {
1633*0ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
1634*0ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
1635*0ade8cd8SKonstantin Porotchkin 	int ret = 0;
1636*0ade8cd8SKonstantin Porotchkin 
1637*0ade8cd8SKonstantin Porotchkin 	debug_enter();
1638*0ade8cd8SKonstantin Porotchkin 
1639*0ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1640*0ade8cd8SKonstantin Porotchkin 				comphy_index);
1641*0ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1642*0ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1643*0ade8cd8SKonstantin Porotchkin 			     comphy_index);
1644*0ade8cd8SKonstantin Porotchkin 
1645*0ade8cd8SKonstantin Porotchkin 	/* configure phy selector for RXAUI */
1646*0ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
1647*0ade8cd8SKonstantin Porotchkin 					    comphy_mode);
1648*0ade8cd8SKonstantin Porotchkin 
1649*0ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
1650*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1651*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1652*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1653*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1654*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1655*0ade8cd8SKonstantin Porotchkin 
1656*0ade8cd8SKonstantin Porotchkin 	if (comphy_index == 2) {
1657*0ade8cd8SKonstantin Porotchkin 		reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1658*0ade8cd8SKonstantin Porotchkin 			0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET,
1659*0ade8cd8SKonstantin Porotchkin 			COMMON_PHY_SD_CTRL1_RXAUI0_MASK);
1660*0ade8cd8SKonstantin Porotchkin 	}
1661*0ade8cd8SKonstantin Porotchkin 	if (comphy_index == 4) {
1662*0ade8cd8SKonstantin Porotchkin 		reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
1663*0ade8cd8SKonstantin Porotchkin 			0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET,
1664*0ade8cd8SKonstantin Porotchkin 			COMMON_PHY_SD_CTRL1_RXAUI1_MASK);
1665*0ade8cd8SKonstantin Porotchkin 	}
1666*0ade8cd8SKonstantin Porotchkin 
1667*0ade8cd8SKonstantin Porotchkin 	/* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
1668*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1669*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1670*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
1671*0ade8cd8SKonstantin Porotchkin 	data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
1672*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
1673*0ade8cd8SKonstantin Porotchkin 	data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
1674*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1675*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1676*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1677*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1678*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
1679*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
1680*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK;
1681*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET;
1682*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1683*0ade8cd8SKonstantin Porotchkin 
1684*0ade8cd8SKonstantin Porotchkin 	/* release from hard reset */
1685*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
1686*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
1687*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
1688*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
1689*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1690*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1691*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1692*0ade8cd8SKonstantin Porotchkin 
1693*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
1694*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
1695*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
1696*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
1697*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1698*0ade8cd8SKonstantin Porotchkin 
1699*0ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
1700*0ade8cd8SKonstantin Porotchkin 	mdelay(1);
1701*0ade8cd8SKonstantin Porotchkin 
1702*0ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
1703*0ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
1704*0ade8cd8SKonstantin Porotchkin 	/* set reference clock */
1705*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG,
1706*0ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
1707*0ade8cd8SKonstantin Porotchkin 		HPIPE_MISC_REFCLK_SEL_MASK);
1708*0ade8cd8SKonstantin Porotchkin 	/* Power and PLL Control */
1709*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1710*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1711*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1712*0ade8cd8SKonstantin Porotchkin 	data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1713*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1714*0ade8cd8SKonstantin Porotchkin 	/* Loopback register */
1715*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
1716*0ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
1717*0ade8cd8SKonstantin Porotchkin 	/* rx control 1 */
1718*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
1719*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
1720*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
1721*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
1722*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
1723*0ade8cd8SKonstantin Porotchkin 	/* DTL Control */
1724*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG,
1725*0ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET,
1726*0ade8cd8SKonstantin Porotchkin 		HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK);
1727*0ade8cd8SKonstantin Porotchkin 
1728*0ade8cd8SKonstantin Porotchkin 	/* Set analog parameters from ETP(HW) */
1729*0ade8cd8SKonstantin Porotchkin 	debug("stage: Analog parameters from ETP(HW)\n");
1730*0ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration 2 */
1731*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG,
1732*0ade8cd8SKonstantin Porotchkin 		0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET,
1733*0ade8cd8SKonstantin Porotchkin 		SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK);
1734*0ade8cd8SKonstantin Porotchkin 	/* 0x7-DFE Resolution control */
1735*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_REG0, 0x1 << HPIPE_DFE_RES_FORCE_OFFSET,
1736*0ade8cd8SKonstantin Porotchkin 		HPIPE_DFE_RES_FORCE_MASK);
1737*0ade8cd8SKonstantin Porotchkin 	/* 0xd-G1_Setting_0 */
1738*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
1739*0ade8cd8SKonstantin Porotchkin 		0xd << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
1740*0ade8cd8SKonstantin Porotchkin 		HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
1741*0ade8cd8SKonstantin Porotchkin 	/* 0xE-G1_Setting_1 */
1742*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
1743*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
1744*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
1745*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
1746*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
1747*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
1748*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
1749*0ade8cd8SKonstantin Porotchkin 	/* 0xA-DFE_Reg3 */
1750*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
1751*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
1752*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
1753*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
1754*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
1755*0ade8cd8SKonstantin Porotchkin 
1756*0ade8cd8SKonstantin Porotchkin 	/* 0x111-G1_Setting_4 */
1757*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
1758*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
1759*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
1760*0ade8cd8SKonstantin Porotchkin 
1761*0ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
1762*0ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration */
1763*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
1764*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
1765*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
1766*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
1767*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
1768*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
1769*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
1770*0ade8cd8SKonstantin Porotchkin 
1771*0ade8cd8SKonstantin Porotchkin 
1772*0ade8cd8SKonstantin Porotchkin 	/* check PLL rx & tx ready */
1773*0ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1774*0ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
1775*0ade8cd8SKonstantin Porotchkin 		SD_EXTERNAL_STATUS0_PLL_TX_MASK;
1776*0ade8cd8SKonstantin Porotchkin 	mask = data;
1777*0ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
1778*0ade8cd8SKonstantin Porotchkin 	if (data != 0) {
1779*0ade8cd8SKonstantin Porotchkin 		debug("Read from reg = %lx - value = 0x%x\n",
1780*0ade8cd8SKonstantin Porotchkin 		      sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
1781*0ade8cd8SKonstantin Porotchkin 		ERROR("SD_EXTERNAL_STATUS0_PLL_RX is %d, -\"-_PLL_TX is %d\n",
1782*0ade8cd8SKonstantin Porotchkin 		      (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK),
1783*0ade8cd8SKonstantin Porotchkin 		      (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK));
1784*0ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
1785*0ade8cd8SKonstantin Porotchkin 	}
1786*0ade8cd8SKonstantin Porotchkin 
1787*0ade8cd8SKonstantin Porotchkin 	/* RX init */
1788*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG,
1789*0ade8cd8SKonstantin Porotchkin 		0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET,
1790*0ade8cd8SKonstantin Porotchkin 		SD_EXTERNAL_CONFIG1_RX_INIT_MASK);
1791*0ade8cd8SKonstantin Porotchkin 
1792*0ade8cd8SKonstantin Porotchkin 	/* check that RX init done */
1793*0ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
1794*0ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
1795*0ade8cd8SKonstantin Porotchkin 	mask = data;
1796*0ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
1797*0ade8cd8SKonstantin Porotchkin 	if (data != 0) {
1798*0ade8cd8SKonstantin Porotchkin 		debug("Read from reg = %lx - value = 0x%x\n",
1799*0ade8cd8SKonstantin Porotchkin 		      sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
1800*0ade8cd8SKonstantin Porotchkin 		ERROR("SD_EXTERNAL_STATUS0_RX_INIT is 0\n");
1801*0ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
1802*0ade8cd8SKonstantin Porotchkin 	}
1803*0ade8cd8SKonstantin Porotchkin 
1804*0ade8cd8SKonstantin Porotchkin 	debug("stage: RF Reset\n");
1805*0ade8cd8SKonstantin Porotchkin 	/* RF Reset */
1806*0ade8cd8SKonstantin Porotchkin 	mask =  SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
1807*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
1808*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
1809*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
1810*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
1811*0ade8cd8SKonstantin Porotchkin 
1812*0ade8cd8SKonstantin Porotchkin 	debug_exit();
1813*0ade8cd8SKonstantin Porotchkin 
1814*0ade8cd8SKonstantin Porotchkin 	return ret;
1815*0ade8cd8SKonstantin Porotchkin }
1816*0ade8cd8SKonstantin Porotchkin 
1817*0ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base,
1818*0ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
1819*0ade8cd8SKonstantin Porotchkin {
1820*0ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, comphy_addr, addr;
1821*0ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
1822*0ade8cd8SKonstantin Porotchkin 	int ret = 0;
1823*0ade8cd8SKonstantin Porotchkin 
1824*0ade8cd8SKonstantin Porotchkin 	debug_enter();
1825*0ade8cd8SKonstantin Porotchkin 
1826*0ade8cd8SKonstantin Porotchkin 	/* Configure PIPE selector for USB3 */
1827*0ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
1828*0ade8cd8SKonstantin Porotchkin 					     comphy_mode);
1829*0ade8cd8SKonstantin Porotchkin 
1830*0ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1831*0ade8cd8SKonstantin Porotchkin 				comphy_index);
1832*0ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
1833*0ade8cd8SKonstantin Porotchkin 
1834*0ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
1835*0ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
1836*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
1837*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
1838*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
1839*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
1840*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1841*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1842*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1843*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1844*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_PHY_MODE_MASK;
1845*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET;
1846*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1847*0ade8cd8SKonstantin Porotchkin 
1848*0ade8cd8SKonstantin Porotchkin 	/* release from hard reset */
1849*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
1850*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
1851*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
1852*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
1853*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
1854*0ade8cd8SKonstantin Porotchkin 
1855*0ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
1856*0ade8cd8SKonstantin Porotchkin 	mdelay(1);
1857*0ade8cd8SKonstantin Porotchkin 
1858*0ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
1859*0ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
1860*0ade8cd8SKonstantin Porotchkin 	/* Set PIPE soft reset */
1861*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
1862*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
1863*0ade8cd8SKonstantin Porotchkin 	/* Set PHY datapath width mode for V0 */
1864*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
1865*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
1866*0ade8cd8SKonstantin Porotchkin 	/* Set Data bus width USB mode for V0 */
1867*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
1868*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
1869*0ade8cd8SKonstantin Porotchkin 	/* Set CORE_CLK output frequency for 250Mhz */
1870*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
1871*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
1872*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
1873*0ade8cd8SKonstantin Porotchkin 	/* Set PLL ready delay for 0x2 */
1874*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG,
1875*0ade8cd8SKonstantin Porotchkin 		0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
1876*0ade8cd8SKonstantin Porotchkin 		HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
1877*0ade8cd8SKonstantin Porotchkin 	/* Set reference clock to come from group 1 - 25Mhz */
1878*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG,
1879*0ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
1880*0ade8cd8SKonstantin Porotchkin 		HPIPE_MISC_REFCLK_SEL_MASK);
1881*0ade8cd8SKonstantin Porotchkin 	/* Set reference frequcency select - 0x2 */
1882*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
1883*0ade8cd8SKonstantin Porotchkin 	data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
1884*0ade8cd8SKonstantin Porotchkin 	/* Set PHY mode to USB - 0x5 */
1885*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
1886*0ade8cd8SKonstantin Porotchkin 	data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
1887*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
1888*0ade8cd8SKonstantin Porotchkin 	/* Set the amount of time spent in the LoZ state - set for 0x7 */
1889*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
1890*0ade8cd8SKonstantin Porotchkin 		0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
1891*0ade8cd8SKonstantin Porotchkin 		HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
1892*0ade8cd8SKonstantin Porotchkin 	/* Set max PHY generation setting - 5Gbps */
1893*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
1894*0ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
1895*0ade8cd8SKonstantin Porotchkin 		HPIPE_INTERFACE_GEN_MAX_MASK);
1896*0ade8cd8SKonstantin Porotchkin 	/* Set select data width 20Bit (SEL_BITS[2:0]) */
1897*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
1898*0ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_LOOPBACK_SEL_OFFSET,
1899*0ade8cd8SKonstantin Porotchkin 		HPIPE_LOOPBACK_SEL_MASK);
1900*0ade8cd8SKonstantin Porotchkin 	/* select de-emphasize 3.5db */
1901*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_CONFIG0_REG,
1902*0ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET,
1903*0ade8cd8SKonstantin Porotchkin 		HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK);
1904*0ade8cd8SKonstantin Porotchkin 	/* override tx margining from the MAC */
1905*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TST_MODE_CTRL_REG,
1906*0ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET,
1907*0ade8cd8SKonstantin Porotchkin 		HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK);
1908*0ade8cd8SKonstantin Porotchkin 
1909*0ade8cd8SKonstantin Porotchkin 	/* Start analog parameters from ETP(HW) */
1910*0ade8cd8SKonstantin Porotchkin 	debug("stage: Analog parameters from ETP(HW)\n");
1911*0ade8cd8SKonstantin Porotchkin 	/* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */
1912*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK;
1913*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET;
1914*0ade8cd8SKonstantin Porotchkin 	/* Set Override PHY DFE control pins for 0x1 */
1915*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK;
1916*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET;
1917*0ade8cd8SKonstantin Porotchkin 	/* Set Spread Spectrum Clock Enable fot 0x1 */
1918*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK;
1919*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET;
1920*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
1921*0ade8cd8SKonstantin Porotchkin 	/* Confifure SSC amplitude */
1922*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G2_TX_SSC_AMP_MASK;
1923*0ade8cd8SKonstantin Porotchkin 	data = 0x1f << HPIPE_G2_TX_SSC_AMP_OFFSET;
1924*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
1925*0ade8cd8SKonstantin Porotchkin 	/* End of analog parameters */
1926*0ade8cd8SKonstantin Porotchkin 
1927*0ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy power up\n");
1928*0ade8cd8SKonstantin Porotchkin 	/* Release from PIPE soft reset */
1929*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
1930*0ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
1931*0ade8cd8SKonstantin Porotchkin 		HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
1932*0ade8cd8SKonstantin Porotchkin 
1933*0ade8cd8SKonstantin Porotchkin 	/* wait 15ms - for comphy calibration done */
1934*0ade8cd8SKonstantin Porotchkin 	debug("stage: Check PLL\n");
1935*0ade8cd8SKonstantin Porotchkin 	/* Read lane status */
1936*0ade8cd8SKonstantin Porotchkin 	addr = hpipe_addr + HPIPE_LANE_STATUS1_REG;
1937*0ade8cd8SKonstantin Porotchkin 	data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
1938*0ade8cd8SKonstantin Porotchkin 	mask = data;
1939*0ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
1940*0ade8cd8SKonstantin Porotchkin 	if (data != 0) {
1941*0ade8cd8SKonstantin Porotchkin 		debug("Read from reg = %lx - value = 0x%x\n",
1942*0ade8cd8SKonstantin Porotchkin 			hpipe_addr + HPIPE_LANE_STATUS1_REG, data);
1943*0ade8cd8SKonstantin Porotchkin 		ERROR("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n");
1944*0ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
1945*0ade8cd8SKonstantin Porotchkin 	}
1946*0ade8cd8SKonstantin Porotchkin 
1947*0ade8cd8SKonstantin Porotchkin 	debug_exit();
1948*0ade8cd8SKonstantin Porotchkin 
1949*0ade8cd8SKonstantin Porotchkin 	return ret;
1950*0ade8cd8SKonstantin Porotchkin }
1951*0ade8cd8SKonstantin Porotchkin 
1952*0ade8cd8SKonstantin Porotchkin /* This function performs RX training for one Feed Forward Equalization (FFE)
1953*0ade8cd8SKonstantin Porotchkin  * value.
1954*0ade8cd8SKonstantin Porotchkin  * The RX traiing result is stored in 'Saved DFE values Register' (SAV_F0D).
1955*0ade8cd8SKonstantin Porotchkin  *
1956*0ade8cd8SKonstantin Porotchkin  * Return '0' on success, error code in  a case of failure.
1957*0ade8cd8SKonstantin Porotchkin  */
1958*0ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_test_single_ffe(uint64_t comphy_base,
1959*0ade8cd8SKonstantin Porotchkin 					      uint8_t comphy_index,
1960*0ade8cd8SKonstantin Porotchkin 					      uint32_t ffe, uint32_t *result)
1961*0ade8cd8SKonstantin Porotchkin {
1962*0ade8cd8SKonstantin Porotchkin 	uint32_t mask, data, timeout;
1963*0ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, sd_ip_addr;
1964*0ade8cd8SKonstantin Porotchkin 
1965*0ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1966*0ade8cd8SKonstantin Porotchkin 				comphy_index);
1967*0ade8cd8SKonstantin Porotchkin 
1968*0ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
1969*0ade8cd8SKonstantin Porotchkin 			     comphy_index);
1970*0ade8cd8SKonstantin Porotchkin 
1971*0ade8cd8SKonstantin Porotchkin 	/* Configure PRBS counters */
1972*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK;
1973*0ade8cd8SKonstantin Porotchkin 	data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET;
1974*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
1975*0ade8cd8SKonstantin Porotchkin 
1976*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PHY_TEST_DATA_MASK;
1977*0ade8cd8SKonstantin Porotchkin 	data = 0x64 << HPIPE_PHY_TEST_DATA_OFFSET;
1978*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask);
1979*0ade8cd8SKonstantin Porotchkin 
1980*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PHY_TEST_EN_MASK;
1981*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET;
1982*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
1983*0ade8cd8SKonstantin Porotchkin 
1984*0ade8cd8SKonstantin Porotchkin 	mdelay(50);
1985*0ade8cd8SKonstantin Porotchkin 
1986*0ade8cd8SKonstantin Porotchkin 	/* Set the FFE value */
1987*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
1988*0ade8cd8SKonstantin Porotchkin 	data = ffe << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
1989*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
1990*0ade8cd8SKonstantin Porotchkin 
1991*0ade8cd8SKonstantin Porotchkin 	/* Start RX training */
1992*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_STATUS_START_RX_TRAINING_MASK;
1993*0ade8cd8SKonstantin Porotchkin 	data = 1 << SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET;
1994*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_STATUS_REG, data, mask);
1995*0ade8cd8SKonstantin Porotchkin 
1996*0ade8cd8SKonstantin Porotchkin 	/* Check the result of RX training */
1997*0ade8cd8SKonstantin Porotchkin 	timeout = RX_TRAINING_TIMEOUT;
1998*0ade8cd8SKonstantin Porotchkin 	while (timeout) {
1999*0ade8cd8SKonstantin Porotchkin 		data = mmio_read_32(sd_ip_addr + SD_EXTERNAL_STATAUS1_REG);
2000*0ade8cd8SKonstantin Porotchkin 		if (data & SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_COMP_MASK)
2001*0ade8cd8SKonstantin Porotchkin 			break;
2002*0ade8cd8SKonstantin Porotchkin 		mdelay(1);
2003*0ade8cd8SKonstantin Porotchkin 		timeout--;
2004*0ade8cd8SKonstantin Porotchkin 	}
2005*0ade8cd8SKonstantin Porotchkin 
2006*0ade8cd8SKonstantin Porotchkin 	if (timeout == 0)
2007*0ade8cd8SKonstantin Porotchkin 		return -ETIMEDOUT;
2008*0ade8cd8SKonstantin Porotchkin 
2009*0ade8cd8SKonstantin Porotchkin 	if (data & SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_FAILED_MASK)
2010*0ade8cd8SKonstantin Porotchkin 		return -EINVAL;
2011*0ade8cd8SKonstantin Porotchkin 
2012*0ade8cd8SKonstantin Porotchkin 	/* Stop RX training */
2013*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_STATUS_START_RX_TRAINING_MASK;
2014*0ade8cd8SKonstantin Porotchkin 	data = 0 << SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET;
2015*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_STATUS_REG, data, mask);
2016*0ade8cd8SKonstantin Porotchkin 
2017*0ade8cd8SKonstantin Porotchkin 	/* Read the result */
2018*0ade8cd8SKonstantin Porotchkin 	data = mmio_read_32(hpipe_addr + HPIPE_SAVED_DFE_VALUES_REG);
2019*0ade8cd8SKonstantin Porotchkin 	data &= HPIPE_SAVED_DFE_VALUES_SAV_F0D_MASK;
2020*0ade8cd8SKonstantin Porotchkin 	data >>= HPIPE_SAVED_DFE_VALUES_SAV_F0D_OFFSET;
2021*0ade8cd8SKonstantin Porotchkin 	*result = data;
2022*0ade8cd8SKonstantin Porotchkin 
2023*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PHY_TEST_RESET_MASK;
2024*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PHY_TEST_RESET_OFFSET;
2025*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PHY_TEST_EN_MASK;
2026*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_PHY_TEST_EN_OFFSET;
2027*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
2028*0ade8cd8SKonstantin Porotchkin 
2029*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PHY_TEST_RESET_MASK;
2030*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_PHY_TEST_RESET_OFFSET;
2031*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
2032*0ade8cd8SKonstantin Porotchkin 
2033*0ade8cd8SKonstantin Porotchkin 	return 0;
2034*0ade8cd8SKonstantin Porotchkin }
2035*0ade8cd8SKonstantin Porotchkin 
2036*0ade8cd8SKonstantin Porotchkin /* This function runs complete RX training sequence:
2037*0ade8cd8SKonstantin Porotchkin  *	- Run RX training for all possible Feed Forward Equalization values
2038*0ade8cd8SKonstantin Porotchkin  *	- Choose the FFE which gives the best result.
2039*0ade8cd8SKonstantin Porotchkin  *	- Run RX training again with the best result.
2040*0ade8cd8SKonstantin Porotchkin  *
2041*0ade8cd8SKonstantin Porotchkin  * Return '0' on success, error code in  a case of failure.
2042*0ade8cd8SKonstantin Porotchkin  */
2043*0ade8cd8SKonstantin Porotchkin int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base,
2044*0ade8cd8SKonstantin Porotchkin 					      uint8_t comphy_index)
2045*0ade8cd8SKonstantin Porotchkin {
2046*0ade8cd8SKonstantin Porotchkin 	uint32_t mask, data, max_rx_train = 0, max_rx_train_index = 0;
2047*0ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr;
2048*0ade8cd8SKonstantin Porotchkin 	uint32_t rx_train_result;
2049*0ade8cd8SKonstantin Porotchkin 	int ret, i;
2050*0ade8cd8SKonstantin Porotchkin 
2051*0ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2052*0ade8cd8SKonstantin Porotchkin 				comphy_index);
2053*0ade8cd8SKonstantin Porotchkin 
2054*0ade8cd8SKonstantin Porotchkin 	debug_enter();
2055*0ade8cd8SKonstantin Porotchkin 
2056*0ade8cd8SKonstantin Porotchkin 	/* Configure SQ threshold and CDR lock */
2057*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_SQUELCH_THRESH_IN_MASK;
2058*0ade8cd8SKonstantin Porotchkin 	data = 0xc << HPIPE_SQUELCH_THRESH_IN_OFFSET;
2059*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SQUELCH_FFE_SETTING_REG, data, mask);
2060*0ade8cd8SKonstantin Porotchkin 
2061*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_SQ_DEGLITCH_WIDTH_P_MASK;
2062*0ade8cd8SKonstantin Porotchkin 	data = 0xf << HPIPE_SQ_DEGLITCH_WIDTH_P_OFFSET;
2063*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_SQ_DEGLITCH_WIDTH_N_MASK;
2064*0ade8cd8SKonstantin Porotchkin 	data |= 0xf << HPIPE_SQ_DEGLITCH_WIDTH_N_OFFSET;
2065*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_SQ_DEGLITCH_EN_MASK;
2066*0ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_SQ_DEGLITCH_EN_OFFSET;
2067*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SQ_GLITCH_FILTER_CTRL, data, mask);
2068*0ade8cd8SKonstantin Porotchkin 
2069*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CDR_LOCK_DET_EN_MASK;
2070*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_CDR_LOCK_DET_EN_OFFSET;
2071*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
2072*0ade8cd8SKonstantin Porotchkin 
2073*0ade8cd8SKonstantin Porotchkin 	udelay(100);
2074*0ade8cd8SKonstantin Porotchkin 
2075*0ade8cd8SKonstantin Porotchkin 	/* Determine if we have a cable attached to this comphy, if not,
2076*0ade8cd8SKonstantin Porotchkin 	 * we can't perform RX training.
2077*0ade8cd8SKonstantin Porotchkin 	 */
2078*0ade8cd8SKonstantin Porotchkin 	data = mmio_read_32(hpipe_addr + HPIPE_SQUELCH_FFE_SETTING_REG);
2079*0ade8cd8SKonstantin Porotchkin 	if (data & HPIPE_SQUELCH_DETECTED_MASK) {
2080*0ade8cd8SKonstantin Porotchkin 		ERROR("Squelsh is not detected, can't perform RX training\n");
2081*0ade8cd8SKonstantin Porotchkin 		return -EINVAL;
2082*0ade8cd8SKonstantin Porotchkin 	}
2083*0ade8cd8SKonstantin Porotchkin 
2084*0ade8cd8SKonstantin Porotchkin 	data = mmio_read_32(hpipe_addr + HPIPE_LOOPBACK_REG);
2085*0ade8cd8SKonstantin Porotchkin 	if (!(data & HPIPE_CDR_LOCK_MASK)) {
2086*0ade8cd8SKonstantin Porotchkin 		ERROR("CDR is not locked, can't perform RX training\n");
2087*0ade8cd8SKonstantin Porotchkin 		return -EINVAL;
2088*0ade8cd8SKonstantin Porotchkin 	}
2089*0ade8cd8SKonstantin Porotchkin 
2090*0ade8cd8SKonstantin Porotchkin 	/* Do preparations for RX training */
2091*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_RES_FORCE_MASK;
2092*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
2093*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
2094*0ade8cd8SKonstantin Porotchkin 
2095*0ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
2096*0ade8cd8SKonstantin Porotchkin 	data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
2097*0ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
2098*0ade8cd8SKonstantin Porotchkin 	data |= 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
2099*0ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
2100*0ade8cd8SKonstantin Porotchkin 
2101*0ade8cd8SKonstantin Porotchkin 	/* Perform RX training for all possible FFE (Feed Forward
2102*0ade8cd8SKonstantin Porotchkin 	 * Equalization, possible values are 0-7).
2103*0ade8cd8SKonstantin Porotchkin 	 * We update the best value reached and the FFE which gave this value.
2104*0ade8cd8SKonstantin Porotchkin 	 */
2105*0ade8cd8SKonstantin Porotchkin 	for (i = 0; i < MAX_NUM_OF_FFE; i++) {
2106*0ade8cd8SKonstantin Porotchkin 		rx_train_result = 0;
2107*0ade8cd8SKonstantin Porotchkin 		ret = mvebu_cp110_comphy_test_single_ffe(comphy_base,
2108*0ade8cd8SKonstantin Porotchkin 							 comphy_index, i,
2109*0ade8cd8SKonstantin Porotchkin 							 &rx_train_result);
2110*0ade8cd8SKonstantin Porotchkin 
2111*0ade8cd8SKonstantin Porotchkin 		if ((!ret) && (rx_train_result > max_rx_train)) {
2112*0ade8cd8SKonstantin Porotchkin 			max_rx_train = rx_train_result;
2113*0ade8cd8SKonstantin Porotchkin 			max_rx_train_index = i;
2114*0ade8cd8SKonstantin Porotchkin 		}
2115*0ade8cd8SKonstantin Porotchkin 	}
2116*0ade8cd8SKonstantin Porotchkin 
2117*0ade8cd8SKonstantin Porotchkin 	/* If we were able to determine which FFE gives the best value,
2118*0ade8cd8SKonstantin Porotchkin 	 * now we need to set it and run RX training again (only for this
2119*0ade8cd8SKonstantin Porotchkin 	 * FFE).
2120*0ade8cd8SKonstantin Porotchkin 	 */
2121*0ade8cd8SKonstantin Porotchkin 	if (max_rx_train) {
2122*0ade8cd8SKonstantin Porotchkin 		ret = mvebu_cp110_comphy_test_single_ffe(comphy_base,
2123*0ade8cd8SKonstantin Porotchkin 							 comphy_index,
2124*0ade8cd8SKonstantin Porotchkin 							 max_rx_train_index,
2125*0ade8cd8SKonstantin Porotchkin 							 &rx_train_result);
2126*0ade8cd8SKonstantin Porotchkin 
2127*0ade8cd8SKonstantin Porotchkin 		if (ret == 0)
2128*0ade8cd8SKonstantin Porotchkin 			debug("RX Training passed (FFE = %d, result = 0x%x)\n",
2129*0ade8cd8SKonstantin Porotchkin 			       max_rx_train_index, rx_train_result);
2130*0ade8cd8SKonstantin Porotchkin 	} else {
2131*0ade8cd8SKonstantin Porotchkin 		ERROR("RX Training failed for comphy%d\n", comphy_index);
2132*0ade8cd8SKonstantin Porotchkin 		ret = -EINVAL;
2133*0ade8cd8SKonstantin Porotchkin 	}
2134*0ade8cd8SKonstantin Porotchkin 
2135*0ade8cd8SKonstantin Porotchkin 	debug_exit();
2136*0ade8cd8SKonstantin Porotchkin 
2137*0ade8cd8SKonstantin Porotchkin 	return ret;
2138*0ade8cd8SKonstantin Porotchkin }
2139*0ade8cd8SKonstantin Porotchkin 
2140*0ade8cd8SKonstantin Porotchkin /* During AP the proper mode is auto-negotiated and the mac, pcs and serdes
2141*0ade8cd8SKonstantin Porotchkin  * configuration are done by the firmware loaded to the MG's CM3 for appropriate
2142*0ade8cd8SKonstantin Porotchkin  * negotiated mode. Therefore there is no need to configure the mac, pcs and
2143*0ade8cd8SKonstantin Porotchkin  * serdes from u-boot. The only thing that need to be setup is powering up
2144*0ade8cd8SKonstantin Porotchkin  * the comphy, which is done through Common PHY<n> Configuration 1 Register
2145*0ade8cd8SKonstantin Porotchkin  * (CP0: 0xF2441000, CP1: 0xF4441000). This step can't be done by MG's CM3,
2146*0ade8cd8SKonstantin Porotchkin  * since it doesn't have an access to this register-set (but it has access to
2147*0ade8cd8SKonstantin Porotchkin  * the network registers like: MG, AP, MAC, PCS, Serdes etc.)
2148*0ade8cd8SKonstantin Porotchkin  */
2149*0ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base,
2150*0ade8cd8SKonstantin Porotchkin 					  uint8_t comphy_index)
2151*0ade8cd8SKonstantin Porotchkin {
2152*0ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
2153*0ade8cd8SKonstantin Porotchkin 	uintptr_t comphy_addr = comphy_addr =
2154*0ade8cd8SKonstantin Porotchkin 				COMPHY_ADDR(comphy_base, comphy_index);
2155*0ade8cd8SKonstantin Porotchkin 
2156*0ade8cd8SKonstantin Porotchkin 	debug_enter();
2157*0ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
2158*0ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
2159*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
2160*0ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
2161*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
2162*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
2163*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
2164*0ade8cd8SKonstantin Porotchkin 	debug_exit();
2165*0ade8cd8SKonstantin Porotchkin 
2166*0ade8cd8SKonstantin Porotchkin 	return 0;
2167*0ade8cd8SKonstantin Porotchkin }
2168*0ade8cd8SKonstantin Porotchkin 
2169*0ade8cd8SKonstantin Porotchkin /*
2170*0ade8cd8SKonstantin Porotchkin  * This function allows to reset the digital synchronizers between
2171*0ade8cd8SKonstantin Porotchkin  * the MAC and the PHY, it is required when the MAC changes its state.
2172*0ade8cd8SKonstantin Porotchkin  */
2173*0ade8cd8SKonstantin Porotchkin int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base,
2174*0ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index,
2175*0ade8cd8SKonstantin Porotchkin 				     uint32_t comphy_mode, uint32_t command)
2176*0ade8cd8SKonstantin Porotchkin {
2177*0ade8cd8SKonstantin Porotchkin 	int mode = COMPHY_GET_MODE(comphy_mode);
2178*0ade8cd8SKonstantin Porotchkin 	uintptr_t sd_ip_addr;
2179*0ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
2180*0ade8cd8SKonstantin Porotchkin 
2181*0ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2182*0ade8cd8SKonstantin Porotchkin 			     comphy_index);
2183*0ade8cd8SKonstantin Porotchkin 
2184*0ade8cd8SKonstantin Porotchkin 	switch (mode) {
2185*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_SGMII_MODE):
2186*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_HS_SGMII_MODE):
2187*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_XFI_MODE):
2188*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_SFI_MODE):
2189*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_RXAUI_MODE):
2190*0ade8cd8SKonstantin Porotchkin 		mask = SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2191*0ade8cd8SKonstantin Porotchkin 		data = ((command == COMPHY_COMMAND_DIGITAL_PWR_OFF) ?
2192*0ade8cd8SKonstantin Porotchkin 			0x0 : 0x1) << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2193*0ade8cd8SKonstantin Porotchkin 		reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2194*0ade8cd8SKonstantin Porotchkin 		break;
2195*0ade8cd8SKonstantin Porotchkin 	default:
2196*0ade8cd8SKonstantin Porotchkin 		ERROR("comphy%d: Digital PWR ON/OFF is not supported\n",
2197*0ade8cd8SKonstantin Porotchkin 			comphy_index);
2198*0ade8cd8SKonstantin Porotchkin 			return -EINVAL;
2199*0ade8cd8SKonstantin Porotchkin 	}
2200*0ade8cd8SKonstantin Porotchkin 
2201*0ade8cd8SKonstantin Porotchkin 	return 0;
2202*0ade8cd8SKonstantin Porotchkin }
2203*0ade8cd8SKonstantin Porotchkin 
2204*0ade8cd8SKonstantin Porotchkin int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint64_t comphy_index,
2205*0ade8cd8SKonstantin Porotchkin 				uint64_t comphy_mode)
2206*0ade8cd8SKonstantin Porotchkin {
2207*0ade8cd8SKonstantin Porotchkin 	int mode = COMPHY_GET_MODE(comphy_mode);
2208*0ade8cd8SKonstantin Porotchkin 	int err = 0;
2209*0ade8cd8SKonstantin Porotchkin 
2210*0ade8cd8SKonstantin Porotchkin 	debug_enter();
2211*0ade8cd8SKonstantin Porotchkin 
2212*0ade8cd8SKonstantin Porotchkin 	switch (mode) {
2213*0ade8cd8SKonstantin Porotchkin 	case(COMPHY_SATA_MODE):
2214*0ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_sata_power_on(comphy_base,
2215*0ade8cd8SKonstantin Porotchkin 						       comphy_index,
2216*0ade8cd8SKonstantin Porotchkin 						       comphy_mode);
2217*0ade8cd8SKonstantin Porotchkin 		break;
2218*0ade8cd8SKonstantin Porotchkin 	case(COMPHY_SGMII_MODE):
2219*0ade8cd8SKonstantin Porotchkin 	case(COMPHY_HS_SGMII_MODE):
2220*0ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_sgmii_power_on(comphy_base,
2221*0ade8cd8SKonstantin Porotchkin 							comphy_index,
2222*0ade8cd8SKonstantin Porotchkin 							comphy_mode);
2223*0ade8cd8SKonstantin Porotchkin 		break;
2224*0ade8cd8SKonstantin Porotchkin 	/* From comphy perspective, XFI and SFI are the same */
2225*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_XFI_MODE):
2226*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_SFI_MODE):
2227*0ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_xfi_power_on(comphy_base,
2228*0ade8cd8SKonstantin Porotchkin 						      comphy_index,
2229*0ade8cd8SKonstantin Porotchkin 						      comphy_mode);
2230*0ade8cd8SKonstantin Porotchkin 		break;
2231*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_PCIE_MODE):
2232*0ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_pcie_power_on(comphy_base,
2233*0ade8cd8SKonstantin Porotchkin 						       comphy_index,
2234*0ade8cd8SKonstantin Porotchkin 						       comphy_mode);
2235*0ade8cd8SKonstantin Porotchkin 		break;
2236*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_RXAUI_MODE):
2237*0ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_rxaui_power_on(comphy_base,
2238*0ade8cd8SKonstantin Porotchkin 							comphy_index,
2239*0ade8cd8SKonstantin Porotchkin 							comphy_mode);
2240*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_USB3H_MODE):
2241*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_USB3D_MODE):
2242*0ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_usb3_power_on(comphy_base,
2243*0ade8cd8SKonstantin Porotchkin 						       comphy_index,
2244*0ade8cd8SKonstantin Porotchkin 						       comphy_mode);
2245*0ade8cd8SKonstantin Porotchkin 		break;
2246*0ade8cd8SKonstantin Porotchkin 	case (COMPHY_AP_MODE):
2247*0ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index);
2248*0ade8cd8SKonstantin Porotchkin 		break;
2249*0ade8cd8SKonstantin Porotchkin 	default:
2250*0ade8cd8SKonstantin Porotchkin 		ERROR("comphy%lld: unsupported comphy mode\n", comphy_index);
2251*0ade8cd8SKonstantin Porotchkin 		err = -EINVAL;
2252*0ade8cd8SKonstantin Porotchkin 		break;
2253*0ade8cd8SKonstantin Porotchkin 	}
2254*0ade8cd8SKonstantin Porotchkin 
2255*0ade8cd8SKonstantin Porotchkin 	debug_exit();
2256*0ade8cd8SKonstantin Porotchkin 
2257*0ade8cd8SKonstantin Porotchkin 	return err;
2258*0ade8cd8SKonstantin Porotchkin }
2259*0ade8cd8SKonstantin Porotchkin 
2260*0ade8cd8SKonstantin Porotchkin int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint64_t comphy_index)
2261*0ade8cd8SKonstantin Porotchkin {
2262*0ade8cd8SKonstantin Porotchkin 	uintptr_t sd_ip_addr, comphy_ip_addr;
2263*0ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
2264*0ade8cd8SKonstantin Porotchkin 
2265*0ade8cd8SKonstantin Porotchkin 	debug_enter();
2266*0ade8cd8SKonstantin Porotchkin 
2267*0ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
2268*0ade8cd8SKonstantin Porotchkin 			     comphy_index);
2269*0ade8cd8SKonstantin Porotchkin 	comphy_ip_addr = COMPHY_ADDR(comphy_base, comphy_index);
2270*0ade8cd8SKonstantin Porotchkin 
2271*0ade8cd8SKonstantin Porotchkin 	/* Hard reset the comphy, for Ethernet modes and Sata */
2272*0ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
2273*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
2274*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
2275*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
2276*0ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
2277*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
2278*0ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
2279*0ade8cd8SKonstantin Porotchkin 
2280*0ade8cd8SKonstantin Porotchkin 	/* PCIe reset */
2281*0ade8cd8SKonstantin Porotchkin 	spin_lock(&cp110_mac_reset_lock);
2282*0ade8cd8SKonstantin Porotchkin 
2283*0ade8cd8SKonstantin Porotchkin 	/* The mvebu_cp110_comphy_power_off will be called only from Linux (to
2284*0ade8cd8SKonstantin Porotchkin 	 * override settings done by bootloader) and it will be relevant only
2285*0ade8cd8SKonstantin Porotchkin 	 * to PCIe (called before check if to skip pcie power off or not).
2286*0ade8cd8SKonstantin Porotchkin 	 */
2287*0ade8cd8SKonstantin Porotchkin 	data = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2288*0ade8cd8SKonstantin Porotchkin 						 SYS_CTRL_UINIT_SOFT_RESET_REG);
2289*0ade8cd8SKonstantin Porotchkin 	switch (comphy_index) {
2290*0ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE0:
2291*0ade8cd8SKonstantin Porotchkin 		data &= ~PCIE_MAC_RESET_MASK_PORT0;
2292*0ade8cd8SKonstantin Porotchkin 		break;
2293*0ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE4:
2294*0ade8cd8SKonstantin Porotchkin 		data &= ~PCIE_MAC_RESET_MASK_PORT1;
2295*0ade8cd8SKonstantin Porotchkin 		break;
2296*0ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE5:
2297*0ade8cd8SKonstantin Porotchkin 		data &= ~PCIE_MAC_RESET_MASK_PORT2;
2298*0ade8cd8SKonstantin Porotchkin 		break;
2299*0ade8cd8SKonstantin Porotchkin 	}
2300*0ade8cd8SKonstantin Porotchkin 
2301*0ade8cd8SKonstantin Porotchkin 	mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
2302*0ade8cd8SKonstantin Porotchkin 					   SYS_CTRL_UINIT_SOFT_RESET_REG, data);
2303*0ade8cd8SKonstantin Porotchkin 	spin_unlock(&cp110_mac_reset_lock);
2304*0ade8cd8SKonstantin Porotchkin 
2305*0ade8cd8SKonstantin Porotchkin 	/* Hard reset the comphy, for PCIe and usb3 */
2306*0ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
2307*0ade8cd8SKonstantin Porotchkin 	data = 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
2308*0ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
2309*0ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
2310*0ade8cd8SKonstantin Porotchkin 	reg_set(comphy_ip_addr + COMMON_PHY_CFG1_REG, data, mask);
2311*0ade8cd8SKonstantin Porotchkin 
2312*0ade8cd8SKonstantin Porotchkin 	/* Clear comphy PHY and PIPE selector, can't rely on previous config. */
2313*0ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
2314*0ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
2315*0ade8cd8SKonstantin Porotchkin 
2316*0ade8cd8SKonstantin Porotchkin 	debug_exit();
2317*0ade8cd8SKonstantin Porotchkin 
2318*0ade8cd8SKonstantin Porotchkin 	return 0;
2319*0ade8cd8SKonstantin Porotchkin }
2320