1378 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2018 Marvell4 *5 * Authors:6 * Evan Wang <xswang@marvell.com>7 * Miquèl Raynal <miquel.raynal@bootlin.com>8 * Pali Rohár <pali@kernel.org>9 * Marek Behún <kabel@kernel.org>10 *11 * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart.12 * Comphy code from ARM Trusted Firmware ported by Pali Rohár <pali@kernel.org>13 * and Marek Behún <kabel@kernel.org>.14 */15 16#include <linux/bitfield.h>17#include <linux/clk.h>18#include <linux/io.h>19#include <linux/iopoll.h>20#include <linux/mfd/syscon.h>21#include <linux/module.h>22#include <linux/of.h>23#include <linux/phy.h>24#include <linux/phy/phy.h>25#include <linux/platform_device.h>26#include <linux/spinlock.h>27 28#define PLL_SET_DELAY_US 60029#define COMPHY_PLL_SLEEP 100030#define COMPHY_PLL_TIMEOUT 15000031 32/* Comphy lane2 indirect access register offset */33#define COMPHY_LANE2_INDIR_ADDR 0x034#define COMPHY_LANE2_INDIR_DATA 0x435 36/* SATA and USB3 PHY offset compared to SATA PHY */37#define COMPHY_LANE2_REGS_BASE 0x20038 39/*40 * When accessing common PHY lane registers directly, we need to shift by 1,41 * since the registers are 16-bit.42 */43#define COMPHY_LANE_REG_DIRECT(reg) (((reg) & 0x7FF) << 1)44 45/* COMPHY registers */46#define COMPHY_POWER_PLL_CTRL 0x0147#define PU_IVREF_BIT BIT(15)48#define PU_PLL_BIT BIT(14)49#define PU_RX_BIT BIT(13)50#define PU_TX_BIT BIT(12)51#define PU_TX_INTP_BIT BIT(11)52#define PU_DFE_BIT BIT(10)53#define RESET_DTL_RX_BIT BIT(9)54#define PLL_LOCK_BIT BIT(8)55#define REF_FREF_SEL_MASK GENMASK(4, 0)56#define REF_FREF_SEL_SERDES_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x1)57#define REF_FREF_SEL_SERDES_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3)58#define REF_FREF_SEL_SERDES_50MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x4)59#define REF_FREF_SEL_PCIE_USB3_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x2)60#define REF_FREF_SEL_PCIE_USB3_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3)61#define COMPHY_MODE_MASK GENMASK(7, 5)62#define COMPHY_MODE_SATA FIELD_PREP(COMPHY_MODE_MASK, 0x0)63#define COMPHY_MODE_PCIE FIELD_PREP(COMPHY_MODE_MASK, 0x3)64#define COMPHY_MODE_SERDES FIELD_PREP(COMPHY_MODE_MASK, 0x4)65#define COMPHY_MODE_USB3 FIELD_PREP(COMPHY_MODE_MASK, 0x5)66 67#define COMPHY_KVCO_CAL_CTRL 0x0268#define USE_MAX_PLL_RATE_BIT BIT(12)69#define SPEED_PLL_MASK GENMASK(7, 2)70#define SPEED_PLL_VALUE_16 FIELD_PREP(SPEED_PLL_MASK, 0x10)71 72#define COMPHY_DIG_LOOPBACK_EN 0x2373#define SEL_DATA_WIDTH_MASK GENMASK(11, 10)74#define DATA_WIDTH_10BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x0)75#define DATA_WIDTH_20BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x1)76#define DATA_WIDTH_40BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x2)77#define PLL_READY_TX_BIT BIT(4)78 79#define COMPHY_SYNC_PATTERN 0x2480#define TXD_INVERT_BIT BIT(10)81#define RXD_INVERT_BIT BIT(11)82 83#define COMPHY_SYNC_MASK_GEN 0x2584#define PHY_GEN_MAX_MASK GENMASK(11, 10)85#define PHY_GEN_MAX_USB3_5G FIELD_PREP(PHY_GEN_MAX_MASK, 0x1)86 87#define COMPHY_ISOLATION_CTRL 0x2688#define PHY_ISOLATE_MODE BIT(15)89 90#define COMPHY_GEN2_SET2 0x3e91#define GS2_TX_SSC_AMP_MASK GENMASK(15, 9)92#define GS2_TX_SSC_AMP_4128 FIELD_PREP(GS2_TX_SSC_AMP_MASK, 0x20)93#define GS2_VREG_RXTX_MAS_ISET_MASK GENMASK(8, 7)94#define GS2_VREG_RXTX_MAS_ISET_60U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\95 0x0)96#define GS2_VREG_RXTX_MAS_ISET_80U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\97 0x1)98#define GS2_VREG_RXTX_MAS_ISET_100U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\99 0x2)100#define GS2_VREG_RXTX_MAS_ISET_120U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\101 0x3)102#define GS2_RSVD_6_0_MASK GENMASK(6, 0)103 104#define COMPHY_GEN3_SET2 0x3f105 106#define COMPHY_IDLE_SYNC_EN 0x48107#define IDLE_SYNC_EN BIT(12)108 109#define COMPHY_MISC_CTRL0 0x4F110#define CLK100M_125M_EN BIT(4)111#define TXDCLK_2X_SEL BIT(6)112#define CLK500M_EN BIT(7)113#define PHY_REF_CLK_SEL BIT(10)114 115#define COMPHY_SFT_RESET 0x52116#define SFT_RST BIT(9)117#define SFT_RST_NO_REG BIT(10)118 119#define COMPHY_MISC_CTRL1 0x73120#define SEL_BITS_PCIE_FORCE BIT(15)121 122#define COMPHY_GEN2_SET3 0x112123#define GS3_FFE_CAP_SEL_MASK GENMASK(3, 0)124#define GS3_FFE_CAP_SEL_VALUE FIELD_PREP(GS3_FFE_CAP_SEL_MASK, 0xF)125 126/* PIPE registers */127#define COMPHY_PIPE_LANE_CFG0 0x180128#define PRD_TXDEEMPH0_MASK BIT(0)129#define PRD_TXMARGIN_MASK GENMASK(3, 1)130#define PRD_TXSWING_MASK BIT(4)131#define CFG_TX_ALIGN_POS_MASK GENMASK(8, 5)132 133#define COMPHY_PIPE_LANE_CFG1 0x181134#define PRD_TXDEEMPH1_MASK BIT(15)135#define USE_MAX_PLL_RATE_EN BIT(9)136#define TX_DET_RX_MODE BIT(6)137#define GEN2_TX_DATA_DLY_MASK GENMASK(4, 3)138#define GEN2_TX_DATA_DLY_DEFT FIELD_PREP(GEN2_TX_DATA_DLY_MASK, 2)139#define TX_ELEC_IDLE_MODE_EN BIT(0)140 141#define COMPHY_PIPE_LANE_STAT1 0x183142#define TXDCLK_PCLK_EN BIT(0)143 144#define COMPHY_PIPE_LANE_CFG4 0x188145#define SPREAD_SPECTRUM_CLK_EN BIT(7)146 147#define COMPHY_PIPE_RST_CLK_CTRL 0x1C1148#define PIPE_SOFT_RESET BIT(0)149#define PIPE_REG_RESET BIT(1)150#define MODE_CORE_CLK_FREQ_SEL BIT(9)151#define MODE_PIPE_WIDTH_32 BIT(3)152#define MODE_REFDIV_MASK GENMASK(5, 4)153#define MODE_REFDIV_BY_4 FIELD_PREP(MODE_REFDIV_MASK, 0x2)154 155#define COMPHY_PIPE_TEST_MODE_CTRL 0x1C2156#define MODE_MARGIN_OVERRIDE BIT(2)157 158#define COMPHY_PIPE_CLK_SRC_LO 0x1C3159#define MODE_CLK_SRC BIT(0)160#define BUNDLE_PERIOD_SEL BIT(1)161#define BUNDLE_PERIOD_SCALE_MASK GENMASK(3, 2)162#define BUNDLE_SAMPLE_CTRL BIT(4)163#define PLL_READY_DLY_MASK GENMASK(7, 5)164#define CFG_SEL_20B BIT(15)165 166#define COMPHY_PIPE_PWR_MGM_TIM1 0x1D0167#define CFG_PM_OSCCLK_WAIT_MASK GENMASK(15, 12)168#define CFG_PM_RXDEN_WAIT_MASK GENMASK(11, 8)169#define CFG_PM_RXDEN_WAIT_1_UNIT FIELD_PREP(CFG_PM_RXDEN_WAIT_MASK, 0x1)170#define CFG_PM_RXDLOZ_WAIT_MASK GENMASK(7, 0)171#define CFG_PM_RXDLOZ_WAIT_7_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0x7)172#define CFG_PM_RXDLOZ_WAIT_12_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0xC)173 174/*175 * This register is not from PHY lane register space. It only exists in the176 * indirect register space, before the actual PHY lane 2 registers. So the177 * offset is absolute, not relative to COMPHY_LANE2_REGS_BASE.178 * It is used only for SATA PHY initialization.179 */180#define COMPHY_RESERVED_REG 0x0E181#define PHYCTRL_FRM_PIN_BIT BIT(13)182 183/* South Bridge PHY Configuration Registers */184#define COMPHY_PHY_REG(lane, reg) (((1 - (lane)) * 0x28) + ((reg) & 0x3f))185 186/*187 * lane0: USB3/GbE1 PHY Configuration 1188 * lane1: PCIe/GbE0 PHY Configuration 1189 * (used only by SGMII code)190 */191#define COMPHY_PHY_CFG1 0x0192#define PIN_PU_IVREF_BIT BIT(1)193#define PIN_RESET_CORE_BIT BIT(11)194#define PIN_RESET_COMPHY_BIT BIT(12)195#define PIN_PU_PLL_BIT BIT(16)196#define PIN_PU_RX_BIT BIT(17)197#define PIN_PU_TX_BIT BIT(18)198#define PIN_TX_IDLE_BIT BIT(19)199#define GEN_RX_SEL_MASK GENMASK(25, 22)200#define GEN_RX_SEL_VALUE(val) FIELD_PREP(GEN_RX_SEL_MASK, (val))201#define GEN_TX_SEL_MASK GENMASK(29, 26)202#define GEN_TX_SEL_VALUE(val) FIELD_PREP(GEN_TX_SEL_MASK, (val))203#define SERDES_SPEED_1_25_G 0x6204#define SERDES_SPEED_3_125_G 0x8205#define PHY_RX_INIT_BIT BIT(30)206 207/*208 * lane0: USB3/GbE1 PHY Status 1209 * lane1: PCIe/GbE0 PHY Status 1210 * (used only by SGMII code)211 */212#define COMPHY_PHY_STAT1 0x18213#define PHY_RX_INIT_DONE_BIT BIT(0)214#define PHY_PLL_READY_RX_BIT BIT(2)215#define PHY_PLL_READY_TX_BIT BIT(3)216 217/* PHY Selector */218#define COMPHY_SELECTOR_PHY_REG 0xFC219/* bit0: 0: Lane1 is GbE0; 1: Lane1 is PCIe */220#define COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT BIT(0)221/* bit4: 0: Lane0 is GbE1; 1: Lane0 is USB3 */222#define COMPHY_SELECTOR_USB3_GBE1_SEL_BIT BIT(4)223/* bit8: 0: Lane0 is USB3 instead of GbE1, Lane2 is SATA; 1: Lane2 is USB3 */224#define COMPHY_SELECTOR_USB3_PHY_SEL_BIT BIT(8)225 226struct mvebu_a3700_comphy_conf {227 unsigned int lane;228 enum phy_mode mode;229 int submode;230};231 232#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode) \233 { \234 .lane = _lane, \235 .mode = _mode, \236 .submode = _smode, \237 }238 239#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode) \240 MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA)241 242#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode) \243 MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode)244 245static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = {246 /* lane 0 */247 MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS),248 MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII),249 MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_1000BASEX),250 MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX),251 /* lane 1 */252 MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE),253 MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII),254 MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_1000BASEX),255 MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX),256 /* lane 2 */257 MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA),258 MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS),259};260 261struct mvebu_a3700_comphy_priv {262 void __iomem *comphy_regs;263 void __iomem *lane0_phy_regs; /* USB3 and GbE1 */264 void __iomem *lane1_phy_regs; /* PCIe and GbE0 */265 void __iomem *lane2_phy_indirect; /* SATA and USB3 */266 spinlock_t lock; /* for PHY selector access */267 bool xtal_is_40m;268};269 270struct mvebu_a3700_comphy_lane {271 struct mvebu_a3700_comphy_priv *priv;272 struct device *dev;273 unsigned int id;274 enum phy_mode mode;275 int submode;276 bool invert_tx;277 bool invert_rx;278};279 280struct gbe_phy_init_data_fix {281 u16 addr;282 u16 value;283};284 285/* Changes to 40M1G25 mode data required for running 40M3G125 init mode */286static struct gbe_phy_init_data_fix gbe_phy_init_fix[] = {287 { 0x005, 0x07CC }, { 0x015, 0x0000 }, { 0x01B, 0x0000 },288 { 0x01D, 0x0000 }, { 0x01E, 0x0000 }, { 0x01F, 0x0000 },289 { 0x020, 0x0000 }, { 0x021, 0x0030 }, { 0x026, 0x0888 },290 { 0x04D, 0x0152 }, { 0x04F, 0xA020 }, { 0x050, 0x07CC },291 { 0x053, 0xE9CA }, { 0x055, 0xBD97 }, { 0x071, 0x3015 },292 { 0x076, 0x03AA }, { 0x07C, 0x0FDF }, { 0x0C2, 0x3030 },293 { 0x0C3, 0x8000 }, { 0x0E2, 0x5550 }, { 0x0E3, 0x12A4 },294 { 0x0E4, 0x7D00 }, { 0x0E6, 0x0C83 }, { 0x101, 0xFCC0 },295 { 0x104, 0x0C10 }296};297 298/* 40M1G25 mode init data */299static u16 gbe_phy_init[512] = {300 /* 0 1 2 3 4 5 6 7 */301 /*-----------------------------------------------------------*/302 /* 8 9 A B C D E F */303 0x3110, 0xFD83, 0x6430, 0x412F, 0x82C0, 0x06FA, 0x4500, 0x6D26, /* 00 */304 0xAFC0, 0x8000, 0xC000, 0x0000, 0x2000, 0x49CC, 0x0BC9, 0x2A52, /* 08 */305 0x0BD2, 0x0CDE, 0x13D2, 0x0CE8, 0x1149, 0x10E0, 0x0000, 0x0000, /* 10 */306 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x4134, 0x0D2D, 0xFFFF, /* 18 */307 0xFFE0, 0x4030, 0x1016, 0x0030, 0x0000, 0x0800, 0x0866, 0x0000, /* 20 */308 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, /* 28 */309 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 30 */310 0x0000, 0x0000, 0x000F, 0x6A62, 0x1988, 0x3100, 0x3100, 0x3100, /* 38 */311 0x3100, 0xA708, 0x2430, 0x0830, 0x1030, 0x4610, 0xFF00, 0xFF00, /* 40 */312 0x0060, 0x1000, 0x0400, 0x0040, 0x00F0, 0x0155, 0x1100, 0xA02A, /* 48 */313 0x06FA, 0x0080, 0xB008, 0xE3ED, 0x5002, 0xB592, 0x7A80, 0x0001, /* 50 */314 0x020A, 0x8820, 0x6014, 0x8054, 0xACAA, 0xFC88, 0x2A02, 0x45CF, /* 58 */315 0x000F, 0x1817, 0x2860, 0x064F, 0x0000, 0x0204, 0x1800, 0x6000, /* 60 */316 0x810F, 0x4F23, 0x4000, 0x4498, 0x0850, 0x0000, 0x000E, 0x1002, /* 68 */317 0x9D3A, 0x3009, 0xD066, 0x0491, 0x0001, 0x6AB0, 0x0399, 0x3780, /* 70 */318 0x0040, 0x5AC0, 0x4A80, 0x0000, 0x01DF, 0x0000, 0x0007, 0x0000, /* 78 */319 0x2D54, 0x00A1, 0x4000, 0x0100, 0xA20A, 0x0000, 0x0000, 0x0000, /* 80 */320 0x0000, 0x0000, 0x0000, 0x7400, 0x0E81, 0x1000, 0x1242, 0x0210, /* 88 */321 0x80DF, 0x0F1F, 0x2F3F, 0x4F5F, 0x6F7F, 0x0F1F, 0x2F3F, 0x4F5F, /* 90 */322 0x6F7F, 0x4BAD, 0x0000, 0x0000, 0x0800, 0x0000, 0x2400, 0xB651, /* 98 */323 0xC9E0, 0x4247, 0x0A24, 0x0000, 0xAF19, 0x1004, 0x0000, 0x0000, /* A0 */324 0x0000, 0x0013, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* A8 */325 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* B0 */326 0x0000, 0x0000, 0x0000, 0x0060, 0x0000, 0x0000, 0x0000, 0x0000, /* B8 */327 0x0000, 0x0000, 0x3010, 0xFA00, 0x0000, 0x0000, 0x0000, 0x0003, /* C0 */328 0x1618, 0x8200, 0x8000, 0x0400, 0x050F, 0x0000, 0x0000, 0x0000, /* C8 */329 0x4C93, 0x0000, 0x1000, 0x1120, 0x0010, 0x1242, 0x1242, 0x1E00, /* D0 */330 0x0000, 0x0000, 0x0000, 0x00F8, 0x0000, 0x0041, 0x0800, 0x0000, /* D8 */331 0x82A0, 0x572E, 0x2490, 0x14A9, 0x4E00, 0x0000, 0x0803, 0x0541, /* E0 */332 0x0C15, 0x0000, 0x0000, 0x0400, 0x2626, 0x0000, 0x0000, 0x4200, /* E8 */333 0x0000, 0xAA55, 0x1020, 0x0000, 0x0000, 0x5010, 0x0000, 0x0000, /* F0 */334 0x0000, 0x0000, 0x5000, 0x0000, 0x0000, 0x0000, 0x02F2, 0x0000, /* F8 */335 0x101F, 0xFDC0, 0x4000, 0x8010, 0x0110, 0x0006, 0x0000, 0x0000, /*100 */336 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*108 */337 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04C6, 0x0000, /*110 */338 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*118 */339 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*120 */340 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*128 */341 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*130 */342 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*138 */343 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*140 */344 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*148 */345 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*150 */346 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*158 */347 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*160 */348 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*168 */349 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*170 */350 0x0000, 0x0000, 0x0000, 0x00F0, 0x08A2, 0x3112, 0x0A14, 0x0000, /*178 */351 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*180 */352 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*188 */353 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*190 */354 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*198 */355 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A0 */356 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A8 */357 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B0 */358 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B8 */359 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C0 */360 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C8 */361 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D0 */362 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D8 */363 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E0 */364 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E8 */365 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1F0 */366 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /*1F8 */367};368 369static inline void comphy_reg_set(void __iomem *addr, u32 data, u32 mask)370{371 u32 val;372 373 val = readl(addr);374 val = (val & ~mask) | (data & mask);375 writel(val, addr);376}377 378static inline void comphy_reg_set16(void __iomem *addr, u16 data, u16 mask)379{380 u16 val;381 382 val = readw(addr);383 val = (val & ~mask) | (data & mask);384 writew(val, addr);385}386 387/* Used for accessing lane 2 registers (SATA/USB3 PHY) */388static void comphy_set_indirect(struct mvebu_a3700_comphy_priv *priv,389 u32 offset, u16 data, u16 mask)390{391 writel(offset,392 priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_ADDR);393 comphy_reg_set(priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_DATA,394 data, mask);395}396 397static void comphy_lane_reg_set(struct mvebu_a3700_comphy_lane *lane,398 u16 reg, u16 data, u16 mask)399{400 if (lane->id == 2) {401 /* lane 2 PHY registers are accessed indirectly */402 comphy_set_indirect(lane->priv,403 reg + COMPHY_LANE2_REGS_BASE,404 data, mask);405 } else {406 void __iomem *base = lane->id == 1 ?407 lane->priv->lane1_phy_regs :408 lane->priv->lane0_phy_regs;409 410 comphy_reg_set16(base + COMPHY_LANE_REG_DIRECT(reg),411 data, mask);412 }413}414 415static int comphy_lane_reg_poll(struct mvebu_a3700_comphy_lane *lane,416 u16 reg, u16 bits,417 ulong sleep_us, ulong timeout_us)418{419 int ret;420 421 if (lane->id == 2) {422 u32 data;423 424 /* lane 2 PHY registers are accessed indirectly */425 writel(reg + COMPHY_LANE2_REGS_BASE,426 lane->priv->lane2_phy_indirect +427 COMPHY_LANE2_INDIR_ADDR);428 429 ret = readl_poll_timeout(lane->priv->lane2_phy_indirect +430 COMPHY_LANE2_INDIR_DATA,431 data, (data & bits) == bits,432 sleep_us, timeout_us);433 } else {434 void __iomem *base = lane->id == 1 ?435 lane->priv->lane1_phy_regs :436 lane->priv->lane0_phy_regs;437 u16 data;438 439 ret = readw_poll_timeout(base + COMPHY_LANE_REG_DIRECT(reg),440 data, (data & bits) == bits,441 sleep_us, timeout_us);442 }443 444 return ret;445}446 447static void comphy_periph_reg_set(struct mvebu_a3700_comphy_lane *lane,448 u8 reg, u32 data, u32 mask)449{450 comphy_reg_set(lane->priv->comphy_regs + COMPHY_PHY_REG(lane->id, reg),451 data, mask);452}453 454static int comphy_periph_reg_poll(struct mvebu_a3700_comphy_lane *lane,455 u8 reg, u32 bits,456 ulong sleep_us, ulong timeout_us)457{458 u32 data;459 460 return readl_poll_timeout(lane->priv->comphy_regs +461 COMPHY_PHY_REG(lane->id, reg),462 data, (data & bits) == bits,463 sleep_us, timeout_us);464}465 466/* PHY selector configures with corresponding modes */467static int468mvebu_a3700_comphy_set_phy_selector(struct mvebu_a3700_comphy_lane *lane)469{470 u32 old, new, clr = 0, set = 0;471 unsigned long flags;472 473 switch (lane->mode) {474 case PHY_MODE_SATA:475 /* SATA must be in Lane2 */476 if (lane->id == 2)477 clr = COMPHY_SELECTOR_USB3_PHY_SEL_BIT;478 else479 goto error;480 break;481 482 case PHY_MODE_ETHERNET:483 if (lane->id == 0)484 clr = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT;485 else if (lane->id == 1)486 clr = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT;487 else488 goto error;489 break;490 491 case PHY_MODE_USB_HOST_SS:492 if (lane->id == 2)493 set = COMPHY_SELECTOR_USB3_PHY_SEL_BIT;494 else if (lane->id == 0)495 set = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT;496 else497 goto error;498 break;499 500 case PHY_MODE_PCIE:501 /* PCIE must be in Lane1 */502 if (lane->id == 1)503 set = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT;504 else505 goto error;506 break;507 508 default:509 goto error;510 }511 512 spin_lock_irqsave(&lane->priv->lock, flags);513 514 old = readl(lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG);515 new = (old & ~clr) | set;516 writel(new, lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG);517 518 spin_unlock_irqrestore(&lane->priv->lock, flags);519 520 dev_dbg(lane->dev,521 "COMPHY[%d] mode[%d] changed PHY selector 0x%08x -> 0x%08x\n",522 lane->id, lane->mode, old, new);523 524 return 0;525error:526 dev_err(lane->dev, "COMPHY[%d] mode[%d] is invalid\n", lane->id,527 lane->mode);528 return -EINVAL;529}530 531static int532mvebu_a3700_comphy_sata_power_on(struct mvebu_a3700_comphy_lane *lane)533{534 u32 mask, data, ref_clk;535 int ret;536 537 /* Configure phy selector for SATA */538 ret = mvebu_a3700_comphy_set_phy_selector(lane);539 if (ret)540 return ret;541 542 /* Clear phy isolation mode to make it work in normal mode */543 comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL,544 0x0, PHY_ISOLATE_MODE);545 546 /* 0. Check the Polarity invert bits */547 data = 0x0;548 if (lane->invert_tx)549 data |= TXD_INVERT_BIT;550 if (lane->invert_rx)551 data |= RXD_INVERT_BIT;552 mask = TXD_INVERT_BIT | RXD_INVERT_BIT;553 comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);554 555 /* 1. Select 40-bit data width */556 comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN,557 DATA_WIDTH_40BIT, SEL_DATA_WIDTH_MASK);558 559 /* 2. Select reference clock(25M) and PHY mode (SATA) */560 if (lane->priv->xtal_is_40m)561 ref_clk = REF_FREF_SEL_SERDES_40MHZ;562 else563 ref_clk = REF_FREF_SEL_SERDES_25MHZ;564 565 data = ref_clk | COMPHY_MODE_SATA;566 mask = REF_FREF_SEL_MASK | COMPHY_MODE_MASK;567 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);568 569 /* 3. Use maximum PLL rate (no power save) */570 comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL,571 USE_MAX_PLL_RATE_BIT, USE_MAX_PLL_RATE_BIT);572 573 /* 4. Reset reserved bit */574 comphy_set_indirect(lane->priv, COMPHY_RESERVED_REG,575 0x0, PHYCTRL_FRM_PIN_BIT);576 577 /* 5. Set vendor-specific configuration (It is done in sata driver) */578 /* XXX: in U-Boot below sequence was executed in this place, in Linux579 * not. Now it is done only in U-Boot before this comphy580 * initialization - tests shows that it works ok, but in case of any581 * future problem it is left for reference.582 * reg_set(MVEBU_REGS_BASE + 0xe00a0, 0, 0xffffffff);583 * reg_set(MVEBU_REGS_BASE + 0xe00a4, BIT(6), BIT(6));584 */585 586 /* Wait for > 55 us to allow PLL be enabled */587 udelay(PLL_SET_DELAY_US);588 589 /* Polling status */590 ret = comphy_lane_reg_poll(lane, COMPHY_DIG_LOOPBACK_EN,591 PLL_READY_TX_BIT, COMPHY_PLL_SLEEP,592 COMPHY_PLL_TIMEOUT);593 if (ret)594 dev_err(lane->dev, "Failed to lock SATA PLL\n");595 596 return ret;597}598 599static void comphy_gbe_phy_init(struct mvebu_a3700_comphy_lane *lane,600 bool is_1gbps)601{602 int addr, fix_idx;603 u16 val;604 605 fix_idx = 0;606 for (addr = 0; addr < ARRAY_SIZE(gbe_phy_init); addr++) {607 /*608 * All PHY register values are defined in full for 3.125Gbps609 * SERDES speed. The values required for 1.25 Gbps are almost610 * the same and only few registers should be "fixed" in611 * comparison to 3.125 Gbps values. These register values are612 * stored in "gbe_phy_init_fix" array.613 */614 if (!is_1gbps &&615 fix_idx < ARRAY_SIZE(gbe_phy_init_fix) &&616 gbe_phy_init_fix[fix_idx].addr == addr) {617 /* Use new value */618 val = gbe_phy_init_fix[fix_idx].value;619 fix_idx++;620 } else {621 val = gbe_phy_init[addr];622 }623 624 comphy_lane_reg_set(lane, addr, val, 0xFFFF);625 }626}627 628static int629mvebu_a3700_comphy_ethernet_power_on(struct mvebu_a3700_comphy_lane *lane)630{631 u32 mask, data, speed_sel;632 int ret;633 634 /* Set selector */635 ret = mvebu_a3700_comphy_set_phy_selector(lane);636 if (ret)637 return ret;638 639 /*640 * 1. Reset PHY by setting PHY input port PIN_RESET=1.641 * 2. Set PHY input port PIN_TX_IDLE=1, PIN_PU_IVREF=1 to keep642 * PHY TXP/TXN output to idle state during PHY initialization643 * 3. Set PHY input port PIN_PU_PLL=0, PIN_PU_RX=0, PIN_PU_TX=0.644 */645 data = PIN_PU_IVREF_BIT | PIN_TX_IDLE_BIT | PIN_RESET_COMPHY_BIT;646 mask = data | PIN_RESET_CORE_BIT | PIN_PU_PLL_BIT | PIN_PU_RX_BIT |647 PIN_PU_TX_BIT | PHY_RX_INIT_BIT;648 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);649 650 /* 4. Release reset to the PHY by setting PIN_RESET=0. */651 data = 0x0;652 mask = PIN_RESET_COMPHY_BIT;653 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);654 655 /*656 * 5. Set PIN_PHY_GEN_TX[3:0] and PIN_PHY_GEN_RX[3:0] to decide COMPHY657 * bit rate658 */659 switch (lane->submode) {660 case PHY_INTERFACE_MODE_SGMII:661 case PHY_INTERFACE_MODE_1000BASEX:662 /* SGMII 1G, SerDes speed 1.25G */663 speed_sel = SERDES_SPEED_1_25_G;664 break;665 case PHY_INTERFACE_MODE_2500BASEX:666 /* 2500Base-X, SerDes speed 3.125G */667 speed_sel = SERDES_SPEED_3_125_G;668 break;669 default:670 /* Other rates are not supported */671 dev_err(lane->dev,672 "unsupported phy speed %d on comphy lane%d\n",673 lane->submode, lane->id);674 return -EINVAL;675 }676 data = GEN_RX_SEL_VALUE(speed_sel) | GEN_TX_SEL_VALUE(speed_sel);677 mask = GEN_RX_SEL_MASK | GEN_TX_SEL_MASK;678 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);679 680 /*681 * 6. Wait 10mS for bandgap and reference clocks to stabilize; then682 * start SW programming.683 */684 mdelay(10);685 686 /* 7. Program COMPHY register PHY_MODE */687 data = COMPHY_MODE_SERDES;688 mask = COMPHY_MODE_MASK;689 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);690 691 /*692 * 8. Set COMPHY register REFCLK_SEL to select the correct REFCLK693 * source694 */695 data = 0x0;696 mask = PHY_REF_CLK_SEL;697 comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask);698 699 /*700 * 9. Set correct reference clock frequency in COMPHY register701 * REF_FREF_SEL.702 */703 if (lane->priv->xtal_is_40m)704 data = REF_FREF_SEL_SERDES_50MHZ;705 else706 data = REF_FREF_SEL_SERDES_25MHZ;707 708 mask = REF_FREF_SEL_MASK;709 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);710 711 /*712 * 10. Program COMPHY register PHY_GEN_MAX[1:0]713 * This step is mentioned in the flow received from verification team.714 * However the PHY_GEN_MAX value is only meaningful for other interfaces715 * (not SERDES). For instance, it selects SATA speed 1.5/3/6 Gbps or716 * PCIe speed 2.5/5 Gbps717 */718 719 /*720 * 11. Program COMPHY register SEL_BITS to set correct parallel data721 * bus width722 */723 data = DATA_WIDTH_10BIT;724 mask = SEL_DATA_WIDTH_MASK;725 comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, data, mask);726 727 /*728 * 12. As long as DFE function needs to be enabled in any mode,729 * COMPHY register DFE_UPDATE_EN[5:0] shall be programmed to 0x3F730 * for real chip during COMPHY power on.731 * The value of the DFE_UPDATE_EN already is 0x3F, because it is the732 * default value after reset of the PHY.733 */734 735 /*736 * 13. Program COMPHY GEN registers.737 * These registers should be programmed based on the lab testing result738 * to achieve optimal performance. Please contact the CEA group to get739 * the related GEN table during real chip bring-up. We only required to740 * run though the entire registers programming flow defined by741 * "comphy_gbe_phy_init" when the REF clock is 40 MHz. For REF clock742 * 25 MHz the default values stored in PHY registers are OK.743 */744 dev_dbg(lane->dev, "Running C-DPI phy init %s mode\n",745 lane->submode == PHY_INTERFACE_MODE_2500BASEX ? "2G5" : "1G");746 if (lane->priv->xtal_is_40m)747 comphy_gbe_phy_init(lane,748 lane->submode != PHY_INTERFACE_MODE_2500BASEX);749 750 /*751 * 14. Check the PHY Polarity invert bit752 */753 data = 0x0;754 if (lane->invert_tx)755 data |= TXD_INVERT_BIT;756 if (lane->invert_rx)757 data |= RXD_INVERT_BIT;758 mask = TXD_INVERT_BIT | RXD_INVERT_BIT;759 comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);760 761 /*762 * 15. Set PHY input ports PIN_PU_PLL, PIN_PU_TX and PIN_PU_RX to 1 to763 * start PHY power up sequence. All the PHY register programming should764 * be done before PIN_PU_PLL=1. There should be no register programming765 * for normal PHY operation from this point.766 */767 data = PIN_PU_PLL_BIT | PIN_PU_RX_BIT | PIN_PU_TX_BIT;768 mask = data;769 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);770 771 /*772 * 16. Wait for PHY power up sequence to finish by checking output ports773 * PIN_PLL_READY_TX=1 and PIN_PLL_READY_RX=1.774 */775 ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1,776 PHY_PLL_READY_TX_BIT |777 PHY_PLL_READY_RX_BIT,778 COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);779 if (ret) {780 dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n",781 lane->id);782 return ret;783 }784 785 /*786 * 17. Set COMPHY input port PIN_TX_IDLE=0787 */788 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, 0x0, PIN_TX_IDLE_BIT);789 790 /*791 * 18. After valid data appear on PIN_RXDATA bus, set PIN_RX_INIT=1. To792 * start RX initialization. PIN_RX_INIT_DONE will be cleared to 0 by the793 * PHY After RX initialization is done, PIN_RX_INIT_DONE will be set to794 * 1 by COMPHY Set PIN_RX_INIT=0 after PIN_RX_INIT_DONE= 1. Please795 * refer to RX initialization part for details.796 */797 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1,798 PHY_RX_INIT_BIT, PHY_RX_INIT_BIT);799 800 ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1,801 PHY_PLL_READY_TX_BIT |802 PHY_PLL_READY_RX_BIT,803 COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);804 if (ret) {805 dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n",806 lane->id);807 return ret;808 }809 810 ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1,811 PHY_RX_INIT_DONE_BIT,812 COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);813 if (ret)814 dev_err(lane->dev, "Failed to init RX of SERDES PHY %d\n",815 lane->id);816 817 return ret;818}819 820static int821mvebu_a3700_comphy_usb3_power_on(struct mvebu_a3700_comphy_lane *lane)822{823 u32 mask, data, cfg, ref_clk;824 int ret;825 826 /* Set phy seclector */827 ret = mvebu_a3700_comphy_set_phy_selector(lane);828 if (ret)829 return ret;830 831 /* COMPHY register reset (cleared automatically) */832 comphy_lane_reg_set(lane, COMPHY_SFT_RESET, SFT_RST, SFT_RST);833 834 /*835 * 0. Set PHY OTG Control(0x5d034), bit 4, Power up OTG module The836 * register belong to UTMI module, so it is set in UTMI phy driver.837 */838 839 /*840 * 1. Set PRD_TXDEEMPH (3.5db de-emph)841 */842 data = PRD_TXDEEMPH0_MASK;843 mask = PRD_TXDEEMPH0_MASK | PRD_TXMARGIN_MASK | PRD_TXSWING_MASK |844 CFG_TX_ALIGN_POS_MASK;845 comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG0, data, mask);846 847 /*848 * 2. Set BIT0: enable transmitter in high impedance mode849 * Set BIT[3:4]: delay 2 clock cycles for HiZ off latency850 * Set BIT6: Tx detect Rx at HiZ mode851 * Unset BIT15: set to 0 to set USB3 De-emphasize level to -3.5db852 * together with bit 0 of COMPHY_PIPE_LANE_CFG0 register853 */854 data = TX_DET_RX_MODE | GEN2_TX_DATA_DLY_DEFT | TX_ELEC_IDLE_MODE_EN;855 mask = PRD_TXDEEMPH1_MASK | TX_DET_RX_MODE | GEN2_TX_DATA_DLY_MASK |856 TX_ELEC_IDLE_MODE_EN;857 comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1, data, mask);858 859 /*860 * 3. Set Spread Spectrum Clock Enabled861 */862 comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG4,863 SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN);864 865 /*866 * 4. Set Override Margining Controls From the MAC:867 * Use margining signals from lane configuration868 */869 comphy_lane_reg_set(lane, COMPHY_PIPE_TEST_MODE_CTRL,870 MODE_MARGIN_OVERRIDE, 0xFFFF);871 872 /*873 * 5. Set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles874 * set Mode Clock Source = PCLK is generated from REFCLK875 */876 data = 0x0;877 mask = MODE_CLK_SRC | BUNDLE_PERIOD_SEL | BUNDLE_PERIOD_SCALE_MASK |878 BUNDLE_SAMPLE_CTRL | PLL_READY_DLY_MASK;879 comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO, data, mask);880 881 /*882 * 6. Set G2 Spread Spectrum Clock Amplitude at 4K883 */884 comphy_lane_reg_set(lane, COMPHY_GEN2_SET2,885 GS2_TX_SSC_AMP_4128, GS2_TX_SSC_AMP_MASK);886 887 /*888 * 7. Unset G3 Spread Spectrum Clock Amplitude889 * set G3 TX and RX Register Master Current Select890 */891 data = GS2_VREG_RXTX_MAS_ISET_60U;892 mask = GS2_TX_SSC_AMP_MASK | GS2_VREG_RXTX_MAS_ISET_MASK |893 GS2_RSVD_6_0_MASK;894 comphy_lane_reg_set(lane, COMPHY_GEN3_SET2, data, mask);895 896 /*897 * 8. Check crystal jumper setting and program the Power and PLL Control898 * accordingly Change RX wait899 */900 if (lane->priv->xtal_is_40m) {901 ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ;902 cfg = CFG_PM_RXDLOZ_WAIT_12_UNIT;903 } else {904 ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ;905 cfg = CFG_PM_RXDLOZ_WAIT_7_UNIT;906 }907 908 data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT |909 PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_USB3 | ref_clk;910 mask = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT |911 PU_TX_INTP_BIT | PU_DFE_BIT | PLL_LOCK_BIT | COMPHY_MODE_MASK |912 REF_FREF_SEL_MASK;913 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);914 915 data = CFG_PM_RXDEN_WAIT_1_UNIT | cfg;916 mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK |917 CFG_PM_RXDLOZ_WAIT_MASK;918 comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask);919 920 /*921 * 9. Enable idle sync922 */923 comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN,924 IDLE_SYNC_EN, IDLE_SYNC_EN);925 926 /*927 * 10. Enable the output of 500M clock928 */929 comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, CLK500M_EN, CLK500M_EN);930 931 /*932 * 11. Set 20-bit data width933 */934 comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN,935 DATA_WIDTH_20BIT, 0xFFFF);936 937 /*938 * 12. Override Speed_PLL value and use MAC PLL939 */940 data = SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT;941 mask = 0xFFFF;942 comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, data, mask);943 944 /*945 * 13. Check the Polarity invert bit946 */947 data = 0x0;948 if (lane->invert_tx)949 data |= TXD_INVERT_BIT;950 if (lane->invert_rx)951 data |= RXD_INVERT_BIT;952 mask = TXD_INVERT_BIT | RXD_INVERT_BIT;953 comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);954 955 /*956 * 14. Set max speed generation to USB3.0 5Gbps957 */958 comphy_lane_reg_set(lane, COMPHY_SYNC_MASK_GEN,959 PHY_GEN_MAX_USB3_5G, PHY_GEN_MAX_MASK);960 961 /*962 * 15. Set capacitor value for FFE gain peaking to 0xF963 */964 comphy_lane_reg_set(lane, COMPHY_GEN2_SET3,965 GS3_FFE_CAP_SEL_VALUE, GS3_FFE_CAP_SEL_MASK);966 967 /*968 * 16. Release SW reset969 */970 data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32 | MODE_REFDIV_BY_4;971 mask = 0xFFFF;972 comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask);973 974 /* Wait for > 55 us to allow PCLK be enabled */975 udelay(PLL_SET_DELAY_US);976 977 ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN,978 COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);979 if (ret)980 dev_err(lane->dev, "Failed to lock USB3 PLL\n");981 982 return ret;983}984 985static int986mvebu_a3700_comphy_pcie_power_on(struct mvebu_a3700_comphy_lane *lane)987{988 u32 mask, data, ref_clk;989 int ret;990 991 /* Configure phy selector for PCIe */992 ret = mvebu_a3700_comphy_set_phy_selector(lane);993 if (ret)994 return ret;995 996 /* 1. Enable max PLL. */997 comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1,998 USE_MAX_PLL_RATE_EN, USE_MAX_PLL_RATE_EN);999 1000 /* 2. Select 20 bit SERDES interface. */1001 comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO,1002 CFG_SEL_20B, CFG_SEL_20B);1003 1004 /* 3. Force to use reg setting for PCIe mode */1005 comphy_lane_reg_set(lane, COMPHY_MISC_CTRL1,1006 SEL_BITS_PCIE_FORCE, SEL_BITS_PCIE_FORCE);1007 1008 /* 4. Change RX wait */1009 data = CFG_PM_RXDEN_WAIT_1_UNIT | CFG_PM_RXDLOZ_WAIT_12_UNIT;1010 mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK |1011 CFG_PM_RXDLOZ_WAIT_MASK;1012 comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask);1013 1014 /* 5. Enable idle sync */1015 comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN,1016 IDLE_SYNC_EN, IDLE_SYNC_EN);1017 1018 /* 6. Enable the output of 100M/125M/500M clock */1019 data = CLK500M_EN | TXDCLK_2X_SEL | CLK100M_125M_EN;1020 mask = data;1021 comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask);1022 1023 /*1024 * 7. Enable TX, PCIE global register, 0xd0074814, it is done in1025 * PCI-E driver1026 */1027 1028 /*1029 * 8. Check crystal jumper setting and program the Power and PLL1030 * Control accordingly1031 */1032 1033 if (lane->priv->xtal_is_40m)1034 ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ;1035 else1036 ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ;1037 1038 data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT |1039 PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_PCIE | ref_clk;1040 mask = 0xFFFF;1041 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask);1042 1043 /* 9. Override Speed_PLL value and use MAC PLL */1044 comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL,1045 SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT,1046 0xFFFF);1047 1048 /* 10. Check the Polarity invert bit */1049 data = 0x0;1050 if (lane->invert_tx)1051 data |= TXD_INVERT_BIT;1052 if (lane->invert_rx)1053 data |= RXD_INVERT_BIT;1054 mask = TXD_INVERT_BIT | RXD_INVERT_BIT;1055 comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask);1056 1057 /* 11. Release SW reset */1058 data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32;1059 mask = data | PIPE_SOFT_RESET | MODE_REFDIV_MASK;1060 comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask);1061 1062 /* Wait for > 55 us to allow PCLK be enabled */1063 udelay(PLL_SET_DELAY_US);1064 1065 ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN,1066 COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT);1067 if (ret)1068 dev_err(lane->dev, "Failed to lock PCIE PLL\n");1069 1070 return ret;1071}1072 1073static void1074mvebu_a3700_comphy_sata_power_off(struct mvebu_a3700_comphy_lane *lane)1075{1076 /* Set phy isolation mode */1077 comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL,1078 PHY_ISOLATE_MODE, PHY_ISOLATE_MODE);1079 1080 /* Power off PLL, Tx, Rx */1081 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL,1082 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT);1083}1084 1085static void1086mvebu_a3700_comphy_ethernet_power_off(struct mvebu_a3700_comphy_lane *lane)1087{1088 u32 mask, data;1089 1090 data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT | PIN_PU_IVREF_BIT |1091 PHY_RX_INIT_BIT;1092 mask = data;1093 comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask);1094}1095 1096static void1097mvebu_a3700_comphy_pcie_power_off(struct mvebu_a3700_comphy_lane *lane)1098{1099 /* Power off PLL, Tx, Rx */1100 comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL,1101 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT);1102}1103 1104static void mvebu_a3700_comphy_usb3_power_off(struct mvebu_a3700_comphy_lane *lane)1105{1106 /*1107 * The USB3 MAC sets the USB3 PHY to low state, so we do not1108 * need to power off USB3 PHY again.1109 */1110}1111 1112static bool mvebu_a3700_comphy_check_mode(int lane,1113 enum phy_mode mode,1114 int submode)1115{1116 int i, n = ARRAY_SIZE(mvebu_a3700_comphy_modes);1117 1118 /* Unused PHY mux value is 0x0 */1119 if (mode == PHY_MODE_INVALID)1120 return false;1121 1122 for (i = 0; i < n; i++) {1123 if (mvebu_a3700_comphy_modes[i].lane == lane &&1124 mvebu_a3700_comphy_modes[i].mode == mode &&1125 mvebu_a3700_comphy_modes[i].submode == submode)1126 break;1127 }1128 1129 if (i == n)1130 return false;1131 1132 return true;1133}1134 1135static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode,1136 int submode)1137{1138 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);1139 1140 if (!mvebu_a3700_comphy_check_mode(lane->id, mode, submode)) {1141 dev_err(lane->dev, "invalid COMPHY mode\n");1142 return -EINVAL;1143 }1144 1145 /* Mode cannot be changed while the PHY is powered on */1146 if (phy->power_count &&1147 (lane->mode != mode || lane->submode != submode))1148 return -EBUSY;1149 1150 /* Just remember the mode, ->power_on() will do the real setup */1151 lane->mode = mode;1152 lane->submode = submode;1153 1154 return 0;1155}1156 1157static int mvebu_a3700_comphy_power_on(struct phy *phy)1158{1159 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);1160 1161 if (!mvebu_a3700_comphy_check_mode(lane->id, lane->mode,1162 lane->submode)) {1163 dev_err(lane->dev, "invalid COMPHY mode\n");1164 return -EINVAL;1165 }1166 1167 switch (lane->mode) {1168 case PHY_MODE_USB_HOST_SS:1169 dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id);1170 return mvebu_a3700_comphy_usb3_power_on(lane);1171 case PHY_MODE_SATA:1172 dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id);1173 return mvebu_a3700_comphy_sata_power_on(lane);1174 case PHY_MODE_ETHERNET:1175 dev_dbg(lane->dev, "set lane %d to Ethernet mode\n", lane->id);1176 return mvebu_a3700_comphy_ethernet_power_on(lane);1177 case PHY_MODE_PCIE:1178 dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id);1179 return mvebu_a3700_comphy_pcie_power_on(lane);1180 default:1181 dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode);1182 return -EOPNOTSUPP;1183 }1184}1185 1186static int mvebu_a3700_comphy_power_off(struct phy *phy)1187{1188 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy);1189 1190 switch (lane->id) {1191 case 0:1192 mvebu_a3700_comphy_usb3_power_off(lane);1193 mvebu_a3700_comphy_ethernet_power_off(lane);1194 return 0;1195 case 1:1196 mvebu_a3700_comphy_pcie_power_off(lane);1197 mvebu_a3700_comphy_ethernet_power_off(lane);1198 return 0;1199 case 2:1200 mvebu_a3700_comphy_usb3_power_off(lane);1201 mvebu_a3700_comphy_sata_power_off(lane);1202 return 0;1203 default:1204 dev_err(lane->dev, "invalid COMPHY mode\n");1205 return -EINVAL;1206 }1207}1208 1209static const struct phy_ops mvebu_a3700_comphy_ops = {1210 .power_on = mvebu_a3700_comphy_power_on,1211 .power_off = mvebu_a3700_comphy_power_off,1212 .set_mode = mvebu_a3700_comphy_set_mode,1213 .owner = THIS_MODULE,1214};1215 1216static struct phy *mvebu_a3700_comphy_xlate(struct device *dev,1217 const struct of_phandle_args *args)1218{1219 struct mvebu_a3700_comphy_lane *lane;1220 unsigned int port;1221 struct phy *phy;1222 1223 phy = of_phy_simple_xlate(dev, args);1224 if (IS_ERR(phy))1225 return phy;1226 1227 lane = phy_get_drvdata(phy);1228 1229 port = args->args[0];1230 if (port != 0 && (port != 1 || lane->id != 0)) {1231 dev_err(lane->dev, "invalid port number %u\n", port);1232 return ERR_PTR(-EINVAL);1233 }1234 1235 lane->invert_tx = args->args[1] & BIT(0);1236 lane->invert_rx = args->args[1] & BIT(1);1237 1238 return phy;1239}1240 1241static int mvebu_a3700_comphy_probe(struct platform_device *pdev)1242{1243 struct mvebu_a3700_comphy_priv *priv;1244 struct phy_provider *provider;1245 struct device_node *child;1246 struct resource *res;1247 struct clk *clk;1248 int ret;1249 1250 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);1251 if (!priv)1252 return -ENOMEM;1253 1254 spin_lock_init(&priv->lock);1255 1256 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "comphy");1257 priv->comphy_regs = devm_ioremap_resource(&pdev->dev, res);1258 if (IS_ERR(priv->comphy_regs))1259 return PTR_ERR(priv->comphy_regs);1260 1261 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,1262 "lane1_pcie_gbe");1263 priv->lane1_phy_regs = devm_ioremap_resource(&pdev->dev, res);1264 if (IS_ERR(priv->lane1_phy_regs))1265 return PTR_ERR(priv->lane1_phy_regs);1266 1267 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,1268 "lane0_usb3_gbe");1269 priv->lane0_phy_regs = devm_ioremap_resource(&pdev->dev, res);1270 if (IS_ERR(priv->lane0_phy_regs))1271 return PTR_ERR(priv->lane0_phy_regs);1272 1273 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,1274 "lane2_sata_usb3");1275 priv->lane2_phy_indirect = devm_ioremap_resource(&pdev->dev, res);1276 if (IS_ERR(priv->lane2_phy_indirect))1277 return PTR_ERR(priv->lane2_phy_indirect);1278 1279 /*1280 * Driver needs to know if reference xtal clock is 40MHz or 25MHz.1281 * Old DT bindings do not have xtal clk present. So do not fail here1282 * and expects that default 25MHz reference clock is used.1283 */1284 clk = clk_get(&pdev->dev, "xtal");1285 if (IS_ERR(clk)) {1286 if (PTR_ERR(clk) == -EPROBE_DEFER)1287 return -EPROBE_DEFER;1288 dev_warn(&pdev->dev, "missing 'xtal' clk (%ld)\n",1289 PTR_ERR(clk));1290 } else {1291 ret = clk_prepare_enable(clk);1292 if (ret) {1293 dev_warn(&pdev->dev, "enabling xtal clk failed (%d)\n",1294 ret);1295 } else {1296 if (clk_get_rate(clk) == 40000000)1297 priv->xtal_is_40m = true;1298 clk_disable_unprepare(clk);1299 }1300 clk_put(clk);1301 }1302 1303 dev_set_drvdata(&pdev->dev, priv);1304 1305 for_each_available_child_of_node(pdev->dev.of_node, child) {1306 struct mvebu_a3700_comphy_lane *lane;1307 struct phy *phy;1308 int ret;1309 u32 lane_id;1310 1311 ret = of_property_read_u32(child, "reg", &lane_id);1312 if (ret < 0) {1313 dev_err(&pdev->dev, "missing 'reg' property (%d)\n",1314 ret);1315 continue;1316 }1317 1318 if (lane_id >= 3) {1319 dev_err(&pdev->dev, "invalid 'reg' property\n");1320 continue;1321 }1322 1323 lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL);1324 if (!lane) {1325 of_node_put(child);1326 return -ENOMEM;1327 }1328 1329 phy = devm_phy_create(&pdev->dev, child,1330 &mvebu_a3700_comphy_ops);1331 if (IS_ERR(phy)) {1332 of_node_put(child);1333 return PTR_ERR(phy);1334 }1335 1336 lane->priv = priv;1337 lane->dev = &pdev->dev;1338 lane->mode = PHY_MODE_INVALID;1339 lane->submode = PHY_INTERFACE_MODE_NA;1340 lane->id = lane_id;1341 lane->invert_tx = false;1342 lane->invert_rx = false;1343 phy_set_drvdata(phy, lane);1344 1345 /*1346 * To avoid relying on the bootloader/firmware configuration,1347 * power off all comphys.1348 */1349 mvebu_a3700_comphy_power_off(phy);1350 }1351 1352 provider = devm_of_phy_provider_register(&pdev->dev,1353 mvebu_a3700_comphy_xlate);1354 1355 return PTR_ERR_OR_ZERO(provider);1356}1357 1358static const struct of_device_id mvebu_a3700_comphy_of_match_table[] = {1359 { .compatible = "marvell,comphy-a3700" },1360 { },1361};1362MODULE_DEVICE_TABLE(of, mvebu_a3700_comphy_of_match_table);1363 1364static struct platform_driver mvebu_a3700_comphy_driver = {1365 .probe = mvebu_a3700_comphy_probe,1366 .driver = {1367 .name = "mvebu-a3700-comphy",1368 .of_match_table = mvebu_a3700_comphy_of_match_table,1369 },1370};1371module_platform_driver(mvebu_a3700_comphy_driver);1372 1373MODULE_AUTHOR("Miquèl Raynal <miquel.raynal@bootlin.com>");1374MODULE_AUTHOR("Pali Rohár <pali@kernel.org>");1375MODULE_AUTHOR("Marek Behún <kabel@kernel.org>");1376MODULE_DESCRIPTION("Common PHY driver for A3700");1377MODULE_LICENSE("GPL v2");1378