183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2c0132f60SStefan Roese /* 3c0132f60SStefan Roese * Copyright (C) 2015-2016 Marvell International Ltd. 4c0132f60SStefan Roese */ 5c0132f60SStefan Roese 6c0132f60SStefan Roese #include <common.h> 7c0132f60SStefan Roese #include <fdtdec.h> 8c0132f60SStefan Roese #include <asm/io.h> 9c0132f60SStefan Roese #include <asm/arch/cpu.h> 10c0132f60SStefan Roese #include <asm/arch/soc.h> 11c0132f60SStefan Roese 124b8cb843SMarek Behún #include "comphy_core.h" 13c0132f60SStefan Roese #include "comphy_hpipe.h" 14c0132f60SStefan Roese #include "sata.h" 15c0132f60SStefan Roese #include "utmi_phy.h" 16c0132f60SStefan Roese 17c0132f60SStefan Roese DECLARE_GLOBAL_DATA_PTR; 18c0132f60SStefan Roese 19c0132f60SStefan Roese #define SD_ADDR(base, lane) (base + 0x1000 * lane) 20c0132f60SStefan Roese #define HPIPE_ADDR(base, lane) (SD_ADDR(base, lane) + 0x800) 21c0132f60SStefan Roese #define COMPHY_ADDR(base, lane) (base + 0x28 * lane) 22c0132f60SStefan Roese 23c0132f60SStefan Roese struct utmi_phy_data { 24c0132f60SStefan Roese void __iomem *utmi_base_addr; 25c0132f60SStefan Roese void __iomem *usb_cfg_addr; 26c0132f60SStefan Roese void __iomem *utmi_cfg_addr; 27c0132f60SStefan Roese u32 utmi_phy_port; 28c0132f60SStefan Roese }; 29c0132f60SStefan Roese 30c0132f60SStefan Roese /* 31c0132f60SStefan Roese * For CP-110 we have 2 Selector registers "PHY Selectors", 32c0132f60SStefan Roese * and "PIPE Selectors". 33c0132f60SStefan Roese * PIPE selector include USB and PCIe options. 34c0132f60SStefan Roese * PHY selector include the Ethernet and SATA options, every Ethernet 35c0132f60SStefan Roese * option has different options, for example: serdes lane2 had option 36e7ed9574SStefan Roese * Eth_port_0 that include (SGMII0, RXAUI0, SFI) 37c0132f60SStefan Roese */ 38c0132f60SStefan Roese struct comphy_mux_data cp110_comphy_phy_mux_data[] = { 39fdc9e880SStefan Roese {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII1, 0x1}, /* Lane 0 */ 40fdc9e880SStefan Roese {PHY_TYPE_SATA1, 0x4} } }, 41fdc9e880SStefan Roese {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII2, 0x1}, /* Lane 1 */ 42fdc9e880SStefan Roese {PHY_TYPE_SATA0, 0x4} } }, 43c0132f60SStefan Roese {6, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x1}, /* Lane 2 */ 44fdc9e880SStefan Roese {PHY_TYPE_RXAUI0, 0x1}, {PHY_TYPE_SFI, 0x1}, 45fdc9e880SStefan Roese {PHY_TYPE_SATA0, 0x4} } }, 46fdc9e880SStefan Roese {8, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_RXAUI1, 0x1}, /* Lane 3 */ 47fdc9e880SStefan Roese {PHY_TYPE_SGMII1, 0x2}, {PHY_TYPE_SATA1, 0x4} } }, 48e7ed9574SStefan Roese {7, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x2}, /* Lane 4 */ 49fdc9e880SStefan Roese {PHY_TYPE_RXAUI0, 0x2}, {PHY_TYPE_SFI, 0x2}, 50e7ed9574SStefan Roese {PHY_TYPE_SGMII1, 0x1} } }, 51fdc9e880SStefan Roese {6, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII2, 0x1}, /* Lane 5 */ 52fdc9e880SStefan Roese {PHY_TYPE_RXAUI1, 0x2}, {PHY_TYPE_SATA1, 0x4} } }, 53c0132f60SStefan Roese }; 54c0132f60SStefan Roese 55c0132f60SStefan Roese struct comphy_mux_data cp110_comphy_pipe_mux_data[] = { 56c0132f60SStefan Roese {2, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_PEX0, 0x4} } }, /* Lane 0 */ 57c0132f60SStefan Roese {4, {{PHY_TYPE_UNCONNECTED, 0x0}, /* Lane 1 */ 58c0132f60SStefan Roese {PHY_TYPE_USB3_HOST0, 0x1}, {PHY_TYPE_USB3_DEVICE, 0x2}, 59c0132f60SStefan Roese {PHY_TYPE_PEX0, 0x4} } }, 60c0132f60SStefan Roese {3, {{PHY_TYPE_UNCONNECTED, 0x0}, /* Lane 2 */ 61c0132f60SStefan Roese {PHY_TYPE_USB3_HOST0, 0x1}, {PHY_TYPE_PEX0, 0x4} } }, 62c0132f60SStefan Roese {3, {{PHY_TYPE_UNCONNECTED, 0x0}, /* Lane 3 */ 63c0132f60SStefan Roese {PHY_TYPE_USB3_HOST1, 0x1}, {PHY_TYPE_PEX0, 0x4} } }, 64c0132f60SStefan Roese {4, {{PHY_TYPE_UNCONNECTED, 0x0}, /* Lane 4 */ 65c0132f60SStefan Roese {PHY_TYPE_USB3_HOST1, 0x1}, 66c0132f60SStefan Roese {PHY_TYPE_USB3_DEVICE, 0x2}, {PHY_TYPE_PEX1, 0x4} } }, 67c0132f60SStefan Roese {2, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_PEX2, 0x4} } }, /* Lane 5 */ 68c0132f60SStefan Roese }; 69c0132f60SStefan Roese 70c0132f60SStefan Roese static u32 polling_with_timeout(void __iomem *addr, u32 val, 71c0132f60SStefan Roese u32 mask, unsigned long usec_timout) 72c0132f60SStefan Roese { 73c0132f60SStefan Roese u32 data; 74c0132f60SStefan Roese 75c0132f60SStefan Roese do { 76c0132f60SStefan Roese udelay(1); 77c0132f60SStefan Roese data = readl(addr) & mask; 78c0132f60SStefan Roese } while (data != val && --usec_timout > 0); 79c0132f60SStefan Roese 80c0132f60SStefan Roese if (usec_timout == 0) 81c0132f60SStefan Roese return data; 82c0132f60SStefan Roese 83c0132f60SStefan Roese return 0; 84c0132f60SStefan Roese } 85c0132f60SStefan Roese 867dda98e0SStefan Roese static int comphy_pcie_power_up(u32 lane, u32 pcie_width, bool clk_src, 877dda98e0SStefan Roese bool is_end_point, void __iomem *hpipe_base, 88c0132f60SStefan Roese void __iomem *comphy_base) 89c0132f60SStefan Roese { 90c0132f60SStefan Roese u32 mask, data, ret = 1; 91c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 92c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 93c0132f60SStefan Roese void __iomem *addr; 94c0132f60SStefan Roese u32 pcie_clk = 0; /* set input by default */ 95c0132f60SStefan Roese 96c0132f60SStefan Roese debug_enter(); 97c0132f60SStefan Roese 98c0132f60SStefan Roese /* 99c0132f60SStefan Roese * ToDo: 100c0132f60SStefan Roese * Add SAR (Sample-At-Reset) configuration for the PCIe clock 101c0132f60SStefan Roese * direction. SAR code is currently not ported from Marvell 102c0132f60SStefan Roese * U-Boot to mainline version. 103c0132f60SStefan Roese * 104c0132f60SStefan Roese * SerDes Lane 4/5 got the PCIe ref-clock #1, 105c0132f60SStefan Roese * and SerDes Lane 0 got PCIe ref-clock #0 106c0132f60SStefan Roese */ 107c0132f60SStefan Roese debug("PCIe clock = %x\n", pcie_clk); 1087dda98e0SStefan Roese debug("PCIe RC = %d\n", !is_end_point); 109c0132f60SStefan Roese debug("PCIe width = %d\n", pcie_width); 110c0132f60SStefan Roese 111c0132f60SStefan Roese /* enable PCIe by4 and by2 */ 112c0132f60SStefan Roese if (lane == 0) { 113c0132f60SStefan Roese if (pcie_width == 4) { 114c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 115c0132f60SStefan Roese 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET, 116c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK); 117c0132f60SStefan Roese } else if (pcie_width == 2) { 118c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 119c0132f60SStefan Roese 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET, 120c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK); 121c0132f60SStefan Roese } 122c0132f60SStefan Roese } 123c0132f60SStefan Roese 124c0132f60SStefan Roese /* 125c0132f60SStefan Roese * If PCIe clock is output and clock source from SerDes lane 5, 126c0132f60SStefan Roese * we need to configure the clock-source MUX. 127c0132f60SStefan Roese * By default, the clock source is from lane 4 128c0132f60SStefan Roese */ 129c0132f60SStefan Roese if (pcie_clk && clk_src && (lane == 5)) { 130c0132f60SStefan Roese reg_set((void __iomem *)DFX_DEV_GEN_CTRL12, 131c0132f60SStefan Roese 0x3 << DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET, 132c0132f60SStefan Roese DFX_DEV_GEN_PCIE_CLK_SRC_MASK); 133c0132f60SStefan Roese } 134c0132f60SStefan Roese 135c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 136c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 137c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 138c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 139c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 140c0132f60SStefan Roese data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 141c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK; 142c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; 143c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; 144c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; 145c0132f60SStefan Roese mask |= COMMON_PHY_PHY_MODE_MASK; 146c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET; 147c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 148c0132f60SStefan Roese 149c0132f60SStefan Roese /* release from hard reset */ 150c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK; 151c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; 152c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; 153c0132f60SStefan Roese data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; 154c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 155c0132f60SStefan Roese 156c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 157c0132f60SStefan Roese mdelay(1); 158c0132f60SStefan Roese /* Start comphy Configuration */ 159c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 160c0132f60SStefan Roese /* Set PIPE soft reset */ 161c0132f60SStefan Roese mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK; 162c0132f60SStefan Roese data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET; 163c0132f60SStefan Roese /* Set PHY datapath width mode for V0 */ 164c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK; 165c0132f60SStefan Roese data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET; 166c0132f60SStefan Roese /* Set Data bus width USB mode for V0 */ 167c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK; 168c0132f60SStefan Roese data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET; 169c0132f60SStefan Roese /* Set CORE_CLK output frequency for 250Mhz */ 170c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK; 171c0132f60SStefan Roese data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET; 172c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask); 173c0132f60SStefan Roese /* Set PLL ready delay for 0x2 */ 174c0132f60SStefan Roese data = 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET; 175c0132f60SStefan Roese mask = HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK; 176c0132f60SStefan Roese if (pcie_width != 1) { 177c0132f60SStefan Roese data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET; 178c0132f60SStefan Roese mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK; 179c0132f60SStefan Roese data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET; 180c0132f60SStefan Roese mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK; 181c0132f60SStefan Roese } 182c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, data, mask); 183c0132f60SStefan Roese 184c0132f60SStefan Roese /* Set PIPE mode interface to PCIe3 - 0x1 & set lane order */ 185c0132f60SStefan Roese data = 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET; 186c0132f60SStefan Roese mask = HPIPE_CLK_SRC_HI_MODE_PIPE_MASK; 187c0132f60SStefan Roese if (pcie_width != 1) { 188c0132f60SStefan Roese mask |= HPIPE_CLK_SRC_HI_LANE_STRT_MASK; 189c0132f60SStefan Roese mask |= HPIPE_CLK_SRC_HI_LANE_MASTER_MASK; 190c0132f60SStefan Roese mask |= HPIPE_CLK_SRC_HI_LANE_BREAK_MASK; 191c0132f60SStefan Roese if (lane == 0) { 192c0132f60SStefan Roese data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET; 193c0132f60SStefan Roese data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET; 194c0132f60SStefan Roese } else if (lane == (pcie_width - 1)) { 195c0132f60SStefan Roese data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET; 196c0132f60SStefan Roese } 197c0132f60SStefan Roese } 198c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_CLK_SRC_HI_REG, data, mask); 199c0132f60SStefan Roese /* Config update polarity equalization */ 200c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG1_REG, 201c0132f60SStefan Roese 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET, 202c0132f60SStefan Roese HPIPE_CFG_UPDATE_POLARITY_MASK); 203c0132f60SStefan Roese /* Set PIPE version 4 to mode enable */ 204c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_CTRL_28_REG, 205c0132f60SStefan Roese 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET, 206c0132f60SStefan Roese HPIPE_DFE_CTRL_28_PIPE4_MASK); 207c0132f60SStefan Roese /* TODO: check if pcie clock is output/input - for bringup use input*/ 208c0132f60SStefan Roese /* Enable PIN clock 100M_125M */ 209c0132f60SStefan Roese mask = 0; 210c0132f60SStefan Roese data = 0; 211c0132f60SStefan Roese /* Only if clock is output, configure the clock-source mux */ 212c0132f60SStefan Roese if (pcie_clk) { 213c0132f60SStefan Roese mask |= HPIPE_MISC_CLK100M_125M_MASK; 214c0132f60SStefan Roese data |= 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET; 215c0132f60SStefan Roese } 216c0132f60SStefan Roese /* 217c0132f60SStefan Roese * Set PIN_TXDCLK_2X Clock Frequency Selection for outputs 500MHz 218c0132f60SStefan Roese * clock 219c0132f60SStefan Roese */ 220c0132f60SStefan Roese mask |= HPIPE_MISC_TXDCLK_2X_MASK; 221c0132f60SStefan Roese data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET; 222c0132f60SStefan Roese /* Enable 500MHz Clock */ 223c0132f60SStefan Roese mask |= HPIPE_MISC_CLK500_EN_MASK; 224c0132f60SStefan Roese data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET; 225c0132f60SStefan Roese if (pcie_clk) { /* output */ 226c0132f60SStefan Roese /* Set reference clock comes from group 1 */ 227c0132f60SStefan Roese mask |= HPIPE_MISC_REFCLK_SEL_MASK; 228c0132f60SStefan Roese data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET; 229c0132f60SStefan Roese } else { 230c0132f60SStefan Roese /* Set reference clock comes from group 2 */ 231c0132f60SStefan Roese mask |= HPIPE_MISC_REFCLK_SEL_MASK; 232c0132f60SStefan Roese data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET; 233c0132f60SStefan Roese } 234ae07a70aSIgal Liberman mask |= HPIPE_MISC_ICP_FORCE_MASK; 235ae07a70aSIgal Liberman data |= 0x1 << HPIPE_MISC_ICP_FORCE_OFFSET; 236c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask); 237c0132f60SStefan Roese if (pcie_clk) { /* output */ 238c0132f60SStefan Roese /* Set reference frequcency select - 0x2 for 25MHz*/ 239c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 240c0132f60SStefan Roese data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 241c0132f60SStefan Roese } else { 242c0132f60SStefan Roese /* Set reference frequcency select - 0x0 for 100MHz*/ 243c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 244c0132f60SStefan Roese data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 245c0132f60SStefan Roese } 246c0132f60SStefan Roese /* Set PHY mode to PCIe */ 247c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 248c0132f60SStefan Roese data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 249c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 250c0132f60SStefan Roese 251c0132f60SStefan Roese /* ref clock alignment */ 252c0132f60SStefan Roese if (pcie_width != 1) { 253c0132f60SStefan Roese mask = HPIPE_LANE_ALIGN_OFF_MASK; 254c0132f60SStefan Roese data = 0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET; 255c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LANE_ALIGN_REG, data, mask); 256c0132f60SStefan Roese } 257c0132f60SStefan Roese 258c0132f60SStefan Roese /* 259c0132f60SStefan Roese * Set the amount of time spent in the LoZ state - set for 0x7 only if 260c0132f60SStefan Roese * the PCIe clock is output 261c0132f60SStefan Roese */ 262c0132f60SStefan Roese if (pcie_clk) { 263c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL, 264c0132f60SStefan Roese 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET, 265c0132f60SStefan Roese HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK); 266c0132f60SStefan Roese } 267c0132f60SStefan Roese 268c0132f60SStefan Roese /* Set Maximal PHY Generation Setting(8Gbps) */ 269c0132f60SStefan Roese mask = HPIPE_INTERFACE_GEN_MAX_MASK; 270c0132f60SStefan Roese data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET; 271ae07a70aSIgal Liberman /* Bypass frame detection and sync detection for RX DATA */ 272ae07a70aSIgal Liberman mask = HPIPE_INTERFACE_DET_BYPASS_MASK; 273ae07a70aSIgal Liberman data = 0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET; 274c0132f60SStefan Roese /* Set Link Train Mode (Tx training control pins are used) */ 275c0132f60SStefan Roese mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK; 276c0132f60SStefan Roese data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET; 277c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_INTERFACE_REG, data, mask); 278c0132f60SStefan Roese 279c0132f60SStefan Roese /* Set Idle_sync enable */ 280c0132f60SStefan Roese mask = HPIPE_PCIE_IDLE_SYNC_MASK; 281c0132f60SStefan Roese data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET; 282c0132f60SStefan Roese /* Select bits for PCIE Gen3(32bit) */ 283c0132f60SStefan Roese mask |= HPIPE_PCIE_SEL_BITS_MASK; 284c0132f60SStefan Roese data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET; 285c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PCIE_REG0, data, mask); 286c0132f60SStefan Roese 287c0132f60SStefan Roese /* Enable Tx_adapt_g1 */ 288c0132f60SStefan Roese mask = HPIPE_TX_TRAIN_CTRL_G1_MASK; 289c0132f60SStefan Roese data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET; 290c0132f60SStefan Roese /* Enable Tx_adapt_gn1 */ 291c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK; 292c0132f60SStefan Roese data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET; 293c0132f60SStefan Roese /* Disable Tx_adapt_g0 */ 294c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK; 295c0132f60SStefan Roese data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET; 296c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask); 297c0132f60SStefan Roese 298c0132f60SStefan Roese /* Set reg_tx_train_chk_init */ 299c0132f60SStefan Roese mask = HPIPE_TX_TRAIN_CHK_INIT_MASK; 300c0132f60SStefan Roese data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET; 301c0132f60SStefan Roese /* Enable TX_COE_FM_PIN_PCIE3_EN */ 302c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK; 303c0132f60SStefan Roese data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET; 304c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask); 305c0132f60SStefan Roese 306c0132f60SStefan Roese debug("stage: TRx training parameters\n"); 307c0132f60SStefan Roese /* Set Preset sweep configurations */ 308c0132f60SStefan Roese mask = HPIPE_TX_TX_STATUS_CHECK_MODE_MASK; 309c0132f60SStefan Roese data = 0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET; 310c0132f60SStefan Roese 311c0132f60SStefan Roese mask |= HPIPE_TX_NUM_OF_PRESET_MASK; 312c0132f60SStefan Roese data |= 0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET; 313c0132f60SStefan Roese 314c0132f60SStefan Roese mask |= HPIPE_TX_SWEEP_PRESET_EN_MASK; 315c0132f60SStefan Roese data |= 0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET; 316c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_11_REG, data, mask); 317c0132f60SStefan Roese 318c0132f60SStefan Roese /* Tx train start configuration */ 319c0132f60SStefan Roese mask = HPIPE_TX_TRAIN_START_SQ_EN_MASK; 320c0132f60SStefan Roese data = 0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET; 321c0132f60SStefan Roese 322c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK; 323c0132f60SStefan Roese data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET; 324c0132f60SStefan Roese 325c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK; 326c0132f60SStefan Roese data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET; 327c0132f60SStefan Roese 328c0132f60SStefan Roese mask |= HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK; 329c0132f60SStefan Roese data |= 0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET; 330c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask); 331c0132f60SStefan Roese 332c0132f60SStefan Roese /* Enable Tx train P2P */ 333c0132f60SStefan Roese mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK; 334c0132f60SStefan Roese data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET; 335c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask); 336c0132f60SStefan Roese 337c0132f60SStefan Roese /* Configure Tx train timeout */ 338c0132f60SStefan Roese mask = HPIPE_TRX_TRAIN_TIMER_MASK; 339c0132f60SStefan Roese data = 0x17 << HPIPE_TRX_TRAIN_TIMER_OFFSET; 340c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_4_REG, data, mask); 341c0132f60SStefan Roese 342c0132f60SStefan Roese /* Disable G0/G1/GN1 adaptation */ 343c0132f60SStefan Roese mask = HPIPE_TX_TRAIN_CTRL_G1_MASK | HPIPE_TX_TRAIN_CTRL_GN1_MASK 344c0132f60SStefan Roese | HPIPE_TX_TRAIN_CTRL_G0_OFFSET; 345c0132f60SStefan Roese data = 0; 346c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask); 347c0132f60SStefan Roese 348c0132f60SStefan Roese /* Disable DTL frequency loop */ 349c0132f60SStefan Roese mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK; 350c0132f60SStefan Roese data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET; 351c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask); 352c0132f60SStefan Roese 353c0132f60SStefan Roese /* Configure G3 DFE */ 354c0132f60SStefan Roese mask = HPIPE_G3_DFE_RES_MASK; 355c0132f60SStefan Roese data = 0x3 << HPIPE_G3_DFE_RES_OFFSET; 356c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask); 357c0132f60SStefan Roese 358ae07a70aSIgal Liberman /* Use TX/RX training result for DFE */ 359c0132f60SStefan Roese mask = HPIPE_DFE_RES_FORCE_MASK; 360ae07a70aSIgal Liberman data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET; 361c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); 362c0132f60SStefan Roese 363c0132f60SStefan Roese /* Configure initial and final coefficient value for receiver */ 364c01f9fe8SIgal Liberman mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK; 365c01f9fe8SIgal Liberman data = 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET; 366c0132f60SStefan Roese 367c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK; 368c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET; 369c0132f60SStefan Roese 370c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK; 371c01f9fe8SIgal Liberman data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET; 372c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask); 373c0132f60SStefan Roese 374c0132f60SStefan Roese /* Trigger sampler enable pulse */ 375c0132f60SStefan Roese mask = HPIPE_SMAPLER_MASK; 376c0132f60SStefan Roese data = 0x1 << HPIPE_SMAPLER_OFFSET; 377c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask); 378c0132f60SStefan Roese udelay(5); 379c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, 0, mask); 380c0132f60SStefan Roese 381c0132f60SStefan Roese /* FFE resistor tuning for different bandwidth */ 382c0132f60SStefan Roese mask = HPIPE_G3_FFE_DEG_RES_LEVEL_MASK; 383c0132f60SStefan Roese data = 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET; 384c0132f60SStefan Roese 385c0132f60SStefan Roese mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK; 386ae07a70aSIgal Liberman data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET; 387c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask); 388c0132f60SStefan Roese 389ae07a70aSIgal Liberman /* Pattern lock lost timeout disable */ 390ae07a70aSIgal Liberman mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK; 391ae07a70aSIgal Liberman data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET; 392ae07a70aSIgal Liberman reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask); 393ae07a70aSIgal Liberman 394ae07a70aSIgal Liberman /* Configure DFE adaptations */ 395ae07a70aSIgal Liberman mask = HPIPE_CDR_MAX_DFE_ADAPT_1_MASK; 396ae07a70aSIgal Liberman data = 0x1 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET; 397ae07a70aSIgal Liberman mask |= HPIPE_CDR_MAX_DFE_ADAPT_0_MASK; 398ae07a70aSIgal Liberman data |= 0x0 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET; 399ae07a70aSIgal Liberman mask |= HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK; 400ae07a70aSIgal Liberman data |= 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET; 401ae07a70aSIgal Liberman reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask); 402ae07a70aSIgal Liberman mask = HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK; 403ae07a70aSIgal Liberman data = 0x0 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET; 404ae07a70aSIgal Liberman reg_set(hpipe_addr + HPIPE_DFE_CONTROL_REG, data, mask); 405ae07a70aSIgal Liberman 406ae07a70aSIgal Liberman /* Genration 2 setting 1*/ 407ae07a70aSIgal Liberman mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK; 408ae07a70aSIgal Liberman data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET; 409ae07a70aSIgal Liberman mask |= HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK; 410ae07a70aSIgal Liberman data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET; 411ae07a70aSIgal Liberman mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK; 412ae07a70aSIgal Liberman data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET; 413ae07a70aSIgal Liberman reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask); 414ae07a70aSIgal Liberman 415ae07a70aSIgal Liberman /* DFE enable */ 416ae07a70aSIgal Liberman mask = HPIPE_G2_DFE_RES_MASK; 417ae07a70aSIgal Liberman data = 0x3 << HPIPE_G2_DFE_RES_OFFSET; 418ae07a70aSIgal Liberman reg_set(hpipe_addr + HPIPE_G2_SETTINGS_4_REG, data, mask); 419ae07a70aSIgal Liberman 420ae07a70aSIgal Liberman /* Configure DFE Resolution */ 421ae07a70aSIgal Liberman mask = HPIPE_LANE_CFG4_DFE_EN_SEL_MASK; 422ae07a70aSIgal Liberman data = 0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET; 423ae07a70aSIgal Liberman reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask); 424ae07a70aSIgal Liberman 425ae07a70aSIgal Liberman /* VDD calibration control */ 426ae07a70aSIgal Liberman mask = HPIPE_EXT_SELLV_RXSAMPL_MASK; 427ae07a70aSIgal Liberman data = 0x16 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET; 428ae07a70aSIgal Liberman reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask); 429ae07a70aSIgal Liberman 430ae07a70aSIgal Liberman /* Set PLL Charge-pump Current Control */ 431ae07a70aSIgal Liberman mask = HPIPE_G3_SETTING_5_G3_ICP_MASK; 432ae07a70aSIgal Liberman data = 0x4 << HPIPE_G3_SETTING_5_G3_ICP_OFFSET; 433ae07a70aSIgal Liberman reg_set(hpipe_addr + HPIPE_G3_SETTING_5_REG, data, mask); 434ae07a70aSIgal Liberman 435ae07a70aSIgal Liberman /* Set lane rqualization remote setting */ 436ae07a70aSIgal Liberman mask = HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK; 437ae07a70aSIgal Liberman data = 0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET; 438ae07a70aSIgal Liberman mask |= HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK; 439ae07a70aSIgal Liberman data |= 0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET; 440ae07a70aSIgal Liberman mask |= HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK; 441ae07a70aSIgal Liberman data |= 0x2 << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET; 442ae07a70aSIgal Liberman reg_set(hpipe_addr + HPIPE_LANE_EQ_REMOTE_SETTING_REG, data, mask); 443ae07a70aSIgal Liberman 4447dda98e0SStefan Roese if (!is_end_point) { 445c0132f60SStefan Roese /* Set phy in root complex mode */ 446c0132f60SStefan Roese mask = HPIPE_CFG_PHY_RC_EP_MASK; 447c0132f60SStefan Roese data = 0x1 << HPIPE_CFG_PHY_RC_EP_OFFSET; 448c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LANE_EQU_CONFIG_0_REG, data, mask); 4497dda98e0SStefan Roese } 450c0132f60SStefan Roese 451c0132f60SStefan Roese debug("stage: Comphy power up\n"); 452c0132f60SStefan Roese 453c0132f60SStefan Roese /* 454c0132f60SStefan Roese * For PCIe by4 or by2 - release from reset only after finish to 455c0132f60SStefan Roese * configure all lanes 456c0132f60SStefan Roese */ 457c0132f60SStefan Roese if ((pcie_width == 1) || (lane == (pcie_width - 1))) { 458c0132f60SStefan Roese u32 i, start_lane, end_lane; 459c0132f60SStefan Roese 460c0132f60SStefan Roese if (pcie_width != 1) { 461c0132f60SStefan Roese /* allows writing to all lanes in one write */ 462c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 463c0132f60SStefan Roese 0x0 << 464c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_OFFSET, 465c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_MASK); 466c0132f60SStefan Roese start_lane = 0; 467c0132f60SStefan Roese end_lane = pcie_width; 468c0132f60SStefan Roese 469c0132f60SStefan Roese /* 470c0132f60SStefan Roese * Release from PIPE soft reset 471c0132f60SStefan Roese * for PCIe by4 or by2 - release from soft reset 472c0132f60SStefan Roese * all lanes - can't use read modify write 473c0132f60SStefan Roese */ 474c0132f60SStefan Roese reg_set(HPIPE_ADDR(hpipe_base, 0) + 475c0132f60SStefan Roese HPIPE_RST_CLK_CTRL_REG, 0x24, 0xffffffff); 476c0132f60SStefan Roese } else { 477c0132f60SStefan Roese start_lane = lane; 478c0132f60SStefan Roese end_lane = lane + 1; 479c0132f60SStefan Roese 480c0132f60SStefan Roese /* 481c0132f60SStefan Roese * Release from PIPE soft reset 482c0132f60SStefan Roese * for PCIe by4 or by2 - release from soft reset 483c0132f60SStefan Roese * all lanes 484c0132f60SStefan Roese */ 485c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, 486c0132f60SStefan Roese 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET, 487c0132f60SStefan Roese HPIPE_RST_CLK_CTRL_PIPE_RST_MASK); 488c0132f60SStefan Roese } 489c0132f60SStefan Roese 490c0132f60SStefan Roese 491c0132f60SStefan Roese if (pcie_width != 1) { 492c0132f60SStefan Roese /* disable writing to all lanes with one write */ 493c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 494c0132f60SStefan Roese 0x3210 << 495c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_OFFSET, 496c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_MASK); 497c0132f60SStefan Roese } 498c0132f60SStefan Roese 499c0132f60SStefan Roese debug("stage: Check PLL\n"); 500c0132f60SStefan Roese /* Read lane status */ 501c0132f60SStefan Roese for (i = start_lane; i < end_lane; i++) { 502c0132f60SStefan Roese addr = HPIPE_ADDR(hpipe_base, i) + 503c0132f60SStefan Roese HPIPE_LANE_STATUS1_REG; 504c0132f60SStefan Roese data = HPIPE_LANE_STATUS1_PCLK_EN_MASK; 505c0132f60SStefan Roese mask = data; 506c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 507c0132f60SStefan Roese if (data != 0) { 508c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 509c0132f60SStefan Roese hpipe_addr + HPIPE_LANE_STATUS1_REG, 510c0132f60SStefan Roese data); 5119b643e31SMasahiro Yamada pr_err("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n"); 512c0132f60SStefan Roese ret = 0; 513c0132f60SStefan Roese } 514c0132f60SStefan Roese } 515c0132f60SStefan Roese } 516c0132f60SStefan Roese 517c0132f60SStefan Roese debug_exit(); 518c0132f60SStefan Roese return ret; 519c0132f60SStefan Roese } 520c0132f60SStefan Roese 521c0132f60SStefan Roese static int comphy_usb3_power_up(u32 lane, void __iomem *hpipe_base, 522c0132f60SStefan Roese void __iomem *comphy_base) 523c0132f60SStefan Roese { 524c0132f60SStefan Roese u32 mask, data, ret = 1; 525c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 526c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 527c0132f60SStefan Roese void __iomem *addr; 528c0132f60SStefan Roese 529c0132f60SStefan Roese debug_enter(); 530c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 531c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 532c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 533c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 534c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 535c0132f60SStefan Roese data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 536c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK; 537c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; 538c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; 539c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; 540c0132f60SStefan Roese mask |= COMMON_PHY_PHY_MODE_MASK; 541c0132f60SStefan Roese data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET; 542c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 543c0132f60SStefan Roese 544c0132f60SStefan Roese /* release from hard reset */ 545c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK; 546c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; 547c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; 548c0132f60SStefan Roese data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; 549c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 550c0132f60SStefan Roese 551c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 552c0132f60SStefan Roese mdelay(1); 553c0132f60SStefan Roese 554c0132f60SStefan Roese /* Start comphy Configuration */ 555c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 556c0132f60SStefan Roese /* Set PIPE soft reset */ 557c0132f60SStefan Roese mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK; 558c0132f60SStefan Roese data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET; 559c0132f60SStefan Roese /* Set PHY datapath width mode for V0 */ 560c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK; 561c0132f60SStefan Roese data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET; 562c0132f60SStefan Roese /* Set Data bus width USB mode for V0 */ 563c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK; 564c0132f60SStefan Roese data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET; 565c0132f60SStefan Roese /* Set CORE_CLK output frequency for 250Mhz */ 566c0132f60SStefan Roese mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK; 567c0132f60SStefan Roese data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET; 568c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask); 569c0132f60SStefan Roese /* Set PLL ready delay for 0x2 */ 570c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, 571c0132f60SStefan Roese 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET, 572c0132f60SStefan Roese HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK); 573c0132f60SStefan Roese /* Set reference clock to come from group 1 - 25Mhz */ 574c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, 575c0132f60SStefan Roese 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET, 576c0132f60SStefan Roese HPIPE_MISC_REFCLK_SEL_MASK); 577c0132f60SStefan Roese /* Set reference frequcency select - 0x2 */ 578c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 579c0132f60SStefan Roese data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 580c0132f60SStefan Roese /* Set PHY mode to USB - 0x5 */ 581c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 582c0132f60SStefan Roese data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 583c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 584c0132f60SStefan Roese /* Set the amount of time spent in the LoZ state - set for 0x7 */ 585c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL, 586c0132f60SStefan Roese 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET, 587c0132f60SStefan Roese HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK); 588c0132f60SStefan Roese /* Set max PHY generation setting - 5Gbps */ 589c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_INTERFACE_REG, 590c0132f60SStefan Roese 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET, 591c0132f60SStefan Roese HPIPE_INTERFACE_GEN_MAX_MASK); 592c0132f60SStefan Roese /* Set select data width 20Bit (SEL_BITS[2:0]) */ 593c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, 594c0132f60SStefan Roese 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, 595c0132f60SStefan Roese HPIPE_LOOPBACK_SEL_MASK); 596c0132f60SStefan Roese /* select de-emphasize 3.5db */ 597c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LANE_CONFIG0_REG, 598c0132f60SStefan Roese 0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET, 599c0132f60SStefan Roese HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK); 600c0132f60SStefan Roese /* override tx margining from the MAC */ 601c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TST_MODE_CTRL_REG, 602c0132f60SStefan Roese 0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET, 603c0132f60SStefan Roese HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK); 604c0132f60SStefan Roese 605c0132f60SStefan Roese /* Start analog paramters from ETP(HW) */ 606c0132f60SStefan Roese debug("stage: Analog paramters from ETP(HW)\n"); 607c0132f60SStefan Roese /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */ 608c0132f60SStefan Roese mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK; 609c0132f60SStefan Roese data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET; 610c0132f60SStefan Roese /* Set Override PHY DFE control pins for 0x1 */ 611c0132f60SStefan Roese mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK; 612c0132f60SStefan Roese data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET; 613c0132f60SStefan Roese /* Set Spread Spectrum Clock Enable fot 0x1 */ 614c0132f60SStefan Roese mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK; 615c0132f60SStefan Roese data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET; 616c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask); 617c0132f60SStefan Roese /* End of analog parameters */ 618c0132f60SStefan Roese 619c0132f60SStefan Roese debug("stage: Comphy power up\n"); 620c0132f60SStefan Roese /* Release from PIPE soft reset */ 621c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, 622c0132f60SStefan Roese 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET, 623c0132f60SStefan Roese HPIPE_RST_CLK_CTRL_PIPE_RST_MASK); 624c0132f60SStefan Roese 625c0132f60SStefan Roese /* wait 15ms - for comphy calibration done */ 626c0132f60SStefan Roese debug("stage: Check PLL\n"); 627c0132f60SStefan Roese /* Read lane status */ 628c0132f60SStefan Roese addr = hpipe_addr + HPIPE_LANE_STATUS1_REG; 629c0132f60SStefan Roese data = HPIPE_LANE_STATUS1_PCLK_EN_MASK; 630c0132f60SStefan Roese mask = data; 631c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 632c0132f60SStefan Roese if (data != 0) { 633c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 634c0132f60SStefan Roese hpipe_addr + HPIPE_LANE_STATUS1_REG, data); 6359b643e31SMasahiro Yamada pr_err("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n"); 636c0132f60SStefan Roese ret = 0; 637c0132f60SStefan Roese } 638c0132f60SStefan Roese 639c0132f60SStefan Roese debug_exit(); 640c0132f60SStefan Roese return ret; 641c0132f60SStefan Roese } 642c0132f60SStefan Roese 643c0132f60SStefan Roese static int comphy_sata_power_up(u32 lane, void __iomem *hpipe_base, 644*d13b740cSRabeeh Khoury void __iomem *comphy_base, int cp_index, 645*d13b740cSRabeeh Khoury u32 invert) 646c0132f60SStefan Roese { 647c0132f60SStefan Roese u32 mask, data, i, ret = 1; 648c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 649c0132f60SStefan Roese void __iomem *sd_ip_addr = SD_ADDR(hpipe_base, lane); 650c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 651c0132f60SStefan Roese void __iomem *addr; 652c0132f60SStefan Roese void __iomem *sata_base = NULL; 653c0132f60SStefan Roese int sata_node = -1; /* Set to -1 in order to read the first sata node */ 654c0132f60SStefan Roese 655c0132f60SStefan Roese debug_enter(); 656c0132f60SStefan Roese 657c0132f60SStefan Roese /* 658c0132f60SStefan Roese * Assumption - each CP has only one SATA controller 659c0132f60SStefan Roese * Calling fdt_node_offset_by_compatible first time (with sata_node = -1 660c0132f60SStefan Roese * will return the first node always. 661c0132f60SStefan Roese * In order to parse each CPs SATA node, fdt_node_offset_by_compatible 662c0132f60SStefan Roese * must be called again (according to the CP id) 663c0132f60SStefan Roese */ 664528213d3SIgal Liberman for (i = 0; i < (cp_index + 1); i++) 665c0132f60SStefan Roese sata_node = fdt_node_offset_by_compatible( 666c0132f60SStefan Roese gd->fdt_blob, sata_node, "marvell,armada-8k-ahci"); 667c0132f60SStefan Roese 668c0132f60SStefan Roese if (sata_node == 0) { 6699b643e31SMasahiro Yamada pr_err("SATA node not found in FDT\n"); 670c0132f60SStefan Roese return 0; 671c0132f60SStefan Roese } 672c0132f60SStefan Roese 673c0132f60SStefan Roese sata_base = (void __iomem *)fdtdec_get_addr_size_auto_noparent( 674c0132f60SStefan Roese gd->fdt_blob, sata_node, "reg", 0, NULL, true); 675c0132f60SStefan Roese if (sata_base == NULL) { 6769b643e31SMasahiro Yamada pr_err("SATA address not found in FDT\n"); 677c0132f60SStefan Roese return 0; 678c0132f60SStefan Roese } 679c0132f60SStefan Roese 680c0132f60SStefan Roese debug("SATA address found in FDT %p\n", sata_base); 681c0132f60SStefan Roese 682c0132f60SStefan Roese debug("stage: MAC configuration - power down comphy\n"); 683c0132f60SStefan Roese /* 684c0132f60SStefan Roese * MAC configuration powe down comphy use indirect address for 685c0132f60SStefan Roese * vendor spesific SATA control register 686c0132f60SStefan Roese */ 687c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_ADDRESS, 688c0132f60SStefan Roese SATA_CONTROL_REG << SATA3_VENDOR_ADDR_OFSSET, 689c0132f60SStefan Roese SATA3_VENDOR_ADDR_MASK); 690c0132f60SStefan Roese /* SATA 0 power down */ 691c0132f60SStefan Roese mask = SATA3_CTRL_SATA0_PD_MASK; 692c0132f60SStefan Roese data = 0x1 << SATA3_CTRL_SATA0_PD_OFFSET; 693c0132f60SStefan Roese /* SATA 1 power down */ 694c0132f60SStefan Roese mask |= SATA3_CTRL_SATA1_PD_MASK; 695c0132f60SStefan Roese data |= 0x1 << SATA3_CTRL_SATA1_PD_OFFSET; 696c0132f60SStefan Roese /* SATA SSU disable */ 697c0132f60SStefan Roese mask |= SATA3_CTRL_SATA1_ENABLE_MASK; 698c0132f60SStefan Roese data |= 0x0 << SATA3_CTRL_SATA1_ENABLE_OFFSET; 699c0132f60SStefan Roese /* SATA port 1 disable */ 700c0132f60SStefan Roese mask |= SATA3_CTRL_SATA_SSU_MASK; 701c0132f60SStefan Roese data |= 0x0 << SATA3_CTRL_SATA_SSU_OFFSET; 702c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_DATA, data, mask); 703c0132f60SStefan Roese 704c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 705c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 706c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 707c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 708c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 709c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 710c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK; 711c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; 712c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; 713c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; 714c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 715c0132f60SStefan Roese 716c0132f60SStefan Roese /* Set select data width 40Bit - SATA mode only */ 717c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG6_REG, 718c0132f60SStefan Roese 0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET, 719c0132f60SStefan Roese COMMON_PHY_CFG6_IF_40_SEL_MASK); 720c0132f60SStefan Roese 721c0132f60SStefan Roese /* release from hard reset in SD external */ 722c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 723c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 724c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 725c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 726c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 727c0132f60SStefan Roese 728c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 729c0132f60SStefan Roese mdelay(1); 730c0132f60SStefan Roese 731c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 732c0132f60SStefan Roese /* Start comphy Configuration */ 733c0132f60SStefan Roese /* Set reference clock to comes from group 1 - choose 25Mhz */ 734c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, 735c0132f60SStefan Roese 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET, 736c0132f60SStefan Roese HPIPE_MISC_REFCLK_SEL_MASK); 737c0132f60SStefan Roese /* Reference frequency select set 1 (for SATA = 25Mhz) */ 738c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 739c0132f60SStefan Roese data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 740c0132f60SStefan Roese /* PHY mode select (set SATA = 0x0 */ 741c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 742c0132f60SStefan Roese data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 743c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 744c0132f60SStefan Roese /* Set max PHY generation setting - 6Gbps */ 745c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_INTERFACE_REG, 746c0132f60SStefan Roese 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET, 747c0132f60SStefan Roese HPIPE_INTERFACE_GEN_MAX_MASK); 748c0132f60SStefan Roese /* Set select data width 40Bit (SEL_BITS[2:0]) */ 749c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, 750c0132f60SStefan Roese 0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK); 751c0132f60SStefan Roese 752c0132f60SStefan Roese debug("stage: Analog paramters from ETP(HW)\n"); 753c01f9fe8SIgal Liberman /* Set analog parameters from ETP(HW) */ 754c01f9fe8SIgal Liberman /* G1 settings */ 755c01f9fe8SIgal Liberman mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK; 756c01f9fe8SIgal Liberman data = 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET; 757c01f9fe8SIgal Liberman mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK; 758c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET; 759c01f9fe8SIgal Liberman mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK; 760c01f9fe8SIgal Liberman data |= 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET; 761c01f9fe8SIgal Liberman mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK; 762c01f9fe8SIgal Liberman data |= 0x3 << HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET; 763c01f9fe8SIgal Liberman mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK; 764c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET; 765c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask); 766c01f9fe8SIgal Liberman 767c01f9fe8SIgal Liberman mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK; 768c01f9fe8SIgal Liberman data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET; 769c01f9fe8SIgal Liberman mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK; 770c01f9fe8SIgal Liberman data |= 0x2 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET; 771c01f9fe8SIgal Liberman mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK; 772c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET; 773c01f9fe8SIgal Liberman mask |= HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_MASK; 774c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET; 775c01f9fe8SIgal Liberman mask |= HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_MASK; 776c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET; 777c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask); 778c01f9fe8SIgal Liberman 779c01f9fe8SIgal Liberman /* G2 settings */ 780c01f9fe8SIgal Liberman mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK; 781c01f9fe8SIgal Liberman data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET; 782c01f9fe8SIgal Liberman mask |= HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK; 783c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET; 784c01f9fe8SIgal Liberman mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK; 785c01f9fe8SIgal Liberman data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET; 786c01f9fe8SIgal Liberman mask |= HPIPE_G2_SET_1_G2_RX_SELMUFF_MASK; 787c01f9fe8SIgal Liberman data |= 0x3 << HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET; 788c01f9fe8SIgal Liberman mask |= HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_MASK; 789c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET; 790c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask); 791c01f9fe8SIgal Liberman 792c01f9fe8SIgal Liberman /* G3 settings */ 793c01f9fe8SIgal Liberman mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK; 794c01f9fe8SIgal Liberman data = 0x2 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET; 795c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK; 796c01f9fe8SIgal Liberman data |= 0x2 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET; 797c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_1_G3_RX_SELMUFI_MASK; 798c01f9fe8SIgal Liberman data |= 0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET; 799c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_1_G3_RX_SELMUFF_MASK; 800c01f9fe8SIgal Liberman data |= 0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET; 801c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_1_G3_RX_DFE_EN_MASK; 802c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET; 803c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_MASK; 804c01f9fe8SIgal Liberman data |= 0x2 << HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET; 805c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK; 806c01f9fe8SIgal Liberman data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET; 807c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask); 808c01f9fe8SIgal Liberman 809c01f9fe8SIgal Liberman /* DTL Control */ 810c01f9fe8SIgal Liberman mask = HPIPE_PWR_CTR_DTL_SQ_DET_EN_MASK; 811c01f9fe8SIgal Liberman data = 0x1 << HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET; 812c01f9fe8SIgal Liberman mask |= HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_MASK; 813c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET; 814c01f9fe8SIgal Liberman mask |= HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK; 815c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET; 816c01f9fe8SIgal Liberman mask |= HPIPE_PWR_CTR_DTL_CLAMPING_SEL_MASK; 817c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET; 818c01f9fe8SIgal Liberman mask |= HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_MASK; 819c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET; 820c01f9fe8SIgal Liberman mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_MASK; 821c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET; 822c01f9fe8SIgal Liberman mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_MASK; 823c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET; 824c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask); 825c01f9fe8SIgal Liberman 826c01f9fe8SIgal Liberman /* Trigger sampler enable pulse (by toggleing the bit) */ 827c01f9fe8SIgal Liberman mask = HPIPE_SMAPLER_MASK; 828c01f9fe8SIgal Liberman data = 0x1 << HPIPE_SMAPLER_OFFSET; 829c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask); 830c01f9fe8SIgal Liberman mask = HPIPE_SMAPLER_MASK; 831c01f9fe8SIgal Liberman data = 0x0 << HPIPE_SMAPLER_OFFSET; 832c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask); 833c01f9fe8SIgal Liberman 834c01f9fe8SIgal Liberman /* VDD Calibration Control 3 */ 835c01f9fe8SIgal Liberman mask = HPIPE_EXT_SELLV_RXSAMPL_MASK; 836c01f9fe8SIgal Liberman data = 0x10 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET; 837c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask); 838c01f9fe8SIgal Liberman 839c01f9fe8SIgal Liberman /* DFE Resolution Control */ 840c01f9fe8SIgal Liberman mask = HPIPE_DFE_RES_FORCE_MASK; 841c01f9fe8SIgal Liberman data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET; 842c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); 843c01f9fe8SIgal Liberman 844c01f9fe8SIgal Liberman /* DFE F3-F5 Coefficient Control */ 845c01f9fe8SIgal Liberman mask = HPIPE_DFE_F3_F5_DFE_EN_MASK; 846c01f9fe8SIgal Liberman data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET; 847c01f9fe8SIgal Liberman mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK; 848c01f9fe8SIgal Liberman data = 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET; 849c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask); 850c01f9fe8SIgal Liberman 851c01f9fe8SIgal Liberman /* G3 Setting 3 */ 852c01f9fe8SIgal Liberman mask = HPIPE_G3_FFE_CAP_SEL_MASK; 853c01f9fe8SIgal Liberman data = 0xf << HPIPE_G3_FFE_CAP_SEL_OFFSET; 854c01f9fe8SIgal Liberman mask |= HPIPE_G3_FFE_RES_SEL_MASK; 855c01f9fe8SIgal Liberman data |= 0x4 << HPIPE_G3_FFE_RES_SEL_OFFSET; 856c01f9fe8SIgal Liberman mask |= HPIPE_G3_FFE_SETTING_FORCE_MASK; 857c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET; 858c01f9fe8SIgal Liberman mask |= HPIPE_G3_FFE_DEG_RES_LEVEL_MASK; 859c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET; 860c01f9fe8SIgal Liberman mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK; 861c01f9fe8SIgal Liberman data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET; 862c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask); 863c01f9fe8SIgal Liberman 864c01f9fe8SIgal Liberman /* G3 Setting 4 */ 865c01f9fe8SIgal Liberman mask = HPIPE_G3_DFE_RES_MASK; 866c01f9fe8SIgal Liberman data = 0x2 << HPIPE_G3_DFE_RES_OFFSET; 867c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask); 868c01f9fe8SIgal Liberman 869c01f9fe8SIgal Liberman /* Offset Phase Control */ 870c01f9fe8SIgal Liberman mask = HPIPE_OS_PH_OFFSET_MASK; 871c01f9fe8SIgal Liberman data = 0x5c << HPIPE_OS_PH_OFFSET_OFFSET; 872c01f9fe8SIgal Liberman mask |= HPIPE_OS_PH_OFFSET_FORCE_MASK; 873c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_OS_PH_OFFSET_FORCE_OFFSET; 874c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask); 875c01f9fe8SIgal Liberman mask = HPIPE_OS_PH_VALID_MASK; 876c01f9fe8SIgal Liberman data = 0x1 << HPIPE_OS_PH_VALID_OFFSET; 877c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask); 878c01f9fe8SIgal Liberman mask = HPIPE_OS_PH_VALID_MASK; 879c01f9fe8SIgal Liberman data = 0x0 << HPIPE_OS_PH_VALID_OFFSET; 880c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask); 881c01f9fe8SIgal Liberman 882c01f9fe8SIgal Liberman /* Set G1 TX amplitude and TX post emphasis value */ 883c01f9fe8SIgal Liberman mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK; 884c01f9fe8SIgal Liberman data = 0x8 << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET; 885c01f9fe8SIgal Liberman mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK; 886c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET; 887c01f9fe8SIgal Liberman mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK; 888c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET; 889c01f9fe8SIgal Liberman mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK; 890c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET; 891c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask); 892c01f9fe8SIgal Liberman 893c01f9fe8SIgal Liberman /* Set G2 TX amplitude and TX post emphasis value */ 894c01f9fe8SIgal Liberman mask = HPIPE_G2_SET_0_G2_TX_AMP_MASK; 895c01f9fe8SIgal Liberman data = 0xa << HPIPE_G2_SET_0_G2_TX_AMP_OFFSET; 896c01f9fe8SIgal Liberman mask |= HPIPE_G2_SET_0_G2_TX_AMP_ADJ_MASK; 897c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET; 898c01f9fe8SIgal Liberman mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_MASK; 899c01f9fe8SIgal Liberman data |= 0x2 << HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET; 900c01f9fe8SIgal Liberman mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_EN_MASK; 901c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET; 902c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_G2_SET_0_REG, data, mask); 903c01f9fe8SIgal Liberman 904c01f9fe8SIgal Liberman /* Set G3 TX amplitude and TX post emphasis value */ 905c01f9fe8SIgal Liberman mask = HPIPE_G3_SET_0_G3_TX_AMP_MASK; 906c01f9fe8SIgal Liberman data = 0xe << HPIPE_G3_SET_0_G3_TX_AMP_OFFSET; 907c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_0_G3_TX_AMP_ADJ_MASK; 908c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET; 909c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_MASK; 910c01f9fe8SIgal Liberman data |= 0x6 << HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET; 911c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_EN_MASK; 912c01f9fe8SIgal Liberman data |= 0x1 << HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET; 913c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_MASK; 914c01f9fe8SIgal Liberman data |= 0x4 << HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET; 915c01f9fe8SIgal Liberman mask |= HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_MASK; 916c01f9fe8SIgal Liberman data |= 0x0 << HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET; 917c01f9fe8SIgal Liberman reg_set(hpipe_addr + HPIPE_G3_SET_0_REG, data, mask); 918c01f9fe8SIgal Liberman 919c01f9fe8SIgal Liberman /* SERDES External Configuration 2 register */ 920c01f9fe8SIgal Liberman mask = SD_EXTERNAL_CONFIG2_SSC_ENABLE_MASK; 921c01f9fe8SIgal Liberman data = 0x1 << SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET; 922c01f9fe8SIgal Liberman reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask); 923c0132f60SStefan Roese 924c0132f60SStefan Roese /* DFE reset sequence */ 925c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 926c0132f60SStefan Roese 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET, 927c0132f60SStefan Roese HPIPE_PWR_CTR_RST_DFE_MASK); 928c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 929c0132f60SStefan Roese 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET, 930c0132f60SStefan Roese HPIPE_PWR_CTR_RST_DFE_MASK); 931*d13b740cSRabeeh Khoury 932*d13b740cSRabeeh Khoury /* Set RX / TX swaps */ 933*d13b740cSRabeeh Khoury data = mask = 0; 934*d13b740cSRabeeh Khoury if (invert & PHY_POLARITY_TXD_INVERT) { 935*d13b740cSRabeeh Khoury data |= (1 << HPIPE_SYNC_PATTERN_TXD_SWAP_OFFSET); 936*d13b740cSRabeeh Khoury mask |= HPIPE_SYNC_PATTERN_TXD_SWAP_MASK; 937*d13b740cSRabeeh Khoury } 938*d13b740cSRabeeh Khoury if (invert & PHY_POLARITY_RXD_INVERT) { 939*d13b740cSRabeeh Khoury data |= (1 << HPIPE_SYNC_PATTERN_RXD_SWAP_OFFSET); 940*d13b740cSRabeeh Khoury mask |= HPIPE_SYNC_PATTERN_RXD_SWAP_MASK; 941*d13b740cSRabeeh Khoury } 942*d13b740cSRabeeh Khoury reg_set(hpipe_addr + HPIPE_SYNC_PATTERN_REG, data, mask); 943*d13b740cSRabeeh Khoury 944c0132f60SStefan Roese /* SW reset for interupt logic */ 945c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 946c0132f60SStefan Roese 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET, 947c0132f60SStefan Roese HPIPE_PWR_CTR_SFT_RST_MASK); 948c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 949c0132f60SStefan Roese 0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET, 950c0132f60SStefan Roese HPIPE_PWR_CTR_SFT_RST_MASK); 951c0132f60SStefan Roese 952c0132f60SStefan Roese debug("stage: Comphy power up\n"); 953c0132f60SStefan Roese /* 954c0132f60SStefan Roese * MAC configuration power up comphy - power up PLL/TX/RX 955c0132f60SStefan Roese * use indirect address for vendor spesific SATA control register 956c0132f60SStefan Roese */ 957c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_ADDRESS, 958c0132f60SStefan Roese SATA_CONTROL_REG << SATA3_VENDOR_ADDR_OFSSET, 959c0132f60SStefan Roese SATA3_VENDOR_ADDR_MASK); 960c0132f60SStefan Roese /* SATA 0 power up */ 961c0132f60SStefan Roese mask = SATA3_CTRL_SATA0_PD_MASK; 962c0132f60SStefan Roese data = 0x0 << SATA3_CTRL_SATA0_PD_OFFSET; 963c0132f60SStefan Roese /* SATA 1 power up */ 964c0132f60SStefan Roese mask |= SATA3_CTRL_SATA1_PD_MASK; 965c0132f60SStefan Roese data |= 0x0 << SATA3_CTRL_SATA1_PD_OFFSET; 966c0132f60SStefan Roese /* SATA SSU enable */ 967c0132f60SStefan Roese mask |= SATA3_CTRL_SATA1_ENABLE_MASK; 968c0132f60SStefan Roese data |= 0x1 << SATA3_CTRL_SATA1_ENABLE_OFFSET; 969c0132f60SStefan Roese /* SATA port 1 enable */ 970c0132f60SStefan Roese mask |= SATA3_CTRL_SATA_SSU_MASK; 971c0132f60SStefan Roese data |= 0x1 << SATA3_CTRL_SATA_SSU_OFFSET; 972c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_DATA, data, mask); 973c0132f60SStefan Roese 974c0132f60SStefan Roese /* MBUS request size and interface select register */ 975c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_ADDRESS, 976c0132f60SStefan Roese SATA_MBUS_SIZE_SELECT_REG << SATA3_VENDOR_ADDR_OFSSET, 977c0132f60SStefan Roese SATA3_VENDOR_ADDR_MASK); 978c0132f60SStefan Roese /* Mbus regret enable */ 979c0132f60SStefan Roese reg_set(sata_base + SATA3_VENDOR_DATA, 980c0132f60SStefan Roese 0x1 << SATA_MBUS_REGRET_EN_OFFSET, SATA_MBUS_REGRET_EN_MASK); 981c0132f60SStefan Roese 982c0132f60SStefan Roese debug("stage: Check PLL\n"); 983c0132f60SStefan Roese 984c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 985c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_PLL_TX_MASK & 986c0132f60SStefan Roese SD_EXTERNAL_STATUS0_PLL_RX_MASK; 987c0132f60SStefan Roese mask = data; 988c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 989c0132f60SStefan Roese if (data != 0) { 990c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 991c0132f60SStefan Roese hpipe_addr + HPIPE_LANE_STATUS1_REG, data); 9929b643e31SMasahiro Yamada pr_err("SD_EXTERNAL_STATUS0_PLL_TX is %d, SD_EXTERNAL_STATUS0_PLL_RX is %d\n", 993c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK), 994c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)); 995c0132f60SStefan Roese ret = 0; 996c0132f60SStefan Roese } 997c0132f60SStefan Roese 998c0132f60SStefan Roese debug_exit(); 999c0132f60SStefan Roese return ret; 1000c0132f60SStefan Roese } 1001c0132f60SStefan Roese 1002c0132f60SStefan Roese static int comphy_sgmii_power_up(u32 lane, u32 sgmii_speed, 1003c0132f60SStefan Roese void __iomem *hpipe_base, 1004c0132f60SStefan Roese void __iomem *comphy_base) 1005c0132f60SStefan Roese { 1006c0132f60SStefan Roese u32 mask, data, ret = 1; 1007c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 1008c0132f60SStefan Roese void __iomem *sd_ip_addr = SD_ADDR(hpipe_base, lane); 1009c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 1010c0132f60SStefan Roese void __iomem *addr; 1011c0132f60SStefan Roese 1012c0132f60SStefan Roese debug_enter(); 1013c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 1014c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 1015c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 1016c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 1017c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 1018c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 1019c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 1020c0132f60SStefan Roese 1021c0132f60SStefan Roese /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */ 1022c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 1023c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 1024c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK; 1025c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK; 1026c0132f60SStefan Roese if (sgmii_speed == PHY_SPEED_1_25G) { 1027c0132f60SStefan Roese data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; 1028c0132f60SStefan Roese data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; 1029c0132f60SStefan Roese } else { 1030c0132f60SStefan Roese /* 3.125G */ 1031c0132f60SStefan Roese data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; 1032c0132f60SStefan Roese data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; 1033c0132f60SStefan Roese } 1034c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 1035c0132f60SStefan Roese data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 1036c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 1037c0132f60SStefan Roese data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 1038c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK; 1039c0132f60SStefan Roese data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET; 1040c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 1041c0132f60SStefan Roese 1042c0132f60SStefan Roese /* release from hard reset */ 1043c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 1044c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 1045c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 1046c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 1047c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 1048c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 1049c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1050c0132f60SStefan Roese 1051c0132f60SStefan Roese /* release from hard reset */ 1052c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 1053c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 1054c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 1055c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 1056c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1057c0132f60SStefan Roese 1058c0132f60SStefan Roese 1059c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 1060c0132f60SStefan Roese mdelay(1); 1061c0132f60SStefan Roese 1062c0132f60SStefan Roese /* Start comphy Configuration */ 1063c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 1064c0132f60SStefan Roese /* set reference clock */ 1065c0132f60SStefan Roese mask = HPIPE_MISC_REFCLK_SEL_MASK; 1066c0132f60SStefan Roese data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET; 1067c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask); 1068c0132f60SStefan Roese /* Power and PLL Control */ 1069c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 1070c0132f60SStefan Roese data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 1071c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 1072c0132f60SStefan Roese data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 1073c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 1074c0132f60SStefan Roese /* Loopback register */ 1075c0132f60SStefan Roese mask = HPIPE_LOOPBACK_SEL_MASK; 1076c0132f60SStefan Roese data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET; 1077c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask); 1078c0132f60SStefan Roese /* rx control 1 */ 1079c0132f60SStefan Roese mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK; 1080c0132f60SStefan Roese data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET; 1081c0132f60SStefan Roese mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK; 1082c0132f60SStefan Roese data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET; 1083c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask); 1084c0132f60SStefan Roese /* DTL Control */ 1085c0132f60SStefan Roese mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK; 1086c0132f60SStefan Roese data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET; 1087c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask); 1088c0132f60SStefan Roese 1089c0132f60SStefan Roese /* Set analog paramters from ETP(HW) - for now use the default datas */ 1090c0132f60SStefan Roese debug("stage: Analog paramters from ETP(HW)\n"); 1091c0132f60SStefan Roese 1092c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, 1093c0132f60SStefan Roese 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET, 1094c0132f60SStefan Roese HPIPE_G1_SET_0_G1_TX_EMPH1_MASK); 1095c0132f60SStefan Roese 1096c0132f60SStefan Roese debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n"); 1097c0132f60SStefan Roese /* SERDES External Configuration */ 1098c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 1099c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 1100c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 1101c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 1102c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 1103c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 1104c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 1105c0132f60SStefan Roese 1106c0132f60SStefan Roese /* check PLL rx & tx ready */ 1107c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 1108c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_PLL_RX_MASK | 1109c0132f60SStefan Roese SD_EXTERNAL_STATUS0_PLL_TX_MASK; 1110c0132f60SStefan Roese mask = data; 1111c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 1112c0132f60SStefan Roese if (data != 0) { 1113c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 1114c0132f60SStefan Roese sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 11159b643e31SMasahiro Yamada pr_err("SD_EXTERNAL_STATUS0_PLL_RX is %d, SD_EXTERNAL_STATUS0_PLL_TX is %d\n", 1116c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK), 1117c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)); 1118c0132f60SStefan Roese ret = 0; 1119c0132f60SStefan Roese } 1120c0132f60SStefan Roese 1121c0132f60SStefan Roese /* RX init */ 1122c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; 1123c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; 1124c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1125c0132f60SStefan Roese 1126c0132f60SStefan Roese /* check that RX init done */ 1127c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 1128c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_RX_INIT_MASK; 1129c0132f60SStefan Roese mask = data; 1130c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 1131c0132f60SStefan Roese if (data != 0) { 1132c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 11339b643e31SMasahiro Yamada pr_err("SD_EXTERNAL_STATUS0_RX_INIT is 0\n"); 1134c0132f60SStefan Roese ret = 0; 1135c0132f60SStefan Roese } 1136c0132f60SStefan Roese 1137c0132f60SStefan Roese debug("stage: RF Reset\n"); 1138c0132f60SStefan Roese /* RF Reset */ 1139c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; 1140c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; 1141c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 1142c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 1143c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1144c0132f60SStefan Roese 1145c0132f60SStefan Roese debug_exit(); 1146c0132f60SStefan Roese return ret; 1147c0132f60SStefan Roese } 1148c0132f60SStefan Roese 1149cb686454SStefan Roese static int comphy_sfi_power_up(u32 lane, void __iomem *hpipe_base, 1150b617a0d7SIgal Liberman void __iomem *comphy_base, u32 speed) 1151c0132f60SStefan Roese { 1152c0132f60SStefan Roese u32 mask, data, ret = 1; 1153c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 1154c0132f60SStefan Roese void __iomem *sd_ip_addr = SD_ADDR(hpipe_base, lane); 1155c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 1156c0132f60SStefan Roese void __iomem *addr; 1157c0132f60SStefan Roese 1158c0132f60SStefan Roese debug_enter(); 1159c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 1160c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 1161c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 1162c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 1163c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 1164c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 1165c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 1166c0132f60SStefan Roese 1167c0132f60SStefan Roese /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */ 1168c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 1169c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 1170c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK; 1171c0132f60SStefan Roese data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; 1172c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK; 1173c0132f60SStefan Roese data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; 1174c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 1175c0132f60SStefan Roese data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 1176c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 1177c0132f60SStefan Roese data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 1178c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK; 1179c0132f60SStefan Roese data |= 0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET; 1180c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 1181c0132f60SStefan Roese 1182c0132f60SStefan Roese /* release from hard reset */ 1183c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 1184c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 1185c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 1186c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 1187c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 1188c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 1189c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1190c0132f60SStefan Roese 1191c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 1192c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 1193c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 1194c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 1195c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1196c0132f60SStefan Roese 1197c0132f60SStefan Roese 1198c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 1199c0132f60SStefan Roese mdelay(1); 1200c0132f60SStefan Roese 1201c0132f60SStefan Roese /* Start comphy Configuration */ 1202c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 1203c0132f60SStefan Roese /* set reference clock */ 1204c0132f60SStefan Roese mask = HPIPE_MISC_ICP_FORCE_MASK; 1205b617a0d7SIgal Liberman data = (speed == PHY_SPEED_5_15625G) ? 1206b617a0d7SIgal Liberman (0x0 << HPIPE_MISC_ICP_FORCE_OFFSET) : 1207b617a0d7SIgal Liberman (0x1 << HPIPE_MISC_ICP_FORCE_OFFSET); 1208c0132f60SStefan Roese mask |= HPIPE_MISC_REFCLK_SEL_MASK; 1209c0132f60SStefan Roese data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET; 1210c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask); 1211c0132f60SStefan Roese /* Power and PLL Control */ 1212c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 1213c0132f60SStefan Roese data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 1214c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 1215c0132f60SStefan Roese data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 1216c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 1217c0132f60SStefan Roese /* Loopback register */ 1218c0132f60SStefan Roese mask = HPIPE_LOOPBACK_SEL_MASK; 1219c0132f60SStefan Roese data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET; 1220c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask); 1221c0132f60SStefan Roese /* rx control 1 */ 1222c0132f60SStefan Roese mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK; 1223c0132f60SStefan Roese data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET; 1224c0132f60SStefan Roese mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK; 1225c0132f60SStefan Roese data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET; 1226c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask); 1227c0132f60SStefan Roese /* DTL Control */ 1228c0132f60SStefan Roese mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK; 1229c0132f60SStefan Roese data = 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET; 1230c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask); 1231c0132f60SStefan Roese 1232b617a0d7SIgal Liberman /* Transmitter/Receiver Speed Divider Force */ 1233b617a0d7SIgal Liberman if (speed == PHY_SPEED_5_15625G) { 1234b617a0d7SIgal Liberman mask = HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_MASK; 1235b617a0d7SIgal Liberman data = 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET; 1236b617a0d7SIgal Liberman mask |= HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_MASK; 1237b617a0d7SIgal Liberman data |= 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET; 1238b617a0d7SIgal Liberman mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_MASK; 1239b617a0d7SIgal Liberman data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET; 1240b617a0d7SIgal Liberman mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_MASK; 1241b617a0d7SIgal Liberman data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET; 1242781ea0abSIgal Liberman } else { 1243781ea0abSIgal Liberman mask = HPIPE_TXDIGCK_DIV_FORCE_MASK; 1244781ea0abSIgal Liberman data = 0x1 << HPIPE_TXDIGCK_DIV_FORCE_OFFSET; 1245b617a0d7SIgal Liberman } 1246781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_SPD_DIV_FORCE_REG, data, mask); 1247b617a0d7SIgal Liberman 1248c0132f60SStefan Roese /* Set analog paramters from ETP(HW) */ 1249c0132f60SStefan Roese debug("stage: Analog paramters from ETP(HW)\n"); 1250c0132f60SStefan Roese /* SERDES External Configuration 2 */ 1251c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK; 1252c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET; 1253c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask); 1254c0132f60SStefan Roese /* 0x7-DFE Resolution control */ 1255c0132f60SStefan Roese mask = HPIPE_DFE_RES_FORCE_MASK; 1256c0132f60SStefan Roese data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET; 1257c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); 1258c0132f60SStefan Roese /* 0xd-G1_Setting_0 */ 1259b617a0d7SIgal Liberman if (speed == PHY_SPEED_5_15625G) { 1260b617a0d7SIgal Liberman mask = HPIPE_G1_SET_0_G1_TX_EMPH1_MASK; 1261b617a0d7SIgal Liberman data = 0x6 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET; 1262b617a0d7SIgal Liberman } else { 1263c0132f60SStefan Roese mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK; 1264c0132f60SStefan Roese data = 0x1c << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET; 1265c0132f60SStefan Roese mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK; 1266c0132f60SStefan Roese data |= 0xe << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET; 1267b617a0d7SIgal Liberman } 1268c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask); 1269c0132f60SStefan Roese /* Genration 1 setting 2 (G1_Setting_2) */ 1270c0132f60SStefan Roese mask = HPIPE_G1_SET_2_G1_TX_EMPH0_MASK; 1271c0132f60SStefan Roese data = 0x0 << HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET; 1272c0132f60SStefan Roese mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK; 1273c0132f60SStefan Roese data |= 0x1 << HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET; 1274c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask); 1275c0132f60SStefan Roese /* Transmitter Slew Rate Control register (tx_reg1) */ 1276c0132f60SStefan Roese mask = HPIPE_TX_REG1_TX_EMPH_RES_MASK; 1277c0132f60SStefan Roese data = 0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET; 1278c0132f60SStefan Roese mask |= HPIPE_TX_REG1_SLC_EN_MASK; 1279c0132f60SStefan Roese data |= 0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET; 1280c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_TX_REG1_REG, data, mask); 1281c0132f60SStefan Roese /* Impedance Calibration Control register (cal_reg1) */ 1282c0132f60SStefan Roese mask = HPIPE_CAL_REG_1_EXT_TXIMP_MASK; 1283c0132f60SStefan Roese data = 0xe << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET; 1284c0132f60SStefan Roese mask |= HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK; 1285c0132f60SStefan Roese data |= 0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET; 1286c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_CAL_REG1_REG, data, mask); 1287c0132f60SStefan Roese /* Generation 1 Setting 5 (g1_setting_5) */ 1288c0132f60SStefan Roese mask = HPIPE_G1_SETTING_5_G1_ICP_MASK; 1289c0132f60SStefan Roese data = 0 << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET; 1290c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SETTING_5_REG, data, mask); 1291c0132f60SStefan Roese /* 0xE-G1_Setting_1 */ 1292781ea0abSIgal Liberman mask = HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK; 1293781ea0abSIgal Liberman data = 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET; 1294781ea0abSIgal Liberman if (speed == PHY_SPEED_5_15625G) { 1295781ea0abSIgal Liberman mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK; 1296781ea0abSIgal Liberman data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET; 1297c0132f60SStefan Roese mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK; 1298c0132f60SStefan Roese data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET; 1299781ea0abSIgal Liberman } else { 1300781ea0abSIgal Liberman mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK; 1301781ea0abSIgal Liberman data |= 0x2 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET; 1302781ea0abSIgal Liberman mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK; 1303781ea0abSIgal Liberman data |= 0x2 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET; 1304781ea0abSIgal Liberman mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK; 1305781ea0abSIgal Liberman data |= 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET; 1306781ea0abSIgal Liberman mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK; 1307781ea0abSIgal Liberman data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET; 1308781ea0abSIgal Liberman mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK; 1309781ea0abSIgal Liberman data |= 0x3 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET; 1310781ea0abSIgal Liberman } 1311c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask); 1312781ea0abSIgal Liberman 1313c0132f60SStefan Roese /* 0xA-DFE_Reg3 */ 1314c0132f60SStefan Roese mask = HPIPE_DFE_F3_F5_DFE_EN_MASK; 1315c0132f60SStefan Roese data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET; 1316c0132f60SStefan Roese mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK; 1317c0132f60SStefan Roese data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET; 1318c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask); 1319c0132f60SStefan Roese 1320c0132f60SStefan Roese /* 0x111-G1_Setting_4 */ 1321c0132f60SStefan Roese mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK; 1322c0132f60SStefan Roese data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET; 1323c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask); 1324c0132f60SStefan Roese /* Genration 1 setting 3 (G1_Setting_3) */ 1325c0132f60SStefan Roese mask = HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK; 1326c0132f60SStefan Roese data = 0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET; 1327b617a0d7SIgal Liberman if (speed == PHY_SPEED_5_15625G) { 1328b617a0d7SIgal Liberman /* Force FFE (Feed Forward Equalization) to 5G */ 1329b617a0d7SIgal Liberman mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK; 1330b617a0d7SIgal Liberman data |= 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET; 1331b617a0d7SIgal Liberman mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK; 1332b617a0d7SIgal Liberman data |= 0x4 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET; 1333b617a0d7SIgal Liberman mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK; 1334b617a0d7SIgal Liberman data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET; 1335b617a0d7SIgal Liberman } 1336c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask); 1337c0132f60SStefan Roese 1338781ea0abSIgal Liberman /* Connfigure RX training timer */ 1339781ea0abSIgal Liberman mask = HPIPE_RX_TRAIN_TIMER_MASK; 1340781ea0abSIgal Liberman data = 0x13 << HPIPE_RX_TRAIN_TIMER_OFFSET; 1341781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask); 1342781ea0abSIgal Liberman 1343781ea0abSIgal Liberman /* Enable TX train peak to peak hold */ 1344781ea0abSIgal Liberman mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK; 1345781ea0abSIgal Liberman data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET; 1346781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask); 1347781ea0abSIgal Liberman 1348781ea0abSIgal Liberman /* Configure TX preset index */ 1349781ea0abSIgal Liberman mask = HPIPE_TX_PRESET_INDEX_MASK; 1350781ea0abSIgal Liberman data = 0x2 << HPIPE_TX_PRESET_INDEX_OFFSET; 1351781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_TX_PRESET_INDEX_REG, data, mask); 1352781ea0abSIgal Liberman 1353781ea0abSIgal Liberman /* Disable pattern lock lost timeout */ 1354781ea0abSIgal Liberman mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK; 1355781ea0abSIgal Liberman data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET; 1356781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask); 1357781ea0abSIgal Liberman 1358781ea0abSIgal Liberman /* Configure TX training pattern and TX training 16bit auto */ 1359781ea0abSIgal Liberman mask = HPIPE_TX_TRAIN_16BIT_AUTO_EN_MASK; 1360781ea0abSIgal Liberman data = 0x1 << HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET; 1361781ea0abSIgal Liberman mask |= HPIPE_TX_TRAIN_PAT_SEL_MASK; 1362781ea0abSIgal Liberman data |= 0x1 << HPIPE_TX_TRAIN_PAT_SEL_OFFSET; 1363781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask); 1364781ea0abSIgal Liberman 1365781ea0abSIgal Liberman /* Configure Training patten number */ 1366781ea0abSIgal Liberman mask = HPIPE_TRAIN_PAT_NUM_MASK; 1367781ea0abSIgal Liberman data = 0x88 << HPIPE_TRAIN_PAT_NUM_OFFSET; 1368781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_0_REG, data, mask); 1369781ea0abSIgal Liberman 1370781ea0abSIgal Liberman /* Configure differencial manchester encoter to ethernet mode */ 1371781ea0abSIgal Liberman mask = HPIPE_DME_ETHERNET_MODE_MASK; 1372781ea0abSIgal Liberman data = 0x1 << HPIPE_DME_ETHERNET_MODE_OFFSET; 1373781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_DME_REG, data, mask); 1374781ea0abSIgal Liberman 1375781ea0abSIgal Liberman /* Configure VDD Continuous Calibration */ 1376781ea0abSIgal Liberman mask = HPIPE_CAL_VDD_CONT_MODE_MASK; 1377781ea0abSIgal Liberman data = 0x1 << HPIPE_CAL_VDD_CONT_MODE_OFFSET; 1378781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_VDD_CAL_0_REG, data, mask); 1379781ea0abSIgal Liberman 1380781ea0abSIgal Liberman /* Trigger sampler enable pulse (by toggleing the bit) */ 1381781ea0abSIgal Liberman mask = HPIPE_RX_SAMPLER_OS_GAIN_MASK; 1382781ea0abSIgal Liberman data = 0x3 << HPIPE_RX_SAMPLER_OS_GAIN_OFFSET; 1383781ea0abSIgal Liberman mask |= HPIPE_SMAPLER_MASK; 1384781ea0abSIgal Liberman data |= 0x1 << HPIPE_SMAPLER_OFFSET; 1385781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask); 1386781ea0abSIgal Liberman mask = HPIPE_SMAPLER_MASK; 1387781ea0abSIgal Liberman data = 0x0 << HPIPE_SMAPLER_OFFSET; 1388781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask); 1389781ea0abSIgal Liberman 1390781ea0abSIgal Liberman /* Set External RX Regulator Control */ 1391781ea0abSIgal Liberman mask = HPIPE_EXT_SELLV_RXSAMPL_MASK; 1392781ea0abSIgal Liberman data = 0x1A << HPIPE_EXT_SELLV_RXSAMPL_OFFSET; 1393781ea0abSIgal Liberman reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask); 1394781ea0abSIgal Liberman 1395c0132f60SStefan Roese debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n"); 1396c0132f60SStefan Roese /* SERDES External Configuration */ 1397c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 1398c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 1399c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 1400c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 1401c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 1402c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 1403c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 1404c0132f60SStefan Roese 1405c0132f60SStefan Roese 1406c0132f60SStefan Roese /* check PLL rx & tx ready */ 1407c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 1408c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_PLL_RX_MASK | 1409c0132f60SStefan Roese SD_EXTERNAL_STATUS0_PLL_TX_MASK; 1410c0132f60SStefan Roese mask = data; 1411c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 1412c0132f60SStefan Roese if (data != 0) { 1413c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 14149b643e31SMasahiro Yamada pr_err("SD_EXTERNAL_STATUS0_PLL_RX is %d, SD_EXTERNAL_STATUS0_PLL_TX is %d\n", 1415c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK), 1416c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)); 1417c0132f60SStefan Roese ret = 0; 1418c0132f60SStefan Roese } 1419c0132f60SStefan Roese 1420c0132f60SStefan Roese /* RX init */ 1421c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; 1422c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; 1423c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1424c0132f60SStefan Roese 1425c0132f60SStefan Roese 1426c0132f60SStefan Roese /* check that RX init done */ 1427c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 1428c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_RX_INIT_MASK; 1429c0132f60SStefan Roese mask = data; 1430c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 1431c0132f60SStefan Roese if (data != 0) { 1432c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 1433c0132f60SStefan Roese sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 14349b643e31SMasahiro Yamada pr_err("SD_EXTERNAL_STATUS0_RX_INIT is 0\n"); 1435c0132f60SStefan Roese ret = 0; 1436c0132f60SStefan Roese } 1437c0132f60SStefan Roese 1438c0132f60SStefan Roese debug("stage: RF Reset\n"); 1439c0132f60SStefan Roese /* RF Reset */ 1440c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; 1441c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; 1442c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 1443c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 1444c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1445c0132f60SStefan Roese 1446c0132f60SStefan Roese debug_exit(); 1447c0132f60SStefan Roese return ret; 1448c0132f60SStefan Roese } 1449c0132f60SStefan Roese 1450c0132f60SStefan Roese static int comphy_rxauii_power_up(u32 lane, void __iomem *hpipe_base, 1451c0132f60SStefan Roese void __iomem *comphy_base) 1452c0132f60SStefan Roese { 1453c0132f60SStefan Roese u32 mask, data, ret = 1; 1454c0132f60SStefan Roese void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base, lane); 1455c0132f60SStefan Roese void __iomem *sd_ip_addr = SD_ADDR(hpipe_base, lane); 1456c0132f60SStefan Roese void __iomem *comphy_addr = COMPHY_ADDR(comphy_base, lane); 1457c0132f60SStefan Roese void __iomem *addr; 1458c0132f60SStefan Roese 1459c0132f60SStefan Roese debug_enter(); 1460c0132f60SStefan Roese debug("stage: RFU configurations - hard reset comphy\n"); 1461c0132f60SStefan Roese /* RFU configurations - hard reset comphy */ 1462c0132f60SStefan Roese mask = COMMON_PHY_CFG1_PWR_UP_MASK; 1463c0132f60SStefan Roese data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; 1464c0132f60SStefan Roese mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; 1465c0132f60SStefan Roese data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; 1466c0132f60SStefan Roese reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); 1467c0132f60SStefan Roese 1468c0132f60SStefan Roese if (lane == 2) { 1469c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 1470c0132f60SStefan Roese 0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET, 1471c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_RXAUI0_MASK); 1472c0132f60SStefan Roese } 1473c0132f60SStefan Roese if (lane == 4) { 1474c0132f60SStefan Roese reg_set(comphy_base + COMMON_PHY_SD_CTRL1, 1475c0132f60SStefan Roese 0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET, 1476c0132f60SStefan Roese COMMON_PHY_SD_CTRL1_RXAUI1_MASK); 1477c0132f60SStefan Roese } 1478c0132f60SStefan Roese 1479c0132f60SStefan Roese /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */ 1480c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 1481c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 1482c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK; 1483c0132f60SStefan Roese data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; 1484c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK; 1485c0132f60SStefan Roese data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; 1486c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 1487c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 1488c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 1489c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 1490c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK; 1491c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET; 1492c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK; 1493c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET; 1494c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 1495c0132f60SStefan Roese 1496c0132f60SStefan Roese /* release from hard reset */ 1497c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 1498c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 1499c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 1500c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 1501c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 1502c0132f60SStefan Roese data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 1503c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1504c0132f60SStefan Roese 1505c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; 1506c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; 1507c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; 1508c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; 1509c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1510c0132f60SStefan Roese 1511c0132f60SStefan Roese /* Wait 1ms - until band gap and ref clock ready */ 1512c0132f60SStefan Roese mdelay(1); 1513c0132f60SStefan Roese 1514c0132f60SStefan Roese /* Start comphy Configuration */ 1515c0132f60SStefan Roese debug("stage: Comphy configuration\n"); 1516c0132f60SStefan Roese /* set reference clock */ 1517c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_MISC_REG, 1518c0132f60SStefan Roese 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET, 1519c0132f60SStefan Roese HPIPE_MISC_REFCLK_SEL_MASK); 1520c0132f60SStefan Roese /* Power and PLL Control */ 1521c0132f60SStefan Roese mask = HPIPE_PWR_PLL_REF_FREQ_MASK; 1522c0132f60SStefan Roese data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; 1523c0132f60SStefan Roese mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; 1524c0132f60SStefan Roese data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; 1525c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask); 1526c0132f60SStefan Roese /* Loopback register */ 1527c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, 1528c0132f60SStefan Roese 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK); 1529c0132f60SStefan Roese /* rx control 1 */ 1530c0132f60SStefan Roese mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK; 1531c0132f60SStefan Roese data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET; 1532c0132f60SStefan Roese mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK; 1533c0132f60SStefan Roese data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET; 1534c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask); 1535c0132f60SStefan Roese /* DTL Control */ 1536c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, 1537c0132f60SStefan Roese 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET, 1538c0132f60SStefan Roese HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK); 1539c0132f60SStefan Roese 1540c0132f60SStefan Roese /* Set analog paramters from ETP(HW) */ 1541c0132f60SStefan Roese debug("stage: Analog paramters from ETP(HW)\n"); 1542c0132f60SStefan Roese /* SERDES External Configuration 2 */ 1543c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, 1544c0132f60SStefan Roese 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET, 1545c0132f60SStefan Roese SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK); 1546c0132f60SStefan Roese /* 0x7-DFE Resolution control */ 1547c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_REG0, 0x1 << HPIPE_DFE_RES_FORCE_OFFSET, 1548c0132f60SStefan Roese HPIPE_DFE_RES_FORCE_MASK); 1549c0132f60SStefan Roese /* 0xd-G1_Setting_0 */ 1550c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, 1551c0132f60SStefan Roese 0xd << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET, 1552c0132f60SStefan Roese HPIPE_G1_SET_0_G1_TX_EMPH1_MASK); 1553c0132f60SStefan Roese /* 0xE-G1_Setting_1 */ 1554c0132f60SStefan Roese mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK; 1555c0132f60SStefan Roese data = 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET; 1556c0132f60SStefan Roese mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK; 1557c0132f60SStefan Roese data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET; 1558c0132f60SStefan Roese mask |= HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK; 1559c0132f60SStefan Roese data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET; 1560c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask); 1561c0132f60SStefan Roese /* 0xA-DFE_Reg3 */ 1562c0132f60SStefan Roese mask = HPIPE_DFE_F3_F5_DFE_EN_MASK; 1563c0132f60SStefan Roese data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET; 1564c0132f60SStefan Roese mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK; 1565c0132f60SStefan Roese data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET; 1566c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask); 1567c0132f60SStefan Roese 1568c0132f60SStefan Roese /* 0x111-G1_Setting_4 */ 1569c0132f60SStefan Roese mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK; 1570c0132f60SStefan Roese data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET; 1571c0132f60SStefan Roese reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask); 1572c0132f60SStefan Roese 1573c0132f60SStefan Roese debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n"); 1574c0132f60SStefan Roese /* SERDES External Configuration */ 1575c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; 1576c0132f60SStefan Roese data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; 1577c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; 1578c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; 1579c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; 1580c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; 1581c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask); 1582c0132f60SStefan Roese 1583c0132f60SStefan Roese 1584c0132f60SStefan Roese /* check PLL rx & tx ready */ 1585c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 1586c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_PLL_RX_MASK | 1587c0132f60SStefan Roese SD_EXTERNAL_STATUS0_PLL_TX_MASK; 1588c0132f60SStefan Roese mask = data; 1589c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 15000); 1590c0132f60SStefan Roese if (data != 0) { 1591c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 1592c0132f60SStefan Roese sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 15939b643e31SMasahiro Yamada pr_err("SD_EXTERNAL_STATUS0_PLL_RX is %d, SD_EXTERNAL_STATUS0_PLL_TX is %d\n", 1594c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK), 1595c0132f60SStefan Roese (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)); 1596c0132f60SStefan Roese ret = 0; 1597c0132f60SStefan Roese } 1598c0132f60SStefan Roese 1599c0132f60SStefan Roese /* RX init */ 1600c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, 1601c0132f60SStefan Roese 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET, 1602c0132f60SStefan Roese SD_EXTERNAL_CONFIG1_RX_INIT_MASK); 1603c0132f60SStefan Roese 1604c0132f60SStefan Roese /* check that RX init done */ 1605c0132f60SStefan Roese addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG; 1606c0132f60SStefan Roese data = SD_EXTERNAL_STATUS0_RX_INIT_MASK; 1607c0132f60SStefan Roese mask = data; 1608c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 1609c0132f60SStefan Roese if (data != 0) { 1610c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", 1611c0132f60SStefan Roese sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data); 16129b643e31SMasahiro Yamada pr_err("SD_EXTERNAL_STATUS0_RX_INIT is 0\n"); 1613c0132f60SStefan Roese ret = 0; 1614c0132f60SStefan Roese } 1615c0132f60SStefan Roese 1616c0132f60SStefan Roese debug("stage: RF Reset\n"); 1617c0132f60SStefan Roese /* RF Reset */ 1618c0132f60SStefan Roese mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; 1619c0132f60SStefan Roese data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; 1620c0132f60SStefan Roese mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; 1621c0132f60SStefan Roese data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; 1622c0132f60SStefan Roese reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); 1623c0132f60SStefan Roese 1624c0132f60SStefan Roese debug_exit(); 1625c0132f60SStefan Roese return ret; 1626c0132f60SStefan Roese } 1627c0132f60SStefan Roese 1628c0132f60SStefan Roese static void comphy_utmi_power_down(u32 utmi_index, void __iomem *utmi_base_addr, 1629c0132f60SStefan Roese void __iomem *usb_cfg_addr, 1630c0132f60SStefan Roese void __iomem *utmi_cfg_addr, 1631c0132f60SStefan Roese u32 utmi_phy_port) 1632c0132f60SStefan Roese { 1633c0132f60SStefan Roese u32 mask, data; 1634c0132f60SStefan Roese 1635c0132f60SStefan Roese debug_enter(); 1636c0132f60SStefan Roese debug("stage: UTMI %d - Power down transceiver (power down Phy), Power down PLL, and SuspendDM\n", 1637c0132f60SStefan Roese utmi_index); 1638c0132f60SStefan Roese /* Power down UTMI PHY */ 1639c0132f60SStefan Roese reg_set(utmi_cfg_addr, 0x0 << UTMI_PHY_CFG_PU_OFFSET, 1640c0132f60SStefan Roese UTMI_PHY_CFG_PU_MASK); 1641c0132f60SStefan Roese 1642c0132f60SStefan Roese /* 1643c0132f60SStefan Roese * If UTMI connected to USB Device, configure mux prior to PHY init 1644c0132f60SStefan Roese * (Device can be connected to UTMI0 or to UTMI1) 1645c0132f60SStefan Roese */ 1646e89acc4bSStefan Roese if (utmi_phy_port == UTMI_PHY_TO_USB3_DEVICE0) { 1647c0132f60SStefan Roese debug("stage: UTMI %d - Enable Device mode and configure UTMI mux\n", 1648c0132f60SStefan Roese utmi_index); 1649c0132f60SStefan Roese /* USB3 Device UTMI enable */ 1650c0132f60SStefan Roese mask = UTMI_USB_CFG_DEVICE_EN_MASK; 1651c0132f60SStefan Roese data = 0x1 << UTMI_USB_CFG_DEVICE_EN_OFFSET; 1652c0132f60SStefan Roese /* USB3 Device UTMI MUX */ 1653c0132f60SStefan Roese mask |= UTMI_USB_CFG_DEVICE_MUX_MASK; 1654c0132f60SStefan Roese data |= utmi_index << UTMI_USB_CFG_DEVICE_MUX_OFFSET; 1655c0132f60SStefan Roese reg_set(usb_cfg_addr, data, mask); 1656c0132f60SStefan Roese } 1657c0132f60SStefan Roese 1658c0132f60SStefan Roese /* Set Test suspendm mode */ 1659c0132f60SStefan Roese mask = UTMI_CTRL_STATUS0_SUSPENDM_MASK; 1660c0132f60SStefan Roese data = 0x1 << UTMI_CTRL_STATUS0_SUSPENDM_OFFSET; 1661c0132f60SStefan Roese /* Enable Test UTMI select */ 1662c0132f60SStefan Roese mask |= UTMI_CTRL_STATUS0_TEST_SEL_MASK; 1663c0132f60SStefan Roese data |= 0x1 << UTMI_CTRL_STATUS0_TEST_SEL_OFFSET; 1664c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_CTRL_STATUS0_REG, data, mask); 1665c0132f60SStefan Roese 1666c0132f60SStefan Roese /* Wait for UTMI power down */ 1667c0132f60SStefan Roese mdelay(1); 1668c0132f60SStefan Roese 1669c0132f60SStefan Roese debug_exit(); 1670c0132f60SStefan Roese return; 1671c0132f60SStefan Roese } 1672c0132f60SStefan Roese 1673c0132f60SStefan Roese static void comphy_utmi_phy_config(u32 utmi_index, void __iomem *utmi_base_addr, 1674c0132f60SStefan Roese void __iomem *usb_cfg_addr, 1675c0132f60SStefan Roese void __iomem *utmi_cfg_addr, 1676c0132f60SStefan Roese u32 utmi_phy_port) 1677c0132f60SStefan Roese { 1678c0132f60SStefan Roese u32 mask, data; 1679c0132f60SStefan Roese 1680c0132f60SStefan Roese debug_exit(); 1681c0132f60SStefan Roese debug("stage: Configure UTMI PHY %d registers\n", utmi_index); 1682c0132f60SStefan Roese /* Reference Clock Divider Select */ 1683c0132f60SStefan Roese mask = UTMI_PLL_CTRL_REFDIV_MASK; 1684c0132f60SStefan Roese data = 0x5 << UTMI_PLL_CTRL_REFDIV_OFFSET; 1685c0132f60SStefan Roese /* Feedback Clock Divider Select - 90 for 25Mhz*/ 1686c0132f60SStefan Roese mask |= UTMI_PLL_CTRL_FBDIV_MASK; 1687c0132f60SStefan Roese data |= 0x60 << UTMI_PLL_CTRL_FBDIV_OFFSET; 1688c0132f60SStefan Roese /* Select LPFR - 0x0 for 25Mhz/5=5Mhz*/ 1689c0132f60SStefan Roese mask |= UTMI_PLL_CTRL_SEL_LPFR_MASK; 1690c0132f60SStefan Roese data |= 0x0 << UTMI_PLL_CTRL_SEL_LPFR_OFFSET; 1691c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_PLL_CTRL_REG, data, mask); 1692c0132f60SStefan Roese 1693c0132f60SStefan Roese /* Impedance Calibration Threshold Setting */ 1694c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_CALIB_CTRL_REG, 1695c0132f60SStefan Roese 0x6 << UTMI_CALIB_CTRL_IMPCAL_VTH_OFFSET, 1696c0132f60SStefan Roese UTMI_CALIB_CTRL_IMPCAL_VTH_MASK); 1697c0132f60SStefan Roese 1698c0132f60SStefan Roese /* Set LS TX driver strength coarse control */ 1699c0132f60SStefan Roese mask = UTMI_TX_CH_CTRL_DRV_EN_LS_MASK; 1700c0132f60SStefan Roese data = 0x3 << UTMI_TX_CH_CTRL_DRV_EN_LS_OFFSET; 1701c0132f60SStefan Roese /* Set LS TX driver fine adjustment */ 1702c0132f60SStefan Roese mask |= UTMI_TX_CH_CTRL_IMP_SEL_LS_MASK; 1703c0132f60SStefan Roese data |= 0x3 << UTMI_TX_CH_CTRL_IMP_SEL_LS_OFFSET; 1704c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_TX_CH_CTRL_REG, data, mask); 1705c0132f60SStefan Roese 1706c0132f60SStefan Roese /* Enable SQ */ 1707c0132f60SStefan Roese mask = UTMI_RX_CH_CTRL0_SQ_DET_MASK; 1708c0132f60SStefan Roese data = 0x0 << UTMI_RX_CH_CTRL0_SQ_DET_OFFSET; 1709c0132f60SStefan Roese /* Enable analog squelch detect */ 1710c0132f60SStefan Roese mask |= UTMI_RX_CH_CTRL0_SQ_ANA_DTC_MASK; 1711c0132f60SStefan Roese data |= 0x1 << UTMI_RX_CH_CTRL0_SQ_ANA_DTC_OFFSET; 1712c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_RX_CH_CTRL0_REG, data, mask); 1713c0132f60SStefan Roese 1714c0132f60SStefan Roese /* Set External squelch calibration number */ 1715c0132f60SStefan Roese mask = UTMI_RX_CH_CTRL1_SQ_AMP_CAL_MASK; 1716c0132f60SStefan Roese data = 0x1 << UTMI_RX_CH_CTRL1_SQ_AMP_CAL_OFFSET; 1717c0132f60SStefan Roese /* Enable the External squelch calibration */ 1718c0132f60SStefan Roese mask |= UTMI_RX_CH_CTRL1_SQ_AMP_CAL_EN_MASK; 1719c0132f60SStefan Roese data |= 0x1 << UTMI_RX_CH_CTRL1_SQ_AMP_CAL_EN_OFFSET; 1720c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_RX_CH_CTRL1_REG, data, mask); 1721c0132f60SStefan Roese 1722c0132f60SStefan Roese /* Set Control VDAT Reference Voltage - 0.325V */ 1723c0132f60SStefan Roese mask = UTMI_CHGDTC_CTRL_VDAT_MASK; 1724c0132f60SStefan Roese data = 0x1 << UTMI_CHGDTC_CTRL_VDAT_OFFSET; 1725c0132f60SStefan Roese /* Set Control VSRC Reference Voltage - 0.6V */ 1726c0132f60SStefan Roese mask |= UTMI_CHGDTC_CTRL_VSRC_MASK; 1727c0132f60SStefan Roese data |= 0x1 << UTMI_CHGDTC_CTRL_VSRC_OFFSET; 1728c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_CHGDTC_CTRL_REG, data, mask); 1729c0132f60SStefan Roese 1730c0132f60SStefan Roese debug_exit(); 1731c0132f60SStefan Roese return; 1732c0132f60SStefan Roese } 1733c0132f60SStefan Roese 1734c0132f60SStefan Roese static int comphy_utmi_power_up(u32 utmi_index, void __iomem *utmi_base_addr, 1735c0132f60SStefan Roese void __iomem *usb_cfg_addr, 1736c0132f60SStefan Roese void __iomem *utmi_cfg_addr, u32 utmi_phy_port) 1737c0132f60SStefan Roese { 1738c0132f60SStefan Roese u32 data, mask, ret = 1; 1739c0132f60SStefan Roese void __iomem *addr; 1740c0132f60SStefan Roese 1741c0132f60SStefan Roese debug_enter(); 1742c0132f60SStefan Roese debug("stage: UTMI %d - Power up transceiver(Power up Phy), and exit SuspendDM\n", 1743c0132f60SStefan Roese utmi_index); 1744c0132f60SStefan Roese /* Power UP UTMI PHY */ 1745c0132f60SStefan Roese reg_set(utmi_cfg_addr, 0x1 << UTMI_PHY_CFG_PU_OFFSET, 1746c0132f60SStefan Roese UTMI_PHY_CFG_PU_MASK); 1747c0132f60SStefan Roese /* Disable Test UTMI select */ 1748c0132f60SStefan Roese reg_set(utmi_base_addr + UTMI_CTRL_STATUS0_REG, 1749c0132f60SStefan Roese 0x0 << UTMI_CTRL_STATUS0_TEST_SEL_OFFSET, 1750c0132f60SStefan Roese UTMI_CTRL_STATUS0_TEST_SEL_MASK); 1751c0132f60SStefan Roese 1752c0132f60SStefan Roese debug("stage: Polling for PLL and impedance calibration done, and PLL ready done\n"); 1753c0132f60SStefan Roese addr = utmi_base_addr + UTMI_CALIB_CTRL_REG; 1754c0132f60SStefan Roese data = UTMI_CALIB_CTRL_IMPCAL_DONE_MASK; 1755c0132f60SStefan Roese mask = data; 1756c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 1757c0132f60SStefan Roese if (data != 0) { 17589b643e31SMasahiro Yamada pr_err("Impedance calibration is not done\n"); 1759c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", addr, data); 1760c0132f60SStefan Roese ret = 0; 1761c0132f60SStefan Roese } 1762c0132f60SStefan Roese 1763c0132f60SStefan Roese data = UTMI_CALIB_CTRL_PLLCAL_DONE_MASK; 1764c0132f60SStefan Roese mask = data; 1765c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 1766c0132f60SStefan Roese if (data != 0) { 17679b643e31SMasahiro Yamada pr_err("PLL calibration is not done\n"); 1768c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", addr, data); 1769c0132f60SStefan Roese ret = 0; 1770c0132f60SStefan Roese } 1771c0132f60SStefan Roese 1772c0132f60SStefan Roese addr = utmi_base_addr + UTMI_PLL_CTRL_REG; 1773c0132f60SStefan Roese data = UTMI_PLL_CTRL_PLL_RDY_MASK; 1774c0132f60SStefan Roese mask = data; 1775c0132f60SStefan Roese data = polling_with_timeout(addr, data, mask, 100); 1776c0132f60SStefan Roese if (data != 0) { 17779b643e31SMasahiro Yamada pr_err("PLL is not ready\n"); 1778c0132f60SStefan Roese debug("Read from reg = %p - value = 0x%x\n", addr, data); 1779c0132f60SStefan Roese ret = 0; 1780c0132f60SStefan Roese } 1781c0132f60SStefan Roese 1782c0132f60SStefan Roese if (ret) 1783c0132f60SStefan Roese debug("Passed\n"); 1784c0132f60SStefan Roese else 1785c0132f60SStefan Roese debug("\n"); 1786c0132f60SStefan Roese 1787c0132f60SStefan Roese debug_exit(); 1788c0132f60SStefan Roese return ret; 1789c0132f60SStefan Roese } 1790c0132f60SStefan Roese 1791c0132f60SStefan Roese /* 1792c0132f60SStefan Roese * comphy_utmi_phy_init initialize the UTMI PHY 1793c0132f60SStefan Roese * the init split in 3 parts: 1794c0132f60SStefan Roese * 1. Power down transceiver and PLL 1795c0132f60SStefan Roese * 2. UTMI PHY configure 1796c0132f60SStefan Roese * 3. Powe up transceiver and PLL 1797c0132f60SStefan Roese * Note: - Power down/up should be once for both UTMI PHYs 1798c0132f60SStefan Roese * - comphy_dedicated_phys_init call this function if at least there is 1799c0132f60SStefan Roese * one UTMI PHY exists in FDT blob. access to cp110_utmi_data[0] is 1800c0132f60SStefan Roese * legal 1801c0132f60SStefan Roese */ 1802c0132f60SStefan Roese static void comphy_utmi_phy_init(u32 utmi_phy_count, 1803c0132f60SStefan Roese struct utmi_phy_data *cp110_utmi_data) 1804c0132f60SStefan Roese { 1805c0132f60SStefan Roese u32 i; 1806c0132f60SStefan Roese 1807c0132f60SStefan Roese debug_enter(); 1808c0132f60SStefan Roese /* UTMI Power down */ 1809c0132f60SStefan Roese for (i = 0; i < utmi_phy_count; i++) { 1810c0132f60SStefan Roese comphy_utmi_power_down(i, cp110_utmi_data[i].utmi_base_addr, 1811c0132f60SStefan Roese cp110_utmi_data[i].usb_cfg_addr, 1812c0132f60SStefan Roese cp110_utmi_data[i].utmi_cfg_addr, 1813c0132f60SStefan Roese cp110_utmi_data[i].utmi_phy_port); 1814c0132f60SStefan Roese } 1815c0132f60SStefan Roese /* PLL Power down */ 1816c0132f60SStefan Roese debug("stage: UTMI PHY power down PLL\n"); 1817c0132f60SStefan Roese for (i = 0; i < utmi_phy_count; i++) { 1818c0132f60SStefan Roese reg_set(cp110_utmi_data[i].usb_cfg_addr, 1819c0132f60SStefan Roese 0x0 << UTMI_USB_CFG_PLL_OFFSET, UTMI_USB_CFG_PLL_MASK); 1820c0132f60SStefan Roese } 1821c0132f60SStefan Roese /* UTMI configure */ 1822c0132f60SStefan Roese for (i = 0; i < utmi_phy_count; i++) { 1823c0132f60SStefan Roese comphy_utmi_phy_config(i, cp110_utmi_data[i].utmi_base_addr, 1824c0132f60SStefan Roese cp110_utmi_data[i].usb_cfg_addr, 1825c0132f60SStefan Roese cp110_utmi_data[i].utmi_cfg_addr, 1826c0132f60SStefan Roese cp110_utmi_data[i].utmi_phy_port); 1827c0132f60SStefan Roese } 1828c0132f60SStefan Roese /* UTMI Power up */ 1829c0132f60SStefan Roese for (i = 0; i < utmi_phy_count; i++) { 1830c0132f60SStefan Roese if (!comphy_utmi_power_up(i, cp110_utmi_data[i].utmi_base_addr, 1831c0132f60SStefan Roese cp110_utmi_data[i].usb_cfg_addr, 1832c0132f60SStefan Roese cp110_utmi_data[i].utmi_cfg_addr, 1833c0132f60SStefan Roese cp110_utmi_data[i].utmi_phy_port)) { 18349b643e31SMasahiro Yamada pr_err("Failed to initialize UTMI PHY %d\n", i); 1835c0132f60SStefan Roese continue; 1836c0132f60SStefan Roese } 1837c0132f60SStefan Roese printf("UTMI PHY %d initialized to ", i); 1838e89acc4bSStefan Roese if (cp110_utmi_data[i].utmi_phy_port == 1839e89acc4bSStefan Roese UTMI_PHY_TO_USB3_DEVICE0) 1840c0132f60SStefan Roese printf("USB Device\n"); 1841c0132f60SStefan Roese else 1842c0132f60SStefan Roese printf("USB Host%d\n", 1843c0132f60SStefan Roese cp110_utmi_data[i].utmi_phy_port); 1844c0132f60SStefan Roese } 1845c0132f60SStefan Roese /* PLL Power up */ 1846c0132f60SStefan Roese debug("stage: UTMI PHY power up PLL\n"); 1847c0132f60SStefan Roese for (i = 0; i < utmi_phy_count; i++) { 1848c0132f60SStefan Roese reg_set(cp110_utmi_data[i].usb_cfg_addr, 1849c0132f60SStefan Roese 0x1 << UTMI_USB_CFG_PLL_OFFSET, UTMI_USB_CFG_PLL_MASK); 1850c0132f60SStefan Roese } 1851c0132f60SStefan Roese 1852c0132f60SStefan Roese debug_exit(); 1853c0132f60SStefan Roese return; 1854c0132f60SStefan Roese } 1855c0132f60SStefan Roese 1856c0132f60SStefan Roese /* 1857c0132f60SStefan Roese * comphy_dedicated_phys_init initialize the dedicated PHYs 1858c0132f60SStefan Roese * - not muxed SerDes lanes e.g. UTMI PHY 1859c0132f60SStefan Roese */ 1860c0132f60SStefan Roese void comphy_dedicated_phys_init(void) 1861c0132f60SStefan Roese { 1862c0132f60SStefan Roese struct utmi_phy_data cp110_utmi_data[MAX_UTMI_PHY_COUNT]; 1863c0132f60SStefan Roese int node; 1864c0132f60SStefan Roese int i; 1865c0132f60SStefan Roese 1866c0132f60SStefan Roese debug_enter(); 1867c0132f60SStefan Roese debug("Initialize USB UTMI PHYs\n"); 1868c0132f60SStefan Roese 1869c0132f60SStefan Roese /* Find the UTMI phy node in device tree and go over them */ 1870c0132f60SStefan Roese node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, 1871c0132f60SStefan Roese "marvell,mvebu-utmi-2.6.0"); 1872c0132f60SStefan Roese 1873c0132f60SStefan Roese i = 0; 1874c0132f60SStefan Roese while (node > 0) { 1875c0132f60SStefan Roese /* get base address of UTMI phy */ 1876c0132f60SStefan Roese cp110_utmi_data[i].utmi_base_addr = 1877c0132f60SStefan Roese (void __iomem *)fdtdec_get_addr_size_auto_noparent( 1878c0132f60SStefan Roese gd->fdt_blob, node, "reg", 0, NULL, true); 1879c0132f60SStefan Roese if (cp110_utmi_data[i].utmi_base_addr == NULL) { 18809b643e31SMasahiro Yamada pr_err("UTMI PHY base address is invalid\n"); 1881c0132f60SStefan Roese i++; 1882c0132f60SStefan Roese continue; 1883c0132f60SStefan Roese } 1884c0132f60SStefan Roese 1885c0132f60SStefan Roese /* get usb config address */ 1886c0132f60SStefan Roese cp110_utmi_data[i].usb_cfg_addr = 1887c0132f60SStefan Roese (void __iomem *)fdtdec_get_addr_size_auto_noparent( 1888c0132f60SStefan Roese gd->fdt_blob, node, "reg", 1, NULL, true); 1889c0132f60SStefan Roese if (cp110_utmi_data[i].usb_cfg_addr == NULL) { 18909b643e31SMasahiro Yamada pr_err("UTMI PHY base address is invalid\n"); 1891c0132f60SStefan Roese i++; 1892c0132f60SStefan Roese continue; 1893c0132f60SStefan Roese } 1894c0132f60SStefan Roese 1895c0132f60SStefan Roese /* get UTMI config address */ 1896c0132f60SStefan Roese cp110_utmi_data[i].utmi_cfg_addr = 1897c0132f60SStefan Roese (void __iomem *)fdtdec_get_addr_size_auto_noparent( 1898c0132f60SStefan Roese gd->fdt_blob, node, "reg", 2, NULL, true); 1899c0132f60SStefan Roese if (cp110_utmi_data[i].utmi_cfg_addr == NULL) { 19009b643e31SMasahiro Yamada pr_err("UTMI PHY base address is invalid\n"); 1901c0132f60SStefan Roese i++; 1902c0132f60SStefan Roese continue; 1903c0132f60SStefan Roese } 1904c0132f60SStefan Roese 1905c0132f60SStefan Roese /* 1906c0132f60SStefan Roese * get the port number (to check if the utmi connected to 1907c0132f60SStefan Roese * host/device) 1908c0132f60SStefan Roese */ 1909c0132f60SStefan Roese cp110_utmi_data[i].utmi_phy_port = fdtdec_get_int( 1910c0132f60SStefan Roese gd->fdt_blob, node, "utmi-port", UTMI_PHY_INVALID); 1911c0132f60SStefan Roese if (cp110_utmi_data[i].utmi_phy_port == UTMI_PHY_INVALID) { 19129b643e31SMasahiro Yamada pr_err("UTMI PHY port type is invalid\n"); 1913c0132f60SStefan Roese i++; 1914c0132f60SStefan Roese continue; 1915c0132f60SStefan Roese } 1916c0132f60SStefan Roese 1917c0132f60SStefan Roese node = fdt_node_offset_by_compatible( 1918c0132f60SStefan Roese gd->fdt_blob, node, "marvell,mvebu-utmi-2.6.0"); 1919c0132f60SStefan Roese i++; 1920c0132f60SStefan Roese } 1921c0132f60SStefan Roese 1922c0132f60SStefan Roese if (i > 0) 1923c0132f60SStefan Roese comphy_utmi_phy_init(i, cp110_utmi_data); 1924c0132f60SStefan Roese 1925c0132f60SStefan Roese debug_exit(); 1926c0132f60SStefan Roese } 1927c0132f60SStefan Roese 1928c0132f60SStefan Roese static void comphy_mux_cp110_init(struct chip_serdes_phy_config *ptr_chip_cfg, 1929c0132f60SStefan Roese struct comphy_map *serdes_map) 1930c0132f60SStefan Roese { 1931c0132f60SStefan Roese void __iomem *comphy_base_addr; 1932c0132f60SStefan Roese struct comphy_map comphy_map_pipe_data[MAX_LANE_OPTIONS]; 1933c0132f60SStefan Roese struct comphy_map comphy_map_phy_data[MAX_LANE_OPTIONS]; 1934c0132f60SStefan Roese u32 lane, comphy_max_count; 1935c0132f60SStefan Roese 1936c0132f60SStefan Roese comphy_max_count = ptr_chip_cfg->comphy_lanes_count; 1937c0132f60SStefan Roese comphy_base_addr = ptr_chip_cfg->comphy_base_addr; 1938c0132f60SStefan Roese 1939c0132f60SStefan Roese /* 1940c0132f60SStefan Roese * Copy the SerDes map configuration for PIPE map and PHY map 1941c0132f60SStefan Roese * the comphy_mux_init modify the type of the lane if the type 1942c0132f60SStefan Roese * is not valid because we have 2 selectores run the 1943c0132f60SStefan Roese * comphy_mux_init twice and after that update the original 1944c0132f60SStefan Roese * serdes_map 1945c0132f60SStefan Roese */ 1946c0132f60SStefan Roese for (lane = 0; lane < comphy_max_count; lane++) { 1947c0132f60SStefan Roese comphy_map_pipe_data[lane].type = serdes_map[lane].type; 1948c0132f60SStefan Roese comphy_map_pipe_data[lane].speed = serdes_map[lane].speed; 1949c0132f60SStefan Roese comphy_map_phy_data[lane].type = serdes_map[lane].type; 1950c0132f60SStefan Roese comphy_map_phy_data[lane].speed = serdes_map[lane].speed; 1951c0132f60SStefan Roese } 1952c0132f60SStefan Roese ptr_chip_cfg->mux_data = cp110_comphy_phy_mux_data; 1953c0132f60SStefan Roese comphy_mux_init(ptr_chip_cfg, comphy_map_phy_data, 1954c0132f60SStefan Roese comphy_base_addr + COMMON_SELECTOR_PHY_OFFSET); 1955c0132f60SStefan Roese 1956c0132f60SStefan Roese ptr_chip_cfg->mux_data = cp110_comphy_pipe_mux_data; 1957c0132f60SStefan Roese comphy_mux_init(ptr_chip_cfg, comphy_map_pipe_data, 1958c0132f60SStefan Roese comphy_base_addr + COMMON_SELECTOR_PIPE_OFFSET); 1959c0132f60SStefan Roese /* Fix the type after check the PHY and PIPE configuration */ 1960c0132f60SStefan Roese for (lane = 0; lane < comphy_max_count; lane++) { 1961c0132f60SStefan Roese if ((comphy_map_pipe_data[lane].type == PHY_TYPE_UNCONNECTED) && 1962c0132f60SStefan Roese (comphy_map_phy_data[lane].type == PHY_TYPE_UNCONNECTED)) 1963c0132f60SStefan Roese serdes_map[lane].type = PHY_TYPE_UNCONNECTED; 1964c0132f60SStefan Roese } 1965c0132f60SStefan Roese } 1966c0132f60SStefan Roese 1967c0132f60SStefan Roese int comphy_cp110_init(struct chip_serdes_phy_config *ptr_chip_cfg, 1968c0132f60SStefan Roese struct comphy_map *serdes_map) 1969c0132f60SStefan Roese { 1970c0132f60SStefan Roese struct comphy_map *ptr_comphy_map; 1971c0132f60SStefan Roese void __iomem *comphy_base_addr, *hpipe_base_addr; 1972c0132f60SStefan Roese u32 comphy_max_count, lane, ret = 0; 1973c0132f60SStefan Roese u32 pcie_width = 0; 1974c0132f60SStefan Roese 1975c0132f60SStefan Roese debug_enter(); 1976c0132f60SStefan Roese 1977c0132f60SStefan Roese comphy_max_count = ptr_chip_cfg->comphy_lanes_count; 1978c0132f60SStefan Roese comphy_base_addr = ptr_chip_cfg->comphy_base_addr; 1979c0132f60SStefan Roese hpipe_base_addr = ptr_chip_cfg->hpipe3_base_addr; 1980c0132f60SStefan Roese 1981c0132f60SStefan Roese /* Config Comphy mux configuration */ 1982c0132f60SStefan Roese comphy_mux_cp110_init(ptr_chip_cfg, serdes_map); 1983c0132f60SStefan Roese 1984c0132f60SStefan Roese /* Check if the first 4 lanes configured as By-4 */ 1985c0132f60SStefan Roese for (lane = 0, ptr_comphy_map = serdes_map; lane < 4; 1986c0132f60SStefan Roese lane++, ptr_comphy_map++) { 1987c0132f60SStefan Roese if (ptr_comphy_map->type != PHY_TYPE_PEX0) 1988c0132f60SStefan Roese break; 1989c0132f60SStefan Roese pcie_width++; 1990c0132f60SStefan Roese } 1991c0132f60SStefan Roese 1992c0132f60SStefan Roese for (lane = 0, ptr_comphy_map = serdes_map; lane < comphy_max_count; 1993c0132f60SStefan Roese lane++, ptr_comphy_map++) { 1994c0132f60SStefan Roese debug("Initialize serdes number %d\n", lane); 1995c0132f60SStefan Roese debug("Serdes type = 0x%x\n", ptr_comphy_map->type); 1996c0132f60SStefan Roese if (lane == 4) { 1997c0132f60SStefan Roese /* 1998c0132f60SStefan Roese * PCIe lanes above the first 4 lanes, can be only 1999c0132f60SStefan Roese * by1 2000c0132f60SStefan Roese */ 2001c0132f60SStefan Roese pcie_width = 1; 2002c0132f60SStefan Roese } 2003c0132f60SStefan Roese switch (ptr_comphy_map->type) { 2004c0132f60SStefan Roese case PHY_TYPE_UNCONNECTED: 20056ecc0b1cSStefan Roese case PHY_TYPE_IGNORE: 2006c0132f60SStefan Roese continue; 2007c0132f60SStefan Roese break; 2008c0132f60SStefan Roese case PHY_TYPE_PEX0: 2009c0132f60SStefan Roese case PHY_TYPE_PEX1: 2010c0132f60SStefan Roese case PHY_TYPE_PEX2: 2011c0132f60SStefan Roese case PHY_TYPE_PEX3: 2012c0132f60SStefan Roese ret = comphy_pcie_power_up( 2013c0132f60SStefan Roese lane, pcie_width, ptr_comphy_map->clk_src, 20147dda98e0SStefan Roese serdes_map->end_point, 2015c0132f60SStefan Roese hpipe_base_addr, comphy_base_addr); 2016c0132f60SStefan Roese break; 2017c0132f60SStefan Roese case PHY_TYPE_SATA0: 2018c0132f60SStefan Roese case PHY_TYPE_SATA1: 2019c0132f60SStefan Roese case PHY_TYPE_SATA2: 2020c0132f60SStefan Roese case PHY_TYPE_SATA3: 2021c0132f60SStefan Roese ret = comphy_sata_power_up( 2022c0132f60SStefan Roese lane, hpipe_base_addr, comphy_base_addr, 2023*d13b740cSRabeeh Khoury ptr_chip_cfg->cp_index, 2024*d13b740cSRabeeh Khoury serdes_map[lane].invert); 2025c0132f60SStefan Roese break; 2026c0132f60SStefan Roese case PHY_TYPE_USB3_HOST0: 2027c0132f60SStefan Roese case PHY_TYPE_USB3_HOST1: 2028c0132f60SStefan Roese case PHY_TYPE_USB3_DEVICE: 2029c0132f60SStefan Roese ret = comphy_usb3_power_up(lane, hpipe_base_addr, 2030c0132f60SStefan Roese comphy_base_addr); 2031c0132f60SStefan Roese break; 2032c0132f60SStefan Roese case PHY_TYPE_SGMII0: 2033c0132f60SStefan Roese case PHY_TYPE_SGMII1: 2034c0132f60SStefan Roese case PHY_TYPE_SGMII2: 2035c0132f60SStefan Roese case PHY_TYPE_SGMII3: 2036c0132f60SStefan Roese if (ptr_comphy_map->speed == PHY_SPEED_INVALID) { 2037c0132f60SStefan Roese debug("Warning: SGMII PHY speed in lane %d is invalid, set PHY speed to 1.25G\n", 2038c0132f60SStefan Roese lane); 2039c0132f60SStefan Roese ptr_comphy_map->speed = PHY_SPEED_1_25G; 2040c0132f60SStefan Roese } 2041c0132f60SStefan Roese ret = comphy_sgmii_power_up( 2042c0132f60SStefan Roese lane, ptr_comphy_map->speed, hpipe_base_addr, 2043c0132f60SStefan Roese comphy_base_addr); 2044c0132f60SStefan Roese break; 2045cb686454SStefan Roese case PHY_TYPE_SFI: 2046cb686454SStefan Roese ret = comphy_sfi_power_up(lane, hpipe_base_addr, 2047b617a0d7SIgal Liberman comphy_base_addr, 2048b617a0d7SIgal Liberman ptr_comphy_map->speed); 2049c0132f60SStefan Roese break; 2050c0132f60SStefan Roese case PHY_TYPE_RXAUI0: 2051c0132f60SStefan Roese case PHY_TYPE_RXAUI1: 2052c0132f60SStefan Roese ret = comphy_rxauii_power_up(lane, hpipe_base_addr, 2053c0132f60SStefan Roese comphy_base_addr); 2054c0132f60SStefan Roese break; 2055c0132f60SStefan Roese default: 2056c0132f60SStefan Roese debug("Unknown SerDes type, skip initialize SerDes %d\n", 2057c0132f60SStefan Roese lane); 2058c0132f60SStefan Roese break; 2059c0132f60SStefan Roese } 2060c0132f60SStefan Roese if (ret == 0) { 2061c0132f60SStefan Roese /* 2062d37f020eSStefan Roese * If interface wans't initialized, set the lane to 2063c0132f60SStefan Roese * PHY_TYPE_UNCONNECTED state. 2064c0132f60SStefan Roese */ 2065c0132f60SStefan Roese ptr_comphy_map->type = PHY_TYPE_UNCONNECTED; 20669b643e31SMasahiro Yamada pr_err("PLL is not locked - Failed to initialize lane %d\n", 2067c0132f60SStefan Roese lane); 2068c0132f60SStefan Roese } 2069c0132f60SStefan Roese } 2070c0132f60SStefan Roese 2071c0132f60SStefan Roese debug_exit(); 2072c0132f60SStefan Roese return 0; 2073c0132f60SStefan Roese } 2074