xref: /rk3399_ARM-atf/drivers/marvell/comphy/phy-comphy-cp110.c (revision a28471722afb3ae784d7bce2118c2ea703f8444c)
10ade8cd8SKonstantin Porotchkin /*
20ade8cd8SKonstantin Porotchkin  * Copyright (C) 2018 Marvell International Ltd.
30ade8cd8SKonstantin Porotchkin  *
40ade8cd8SKonstantin Porotchkin  * SPDX-License-Identifier:     BSD-3-Clause
50ade8cd8SKonstantin Porotchkin  * https://spdx.org/licenses
60ade8cd8SKonstantin Porotchkin  */
70ade8cd8SKonstantin Porotchkin 
80ade8cd8SKonstantin Porotchkin /* Marvell CP110 SoC COMPHY unit driver */
90ade8cd8SKonstantin Porotchkin 
100ade8cd8SKonstantin Porotchkin #include <errno.h>
1109d40e0eSAntonio Nino Diaz 
1209d40e0eSAntonio Nino Diaz #include <common/debug.h>
1309d40e0eSAntonio Nino Diaz #include <drivers/delay_timer.h>
1409d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
1509d40e0eSAntonio Nino Diaz #include <lib/spinlock.h>
1609d40e0eSAntonio Nino Diaz 
170ade8cd8SKonstantin Porotchkin #include <mvebu_def.h>
180ade8cd8SKonstantin Porotchkin #include "mvebu.h"
190ade8cd8SKonstantin Porotchkin #include "comphy-cp110.h"
2042a29337SGrzegorz Jaszczyk #include "phy-comphy-cp110.h"
2142a29337SGrzegorz Jaszczyk #include "phy-comphy-common.h"
220ade8cd8SKonstantin Porotchkin 
2342a29337SGrzegorz Jaszczyk #if __has_include("phy-porting-layer.h")
2442a29337SGrzegorz Jaszczyk #include "phy-porting-layer.h"
250ade8cd8SKonstantin Porotchkin #else
2642a29337SGrzegorz Jaszczyk #include "phy-default-porting-layer.h"
270ade8cd8SKonstantin Porotchkin #endif
280ade8cd8SKonstantin Porotchkin 
290ade8cd8SKonstantin Porotchkin /* COMPHY speed macro */
300ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_1_25G		0 /* SGMII 1G */
310ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_2_5G		1
320ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_3_125G		2 /* SGMII 2.5G */
330ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_5G			3
340ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_5_15625G		4 /* XFI 5G */
350ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_6G			5
360ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_10_3125G		6 /* XFI 10G */
370ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_MAX		0x3F
380ade8cd8SKonstantin Porotchkin /* The  default speed for IO with fixed known speed */
390ade8cd8SKonstantin Porotchkin #define COMPHY_SPEED_DEFAULT		COMPHY_SPEED_MAX
400ade8cd8SKonstantin Porotchkin 
410ade8cd8SKonstantin Porotchkin /* Commands for comphy driver */
420ade8cd8SKonstantin Porotchkin #define COMPHY_COMMAND_DIGITAL_PWR_OFF		0x00000001
430ade8cd8SKonstantin Porotchkin #define COMPHY_COMMAND_DIGITAL_PWR_ON		0x00000002
440ade8cd8SKonstantin Porotchkin 
450ade8cd8SKonstantin Porotchkin #define COMPHY_PIPE_FROM_COMPHY_ADDR(x)	((x & ~0xffffff) + 0x120000)
460ade8cd8SKonstantin Porotchkin 
470ade8cd8SKonstantin Porotchkin /* System controller registers */
480ade8cd8SKonstantin Porotchkin #define PCIE_MAC_RESET_MASK_PORT0	BIT(13)
490ade8cd8SKonstantin Porotchkin #define PCIE_MAC_RESET_MASK_PORT1	BIT(11)
500ade8cd8SKonstantin Porotchkin #define PCIE_MAC_RESET_MASK_PORT2	BIT(12)
510ade8cd8SKonstantin Porotchkin #define SYS_CTRL_UINIT_SOFT_RESET_REG	0x268
520ade8cd8SKonstantin Porotchkin #define SYS_CTRL_FROM_COMPHY_ADDR(x)	((x & ~0xffffff) + 0x440000)
530ade8cd8SKonstantin Porotchkin 
540ade8cd8SKonstantin Porotchkin /* DFX register spaces */
550ade8cd8SKonstantin Porotchkin #define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET	(0)
560ade8cd8SKonstantin Porotchkin #define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK	(0x1 << \
570ade8cd8SKonstantin Porotchkin 					SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET)
580ade8cd8SKonstantin Porotchkin #define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET	(1)
590ade8cd8SKonstantin Porotchkin #define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK	(0x1 << \
600ade8cd8SKonstantin Porotchkin 					SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET)
610ade8cd8SKonstantin Porotchkin #define SAR_STATUS_0_REG			200
620ade8cd8SKonstantin Porotchkin #define DFX_FROM_COMPHY_ADDR(x)			((x & ~0xffffff) + DFX_BASE)
630ade8cd8SKonstantin Porotchkin 
640ade8cd8SKonstantin Porotchkin /* The same Units Soft Reset Config register are accessed in all PCIe ports
650ade8cd8SKonstantin Porotchkin  * initialization, so a spin lock is defined in case when more than 1 CPUs
660ade8cd8SKonstantin Porotchkin  * resets PCIe MAC and need to access the register in the same time. The spin
670ade8cd8SKonstantin Porotchkin  * lock is shared by all CP110 units.
680ade8cd8SKonstantin Porotchkin  */
690ade8cd8SKonstantin Porotchkin spinlock_t cp110_mac_reset_lock;
700ade8cd8SKonstantin Porotchkin 
710ade8cd8SKonstantin Porotchkin /* These values come from the PCI Express Spec */
720ade8cd8SKonstantin Porotchkin enum pcie_link_width {
730ade8cd8SKonstantin Porotchkin 	PCIE_LNK_WIDTH_RESRV	= 0x00,
740ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X1		= 0x01,
750ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X2		= 0x02,
760ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X4		= 0x04,
770ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X8		= 0x08,
780ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X12		= 0x0C,
790ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X16		= 0x10,
800ade8cd8SKonstantin Porotchkin 	PCIE_LNK_X32		= 0x20,
810ade8cd8SKonstantin Porotchkin 	PCIE_LNK_WIDTH_UNKNOWN  = 0xFF,
820ade8cd8SKonstantin Porotchkin };
830ade8cd8SKonstantin Porotchkin 
8442a29337SGrzegorz Jaszczyk _Bool rx_trainng_done[AP_NUM][CP_NUM][MAX_LANE_NR] = {0};
8542a29337SGrzegorz Jaszczyk 
8642a29337SGrzegorz Jaszczyk static void mvebu_cp110_get_ap_and_cp_nr(uint8_t *ap_nr, uint8_t *cp_nr,
8742a29337SGrzegorz Jaszczyk 					 uint64_t comphy_base)
880ade8cd8SKonstantin Porotchkin {
8942a29337SGrzegorz Jaszczyk #if (AP_NUM == 1)
9042a29337SGrzegorz Jaszczyk 	*ap_nr = 0;
9142a29337SGrzegorz Jaszczyk #else
9242a29337SGrzegorz Jaszczyk 	*ap_nr = (((comphy_base & ~0xffffff) - MVEBU_AP_IO_BASE(0)) /
9342a29337SGrzegorz Jaszczyk 			 AP_IO_OFFSET);
9442a29337SGrzegorz Jaszczyk #endif
950ade8cd8SKonstantin Porotchkin 
9642a29337SGrzegorz Jaszczyk 	*cp_nr = (((comphy_base & ~0xffffff) - MVEBU_AP_IO_BASE(*ap_nr)) /
9742a29337SGrzegorz Jaszczyk 		 MVEBU_CP_OFFSET);
980ade8cd8SKonstantin Porotchkin 
9942a29337SGrzegorz Jaszczyk 	debug("cp_base 0x%llx, ap_io_base 0x%lx, cp_offset 0x%lx\n",
10042a29337SGrzegorz Jaszczyk 	       comphy_base, (unsigned long)MVEBU_AP_IO_BASE(*ap_nr),
10142a29337SGrzegorz Jaszczyk 	       (unsigned long)MVEBU_CP_OFFSET);
1020ade8cd8SKonstantin Porotchkin }
1030ade8cd8SKonstantin Porotchkin 
1040ade8cd8SKonstantin Porotchkin /* Clear PIPE selector - avoid collision with previous configuration */
1050ade8cd8SKonstantin Porotchkin static void mvebu_cp110_comphy_clr_pipe_selector(uint64_t comphy_base,
1060ade8cd8SKonstantin Porotchkin 						 uint8_t comphy_index)
1070ade8cd8SKonstantin Porotchkin {
1080ade8cd8SKonstantin Porotchkin 	uint32_t reg, mask, field;
1090ade8cd8SKonstantin Porotchkin 	uint32_t comphy_offset =
1100ade8cd8SKonstantin Porotchkin 			COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
1110ade8cd8SKonstantin Porotchkin 
1120ade8cd8SKonstantin Porotchkin 	mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
1130ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
1140ade8cd8SKonstantin Porotchkin 	field = reg & mask;
1150ade8cd8SKonstantin Porotchkin 
1160ade8cd8SKonstantin Porotchkin 	if (field) {
1170ade8cd8SKonstantin Porotchkin 		reg &= ~mask;
1180ade8cd8SKonstantin Porotchkin 		mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET,
1190ade8cd8SKonstantin Porotchkin 			     reg);
1200ade8cd8SKonstantin Porotchkin 	}
1210ade8cd8SKonstantin Porotchkin }
1220ade8cd8SKonstantin Porotchkin 
1230ade8cd8SKonstantin Porotchkin /* Clear PHY selector - avoid collision with previous configuration */
1240ade8cd8SKonstantin Porotchkin static void mvebu_cp110_comphy_clr_phy_selector(uint64_t comphy_base,
1250ade8cd8SKonstantin Porotchkin 						uint8_t comphy_index)
1260ade8cd8SKonstantin Porotchkin {
1270ade8cd8SKonstantin Porotchkin 	uint32_t reg, mask, field;
1280ade8cd8SKonstantin Porotchkin 	uint32_t comphy_offset =
1290ade8cd8SKonstantin Porotchkin 			COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
1300ade8cd8SKonstantin Porotchkin 
1310ade8cd8SKonstantin Porotchkin 	mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
1320ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
1330ade8cd8SKonstantin Porotchkin 	field = reg & mask;
1340ade8cd8SKonstantin Porotchkin 
1350ade8cd8SKonstantin Porotchkin 	/* Clear comphy selector - if it was already configured.
1360ade8cd8SKonstantin Porotchkin 	 * (might be that this comphy was configured as PCIe/USB,
1370ade8cd8SKonstantin Porotchkin 	 * in such case, no need to clear comphy selector because PCIe/USB
1380ade8cd8SKonstantin Porotchkin 	 * are controlled by hpipe selector).
1390ade8cd8SKonstantin Porotchkin 	 */
1400ade8cd8SKonstantin Porotchkin 	if (field) {
1410ade8cd8SKonstantin Porotchkin 		reg &= ~mask;
1420ade8cd8SKonstantin Porotchkin 		mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET,
1430ade8cd8SKonstantin Porotchkin 			      reg);
1440ade8cd8SKonstantin Porotchkin 	}
1450ade8cd8SKonstantin Porotchkin }
1460ade8cd8SKonstantin Porotchkin 
1470ade8cd8SKonstantin Porotchkin /* PHY selector configures SATA and Network modes */
1480ade8cd8SKonstantin Porotchkin static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base,
1490ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
1500ade8cd8SKonstantin Porotchkin {
1510ade8cd8SKonstantin Porotchkin 	uint32_t reg, mask;
1520ade8cd8SKonstantin Porotchkin 	uint32_t comphy_offset =
1530ade8cd8SKonstantin Porotchkin 			COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
1540ade8cd8SKonstantin Porotchkin 	int mode;
1550ade8cd8SKonstantin Porotchkin 
1560ade8cd8SKonstantin Porotchkin 	/* If phy selector is used the pipe selector should be marked as
1570ade8cd8SKonstantin Porotchkin 	 * unconnected.
1580ade8cd8SKonstantin Porotchkin 	 */
1590ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
1600ade8cd8SKonstantin Porotchkin 
1610ade8cd8SKonstantin Porotchkin 	/* Comphy mode (compound of the IO mode and id). Here, only the IO mode
1620ade8cd8SKonstantin Porotchkin 	 * is required to distinguish between SATA and network modes.
1630ade8cd8SKonstantin Porotchkin 	 */
1640ade8cd8SKonstantin Porotchkin 	mode = COMPHY_GET_MODE(comphy_mode);
1650ade8cd8SKonstantin Porotchkin 
1660ade8cd8SKonstantin Porotchkin 	mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
1670ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
1680ade8cd8SKonstantin Porotchkin 	reg &= ~mask;
1690ade8cd8SKonstantin Porotchkin 
1700ade8cd8SKonstantin Porotchkin 	/* SATA port 0/1 require the same configuration */
1710ade8cd8SKonstantin Porotchkin 	if (mode == COMPHY_SATA_MODE) {
1720ade8cd8SKonstantin Porotchkin 		/* SATA selector values is always 4 */
1730ade8cd8SKonstantin Porotchkin 		reg |= COMMON_SELECTOR_COMPHYN_SATA << comphy_offset;
1740ade8cd8SKonstantin Porotchkin 	} else {
1750ade8cd8SKonstantin Porotchkin 		switch (comphy_index) {
1760ade8cd8SKonstantin Porotchkin 		case(0):
1770ade8cd8SKonstantin Porotchkin 		case(1):
1780ade8cd8SKonstantin Porotchkin 		case(2):
1790ade8cd8SKonstantin Porotchkin 			/* For comphy 0,1, and 2:
1800ade8cd8SKonstantin Porotchkin 			 * Network selector value is always 1.
1810ade8cd8SKonstantin Porotchkin 			 */
1820ade8cd8SKonstantin Porotchkin 			reg |= COMMON_SELECTOR_COMPHY0_1_2_NETWORK <<
1830ade8cd8SKonstantin Porotchkin 				comphy_offset;
1840ade8cd8SKonstantin Porotchkin 			break;
1850ade8cd8SKonstantin Porotchkin 		case(3):
1860ade8cd8SKonstantin Porotchkin 			/* For comphy 3:
1870ade8cd8SKonstantin Porotchkin 			 * 0x1 = RXAUI_Lane1
1880ade8cd8SKonstantin Porotchkin 			 * 0x2 = SGMII/HS-SGMII Port1
1890ade8cd8SKonstantin Porotchkin 			 */
1900ade8cd8SKonstantin Porotchkin 			if (mode == COMPHY_RXAUI_MODE)
1910ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY3_RXAUI <<
1920ade8cd8SKonstantin Porotchkin 					comphy_offset;
1930ade8cd8SKonstantin Porotchkin 			else
1940ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY3_SGMII <<
1950ade8cd8SKonstantin Porotchkin 					comphy_offset;
1960ade8cd8SKonstantin Porotchkin 			break;
1970ade8cd8SKonstantin Porotchkin 		case(4):
1980ade8cd8SKonstantin Porotchkin 			 /* For comphy 4:
1990ade8cd8SKonstantin Porotchkin 			  * 0x1 = SGMII/HS-SGMII Port1, XFI1/SFI1
2000ade8cd8SKonstantin Porotchkin 			  * 0x2 = SGMII/HS-SGMII Port0: XFI0/SFI0, RXAUI_Lane0
2010ade8cd8SKonstantin Porotchkin 			  *
2020ade8cd8SKonstantin Porotchkin 			  * We want to check if SGMII1/HS_SGMII1 is the
2030ade8cd8SKonstantin Porotchkin 			  * requested mode in order to determine which value
2040ade8cd8SKonstantin Porotchkin 			  * should be set (all other modes use the same value)
2050ade8cd8SKonstantin Porotchkin 			  * so we need to strip the mode, and check the ID
2060ade8cd8SKonstantin Porotchkin 			  * because we might handle SGMII0/HS_SGMII0 too.
2070ade8cd8SKonstantin Porotchkin 			  */
2080ade8cd8SKonstantin Porotchkin 			  /* TODO: need to distinguish between CP110 and CP115
2090ade8cd8SKonstantin Porotchkin 			   * as SFI1/XFI1 available only for CP115.
2100ade8cd8SKonstantin Porotchkin 			   */
2110ade8cd8SKonstantin Porotchkin 			if ((mode == COMPHY_SGMII_MODE ||
2120ade8cd8SKonstantin Porotchkin 			    mode == COMPHY_HS_SGMII_MODE ||
2130529106cSGrzegorz Jaszczyk 			    mode == COMPHY_SFI_MODE || mode == COMPHY_XFI_MODE)
2140529106cSGrzegorz Jaszczyk 			    && COMPHY_GET_ID(comphy_mode) == 1)
2150ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY4_PORT1 <<
2160ade8cd8SKonstantin Porotchkin 					comphy_offset;
2170ade8cd8SKonstantin Porotchkin 			else
2180ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY4_ALL_OTHERS <<
2190ade8cd8SKonstantin Porotchkin 					comphy_offset;
2200ade8cd8SKonstantin Porotchkin 			break;
2210ade8cd8SKonstantin Porotchkin 		case(5):
2220ade8cd8SKonstantin Porotchkin 			/* For comphy 5:
2230ade8cd8SKonstantin Porotchkin 			 * 0x1 = SGMII/HS-SGMII Port2
2240ade8cd8SKonstantin Porotchkin 			 * 0x2 = RXAUI Lane1
2250ade8cd8SKonstantin Porotchkin 			 */
2260ade8cd8SKonstantin Porotchkin 			if (mode == COMPHY_RXAUI_MODE)
2270ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY5_RXAUI <<
2280ade8cd8SKonstantin Porotchkin 					comphy_offset;
2290ade8cd8SKonstantin Porotchkin 			else
2300ade8cd8SKonstantin Porotchkin 				reg |= COMMON_SELECTOR_COMPHY5_SGMII <<
2310ade8cd8SKonstantin Porotchkin 					comphy_offset;
2320ade8cd8SKonstantin Porotchkin 			break;
2330ade8cd8SKonstantin Porotchkin 		}
2340ade8cd8SKonstantin Porotchkin 	}
2350ade8cd8SKonstantin Porotchkin 
2360ade8cd8SKonstantin Porotchkin 	mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET, reg);
2370ade8cd8SKonstantin Porotchkin }
2380ade8cd8SKonstantin Porotchkin 
2390ade8cd8SKonstantin Porotchkin /* PIPE selector configures for PCIe, USB 3.0 Host, and USB 3.0 Device mode */
2400ade8cd8SKonstantin Porotchkin static void mvebu_cp110_comphy_set_pipe_selector(uint64_t comphy_base,
2410ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
2420ade8cd8SKonstantin Porotchkin {
2430ade8cd8SKonstantin Porotchkin 	uint32_t reg;
2440ade8cd8SKonstantin Porotchkin 	uint32_t shift = COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
2450ade8cd8SKonstantin Porotchkin 	int mode = COMPHY_GET_MODE(comphy_mode);
2460ade8cd8SKonstantin Porotchkin 	uint32_t mask = COMMON_SELECTOR_COMPHY_MASK << shift;
2470ade8cd8SKonstantin Porotchkin 	uint32_t pipe_sel = 0x0;
2480ade8cd8SKonstantin Porotchkin 
2490ade8cd8SKonstantin Porotchkin 	/* If pipe selector is used the phy selector should be marked as
2500ade8cd8SKonstantin Porotchkin 	 * unconnected.
2510ade8cd8SKonstantin Porotchkin 	 */
2520ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
2530ade8cd8SKonstantin Porotchkin 
2540ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
2550ade8cd8SKonstantin Porotchkin 	reg &= ~mask;
2560ade8cd8SKonstantin Porotchkin 
2570ade8cd8SKonstantin Porotchkin 	switch (mode) {
2580ade8cd8SKonstantin Porotchkin 	case (COMPHY_PCIE_MODE):
2590ade8cd8SKonstantin Porotchkin 		/* For lanes support PCIE, selector value are all same */
2600ade8cd8SKonstantin Porotchkin 		pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_PCIE;
2610ade8cd8SKonstantin Porotchkin 		break;
2620ade8cd8SKonstantin Porotchkin 
2630ade8cd8SKonstantin Porotchkin 	case (COMPHY_USB3H_MODE):
2640ade8cd8SKonstantin Porotchkin 		/* Only lane 1-4 support USB host, selector value is same */
2650ade8cd8SKonstantin Porotchkin 		if (comphy_index == COMPHY_LANE0 ||
2660ade8cd8SKonstantin Porotchkin 		    comphy_index == COMPHY_LANE5)
2670ade8cd8SKonstantin Porotchkin 			ERROR("COMPHY[%d] mode[%d] is invalid\n",
2680ade8cd8SKonstantin Porotchkin 			      comphy_index, mode);
2690ade8cd8SKonstantin Porotchkin 		else
2700ade8cd8SKonstantin Porotchkin 			pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBH;
2710ade8cd8SKonstantin Porotchkin 		break;
2720ade8cd8SKonstantin Porotchkin 
2730ade8cd8SKonstantin Porotchkin 	case (COMPHY_USB3D_MODE):
2740ade8cd8SKonstantin Porotchkin 		/* Lane 1 and 4 support USB device, selector value is same */
2750ade8cd8SKonstantin Porotchkin 		if (comphy_index == COMPHY_LANE1 ||
2760ade8cd8SKonstantin Porotchkin 		    comphy_index == COMPHY_LANE4)
2770ade8cd8SKonstantin Porotchkin 			pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBD;
2780ade8cd8SKonstantin Porotchkin 		else
2790ade8cd8SKonstantin Porotchkin 			ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index,
2800ade8cd8SKonstantin Porotchkin 			      mode);
2810ade8cd8SKonstantin Porotchkin 		break;
2820ade8cd8SKonstantin Porotchkin 
2830ade8cd8SKonstantin Porotchkin 	default:
2840ade8cd8SKonstantin Porotchkin 		ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode);
2850ade8cd8SKonstantin Porotchkin 		break;
2860ade8cd8SKonstantin Porotchkin 	}
2870ade8cd8SKonstantin Porotchkin 
2880ade8cd8SKonstantin Porotchkin 	mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET, reg |
2890ade8cd8SKonstantin Porotchkin 		      (pipe_sel << shift));
2900ade8cd8SKonstantin Porotchkin }
2910ade8cd8SKonstantin Porotchkin 
2920ade8cd8SKonstantin Porotchkin int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index)
2930ade8cd8SKonstantin Porotchkin {
2940ade8cd8SKonstantin Porotchkin 	uintptr_t sd_ip_addr, addr;
2950ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
2960ade8cd8SKonstantin Porotchkin 	int ret = 0;
2970ade8cd8SKonstantin Porotchkin 
2980ade8cd8SKonstantin Porotchkin 	debug_enter();
2990ade8cd8SKonstantin Porotchkin 
3000ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
3010ade8cd8SKonstantin Porotchkin 			     comphy_index);
3020ade8cd8SKonstantin Porotchkin 
3030ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
3040ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_PLL_TX_MASK &
3050ade8cd8SKonstantin Porotchkin 		SD_EXTERNAL_STATUS0_PLL_RX_MASK;
3060ade8cd8SKonstantin Porotchkin 	mask = data;
3070ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask,
3080ade8cd8SKonstantin Porotchkin 				    PLL_LOCK_TIMEOUT, REG_32BIT);
3090ade8cd8SKonstantin Porotchkin 	if (data != 0) {
3100ade8cd8SKonstantin Porotchkin 		if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
3110ade8cd8SKonstantin Porotchkin 			ERROR("RX PLL is not locked\n");
3120ade8cd8SKonstantin Porotchkin 		if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
3130ade8cd8SKonstantin Porotchkin 			ERROR("TX PLL is not locked\n");
3140ade8cd8SKonstantin Porotchkin 
3150ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
3160ade8cd8SKonstantin Porotchkin 	}
3170ade8cd8SKonstantin Porotchkin 
3180ade8cd8SKonstantin Porotchkin 	debug_exit();
3190ade8cd8SKonstantin Porotchkin 
3200ade8cd8SKonstantin Porotchkin 	return ret;
3210ade8cd8SKonstantin Porotchkin }
3220ade8cd8SKonstantin Porotchkin 
3230ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base,
3240ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
3250ade8cd8SKonstantin Porotchkin {
3260ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, sd_ip_addr, comphy_addr;
3270ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
32842a29337SGrzegorz Jaszczyk 	uint8_t ap_nr, cp_nr;
3290ade8cd8SKonstantin Porotchkin 	int ret = 0;
3300ade8cd8SKonstantin Porotchkin 
3310ade8cd8SKonstantin Porotchkin 	debug_enter();
3320ade8cd8SKonstantin Porotchkin 
33342a29337SGrzegorz Jaszczyk 	mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
33442a29337SGrzegorz Jaszczyk 
33542a29337SGrzegorz Jaszczyk 	const struct sata_params *sata_static_values =
33642a29337SGrzegorz Jaszczyk 			&sata_static_values_tab[ap_nr][cp_nr][comphy_index];
33742a29337SGrzegorz Jaszczyk 
33842a29337SGrzegorz Jaszczyk 
3390ade8cd8SKonstantin Porotchkin 	/* configure phy selector for SATA */
3400ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_phy_selector(comphy_base,
3410ade8cd8SKonstantin Porotchkin 					    comphy_index, comphy_mode);
3420ade8cd8SKonstantin Porotchkin 
3430ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
3440ade8cd8SKonstantin Porotchkin 				comphy_index);
3450ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
3460ade8cd8SKonstantin Porotchkin 			     comphy_index);
3470ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
3480ade8cd8SKonstantin Porotchkin 
3490ade8cd8SKonstantin Porotchkin 	debug(" add hpipe 0x%lx, sd 0x%lx, comphy 0x%lx\n",
3500ade8cd8SKonstantin Porotchkin 					   hpipe_addr, sd_ip_addr, comphy_addr);
3510ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
3520ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
3530ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
3540ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
3550ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
3560ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
3570ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
3580ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
3590ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
3600ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
3610ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
3620ade8cd8SKonstantin Porotchkin 
3630ade8cd8SKonstantin Porotchkin 	/* Set select data  width 40Bit - SATA mode only */
3640ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG6_REG,
3650ade8cd8SKonstantin Porotchkin 		0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET,
3660ade8cd8SKonstantin Porotchkin 		COMMON_PHY_CFG6_IF_40_SEL_MASK);
3670ade8cd8SKonstantin Porotchkin 
3680ade8cd8SKonstantin Porotchkin 	/* release from hard reset in SD external */
3690ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
3700ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
3710ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
3720ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
3730ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
3740ade8cd8SKonstantin Porotchkin 
3750ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
3760ade8cd8SKonstantin Porotchkin 	mdelay(1);
3770ade8cd8SKonstantin Porotchkin 
3780ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
3790ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
3800ade8cd8SKonstantin Porotchkin 	/* Set reference clock to comes from group 1 - choose 25Mhz */
3810ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG,
3820ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
3830ade8cd8SKonstantin Porotchkin 		HPIPE_MISC_REFCLK_SEL_MASK);
3840ade8cd8SKonstantin Porotchkin 	/* Reference frequency select set 1 (for SATA = 25Mhz) */
3850ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
3860ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
3870ade8cd8SKonstantin Porotchkin 	/* PHY mode select (set SATA = 0x0 */
3880ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
3890ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
3900ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
3910ade8cd8SKonstantin Porotchkin 	/* Set max PHY generation setting - 6Gbps */
3920ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
3930ade8cd8SKonstantin Porotchkin 		0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
3940ade8cd8SKonstantin Porotchkin 		HPIPE_INTERFACE_GEN_MAX_MASK);
3950ade8cd8SKonstantin Porotchkin 	/* Set select data  width 40Bit (SEL_BITS[2:0]) */
3960ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
3970ade8cd8SKonstantin Porotchkin 		0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
3980ade8cd8SKonstantin Porotchkin 
3990ade8cd8SKonstantin Porotchkin 	debug("stage: Analog parameters from ETP(HW)\n");
4000ade8cd8SKonstantin Porotchkin 	/* G1 settings */
4010ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
40242a29337SGrzegorz Jaszczyk 	data = sata_static_values->g1_rx_selmupi <<
40342a29337SGrzegorz Jaszczyk 			HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
4043c0024ccSGrzegorz Jaszczyk 	mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
40542a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g1_rx_selmupf <<
40642a29337SGrzegorz Jaszczyk 			HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
4070ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
40842a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g1_rx_selmufi <<
40942a29337SGrzegorz Jaszczyk 			HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
4100ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
41142a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g1_rx_selmuff <<
41242a29337SGrzegorz Jaszczyk 			HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
4130ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
4140ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
4150ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
4160ade8cd8SKonstantin Porotchkin 
4170ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
4180ade8cd8SKonstantin Porotchkin 	data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
4190ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
4200ade8cd8SKonstantin Porotchkin 	data |= 0x2 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
4210ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
4220ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
4230ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_MASK;
4240ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET;
4250ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_MASK;
4260ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET;
4270ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
4280ade8cd8SKonstantin Porotchkin 
4290ade8cd8SKonstantin Porotchkin 	/* G2 settings */
4300ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
43142a29337SGrzegorz Jaszczyk 	data = sata_static_values->g2_rx_selmupi <<
43242a29337SGrzegorz Jaszczyk 			HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
4333c0024ccSGrzegorz Jaszczyk 	mask |= HPIPE_G2_SET_1_G2_RX_SELMUPF_MASK;
43442a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g2_rx_selmupf <<
43542a29337SGrzegorz Jaszczyk 			HPIPE_G2_SET_1_G2_RX_SELMUPF_OFFSET;
4360ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
43742a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g2_rx_selmufi <<
43842a29337SGrzegorz Jaszczyk 			HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
4390ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_1_G2_RX_SELMUFF_MASK;
44042a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g2_rx_selmuff <<
44142a29337SGrzegorz Jaszczyk 			HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET;
4420ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_MASK;
4430ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET;
4440ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
4450ade8cd8SKonstantin Porotchkin 
4460ade8cd8SKonstantin Porotchkin 	/* G3 settings */
4470ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
44842a29337SGrzegorz Jaszczyk 	data = sata_static_values->g3_rx_selmupi <<
44942a29337SGrzegorz Jaszczyk 			HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
4500ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
45142a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g3_rx_selmupf <<
45242a29337SGrzegorz Jaszczyk 			HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
4530ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_SELMUFI_MASK;
45442a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g3_rx_selmufi <<
45542a29337SGrzegorz Jaszczyk 			HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET;
4560ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_SELMUFF_MASK;
45742a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g3_rx_selmuff <<
45842a29337SGrzegorz Jaszczyk 			HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET;
4590ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_DFE_EN_MASK;
4600ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET;
4610ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_MASK;
4620ade8cd8SKonstantin Porotchkin 	data |= 0x2 << HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET;
4630ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
4640ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
4650ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
4660ade8cd8SKonstantin Porotchkin 
4670ade8cd8SKonstantin Porotchkin 	/* DTL Control */
4680ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_CTR_DTL_SQ_DET_EN_MASK;
4690ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET;
4700ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_MASK;
4710ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET;
4720ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
4730ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
4740ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_CLAMPING_SEL_MASK;
4750ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET;
4760ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_MASK;
4770ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET;
4780ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_MASK;
4790ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET;
4800ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_MASK;
4810ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET;
4820ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
4830ade8cd8SKonstantin Porotchkin 
4840ade8cd8SKonstantin Porotchkin 	/* Trigger sampler enable pulse */
4850ade8cd8SKonstantin Porotchkin 	mask = HPIPE_SMAPLER_MASK;
4860ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_SMAPLER_OFFSET;
4870ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
4880ade8cd8SKonstantin Porotchkin 	mask = HPIPE_SMAPLER_MASK;
4890ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_SMAPLER_OFFSET;
4900ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
4910ade8cd8SKonstantin Porotchkin 
4920ade8cd8SKonstantin Porotchkin 	/* VDD Calibration Control 3 */
4930ade8cd8SKonstantin Porotchkin 	mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
4940ade8cd8SKonstantin Porotchkin 	data = 0x10 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
4950ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
4960ade8cd8SKonstantin Porotchkin 
4970ade8cd8SKonstantin Porotchkin 	/* DFE Resolution Control */
4980ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_RES_FORCE_MASK;
4990ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
5000ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
5010ade8cd8SKonstantin Porotchkin 
5020ade8cd8SKonstantin Porotchkin 	/* DFE F3-F5 Coefficient Control */
5030ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
5040ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
5050ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
5060ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
5070ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
5080ade8cd8SKonstantin Porotchkin 
5090ade8cd8SKonstantin Porotchkin 	/* G3 Setting 3 */
5100ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_FFE_CAP_SEL_MASK;
51142a29337SGrzegorz Jaszczyk 	data = sata_static_values->g3_ffe_cap_sel <<
51242a29337SGrzegorz Jaszczyk 			HPIPE_G3_FFE_CAP_SEL_OFFSET;
5130ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_FFE_RES_SEL_MASK;
51442a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g3_ffe_res_sel <<
51542a29337SGrzegorz Jaszczyk 			HPIPE_G3_FFE_RES_SEL_OFFSET;
5160ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_FFE_SETTING_FORCE_MASK;
5170ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET;
5180ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
5190ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
5200ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
5210ade8cd8SKonstantin Porotchkin 	data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
5220ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
5230ade8cd8SKonstantin Porotchkin 
5240ade8cd8SKonstantin Porotchkin 	/* G3 Setting 4 */
5250ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_DFE_RES_MASK;
52642a29337SGrzegorz Jaszczyk 	data = sata_static_values->g3_dfe_res << HPIPE_G3_DFE_RES_OFFSET;
5270ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
5280ade8cd8SKonstantin Porotchkin 
5290ade8cd8SKonstantin Porotchkin 	/* Offset Phase Control */
5300ade8cd8SKonstantin Porotchkin 	mask = HPIPE_OS_PH_OFFSET_MASK;
53142a29337SGrzegorz Jaszczyk 	data = sata_static_values->align90 << HPIPE_OS_PH_OFFSET_OFFSET;
5320ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_OS_PH_OFFSET_FORCE_MASK;
5330ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_OS_PH_OFFSET_FORCE_OFFSET;
5340ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_OS_PH_VALID_MASK;
5350ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_OS_PH_VALID_OFFSET;
5360ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
5370ade8cd8SKonstantin Porotchkin 	mask = HPIPE_OS_PH_VALID_MASK;
5380ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_OS_PH_VALID_OFFSET;
5390ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
5400ade8cd8SKonstantin Porotchkin 	mask = HPIPE_OS_PH_VALID_MASK;
5410ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_OS_PH_VALID_OFFSET;
5420ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
5430ade8cd8SKonstantin Porotchkin 
5440ade8cd8SKonstantin Porotchkin 	/* Set G1 TX amplitude and TX post emphasis value */
5450ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
54642a29337SGrzegorz Jaszczyk 	data = sata_static_values->g1_amp << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
5470ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
54842a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g1_tx_amp_adj <<
54942a29337SGrzegorz Jaszczyk 			HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
5500ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
55142a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g1_emph <<
55242a29337SGrzegorz Jaszczyk 			HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
5530ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
55442a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g1_emph_en <<
55542a29337SGrzegorz Jaszczyk 			HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
5560ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
5570ade8cd8SKonstantin Porotchkin 
55842a29337SGrzegorz Jaszczyk 	/* Set G1 emph */
55942a29337SGrzegorz Jaszczyk 	mask = HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
56042a29337SGrzegorz Jaszczyk 	data = sata_static_values->g1_tx_emph_en <<
56142a29337SGrzegorz Jaszczyk 			HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
56242a29337SGrzegorz Jaszczyk 	mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
56342a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g1_tx_emph <<
56442a29337SGrzegorz Jaszczyk 			HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
56542a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
56642a29337SGrzegorz Jaszczyk 
5670ade8cd8SKonstantin Porotchkin 	/* Set G2 TX amplitude and TX post emphasis value */
5680ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G2_SET_0_G2_TX_AMP_MASK;
56942a29337SGrzegorz Jaszczyk 	data = sata_static_values->g2_amp << HPIPE_G2_SET_0_G2_TX_AMP_OFFSET;
5700ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_0_G2_TX_AMP_ADJ_MASK;
57142a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g2_tx_amp_adj <<
57242a29337SGrzegorz Jaszczyk 			HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET;
5730ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_MASK;
57442a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g2_emph <<
57542a29337SGrzegorz Jaszczyk 			HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET;
5760ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_EN_MASK;
57742a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g2_emph_en <<
57842a29337SGrzegorz Jaszczyk 			HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET;
5790ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G2_SET_0_REG, data, mask);
5800ade8cd8SKonstantin Porotchkin 
58142a29337SGrzegorz Jaszczyk 	/* Set G2 emph */
58242a29337SGrzegorz Jaszczyk 	mask = HPIPE_G2_SET_2_G2_TX_EMPH0_EN_MASK;
58342a29337SGrzegorz Jaszczyk 	data = sata_static_values->g2_tx_emph_en <<
58442a29337SGrzegorz Jaszczyk 			HPIPE_G2_SET_2_G2_TX_EMPH0_EN_OFFSET;
58542a29337SGrzegorz Jaszczyk 	mask |= HPIPE_G2_SET_2_G2_TX_EMPH0_MASK;
58642a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g2_tx_emph <<
58742a29337SGrzegorz Jaszczyk 			HPIPE_G2_SET_2_G2_TX_EMPH0_OFFSET;
58842a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
58942a29337SGrzegorz Jaszczyk 
5900ade8cd8SKonstantin Porotchkin 	/* Set G3 TX amplitude and TX post emphasis value */
5910ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_SET_0_G3_TX_AMP_MASK;
59242a29337SGrzegorz Jaszczyk 	data = sata_static_values->g3_amp << HPIPE_G3_SET_0_G3_TX_AMP_OFFSET;
5930ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_0_G3_TX_AMP_ADJ_MASK;
59442a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g3_tx_amp_adj <<
59542a29337SGrzegorz Jaszczyk 			HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET;
5960ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_MASK;
59742a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g3_emph <<
59842a29337SGrzegorz Jaszczyk 			HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET;
5990ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_EN_MASK;
60042a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g3_emph_en <<
60142a29337SGrzegorz Jaszczyk 			HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET;
6020ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_MASK;
6030ade8cd8SKonstantin Porotchkin 	data |= 0x4 << HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET;
6040ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_MASK;
6050ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET;
6060ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SET_0_REG, data, mask);
6070ade8cd8SKonstantin Porotchkin 
60842a29337SGrzegorz Jaszczyk 	/* Set G3 emph */
60942a29337SGrzegorz Jaszczyk 	mask = HPIPE_G3_SET_2_G3_TX_EMPH0_EN_MASK;
61042a29337SGrzegorz Jaszczyk 	data = sata_static_values->g3_tx_emph_en <<
61142a29337SGrzegorz Jaszczyk 			HPIPE_G3_SET_2_G3_TX_EMPH0_EN_OFFSET;
61242a29337SGrzegorz Jaszczyk 	mask |= HPIPE_G3_SET_2_G3_TX_EMPH0_MASK;
61342a29337SGrzegorz Jaszczyk 	data |= sata_static_values->g3_tx_emph <<
61442a29337SGrzegorz Jaszczyk 			HPIPE_G3_SET_2_G3_TX_EMPH0_OFFSET;
61542a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_G3_SET_2_REG, data, mask);
61642a29337SGrzegorz Jaszczyk 
6170ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration 2 register */
6180ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG2_SSC_ENABLE_MASK;
6190ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET;
6200ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
6210ade8cd8SKonstantin Porotchkin 
6220ade8cd8SKonstantin Porotchkin 	/* DFE reset sequence */
6230ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
6240ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
6250ade8cd8SKonstantin Porotchkin 		HPIPE_PWR_CTR_RST_DFE_MASK);
6260ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
6270ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
6280ade8cd8SKonstantin Porotchkin 		HPIPE_PWR_CTR_RST_DFE_MASK);
6290ade8cd8SKonstantin Porotchkin 	/* SW reset for interrupt logic */
6300ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
6310ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
6320ade8cd8SKonstantin Porotchkin 		HPIPE_PWR_CTR_SFT_RST_MASK);
6330ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
6340ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
6350ade8cd8SKonstantin Porotchkin 		HPIPE_PWR_CTR_SFT_RST_MASK);
6360ade8cd8SKonstantin Porotchkin 
6370ade8cd8SKonstantin Porotchkin 	debug_exit();
6380ade8cd8SKonstantin Porotchkin 
6390ade8cd8SKonstantin Porotchkin 	return ret;
6400ade8cd8SKonstantin Porotchkin }
6410ade8cd8SKonstantin Porotchkin 
6420ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_sgmii_power_on(uint64_t comphy_base,
6430ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
6440ade8cd8SKonstantin Porotchkin {
6450ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
6460ade8cd8SKonstantin Porotchkin 	uint32_t mask, data, sgmii_speed = COMPHY_GET_SPEED(comphy_mode);
6470ade8cd8SKonstantin Porotchkin 	int ret = 0;
6480ade8cd8SKonstantin Porotchkin 
6490ade8cd8SKonstantin Porotchkin 	debug_enter();
6500ade8cd8SKonstantin Porotchkin 
6510ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
6520ade8cd8SKonstantin Porotchkin 				comphy_index);
6530ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
6540ade8cd8SKonstantin Porotchkin 			     comphy_index);
6550ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
6560ade8cd8SKonstantin Porotchkin 
6570ade8cd8SKonstantin Porotchkin 	/* configure phy selector for SGMII */
6580ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
6590ade8cd8SKonstantin Porotchkin 					    comphy_mode);
6600ade8cd8SKonstantin Porotchkin 
6610ade8cd8SKonstantin Porotchkin 	/* Confiugre the lane */
6620ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
6630ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
6640ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
6650ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
6660ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
6670ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
6680ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
6690ade8cd8SKonstantin Porotchkin 
6700ade8cd8SKonstantin Porotchkin 	/* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
6710ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
6720ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
6730ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
6740ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
6750ade8cd8SKonstantin Porotchkin 
6760ade8cd8SKonstantin Porotchkin 	if (sgmii_speed == COMPHY_SPEED_1_25G) {
6770ade8cd8SKonstantin Porotchkin 		/* SGMII 1G, SerDes speed 1.25G */
6780ade8cd8SKonstantin Porotchkin 		data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
6790ade8cd8SKonstantin Porotchkin 		data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
6800ade8cd8SKonstantin Porotchkin 	} else if (sgmii_speed == COMPHY_SPEED_3_125G) {
6810ade8cd8SKonstantin Porotchkin 		/* HS SGMII (2.5G), SerDes speed 3.125G */
6820ade8cd8SKonstantin Porotchkin 		data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
6830ade8cd8SKonstantin Porotchkin 		data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
6840ade8cd8SKonstantin Porotchkin 	} else {
6850ade8cd8SKonstantin Porotchkin 		/* Other rates are not supported */
6860ade8cd8SKonstantin Porotchkin 		ERROR("unsupported SGMII speed on comphy%d\n", comphy_index);
6870ade8cd8SKonstantin Porotchkin 		return -EINVAL;
6880ade8cd8SKonstantin Porotchkin 	}
6890ade8cd8SKonstantin Porotchkin 
6900ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
6910ade8cd8SKonstantin Porotchkin 	data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
6920ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
6930ade8cd8SKonstantin Porotchkin 	data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
6940ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
6950ade8cd8SKonstantin Porotchkin 	data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
6960ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
6970ade8cd8SKonstantin Porotchkin 
6980ade8cd8SKonstantin Porotchkin 	/* Set hard reset */
6990ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
7000ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
7010ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
7020ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
7030ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
7040ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
7050ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
7060ade8cd8SKonstantin Porotchkin 
7070ade8cd8SKonstantin Porotchkin 	/* Release hard reset */
7080ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
7090ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
7100ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
7110ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
7120ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
7130ade8cd8SKonstantin Porotchkin 
7140ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
7150ade8cd8SKonstantin Porotchkin 	mdelay(1);
7160ade8cd8SKonstantin Porotchkin 
7170ade8cd8SKonstantin Porotchkin 	/* Make sure that 40 data bits is disabled
7180ade8cd8SKonstantin Porotchkin 	 * This bit is not cleared by reset
7190ade8cd8SKonstantin Porotchkin 	 */
7200ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
7210ade8cd8SKonstantin Porotchkin 	data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
7220ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
7230ade8cd8SKonstantin Porotchkin 
7240ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
7250ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
7260ade8cd8SKonstantin Porotchkin 	/* set reference clock */
7270ade8cd8SKonstantin Porotchkin 	mask = HPIPE_MISC_REFCLK_SEL_MASK;
7280ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
7290ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
7300ade8cd8SKonstantin Porotchkin 	/* Power and PLL Control */
7310ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
7320ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
7330ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
7340ade8cd8SKonstantin Porotchkin 	data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
7350ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
7360ade8cd8SKonstantin Porotchkin 	/* Loopback register */
7370ade8cd8SKonstantin Porotchkin 	mask = HPIPE_LOOPBACK_SEL_MASK;
7380ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
7390ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
7400ade8cd8SKonstantin Porotchkin 	/* rx control 1 */
7410ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
7420ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
7430ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
7440ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
7450ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
7460ade8cd8SKonstantin Porotchkin 	/* DTL Control */
7470ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
7480ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
7490ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
7500ade8cd8SKonstantin Porotchkin 
75142a29337SGrzegorz Jaszczyk 	/* Set analog parameters from ETP(HW) - for now use the default data */
7520ade8cd8SKonstantin Porotchkin 	debug("stage: Analog parameters from ETP(HW)\n");
7530ade8cd8SKonstantin Porotchkin 
7540ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
7550ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
7560ade8cd8SKonstantin Porotchkin 		HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
7570ade8cd8SKonstantin Porotchkin 
7580ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
7590ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration */
7600ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
7610ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
7620ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
7630ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
7640ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
7650ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
7660ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
7670ade8cd8SKonstantin Porotchkin 
7680ade8cd8SKonstantin Porotchkin 	ret = mvebu_cp110_comphy_is_pll_locked(comphy_base, comphy_index);
7690ade8cd8SKonstantin Porotchkin 	if (ret)
7700ade8cd8SKonstantin Porotchkin 		return ret;
7710ade8cd8SKonstantin Porotchkin 
7720ade8cd8SKonstantin Porotchkin 	/* RX init */
7730ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
7740ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
7750ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
7760ade8cd8SKonstantin Porotchkin 
7770ade8cd8SKonstantin Porotchkin 	/* check that RX init done */
7780ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
7790ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
7800ade8cd8SKonstantin Porotchkin 	mask = data;
7810ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
7820ade8cd8SKonstantin Porotchkin 	if (data != 0) {
7830ade8cd8SKonstantin Porotchkin 		ERROR("RX init failed\n");
7840ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
7850ade8cd8SKonstantin Porotchkin 	}
7860ade8cd8SKonstantin Porotchkin 
7870ade8cd8SKonstantin Porotchkin 	debug("stage: RF Reset\n");
7880ade8cd8SKonstantin Porotchkin 	/* RF Reset */
7890ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
7900ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
7910ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
7920ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
7930ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
7940ade8cd8SKonstantin Porotchkin 
7950ade8cd8SKonstantin Porotchkin 	debug_exit();
7960ade8cd8SKonstantin Porotchkin 
7970ade8cd8SKonstantin Porotchkin 	return ret;
7980ade8cd8SKonstantin Porotchkin }
7990ade8cd8SKonstantin Porotchkin 
8000ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base,
8010ade8cd8SKonstantin Porotchkin 					   uint8_t comphy_index,
8020ade8cd8SKonstantin Porotchkin 					   uint32_t comphy_mode)
8030ade8cd8SKonstantin Porotchkin {
8040ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
8050ade8cd8SKonstantin Porotchkin 	uint32_t mask, data, speed = COMPHY_GET_SPEED(comphy_mode);
8060ade8cd8SKonstantin Porotchkin 	int ret = 0;
80742a29337SGrzegorz Jaszczyk 	uint8_t ap_nr, cp_nr;
8080ade8cd8SKonstantin Porotchkin 
8090ade8cd8SKonstantin Porotchkin 	debug_enter();
8100ade8cd8SKonstantin Porotchkin 
81142a29337SGrzegorz Jaszczyk 	mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
81242a29337SGrzegorz Jaszczyk 
81342a29337SGrzegorz Jaszczyk 	if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) {
81442a29337SGrzegorz Jaszczyk 		debug("Skip %s for comphy[%d][%d][%d], due to rx training\n",
81542a29337SGrzegorz Jaszczyk 		       __func__, ap_nr, cp_nr, comphy_index);
81642a29337SGrzegorz Jaszczyk 		return 0;
81742a29337SGrzegorz Jaszczyk 	}
81842a29337SGrzegorz Jaszczyk 
81942a29337SGrzegorz Jaszczyk 	const struct xfi_params *xfi_static_values =
82042a29337SGrzegorz Jaszczyk 			     &xfi_static_values_tab[ap_nr][cp_nr][comphy_index];
82142a29337SGrzegorz Jaszczyk 
82242a29337SGrzegorz Jaszczyk 	debug("%s: the ap_nr = %d, cp_nr = %d, comphy_index %d\n",
82342a29337SGrzegorz Jaszczyk 	      __func__, ap_nr, cp_nr, comphy_index);
82442a29337SGrzegorz Jaszczyk 
82542a29337SGrzegorz Jaszczyk 	debug("g1_ffe_cap_sel= 0x%x, g1_ffe_res_sel= 0x%x, g1_dfe_res= 0x%x\n",
82642a29337SGrzegorz Jaszczyk 	      xfi_static_values->g1_ffe_cap_sel,
82742a29337SGrzegorz Jaszczyk 	      xfi_static_values->g1_ffe_res_sel,
82842a29337SGrzegorz Jaszczyk 	      xfi_static_values->g1_dfe_res);
82942a29337SGrzegorz Jaszczyk 
83042a29337SGrzegorz Jaszczyk 	if (!xfi_static_values->valid) {
83142a29337SGrzegorz Jaszczyk 		ERROR("[ap%d][cp[%d][comphy:%d]: Has no valid static params\n",
83242a29337SGrzegorz Jaszczyk 		      ap_nr, cp_nr, comphy_index);
83342a29337SGrzegorz Jaszczyk 		ERROR("[ap%d][cp[%d][comphy:%d]: porting layer needs update\n",
83442a29337SGrzegorz Jaszczyk 		      ap_nr, cp_nr, comphy_index);
83542a29337SGrzegorz Jaszczyk 		return -EINVAL;
83642a29337SGrzegorz Jaszczyk 	}
83742a29337SGrzegorz Jaszczyk 
8380ade8cd8SKonstantin Porotchkin 	if ((speed != COMPHY_SPEED_5_15625G) &&
8390ade8cd8SKonstantin Porotchkin 	     (speed != COMPHY_SPEED_10_3125G) &&
8400ade8cd8SKonstantin Porotchkin 	     (speed != COMPHY_SPEED_DEFAULT)) {
8410ade8cd8SKonstantin Porotchkin 		ERROR("comphy:%d: unsupported sfi/xfi speed\n", comphy_index);
8420ade8cd8SKonstantin Porotchkin 		return -EINVAL;
8430ade8cd8SKonstantin Porotchkin 	}
8440ade8cd8SKonstantin Porotchkin 
8450ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
8460ade8cd8SKonstantin Porotchkin 				comphy_index);
8470ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
8480ade8cd8SKonstantin Porotchkin 			     comphy_index);
8490ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
8500ade8cd8SKonstantin Porotchkin 
8510ade8cd8SKonstantin Porotchkin 	/* configure phy selector for XFI/SFI */
8520ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
8530ade8cd8SKonstantin Porotchkin 					    comphy_mode);
8540ade8cd8SKonstantin Porotchkin 
8550ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
8560ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
8570ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
8580ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
8590ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
8600ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
8610ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
8620ade8cd8SKonstantin Porotchkin 
8630ade8cd8SKonstantin Porotchkin 	/* Make sure that 40 data bits is disabled
8640ade8cd8SKonstantin Porotchkin 	 * This bit is not cleared by reset
8650ade8cd8SKonstantin Porotchkin 	 */
8660ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
8670ade8cd8SKonstantin Porotchkin 	data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
8680ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
8690ade8cd8SKonstantin Porotchkin 
8700ade8cd8SKonstantin Porotchkin 	/* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
8710ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
8720ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
8730ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
8740ade8cd8SKonstantin Porotchkin 	data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
8750ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
8760ade8cd8SKonstantin Porotchkin 	data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
8770ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
8780ade8cd8SKonstantin Porotchkin 	data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
8790ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
8800ade8cd8SKonstantin Porotchkin 	data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
8810ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
8820ade8cd8SKonstantin Porotchkin 	data |= 0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
8830ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
8840ade8cd8SKonstantin Porotchkin 
8850ade8cd8SKonstantin Porotchkin 	/* release from hard reset */
8860ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
8870ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
8880ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
8890ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
8900ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
8910ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
8920ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
8930ade8cd8SKonstantin Porotchkin 
8940ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
8950ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
8960ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
8970ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
8980ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
8990ade8cd8SKonstantin Porotchkin 
9000ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
9010ade8cd8SKonstantin Porotchkin 	mdelay(1);
9020ade8cd8SKonstantin Porotchkin 
9030ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
9040ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
9050ade8cd8SKonstantin Porotchkin 	/* set reference clock */
9060ade8cd8SKonstantin Porotchkin 	mask = HPIPE_MISC_ICP_FORCE_MASK;
9070ade8cd8SKonstantin Porotchkin 	data = (speed == COMPHY_SPEED_5_15625G) ?
9080ade8cd8SKonstantin Porotchkin 		(0x0 << HPIPE_MISC_ICP_FORCE_OFFSET) :
9090ade8cd8SKonstantin Porotchkin 		(0x1 << HPIPE_MISC_ICP_FORCE_OFFSET);
9100ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_MISC_REFCLK_SEL_MASK;
9110ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
9120ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
9130ade8cd8SKonstantin Porotchkin 	/* Power and PLL Control */
9140ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
9150ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
9160ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
9170ade8cd8SKonstantin Porotchkin 	data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
9180ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
9190ade8cd8SKonstantin Porotchkin 	/* Loopback register */
9200ade8cd8SKonstantin Porotchkin 	mask = HPIPE_LOOPBACK_SEL_MASK;
9210ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
9220ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
9230ade8cd8SKonstantin Porotchkin 	/* rx control 1 */
9240ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
9250ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
9260ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
9270ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
9280ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
9290ade8cd8SKonstantin Porotchkin 	/* DTL Control */
9300ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
9310ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
9320ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
9330ade8cd8SKonstantin Porotchkin 
9340ade8cd8SKonstantin Porotchkin 	/* Transmitter/Receiver Speed Divider Force */
9350ade8cd8SKonstantin Porotchkin 	if (speed == COMPHY_SPEED_5_15625G) {
9360ade8cd8SKonstantin Porotchkin 		mask = HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_MASK;
9370ade8cd8SKonstantin Porotchkin 		data = 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET;
9380ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_MASK;
9390ade8cd8SKonstantin Porotchkin 		data |= 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET;
9400ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_MASK;
9410ade8cd8SKonstantin Porotchkin 		data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET;
9420ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_MASK;
9430ade8cd8SKonstantin Porotchkin 		data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET;
9440ade8cd8SKonstantin Porotchkin 	} else {
9450ade8cd8SKonstantin Porotchkin 		mask = HPIPE_TXDIGCK_DIV_FORCE_MASK;
9460ade8cd8SKonstantin Porotchkin 		data = 0x1 << HPIPE_TXDIGCK_DIV_FORCE_OFFSET;
9470ade8cd8SKonstantin Porotchkin 	}
9480ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SPD_DIV_FORCE_REG, data, mask);
9490ade8cd8SKonstantin Porotchkin 
9500ade8cd8SKonstantin Porotchkin 	/* Set analog parameters from ETP(HW) */
9510ade8cd8SKonstantin Porotchkin 	debug("stage: Analog parameters from ETP(HW)\n");
9520ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration 2 */
9530ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK;
9540ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET;
9550ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
9560ade8cd8SKonstantin Porotchkin 	/* 0x7-DFE Resolution control */
9570ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_RES_FORCE_MASK;
9580ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
9590ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
9600ade8cd8SKonstantin Porotchkin 	/* 0xd-G1_Setting_0 */
9610ade8cd8SKonstantin Porotchkin 	if (speed == COMPHY_SPEED_5_15625G) {
9620ade8cd8SKonstantin Porotchkin 		mask = HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
9630ade8cd8SKonstantin Porotchkin 		data = 0x6 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
9640ade8cd8SKonstantin Porotchkin 	} else {
9650ade8cd8SKonstantin Porotchkin 		mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
96642a29337SGrzegorz Jaszczyk 		data = xfi_static_values->g1_amp <<
96742a29337SGrzegorz Jaszczyk 				HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
9680ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
96942a29337SGrzegorz Jaszczyk 		data |= xfi_static_values->g1_emph <<
97042a29337SGrzegorz Jaszczyk 				HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
97142a29337SGrzegorz Jaszczyk 
97242a29337SGrzegorz Jaszczyk 		mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
97342a29337SGrzegorz Jaszczyk 		data |= xfi_static_values->g1_emph_en <<
97442a29337SGrzegorz Jaszczyk 				HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
97542a29337SGrzegorz Jaszczyk 		mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
97642a29337SGrzegorz Jaszczyk 		data |= xfi_static_values->g1_tx_amp_adj <<
97742a29337SGrzegorz Jaszczyk 				HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
9780ade8cd8SKonstantin Porotchkin 	}
9790ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
9800ade8cd8SKonstantin Porotchkin 	/* Genration 1 setting 2 (G1_Setting_2) */
9810ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
98242a29337SGrzegorz Jaszczyk 	data = xfi_static_values->g1_tx_emph <<
98342a29337SGrzegorz Jaszczyk 				HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
9840ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
98542a29337SGrzegorz Jaszczyk 	data |= xfi_static_values->g1_tx_emph_en <<
98642a29337SGrzegorz Jaszczyk 				HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
9870ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
9880ade8cd8SKonstantin Porotchkin 	/* Transmitter Slew Rate Control register (tx_reg1) */
9890ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_REG1_TX_EMPH_RES_MASK;
9900ade8cd8SKonstantin Porotchkin 	data = 0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET;
9910ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_REG1_SLC_EN_MASK;
9920ade8cd8SKonstantin Porotchkin 	data |= 0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET;
9930ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_REG1_REG, data, mask);
9940ade8cd8SKonstantin Porotchkin 	/* Impedance Calibration Control register (cal_reg1) */
9950ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CAL_REG_1_EXT_TXIMP_MASK;
9960ade8cd8SKonstantin Porotchkin 	data = 0xe << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
9970ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK;
9980ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET;
9990ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_CAL_REG1_REG, data, mask);
10000ade8cd8SKonstantin Porotchkin 	/* Generation 1 Setting 5 (g1_setting_5) */
10010ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTING_5_G1_ICP_MASK;
10020ade8cd8SKonstantin Porotchkin 	data = 0 << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
10030ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SETTING_5_REG, data, mask);
10040ade8cd8SKonstantin Porotchkin 
10050ade8cd8SKonstantin Porotchkin 	/* 0xE-G1_Setting_1 */
10060ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
10070ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
10080ade8cd8SKonstantin Porotchkin 	if (speed == COMPHY_SPEED_5_15625G) {
10090ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
10100ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
10113c0024ccSGrzegorz Jaszczyk 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
10123c0024ccSGrzegorz Jaszczyk 		data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
10130ade8cd8SKonstantin Porotchkin 	} else {
10140ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
101542a29337SGrzegorz Jaszczyk 		data |= xfi_static_values->g1_rx_selmupi <<
101642a29337SGrzegorz Jaszczyk 				HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
10173c0024ccSGrzegorz Jaszczyk 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
101842a29337SGrzegorz Jaszczyk 		data |= xfi_static_values->g1_rx_selmupf <<
101942a29337SGrzegorz Jaszczyk 				HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
10200ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
102142a29337SGrzegorz Jaszczyk 		data |= xfi_static_values->g1_rx_selmufi <<
102242a29337SGrzegorz Jaszczyk 				HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
10230ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
102442a29337SGrzegorz Jaszczyk 		data |= xfi_static_values->g1_rx_selmuff <<
102542a29337SGrzegorz Jaszczyk 				HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
10260ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
10270ade8cd8SKonstantin Porotchkin 		data |= 0x3 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
10280ade8cd8SKonstantin Porotchkin 	}
10290ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
10300ade8cd8SKonstantin Porotchkin 
10310ade8cd8SKonstantin Porotchkin 	/* 0xA-DFE_Reg3 */
10320ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
10330ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
10340ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
10350ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
10360ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
10370ade8cd8SKonstantin Porotchkin 
10380ade8cd8SKonstantin Porotchkin 	/* 0x111-G1_Setting_4 */
10390ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
10400ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
10410ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
10420ade8cd8SKonstantin Porotchkin 	/* Genration 1 setting 3 (G1_Setting_3) */
10430ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK;
10440ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET;
10450ade8cd8SKonstantin Porotchkin 	if (speed == COMPHY_SPEED_5_15625G) {
10460ade8cd8SKonstantin Porotchkin 		/* Force FFE (Feed Forward Equalization) to 5G */
10470ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
10480ade8cd8SKonstantin Porotchkin 		data |= 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
10490ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
10500ade8cd8SKonstantin Porotchkin 		data |= 0x4 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
10510ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
10520ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
10530ade8cd8SKonstantin Porotchkin 		reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
105442a29337SGrzegorz Jaszczyk 	} else {
105542a29337SGrzegorz Jaszczyk 		mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
105642a29337SGrzegorz Jaszczyk 		data |= xfi_static_values->g1_ffe_cap_sel <<
105742a29337SGrzegorz Jaszczyk 			HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
105842a29337SGrzegorz Jaszczyk 		mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
105942a29337SGrzegorz Jaszczyk 		data |= xfi_static_values->g1_ffe_res_sel <<
106042a29337SGrzegorz Jaszczyk 			HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
106142a29337SGrzegorz Jaszczyk 		mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
106242a29337SGrzegorz Jaszczyk 		data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
106342a29337SGrzegorz Jaszczyk 		reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
106442a29337SGrzegorz Jaszczyk 
106542a29337SGrzegorz Jaszczyk 		/* Use the value from CAL_OS_PH_EXT */
106642a29337SGrzegorz Jaszczyk 		mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
106742a29337SGrzegorz Jaszczyk 		data = 1 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
106842a29337SGrzegorz Jaszczyk 		reg_set(hpipe_addr +
106942a29337SGrzegorz Jaszczyk 			HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
107042a29337SGrzegorz Jaszczyk 			data, mask);
107142a29337SGrzegorz Jaszczyk 
107242a29337SGrzegorz Jaszczyk 		/* Update align90 */
107342a29337SGrzegorz Jaszczyk 		mask = HPIPE_CAL_OS_PH_EXT_MASK;
107442a29337SGrzegorz Jaszczyk 		data = xfi_static_values->align90 << HPIPE_CAL_OS_PH_EXT_OFFSET;
107542a29337SGrzegorz Jaszczyk 		reg_set(hpipe_addr +
107642a29337SGrzegorz Jaszczyk 			HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
107742a29337SGrzegorz Jaszczyk 			data, mask);
107842a29337SGrzegorz Jaszczyk 
107942a29337SGrzegorz Jaszczyk 		/* Force DFE resolution (use gen table value) */
108042a29337SGrzegorz Jaszczyk 		mask = HPIPE_DFE_RES_FORCE_MASK;
108142a29337SGrzegorz Jaszczyk 		data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
108242a29337SGrzegorz Jaszczyk 		reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
108342a29337SGrzegorz Jaszczyk 
108442a29337SGrzegorz Jaszczyk 		/* 0x111-G1 DFE_Setting_4 */
108542a29337SGrzegorz Jaszczyk 		mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
108642a29337SGrzegorz Jaszczyk 		data = xfi_static_values->g1_dfe_res <<
108742a29337SGrzegorz Jaszczyk 			HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
108842a29337SGrzegorz Jaszczyk 		reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
108942a29337SGrzegorz Jaszczyk 	}
10900ade8cd8SKonstantin Porotchkin 
10910ade8cd8SKonstantin Porotchkin 	/* Connfigure RX training timer */
10920ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RX_TRAIN_TIMER_MASK;
10930ade8cd8SKonstantin Porotchkin 	data = 0x13 << HPIPE_RX_TRAIN_TIMER_OFFSET;
10940ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
10950ade8cd8SKonstantin Porotchkin 
10960ade8cd8SKonstantin Porotchkin 	/* Enable TX train peak to peak hold */
10970ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
10980ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
10990ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
11000ade8cd8SKonstantin Porotchkin 
11010ade8cd8SKonstantin Porotchkin 	/* Configure TX preset index */
11020ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_PRESET_INDEX_MASK;
11030ade8cd8SKonstantin Porotchkin 	data = 0x2 << HPIPE_TX_PRESET_INDEX_OFFSET;
11040ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_PRESET_INDEX_REG, data, mask);
11050ade8cd8SKonstantin Porotchkin 
11060ade8cd8SKonstantin Porotchkin 	/* Disable pattern lock lost timeout */
11070ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
11080ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
11090ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
11100ade8cd8SKonstantin Porotchkin 
11110ade8cd8SKonstantin Porotchkin 	/* Configure TX training pattern and TX training 16bit auto */
11120ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_16BIT_AUTO_EN_MASK;
11130ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET;
11140ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_PAT_SEL_MASK;
11150ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_TX_TRAIN_PAT_SEL_OFFSET;
11160ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
11170ade8cd8SKonstantin Porotchkin 
11180ade8cd8SKonstantin Porotchkin 	/* Configure Training patten number */
11190ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TRAIN_PAT_NUM_MASK;
11200ade8cd8SKonstantin Porotchkin 	data = 0x88 << HPIPE_TRAIN_PAT_NUM_OFFSET;
11210ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_0_REG, data, mask);
11220ade8cd8SKonstantin Porotchkin 
11230ade8cd8SKonstantin Porotchkin 	/* Configure differencial manchester encoter to ethernet mode */
11240ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DME_ETHERNET_MODE_MASK;
11250ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_DME_ETHERNET_MODE_OFFSET;
11260ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DME_REG, data, mask);
11270ade8cd8SKonstantin Porotchkin 
11280ade8cd8SKonstantin Porotchkin 	/* Configure VDD Continuous Calibration */
11290ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CAL_VDD_CONT_MODE_MASK;
11300ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_CAL_VDD_CONT_MODE_OFFSET;
11310ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_VDD_CAL_0_REG, data, mask);
11320ade8cd8SKonstantin Porotchkin 
11330ade8cd8SKonstantin Porotchkin 	/* Trigger sampler enable pulse (by toggleing the bit) */
11340ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RX_SAMPLER_OS_GAIN_MASK;
11350ade8cd8SKonstantin Porotchkin 	data = 0x3 << HPIPE_RX_SAMPLER_OS_GAIN_OFFSET;
11360ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_SMAPLER_MASK;
11370ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_SMAPLER_OFFSET;
11380ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
11390ade8cd8SKonstantin Porotchkin 	mask = HPIPE_SMAPLER_MASK;
11400ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_SMAPLER_OFFSET;
11410ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
11420ade8cd8SKonstantin Porotchkin 
11430ade8cd8SKonstantin Porotchkin 	/* Set External RX Regulator Control */
11440ade8cd8SKonstantin Porotchkin 	mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
11450ade8cd8SKonstantin Porotchkin 	data = 0x1A << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
11460ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
11470ade8cd8SKonstantin Porotchkin 
11480ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
11490ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration */
11500ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
11510ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
11520ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
11530ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
11540ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
11550ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
11560ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
11570ade8cd8SKonstantin Porotchkin 
11580ade8cd8SKonstantin Porotchkin 	/* check PLL rx & tx ready */
11590ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
11600ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
11610ade8cd8SKonstantin Porotchkin 	       SD_EXTERNAL_STATUS0_PLL_TX_MASK;
11620ade8cd8SKonstantin Porotchkin 	mask = data;
11630ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask,
11640ade8cd8SKonstantin Porotchkin 				    PLL_LOCK_TIMEOUT, REG_32BIT);
11650ade8cd8SKonstantin Porotchkin 	if (data != 0) {
11660ade8cd8SKonstantin Porotchkin 		if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
11670ade8cd8SKonstantin Porotchkin 			ERROR("RX PLL is not locked\n");
11680ade8cd8SKonstantin Porotchkin 		if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
11690ade8cd8SKonstantin Porotchkin 			ERROR("TX PLL is not locked\n");
11700ade8cd8SKonstantin Porotchkin 
11710ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
11720ade8cd8SKonstantin Porotchkin 	}
11730ade8cd8SKonstantin Porotchkin 
11740ade8cd8SKonstantin Porotchkin 	/* RX init */
11750ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
11760ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
11770ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
11780ade8cd8SKonstantin Porotchkin 
11790ade8cd8SKonstantin Porotchkin 	/* check that RX init done */
11800ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
11810ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
11820ade8cd8SKonstantin Porotchkin 	mask = data;
11830ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
11840ade8cd8SKonstantin Porotchkin 	if (data != 0) {
11850ade8cd8SKonstantin Porotchkin 		ERROR("RX init failed\n");
11860ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
11870ade8cd8SKonstantin Porotchkin 	}
11880ade8cd8SKonstantin Porotchkin 
11890ade8cd8SKonstantin Porotchkin 	debug("stage: RF Reset\n");
11900ade8cd8SKonstantin Porotchkin 	/* RF Reset */
11910ade8cd8SKonstantin Porotchkin 	mask =  SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
11920ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
11930ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
11940ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
11950ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
11960ade8cd8SKonstantin Porotchkin 
11970ade8cd8SKonstantin Porotchkin 	debug_exit();
11980ade8cd8SKonstantin Porotchkin 
11990ade8cd8SKonstantin Porotchkin 	return ret;
12000ade8cd8SKonstantin Porotchkin }
12010ade8cd8SKonstantin Porotchkin 
12020ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_pcie_power_on(uint64_t comphy_base,
12030ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
12040ade8cd8SKonstantin Porotchkin {
12050ade8cd8SKonstantin Porotchkin 	int ret = 0;
12060ade8cd8SKonstantin Porotchkin 	uint32_t reg, mask, data, pcie_width;
12070ade8cd8SKonstantin Porotchkin 	uint32_t clk_dir;
12080ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, comphy_addr, addr;
12090ade8cd8SKonstantin Porotchkin 	_Bool clk_src = COMPHY_GET_CLK_SRC(comphy_mode);
121055df84f9SIgal Liberman 	_Bool called_from_uboot = COMPHY_GET_CALLER(comphy_mode);
121155df84f9SIgal Liberman 
121255df84f9SIgal Liberman 	/* In Armada 8K DB boards, PCIe initialization can be executed
121355df84f9SIgal Liberman 	 * only once (PCIe reset performed during chip power on and
121455df84f9SIgal Liberman 	 * it cannot be executed via GPIO later).
121555df84f9SIgal Liberman 	 * This means that power on can be executed only once, so let's
121655df84f9SIgal Liberman 	 * mark if the caller is bootloader or Linux.
121755df84f9SIgal Liberman 	 * If bootloader -> run power on.
121855df84f9SIgal Liberman 	 * If Linux -> exit.
121955df84f9SIgal Liberman 	 *
122055df84f9SIgal Liberman 	 * TODO: In MacciatoBIN, PCIe reset is connected via GPIO,
122155df84f9SIgal Liberman 	 * so after GPIO reset is added to Linux Kernel, it can be
122255df84f9SIgal Liberman 	 * powered-on by Linux.
122355df84f9SIgal Liberman 	 */
122455df84f9SIgal Liberman 	if (!called_from_uboot)
122555df84f9SIgal Liberman 		return ret;
12260ade8cd8SKonstantin Porotchkin 
12270ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
12280ade8cd8SKonstantin Porotchkin 				comphy_index);
12290ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
12300ade8cd8SKonstantin Porotchkin 	pcie_width = COMPHY_GET_PCIE_WIDTH(comphy_mode);
12310ade8cd8SKonstantin Porotchkin 
12320ade8cd8SKonstantin Porotchkin 	debug_enter();
12330ade8cd8SKonstantin Porotchkin 
12340ade8cd8SKonstantin Porotchkin 	spin_lock(&cp110_mac_reset_lock);
12350ade8cd8SKonstantin Porotchkin 
12360ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
12370ade8cd8SKonstantin Porotchkin 						SYS_CTRL_UINIT_SOFT_RESET_REG);
12380ade8cd8SKonstantin Porotchkin 	switch (comphy_index) {
12390ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE0:
12400ade8cd8SKonstantin Porotchkin 		reg |= PCIE_MAC_RESET_MASK_PORT0;
12410ade8cd8SKonstantin Porotchkin 		break;
12420ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE4:
12430ade8cd8SKonstantin Porotchkin 		reg |= PCIE_MAC_RESET_MASK_PORT1;
12440ade8cd8SKonstantin Porotchkin 		break;
12450ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE5:
12460ade8cd8SKonstantin Porotchkin 		reg |= PCIE_MAC_RESET_MASK_PORT2;
12470ade8cd8SKonstantin Porotchkin 		break;
12480ade8cd8SKonstantin Porotchkin 	}
12490ade8cd8SKonstantin Porotchkin 
12500ade8cd8SKonstantin Porotchkin 	mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
12510ade8cd8SKonstantin Porotchkin 					    SYS_CTRL_UINIT_SOFT_RESET_REG, reg);
12520ade8cd8SKonstantin Porotchkin 	spin_unlock(&cp110_mac_reset_lock);
12530ade8cd8SKonstantin Porotchkin 
12540ade8cd8SKonstantin Porotchkin 	/* Configure PIPE selector for PCIE */
12550ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
12560ade8cd8SKonstantin Porotchkin 					     comphy_mode);
12570ade8cd8SKonstantin Porotchkin 
12580ade8cd8SKonstantin Porotchkin 	/*
12590ade8cd8SKonstantin Porotchkin 	 * Read SAR (Sample-At-Reset) configuration for the PCIe clock
12600ade8cd8SKonstantin Porotchkin 	 * direction.
12610ade8cd8SKonstantin Porotchkin 	 *
12620ade8cd8SKonstantin Porotchkin 	 * SerDes Lane 4/5 got the PCIe ref-clock #1,
12630ade8cd8SKonstantin Porotchkin 	 * and SerDes Lane 0 got PCIe ref-clock #0
12640ade8cd8SKonstantin Porotchkin 	 */
12650ade8cd8SKonstantin Porotchkin 	reg = mmio_read_32(DFX_FROM_COMPHY_ADDR(comphy_base) +
12660ade8cd8SKonstantin Porotchkin 			   SAR_STATUS_0_REG);
12670ade8cd8SKonstantin Porotchkin 	if (comphy_index == COMPHY_LANE4 || comphy_index == COMPHY_LANE5)
12680ade8cd8SKonstantin Porotchkin 		clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK) >>
12690ade8cd8SKonstantin Porotchkin 					  SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET;
12700ade8cd8SKonstantin Porotchkin 	else
12710ade8cd8SKonstantin Porotchkin 		clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK) >>
12720ade8cd8SKonstantin Porotchkin 					  SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET;
12730ade8cd8SKonstantin Porotchkin 
12740ade8cd8SKonstantin Porotchkin 	debug("On lane %d\n", comphy_index);
12750ade8cd8SKonstantin Porotchkin 	debug("PCIe clock direction = %x\n", clk_dir);
12760ade8cd8SKonstantin Porotchkin 	debug("PCIe Width = %d\n", pcie_width);
12770ade8cd8SKonstantin Porotchkin 
12780ade8cd8SKonstantin Porotchkin 	/* enable PCIe X4 and X2 */
12790ade8cd8SKonstantin Porotchkin 	if (comphy_index == COMPHY_LANE0) {
12800ade8cd8SKonstantin Porotchkin 		if (pcie_width == PCIE_LNK_X4) {
12810ade8cd8SKonstantin Porotchkin 			data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET;
12820ade8cd8SKonstantin Porotchkin 			mask = COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK;
12830ade8cd8SKonstantin Porotchkin 			reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
12840ade8cd8SKonstantin Porotchkin 				data, mask);
12850ade8cd8SKonstantin Porotchkin 		} else if (pcie_width == PCIE_LNK_X2) {
12860ade8cd8SKonstantin Porotchkin 			data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET;
12870ade8cd8SKonstantin Porotchkin 			mask = COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK;
12880ade8cd8SKonstantin Porotchkin 			reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
12890ade8cd8SKonstantin Porotchkin 		}
12900ade8cd8SKonstantin Porotchkin 	}
12910ade8cd8SKonstantin Porotchkin 
12920ade8cd8SKonstantin Porotchkin 	/* If PCIe clock is output and clock source from SerDes lane 5,
12930ade8cd8SKonstantin Porotchkin 	 * need to configure the clock-source MUX.
12940ade8cd8SKonstantin Porotchkin 	 * By default, the clock source is from lane 4
12950ade8cd8SKonstantin Porotchkin 	 */
12960ade8cd8SKonstantin Porotchkin 	if (clk_dir && clk_src && (comphy_index == COMPHY_LANE5)) {
12970ade8cd8SKonstantin Porotchkin 		data = DFX_DEV_GEN_PCIE_CLK_SRC_MUX <<
12980ade8cd8SKonstantin Porotchkin 						DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET;
12990ade8cd8SKonstantin Porotchkin 		mask = DFX_DEV_GEN_PCIE_CLK_SRC_MASK;
13000ade8cd8SKonstantin Porotchkin 		reg_set(DFX_FROM_COMPHY_ADDR(comphy_base) +
13010ade8cd8SKonstantin Porotchkin 			DFX_DEV_GEN_CTRL12_REG, data, mask);
13020ade8cd8SKonstantin Porotchkin 	}
13030ade8cd8SKonstantin Porotchkin 
13040ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
13050ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
13060ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
13070ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
13080ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
13090ade8cd8SKonstantin Porotchkin 	data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
13100ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
13110ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
13120ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
13130ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
13140ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_PHY_MODE_MASK;
13150ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET;
13160ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
13170ade8cd8SKonstantin Porotchkin 
13180ade8cd8SKonstantin Porotchkin 	/* release from hard reset */
13190ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
13200ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
13210ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
13220ade8cd8SKonstantin Porotchkin 	data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
13230ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
13240ade8cd8SKonstantin Porotchkin 
13250ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
13260ade8cd8SKonstantin Porotchkin 	mdelay(1);
13270ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
13280ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
13290ade8cd8SKonstantin Porotchkin 	/* Set PIPE soft reset */
13300ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
13310ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
13320ade8cd8SKonstantin Porotchkin 	/* Set PHY datapath width mode for V0 */
13330ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
13340ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
13350ade8cd8SKonstantin Porotchkin 	/* Set Data bus width USB mode for V0 */
13360ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
13370ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
13380ade8cd8SKonstantin Porotchkin 	/* Set CORE_CLK output frequency for 250Mhz */
13390ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
13400ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
13410ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
13420ade8cd8SKonstantin Porotchkin 	/* Set PLL ready delay for 0x2 */
13430ade8cd8SKonstantin Porotchkin 	data = 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET;
13440ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK;
13450ade8cd8SKonstantin Porotchkin 	if (pcie_width != PCIE_LNK_X1) {
13460ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET;
13470ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK;
13480ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET;
13490ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK;
13500ade8cd8SKonstantin Porotchkin 	}
13510ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, data, mask);
13520ade8cd8SKonstantin Porotchkin 
13530ade8cd8SKonstantin Porotchkin 	/* Set PIPE mode interface to PCIe3 - 0x1  & set lane order */
13540ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET;
13550ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CLK_SRC_HI_MODE_PIPE_MASK;
13560ade8cd8SKonstantin Porotchkin 	if (pcie_width != PCIE_LNK_X1) {
13570ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_CLK_SRC_HI_LANE_STRT_MASK;
13580ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_CLK_SRC_HI_LANE_MASTER_MASK;
13590ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_CLK_SRC_HI_LANE_BREAK_MASK;
13600ade8cd8SKonstantin Porotchkin 		if (comphy_index == 0) {
13610ade8cd8SKonstantin Porotchkin 			data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET;
13620ade8cd8SKonstantin Porotchkin 			data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET;
13630ade8cd8SKonstantin Porotchkin 		} else if (comphy_index == (pcie_width - 1)) {
13640ade8cd8SKonstantin Porotchkin 			data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET;
13650ade8cd8SKonstantin Porotchkin 		}
13660ade8cd8SKonstantin Porotchkin 	}
13670ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_CLK_SRC_HI_REG, data, mask);
13680ade8cd8SKonstantin Porotchkin 	/* Config update polarity equalization */
13690ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET;
13700ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CFG_UPDATE_POLARITY_MASK;
13710ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG1_REG, data, mask);
13720ade8cd8SKonstantin Porotchkin 	/* Set PIPE version 4 to mode enable */
13730ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET;
13740ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_CTRL_28_PIPE4_MASK;
13750ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_CTRL_28_REG, data, mask);
13760ade8cd8SKonstantin Porotchkin 	/* TODO: check if pcie clock is output/input - for bringup use input*/
13770ade8cd8SKonstantin Porotchkin 	/* Enable PIN clock 100M_125M */
13780ade8cd8SKonstantin Porotchkin 	mask = 0;
13790ade8cd8SKonstantin Porotchkin 	data = 0;
13800ade8cd8SKonstantin Porotchkin 	/* Only if clock is output, configure the clock-source mux */
13810ade8cd8SKonstantin Porotchkin 	if (clk_dir) {
13820ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_MISC_CLK100M_125M_MASK;
13830ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET;
13840ade8cd8SKonstantin Porotchkin 	}
13850ade8cd8SKonstantin Porotchkin 	/* Set PIN_TXDCLK_2X Clock Freq. Selection for outputs 500MHz clock */
13860ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_MISC_TXDCLK_2X_MASK;
13870ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET;
13880ade8cd8SKonstantin Porotchkin 	/* Enable 500MHz Clock */
13890ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_MISC_CLK500_EN_MASK;
13900ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET;
13910ade8cd8SKonstantin Porotchkin 	if (clk_dir) { /* output */
13920ade8cd8SKonstantin Porotchkin 		/* Set reference clock comes from group 1 */
13930ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_MISC_REFCLK_SEL_MASK;
13940ade8cd8SKonstantin Porotchkin 		data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
13950ade8cd8SKonstantin Porotchkin 	} else {
13960ade8cd8SKonstantin Porotchkin 		/* Set reference clock comes from group 2 */
13970ade8cd8SKonstantin Porotchkin 		mask |= HPIPE_MISC_REFCLK_SEL_MASK;
13980ade8cd8SKonstantin Porotchkin 		data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET;
13990ade8cd8SKonstantin Porotchkin 	}
14000ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_MISC_ICP_FORCE_MASK;
14010ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_MISC_ICP_FORCE_OFFSET;
14020ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
14030ade8cd8SKonstantin Porotchkin 	if (clk_dir) { /* output */
14040ade8cd8SKonstantin Porotchkin 		/* Set reference frequcency select - 0x2 for 25MHz*/
14050ade8cd8SKonstantin Porotchkin 		mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
14060ade8cd8SKonstantin Porotchkin 		data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
14070ade8cd8SKonstantin Porotchkin 	} else {
14080ade8cd8SKonstantin Porotchkin 		/* Set reference frequcency select - 0x0 for 100MHz*/
14090ade8cd8SKonstantin Porotchkin 		mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
14100ade8cd8SKonstantin Porotchkin 		data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
14110ade8cd8SKonstantin Porotchkin 	}
14120ade8cd8SKonstantin Porotchkin 	/* Set PHY mode to PCIe */
14130ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
14140ade8cd8SKonstantin Porotchkin 	data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
14150ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
14160ade8cd8SKonstantin Porotchkin 
14170ade8cd8SKonstantin Porotchkin 	/* ref clock alignment */
14180ade8cd8SKonstantin Porotchkin 	if (pcie_width != PCIE_LNK_X1) {
14190ade8cd8SKonstantin Porotchkin 		mask = HPIPE_LANE_ALIGN_OFF_MASK;
14200ade8cd8SKonstantin Porotchkin 		data = 0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET;
14210ade8cd8SKonstantin Porotchkin 		reg_set(hpipe_addr + HPIPE_LANE_ALIGN_REG, data, mask);
14220ade8cd8SKonstantin Porotchkin 	}
14230ade8cd8SKonstantin Porotchkin 
14240ade8cd8SKonstantin Porotchkin 	/* Set the amount of time spent in the LoZ state - set for 0x7 only if
14250ade8cd8SKonstantin Porotchkin 	 * the PCIe clock is output
14260ade8cd8SKonstantin Porotchkin 	 */
14270ade8cd8SKonstantin Porotchkin 	if (clk_dir)
14280ade8cd8SKonstantin Porotchkin 		reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
14290ade8cd8SKonstantin Porotchkin 			0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
14300ade8cd8SKonstantin Porotchkin 			HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
14310ade8cd8SKonstantin Porotchkin 
14320ade8cd8SKonstantin Porotchkin 	/* Set Maximal PHY Generation Setting(8Gbps) */
14330ade8cd8SKonstantin Porotchkin 	mask = HPIPE_INTERFACE_GEN_MAX_MASK;
14340ade8cd8SKonstantin Porotchkin 	data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET;
14350ade8cd8SKonstantin Porotchkin 	/* Bypass frame detection and sync detection for RX DATA */
14360ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_INTERFACE_DET_BYPASS_MASK;
14370ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET;
14380ade8cd8SKonstantin Porotchkin 	/* Set Link Train Mode (Tx training control pins are used) */
14390ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK;
14400ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET;
14410ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_INTERFACE_REG, data, mask);
14420ade8cd8SKonstantin Porotchkin 
14430ade8cd8SKonstantin Porotchkin 	/* Set Idle_sync enable */
14440ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PCIE_IDLE_SYNC_MASK;
14450ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET;
14460ade8cd8SKonstantin Porotchkin 	/* Select bits for PCIE Gen3(32bit) */
14470ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PCIE_SEL_BITS_MASK;
14480ade8cd8SKonstantin Porotchkin 	data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET;
14490ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PCIE_REG0, data, mask);
14500ade8cd8SKonstantin Porotchkin 
14510ade8cd8SKonstantin Porotchkin 	/* Enable Tx_adapt_g1 */
14520ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_CTRL_G1_MASK;
14530ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET;
14540ade8cd8SKonstantin Porotchkin 	/* Enable Tx_adapt_gn1 */
14550ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK;
14560ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET;
14570ade8cd8SKonstantin Porotchkin 	/* Disable Tx_adapt_g0 */
14580ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK;
14590ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
14600ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
14610ade8cd8SKonstantin Porotchkin 
14620ade8cd8SKonstantin Porotchkin 	/* Set reg_tx_train_chk_init */
14630ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_CHK_INIT_MASK;
14640ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET;
14650ade8cd8SKonstantin Porotchkin 	/* Enable TX_COE_FM_PIN_PCIE3_EN */
14660ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK;
14670ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET;
14680ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
14690ade8cd8SKonstantin Porotchkin 
14700ade8cd8SKonstantin Porotchkin 	debug("stage: TRx training parameters\n");
14710ade8cd8SKonstantin Porotchkin 	/* Set Preset sweep configurations */
14720ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TX_STATUS_CHECK_MODE_MASK;
14730ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET;
14740ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_NUM_OF_PRESET_MASK;
14750ade8cd8SKonstantin Porotchkin 	data |= 0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET;
14760ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_SWEEP_PRESET_EN_MASK;
14770ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET;
14780ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_11_REG, data, mask);
14790ade8cd8SKonstantin Porotchkin 
14800ade8cd8SKonstantin Porotchkin 	/* Tx train start configuration */
14810ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_START_SQ_EN_MASK;
14820ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET;
14830ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK;
14840ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET;
14850ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK;
14860ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET;
14870ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK;
14880ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET;
14890ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
14900ade8cd8SKonstantin Porotchkin 
14910ade8cd8SKonstantin Porotchkin 	/* Enable Tx train P2P */
14920ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
14930ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
14940ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
14950ade8cd8SKonstantin Porotchkin 
14960ade8cd8SKonstantin Porotchkin 	/* Configure Tx train timeout */
14970ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TRX_TRAIN_TIMER_MASK;
14980ade8cd8SKonstantin Porotchkin 	data = 0x17 << HPIPE_TRX_TRAIN_TIMER_OFFSET;
14990ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_4_REG, data, mask);
15000ade8cd8SKonstantin Porotchkin 
15010ade8cd8SKonstantin Porotchkin 	/* Disable G0/G1/GN1 adaptation */
15020ade8cd8SKonstantin Porotchkin 	mask = HPIPE_TX_TRAIN_CTRL_G1_MASK | HPIPE_TX_TRAIN_CTRL_GN1_MASK
15030ade8cd8SKonstantin Porotchkin 		| HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
15040ade8cd8SKonstantin Porotchkin 	data = 0;
15050ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
15060ade8cd8SKonstantin Porotchkin 
15070ade8cd8SKonstantin Porotchkin 	/* Disable DTL frequency loop */
15080ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
15090ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
15100ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
15110ade8cd8SKonstantin Porotchkin 
15120ade8cd8SKonstantin Porotchkin 	/* Configure G3 DFE */
15130ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_DFE_RES_MASK;
15140ade8cd8SKonstantin Porotchkin 	data = 0x3 << HPIPE_G3_DFE_RES_OFFSET;
15150ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
15160ade8cd8SKonstantin Porotchkin 
15170ade8cd8SKonstantin Porotchkin 	/* Use TX/RX training result for DFE */
15180ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_RES_FORCE_MASK;
15190ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
15200ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_REG0,  data, mask);
15210ade8cd8SKonstantin Porotchkin 
15220ade8cd8SKonstantin Porotchkin 	/* Configure initial and final coefficient value for receiver */
15230ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
15240ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
15250ade8cd8SKonstantin Porotchkin 
15260ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
15270ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
15280ade8cd8SKonstantin Porotchkin 
15290ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
15300ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
15310ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SET_1_REG,  data, mask);
15320ade8cd8SKonstantin Porotchkin 
15330ade8cd8SKonstantin Porotchkin 	/* Trigger sampler enable pulse */
15340ade8cd8SKonstantin Porotchkin 	mask = HPIPE_SMAPLER_MASK;
15350ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_SMAPLER_OFFSET;
15360ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
15370ade8cd8SKonstantin Porotchkin 	udelay(5);
15380ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, 0, mask);
15390ade8cd8SKonstantin Porotchkin 
15400ade8cd8SKonstantin Porotchkin 	/* FFE resistor tuning for different bandwidth  */
15410ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
15420ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
15430ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
15440ade8cd8SKonstantin Porotchkin 	data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
15450ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
15460ade8cd8SKonstantin Porotchkin 
15470ade8cd8SKonstantin Porotchkin 	/* Pattern lock lost timeout disable */
15480ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
15490ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
15500ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
15510ade8cd8SKonstantin Porotchkin 
15520ade8cd8SKonstantin Porotchkin 	/* Configure DFE adaptations */
15530ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK;
15540ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET;
15550ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK;
15560ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET;
15570ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_CDR_MAX_DFE_ADAPT_0_MASK;
15580ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET;
15590ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_CDR_MAX_DFE_ADAPT_1_MASK;
15600ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET;
15610ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
15620ade8cd8SKonstantin Porotchkin 
15630ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK;
15640ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET;
15650ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_CONTROL_REG, data, mask);
15660ade8cd8SKonstantin Porotchkin 
15670ade8cd8SKonstantin Porotchkin 	/* Genration 2 setting 1*/
15680ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
15690ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
15703c0024ccSGrzegorz Jaszczyk 	mask |= HPIPE_G2_SET_1_G2_RX_SELMUPF_MASK;
15713c0024ccSGrzegorz Jaszczyk 	data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPF_OFFSET;
15720ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
15730ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
15740ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
15750ade8cd8SKonstantin Porotchkin 
15760ade8cd8SKonstantin Porotchkin 	/* DFE enable */
15770ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G2_DFE_RES_MASK;
15780ade8cd8SKonstantin Porotchkin 	data = 0x3 << HPIPE_G2_DFE_RES_OFFSET;
15790ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G2_SETTINGS_4_REG, data, mask);
15800ade8cd8SKonstantin Porotchkin 
15810ade8cd8SKonstantin Porotchkin 	/* Configure DFE Resolution */
15820ade8cd8SKonstantin Porotchkin 	mask = HPIPE_LANE_CFG4_DFE_EN_SEL_MASK;
15830ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET;
15840ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
15850ade8cd8SKonstantin Porotchkin 
15860ade8cd8SKonstantin Porotchkin 	/* VDD calibration control */
15870ade8cd8SKonstantin Porotchkin 	mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
15880ade8cd8SKonstantin Porotchkin 	data = 0x16 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
15890ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
15900ade8cd8SKonstantin Porotchkin 
15910ade8cd8SKonstantin Porotchkin 	/* Set PLL Charge-pump Current Control */
15920ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G3_SETTING_5_G3_ICP_MASK;
15930ade8cd8SKonstantin Porotchkin 	data = 0x4 << HPIPE_G3_SETTING_5_G3_ICP_OFFSET;
15940ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G3_SETTING_5_REG, data, mask);
15950ade8cd8SKonstantin Porotchkin 
15960ade8cd8SKonstantin Porotchkin 	/* Set lane rqualization remote setting */
15970ade8cd8SKonstantin Porotchkin 	mask = HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK;
15980ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET;
15990ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK;
16000ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET;
16010ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK;
16020ade8cd8SKonstantin Porotchkin 	data |= 0x6 << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET;
16030ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_EQ_REMOTE_SETTING_REG, data, mask);
16040ade8cd8SKonstantin Porotchkin 
16050ade8cd8SKonstantin Porotchkin 	mask = HPIPE_CFG_EQ_BUNDLE_DIS_MASK;
16060ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET;
16070ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG2_REG, data, mask);
16080ade8cd8SKonstantin Porotchkin 
16090ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy power up\n");
16100ade8cd8SKonstantin Porotchkin 
16110ade8cd8SKonstantin Porotchkin 	/* For PCIe X4 or X2:
16120ade8cd8SKonstantin Porotchkin 	 * release from reset only after finish to configure all lanes
16130ade8cd8SKonstantin Porotchkin 	 */
16140ade8cd8SKonstantin Porotchkin 	if ((pcie_width == PCIE_LNK_X1) || (comphy_index == (pcie_width - 1))) {
16150ade8cd8SKonstantin Porotchkin 		uint32_t i, start_lane, end_lane;
16160ade8cd8SKonstantin Porotchkin 
16170ade8cd8SKonstantin Porotchkin 		if (pcie_width != PCIE_LNK_X1) {
16180ade8cd8SKonstantin Porotchkin 			/* allows writing to all lanes in one write */
16190ade8cd8SKonstantin Porotchkin 			data = 0x0;
16200ade8cd8SKonstantin Porotchkin 			if (pcie_width == PCIE_LNK_X2)
16210ade8cd8SKonstantin Porotchkin 				mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
16220ade8cd8SKonstantin Porotchkin 			else if (pcie_width == PCIE_LNK_X4)
16230ade8cd8SKonstantin Porotchkin 				mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
16240ade8cd8SKonstantin Porotchkin 			reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
16250ade8cd8SKonstantin Porotchkin 			start_lane = 0;
16260ade8cd8SKonstantin Porotchkin 			end_lane = pcie_width;
16270ade8cd8SKonstantin Porotchkin 
16280ade8cd8SKonstantin Porotchkin 			/* Release from PIPE soft reset
16290ade8cd8SKonstantin Porotchkin 			 * For PCIe by4 or by2:
16300ade8cd8SKonstantin Porotchkin 			 * release from soft reset all lanes - can't use
16310ade8cd8SKonstantin Porotchkin 			 * read modify write
16320ade8cd8SKonstantin Porotchkin 			 */
16330ade8cd8SKonstantin Porotchkin 			reg_set(HPIPE_ADDR(
16340ade8cd8SKonstantin Porotchkin 				COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), 0) +
16350ade8cd8SKonstantin Porotchkin 				HPIPE_RST_CLK_CTRL_REG, 0x24, 0xffffffff);
16360ade8cd8SKonstantin Porotchkin 		} else {
16370ade8cd8SKonstantin Porotchkin 			start_lane = comphy_index;
16380ade8cd8SKonstantin Porotchkin 			end_lane = comphy_index + 1;
16390ade8cd8SKonstantin Porotchkin 
16400ade8cd8SKonstantin Porotchkin 			/* Release from PIPE soft reset
16410ade8cd8SKonstantin Porotchkin 			 * for PCIe by4 or by2:
16420ade8cd8SKonstantin Porotchkin 			 * release from soft reset all lanes
16430ade8cd8SKonstantin Porotchkin 			 */
16440ade8cd8SKonstantin Porotchkin 			reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
16450ade8cd8SKonstantin Porotchkin 				0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
16460ade8cd8SKonstantin Porotchkin 				HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
16470ade8cd8SKonstantin Porotchkin 		}
16480ade8cd8SKonstantin Porotchkin 
16490ade8cd8SKonstantin Porotchkin 		if (pcie_width != PCIE_LNK_X1) {
16500ade8cd8SKonstantin Porotchkin 			/* disable writing to all lanes with one write */
16510ade8cd8SKonstantin Porotchkin 			if (pcie_width == PCIE_LNK_X2) {
16520ade8cd8SKonstantin Porotchkin 				data = (COMPHY_LANE0 <<
16530ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
16540ade8cd8SKonstantin Porotchkin 				(COMPHY_LANE1 <<
16550ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET);
16560ade8cd8SKonstantin Porotchkin 				mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
16570ade8cd8SKonstantin Porotchkin 			} else if (pcie_width == PCIE_LNK_X4) {
16580ade8cd8SKonstantin Porotchkin 				data = (COMPHY_LANE0 <<
16590ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
16600ade8cd8SKonstantin Porotchkin 				(COMPHY_LANE1 <<
16610ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET) |
16620ade8cd8SKonstantin Porotchkin 				(COMPHY_LANE2 <<
16630ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_2_PORT_OFFSET) |
16640ade8cd8SKonstantin Porotchkin 				(COMPHY_LANE3 <<
16650ade8cd8SKonstantin Porotchkin 				COMMON_PHY_SD_CTRL1_COMPHY_3_PORT_OFFSET);
16660ade8cd8SKonstantin Porotchkin 				mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
16670ade8cd8SKonstantin Porotchkin 			}
16680ade8cd8SKonstantin Porotchkin 			reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
16690ade8cd8SKonstantin Porotchkin 				data, mask);
16700ade8cd8SKonstantin Porotchkin 		}
16710ade8cd8SKonstantin Porotchkin 
16720ade8cd8SKonstantin Porotchkin 		debug("stage: Check PLL\n");
16730ade8cd8SKonstantin Porotchkin 		/* Read lane status */
16740ade8cd8SKonstantin Porotchkin 		for (i = start_lane; i < end_lane; i++) {
16750ade8cd8SKonstantin Porotchkin 			addr = HPIPE_ADDR(
16760ade8cd8SKonstantin Porotchkin 				COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), i) +
16770ade8cd8SKonstantin Porotchkin 				HPIPE_LANE_STATUS1_REG;
16780ade8cd8SKonstantin Porotchkin 			data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
16790ade8cd8SKonstantin Porotchkin 			mask = data;
16800ade8cd8SKonstantin Porotchkin 			ret = polling_with_timeout(addr, data, mask,
16810ade8cd8SKonstantin Porotchkin 						   PLL_LOCK_TIMEOUT,
16820ade8cd8SKonstantin Porotchkin 						   REG_32BIT);
16830ade8cd8SKonstantin Porotchkin 			if (ret)
16840ade8cd8SKonstantin Porotchkin 				ERROR("Failed to lock PCIE PLL\n");
16850ade8cd8SKonstantin Porotchkin 		}
16860ade8cd8SKonstantin Porotchkin 	}
16870ade8cd8SKonstantin Porotchkin 
16880ade8cd8SKonstantin Porotchkin 	debug_exit();
16890ade8cd8SKonstantin Porotchkin 
16900ade8cd8SKonstantin Porotchkin 	return ret;
16910ade8cd8SKonstantin Porotchkin }
16920ade8cd8SKonstantin Porotchkin 
16930ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_rxaui_power_on(uint64_t comphy_base,
16940ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
16950ade8cd8SKonstantin Porotchkin {
16960ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
16970ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
16980ade8cd8SKonstantin Porotchkin 	int ret = 0;
16990ade8cd8SKonstantin Porotchkin 
17000ade8cd8SKonstantin Porotchkin 	debug_enter();
17010ade8cd8SKonstantin Porotchkin 
17020ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
17030ade8cd8SKonstantin Porotchkin 				comphy_index);
17040ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
17050ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
17060ade8cd8SKonstantin Porotchkin 			     comphy_index);
17070ade8cd8SKonstantin Porotchkin 
17080ade8cd8SKonstantin Porotchkin 	/* configure phy selector for RXAUI */
17090ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
17100ade8cd8SKonstantin Porotchkin 					    comphy_mode);
17110ade8cd8SKonstantin Porotchkin 
17120ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
17130ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
17140ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
17150ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
17160ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
17170ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
17180ade8cd8SKonstantin Porotchkin 
17190ade8cd8SKonstantin Porotchkin 	if (comphy_index == 2) {
17200ade8cd8SKonstantin Porotchkin 		reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
17210ade8cd8SKonstantin Porotchkin 			0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET,
17220ade8cd8SKonstantin Porotchkin 			COMMON_PHY_SD_CTRL1_RXAUI0_MASK);
17230ade8cd8SKonstantin Porotchkin 	}
17240ade8cd8SKonstantin Porotchkin 	if (comphy_index == 4) {
17250ade8cd8SKonstantin Porotchkin 		reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
17260ade8cd8SKonstantin Porotchkin 			0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET,
17270ade8cd8SKonstantin Porotchkin 			COMMON_PHY_SD_CTRL1_RXAUI1_MASK);
17280ade8cd8SKonstantin Porotchkin 	}
17290ade8cd8SKonstantin Porotchkin 
17300ade8cd8SKonstantin Porotchkin 	/* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
17310ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
17320ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
17330ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
17340ade8cd8SKonstantin Porotchkin 	data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
17350ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
17360ade8cd8SKonstantin Porotchkin 	data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
17370ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
17380ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
17390ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
17400ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
17410ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
17420ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
17430ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK;
17440ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET;
17450ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
17460ade8cd8SKonstantin Porotchkin 
17470ade8cd8SKonstantin Porotchkin 	/* release from hard reset */
17480ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
17490ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
17500ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
17510ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
17520ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
17530ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
17540ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
17550ade8cd8SKonstantin Porotchkin 
17560ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
17570ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
17580ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
17590ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
17600ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
17610ade8cd8SKonstantin Porotchkin 
17620ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
17630ade8cd8SKonstantin Porotchkin 	mdelay(1);
17640ade8cd8SKonstantin Porotchkin 
17650ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
17660ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
17670ade8cd8SKonstantin Porotchkin 	/* set reference clock */
17680ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG,
17690ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
17700ade8cd8SKonstantin Porotchkin 		HPIPE_MISC_REFCLK_SEL_MASK);
17710ade8cd8SKonstantin Porotchkin 	/* Power and PLL Control */
17720ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
17730ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
17740ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
17750ade8cd8SKonstantin Porotchkin 	data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
17760ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
17770ade8cd8SKonstantin Porotchkin 	/* Loopback register */
17780ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
17790ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
17800ade8cd8SKonstantin Porotchkin 	/* rx control 1 */
17810ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
17820ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
17830ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
17840ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
17850ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
17860ade8cd8SKonstantin Porotchkin 	/* DTL Control */
17870ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG,
17880ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET,
17890ade8cd8SKonstantin Porotchkin 		HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK);
17900ade8cd8SKonstantin Porotchkin 
17910ade8cd8SKonstantin Porotchkin 	/* Set analog parameters from ETP(HW) */
17920ade8cd8SKonstantin Porotchkin 	debug("stage: Analog parameters from ETP(HW)\n");
17930ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration 2 */
17940ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG,
17950ade8cd8SKonstantin Porotchkin 		0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET,
17960ade8cd8SKonstantin Porotchkin 		SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK);
17970ade8cd8SKonstantin Porotchkin 	/* 0x7-DFE Resolution control */
17980ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_REG0, 0x1 << HPIPE_DFE_RES_FORCE_OFFSET,
17990ade8cd8SKonstantin Porotchkin 		HPIPE_DFE_RES_FORCE_MASK);
18000ade8cd8SKonstantin Porotchkin 	/* 0xd-G1_Setting_0 */
18010ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
18020ade8cd8SKonstantin Porotchkin 		0xd << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
18030ade8cd8SKonstantin Porotchkin 		HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
18040ade8cd8SKonstantin Porotchkin 	/* 0xE-G1_Setting_1 */
18050ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
18060ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
18073c0024ccSGrzegorz Jaszczyk 	mask |= HPIPE_G1_SET_1_G1_RX_SELMUPF_MASK;
18083c0024ccSGrzegorz Jaszczyk 	data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPF_OFFSET;
18090ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
18100ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
18110ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
18120ade8cd8SKonstantin Porotchkin 	/* 0xA-DFE_Reg3 */
18130ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
18140ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
18150ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
18160ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
18170ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
18180ade8cd8SKonstantin Porotchkin 
18190ade8cd8SKonstantin Porotchkin 	/* 0x111-G1_Setting_4 */
18200ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
18210ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
18220ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
18230ade8cd8SKonstantin Porotchkin 
18240ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
18250ade8cd8SKonstantin Porotchkin 	/* SERDES External Configuration */
18260ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
18270ade8cd8SKonstantin Porotchkin 	data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
18280ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
18290ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
18300ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
18310ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
18320ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
18330ade8cd8SKonstantin Porotchkin 
18340ade8cd8SKonstantin Porotchkin 
18350ade8cd8SKonstantin Porotchkin 	/* check PLL rx & tx ready */
18360ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
18370ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
18380ade8cd8SKonstantin Porotchkin 		SD_EXTERNAL_STATUS0_PLL_TX_MASK;
18390ade8cd8SKonstantin Porotchkin 	mask = data;
18400ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
18410ade8cd8SKonstantin Porotchkin 	if (data != 0) {
18420ade8cd8SKonstantin Porotchkin 		debug("Read from reg = %lx - value = 0x%x\n",
18430ade8cd8SKonstantin Porotchkin 		      sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
18440ade8cd8SKonstantin Porotchkin 		ERROR("SD_EXTERNAL_STATUS0_PLL_RX is %d, -\"-_PLL_TX is %d\n",
18450ade8cd8SKonstantin Porotchkin 		      (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK),
18460ade8cd8SKonstantin Porotchkin 		      (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK));
18470ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
18480ade8cd8SKonstantin Porotchkin 	}
18490ade8cd8SKonstantin Porotchkin 
18500ade8cd8SKonstantin Porotchkin 	/* RX init */
18510ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG,
18520ade8cd8SKonstantin Porotchkin 		0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET,
18530ade8cd8SKonstantin Porotchkin 		SD_EXTERNAL_CONFIG1_RX_INIT_MASK);
18540ade8cd8SKonstantin Porotchkin 
18550ade8cd8SKonstantin Porotchkin 	/* check that RX init done */
18560ade8cd8SKonstantin Porotchkin 	addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
18570ade8cd8SKonstantin Porotchkin 	data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
18580ade8cd8SKonstantin Porotchkin 	mask = data;
18590ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
18600ade8cd8SKonstantin Porotchkin 	if (data != 0) {
18610ade8cd8SKonstantin Porotchkin 		debug("Read from reg = %lx - value = 0x%x\n",
18620ade8cd8SKonstantin Porotchkin 		      sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
18630ade8cd8SKonstantin Porotchkin 		ERROR("SD_EXTERNAL_STATUS0_RX_INIT is 0\n");
18640ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
18650ade8cd8SKonstantin Porotchkin 	}
18660ade8cd8SKonstantin Porotchkin 
18670ade8cd8SKonstantin Porotchkin 	debug("stage: RF Reset\n");
18680ade8cd8SKonstantin Porotchkin 	/* RF Reset */
18690ade8cd8SKonstantin Porotchkin 	mask =  SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
18700ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
18710ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
18720ade8cd8SKonstantin Porotchkin 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
18730ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
18740ade8cd8SKonstantin Porotchkin 
18750ade8cd8SKonstantin Porotchkin 	debug_exit();
18760ade8cd8SKonstantin Porotchkin 
18770ade8cd8SKonstantin Porotchkin 	return ret;
18780ade8cd8SKonstantin Porotchkin }
18790ade8cd8SKonstantin Porotchkin 
18800ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base,
18810ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index, uint32_t comphy_mode)
18820ade8cd8SKonstantin Porotchkin {
18830ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, comphy_addr, addr;
18840ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
18850ade8cd8SKonstantin Porotchkin 	int ret = 0;
18860ade8cd8SKonstantin Porotchkin 
18870ade8cd8SKonstantin Porotchkin 	debug_enter();
18880ade8cd8SKonstantin Porotchkin 
18890ade8cd8SKonstantin Porotchkin 	/* Configure PIPE selector for USB3 */
18900ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
18910ade8cd8SKonstantin Porotchkin 					     comphy_mode);
18920ade8cd8SKonstantin Porotchkin 
18930ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
18940ade8cd8SKonstantin Porotchkin 				comphy_index);
18950ade8cd8SKonstantin Porotchkin 	comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
18960ade8cd8SKonstantin Porotchkin 
18970ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
18980ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
18990ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
19000ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
19010ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
19020ade8cd8SKonstantin Porotchkin 	data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
19030ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
19040ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
19050ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
19060ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
19070ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_PHY_MODE_MASK;
19080ade8cd8SKonstantin Porotchkin 	data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET;
19090ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
19100ade8cd8SKonstantin Porotchkin 
19110ade8cd8SKonstantin Porotchkin 	/* release from hard reset */
19120ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
19130ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
19140ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
19150ade8cd8SKonstantin Porotchkin 	data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
19160ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
19170ade8cd8SKonstantin Porotchkin 
19180ade8cd8SKonstantin Porotchkin 	/* Wait 1ms - until band gap and ref clock ready */
19190ade8cd8SKonstantin Porotchkin 	mdelay(1);
19200ade8cd8SKonstantin Porotchkin 
19210ade8cd8SKonstantin Porotchkin 	/* Start comphy Configuration */
19220ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy configuration\n");
19230ade8cd8SKonstantin Porotchkin 	/* Set PIPE soft reset */
19240ade8cd8SKonstantin Porotchkin 	mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
19250ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
19260ade8cd8SKonstantin Porotchkin 	/* Set PHY datapath width mode for V0 */
19270ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
19280ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
19290ade8cd8SKonstantin Porotchkin 	/* Set Data bus width USB mode for V0 */
19300ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
19310ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
19320ade8cd8SKonstantin Porotchkin 	/* Set CORE_CLK output frequency for 250Mhz */
19330ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
19340ade8cd8SKonstantin Porotchkin 	data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
19350ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
19360ade8cd8SKonstantin Porotchkin 	/* Set PLL ready delay for 0x2 */
19370ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG,
19380ade8cd8SKonstantin Porotchkin 		0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
19390ade8cd8SKonstantin Porotchkin 		HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
19400ade8cd8SKonstantin Porotchkin 	/* Set reference clock to come from group 1 - 25Mhz */
19410ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_MISC_REG,
19420ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
19430ade8cd8SKonstantin Porotchkin 		HPIPE_MISC_REFCLK_SEL_MASK);
19440ade8cd8SKonstantin Porotchkin 	/* Set reference frequcency select - 0x2 */
19450ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
19460ade8cd8SKonstantin Porotchkin 	data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
19470ade8cd8SKonstantin Porotchkin 	/* Set PHY mode to USB - 0x5 */
19480ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
19490ade8cd8SKonstantin Porotchkin 	data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
19500ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
19510ade8cd8SKonstantin Porotchkin 	/* Set the amount of time spent in the LoZ state - set for 0x7 */
19520ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
19530ade8cd8SKonstantin Porotchkin 		0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
19540ade8cd8SKonstantin Porotchkin 		HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
19550ade8cd8SKonstantin Porotchkin 	/* Set max PHY generation setting - 5Gbps */
19560ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
19570ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
19580ade8cd8SKonstantin Porotchkin 		HPIPE_INTERFACE_GEN_MAX_MASK);
19590ade8cd8SKonstantin Porotchkin 	/* Set select data width 20Bit (SEL_BITS[2:0]) */
19600ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
19610ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_LOOPBACK_SEL_OFFSET,
19620ade8cd8SKonstantin Porotchkin 		HPIPE_LOOPBACK_SEL_MASK);
19630ade8cd8SKonstantin Porotchkin 	/* select de-emphasize 3.5db */
19640ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_CONFIG0_REG,
19650ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET,
19660ade8cd8SKonstantin Porotchkin 		HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK);
19670ade8cd8SKonstantin Porotchkin 	/* override tx margining from the MAC */
19680ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_TST_MODE_CTRL_REG,
19690ade8cd8SKonstantin Porotchkin 		0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET,
19700ade8cd8SKonstantin Porotchkin 		HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK);
19710ade8cd8SKonstantin Porotchkin 
19720ade8cd8SKonstantin Porotchkin 	/* Start analog parameters from ETP(HW) */
19730ade8cd8SKonstantin Porotchkin 	debug("stage: Analog parameters from ETP(HW)\n");
19740ade8cd8SKonstantin Porotchkin 	/* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */
19750ade8cd8SKonstantin Porotchkin 	mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK;
19760ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET;
19770ade8cd8SKonstantin Porotchkin 	/* Set Override PHY DFE control pins for 0x1 */
19780ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK;
19790ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET;
19800ade8cd8SKonstantin Porotchkin 	/* Set Spread Spectrum Clock Enable fot 0x1 */
19810ade8cd8SKonstantin Porotchkin 	mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK;
19820ade8cd8SKonstantin Porotchkin 	data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET;
19830ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
19840ade8cd8SKonstantin Porotchkin 	/* Confifure SSC amplitude */
19850ade8cd8SKonstantin Porotchkin 	mask = HPIPE_G2_TX_SSC_AMP_MASK;
19860ade8cd8SKonstantin Porotchkin 	data = 0x1f << HPIPE_G2_TX_SSC_AMP_OFFSET;
19870ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
19880ade8cd8SKonstantin Porotchkin 	/* End of analog parameters */
19890ade8cd8SKonstantin Porotchkin 
19900ade8cd8SKonstantin Porotchkin 	debug("stage: Comphy power up\n");
19910ade8cd8SKonstantin Porotchkin 	/* Release from PIPE soft reset */
19920ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
19930ade8cd8SKonstantin Porotchkin 		0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
19940ade8cd8SKonstantin Porotchkin 		HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
19950ade8cd8SKonstantin Porotchkin 
19960ade8cd8SKonstantin Porotchkin 	/* wait 15ms - for comphy calibration done */
19970ade8cd8SKonstantin Porotchkin 	debug("stage: Check PLL\n");
19980ade8cd8SKonstantin Porotchkin 	/* Read lane status */
19990ade8cd8SKonstantin Porotchkin 	addr = hpipe_addr + HPIPE_LANE_STATUS1_REG;
20000ade8cd8SKonstantin Porotchkin 	data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
20010ade8cd8SKonstantin Porotchkin 	mask = data;
20020ade8cd8SKonstantin Porotchkin 	data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
20030ade8cd8SKonstantin Porotchkin 	if (data != 0) {
20040ade8cd8SKonstantin Porotchkin 		debug("Read from reg = %lx - value = 0x%x\n",
20050ade8cd8SKonstantin Porotchkin 			hpipe_addr + HPIPE_LANE_STATUS1_REG, data);
20060ade8cd8SKonstantin Porotchkin 		ERROR("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n");
20070ade8cd8SKonstantin Porotchkin 		ret = -ETIMEDOUT;
20080ade8cd8SKonstantin Porotchkin 	}
20090ade8cd8SKonstantin Porotchkin 
20100ade8cd8SKonstantin Porotchkin 	debug_exit();
20110ade8cd8SKonstantin Porotchkin 
20120ade8cd8SKonstantin Porotchkin 	return ret;
20130ade8cd8SKonstantin Porotchkin }
20140ade8cd8SKonstantin Porotchkin 
201542a29337SGrzegorz Jaszczyk int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base,
201642a29337SGrzegorz Jaszczyk 					      uint8_t comphy_index)
20170ade8cd8SKonstantin Porotchkin {
20180ade8cd8SKonstantin Porotchkin 	uint32_t mask, data, timeout;
201942a29337SGrzegorz Jaszczyk 	uint32_t g1_ffe_cap_sel, g1_ffe_res_sel, align90, g1_dfe_res;
20200ade8cd8SKonstantin Porotchkin 	uintptr_t hpipe_addr, sd_ip_addr;
20210ade8cd8SKonstantin Porotchkin 
202242a29337SGrzegorz Jaszczyk 	uint8_t ap_nr, cp_nr;
202342a29337SGrzegorz Jaszczyk 
202442a29337SGrzegorz Jaszczyk 	mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
202542a29337SGrzegorz Jaszczyk 
20260ade8cd8SKonstantin Porotchkin 	hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
20270ade8cd8SKonstantin Porotchkin 				comphy_index);
20280ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
20290ade8cd8SKonstantin Porotchkin 			     comphy_index);
20300ade8cd8SKonstantin Porotchkin 
203142a29337SGrzegorz Jaszczyk 	debug_enter();
203242a29337SGrzegorz Jaszczyk 
203342a29337SGrzegorz Jaszczyk 	debug("stage: RF Reset\n");
203442a29337SGrzegorz Jaszczyk 
203542a29337SGrzegorz Jaszczyk 	/* Release from hard reset */
203642a29337SGrzegorz Jaszczyk 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
203742a29337SGrzegorz Jaszczyk 	data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
203842a29337SGrzegorz Jaszczyk 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
203942a29337SGrzegorz Jaszczyk 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
204042a29337SGrzegorz Jaszczyk 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
204142a29337SGrzegorz Jaszczyk 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
204242a29337SGrzegorz Jaszczyk 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
204342a29337SGrzegorz Jaszczyk 
204442a29337SGrzegorz Jaszczyk 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
204542a29337SGrzegorz Jaszczyk 	data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
204642a29337SGrzegorz Jaszczyk 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
204742a29337SGrzegorz Jaszczyk 	data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
204842a29337SGrzegorz Jaszczyk 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
204942a29337SGrzegorz Jaszczyk 
205042a29337SGrzegorz Jaszczyk 	/* Wait 50ms - until band gap and ref clock ready */
205142a29337SGrzegorz Jaszczyk 	mdelay(50);
205242a29337SGrzegorz Jaszczyk 
205342a29337SGrzegorz Jaszczyk 	debug("Preparation for rx_training\n\n");
205442a29337SGrzegorz Jaszczyk 
205542a29337SGrzegorz Jaszczyk 	/* Use the FFE table */
205642a29337SGrzegorz Jaszczyk 	mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
205742a29337SGrzegorz Jaszczyk 	data = 0 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
205842a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
205942a29337SGrzegorz Jaszczyk 
206042a29337SGrzegorz Jaszczyk 	/* Use auto-calibration value */
206142a29337SGrzegorz Jaszczyk 	mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
206242a29337SGrzegorz Jaszczyk 	data = 0 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
206342a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
206442a29337SGrzegorz Jaszczyk 		data, mask);
206542a29337SGrzegorz Jaszczyk 
206642a29337SGrzegorz Jaszczyk 	/* Use Tx/Rx training results */
206742a29337SGrzegorz Jaszczyk 	mask = HPIPE_DFE_RES_FORCE_MASK;
206842a29337SGrzegorz Jaszczyk 	data = 0 << HPIPE_DFE_RES_FORCE_OFFSET;
206942a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
207042a29337SGrzegorz Jaszczyk 
207142a29337SGrzegorz Jaszczyk 	debug("PRBS31 loppback\n\n");
207242a29337SGrzegorz Jaszczyk 
20730ade8cd8SKonstantin Porotchkin 	/* Configure PRBS counters */
20740ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK;
20750ade8cd8SKonstantin Porotchkin 	data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET;
20760ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
20770ade8cd8SKonstantin Porotchkin 
20780ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PHY_TEST_DATA_MASK;
207942a29337SGrzegorz Jaszczyk 	data = 0xc4 << HPIPE_PHY_TEST_DATA_OFFSET;
20800ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask);
20810ade8cd8SKonstantin Porotchkin 
20820ade8cd8SKonstantin Porotchkin 	mask = HPIPE_PHY_TEST_EN_MASK;
20830ade8cd8SKonstantin Porotchkin 	data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET;
20840ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
20850ade8cd8SKonstantin Porotchkin 
208642a29337SGrzegorz Jaszczyk 	mdelay(10);
208742a29337SGrzegorz Jaszczyk 	debug("Enable TX/RX training\n\n");
20880ade8cd8SKonstantin Porotchkin 
208942a29337SGrzegorz Jaszczyk 	mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
209042a29337SGrzegorz Jaszczyk 	data = 0x1 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
209142a29337SGrzegorz Jaszczyk 	mask |= HPIPE_TRX_RX_ANA_IF_CLK_ENE_MASK;
209242a29337SGrzegorz Jaszczyk 	data |= 0x1 << HPIPE_TRX_RX_ANA_IF_CLK_ENE_OFFSET;
209342a29337SGrzegorz Jaszczyk 	mask |= HPIPE_TRX_TX_CTRL_CLK_EN_MASK;
209442a29337SGrzegorz Jaszczyk 	data |= 0x1 << HPIPE_TRX_TX_CTRL_CLK_EN_OFFSET;
209542a29337SGrzegorz Jaszczyk 	mask |= HPIPE_TRX_UPDATE_THEN_HOLD_MASK;
209642a29337SGrzegorz Jaszczyk 	data |= 0x1 << HPIPE_TRX_UPDATE_THEN_HOLD_OFFSET;
209742a29337SGrzegorz Jaszczyk 	mask |= HPIPE_TRX_TX_F0T_EO_BASED_MASK;
209842a29337SGrzegorz Jaszczyk 	data |= 0x1 << HPIPE_TRX_TX_F0T_EO_BASED_OFFSET;
209942a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
21000ade8cd8SKonstantin Porotchkin 
21010ade8cd8SKonstantin Porotchkin 	/* Check the result of RX training */
21020ade8cd8SKonstantin Porotchkin 	timeout = RX_TRAINING_TIMEOUT;
210342a29337SGrzegorz Jaszczyk 	mask = HPIPE_INTERRUPT_TRX_TRAIN_DONE_OFFSET |
210442a29337SGrzegorz Jaszczyk 		HPIPE_INTERRUPT_DFE_DONE_INT_OFFSET |
210542a29337SGrzegorz Jaszczyk 		HPIPE_INTERRUPT_RX_TRAIN_COMPLETE_INT_MASK;
21060ade8cd8SKonstantin Porotchkin 	while (timeout) {
210742a29337SGrzegorz Jaszczyk 		data = mmio_read_32(hpipe_addr + HPIPE_INTERRUPT_1_REGISTER);
210842a29337SGrzegorz Jaszczyk 		if (data & mask)
21090ade8cd8SKonstantin Porotchkin 			break;
21100ade8cd8SKonstantin Porotchkin 		mdelay(1);
21110ade8cd8SKonstantin Porotchkin 		timeout--;
21120ade8cd8SKonstantin Porotchkin 	}
21130ade8cd8SKonstantin Porotchkin 
211442a29337SGrzegorz Jaszczyk 	debug("RX training result: interrupt reg 0x%lx = 0x%x\n\n",
211542a29337SGrzegorz Jaszczyk 	       hpipe_addr + HPIPE_INTERRUPT_1_REGISTER, data);
211642a29337SGrzegorz Jaszczyk 
211742a29337SGrzegorz Jaszczyk 	if (timeout == 0 || data & HPIPE_TRX_TRAIN_TIME_OUT_INT_MASK) {
211842a29337SGrzegorz Jaszczyk 		ERROR("Rx training timeout...\n");
21190ade8cd8SKonstantin Porotchkin 		return -ETIMEDOUT;
21200ade8cd8SKonstantin Porotchkin 	}
21210ade8cd8SKonstantin Porotchkin 
212242a29337SGrzegorz Jaszczyk 	if (data & HPIPE_TRX_TRAIN_FAILED_MASK) {
212342a29337SGrzegorz Jaszczyk 		ERROR("Rx training failed...\n");
212442a29337SGrzegorz Jaszczyk 		return -EINVAL;
212542a29337SGrzegorz Jaszczyk 	}
212642a29337SGrzegorz Jaszczyk 
212742a29337SGrzegorz Jaszczyk 	mask = HPIPE_TRX_RX_TRAIN_EN_MASK;
212842a29337SGrzegorz Jaszczyk 	data = 0x0 << HPIPE_TRX_RX_TRAIN_EN_OFFSET;
212942a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask);
213042a29337SGrzegorz Jaszczyk 
213142a29337SGrzegorz Jaszczyk 	debug("Training done, reading results...\n\n");
213242a29337SGrzegorz Jaszczyk 
213342a29337SGrzegorz Jaszczyk 	mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_MASK;
213442a29337SGrzegorz Jaszczyk 	g1_ffe_res_sel = ((mmio_read_32(hpipe_addr +
213542a29337SGrzegorz Jaszczyk 			   HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
213642a29337SGrzegorz Jaszczyk 			   & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_RES_OFFSET);
213742a29337SGrzegorz Jaszczyk 
213842a29337SGrzegorz Jaszczyk 	mask = HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_MASK;
213942a29337SGrzegorz Jaszczyk 	g1_ffe_cap_sel = ((mmio_read_32(hpipe_addr +
214042a29337SGrzegorz Jaszczyk 			   HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG)
214142a29337SGrzegorz Jaszczyk 			   & mask) >> HPIPE_ADAPTED_FFE_ADAPTED_FFE_CAP_OFFSET);
214242a29337SGrzegorz Jaszczyk 
214342a29337SGrzegorz Jaszczyk 	mask = HPIPE_DATA_PHASE_ADAPTED_OS_PH_MASK;
214442a29337SGrzegorz Jaszczyk 	align90 = ((mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG)
214542a29337SGrzegorz Jaszczyk 		    & mask) >> HPIPE_DATA_PHASE_ADAPTED_OS_PH_OFFSET);
214642a29337SGrzegorz Jaszczyk 
214742a29337SGrzegorz Jaszczyk 	mask = HPIPE_ADAPTED_DFE_RES_MASK;
214842a29337SGrzegorz Jaszczyk 	g1_dfe_res = ((mmio_read_32(hpipe_addr +
214942a29337SGrzegorz Jaszczyk 		       HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG)
215042a29337SGrzegorz Jaszczyk 		       & mask) >> HPIPE_ADAPTED_DFE_RES_OFFSET);
215142a29337SGrzegorz Jaszczyk 
215242a29337SGrzegorz Jaszczyk 	debug("================================================\n");
215342a29337SGrzegorz Jaszczyk 	debug("Switching to static configuration:\n");
215442a29337SGrzegorz Jaszczyk 	debug("FFE_RES = 0x%x FFE_CAP = 0x%x align90 = 0x%x g1_dfe_res 0x%x\n",
215542a29337SGrzegorz Jaszczyk 	       g1_ffe_res_sel, g1_ffe_cap_sel, align90, g1_dfe_res);
215642a29337SGrzegorz Jaszczyk 	debug("Result after training: 0x%lx= 0x%x, 0x%lx= 0x%x, 0x%lx = 0x%x\n",
215742a29337SGrzegorz Jaszczyk 	      (hpipe_addr + HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
215842a29337SGrzegorz Jaszczyk 	       mmio_read_32(hpipe_addr +
215942a29337SGrzegorz Jaszczyk 			    HPIPE_ADAPTED_FFE_CAPACITOR_COUNTER_CTRL_REG),
216042a29337SGrzegorz Jaszczyk 			    (hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
216142a29337SGrzegorz Jaszczyk 	       mmio_read_32(hpipe_addr + HPIPE_DATA_PHASE_OFF_CTRL_REG),
216242a29337SGrzegorz Jaszczyk 			    (hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG),
216342a29337SGrzegorz Jaszczyk 	       mmio_read_32(hpipe_addr + HPIPE_ADAPTED_DFE_COEFFICIENT_1_REG));
216442a29337SGrzegorz Jaszczyk 	debug("================================================\n");
216542a29337SGrzegorz Jaszczyk 
216642a29337SGrzegorz Jaszczyk 	/* Update FFE_RES */
216742a29337SGrzegorz Jaszczyk 	mask = HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
216842a29337SGrzegorz Jaszczyk 	data = g1_ffe_res_sel << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
216942a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
217042a29337SGrzegorz Jaszczyk 
217142a29337SGrzegorz Jaszczyk 	/* Update FFE_CAP */
217242a29337SGrzegorz Jaszczyk 	mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
217342a29337SGrzegorz Jaszczyk 	data = g1_ffe_cap_sel << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
217442a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
217542a29337SGrzegorz Jaszczyk 
217642a29337SGrzegorz Jaszczyk 	/* Bypass the FFE table settings and use the FFE settings directly from
217742a29337SGrzegorz Jaszczyk 	 * registers FFE_RES_SEL and FFE_CAP_SEL
21780ade8cd8SKonstantin Porotchkin 	 */
217942a29337SGrzegorz Jaszczyk 	mask = HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
218042a29337SGrzegorz Jaszczyk 	data = 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
218142a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
21820ade8cd8SKonstantin Porotchkin 
218342a29337SGrzegorz Jaszczyk 	/* Use the value from CAL_OS_PH_EXT */
218442a29337SGrzegorz Jaszczyk 	mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK;
218542a29337SGrzegorz Jaszczyk 	data = 1 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET;
218642a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
218742a29337SGrzegorz Jaszczyk 		data, mask);
21880ade8cd8SKonstantin Porotchkin 
218942a29337SGrzegorz Jaszczyk 	/* Update align90 */
219042a29337SGrzegorz Jaszczyk 	mask = HPIPE_CAL_OS_PH_EXT_MASK;
219142a29337SGrzegorz Jaszczyk 	data = align90 << HPIPE_CAL_OS_PH_EXT_OFFSET;
219242a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG,
219342a29337SGrzegorz Jaszczyk 		data, mask);
21940ade8cd8SKonstantin Porotchkin 
219542a29337SGrzegorz Jaszczyk 	/* Force DFE resolution (use gen table value) */
21960ade8cd8SKonstantin Porotchkin 	mask = HPIPE_DFE_RES_FORCE_MASK;
21970ade8cd8SKonstantin Porotchkin 	data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
21980ade8cd8SKonstantin Porotchkin 	reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
21990ade8cd8SKonstantin Porotchkin 
220042a29337SGrzegorz Jaszczyk 	/* 0x111-G1 DFE_Setting_4 */
220142a29337SGrzegorz Jaszczyk 	mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
220242a29337SGrzegorz Jaszczyk 	data = g1_dfe_res << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
220342a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
22040ade8cd8SKonstantin Porotchkin 
220542a29337SGrzegorz Jaszczyk 	debug("PRBS31 loppback\n\n");
22060ade8cd8SKonstantin Porotchkin 
220742a29337SGrzegorz Jaszczyk 	mask = HPIPE_PHY_TEST_PT_TESTMODE_MASK;
220842a29337SGrzegorz Jaszczyk 	data = 0x1 << HPIPE_PHY_TEST_PT_TESTMODE_OFFSET;
220942a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_PHY_TEST_OOB_0_REGISTER, data, mask);
22100ade8cd8SKonstantin Porotchkin 
221142a29337SGrzegorz Jaszczyk 	/* Configure PRBS counters */
221242a29337SGrzegorz Jaszczyk 	mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK;
221342a29337SGrzegorz Jaszczyk 	data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET;
221442a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
22150ade8cd8SKonstantin Porotchkin 
221642a29337SGrzegorz Jaszczyk 	mask = HPIPE_PHY_TEST_DATA_MASK;
221742a29337SGrzegorz Jaszczyk 	data = 0xc4 << HPIPE_PHY_TEST_DATA_OFFSET;
221842a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask);
22190ade8cd8SKonstantin Porotchkin 
222042a29337SGrzegorz Jaszczyk 	mask = HPIPE_PHY_TEST_EN_MASK;
222142a29337SGrzegorz Jaszczyk 	data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET;
222242a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
22230ade8cd8SKonstantin Porotchkin 
222442a29337SGrzegorz Jaszczyk 	/* Reset PRBS error counter */
222542a29337SGrzegorz Jaszczyk 	mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK;
222642a29337SGrzegorz Jaszczyk 	data = 0x1 << HPIPE_PHY_TEST_RESET_OFFSET;
222742a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
222842a29337SGrzegorz Jaszczyk 
222942a29337SGrzegorz Jaszczyk 	mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK;
223042a29337SGrzegorz Jaszczyk 	data = 0x0 << HPIPE_PHY_TEST_RESET_OFFSET;
223142a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
223242a29337SGrzegorz Jaszczyk 
223342a29337SGrzegorz Jaszczyk 	mask = HPIPE_PHY_TEST_PT_TESTMODE_MASK;
223442a29337SGrzegorz Jaszczyk 	data = 0x1 << HPIPE_PHY_TEST_PT_TESTMODE_OFFSET;
223542a29337SGrzegorz Jaszczyk 	reg_set(hpipe_addr + HPIPE_PHY_TEST_OOB_0_REGISTER, data, mask);
223642a29337SGrzegorz Jaszczyk 
223742a29337SGrzegorz Jaszczyk 	printf("########################################################\n");
223842a29337SGrzegorz Jaszczyk 	printf("# To use trained values update the ATF sources:\n");
2239*a2847172SGrzegorz Jaszczyk 	printf("# plat/marvell/armada/a8k/<board_type>/board/phy-porting-layer.h ");
224042a29337SGrzegorz Jaszczyk 	printf("file\n# with new values as below (for appropriate AP nr %d",
224142a29337SGrzegorz Jaszczyk 	       ap_nr);
224242a29337SGrzegorz Jaszczyk 	printf("and CP nr: %d comphy_index %d\n\n",
224342a29337SGrzegorz Jaszczyk 	       cp_nr, comphy_index);
224442a29337SGrzegorz Jaszczyk 	printf("static struct xfi_params xfi_static_values_tab[AP_NUM]");
224542a29337SGrzegorz Jaszczyk 	printf("[CP_NUM][MAX_LANE_NR] = {\n");
224642a29337SGrzegorz Jaszczyk 	printf("\t...\n");
224742a29337SGrzegorz Jaszczyk 	printf("\t.g1_ffe_res_sel = 0x%x,\n", g1_ffe_res_sel);
224842a29337SGrzegorz Jaszczyk 	printf("\t.g1_ffe_cap_sel = 0x%x,\n", g1_ffe_cap_sel);
224942a29337SGrzegorz Jaszczyk 	printf("\t.align90 = 0x%x,\n", align90);
225042a29337SGrzegorz Jaszczyk 	printf("\t.g1_dfe_res = 0x%x\n", g1_dfe_res);
225142a29337SGrzegorz Jaszczyk 	printf("\t...\n");
225242a29337SGrzegorz Jaszczyk 	printf("};\n\n");
225342a29337SGrzegorz Jaszczyk 	printf("########################################################\n");
225442a29337SGrzegorz Jaszczyk 
225542a29337SGrzegorz Jaszczyk 	/* check */
225642a29337SGrzegorz Jaszczyk 	debug("PRBS error counter[0x%lx] 0x%x\n\n",
225742a29337SGrzegorz Jaszczyk 	      hpipe_addr + HPIPE_PHY_TEST_PRBS_ERROR_COUNTER_1_REG,
225842a29337SGrzegorz Jaszczyk 	      mmio_read_32(hpipe_addr +
225942a29337SGrzegorz Jaszczyk 			   HPIPE_PHY_TEST_PRBS_ERROR_COUNTER_1_REG));
226042a29337SGrzegorz Jaszczyk 
226142a29337SGrzegorz Jaszczyk 	rx_trainng_done[ap_nr][cp_nr][comphy_index] = 1;
226242a29337SGrzegorz Jaszczyk 
226342a29337SGrzegorz Jaszczyk 	return 0;
22640ade8cd8SKonstantin Porotchkin }
22650ade8cd8SKonstantin Porotchkin 
22660ade8cd8SKonstantin Porotchkin /* During AP the proper mode is auto-negotiated and the mac, pcs and serdes
22670ade8cd8SKonstantin Porotchkin  * configuration are done by the firmware loaded to the MG's CM3 for appropriate
22680ade8cd8SKonstantin Porotchkin  * negotiated mode. Therefore there is no need to configure the mac, pcs and
22690ade8cd8SKonstantin Porotchkin  * serdes from u-boot. The only thing that need to be setup is powering up
22700ade8cd8SKonstantin Porotchkin  * the comphy, which is done through Common PHY<n> Configuration 1 Register
22710ade8cd8SKonstantin Porotchkin  * (CP0: 0xF2441000, CP1: 0xF4441000). This step can't be done by MG's CM3,
22720ade8cd8SKonstantin Porotchkin  * since it doesn't have an access to this register-set (but it has access to
22730ade8cd8SKonstantin Porotchkin  * the network registers like: MG, AP, MAC, PCS, Serdes etc.)
22740ade8cd8SKonstantin Porotchkin  */
22750ade8cd8SKonstantin Porotchkin static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base,
22760ade8cd8SKonstantin Porotchkin 					  uint8_t comphy_index)
22770ade8cd8SKonstantin Porotchkin {
22780ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
22790ade8cd8SKonstantin Porotchkin 	uintptr_t comphy_addr = comphy_addr =
22800ade8cd8SKonstantin Porotchkin 				COMPHY_ADDR(comphy_base, comphy_index);
22810ade8cd8SKonstantin Porotchkin 
22820ade8cd8SKonstantin Porotchkin 	debug_enter();
22830ade8cd8SKonstantin Porotchkin 	debug("stage: RFU configurations - hard reset comphy\n");
22840ade8cd8SKonstantin Porotchkin 	/* RFU configurations - hard reset comphy */
22850ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_UP_MASK;
22860ade8cd8SKonstantin Porotchkin 	data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
22870ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
22880ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
22890ade8cd8SKonstantin Porotchkin 	reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
22900ade8cd8SKonstantin Porotchkin 	debug_exit();
22910ade8cd8SKonstantin Porotchkin 
22920ade8cd8SKonstantin Porotchkin 	return 0;
22930ade8cd8SKonstantin Porotchkin }
22940ade8cd8SKonstantin Porotchkin 
22950ade8cd8SKonstantin Porotchkin /*
22960ade8cd8SKonstantin Porotchkin  * This function allows to reset the digital synchronizers between
22970ade8cd8SKonstantin Porotchkin  * the MAC and the PHY, it is required when the MAC changes its state.
22980ade8cd8SKonstantin Porotchkin  */
22990ade8cd8SKonstantin Porotchkin int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base,
23000ade8cd8SKonstantin Porotchkin 				     uint8_t comphy_index,
23010ade8cd8SKonstantin Porotchkin 				     uint32_t comphy_mode, uint32_t command)
23020ade8cd8SKonstantin Porotchkin {
23030ade8cd8SKonstantin Porotchkin 	int mode = COMPHY_GET_MODE(comphy_mode);
23040ade8cd8SKonstantin Porotchkin 	uintptr_t sd_ip_addr;
23050ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
23060ade8cd8SKonstantin Porotchkin 
23070ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
23080ade8cd8SKonstantin Porotchkin 			     comphy_index);
23090ade8cd8SKonstantin Porotchkin 
23100ade8cd8SKonstantin Porotchkin 	switch (mode) {
23110ade8cd8SKonstantin Porotchkin 	case (COMPHY_SGMII_MODE):
23120ade8cd8SKonstantin Porotchkin 	case (COMPHY_HS_SGMII_MODE):
23130ade8cd8SKonstantin Porotchkin 	case (COMPHY_XFI_MODE):
23140ade8cd8SKonstantin Porotchkin 	case (COMPHY_SFI_MODE):
23150ade8cd8SKonstantin Porotchkin 	case (COMPHY_RXAUI_MODE):
23160ade8cd8SKonstantin Porotchkin 		mask = SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
23170ade8cd8SKonstantin Porotchkin 		data = ((command == COMPHY_COMMAND_DIGITAL_PWR_OFF) ?
23180ade8cd8SKonstantin Porotchkin 			0x0 : 0x1) << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
23190ade8cd8SKonstantin Porotchkin 		reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
23200ade8cd8SKonstantin Porotchkin 		break;
23210ade8cd8SKonstantin Porotchkin 	default:
23220ade8cd8SKonstantin Porotchkin 		ERROR("comphy%d: Digital PWR ON/OFF is not supported\n",
23230ade8cd8SKonstantin Porotchkin 			comphy_index);
23240ade8cd8SKonstantin Porotchkin 			return -EINVAL;
23250ade8cd8SKonstantin Porotchkin 	}
23260ade8cd8SKonstantin Porotchkin 
23270ade8cd8SKonstantin Porotchkin 	return 0;
23280ade8cd8SKonstantin Porotchkin }
23290ade8cd8SKonstantin Porotchkin 
2330f858e989SGrzegorz Jaszczyk int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint8_t comphy_index,
23310ade8cd8SKonstantin Porotchkin 				uint64_t comphy_mode)
23320ade8cd8SKonstantin Porotchkin {
23330ade8cd8SKonstantin Porotchkin 	int mode = COMPHY_GET_MODE(comphy_mode);
23340ade8cd8SKonstantin Porotchkin 	int err = 0;
23350ade8cd8SKonstantin Porotchkin 
23360ade8cd8SKonstantin Porotchkin 	debug_enter();
23370ade8cd8SKonstantin Porotchkin 
23380ade8cd8SKonstantin Porotchkin 	switch (mode) {
23390ade8cd8SKonstantin Porotchkin 	case(COMPHY_SATA_MODE):
23400ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_sata_power_on(comphy_base,
23410ade8cd8SKonstantin Porotchkin 						       comphy_index,
23420ade8cd8SKonstantin Porotchkin 						       comphy_mode);
23430ade8cd8SKonstantin Porotchkin 		break;
23440ade8cd8SKonstantin Porotchkin 	case(COMPHY_SGMII_MODE):
23450ade8cd8SKonstantin Porotchkin 	case(COMPHY_HS_SGMII_MODE):
23460ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_sgmii_power_on(comphy_base,
23470ade8cd8SKonstantin Porotchkin 							comphy_index,
23480ade8cd8SKonstantin Porotchkin 							comphy_mode);
23490ade8cd8SKonstantin Porotchkin 		break;
23500ade8cd8SKonstantin Porotchkin 	/* From comphy perspective, XFI and SFI are the same */
23510ade8cd8SKonstantin Porotchkin 	case (COMPHY_XFI_MODE):
23520ade8cd8SKonstantin Porotchkin 	case (COMPHY_SFI_MODE):
23530ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_xfi_power_on(comphy_base,
23540ade8cd8SKonstantin Porotchkin 						      comphy_index,
23550ade8cd8SKonstantin Porotchkin 						      comphy_mode);
23560ade8cd8SKonstantin Porotchkin 		break;
23570ade8cd8SKonstantin Porotchkin 	case (COMPHY_PCIE_MODE):
23580ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_pcie_power_on(comphy_base,
23590ade8cd8SKonstantin Porotchkin 						       comphy_index,
23600ade8cd8SKonstantin Porotchkin 						       comphy_mode);
23610ade8cd8SKonstantin Porotchkin 		break;
23620ade8cd8SKonstantin Porotchkin 	case (COMPHY_RXAUI_MODE):
23630ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_rxaui_power_on(comphy_base,
23640ade8cd8SKonstantin Porotchkin 							comphy_index,
23650ade8cd8SKonstantin Porotchkin 							comphy_mode);
236642a29337SGrzegorz Jaszczyk 		break;
23670ade8cd8SKonstantin Porotchkin 	case (COMPHY_USB3H_MODE):
23680ade8cd8SKonstantin Porotchkin 	case (COMPHY_USB3D_MODE):
23690ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_usb3_power_on(comphy_base,
23700ade8cd8SKonstantin Porotchkin 						       comphy_index,
23710ade8cd8SKonstantin Porotchkin 						       comphy_mode);
23720ade8cd8SKonstantin Porotchkin 		break;
23730ade8cd8SKonstantin Porotchkin 	case (COMPHY_AP_MODE):
23740ade8cd8SKonstantin Porotchkin 		err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index);
23750ade8cd8SKonstantin Porotchkin 		break;
23760ade8cd8SKonstantin Porotchkin 	default:
2377f858e989SGrzegorz Jaszczyk 		ERROR("comphy%d: unsupported comphy mode\n", comphy_index);
23780ade8cd8SKonstantin Porotchkin 		err = -EINVAL;
23790ade8cd8SKonstantin Porotchkin 		break;
23800ade8cd8SKonstantin Porotchkin 	}
23810ade8cd8SKonstantin Porotchkin 
23820ade8cd8SKonstantin Porotchkin 	debug_exit();
23830ade8cd8SKonstantin Porotchkin 
23840ade8cd8SKonstantin Porotchkin 	return err;
23850ade8cd8SKonstantin Porotchkin }
23860ade8cd8SKonstantin Porotchkin 
238755df84f9SIgal Liberman int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint8_t comphy_index,
238855df84f9SIgal Liberman 				 uint64_t comphy_mode)
23890ade8cd8SKonstantin Porotchkin {
23900ade8cd8SKonstantin Porotchkin 	uintptr_t sd_ip_addr, comphy_ip_addr;
23910ade8cd8SKonstantin Porotchkin 	uint32_t mask, data;
239242a29337SGrzegorz Jaszczyk 	uint8_t ap_nr, cp_nr;
239355df84f9SIgal Liberman 	_Bool called_from_uboot = COMPHY_GET_CALLER(comphy_mode);
23940ade8cd8SKonstantin Porotchkin 
23950ade8cd8SKonstantin Porotchkin 	debug_enter();
23960ade8cd8SKonstantin Porotchkin 
239755df84f9SIgal Liberman 	/* Power-off might happen because of 2 things:
239855df84f9SIgal Liberman 	 *	1. Bootloader turns off unconnected lanes
239955df84f9SIgal Liberman 	 *	2. Linux turns off all lanes during boot
240055df84f9SIgal Liberman 	 *	   (and then reconfigure it).
240155df84f9SIgal Liberman 	 *
240255df84f9SIgal Liberman 	 * For PCIe, there's a problem:
240355df84f9SIgal Liberman 	 * In Armada 8K DB boards, PCIe initialization can be executed
240455df84f9SIgal Liberman 	 * only once (PCIe reset performed during chip power on and
240555df84f9SIgal Liberman 	 * it cannot be executed via GPIO later) so a lane configured to
240655df84f9SIgal Liberman 	 * PCIe should not be powered off by Linux.
240755df84f9SIgal Liberman 	 *
240855df84f9SIgal Liberman 	 * So, check 2 things:
240955df84f9SIgal Liberman 	 *	1. Is Linux called for power-off?
241055df84f9SIgal Liberman 	 *	2. Is the comphy configured to PCIe?
241155df84f9SIgal Liberman 	 * If the answer is YES for both 1 and 2, skip the power-off.
241255df84f9SIgal Liberman 	 *
241355df84f9SIgal Liberman 	 * TODO: In MacciatoBIN, PCIe reset is connected via GPIO,
241455df84f9SIgal Liberman 	 * so after GPIO reset is added to Linux Kernel, it can be
241555df84f9SIgal Liberman 	 * powered-off.
241655df84f9SIgal Liberman 	 */
241755df84f9SIgal Liberman 	if (!called_from_uboot) {
241855df84f9SIgal Liberman 		data = mmio_read_32(comphy_base +
241955df84f9SIgal Liberman 				    COMMON_SELECTOR_PIPE_REG_OFFSET);
242055df84f9SIgal Liberman 		data >>= (COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index);
242155df84f9SIgal Liberman 		data &= COMMON_SELECTOR_COMPHY_MASK;
242255df84f9SIgal Liberman 		if (data == COMMON_SELECTOR_PIPE_COMPHY_PCIE)
242355df84f9SIgal Liberman 			return 0;
242455df84f9SIgal Liberman 	}
242555df84f9SIgal Liberman 
242642a29337SGrzegorz Jaszczyk 	mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
242742a29337SGrzegorz Jaszczyk 
242842a29337SGrzegorz Jaszczyk 	if (rx_trainng_done[ap_nr][cp_nr][comphy_index]) {
242942a29337SGrzegorz Jaszczyk 		debug("Skip %s for comphy[%d][%d][%d], due to rx training\n",
243042a29337SGrzegorz Jaszczyk 		       __func__, ap_nr, cp_nr, comphy_index);
243142a29337SGrzegorz Jaszczyk 		return 0;
243242a29337SGrzegorz Jaszczyk 	}
243342a29337SGrzegorz Jaszczyk 
24340ade8cd8SKonstantin Porotchkin 	sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
24350ade8cd8SKonstantin Porotchkin 			     comphy_index);
24360ade8cd8SKonstantin Porotchkin 	comphy_ip_addr = COMPHY_ADDR(comphy_base, comphy_index);
24370ade8cd8SKonstantin Porotchkin 
24380ade8cd8SKonstantin Porotchkin 	/* Hard reset the comphy, for Ethernet modes and Sata */
24390ade8cd8SKonstantin Porotchkin 	mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
24400ade8cd8SKonstantin Porotchkin 	data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
24410ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
24420ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
24430ade8cd8SKonstantin Porotchkin 	mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
24440ade8cd8SKonstantin Porotchkin 	data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
24450ade8cd8SKonstantin Porotchkin 	reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
24460ade8cd8SKonstantin Porotchkin 
24470ade8cd8SKonstantin Porotchkin 	/* PCIe reset */
24480ade8cd8SKonstantin Porotchkin 	spin_lock(&cp110_mac_reset_lock);
24490ade8cd8SKonstantin Porotchkin 
24500ade8cd8SKonstantin Porotchkin 	/* The mvebu_cp110_comphy_power_off will be called only from Linux (to
24510ade8cd8SKonstantin Porotchkin 	 * override settings done by bootloader) and it will be relevant only
24520ade8cd8SKonstantin Porotchkin 	 * to PCIe (called before check if to skip pcie power off or not).
24530ade8cd8SKonstantin Porotchkin 	 */
24540ade8cd8SKonstantin Porotchkin 	data = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
24550ade8cd8SKonstantin Porotchkin 						 SYS_CTRL_UINIT_SOFT_RESET_REG);
24560ade8cd8SKonstantin Porotchkin 	switch (comphy_index) {
24570ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE0:
24580ade8cd8SKonstantin Porotchkin 		data &= ~PCIE_MAC_RESET_MASK_PORT0;
24590ade8cd8SKonstantin Porotchkin 		break;
24600ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE4:
24610ade8cd8SKonstantin Porotchkin 		data &= ~PCIE_MAC_RESET_MASK_PORT1;
24620ade8cd8SKonstantin Porotchkin 		break;
24630ade8cd8SKonstantin Porotchkin 	case COMPHY_LANE5:
24640ade8cd8SKonstantin Porotchkin 		data &= ~PCIE_MAC_RESET_MASK_PORT2;
24650ade8cd8SKonstantin Porotchkin 		break;
24660ade8cd8SKonstantin Porotchkin 	}
24670ade8cd8SKonstantin Porotchkin 
24680ade8cd8SKonstantin Porotchkin 	mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
24690ade8cd8SKonstantin Porotchkin 					   SYS_CTRL_UINIT_SOFT_RESET_REG, data);
24700ade8cd8SKonstantin Porotchkin 	spin_unlock(&cp110_mac_reset_lock);
24710ade8cd8SKonstantin Porotchkin 
24720ade8cd8SKonstantin Porotchkin 	/* Hard reset the comphy, for PCIe and usb3 */
24730ade8cd8SKonstantin Porotchkin 	mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
24740ade8cd8SKonstantin Porotchkin 	data = 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
24750ade8cd8SKonstantin Porotchkin 	mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
24760ade8cd8SKonstantin Porotchkin 	data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
24770ade8cd8SKonstantin Porotchkin 	reg_set(comphy_ip_addr + COMMON_PHY_CFG1_REG, data, mask);
24780ade8cd8SKonstantin Porotchkin 
24790ade8cd8SKonstantin Porotchkin 	/* Clear comphy PHY and PIPE selector, can't rely on previous config. */
24800ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
24810ade8cd8SKonstantin Porotchkin 	mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
24820ade8cd8SKonstantin Porotchkin 
24830ade8cd8SKonstantin Porotchkin 	debug_exit();
24840ade8cd8SKonstantin Porotchkin 
24850ade8cd8SKonstantin Porotchkin 	return 0;
24860ade8cd8SKonstantin Porotchkin }
2487