1*c0132f60SStefan Roese /* 2*c0132f60SStefan Roese * Copyright (C) 2015-2016 Marvell International Ltd. 3*c0132f60SStefan Roese * 4*c0132f60SStefan Roese * SPDX-License-Identifier: GPL-2.0+ 5*c0132f60SStefan Roese */ 6*c0132f60SStefan Roese 7*c0132f60SStefan Roese #include <common.h> 8*c0132f60SStefan Roese #include <fdtdec.h> 9*c0132f60SStefan Roese #include <asm/io.h> 10*c0132f60SStefan Roese #include <asm/arch/cpu.h> 11*c0132f60SStefan Roese #include <asm/arch/soc.h> 12*c0132f60SStefan Roese 13*c0132f60SStefan Roese #include "comphy.h" 14*c0132f60SStefan Roese #include "comphy_hpipe.h" 15*c0132f60SStefan Roese #include "sata.h" 16*c0132f60SStefan Roese #include "utmi_phy.h" 17*c0132f60SStefan Roese 18*c0132f60SStefan Roese DECLARE_GLOBAL_DATA_PTR; 19*c0132f60SStefan Roese 20*c0132f60SStefan Roese #define SD_ADDR(base, lane) (base + 0x1000 * lane) 21*c0132f60SStefan Roese #define HPIPE_ADDR(base, lane) (SD_ADDR(base, lane) + 0x800) 22*c0132f60SStefan Roese #define COMPHY_ADDR(base, lane) (base + 0x28 * lane) 23*c0132f60SStefan Roese 24*c0132f60SStefan Roese struct utmi_phy_data { 25*c0132f60SStefan Roese void __iomem *utmi_base_addr; 26*c0132f60SStefan Roese void __iomem *usb_cfg_addr; 27*c0132f60SStefan Roese void __iomem *utmi_cfg_addr; 28*c0132f60SStefan Roese u32 utmi_phy_port; 29*c0132f60SStefan Roese }; 30*c0132f60SStefan Roese 31*c0132f60SStefan Roese /* 32*c0132f60SStefan Roese * For CP-110 we have 2 Selector registers "PHY Selectors", 33*c0132f60SStefan Roese * and "PIPE Selectors". 34*c0132f60SStefan Roese * PIPE selector include USB and PCIe options. 35*c0132f60SStefan Roese * PHY selector include the Ethernet and SATA options, every Ethernet 36*c0132f60SStefan Roese * option has different options, for example: serdes lane2 had option 37*c0132f60SStefan Roese * Eth_port_0 that include (SGMII0, XAUI0, RXAUI0, KR) 38*c0132f60SStefan Roese */ 39*c0132f60SStefan Roese struct comphy_mux_data cp110_comphy_phy_mux_data[] = { 40*c0132f60SStefan Roese {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII2, 0x1}, /* Lane 0 */ 41*c0132f60SStefan Roese {PHY_TYPE_XAUI2, 0x1}, {PHY_TYPE_SATA1, 0x4} } }, 42*c0132f60SStefan Roese {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII3, 0x1}, /* Lane 1 */ 43*c0132f60SStefan Roese {PHY_TYPE_XAUI3, 0x1}, {PHY_TYPE_SATA0, 0x4} } }, 44*c0132f60SStefan Roese {6, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x1}, /* Lane 2 */ 45*c0132f60SStefan Roese {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, 46*c0132f60SStefan Roese {PHY_TYPE_KR, 0x1}, {PHY_TYPE_SATA0, 0x4} } }, 47*c0132f60SStefan Roese {8, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x1}, /* Lane 3 */ 48*c0132f60SStefan Roese {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, 49*c0132f60SStefan Roese {PHY_TYPE_KR, 0x1}, {PHY_TYPE_XAUI1, 0x1}, 50*c0132f60SStefan Roese {PHY_TYPE_RXAUI1, 0x1}, {PHY_TYPE_SATA1, 0x4} } }, 51*c0132f60SStefan Roese {7, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x2}, /* Lane 4 */ 52*c0132f60SStefan Roese {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, {PHY_TYPE_KR, 0x1}, 53*c0132f60SStefan Roese {PHY_TYPE_SGMII2, 0x1}, {PHY_TYPE_XAUI2, 0x1} } }, 54*c0132f60SStefan Roese {6, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_XAUI1, 0x1}, /* Lane 5 */ 55*c0132f60SStefan Roese {PHY_TYPE_RXAUI1, 0x1}, {PHY_TYPE_SGMII3, 0x1}, 56*c0132f60SStefan Roese {PHY_TYPE_XAUI3, 0x1}, {PHY_TYPE_SATA1, 0x4} } }, 57*c0132f60SStefan Roese }; 58*c0132f60SStefan Roese 59*c0132f60SStefan Roese struct comphy_mux_data cp110_comphy_pipe_mux_data[] = { 60*c0132f60SStefan Roese {2, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_PEX0, 0x4} } }, /* Lane 0 */ 61*c0132f60SStefan Roese {4, {{PHY_TYPE_UNCONNECTED, 0x0}, /* Lane 1 */ 62*c0132f60SStefan Roese {PHY_TYPE_USB3_HOST0, 0x1}, {PHY_TYPE_USB3_DEVICE, 0x2}, 63*c0132f60SStefan Roese {PHY_TYPE_PEX0, 0x4} } }, 64*c0132f60SStefan Roese {3, {{PHY_TYPE_UNCONNECTED, 0x0}, /* Lane 2 */ 65*c0132f60SStefan Roese {PHY_TYPE_USB3_HOST0, 0x1}, {PHY_TYPE_PEX0, 0x4} } }, 66*c0132f60SStefan Roese {3, {{PHY_TYPE_UNCONNECTED, 0x0}, /* Lane 3 */ 67*c0132f60SStefan Roese {PHY_TYPE_USB3_HOST1, 0x1}, {PHY_TYPE_PEX0, 0x4} } }, 68*c0132f60SStefan Roese {4, {{PHY_TYPE_UNCONNECTED, 0x0}, /* Lane 4 */ 69*c0132f60SStefan Roese {PHY_TYPE_USB3_HOST1, 0x1}, 70*c0132f60SStefan Roese {PHY_TYPE_USB3_DEVICE, 0x2}, {PHY_TYPE_PEX1, 0x4} } }, 71*c0132f60SStefan Roese {2, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_PEX2, 0x4} } }, /* Lane 5 */ 72*c0132f60SStefan Roese }; 73*c0132f60SStefan Roese 74*c0132f60SStefan Roese static u32 polling_with_timeout(void __iomem *addr, u32 val, 75*c0132f60SStefan Roese u32 mask, unsigned long usec_timout) 76*c0132f60SStefan Roese { 77*c0132f60SStefan Roese u32 data; 78*c0132f60SStefan Roese 79*c0132f60SStefan Roese do { 80*c0132f60SStefan Roese udelay(1); 81*c0132f60SStefan Roese data = readl(addr) & mask; 82*c0132f60SStefan Roese } while (data != val && --usec_timout > 0); 83*c0132f60SStefan Roese 84*c0132f60SStefan Roese if (usec_timout == 0) 85*c0132f60SStefan Roese return data; 86*c0132f60SStefan Roese 87*c0132f60SStefan Roese return 0; 88*c0132f60SStefan Roese } 89*c0132f60SStefan Roese 90*c0132f60SStefan Roese static int comphy_pcie_power_up(u32 lane, u32 pcie_width, 91*c0132f60SStefan Roese bool clk_src, void __iomem *hpipe_base, 92*c0132f60SStefan Roese void __iomem *comphy_base) 93*c0132f60SStefan Roese { 94*c0132f60SStefan Roese u32 mask, data, ret = 1; 95*c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 96*c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 97*c0132f60SStefan Roese void __iomem *addr; 98*c0132f60SStefan Roese u32 pcie_clk = 0; /* set input by default */ 99*c0132f60SStefan Roese 100*c0132f60SStefan Roese debug_enter(); 101*c0132f60SStefan Roese 102*c0132f60SStefan Roese /* 103*c0132f60SStefan Roese * ToDo: 104*c0132f60SStefan Roese * Add SAR (Sample-At-Reset) configuration for the PCIe clock 105*c0132f60SStefan Roese * direction. SAR code is currently not ported from Marvell 106*c0132f60SStefan Roese * U-Boot to mainline version. 107*c0132f60SStefan Roese * 108*c0132f60SStefan Roese * SerDes Lane 4/5 got the PCIe ref-clock #1, 109*c0132f60SStefan Roese * and SerDes Lane 0 got PCIe ref-clock #0 110*c0132f60SStefan Roese */ 111*c0132f60SStefan Roese debug("PCIe clock = %x\n", pcie_clk); 112*c0132f60SStefan Roese debug("PCIe width = %d\n", pcie_width); 113*c0132f60SStefan Roese 114*c0132f60SStefan Roese /* enable PCIe by4 and by2 */ 115*c0132f60SStefan Roese if (lane == 0) { 116*c0132f60SStefan Roese if (pcie_width == 4) { 117*c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 118*c0132f60SStefan Roese 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET, 119*c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK); 120*c0132f60SStefan Roese } else if (pcie_width == 2) { 121*c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 122*c0132f60SStefan Roese 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET, 123*c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK); 124*c0132f60SStefan Roese } 125*c0132f60SStefan Roese } 126*c0132f60SStefan Roese 127*c0132f60SStefan Roese /* 128*c0132f60SStefan Roese * If PCIe clock is output and clock source from SerDes lane 5, 129*c0132f60SStefan Roese * we need to configure the clock-source MUX. 130*c0132f60SStefan Roese * By default, the clock source is from lane 4 131*c0132f60SStefan Roese */ 132*c0132f60SStefan Roese if (pcie_clk && clk_src && (lane == 5)) { 133*c0132f60SStefan Roese reg_set((void __iomem *)DFX_DEV_GEN_CTRL12, 134*c0132f60SStefan Roese 0x3 << DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET, 135*c0132f60SStefan Roese DFX_DEV_GEN_PCIE_CLK_SRC_MASK); 136*c0132f60SStefan Roese } 137*c0132f60SStefan Roese 138*c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 139*c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 140*c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 141*c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 142*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 143*c0132f60SStefan Roese data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 144*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK; 145*c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; 146*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; 147*c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; 148*c0132f60SStefan Roese mask |= COMMON_PHY_PHY_MODE_MASK; 149*c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET; 150*c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 151*c0132f60SStefan Roese 152*c0132f60SStefan Roese /* release from hard reset */ 153*c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK; 154*c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; 155*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; 156*c0132f60SStefan Roese data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; 157*c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 158*c0132f60SStefan Roese 159*c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 160*c0132f60SStefan Roese mdelay(1); 161*c0132f60SStefan Roese /* Start comphy Configuration */ 162*c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 163*c0132f60SStefan Roese /* Set PIPE soft reset */ 164*c0132f60SStefan Roese mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK; 165*c0132f60SStefan Roese data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET; 166*c0132f60SStefan Roese /* Set PHY datapath width mode for V0 */ 167*c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK; 168*c0132f60SStefan Roese data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET; 169*c0132f60SStefan Roese /* Set Data bus width USB mode for V0 */ 170*c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK; 171*c0132f60SStefan Roese data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET; 172*c0132f60SStefan Roese /* Set CORE_CLK output frequency for 250Mhz */ 173*c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK; 174*c0132f60SStefan Roese data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET; 175*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask); 176*c0132f60SStefan Roese /* Set PLL ready delay for 0x2 */ 177*c0132f60SStefan Roese data = 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET; 178*c0132f60SStefan Roese mask = HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK; 179*c0132f60SStefan Roese if (pcie_width != 1) { 180*c0132f60SStefan Roese data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET; 181*c0132f60SStefan Roese mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK; 182*c0132f60SStefan Roese data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET; 183*c0132f60SStefan Roese mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK; 184*c0132f60SStefan Roese } 185*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, data, mask); 186*c0132f60SStefan Roese 187*c0132f60SStefan Roese /* Set PIPE mode interface to PCIe3 - 0x1 & set lane order */ 188*c0132f60SStefan Roese data = 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET; 189*c0132f60SStefan Roese mask = HPIPE_CLK_SRC_HI_MODE_PIPE_MASK; 190*c0132f60SStefan Roese if (pcie_width != 1) { 191*c0132f60SStefan Roese mask |= HPIPE_CLK_SRC_HI_LANE_STRT_MASK; 192*c0132f60SStefan Roese mask |= HPIPE_CLK_SRC_HI_LANE_MASTER_MASK; 193*c0132f60SStefan Roese mask |= HPIPE_CLK_SRC_HI_LANE_BREAK_MASK; 194*c0132f60SStefan Roese if (lane == 0) { 195*c0132f60SStefan Roese data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET; 196*c0132f60SStefan Roese data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET; 197*c0132f60SStefan Roese } else if (lane == (pcie_width - 1)) { 198*c0132f60SStefan Roese data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET; 199*c0132f60SStefan Roese } 200*c0132f60SStefan Roese } 201*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_CLK_SRC_HI_REG, data, mask); 202*c0132f60SStefan Roese /* Config update polarity equalization */ 203*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG1_REG, 204*c0132f60SStefan Roese 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET, 205*c0132f60SStefan Roese HPIPE_CFG_UPDATE_POLARITY_MASK); 206*c0132f60SStefan Roese /* Set PIPE version 4 to mode enable */ 207*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_CTRL_28_REG, 208*c0132f60SStefan Roese 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET, 209*c0132f60SStefan Roese HPIPE_DFE_CTRL_28_PIPE4_MASK); 210*c0132f60SStefan Roese /* TODO: check if pcie clock is output/input - for bringup use input*/ 211*c0132f60SStefan Roese /* Enable PIN clock 100M_125M */ 212*c0132f60SStefan Roese mask = 0; 213*c0132f60SStefan Roese data = 0; 214*c0132f60SStefan Roese /* Only if clock is output, configure the clock-source mux */ 215*c0132f60SStefan Roese if (pcie_clk) { 216*c0132f60SStefan Roese mask |= HPIPE_MISC_CLK100M_125M_MASK; 217*c0132f60SStefan Roese data |= 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET; 218*c0132f60SStefan Roese } 219*c0132f60SStefan Roese /* 220*c0132f60SStefan Roese * Set PIN_TXDCLK_2X Clock Frequency Selection for outputs 500MHz 221*c0132f60SStefan Roese * clock 222*c0132f60SStefan Roese */ 223*c0132f60SStefan Roese mask |= HPIPE_MISC_TXDCLK_2X_MASK; 224*c0132f60SStefan Roese data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET; 225*c0132f60SStefan Roese /* Enable 500MHz Clock */ 226*c0132f60SStefan Roese mask |= HPIPE_MISC_CLK500_EN_MASK; 227*c0132f60SStefan Roese data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET; 228*c0132f60SStefan Roese if (pcie_clk) { /* output */ 229*c0132f60SStefan Roese /* Set reference clock comes from group 1 */ 230*c0132f60SStefan Roese mask |= HPIPE_MISC_REFCLK_SEL_MASK; 231*c0132f60SStefan Roese data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET; 232*c0132f60SStefan Roese } else { 233*c0132f60SStefan Roese /* Set reference clock comes from group 2 */ 234*c0132f60SStefan Roese mask |= HPIPE_MISC_REFCLK_SEL_MASK; 235*c0132f60SStefan Roese data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET; 236*c0132f60SStefan Roese } 237*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask); 238*c0132f60SStefan Roese if (pcie_clk) { /* output */ 239*c0132f60SStefan Roese /* Set reference frequcency select - 0x2 for 25MHz*/ 240*c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 241*c0132f60SStefan Roese data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 242*c0132f60SStefan Roese } else { 243*c0132f60SStefan Roese /* Set reference frequcency select - 0x0 for 100MHz*/ 244*c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 245*c0132f60SStefan Roese data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 246*c0132f60SStefan Roese } 247*c0132f60SStefan Roese /* Set PHY mode to PCIe */ 248*c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 249*c0132f60SStefan Roese data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 250*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 251*c0132f60SStefan Roese 252*c0132f60SStefan Roese /* ref clock alignment */ 253*c0132f60SStefan Roese if (pcie_width != 1) { 254*c0132f60SStefan Roese mask = HPIPE_LANE_ALIGN_OFF_MASK; 255*c0132f60SStefan Roese data = 0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET; 256*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LANE_ALIGN_REG, data, mask); 257*c0132f60SStefan Roese } 258*c0132f60SStefan Roese 259*c0132f60SStefan Roese /* 260*c0132f60SStefan Roese * Set the amount of time spent in the LoZ state - set for 0x7 only if 261*c0132f60SStefan Roese * the PCIe clock is output 262*c0132f60SStefan Roese */ 263*c0132f60SStefan Roese if (pcie_clk) { 264*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL, 265*c0132f60SStefan Roese 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET, 266*c0132f60SStefan Roese HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK); 267*c0132f60SStefan Roese } 268*c0132f60SStefan Roese 269*c0132f60SStefan Roese /* Set Maximal PHY Generation Setting(8Gbps) */ 270*c0132f60SStefan Roese mask = HPIPE_INTERFACE_GEN_MAX_MASK; 271*c0132f60SStefan Roese data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET; 272*c0132f60SStefan Roese /* Set Link Train Mode (Tx training control pins are used) */ 273*c0132f60SStefan Roese mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK; 274*c0132f60SStefan Roese data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET; 275*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_INTERFACE_REG, data, mask); 276*c0132f60SStefan Roese 277*c0132f60SStefan Roese /* Set Idle_sync enable */ 278*c0132f60SStefan Roese mask = HPIPE_PCIE_IDLE_SYNC_MASK; 279*c0132f60SStefan Roese data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET; 280*c0132f60SStefan Roese /* Select bits for PCIE Gen3(32bit) */ 281*c0132f60SStefan Roese mask |= HPIPE_PCIE_SEL_BITS_MASK; 282*c0132f60SStefan Roese data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET; 283*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PCIE_REG0, data, mask); 284*c0132f60SStefan Roese 285*c0132f60SStefan Roese /* Enable Tx_adapt_g1 */ 286*c0132f60SStefan Roese mask = HPIPE_TX_TRAIN_CTRL_G1_MASK; 287*c0132f60SStefan Roese data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET; 288*c0132f60SStefan Roese /* Enable Tx_adapt_gn1 */ 289*c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK; 290*c0132f60SStefan Roese data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET; 291*c0132f60SStefan Roese /* Disable Tx_adapt_g0 */ 292*c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK; 293*c0132f60SStefan Roese data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET; 294*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask); 295*c0132f60SStefan Roese 296*c0132f60SStefan Roese /* Set reg_tx_train_chk_init */ 297*c0132f60SStefan Roese mask = HPIPE_TX_TRAIN_CHK_INIT_MASK; 298*c0132f60SStefan Roese data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET; 299*c0132f60SStefan Roese /* Enable TX_COE_FM_PIN_PCIE3_EN */ 300*c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK; 301*c0132f60SStefan Roese data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET; 302*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask); 303*c0132f60SStefan Roese 304*c0132f60SStefan Roese debug("stage: TRx training parameters\n"); 305*c0132f60SStefan Roese /* Set Preset sweep configurations */ 306*c0132f60SStefan Roese mask = HPIPE_TX_TX_STATUS_CHECK_MODE_MASK; 307*c0132f60SStefan Roese data = 0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET; 308*c0132f60SStefan Roese 309*c0132f60SStefan Roese mask |= HPIPE_TX_NUM_OF_PRESET_MASK; 310*c0132f60SStefan Roese data |= 0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET; 311*c0132f60SStefan Roese 312*c0132f60SStefan Roese mask |= HPIPE_TX_SWEEP_PRESET_EN_MASK; 313*c0132f60SStefan Roese data |= 0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET; 314*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_11_REG, data, mask); 315*c0132f60SStefan Roese 316*c0132f60SStefan Roese /* Tx train start configuration */ 317*c0132f60SStefan Roese mask = HPIPE_TX_TRAIN_START_SQ_EN_MASK; 318*c0132f60SStefan Roese data = 0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET; 319*c0132f60SStefan Roese 320*c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK; 321*c0132f60SStefan Roese data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET; 322*c0132f60SStefan Roese 323*c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK; 324*c0132f60SStefan Roese data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET; 325*c0132f60SStefan Roese 326*c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK; 327*c0132f60SStefan Roese data |= 0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET; 328*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask); 329*c0132f60SStefan Roese 330*c0132f60SStefan Roese /* Enable Tx train P2P */ 331*c0132f60SStefan Roese mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK; 332*c0132f60SStefan Roese data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET; 333*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask); 334*c0132f60SStefan Roese 335*c0132f60SStefan Roese /* Configure Tx train timeout */ 336*c0132f60SStefan Roese mask = HPIPE_TRX_TRAIN_TIMER_MASK; 337*c0132f60SStefan Roese data = 0x17 << HPIPE_TRX_TRAIN_TIMER_OFFSET; 338*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_4_REG, data, mask); 339*c0132f60SStefan Roese 340*c0132f60SStefan Roese /* Disable G0/G1/GN1 adaptation */ 341*c0132f60SStefan Roese mask = HPIPE_TX_TRAIN_CTRL_G1_MASK | HPIPE_TX_TRAIN_CTRL_GN1_MASK 342*c0132f60SStefan Roese | HPIPE_TX_TRAIN_CTRL_G0_OFFSET; 343*c0132f60SStefan Roese data = 0; 344*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask); 345*c0132f60SStefan Roese 346*c0132f60SStefan Roese /* Disable DTL frequency loop */ 347*c0132f60SStefan Roese mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK; 348*c0132f60SStefan Roese data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET; 349*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask); 350*c0132f60SStefan Roese 351*c0132f60SStefan Roese /* Configure G3 DFE */ 352*c0132f60SStefan Roese mask = HPIPE_G3_DFE_RES_MASK; 353*c0132f60SStefan Roese data = 0x3 << HPIPE_G3_DFE_RES_OFFSET; 354*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask); 355*c0132f60SStefan Roese 356*c0132f60SStefan Roese /* Force DFE resolution (use GEN table value) */ 357*c0132f60SStefan Roese mask = HPIPE_DFE_RES_FORCE_MASK; 358*c0132f60SStefan Roese data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET; 359*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); 360*c0132f60SStefan Roese 361*c0132f60SStefan Roese /* Configure initial and final coefficient value for receiver */ 362*c0132f60SStefan Roese mask = HPIPE_G3_RX_SELMUPI_MASK; 363*c0132f60SStefan Roese data = 0x1 << HPIPE_G3_RX_SELMUPI_OFFSET; 364*c0132f60SStefan Roese 365*c0132f60SStefan Roese mask |= HPIPE_G3_RX_SELMUPF_MASK; 366*c0132f60SStefan Roese data |= 0x1 << HPIPE_G3_RX_SELMUPF_OFFSET; 367*c0132f60SStefan Roese 368*c0132f60SStefan Roese mask |= HPIPE_G3_SETTING_BIT_MASK; 369*c0132f60SStefan Roese data |= 0x0 << HPIPE_G3_SETTING_BIT_OFFSET; 370*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G3_SETTINGS_1_REG, data, mask); 371*c0132f60SStefan Roese 372*c0132f60SStefan Roese /* Trigger sampler enable pulse */ 373*c0132f60SStefan Roese mask = HPIPE_SMAPLER_MASK; 374*c0132f60SStefan Roese data = 0x1 << HPIPE_SMAPLER_OFFSET; 375*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask); 376*c0132f60SStefan Roese udelay(5); 377*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, 0, mask); 378*c0132f60SStefan Roese 379*c0132f60SStefan Roese /* FFE resistor tuning for different bandwidth */ 380*c0132f60SStefan Roese mask = HPIPE_G3_FFE_DEG_RES_LEVEL_MASK; 381*c0132f60SStefan Roese data = 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET; 382*c0132f60SStefan Roese 383*c0132f60SStefan Roese mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK; 384*c0132f60SStefan Roese data |= 0x1 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET; 385*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask); 386*c0132f60SStefan Roese 387*c0132f60SStefan Roese /* Set phy in root complex mode */ 388*c0132f60SStefan Roese mask = HPIPE_CFG_PHY_RC_EP_MASK; 389*c0132f60SStefan Roese data = 0x1 << HPIPE_CFG_PHY_RC_EP_OFFSET; 390*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LANE_EQU_CONFIG_0_REG, data, mask); 391*c0132f60SStefan Roese 392*c0132f60SStefan Roese debug("stage: Comphy power up\n"); 393*c0132f60SStefan Roese 394*c0132f60SStefan Roese /* 395*c0132f60SStefan Roese * For PCIe by4 or by2 - release from reset only after finish to 396*c0132f60SStefan Roese * configure all lanes 397*c0132f60SStefan Roese */ 398*c0132f60SStefan Roese if ((pcie_width == 1) || (lane == (pcie_width - 1))) { 399*c0132f60SStefan Roese u32 i, start_lane, end_lane; 400*c0132f60SStefan Roese 401*c0132f60SStefan Roese if (pcie_width != 1) { 402*c0132f60SStefan Roese /* allows writing to all lanes in one write */ 403*c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 404*c0132f60SStefan Roese 0x0 << 405*c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_OFFSET, 406*c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_MASK); 407*c0132f60SStefan Roese start_lane = 0; 408*c0132f60SStefan Roese end_lane = pcie_width; 409*c0132f60SStefan Roese 410*c0132f60SStefan Roese /* 411*c0132f60SStefan Roese * Release from PIPE soft reset 412*c0132f60SStefan Roese * for PCIe by4 or by2 - release from soft reset 413*c0132f60SStefan Roese * all lanes - can't use read modify write 414*c0132f60SStefan Roese */ 415*c0132f60SStefan Roese reg_set(HPIPE_ADDR(hpipe_base, 0) + 416*c0132f60SStefan Roese HPIPE_RST_CLK_CTRL_REG, 0x24, 0xffffffff); 417*c0132f60SStefan Roese } else { 418*c0132f60SStefan Roese start_lane = lane; 419*c0132f60SStefan Roese end_lane = lane + 1; 420*c0132f60SStefan Roese 421*c0132f60SStefan Roese /* 422*c0132f60SStefan Roese * Release from PIPE soft reset 423*c0132f60SStefan Roese * for PCIe by4 or by2 - release from soft reset 424*c0132f60SStefan Roese * all lanes 425*c0132f60SStefan Roese */ 426*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, 427*c0132f60SStefan Roese 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET, 428*c0132f60SStefan Roese HPIPE_RST_CLK_CTRL_PIPE_RST_MASK); 429*c0132f60SStefan Roese } 430*c0132f60SStefan Roese 431*c0132f60SStefan Roese 432*c0132f60SStefan Roese if (pcie_width != 1) { 433*c0132f60SStefan Roese /* disable writing to all lanes with one write */ 434*c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 435*c0132f60SStefan Roese 0x3210 << 436*c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_OFFSET, 437*c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_MASK); 438*c0132f60SStefan Roese } 439*c0132f60SStefan Roese 440*c0132f60SStefan Roese debug("stage: Check PLL\n"); 441*c0132f60SStefan Roese /* Read lane status */ 442*c0132f60SStefan Roese for (i = start_lane; i < end_lane; i++) { 443*c0132f60SStefan Roese addr = HPIPE_ADDR(hpipe_base, i) + 444*c0132f60SStefan Roese HPIPE_LANE_STATUS1_REG; 445*c0132f60SStefan Roese data = HPIPE_LANE_STATUS1_PCLK_EN_MASK; 446*c0132f60SStefan Roese mask = data; 447*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 448*c0132f60SStefan Roese if (data != 0) { 449*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 450*c0132f60SStefan Roese hpipe_addr + HPIPE_LANE_STATUS1_REG, 451*c0132f60SStefan Roese data); 452*c0132f60SStefan Roese error("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n"); 453*c0132f60SStefan Roese ret = 0; 454*c0132f60SStefan Roese } 455*c0132f60SStefan Roese } 456*c0132f60SStefan Roese } 457*c0132f60SStefan Roese 458*c0132f60SStefan Roese debug_exit(); 459*c0132f60SStefan Roese return ret; 460*c0132f60SStefan Roese } 461*c0132f60SStefan Roese 462*c0132f60SStefan Roese static int comphy_usb3_power_up(u32 lane, void __iomem *hpipe_base, 463*c0132f60SStefan Roese void __iomem *comphy_base) 464*c0132f60SStefan Roese { 465*c0132f60SStefan Roese u32 mask, data, ret = 1; 466*c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 467*c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 468*c0132f60SStefan Roese void __iomem *addr; 469*c0132f60SStefan Roese 470*c0132f60SStefan Roese debug_enter(); 471*c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 472*c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 473*c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 474*c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 475*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 476*c0132f60SStefan Roese data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 477*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK; 478*c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; 479*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; 480*c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; 481*c0132f60SStefan Roese mask |= COMMON_PHY_PHY_MODE_MASK; 482*c0132f60SStefan Roese data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET; 483*c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 484*c0132f60SStefan Roese 485*c0132f60SStefan Roese /* release from hard reset */ 486*c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK; 487*c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; 488*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; 489*c0132f60SStefan Roese data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; 490*c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 491*c0132f60SStefan Roese 492*c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 493*c0132f60SStefan Roese mdelay(1); 494*c0132f60SStefan Roese 495*c0132f60SStefan Roese /* Start comphy Configuration */ 496*c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 497*c0132f60SStefan Roese /* Set PIPE soft reset */ 498*c0132f60SStefan Roese mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK; 499*c0132f60SStefan Roese data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET; 500*c0132f60SStefan Roese /* Set PHY datapath width mode for V0 */ 501*c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK; 502*c0132f60SStefan Roese data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET; 503*c0132f60SStefan Roese /* Set Data bus width USB mode for V0 */ 504*c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK; 505*c0132f60SStefan Roese data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET; 506*c0132f60SStefan Roese /* Set CORE_CLK output frequency for 250Mhz */ 507*c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK; 508*c0132f60SStefan Roese data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET; 509*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask); 510*c0132f60SStefan Roese /* Set PLL ready delay for 0x2 */ 511*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, 512*c0132f60SStefan Roese 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET, 513*c0132f60SStefan Roese HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK); 514*c0132f60SStefan Roese /* Set reference clock to come from group 1 - 25Mhz */ 515*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, 516*c0132f60SStefan Roese 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET, 517*c0132f60SStefan Roese HPIPE_MISC_REFCLK_SEL_MASK); 518*c0132f60SStefan Roese /* Set reference frequcency select - 0x2 */ 519*c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 520*c0132f60SStefan Roese data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 521*c0132f60SStefan Roese /* Set PHY mode to USB - 0x5 */ 522*c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 523*c0132f60SStefan Roese data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 524*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 525*c0132f60SStefan Roese /* Set the amount of time spent in the LoZ state - set for 0x7 */ 526*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL, 527*c0132f60SStefan Roese 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET, 528*c0132f60SStefan Roese HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK); 529*c0132f60SStefan Roese /* Set max PHY generation setting - 5Gbps */ 530*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_INTERFACE_REG, 531*c0132f60SStefan Roese 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET, 532*c0132f60SStefan Roese HPIPE_INTERFACE_GEN_MAX_MASK); 533*c0132f60SStefan Roese /* Set select data width 20Bit (SEL_BITS[2:0]) */ 534*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, 535*c0132f60SStefan Roese 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, 536*c0132f60SStefan Roese HPIPE_LOOPBACK_SEL_MASK); 537*c0132f60SStefan Roese /* select de-emphasize 3.5db */ 538*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LANE_CONFIG0_REG, 539*c0132f60SStefan Roese 0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET, 540*c0132f60SStefan Roese HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK); 541*c0132f60SStefan Roese /* override tx margining from the MAC */ 542*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TST_MODE_CTRL_REG, 543*c0132f60SStefan Roese 0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET, 544*c0132f60SStefan Roese HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK); 545*c0132f60SStefan Roese 546*c0132f60SStefan Roese /* Start analog paramters from ETP(HW) */ 547*c0132f60SStefan Roese debug("stage: Analog paramters from ETP(HW)\n"); 548*c0132f60SStefan Roese /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */ 549*c0132f60SStefan Roese mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK; 550*c0132f60SStefan Roese data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET; 551*c0132f60SStefan Roese /* Set Override PHY DFE control pins for 0x1 */ 552*c0132f60SStefan Roese mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK; 553*c0132f60SStefan Roese data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET; 554*c0132f60SStefan Roese /* Set Spread Spectrum Clock Enable fot 0x1 */ 555*c0132f60SStefan Roese mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK; 556*c0132f60SStefan Roese data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET; 557*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask); 558*c0132f60SStefan Roese /* End of analog parameters */ 559*c0132f60SStefan Roese 560*c0132f60SStefan Roese debug("stage: Comphy power up\n"); 561*c0132f60SStefan Roese /* Release from PIPE soft reset */ 562*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, 563*c0132f60SStefan Roese 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET, 564*c0132f60SStefan Roese HPIPE_RST_CLK_CTRL_PIPE_RST_MASK); 565*c0132f60SStefan Roese 566*c0132f60SStefan Roese /* wait 15ms - for comphy calibration done */ 567*c0132f60SStefan Roese debug("stage: Check PLL\n"); 568*c0132f60SStefan Roese /* Read lane status */ 569*c0132f60SStefan Roese addr = hpipe_addr + HPIPE_LANE_STATUS1_REG; 570*c0132f60SStefan Roese data = HPIPE_LANE_STATUS1_PCLK_EN_MASK; 571*c0132f60SStefan Roese mask = data; 572*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 573*c0132f60SStefan Roese if (data != 0) { 574*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 575*c0132f60SStefan Roese hpipe_addr + HPIPE_LANE_STATUS1_REG, data); 576*c0132f60SStefan Roese error("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n"); 577*c0132f60SStefan Roese ret = 0; 578*c0132f60SStefan Roese } 579*c0132f60SStefan Roese 580*c0132f60SStefan Roese debug_exit(); 581*c0132f60SStefan Roese return ret; 582*c0132f60SStefan Roese } 583*c0132f60SStefan Roese 584*c0132f60SStefan Roese static int comphy_sata_power_up(u32 lane, void __iomem *hpipe_base, 585*c0132f60SStefan Roese void __iomem *comphy_base, int comphy_index) 586*c0132f60SStefan Roese { 587*c0132f60SStefan Roese u32 mask, data, i, ret = 1; 588*c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 589*c0132f60SStefan Roese void __iomem *sd_ip_addr = SD_ADDR(hpipe_base, lane); 590*c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 591*c0132f60SStefan Roese void __iomem *addr; 592*c0132f60SStefan Roese void __iomem *sata_base = NULL; 593*c0132f60SStefan Roese int sata_node = -1; /* Set to -1 in order to read the first sata node */ 594*c0132f60SStefan Roese 595*c0132f60SStefan Roese debug_enter(); 596*c0132f60SStefan Roese 597*c0132f60SStefan Roese /* 598*c0132f60SStefan Roese * Assumption - each CP has only one SATA controller 599*c0132f60SStefan Roese * Calling fdt_node_offset_by_compatible first time (with sata_node = -1 600*c0132f60SStefan Roese * will return the first node always. 601*c0132f60SStefan Roese * In order to parse each CPs SATA node, fdt_node_offset_by_compatible 602*c0132f60SStefan Roese * must be called again (according to the CP id) 603*c0132f60SStefan Roese */ 604*c0132f60SStefan Roese for (i = 0; i < (comphy_index + 1); i++) 605*c0132f60SStefan Roese sata_node = fdt_node_offset_by_compatible( 606*c0132f60SStefan Roese gd->fdt_blob, sata_node, "marvell,armada-8k-ahci"); 607*c0132f60SStefan Roese 608*c0132f60SStefan Roese if (sata_node == 0) { 609*c0132f60SStefan Roese error("SATA node not found in FDT\n"); 610*c0132f60SStefan Roese return 0; 611*c0132f60SStefan Roese } 612*c0132f60SStefan Roese 613*c0132f60SStefan Roese sata_base = (void __iomem *)fdtdec_get_addr_size_auto_noparent( 614*c0132f60SStefan Roese gd->fdt_blob, sata_node, "reg", 0, NULL, true); 615*c0132f60SStefan Roese if (sata_base == NULL) { 616*c0132f60SStefan Roese error("SATA address not found in FDT\n"); 617*c0132f60SStefan Roese return 0; 618*c0132f60SStefan Roese } 619*c0132f60SStefan Roese 620*c0132f60SStefan Roese debug("SATA address found in FDT %p\n", sata_base); 621*c0132f60SStefan Roese 622*c0132f60SStefan Roese debug("stage: MAC configuration - power down comphy\n"); 623*c0132f60SStefan Roese /* 624*c0132f60SStefan Roese * MAC configuration powe down comphy use indirect address for 625*c0132f60SStefan Roese * vendor spesific SATA control register 626*c0132f60SStefan Roese */ 627*c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_ADDRESS, 628*c0132f60SStefan Roese SATA_CONTROL_REG << SATA3_VENDOR_ADDR_OFSSET, 629*c0132f60SStefan Roese SATA3_VENDOR_ADDR_MASK); 630*c0132f60SStefan Roese /* SATA 0 power down */ 631*c0132f60SStefan Roese mask = SATA3_CTRL_SATA0_PD_MASK; 632*c0132f60SStefan Roese data = 0x1 << SATA3_CTRL_SATA0_PD_OFFSET; 633*c0132f60SStefan Roese /* SATA 1 power down */ 634*c0132f60SStefan Roese mask |= SATA3_CTRL_SATA1_PD_MASK; 635*c0132f60SStefan Roese data |= 0x1 << SATA3_CTRL_SATA1_PD_OFFSET; 636*c0132f60SStefan Roese /* SATA SSU disable */ 637*c0132f60SStefan Roese mask |= SATA3_CTRL_SATA1_ENABLE_MASK; 638*c0132f60SStefan Roese data |= 0x0 << SATA3_CTRL_SATA1_ENABLE_OFFSET; 639*c0132f60SStefan Roese /* SATA port 1 disable */ 640*c0132f60SStefan Roese mask |= SATA3_CTRL_SATA_SSU_MASK; 641*c0132f60SStefan Roese data |= 0x0 << SATA3_CTRL_SATA_SSU_OFFSET; 642*c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_DATA, data, mask); 643*c0132f60SStefan Roese 644*c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 645*c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 646*c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 647*c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 648*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 649*c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 650*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK; 651*c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; 652*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; 653*c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; 654*c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 655*c0132f60SStefan Roese 656*c0132f60SStefan Roese /* Set select data width 40Bit - SATA mode only */ 657*c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG6_REG, 658*c0132f60SStefan Roese 0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET, 659*c0132f60SStefan Roese COMMON_PHY_CFG6_IF_40_SEL_MASK); 660*c0132f60SStefan Roese 661*c0132f60SStefan Roese /* release from hard reset in SD external */ 662*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 663*c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 664*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 665*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 666*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 667*c0132f60SStefan Roese 668*c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 669*c0132f60SStefan Roese mdelay(1); 670*c0132f60SStefan Roese 671*c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 672*c0132f60SStefan Roese /* Start comphy Configuration */ 673*c0132f60SStefan Roese /* Set reference clock to comes from group 1 - choose 25Mhz */ 674*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, 675*c0132f60SStefan Roese 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET, 676*c0132f60SStefan Roese HPIPE_MISC_REFCLK_SEL_MASK); 677*c0132f60SStefan Roese /* Reference frequency select set 1 (for SATA = 25Mhz) */ 678*c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 679*c0132f60SStefan Roese data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 680*c0132f60SStefan Roese /* PHY mode select (set SATA = 0x0 */ 681*c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 682*c0132f60SStefan Roese data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 683*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 684*c0132f60SStefan Roese /* Set max PHY generation setting - 6Gbps */ 685*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_INTERFACE_REG, 686*c0132f60SStefan Roese 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET, 687*c0132f60SStefan Roese HPIPE_INTERFACE_GEN_MAX_MASK); 688*c0132f60SStefan Roese /* Set select data width 40Bit (SEL_BITS[2:0]) */ 689*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, 690*c0132f60SStefan Roese 0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK); 691*c0132f60SStefan Roese 692*c0132f60SStefan Roese debug("stage: Analog paramters from ETP(HW)\n"); 693*c0132f60SStefan Roese /* 694*c0132f60SStefan Roese * TODO: Set analog paramters from ETP(HW) - for now use the 695*c0132f60SStefan Roese * default datas 696*c0132f60SStefan Roese */ 697*c0132f60SStefan Roese 698*c0132f60SStefan Roese /* DFE reset sequence */ 699*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 700*c0132f60SStefan Roese 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET, 701*c0132f60SStefan Roese HPIPE_PWR_CTR_RST_DFE_MASK); 702*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 703*c0132f60SStefan Roese 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET, 704*c0132f60SStefan Roese HPIPE_PWR_CTR_RST_DFE_MASK); 705*c0132f60SStefan Roese /* SW reset for interupt logic */ 706*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 707*c0132f60SStefan Roese 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET, 708*c0132f60SStefan Roese HPIPE_PWR_CTR_SFT_RST_MASK); 709*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 710*c0132f60SStefan Roese 0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET, 711*c0132f60SStefan Roese HPIPE_PWR_CTR_SFT_RST_MASK); 712*c0132f60SStefan Roese 713*c0132f60SStefan Roese debug("stage: Comphy power up\n"); 714*c0132f60SStefan Roese /* 715*c0132f60SStefan Roese * MAC configuration power up comphy - power up PLL/TX/RX 716*c0132f60SStefan Roese * use indirect address for vendor spesific SATA control register 717*c0132f60SStefan Roese */ 718*c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_ADDRESS, 719*c0132f60SStefan Roese SATA_CONTROL_REG << SATA3_VENDOR_ADDR_OFSSET, 720*c0132f60SStefan Roese SATA3_VENDOR_ADDR_MASK); 721*c0132f60SStefan Roese /* SATA 0 power up */ 722*c0132f60SStefan Roese mask = SATA3_CTRL_SATA0_PD_MASK; 723*c0132f60SStefan Roese data = 0x0 << SATA3_CTRL_SATA0_PD_OFFSET; 724*c0132f60SStefan Roese /* SATA 1 power up */ 725*c0132f60SStefan Roese mask |= SATA3_CTRL_SATA1_PD_MASK; 726*c0132f60SStefan Roese data |= 0x0 << SATA3_CTRL_SATA1_PD_OFFSET; 727*c0132f60SStefan Roese /* SATA SSU enable */ 728*c0132f60SStefan Roese mask |= SATA3_CTRL_SATA1_ENABLE_MASK; 729*c0132f60SStefan Roese data |= 0x1 << SATA3_CTRL_SATA1_ENABLE_OFFSET; 730*c0132f60SStefan Roese /* SATA port 1 enable */ 731*c0132f60SStefan Roese mask |= SATA3_CTRL_SATA_SSU_MASK; 732*c0132f60SStefan Roese data |= 0x1 << SATA3_CTRL_SATA_SSU_OFFSET; 733*c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_DATA, data, mask); 734*c0132f60SStefan Roese 735*c0132f60SStefan Roese /* MBUS request size and interface select register */ 736*c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_ADDRESS, 737*c0132f60SStefan Roese SATA_MBUS_SIZE_SELECT_REG << SATA3_VENDOR_ADDR_OFSSET, 738*c0132f60SStefan Roese SATA3_VENDOR_ADDR_MASK); 739*c0132f60SStefan Roese /* Mbus regret enable */ 740*c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_DATA, 741*c0132f60SStefan Roese 0x1 << SATA_MBUS_REGRET_EN_OFFSET, SATA_MBUS_REGRET_EN_MASK); 742*c0132f60SStefan Roese 743*c0132f60SStefan Roese debug("stage: Check PLL\n"); 744*c0132f60SStefan Roese 745*c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 746*c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_PLL_TX_MASK & 747*c0132f60SStefan Roese SD_EXTERNAL_STATUS0_PLL_RX_MASK; 748*c0132f60SStefan Roese mask = data; 749*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 750*c0132f60SStefan Roese if (data != 0) { 751*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 752*c0132f60SStefan Roese hpipe_addr + HPIPE_LANE_STATUS1_REG, data); 753*c0132f60SStefan Roese error("SD_EXTERNAL_STATUS0_PLL_TX is %d, SD_EXTERNAL_STATUS0_PLL_RX is %d\n", 754*c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK), 755*c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)); 756*c0132f60SStefan Roese ret = 0; 757*c0132f60SStefan Roese } 758*c0132f60SStefan Roese 759*c0132f60SStefan Roese debug_exit(); 760*c0132f60SStefan Roese return ret; 761*c0132f60SStefan Roese } 762*c0132f60SStefan Roese 763*c0132f60SStefan Roese static int comphy_sgmii_power_up(u32 lane, u32 sgmii_speed, 764*c0132f60SStefan Roese void __iomem *hpipe_base, 765*c0132f60SStefan Roese void __iomem *comphy_base) 766*c0132f60SStefan Roese { 767*c0132f60SStefan Roese u32 mask, data, ret = 1; 768*c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 769*c0132f60SStefan Roese void __iomem *sd_ip_addr = SD_ADDR(hpipe_base, lane); 770*c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 771*c0132f60SStefan Roese void __iomem *addr; 772*c0132f60SStefan Roese 773*c0132f60SStefan Roese debug_enter(); 774*c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 775*c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 776*c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 777*c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 778*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 779*c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 780*c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 781*c0132f60SStefan Roese 782*c0132f60SStefan Roese /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */ 783*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 784*c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 785*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK; 786*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK; 787*c0132f60SStefan Roese if (sgmii_speed == PHY_SPEED_1_25G) { 788*c0132f60SStefan Roese data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; 789*c0132f60SStefan Roese data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; 790*c0132f60SStefan Roese } else { 791*c0132f60SStefan Roese /* 3.125G */ 792*c0132f60SStefan Roese data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; 793*c0132f60SStefan Roese data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; 794*c0132f60SStefan Roese } 795*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 796*c0132f60SStefan Roese data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 797*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 798*c0132f60SStefan Roese data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 799*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK; 800*c0132f60SStefan Roese data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET; 801*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 802*c0132f60SStefan Roese 803*c0132f60SStefan Roese /* release from hard reset */ 804*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 805*c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 806*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 807*c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 808*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 809*c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 810*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 811*c0132f60SStefan Roese 812*c0132f60SStefan Roese /* release from hard reset */ 813*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 814*c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 815*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 816*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 817*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 818*c0132f60SStefan Roese 819*c0132f60SStefan Roese 820*c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 821*c0132f60SStefan Roese mdelay(1); 822*c0132f60SStefan Roese 823*c0132f60SStefan Roese /* Start comphy Configuration */ 824*c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 825*c0132f60SStefan Roese /* set reference clock */ 826*c0132f60SStefan Roese mask = HPIPE_MISC_REFCLK_SEL_MASK; 827*c0132f60SStefan Roese data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET; 828*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask); 829*c0132f60SStefan Roese /* Power and PLL Control */ 830*c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 831*c0132f60SStefan Roese data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 832*c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 833*c0132f60SStefan Roese data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 834*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 835*c0132f60SStefan Roese /* Loopback register */ 836*c0132f60SStefan Roese mask = HPIPE_LOOPBACK_SEL_MASK; 837*c0132f60SStefan Roese data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET; 838*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask); 839*c0132f60SStefan Roese /* rx control 1 */ 840*c0132f60SStefan Roese mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK; 841*c0132f60SStefan Roese data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET; 842*c0132f60SStefan Roese mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK; 843*c0132f60SStefan Roese data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET; 844*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask); 845*c0132f60SStefan Roese /* DTL Control */ 846*c0132f60SStefan Roese mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK; 847*c0132f60SStefan Roese data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET; 848*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask); 849*c0132f60SStefan Roese 850*c0132f60SStefan Roese /* Set analog paramters from ETP(HW) - for now use the default datas */ 851*c0132f60SStefan Roese debug("stage: Analog paramters from ETP(HW)\n"); 852*c0132f60SStefan Roese 853*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, 854*c0132f60SStefan Roese 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET, 855*c0132f60SStefan Roese HPIPE_G1_SET_0_G1_TX_EMPH1_MASK); 856*c0132f60SStefan Roese 857*c0132f60SStefan Roese debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n"); 858*c0132f60SStefan Roese /* SERDES External Configuration */ 859*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 860*c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 861*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 862*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 863*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 864*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 865*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 866*c0132f60SStefan Roese 867*c0132f60SStefan Roese /* check PLL rx & tx ready */ 868*c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 869*c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_PLL_RX_MASK | 870*c0132f60SStefan Roese SD_EXTERNAL_STATUS0_PLL_TX_MASK; 871*c0132f60SStefan Roese mask = data; 872*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 873*c0132f60SStefan Roese if (data != 0) { 874*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 875*c0132f60SStefan Roese sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 876*c0132f60SStefan Roese error("SD_EXTERNAL_STATUS0_PLL_RX is %d, SD_EXTERNAL_STATUS0_PLL_TX is %d\n", 877*c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK), 878*c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)); 879*c0132f60SStefan Roese ret = 0; 880*c0132f60SStefan Roese } 881*c0132f60SStefan Roese 882*c0132f60SStefan Roese /* RX init */ 883*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; 884*c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; 885*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 886*c0132f60SStefan Roese 887*c0132f60SStefan Roese /* check that RX init done */ 888*c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 889*c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_RX_INIT_MASK; 890*c0132f60SStefan Roese mask = data; 891*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 892*c0132f60SStefan Roese if (data != 0) { 893*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 894*c0132f60SStefan Roese error("SD_EXTERNAL_STATUS0_RX_INIT is 0\n"); 895*c0132f60SStefan Roese ret = 0; 896*c0132f60SStefan Roese } 897*c0132f60SStefan Roese 898*c0132f60SStefan Roese debug("stage: RF Reset\n"); 899*c0132f60SStefan Roese /* RF Reset */ 900*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; 901*c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; 902*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 903*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 904*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 905*c0132f60SStefan Roese 906*c0132f60SStefan Roese debug_exit(); 907*c0132f60SStefan Roese return ret; 908*c0132f60SStefan Roese } 909*c0132f60SStefan Roese 910*c0132f60SStefan Roese static int comphy_kr_power_up(u32 lane, void __iomem *hpipe_base, 911*c0132f60SStefan Roese void __iomem *comphy_base) 912*c0132f60SStefan Roese { 913*c0132f60SStefan Roese u32 mask, data, ret = 1; 914*c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 915*c0132f60SStefan Roese void __iomem *sd_ip_addr = SD_ADDR(hpipe_base, lane); 916*c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 917*c0132f60SStefan Roese void __iomem *addr; 918*c0132f60SStefan Roese 919*c0132f60SStefan Roese debug_enter(); 920*c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 921*c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 922*c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 923*c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 924*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 925*c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 926*c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 927*c0132f60SStefan Roese 928*c0132f60SStefan Roese /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */ 929*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 930*c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 931*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK; 932*c0132f60SStefan Roese data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; 933*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK; 934*c0132f60SStefan Roese data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; 935*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 936*c0132f60SStefan Roese data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 937*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 938*c0132f60SStefan Roese data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 939*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK; 940*c0132f60SStefan Roese data |= 0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET; 941*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 942*c0132f60SStefan Roese 943*c0132f60SStefan Roese /* release from hard reset */ 944*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 945*c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 946*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 947*c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 948*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 949*c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 950*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 951*c0132f60SStefan Roese 952*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 953*c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 954*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 955*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 956*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 957*c0132f60SStefan Roese 958*c0132f60SStefan Roese 959*c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 960*c0132f60SStefan Roese mdelay(1); 961*c0132f60SStefan Roese 962*c0132f60SStefan Roese /* Start comphy Configuration */ 963*c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 964*c0132f60SStefan Roese /* set reference clock */ 965*c0132f60SStefan Roese mask = HPIPE_MISC_ICP_FORCE_MASK; 966*c0132f60SStefan Roese data = 0x1 << HPIPE_MISC_ICP_FORCE_OFFSET; 967*c0132f60SStefan Roese mask |= HPIPE_MISC_REFCLK_SEL_MASK; 968*c0132f60SStefan Roese data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET; 969*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask); 970*c0132f60SStefan Roese /* Power and PLL Control */ 971*c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 972*c0132f60SStefan Roese data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 973*c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 974*c0132f60SStefan Roese data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 975*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 976*c0132f60SStefan Roese /* Loopback register */ 977*c0132f60SStefan Roese mask = HPIPE_LOOPBACK_SEL_MASK; 978*c0132f60SStefan Roese data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET; 979*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask); 980*c0132f60SStefan Roese /* rx control 1 */ 981*c0132f60SStefan Roese mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK; 982*c0132f60SStefan Roese data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET; 983*c0132f60SStefan Roese mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK; 984*c0132f60SStefan Roese data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET; 985*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask); 986*c0132f60SStefan Roese /* DTL Control */ 987*c0132f60SStefan Roese mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK; 988*c0132f60SStefan Roese data = 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET; 989*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask); 990*c0132f60SStefan Roese 991*c0132f60SStefan Roese /* Set analog paramters from ETP(HW) */ 992*c0132f60SStefan Roese debug("stage: Analog paramters from ETP(HW)\n"); 993*c0132f60SStefan Roese /* SERDES External Configuration 2 */ 994*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK; 995*c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET; 996*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask); 997*c0132f60SStefan Roese /* 0x7-DFE Resolution control */ 998*c0132f60SStefan Roese mask = HPIPE_DFE_RES_FORCE_MASK; 999*c0132f60SStefan Roese data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET; 1000*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); 1001*c0132f60SStefan Roese /* 0xd-G1_Setting_0 */ 1002*c0132f60SStefan Roese mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK; 1003*c0132f60SStefan Roese data = 0x1c << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET; 1004*c0132f60SStefan Roese mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK; 1005*c0132f60SStefan Roese data |= 0xe << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET; 1006*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask); 1007*c0132f60SStefan Roese /* Genration 1 setting 2 (G1_Setting_2) */ 1008*c0132f60SStefan Roese mask = HPIPE_G1_SET_2_G1_TX_EMPH0_MASK; 1009*c0132f60SStefan Roese data = 0x0 << HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET; 1010*c0132f60SStefan Roese mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK; 1011*c0132f60SStefan Roese data |= 0x1 << HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET; 1012*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask); 1013*c0132f60SStefan Roese /* Transmitter Slew Rate Control register (tx_reg1) */ 1014*c0132f60SStefan Roese mask = HPIPE_TX_REG1_TX_EMPH_RES_MASK; 1015*c0132f60SStefan Roese data = 0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET; 1016*c0132f60SStefan Roese mask |= HPIPE_TX_REG1_SLC_EN_MASK; 1017*c0132f60SStefan Roese data |= 0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET; 1018*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_REG1_REG, data, mask); 1019*c0132f60SStefan Roese /* Impedance Calibration Control register (cal_reg1) */ 1020*c0132f60SStefan Roese mask = HPIPE_CAL_REG_1_EXT_TXIMP_MASK; 1021*c0132f60SStefan Roese data = 0xe << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET; 1022*c0132f60SStefan Roese mask |= HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK; 1023*c0132f60SStefan Roese data |= 0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET; 1024*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_CAL_REG1_REG, data, mask); 1025*c0132f60SStefan Roese /* Generation 1 Setting 5 (g1_setting_5) */ 1026*c0132f60SStefan Roese mask = HPIPE_G1_SETTING_5_G1_ICP_MASK; 1027*c0132f60SStefan Roese data = 0 << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET; 1028*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SETTING_5_REG, data, mask); 1029*c0132f60SStefan Roese /* 0xE-G1_Setting_1 */ 1030*c0132f60SStefan Roese mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK; 1031*c0132f60SStefan Roese data = 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET; 1032*c0132f60SStefan Roese mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK; 1033*c0132f60SStefan Roese data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET; 1034*c0132f60SStefan Roese mask |= HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK; 1035*c0132f60SStefan Roese data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET; 1036*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask); 1037*c0132f60SStefan Roese /* 0xA-DFE_Reg3 */ 1038*c0132f60SStefan Roese mask = HPIPE_DFE_F3_F5_DFE_EN_MASK; 1039*c0132f60SStefan Roese data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET; 1040*c0132f60SStefan Roese mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK; 1041*c0132f60SStefan Roese data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET; 1042*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask); 1043*c0132f60SStefan Roese 1044*c0132f60SStefan Roese /* 0x111-G1_Setting_4 */ 1045*c0132f60SStefan Roese mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK; 1046*c0132f60SStefan Roese data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET; 1047*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask); 1048*c0132f60SStefan Roese /* Genration 1 setting 3 (G1_Setting_3) */ 1049*c0132f60SStefan Roese mask = HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK; 1050*c0132f60SStefan Roese data = 0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET; 1051*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask); 1052*c0132f60SStefan Roese 1053*c0132f60SStefan Roese debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n"); 1054*c0132f60SStefan Roese /* SERDES External Configuration */ 1055*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 1056*c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 1057*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 1058*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 1059*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 1060*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 1061*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 1062*c0132f60SStefan Roese 1063*c0132f60SStefan Roese 1064*c0132f60SStefan Roese /* check PLL rx & tx ready */ 1065*c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 1066*c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_PLL_RX_MASK | 1067*c0132f60SStefan Roese SD_EXTERNAL_STATUS0_PLL_TX_MASK; 1068*c0132f60SStefan Roese mask = data; 1069*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 1070*c0132f60SStefan Roese if (data != 0) { 1071*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 1072*c0132f60SStefan Roese error("SD_EXTERNAL_STATUS0_PLL_RX is %d, SD_EXTERNAL_STATUS0_PLL_TX is %d\n", 1073*c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK), 1074*c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)); 1075*c0132f60SStefan Roese ret = 0; 1076*c0132f60SStefan Roese } 1077*c0132f60SStefan Roese 1078*c0132f60SStefan Roese /* RX init */ 1079*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; 1080*c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; 1081*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1082*c0132f60SStefan Roese 1083*c0132f60SStefan Roese 1084*c0132f60SStefan Roese /* check that RX init done */ 1085*c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 1086*c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_RX_INIT_MASK; 1087*c0132f60SStefan Roese mask = data; 1088*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 1089*c0132f60SStefan Roese if (data != 0) { 1090*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 1091*c0132f60SStefan Roese sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 1092*c0132f60SStefan Roese error("SD_EXTERNAL_STATUS0_RX_INIT is 0\n"); 1093*c0132f60SStefan Roese ret = 0; 1094*c0132f60SStefan Roese } 1095*c0132f60SStefan Roese 1096*c0132f60SStefan Roese debug("stage: RF Reset\n"); 1097*c0132f60SStefan Roese /* RF Reset */ 1098*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; 1099*c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; 1100*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 1101*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 1102*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1103*c0132f60SStefan Roese 1104*c0132f60SStefan Roese debug_exit(); 1105*c0132f60SStefan Roese return ret; 1106*c0132f60SStefan Roese } 1107*c0132f60SStefan Roese 1108*c0132f60SStefan Roese static int comphy_rxauii_power_up(u32 lane, void __iomem *hpipe_base, 1109*c0132f60SStefan Roese void __iomem *comphy_base) 1110*c0132f60SStefan Roese { 1111*c0132f60SStefan Roese u32 mask, data, ret = 1; 1112*c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 1113*c0132f60SStefan Roese void __iomem *sd_ip_addr = SD_ADDR(hpipe_base, lane); 1114*c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 1115*c0132f60SStefan Roese void __iomem *addr; 1116*c0132f60SStefan Roese 1117*c0132f60SStefan Roese debug_enter(); 1118*c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 1119*c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 1120*c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 1121*c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 1122*c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 1123*c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 1124*c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 1125*c0132f60SStefan Roese 1126*c0132f60SStefan Roese if (lane == 2) { 1127*c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 1128*c0132f60SStefan Roese 0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET, 1129*c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_RXAUI0_MASK); 1130*c0132f60SStefan Roese } 1131*c0132f60SStefan Roese if (lane == 4) { 1132*c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 1133*c0132f60SStefan Roese 0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET, 1134*c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_RXAUI1_MASK); 1135*c0132f60SStefan Roese } 1136*c0132f60SStefan Roese 1137*c0132f60SStefan Roese /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */ 1138*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 1139*c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 1140*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK; 1141*c0132f60SStefan Roese data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; 1142*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK; 1143*c0132f60SStefan Roese data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; 1144*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 1145*c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 1146*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 1147*c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 1148*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK; 1149*c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET; 1150*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK; 1151*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET; 1152*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 1153*c0132f60SStefan Roese 1154*c0132f60SStefan Roese /* release from hard reset */ 1155*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 1156*c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 1157*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 1158*c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 1159*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 1160*c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 1161*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1162*c0132f60SStefan Roese 1163*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 1164*c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 1165*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 1166*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 1167*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1168*c0132f60SStefan Roese 1169*c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 1170*c0132f60SStefan Roese mdelay(1); 1171*c0132f60SStefan Roese 1172*c0132f60SStefan Roese /* Start comphy Configuration */ 1173*c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 1174*c0132f60SStefan Roese /* set reference clock */ 1175*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, 1176*c0132f60SStefan Roese 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET, 1177*c0132f60SStefan Roese HPIPE_MISC_REFCLK_SEL_MASK); 1178*c0132f60SStefan Roese /* Power and PLL Control */ 1179*c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 1180*c0132f60SStefan Roese data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 1181*c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 1182*c0132f60SStefan Roese data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 1183*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 1184*c0132f60SStefan Roese /* Loopback register */ 1185*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, 1186*c0132f60SStefan Roese 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK); 1187*c0132f60SStefan Roese /* rx control 1 */ 1188*c0132f60SStefan Roese mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK; 1189*c0132f60SStefan Roese data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET; 1190*c0132f60SStefan Roese mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK; 1191*c0132f60SStefan Roese data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET; 1192*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask); 1193*c0132f60SStefan Roese /* DTL Control */ 1194*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, 1195*c0132f60SStefan Roese 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET, 1196*c0132f60SStefan Roese HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK); 1197*c0132f60SStefan Roese 1198*c0132f60SStefan Roese /* Set analog paramters from ETP(HW) */ 1199*c0132f60SStefan Roese debug("stage: Analog paramters from ETP(HW)\n"); 1200*c0132f60SStefan Roese /* SERDES External Configuration 2 */ 1201*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, 1202*c0132f60SStefan Roese 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET, 1203*c0132f60SStefan Roese SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK); 1204*c0132f60SStefan Roese /* 0x7-DFE Resolution control */ 1205*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_REG0, 0x1 << HPIPE_DFE_RES_FORCE_OFFSET, 1206*c0132f60SStefan Roese HPIPE_DFE_RES_FORCE_MASK); 1207*c0132f60SStefan Roese /* 0xd-G1_Setting_0 */ 1208*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, 1209*c0132f60SStefan Roese 0xd << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET, 1210*c0132f60SStefan Roese HPIPE_G1_SET_0_G1_TX_EMPH1_MASK); 1211*c0132f60SStefan Roese /* 0xE-G1_Setting_1 */ 1212*c0132f60SStefan Roese mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK; 1213*c0132f60SStefan Roese data = 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET; 1214*c0132f60SStefan Roese mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK; 1215*c0132f60SStefan Roese data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET; 1216*c0132f60SStefan Roese mask |= HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK; 1217*c0132f60SStefan Roese data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET; 1218*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask); 1219*c0132f60SStefan Roese /* 0xA-DFE_Reg3 */ 1220*c0132f60SStefan Roese mask = HPIPE_DFE_F3_F5_DFE_EN_MASK; 1221*c0132f60SStefan Roese data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET; 1222*c0132f60SStefan Roese mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK; 1223*c0132f60SStefan Roese data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET; 1224*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask); 1225*c0132f60SStefan Roese 1226*c0132f60SStefan Roese /* 0x111-G1_Setting_4 */ 1227*c0132f60SStefan Roese mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK; 1228*c0132f60SStefan Roese data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET; 1229*c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask); 1230*c0132f60SStefan Roese 1231*c0132f60SStefan Roese debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n"); 1232*c0132f60SStefan Roese /* SERDES External Configuration */ 1233*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 1234*c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 1235*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 1236*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 1237*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 1238*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 1239*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 1240*c0132f60SStefan Roese 1241*c0132f60SStefan Roese 1242*c0132f60SStefan Roese /* check PLL rx & tx ready */ 1243*c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 1244*c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_PLL_RX_MASK | 1245*c0132f60SStefan Roese SD_EXTERNAL_STATUS0_PLL_TX_MASK; 1246*c0132f60SStefan Roese mask = data; 1247*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 1248*c0132f60SStefan Roese if (data != 0) { 1249*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 1250*c0132f60SStefan Roese sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 1251*c0132f60SStefan Roese error("SD_EXTERNAL_STATUS0_PLL_RX is %d, SD_EXTERNAL_STATUS0_PLL_TX is %d\n", 1252*c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK), 1253*c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)); 1254*c0132f60SStefan Roese ret = 0; 1255*c0132f60SStefan Roese } 1256*c0132f60SStefan Roese 1257*c0132f60SStefan Roese /* RX init */ 1258*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, 1259*c0132f60SStefan Roese 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET, 1260*c0132f60SStefan Roese SD_EXTERNAL_CONFIG1_RX_INIT_MASK); 1261*c0132f60SStefan Roese 1262*c0132f60SStefan Roese /* check that RX init done */ 1263*c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 1264*c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_RX_INIT_MASK; 1265*c0132f60SStefan Roese mask = data; 1266*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 1267*c0132f60SStefan Roese if (data != 0) { 1268*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 1269*c0132f60SStefan Roese sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 1270*c0132f60SStefan Roese error("SD_EXTERNAL_STATUS0_RX_INIT is 0\n"); 1271*c0132f60SStefan Roese ret = 0; 1272*c0132f60SStefan Roese } 1273*c0132f60SStefan Roese 1274*c0132f60SStefan Roese debug("stage: RF Reset\n"); 1275*c0132f60SStefan Roese /* RF Reset */ 1276*c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; 1277*c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; 1278*c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 1279*c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 1280*c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1281*c0132f60SStefan Roese 1282*c0132f60SStefan Roese debug_exit(); 1283*c0132f60SStefan Roese return ret; 1284*c0132f60SStefan Roese } 1285*c0132f60SStefan Roese 1286*c0132f60SStefan Roese static void comphy_utmi_power_down(u32 utmi_index, void __iomem *utmi_base_addr, 1287*c0132f60SStefan Roese void __iomem *usb_cfg_addr, 1288*c0132f60SStefan Roese void __iomem *utmi_cfg_addr, 1289*c0132f60SStefan Roese u32 utmi_phy_port) 1290*c0132f60SStefan Roese { 1291*c0132f60SStefan Roese u32 mask, data; 1292*c0132f60SStefan Roese 1293*c0132f60SStefan Roese debug_enter(); 1294*c0132f60SStefan Roese debug("stage: UTMI %d - Power down transceiver (power down Phy), Power down PLL, and SuspendDM\n", 1295*c0132f60SStefan Roese utmi_index); 1296*c0132f60SStefan Roese /* Power down UTMI PHY */ 1297*c0132f60SStefan Roese reg_set(utmi_cfg_addr, 0x0 << UTMI_PHY_CFG_PU_OFFSET, 1298*c0132f60SStefan Roese UTMI_PHY_CFG_PU_MASK); 1299*c0132f60SStefan Roese 1300*c0132f60SStefan Roese /* 1301*c0132f60SStefan Roese * If UTMI connected to USB Device, configure mux prior to PHY init 1302*c0132f60SStefan Roese * (Device can be connected to UTMI0 or to UTMI1) 1303*c0132f60SStefan Roese */ 1304*c0132f60SStefan Roese if (utmi_phy_port == UTMI_PHY_TO_USB_DEVICE0) { 1305*c0132f60SStefan Roese debug("stage: UTMI %d - Enable Device mode and configure UTMI mux\n", 1306*c0132f60SStefan Roese utmi_index); 1307*c0132f60SStefan Roese /* USB3 Device UTMI enable */ 1308*c0132f60SStefan Roese mask = UTMI_USB_CFG_DEVICE_EN_MASK; 1309*c0132f60SStefan Roese data = 0x1 << UTMI_USB_CFG_DEVICE_EN_OFFSET; 1310*c0132f60SStefan Roese /* USB3 Device UTMI MUX */ 1311*c0132f60SStefan Roese mask |= UTMI_USB_CFG_DEVICE_MUX_MASK; 1312*c0132f60SStefan Roese data |= utmi_index << UTMI_USB_CFG_DEVICE_MUX_OFFSET; 1313*c0132f60SStefan Roese reg_set(usb_cfg_addr, data, mask); 1314*c0132f60SStefan Roese } 1315*c0132f60SStefan Roese 1316*c0132f60SStefan Roese /* Set Test suspendm mode */ 1317*c0132f60SStefan Roese mask = UTMI_CTRL_STATUS0_SUSPENDM_MASK; 1318*c0132f60SStefan Roese data = 0x1 << UTMI_CTRL_STATUS0_SUSPENDM_OFFSET; 1319*c0132f60SStefan Roese /* Enable Test UTMI select */ 1320*c0132f60SStefan Roese mask |= UTMI_CTRL_STATUS0_TEST_SEL_MASK; 1321*c0132f60SStefan Roese data |= 0x1 << UTMI_CTRL_STATUS0_TEST_SEL_OFFSET; 1322*c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_CTRL_STATUS0_REG, data, mask); 1323*c0132f60SStefan Roese 1324*c0132f60SStefan Roese /* Wait for UTMI power down */ 1325*c0132f60SStefan Roese mdelay(1); 1326*c0132f60SStefan Roese 1327*c0132f60SStefan Roese debug_exit(); 1328*c0132f60SStefan Roese return; 1329*c0132f60SStefan Roese } 1330*c0132f60SStefan Roese 1331*c0132f60SStefan Roese static void comphy_utmi_phy_config(u32 utmi_index, void __iomem *utmi_base_addr, 1332*c0132f60SStefan Roese void __iomem *usb_cfg_addr, 1333*c0132f60SStefan Roese void __iomem *utmi_cfg_addr, 1334*c0132f60SStefan Roese u32 utmi_phy_port) 1335*c0132f60SStefan Roese { 1336*c0132f60SStefan Roese u32 mask, data; 1337*c0132f60SStefan Roese 1338*c0132f60SStefan Roese debug_exit(); 1339*c0132f60SStefan Roese debug("stage: Configure UTMI PHY %d registers\n", utmi_index); 1340*c0132f60SStefan Roese /* Reference Clock Divider Select */ 1341*c0132f60SStefan Roese mask = UTMI_PLL_CTRL_REFDIV_MASK; 1342*c0132f60SStefan Roese data = 0x5 << UTMI_PLL_CTRL_REFDIV_OFFSET; 1343*c0132f60SStefan Roese /* Feedback Clock Divider Select - 90 for 25Mhz*/ 1344*c0132f60SStefan Roese mask |= UTMI_PLL_CTRL_FBDIV_MASK; 1345*c0132f60SStefan Roese data |= 0x60 << UTMI_PLL_CTRL_FBDIV_OFFSET; 1346*c0132f60SStefan Roese /* Select LPFR - 0x0 for 25Mhz/5=5Mhz*/ 1347*c0132f60SStefan Roese mask |= UTMI_PLL_CTRL_SEL_LPFR_MASK; 1348*c0132f60SStefan Roese data |= 0x0 << UTMI_PLL_CTRL_SEL_LPFR_OFFSET; 1349*c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_PLL_CTRL_REG, data, mask); 1350*c0132f60SStefan Roese 1351*c0132f60SStefan Roese /* Impedance Calibration Threshold Setting */ 1352*c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_CALIB_CTRL_REG, 1353*c0132f60SStefan Roese 0x6 << UTMI_CALIB_CTRL_IMPCAL_VTH_OFFSET, 1354*c0132f60SStefan Roese UTMI_CALIB_CTRL_IMPCAL_VTH_MASK); 1355*c0132f60SStefan Roese 1356*c0132f60SStefan Roese /* Set LS TX driver strength coarse control */ 1357*c0132f60SStefan Roese mask = UTMI_TX_CH_CTRL_DRV_EN_LS_MASK; 1358*c0132f60SStefan Roese data = 0x3 << UTMI_TX_CH_CTRL_DRV_EN_LS_OFFSET; 1359*c0132f60SStefan Roese /* Set LS TX driver fine adjustment */ 1360*c0132f60SStefan Roese mask |= UTMI_TX_CH_CTRL_IMP_SEL_LS_MASK; 1361*c0132f60SStefan Roese data |= 0x3 << UTMI_TX_CH_CTRL_IMP_SEL_LS_OFFSET; 1362*c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_TX_CH_CTRL_REG, data, mask); 1363*c0132f60SStefan Roese 1364*c0132f60SStefan Roese /* Enable SQ */ 1365*c0132f60SStefan Roese mask = UTMI_RX_CH_CTRL0_SQ_DET_MASK; 1366*c0132f60SStefan Roese data = 0x0 << UTMI_RX_CH_CTRL0_SQ_DET_OFFSET; 1367*c0132f60SStefan Roese /* Enable analog squelch detect */ 1368*c0132f60SStefan Roese mask |= UTMI_RX_CH_CTRL0_SQ_ANA_DTC_MASK; 1369*c0132f60SStefan Roese data |= 0x1 << UTMI_RX_CH_CTRL0_SQ_ANA_DTC_OFFSET; 1370*c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_RX_CH_CTRL0_REG, data, mask); 1371*c0132f60SStefan Roese 1372*c0132f60SStefan Roese /* Set External squelch calibration number */ 1373*c0132f60SStefan Roese mask = UTMI_RX_CH_CTRL1_SQ_AMP_CAL_MASK; 1374*c0132f60SStefan Roese data = 0x1 << UTMI_RX_CH_CTRL1_SQ_AMP_CAL_OFFSET; 1375*c0132f60SStefan Roese /* Enable the External squelch calibration */ 1376*c0132f60SStefan Roese mask |= UTMI_RX_CH_CTRL1_SQ_AMP_CAL_EN_MASK; 1377*c0132f60SStefan Roese data |= 0x1 << UTMI_RX_CH_CTRL1_SQ_AMP_CAL_EN_OFFSET; 1378*c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_RX_CH_CTRL1_REG, data, mask); 1379*c0132f60SStefan Roese 1380*c0132f60SStefan Roese /* Set Control VDAT Reference Voltage - 0.325V */ 1381*c0132f60SStefan Roese mask = UTMI_CHGDTC_CTRL_VDAT_MASK; 1382*c0132f60SStefan Roese data = 0x1 << UTMI_CHGDTC_CTRL_VDAT_OFFSET; 1383*c0132f60SStefan Roese /* Set Control VSRC Reference Voltage - 0.6V */ 1384*c0132f60SStefan Roese mask |= UTMI_CHGDTC_CTRL_VSRC_MASK; 1385*c0132f60SStefan Roese data |= 0x1 << UTMI_CHGDTC_CTRL_VSRC_OFFSET; 1386*c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_CHGDTC_CTRL_REG, data, mask); 1387*c0132f60SStefan Roese 1388*c0132f60SStefan Roese debug_exit(); 1389*c0132f60SStefan Roese return; 1390*c0132f60SStefan Roese } 1391*c0132f60SStefan Roese 1392*c0132f60SStefan Roese static int comphy_utmi_power_up(u32 utmi_index, void __iomem *utmi_base_addr, 1393*c0132f60SStefan Roese void __iomem *usb_cfg_addr, 1394*c0132f60SStefan Roese void __iomem *utmi_cfg_addr, u32 utmi_phy_port) 1395*c0132f60SStefan Roese { 1396*c0132f60SStefan Roese u32 data, mask, ret = 1; 1397*c0132f60SStefan Roese void __iomem *addr; 1398*c0132f60SStefan Roese 1399*c0132f60SStefan Roese debug_enter(); 1400*c0132f60SStefan Roese debug("stage: UTMI %d - Power up transceiver(Power up Phy), and exit SuspendDM\n", 1401*c0132f60SStefan Roese utmi_index); 1402*c0132f60SStefan Roese /* Power UP UTMI PHY */ 1403*c0132f60SStefan Roese reg_set(utmi_cfg_addr, 0x1 << UTMI_PHY_CFG_PU_OFFSET, 1404*c0132f60SStefan Roese UTMI_PHY_CFG_PU_MASK); 1405*c0132f60SStefan Roese /* Disable Test UTMI select */ 1406*c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_CTRL_STATUS0_REG, 1407*c0132f60SStefan Roese 0x0 << UTMI_CTRL_STATUS0_TEST_SEL_OFFSET, 1408*c0132f60SStefan Roese UTMI_CTRL_STATUS0_TEST_SEL_MASK); 1409*c0132f60SStefan Roese 1410*c0132f60SStefan Roese debug("stage: Polling for PLL and impedance calibration done, and PLL ready done\n"); 1411*c0132f60SStefan Roese addr = utmi_base_addr + UTMI_CALIB_CTRL_REG; 1412*c0132f60SStefan Roese data = UTMI_CALIB_CTRL_IMPCAL_DONE_MASK; 1413*c0132f60SStefan Roese mask = data; 1414*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 1415*c0132f60SStefan Roese if (data != 0) { 1416*c0132f60SStefan Roese error("Impedance calibration is not done\n"); 1417*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", addr, data); 1418*c0132f60SStefan Roese ret = 0; 1419*c0132f60SStefan Roese } 1420*c0132f60SStefan Roese 1421*c0132f60SStefan Roese data = UTMI_CALIB_CTRL_PLLCAL_DONE_MASK; 1422*c0132f60SStefan Roese mask = data; 1423*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 1424*c0132f60SStefan Roese if (data != 0) { 1425*c0132f60SStefan Roese error("PLL calibration is not done\n"); 1426*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", addr, data); 1427*c0132f60SStefan Roese ret = 0; 1428*c0132f60SStefan Roese } 1429*c0132f60SStefan Roese 1430*c0132f60SStefan Roese addr = utmi_base_addr + UTMI_PLL_CTRL_REG; 1431*c0132f60SStefan Roese data = UTMI_PLL_CTRL_PLL_RDY_MASK; 1432*c0132f60SStefan Roese mask = data; 1433*c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 1434*c0132f60SStefan Roese if (data != 0) { 1435*c0132f60SStefan Roese error("PLL is not ready\n"); 1436*c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", addr, data); 1437*c0132f60SStefan Roese ret = 0; 1438*c0132f60SStefan Roese } 1439*c0132f60SStefan Roese 1440*c0132f60SStefan Roese if (ret) 1441*c0132f60SStefan Roese debug("Passed\n"); 1442*c0132f60SStefan Roese else 1443*c0132f60SStefan Roese debug("\n"); 1444*c0132f60SStefan Roese 1445*c0132f60SStefan Roese debug_exit(); 1446*c0132f60SStefan Roese return ret; 1447*c0132f60SStefan Roese } 1448*c0132f60SStefan Roese 1449*c0132f60SStefan Roese /* 1450*c0132f60SStefan Roese * comphy_utmi_phy_init initialize the UTMI PHY 1451*c0132f60SStefan Roese * the init split in 3 parts: 1452*c0132f60SStefan Roese * 1. Power down transceiver and PLL 1453*c0132f60SStefan Roese * 2. UTMI PHY configure 1454*c0132f60SStefan Roese * 3. Powe up transceiver and PLL 1455*c0132f60SStefan Roese * Note: - Power down/up should be once for both UTMI PHYs 1456*c0132f60SStefan Roese * - comphy_dedicated_phys_init call this function if at least there is 1457*c0132f60SStefan Roese * one UTMI PHY exists in FDT blob. access to cp110_utmi_data[0] is 1458*c0132f60SStefan Roese * legal 1459*c0132f60SStefan Roese */ 1460*c0132f60SStefan Roese static void comphy_utmi_phy_init(u32 utmi_phy_count, 1461*c0132f60SStefan Roese struct utmi_phy_data *cp110_utmi_data) 1462*c0132f60SStefan Roese { 1463*c0132f60SStefan Roese u32 i; 1464*c0132f60SStefan Roese 1465*c0132f60SStefan Roese debug_enter(); 1466*c0132f60SStefan Roese /* UTMI Power down */ 1467*c0132f60SStefan Roese for (i = 0; i < utmi_phy_count; i++) { 1468*c0132f60SStefan Roese comphy_utmi_power_down(i, cp110_utmi_data[i].utmi_base_addr, 1469*c0132f60SStefan Roese cp110_utmi_data[i].usb_cfg_addr, 1470*c0132f60SStefan Roese cp110_utmi_data[i].utmi_cfg_addr, 1471*c0132f60SStefan Roese cp110_utmi_data[i].utmi_phy_port); 1472*c0132f60SStefan Roese } 1473*c0132f60SStefan Roese /* PLL Power down */ 1474*c0132f60SStefan Roese debug("stage: UTMI PHY power down PLL\n"); 1475*c0132f60SStefan Roese for (i = 0; i < utmi_phy_count; i++) { 1476*c0132f60SStefan Roese reg_set(cp110_utmi_data[i].usb_cfg_addr, 1477*c0132f60SStefan Roese 0x0 << UTMI_USB_CFG_PLL_OFFSET, UTMI_USB_CFG_PLL_MASK); 1478*c0132f60SStefan Roese } 1479*c0132f60SStefan Roese /* UTMI configure */ 1480*c0132f60SStefan Roese for (i = 0; i < utmi_phy_count; i++) { 1481*c0132f60SStefan Roese comphy_utmi_phy_config(i, cp110_utmi_data[i].utmi_base_addr, 1482*c0132f60SStefan Roese cp110_utmi_data[i].usb_cfg_addr, 1483*c0132f60SStefan Roese cp110_utmi_data[i].utmi_cfg_addr, 1484*c0132f60SStefan Roese cp110_utmi_data[i].utmi_phy_port); 1485*c0132f60SStefan Roese } 1486*c0132f60SStefan Roese /* UTMI Power up */ 1487*c0132f60SStefan Roese for (i = 0; i < utmi_phy_count; i++) { 1488*c0132f60SStefan Roese if (!comphy_utmi_power_up(i, cp110_utmi_data[i].utmi_base_addr, 1489*c0132f60SStefan Roese cp110_utmi_data[i].usb_cfg_addr, 1490*c0132f60SStefan Roese cp110_utmi_data[i].utmi_cfg_addr, 1491*c0132f60SStefan Roese cp110_utmi_data[i].utmi_phy_port)) { 1492*c0132f60SStefan Roese error("Failed to initialize UTMI PHY %d\n", i); 1493*c0132f60SStefan Roese continue; 1494*c0132f60SStefan Roese } 1495*c0132f60SStefan Roese printf("UTMI PHY %d initialized to ", i); 1496*c0132f60SStefan Roese if (cp110_utmi_data[i].utmi_phy_port == UTMI_PHY_TO_USB_DEVICE0) 1497*c0132f60SStefan Roese printf("USB Device\n"); 1498*c0132f60SStefan Roese else 1499*c0132f60SStefan Roese printf("USB Host%d\n", 1500*c0132f60SStefan Roese cp110_utmi_data[i].utmi_phy_port); 1501*c0132f60SStefan Roese } 1502*c0132f60SStefan Roese /* PLL Power up */ 1503*c0132f60SStefan Roese debug("stage: UTMI PHY power up PLL\n"); 1504*c0132f60SStefan Roese for (i = 0; i < utmi_phy_count; i++) { 1505*c0132f60SStefan Roese reg_set(cp110_utmi_data[i].usb_cfg_addr, 1506*c0132f60SStefan Roese 0x1 << UTMI_USB_CFG_PLL_OFFSET, UTMI_USB_CFG_PLL_MASK); 1507*c0132f60SStefan Roese } 1508*c0132f60SStefan Roese 1509*c0132f60SStefan Roese debug_exit(); 1510*c0132f60SStefan Roese return; 1511*c0132f60SStefan Roese } 1512*c0132f60SStefan Roese 1513*c0132f60SStefan Roese /* 1514*c0132f60SStefan Roese * comphy_dedicated_phys_init initialize the dedicated PHYs 1515*c0132f60SStefan Roese * - not muxed SerDes lanes e.g. UTMI PHY 1516*c0132f60SStefan Roese */ 1517*c0132f60SStefan Roese void comphy_dedicated_phys_init(void) 1518*c0132f60SStefan Roese { 1519*c0132f60SStefan Roese struct utmi_phy_data cp110_utmi_data[MAX_UTMI_PHY_COUNT]; 1520*c0132f60SStefan Roese int node; 1521*c0132f60SStefan Roese int i; 1522*c0132f60SStefan Roese 1523*c0132f60SStefan Roese debug_enter(); 1524*c0132f60SStefan Roese debug("Initialize USB UTMI PHYs\n"); 1525*c0132f60SStefan Roese 1526*c0132f60SStefan Roese /* Find the UTMI phy node in device tree and go over them */ 1527*c0132f60SStefan Roese node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, 1528*c0132f60SStefan Roese "marvell,mvebu-utmi-2.6.0"); 1529*c0132f60SStefan Roese 1530*c0132f60SStefan Roese i = 0; 1531*c0132f60SStefan Roese while (node > 0) { 1532*c0132f60SStefan Roese /* get base address of UTMI phy */ 1533*c0132f60SStefan Roese cp110_utmi_data[i].utmi_base_addr = 1534*c0132f60SStefan Roese (void __iomem *)fdtdec_get_addr_size_auto_noparent( 1535*c0132f60SStefan Roese gd->fdt_blob, node, "reg", 0, NULL, true); 1536*c0132f60SStefan Roese if (cp110_utmi_data[i].utmi_base_addr == NULL) { 1537*c0132f60SStefan Roese error("UTMI PHY base address is invalid\n"); 1538*c0132f60SStefan Roese i++; 1539*c0132f60SStefan Roese continue; 1540*c0132f60SStefan Roese } 1541*c0132f60SStefan Roese 1542*c0132f60SStefan Roese /* get usb config address */ 1543*c0132f60SStefan Roese cp110_utmi_data[i].usb_cfg_addr = 1544*c0132f60SStefan Roese (void __iomem *)fdtdec_get_addr_size_auto_noparent( 1545*c0132f60SStefan Roese gd->fdt_blob, node, "reg", 1, NULL, true); 1546*c0132f60SStefan Roese if (cp110_utmi_data[i].usb_cfg_addr == NULL) { 1547*c0132f60SStefan Roese error("UTMI PHY base address is invalid\n"); 1548*c0132f60SStefan Roese i++; 1549*c0132f60SStefan Roese continue; 1550*c0132f60SStefan Roese } 1551*c0132f60SStefan Roese 1552*c0132f60SStefan Roese /* get UTMI config address */ 1553*c0132f60SStefan Roese cp110_utmi_data[i].utmi_cfg_addr = 1554*c0132f60SStefan Roese (void __iomem *)fdtdec_get_addr_size_auto_noparent( 1555*c0132f60SStefan Roese gd->fdt_blob, node, "reg", 2, NULL, true); 1556*c0132f60SStefan Roese if (cp110_utmi_data[i].utmi_cfg_addr == NULL) { 1557*c0132f60SStefan Roese error("UTMI PHY base address is invalid\n"); 1558*c0132f60SStefan Roese i++; 1559*c0132f60SStefan Roese continue; 1560*c0132f60SStefan Roese } 1561*c0132f60SStefan Roese 1562*c0132f60SStefan Roese /* 1563*c0132f60SStefan Roese * get the port number (to check if the utmi connected to 1564*c0132f60SStefan Roese * host/device) 1565*c0132f60SStefan Roese */ 1566*c0132f60SStefan Roese cp110_utmi_data[i].utmi_phy_port = fdtdec_get_int( 1567*c0132f60SStefan Roese gd->fdt_blob, node, "utmi-port", UTMI_PHY_INVALID); 1568*c0132f60SStefan Roese if (cp110_utmi_data[i].utmi_phy_port == UTMI_PHY_INVALID) { 1569*c0132f60SStefan Roese error("UTMI PHY port type is invalid\n"); 1570*c0132f60SStefan Roese i++; 1571*c0132f60SStefan Roese continue; 1572*c0132f60SStefan Roese } 1573*c0132f60SStefan Roese 1574*c0132f60SStefan Roese node = fdt_node_offset_by_compatible( 1575*c0132f60SStefan Roese gd->fdt_blob, node, "marvell,mvebu-utmi-2.6.0"); 1576*c0132f60SStefan Roese i++; 1577*c0132f60SStefan Roese } 1578*c0132f60SStefan Roese 1579*c0132f60SStefan Roese if (i > 0) 1580*c0132f60SStefan Roese comphy_utmi_phy_init(i, cp110_utmi_data); 1581*c0132f60SStefan Roese 1582*c0132f60SStefan Roese debug_exit(); 1583*c0132f60SStefan Roese } 1584*c0132f60SStefan Roese 1585*c0132f60SStefan Roese static void comphy_mux_cp110_init(struct chip_serdes_phy_config *ptr_chip_cfg, 1586*c0132f60SStefan Roese struct comphy_map *serdes_map) 1587*c0132f60SStefan Roese { 1588*c0132f60SStefan Roese void __iomem *comphy_base_addr; 1589*c0132f60SStefan Roese struct comphy_map comphy_map_pipe_data[MAX_LANE_OPTIONS]; 1590*c0132f60SStefan Roese struct comphy_map comphy_map_phy_data[MAX_LANE_OPTIONS]; 1591*c0132f60SStefan Roese u32 lane, comphy_max_count; 1592*c0132f60SStefan Roese 1593*c0132f60SStefan Roese comphy_max_count = ptr_chip_cfg->comphy_lanes_count; 1594*c0132f60SStefan Roese comphy_base_addr = ptr_chip_cfg->comphy_base_addr; 1595*c0132f60SStefan Roese 1596*c0132f60SStefan Roese /* 1597*c0132f60SStefan Roese * Copy the SerDes map configuration for PIPE map and PHY map 1598*c0132f60SStefan Roese * the comphy_mux_init modify the type of the lane if the type 1599*c0132f60SStefan Roese * is not valid because we have 2 selectores run the 1600*c0132f60SStefan Roese * comphy_mux_init twice and after that update the original 1601*c0132f60SStefan Roese * serdes_map 1602*c0132f60SStefan Roese */ 1603*c0132f60SStefan Roese for (lane = 0; lane < comphy_max_count; lane++) { 1604*c0132f60SStefan Roese comphy_map_pipe_data[lane].type = serdes_map[lane].type; 1605*c0132f60SStefan Roese comphy_map_pipe_data[lane].speed = serdes_map[lane].speed; 1606*c0132f60SStefan Roese comphy_map_phy_data[lane].type = serdes_map[lane].type; 1607*c0132f60SStefan Roese comphy_map_phy_data[lane].speed = serdes_map[lane].speed; 1608*c0132f60SStefan Roese } 1609*c0132f60SStefan Roese ptr_chip_cfg->mux_data = cp110_comphy_phy_mux_data; 1610*c0132f60SStefan Roese comphy_mux_init(ptr_chip_cfg, comphy_map_phy_data, 1611*c0132f60SStefan Roese comphy_base_addr + COMMON_SELECTOR_PHY_OFFSET); 1612*c0132f60SStefan Roese 1613*c0132f60SStefan Roese ptr_chip_cfg->mux_data = cp110_comphy_pipe_mux_data; 1614*c0132f60SStefan Roese comphy_mux_init(ptr_chip_cfg, comphy_map_pipe_data, 1615*c0132f60SStefan Roese comphy_base_addr + COMMON_SELECTOR_PIPE_OFFSET); 1616*c0132f60SStefan Roese /* Fix the type after check the PHY and PIPE configuration */ 1617*c0132f60SStefan Roese for (lane = 0; lane < comphy_max_count; lane++) { 1618*c0132f60SStefan Roese if ((comphy_map_pipe_data[lane].type == PHY_TYPE_UNCONNECTED) && 1619*c0132f60SStefan Roese (comphy_map_phy_data[lane].type == PHY_TYPE_UNCONNECTED)) 1620*c0132f60SStefan Roese serdes_map[lane].type = PHY_TYPE_UNCONNECTED; 1621*c0132f60SStefan Roese } 1622*c0132f60SStefan Roese } 1623*c0132f60SStefan Roese 1624*c0132f60SStefan Roese int comphy_cp110_init(struct chip_serdes_phy_config *ptr_chip_cfg, 1625*c0132f60SStefan Roese struct comphy_map *serdes_map) 1626*c0132f60SStefan Roese { 1627*c0132f60SStefan Roese struct comphy_map *ptr_comphy_map; 1628*c0132f60SStefan Roese void __iomem *comphy_base_addr, *hpipe_base_addr; 1629*c0132f60SStefan Roese u32 comphy_max_count, lane, ret = 0; 1630*c0132f60SStefan Roese u32 pcie_width = 0; 1631*c0132f60SStefan Roese 1632*c0132f60SStefan Roese debug_enter(); 1633*c0132f60SStefan Roese 1634*c0132f60SStefan Roese comphy_max_count = ptr_chip_cfg->comphy_lanes_count; 1635*c0132f60SStefan Roese comphy_base_addr = ptr_chip_cfg->comphy_base_addr; 1636*c0132f60SStefan Roese hpipe_base_addr = ptr_chip_cfg->hpipe3_base_addr; 1637*c0132f60SStefan Roese 1638*c0132f60SStefan Roese /* Config Comphy mux configuration */ 1639*c0132f60SStefan Roese comphy_mux_cp110_init(ptr_chip_cfg, serdes_map); 1640*c0132f60SStefan Roese 1641*c0132f60SStefan Roese /* Check if the first 4 lanes configured as By-4 */ 1642*c0132f60SStefan Roese for (lane = 0, ptr_comphy_map = serdes_map; lane < 4; 1643*c0132f60SStefan Roese lane++, ptr_comphy_map++) { 1644*c0132f60SStefan Roese if (ptr_comphy_map->type != PHY_TYPE_PEX0) 1645*c0132f60SStefan Roese break; 1646*c0132f60SStefan Roese pcie_width++; 1647*c0132f60SStefan Roese } 1648*c0132f60SStefan Roese 1649*c0132f60SStefan Roese for (lane = 0, ptr_comphy_map = serdes_map; lane < comphy_max_count; 1650*c0132f60SStefan Roese lane++, ptr_comphy_map++) { 1651*c0132f60SStefan Roese debug("Initialize serdes number %d\n", lane); 1652*c0132f60SStefan Roese debug("Serdes type = 0x%x\n", ptr_comphy_map->type); 1653*c0132f60SStefan Roese if (lane == 4) { 1654*c0132f60SStefan Roese /* 1655*c0132f60SStefan Roese * PCIe lanes above the first 4 lanes, can be only 1656*c0132f60SStefan Roese * by1 1657*c0132f60SStefan Roese */ 1658*c0132f60SStefan Roese pcie_width = 1; 1659*c0132f60SStefan Roese } 1660*c0132f60SStefan Roese switch (ptr_comphy_map->type) { 1661*c0132f60SStefan Roese case PHY_TYPE_UNCONNECTED: 1662*c0132f60SStefan Roese continue; 1663*c0132f60SStefan Roese break; 1664*c0132f60SStefan Roese case PHY_TYPE_PEX0: 1665*c0132f60SStefan Roese case PHY_TYPE_PEX1: 1666*c0132f60SStefan Roese case PHY_TYPE_PEX2: 1667*c0132f60SStefan Roese case PHY_TYPE_PEX3: 1668*c0132f60SStefan Roese ret = comphy_pcie_power_up( 1669*c0132f60SStefan Roese lane, pcie_width, ptr_comphy_map->clk_src, 1670*c0132f60SStefan Roese hpipe_base_addr, comphy_base_addr); 1671*c0132f60SStefan Roese break; 1672*c0132f60SStefan Roese case PHY_TYPE_SATA0: 1673*c0132f60SStefan Roese case PHY_TYPE_SATA1: 1674*c0132f60SStefan Roese case PHY_TYPE_SATA2: 1675*c0132f60SStefan Roese case PHY_TYPE_SATA3: 1676*c0132f60SStefan Roese ret = comphy_sata_power_up( 1677*c0132f60SStefan Roese lane, hpipe_base_addr, comphy_base_addr, 1678*c0132f60SStefan Roese ptr_chip_cfg->comphy_index); 1679*c0132f60SStefan Roese break; 1680*c0132f60SStefan Roese case PHY_TYPE_USB3_HOST0: 1681*c0132f60SStefan Roese case PHY_TYPE_USB3_HOST1: 1682*c0132f60SStefan Roese case PHY_TYPE_USB3_DEVICE: 1683*c0132f60SStefan Roese ret = comphy_usb3_power_up(lane, hpipe_base_addr, 1684*c0132f60SStefan Roese comphy_base_addr); 1685*c0132f60SStefan Roese break; 1686*c0132f60SStefan Roese case PHY_TYPE_SGMII0: 1687*c0132f60SStefan Roese case PHY_TYPE_SGMII1: 1688*c0132f60SStefan Roese case PHY_TYPE_SGMII2: 1689*c0132f60SStefan Roese case PHY_TYPE_SGMII3: 1690*c0132f60SStefan Roese if (ptr_comphy_map->speed == PHY_SPEED_INVALID) { 1691*c0132f60SStefan Roese debug("Warning: SGMII PHY speed in lane %d is invalid, set PHY speed to 1.25G\n", 1692*c0132f60SStefan Roese lane); 1693*c0132f60SStefan Roese ptr_comphy_map->speed = PHY_SPEED_1_25G; 1694*c0132f60SStefan Roese } 1695*c0132f60SStefan Roese ret = comphy_sgmii_power_up( 1696*c0132f60SStefan Roese lane, ptr_comphy_map->speed, hpipe_base_addr, 1697*c0132f60SStefan Roese comphy_base_addr); 1698*c0132f60SStefan Roese break; 1699*c0132f60SStefan Roese case PHY_TYPE_KR: 1700*c0132f60SStefan Roese ret = comphy_kr_power_up(lane, hpipe_base_addr, 1701*c0132f60SStefan Roese comphy_base_addr); 1702*c0132f60SStefan Roese break; 1703*c0132f60SStefan Roese case PHY_TYPE_RXAUI0: 1704*c0132f60SStefan Roese case PHY_TYPE_RXAUI1: 1705*c0132f60SStefan Roese ret = comphy_rxauii_power_up(lane, hpipe_base_addr, 1706*c0132f60SStefan Roese comphy_base_addr); 1707*c0132f60SStefan Roese break; 1708*c0132f60SStefan Roese default: 1709*c0132f60SStefan Roese debug("Unknown SerDes type, skip initialize SerDes %d\n", 1710*c0132f60SStefan Roese lane); 1711*c0132f60SStefan Roese break; 1712*c0132f60SStefan Roese } 1713*c0132f60SStefan Roese if (ret == 0) { 1714*c0132f60SStefan Roese /* 1715*c0132f60SStefan Roese * If interface wans't initialiuzed, set the lane to 1716*c0132f60SStefan Roese * PHY_TYPE_UNCONNECTED state. 1717*c0132f60SStefan Roese */ 1718*c0132f60SStefan Roese ptr_comphy_map->type = PHY_TYPE_UNCONNECTED; 1719*c0132f60SStefan Roese error("PLL is not locked - Failed to initialize lane %d\n", 1720*c0132f60SStefan Roese lane); 1721*c0132f60SStefan Roese } 1722*c0132f60SStefan Roese } 1723*c0132f60SStefan Roese 1724*c0132f60SStefan Roese debug_exit(); 1725*c0132f60SStefan Roese return 0; 1726*c0132f60SStefan Roese } 1727