19695375aSMiquel Raynal // SPDX-License-Identifier: GPL-2.0 29695375aSMiquel Raynal /* 39695375aSMiquel Raynal * Copyright (C) 2018 Marvell 49695375aSMiquel Raynal * 59695375aSMiquel Raynal * Authors: 69695375aSMiquel Raynal * Evan Wang <xswang@marvell.com> 79695375aSMiquel Raynal * Miquèl Raynal <miquel.raynal@bootlin.com> 893433708SPali Rohár * Pali Rohár <pali@kernel.org> 993433708SPali Rohár * Marek Behún <kabel@kernel.org> 109695375aSMiquel Raynal * 119695375aSMiquel Raynal * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart. 1293433708SPali Rohár * Comphy code from ARM Trusted Firmware ported by Pali Rohár <pali@kernel.org> 1393433708SPali Rohár * and Marek Behún <kabel@kernel.org>. 149695375aSMiquel Raynal */ 159695375aSMiquel Raynal 1693433708SPali Rohár #include <linux/bitfield.h> 1793433708SPali Rohár #include <linux/clk.h> 189695375aSMiquel Raynal #include <linux/io.h> 199695375aSMiquel Raynal #include <linux/iopoll.h> 209695375aSMiquel Raynal #include <linux/mfd/syscon.h> 219695375aSMiquel Raynal #include <linux/module.h> 229695375aSMiquel Raynal #include <linux/phy.h> 239695375aSMiquel Raynal #include <linux/phy/phy.h> 249695375aSMiquel Raynal #include <linux/platform_device.h> 2593433708SPali Rohár #include <linux/spinlock.h> 269695375aSMiquel Raynal 2793433708SPali Rohár #define PLL_SET_DELAY_US 600 2893433708SPali Rohár #define COMPHY_PLL_SLEEP 1000 2993433708SPali Rohár #define COMPHY_PLL_TIMEOUT 150000 309695375aSMiquel Raynal 3193433708SPali Rohár /* Comphy lane2 indirect access register offset */ 3293433708SPali Rohár #define COMPHY_LANE2_INDIR_ADDR 0x0 3393433708SPali Rohár #define COMPHY_LANE2_INDIR_DATA 0x4 349695375aSMiquel Raynal 3593433708SPali Rohár /* SATA and USB3 PHY offset compared to SATA PHY */ 3693433708SPali Rohár #define COMPHY_LANE2_REGS_BASE 0x200 379695375aSMiquel Raynal 3893433708SPali Rohár /* 3993433708SPali Rohár * When accessing common PHY lane registers directly, we need to shift by 1, 4093433708SPali Rohár * since the registers are 16-bit. 4193433708SPali Rohár */ 4293433708SPali Rohár #define COMPHY_LANE_REG_DIRECT(reg) (((reg) & 0x7FF) << 1) 439695375aSMiquel Raynal 4493433708SPali Rohár /* COMPHY registers */ 4593433708SPali Rohár #define COMPHY_POWER_PLL_CTRL 0x01 4693433708SPali Rohár #define PU_IVREF_BIT BIT(15) 4793433708SPali Rohár #define PU_PLL_BIT BIT(14) 4893433708SPali Rohár #define PU_RX_BIT BIT(13) 4993433708SPali Rohár #define PU_TX_BIT BIT(12) 5093433708SPali Rohár #define PU_TX_INTP_BIT BIT(11) 5193433708SPali Rohár #define PU_DFE_BIT BIT(10) 5293433708SPali Rohár #define RESET_DTL_RX_BIT BIT(9) 5393433708SPali Rohár #define PLL_LOCK_BIT BIT(8) 5493433708SPali Rohár #define REF_FREF_SEL_MASK GENMASK(4, 0) 5593433708SPali Rohár #define REF_FREF_SEL_SERDES_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x1) 5693433708SPali Rohár #define REF_FREF_SEL_SERDES_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3) 5793433708SPali Rohár #define REF_FREF_SEL_SERDES_50MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x4) 5893433708SPali Rohár #define REF_FREF_SEL_PCIE_USB3_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x2) 5993433708SPali Rohár #define REF_FREF_SEL_PCIE_USB3_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3) 6093433708SPali Rohár #define COMPHY_MODE_MASK GENMASK(7, 5) 6193433708SPali Rohár #define COMPHY_MODE_SATA FIELD_PREP(COMPHY_MODE_MASK, 0x0) 6293433708SPali Rohár #define COMPHY_MODE_PCIE FIELD_PREP(COMPHY_MODE_MASK, 0x3) 6393433708SPali Rohár #define COMPHY_MODE_SERDES FIELD_PREP(COMPHY_MODE_MASK, 0x4) 6493433708SPali Rohár #define COMPHY_MODE_USB3 FIELD_PREP(COMPHY_MODE_MASK, 0x5) 6593433708SPali Rohár 6693433708SPali Rohár #define COMPHY_KVCO_CAL_CTRL 0x02 6793433708SPali Rohár #define USE_MAX_PLL_RATE_BIT BIT(12) 6893433708SPali Rohár #define SPEED_PLL_MASK GENMASK(7, 2) 6993433708SPali Rohár #define SPEED_PLL_VALUE_16 FIELD_PREP(SPEED_PLL_MASK, 0x10) 7093433708SPali Rohár 7193433708SPali Rohár #define COMPHY_DIG_LOOPBACK_EN 0x23 7293433708SPali Rohár #define SEL_DATA_WIDTH_MASK GENMASK(11, 10) 7393433708SPali Rohár #define DATA_WIDTH_10BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x0) 7493433708SPali Rohár #define DATA_WIDTH_20BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x1) 7593433708SPali Rohár #define DATA_WIDTH_40BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x2) 7693433708SPali Rohár #define PLL_READY_TX_BIT BIT(4) 7793433708SPali Rohár 7893433708SPali Rohár #define COMPHY_SYNC_PATTERN 0x24 7993433708SPali Rohár #define TXD_INVERT_BIT BIT(10) 8093433708SPali Rohár #define RXD_INVERT_BIT BIT(11) 8193433708SPali Rohár 8293433708SPali Rohár #define COMPHY_SYNC_MASK_GEN 0x25 8393433708SPali Rohár #define PHY_GEN_MAX_MASK GENMASK(11, 10) 8493433708SPali Rohár #define PHY_GEN_MAX_USB3_5G FIELD_PREP(PHY_GEN_MAX_MASK, 0x1) 8593433708SPali Rohár 8693433708SPali Rohár #define COMPHY_ISOLATION_CTRL 0x26 8793433708SPali Rohár #define PHY_ISOLATE_MODE BIT(15) 8893433708SPali Rohár 8993433708SPali Rohár #define COMPHY_GEN2_SET2 0x3e 9093433708SPali Rohár #define GS2_TX_SSC_AMP_MASK GENMASK(15, 9) 9193433708SPali Rohár #define GS2_TX_SSC_AMP_4128 FIELD_PREP(GS2_TX_SSC_AMP_MASK, 0x20) 9293433708SPali Rohár #define GS2_VREG_RXTX_MAS_ISET_MASK GENMASK(8, 7) 9393433708SPali Rohár #define GS2_VREG_RXTX_MAS_ISET_60U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ 9493433708SPali Rohár 0x0) 9593433708SPali Rohár #define GS2_VREG_RXTX_MAS_ISET_80U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ 9693433708SPali Rohár 0x1) 9793433708SPali Rohár #define GS2_VREG_RXTX_MAS_ISET_100U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ 9893433708SPali Rohár 0x2) 9993433708SPali Rohár #define GS2_VREG_RXTX_MAS_ISET_120U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ 10093433708SPali Rohár 0x3) 10193433708SPali Rohár #define GS2_RSVD_6_0_MASK GENMASK(6, 0) 10293433708SPali Rohár 10393433708SPali Rohár #define COMPHY_GEN3_SET2 0x3f 10493433708SPali Rohár 10593433708SPali Rohár #define COMPHY_IDLE_SYNC_EN 0x48 10693433708SPali Rohár #define IDLE_SYNC_EN BIT(12) 10793433708SPali Rohár 10893433708SPali Rohár #define COMPHY_MISC_CTRL0 0x4F 10993433708SPali Rohár #define CLK100M_125M_EN BIT(4) 11093433708SPali Rohár #define TXDCLK_2X_SEL BIT(6) 11193433708SPali Rohár #define CLK500M_EN BIT(7) 11293433708SPali Rohár #define PHY_REF_CLK_SEL BIT(10) 11393433708SPali Rohár 11493433708SPali Rohár #define COMPHY_SFT_RESET 0x52 11593433708SPali Rohár #define SFT_RST BIT(9) 11693433708SPali Rohár #define SFT_RST_NO_REG BIT(10) 11793433708SPali Rohár 11893433708SPali Rohár #define COMPHY_MISC_CTRL1 0x73 11993433708SPali Rohár #define SEL_BITS_PCIE_FORCE BIT(15) 12093433708SPali Rohár 12193433708SPali Rohár #define COMPHY_GEN2_SET3 0x112 12293433708SPali Rohár #define GS3_FFE_CAP_SEL_MASK GENMASK(3, 0) 12393433708SPali Rohár #define GS3_FFE_CAP_SEL_VALUE FIELD_PREP(GS3_FFE_CAP_SEL_MASK, 0xF) 12493433708SPali Rohár 12593433708SPali Rohár /* PIPE registers */ 12693433708SPali Rohár #define COMPHY_PIPE_LANE_CFG0 0x180 12793433708SPali Rohár #define PRD_TXDEEMPH0_MASK BIT(0) 12893433708SPali Rohár #define PRD_TXMARGIN_MASK GENMASK(3, 1) 12993433708SPali Rohár #define PRD_TXSWING_MASK BIT(4) 13093433708SPali Rohár #define CFG_TX_ALIGN_POS_MASK GENMASK(8, 5) 13193433708SPali Rohár 13293433708SPali Rohár #define COMPHY_PIPE_LANE_CFG1 0x181 13393433708SPali Rohár #define PRD_TXDEEMPH1_MASK BIT(15) 13493433708SPali Rohár #define USE_MAX_PLL_RATE_EN BIT(9) 13593433708SPali Rohár #define TX_DET_RX_MODE BIT(6) 13693433708SPali Rohár #define GEN2_TX_DATA_DLY_MASK GENMASK(4, 3) 13793433708SPali Rohár #define GEN2_TX_DATA_DLY_DEFT FIELD_PREP(GEN2_TX_DATA_DLY_MASK, 2) 13893433708SPali Rohár #define TX_ELEC_IDLE_MODE_EN BIT(0) 13993433708SPali Rohár 14093433708SPali Rohár #define COMPHY_PIPE_LANE_STAT1 0x183 14193433708SPali Rohár #define TXDCLK_PCLK_EN BIT(0) 14293433708SPali Rohár 14393433708SPali Rohár #define COMPHY_PIPE_LANE_CFG4 0x188 14493433708SPali Rohár #define SPREAD_SPECTRUM_CLK_EN BIT(7) 14593433708SPali Rohár 14693433708SPali Rohár #define COMPHY_PIPE_RST_CLK_CTRL 0x1C1 14793433708SPali Rohár #define PIPE_SOFT_RESET BIT(0) 14893433708SPali Rohár #define PIPE_REG_RESET BIT(1) 14993433708SPali Rohár #define MODE_CORE_CLK_FREQ_SEL BIT(9) 15093433708SPali Rohár #define MODE_PIPE_WIDTH_32 BIT(3) 15193433708SPali Rohár #define MODE_REFDIV_MASK GENMASK(5, 4) 15293433708SPali Rohár #define MODE_REFDIV_BY_4 FIELD_PREP(MODE_REFDIV_MASK, 0x2) 15393433708SPali Rohár 15493433708SPali Rohár #define COMPHY_PIPE_TEST_MODE_CTRL 0x1C2 15593433708SPali Rohár #define MODE_MARGIN_OVERRIDE BIT(2) 15693433708SPali Rohár 15793433708SPali Rohár #define COMPHY_PIPE_CLK_SRC_LO 0x1C3 15893433708SPali Rohár #define MODE_CLK_SRC BIT(0) 15993433708SPali Rohár #define BUNDLE_PERIOD_SEL BIT(1) 16093433708SPali Rohár #define BUNDLE_PERIOD_SCALE_MASK GENMASK(3, 2) 16193433708SPali Rohár #define BUNDLE_SAMPLE_CTRL BIT(4) 16293433708SPali Rohár #define PLL_READY_DLY_MASK GENMASK(7, 5) 16393433708SPali Rohár #define CFG_SEL_20B BIT(15) 16493433708SPali Rohár 16593433708SPali Rohár #define COMPHY_PIPE_PWR_MGM_TIM1 0x1D0 16693433708SPali Rohár #define CFG_PM_OSCCLK_WAIT_MASK GENMASK(15, 12) 16793433708SPali Rohár #define CFG_PM_RXDEN_WAIT_MASK GENMASK(11, 8) 16893433708SPali Rohár #define CFG_PM_RXDEN_WAIT_1_UNIT FIELD_PREP(CFG_PM_RXDEN_WAIT_MASK, 0x1) 16993433708SPali Rohár #define CFG_PM_RXDLOZ_WAIT_MASK GENMASK(7, 0) 17093433708SPali Rohár #define CFG_PM_RXDLOZ_WAIT_7_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0x7) 17193433708SPali Rohár #define CFG_PM_RXDLOZ_WAIT_12_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0xC) 17293433708SPali Rohár 17393433708SPali Rohár /* 17493433708SPali Rohár * This register is not from PHY lane register space. It only exists in the 17593433708SPali Rohár * indirect register space, before the actual PHY lane 2 registers. So the 17693433708SPali Rohár * offset is absolute, not relative to COMPHY_LANE2_REGS_BASE. 17793433708SPali Rohár * It is used only for SATA PHY initialization. 17893433708SPali Rohár */ 17993433708SPali Rohár #define COMPHY_RESERVED_REG 0x0E 18093433708SPali Rohár #define PHYCTRL_FRM_PIN_BIT BIT(13) 18193433708SPali Rohár 18293433708SPali Rohár /* South Bridge PHY Configuration Registers */ 18393433708SPali Rohár #define COMPHY_PHY_REG(lane, reg) (((1 - (lane)) * 0x28) + ((reg) & 0x3f)) 18493433708SPali Rohár 18593433708SPali Rohár /* 18693433708SPali Rohár * lane0: USB3/GbE1 PHY Configuration 1 18793433708SPali Rohár * lane1: PCIe/GbE0 PHY Configuration 1 18893433708SPali Rohár * (used only by SGMII code) 18993433708SPali Rohár */ 19093433708SPali Rohár #define COMPHY_PHY_CFG1 0x0 19193433708SPali Rohár #define PIN_PU_IVREF_BIT BIT(1) 19293433708SPali Rohár #define PIN_RESET_CORE_BIT BIT(11) 19393433708SPali Rohár #define PIN_RESET_COMPHY_BIT BIT(12) 19493433708SPali Rohár #define PIN_PU_PLL_BIT BIT(16) 19593433708SPali Rohár #define PIN_PU_RX_BIT BIT(17) 19693433708SPali Rohár #define PIN_PU_TX_BIT BIT(18) 19793433708SPali Rohár #define PIN_TX_IDLE_BIT BIT(19) 19893433708SPali Rohár #define GEN_RX_SEL_MASK GENMASK(25, 22) 19993433708SPali Rohár #define GEN_RX_SEL_VALUE(val) FIELD_PREP(GEN_RX_SEL_MASK, (val)) 20093433708SPali Rohár #define GEN_TX_SEL_MASK GENMASK(29, 26) 20193433708SPali Rohár #define GEN_TX_SEL_VALUE(val) FIELD_PREP(GEN_TX_SEL_MASK, (val)) 20293433708SPali Rohár #define SERDES_SPEED_1_25_G 0x6 20393433708SPali Rohár #define SERDES_SPEED_3_125_G 0x8 20493433708SPali Rohár #define PHY_RX_INIT_BIT BIT(30) 20593433708SPali Rohár 20693433708SPali Rohár /* 20793433708SPali Rohár * lane0: USB3/GbE1 PHY Status 1 20893433708SPali Rohár * lane1: PCIe/GbE0 PHY Status 1 20993433708SPali Rohár * (used only by SGMII code) 21093433708SPali Rohár */ 21193433708SPali Rohár #define COMPHY_PHY_STAT1 0x18 21293433708SPali Rohár #define PHY_RX_INIT_DONE_BIT BIT(0) 21393433708SPali Rohár #define PHY_PLL_READY_RX_BIT BIT(2) 21493433708SPali Rohár #define PHY_PLL_READY_TX_BIT BIT(3) 21593433708SPali Rohár 21693433708SPali Rohár /* PHY Selector */ 21793433708SPali Rohár #define COMPHY_SELECTOR_PHY_REG 0xFC 21893433708SPali Rohár /* bit0: 0: Lane1 is GbE0; 1: Lane1 is PCIe */ 21993433708SPali Rohár #define COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT BIT(0) 22093433708SPali Rohár /* bit4: 0: Lane0 is GbE1; 1: Lane0 is USB3 */ 22193433708SPali Rohár #define COMPHY_SELECTOR_USB3_GBE1_SEL_BIT BIT(4) 22293433708SPali Rohár /* bit8: 0: Lane0 is USB3 instead of GbE1, Lane2 is SATA; 1: Lane2 is USB3 */ 22393433708SPali Rohár #define COMPHY_SELECTOR_USB3_PHY_SEL_BIT BIT(8) 2249695375aSMiquel Raynal 2259695375aSMiquel Raynal struct mvebu_a3700_comphy_conf { 2269695375aSMiquel Raynal unsigned int lane; 2279695375aSMiquel Raynal enum phy_mode mode; 2289695375aSMiquel Raynal int submode; 2299695375aSMiquel Raynal }; 2309695375aSMiquel Raynal 23193433708SPali Rohár #define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode) \ 2329695375aSMiquel Raynal { \ 2339695375aSMiquel Raynal .lane = _lane, \ 2349695375aSMiquel Raynal .mode = _mode, \ 2359695375aSMiquel Raynal .submode = _smode, \ 2369695375aSMiquel Raynal } 2379695375aSMiquel Raynal 23893433708SPali Rohár #define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode) \ 23993433708SPali Rohár MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA) 2409695375aSMiquel Raynal 24193433708SPali Rohár #define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode) \ 24293433708SPali Rohár MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode) 2439695375aSMiquel Raynal 2449695375aSMiquel Raynal static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = { 2459695375aSMiquel Raynal /* lane 0 */ 24693433708SPali Rohár MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS), 24793433708SPali Rohár MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII), 24893433708SPali Rohár MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_1000BASEX), 24993433708SPali Rohár MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX), 2509695375aSMiquel Raynal /* lane 1 */ 25193433708SPali Rohár MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE), 25293433708SPali Rohár MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII), 25393433708SPali Rohár MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_1000BASEX), 25493433708SPali Rohár MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX), 2559695375aSMiquel Raynal /* lane 2 */ 25693433708SPali Rohár MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA), 25793433708SPali Rohár MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS), 25893433708SPali Rohár }; 25993433708SPali Rohár 26093433708SPali Rohár struct mvebu_a3700_comphy_priv { 26193433708SPali Rohár void __iomem *comphy_regs; 26293433708SPali Rohár void __iomem *lane0_phy_regs; /* USB3 and GbE1 */ 26393433708SPali Rohár void __iomem *lane1_phy_regs; /* PCIe and GbE0 */ 26493433708SPali Rohár void __iomem *lane2_phy_indirect; /* SATA and USB3 */ 26593433708SPali Rohár spinlock_t lock; /* for PHY selector access */ 26693433708SPali Rohár bool xtal_is_40m; 2679695375aSMiquel Raynal }; 2689695375aSMiquel Raynal 2699695375aSMiquel Raynal struct mvebu_a3700_comphy_lane { 27093433708SPali Rohár struct mvebu_a3700_comphy_priv *priv; 2719695375aSMiquel Raynal struct device *dev; 2729695375aSMiquel Raynal unsigned int id; 2739695375aSMiquel Raynal enum phy_mode mode; 2749695375aSMiquel Raynal int submode; 27593433708SPali Rohár bool invert_tx; 27693433708SPali Rohár bool invert_rx; 2779695375aSMiquel Raynal }; 2789695375aSMiquel Raynal 27993433708SPali Rohár struct gbe_phy_init_data_fix { 28093433708SPali Rohár u16 addr; 28193433708SPali Rohár u16 value; 28293433708SPali Rohár }; 28393433708SPali Rohár 28493433708SPali Rohár /* Changes to 40M1G25 mode data required for running 40M3G125 init mode */ 28593433708SPali Rohár static struct gbe_phy_init_data_fix gbe_phy_init_fix[] = { 28693433708SPali Rohár { 0x005, 0x07CC }, { 0x015, 0x0000 }, { 0x01B, 0x0000 }, 28793433708SPali Rohár { 0x01D, 0x0000 }, { 0x01E, 0x0000 }, { 0x01F, 0x0000 }, 28893433708SPali Rohár { 0x020, 0x0000 }, { 0x021, 0x0030 }, { 0x026, 0x0888 }, 28993433708SPali Rohár { 0x04D, 0x0152 }, { 0x04F, 0xA020 }, { 0x050, 0x07CC }, 29093433708SPali Rohár { 0x053, 0xE9CA }, { 0x055, 0xBD97 }, { 0x071, 0x3015 }, 29193433708SPali Rohár { 0x076, 0x03AA }, { 0x07C, 0x0FDF }, { 0x0C2, 0x3030 }, 29293433708SPali Rohár { 0x0C3, 0x8000 }, { 0x0E2, 0x5550 }, { 0x0E3, 0x12A4 }, 29393433708SPali Rohár { 0x0E4, 0x7D00 }, { 0x0E6, 0x0C83 }, { 0x101, 0xFCC0 }, 29493433708SPali Rohár { 0x104, 0x0C10 } 29593433708SPali Rohár }; 29693433708SPali Rohár 29793433708SPali Rohár /* 40M1G25 mode init data */ 29893433708SPali Rohár static u16 gbe_phy_init[512] = { 29993433708SPali Rohár /* 0 1 2 3 4 5 6 7 */ 30093433708SPali Rohár /*-----------------------------------------------------------*/ 30193433708SPali Rohár /* 8 9 A B C D E F */ 30293433708SPali Rohár 0x3110, 0xFD83, 0x6430, 0x412F, 0x82C0, 0x06FA, 0x4500, 0x6D26, /* 00 */ 30393433708SPali Rohár 0xAFC0, 0x8000, 0xC000, 0x0000, 0x2000, 0x49CC, 0x0BC9, 0x2A52, /* 08 */ 30493433708SPali Rohár 0x0BD2, 0x0CDE, 0x13D2, 0x0CE8, 0x1149, 0x10E0, 0x0000, 0x0000, /* 10 */ 30593433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x4134, 0x0D2D, 0xFFFF, /* 18 */ 30693433708SPali Rohár 0xFFE0, 0x4030, 0x1016, 0x0030, 0x0000, 0x0800, 0x0866, 0x0000, /* 20 */ 30793433708SPali Rohár 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, /* 28 */ 30893433708SPali Rohár 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 30 */ 30993433708SPali Rohár 0x0000, 0x0000, 0x000F, 0x6A62, 0x1988, 0x3100, 0x3100, 0x3100, /* 38 */ 31093433708SPali Rohár 0x3100, 0xA708, 0x2430, 0x0830, 0x1030, 0x4610, 0xFF00, 0xFF00, /* 40 */ 31193433708SPali Rohár 0x0060, 0x1000, 0x0400, 0x0040, 0x00F0, 0x0155, 0x1100, 0xA02A, /* 48 */ 31293433708SPali Rohár 0x06FA, 0x0080, 0xB008, 0xE3ED, 0x5002, 0xB592, 0x7A80, 0x0001, /* 50 */ 31393433708SPali Rohár 0x020A, 0x8820, 0x6014, 0x8054, 0xACAA, 0xFC88, 0x2A02, 0x45CF, /* 58 */ 31493433708SPali Rohár 0x000F, 0x1817, 0x2860, 0x064F, 0x0000, 0x0204, 0x1800, 0x6000, /* 60 */ 31593433708SPali Rohár 0x810F, 0x4F23, 0x4000, 0x4498, 0x0850, 0x0000, 0x000E, 0x1002, /* 68 */ 31693433708SPali Rohár 0x9D3A, 0x3009, 0xD066, 0x0491, 0x0001, 0x6AB0, 0x0399, 0x3780, /* 70 */ 31793433708SPali Rohár 0x0040, 0x5AC0, 0x4A80, 0x0000, 0x01DF, 0x0000, 0x0007, 0x0000, /* 78 */ 31893433708SPali Rohár 0x2D54, 0x00A1, 0x4000, 0x0100, 0xA20A, 0x0000, 0x0000, 0x0000, /* 80 */ 31993433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x7400, 0x0E81, 0x1000, 0x1242, 0x0210, /* 88 */ 32093433708SPali Rohár 0x80DF, 0x0F1F, 0x2F3F, 0x4F5F, 0x6F7F, 0x0F1F, 0x2F3F, 0x4F5F, /* 90 */ 32193433708SPali Rohár 0x6F7F, 0x4BAD, 0x0000, 0x0000, 0x0800, 0x0000, 0x2400, 0xB651, /* 98 */ 32293433708SPali Rohár 0xC9E0, 0x4247, 0x0A24, 0x0000, 0xAF19, 0x1004, 0x0000, 0x0000, /* A0 */ 32393433708SPali Rohár 0x0000, 0x0013, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* A8 */ 32493433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* B0 */ 32593433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0060, 0x0000, 0x0000, 0x0000, 0x0000, /* B8 */ 32693433708SPali Rohár 0x0000, 0x0000, 0x3010, 0xFA00, 0x0000, 0x0000, 0x0000, 0x0003, /* C0 */ 32793433708SPali Rohár 0x1618, 0x8200, 0x8000, 0x0400, 0x050F, 0x0000, 0x0000, 0x0000, /* C8 */ 32893433708SPali Rohár 0x4C93, 0x0000, 0x1000, 0x1120, 0x0010, 0x1242, 0x1242, 0x1E00, /* D0 */ 32993433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x00F8, 0x0000, 0x0041, 0x0800, 0x0000, /* D8 */ 33093433708SPali Rohár 0x82A0, 0x572E, 0x2490, 0x14A9, 0x4E00, 0x0000, 0x0803, 0x0541, /* E0 */ 33193433708SPali Rohár 0x0C15, 0x0000, 0x0000, 0x0400, 0x2626, 0x0000, 0x0000, 0x4200, /* E8 */ 33293433708SPali Rohár 0x0000, 0xAA55, 0x1020, 0x0000, 0x0000, 0x5010, 0x0000, 0x0000, /* F0 */ 33393433708SPali Rohár 0x0000, 0x0000, 0x5000, 0x0000, 0x0000, 0x0000, 0x02F2, 0x0000, /* F8 */ 33493433708SPali Rohár 0x101F, 0xFDC0, 0x4000, 0x8010, 0x0110, 0x0006, 0x0000, 0x0000, /*100 */ 33593433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*108 */ 33693433708SPali Rohár 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04C6, 0x0000, /*110 */ 33793433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*118 */ 33893433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*120 */ 33993433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*128 */ 34093433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*130 */ 34193433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*138 */ 34293433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*140 */ 34393433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*148 */ 34493433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*150 */ 34593433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*158 */ 34693433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*160 */ 34793433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*168 */ 34893433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*170 */ 34993433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x00F0, 0x08A2, 0x3112, 0x0A14, 0x0000, /*178 */ 35093433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*180 */ 35193433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*188 */ 35293433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*190 */ 35393433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*198 */ 35493433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A0 */ 35593433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A8 */ 35693433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B0 */ 35793433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B8 */ 35893433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C0 */ 35993433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C8 */ 36093433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D0 */ 36193433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D8 */ 36293433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E0 */ 36393433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E8 */ 36493433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1F0 */ 36593433708SPali Rohár 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /*1F8 */ 36693433708SPali Rohár }; 36793433708SPali Rohár 36893433708SPali Rohár static inline void comphy_reg_set(void __iomem *addr, u32 data, u32 mask) 3699695375aSMiquel Raynal { 37093433708SPali Rohár u32 val; 3719695375aSMiquel Raynal 37293433708SPali Rohár val = readl(addr); 37393433708SPali Rohár val = (val & ~mask) | (data & mask); 37493433708SPali Rohár writel(val, addr); 37593433708SPali Rohár } 3769695375aSMiquel Raynal 37793433708SPali Rohár static inline void comphy_reg_set16(void __iomem *addr, u16 data, u16 mask) 37893433708SPali Rohár { 37993433708SPali Rohár u16 val; 38093433708SPali Rohár 38193433708SPali Rohár val = readw(addr); 38293433708SPali Rohár val = (val & ~mask) | (data & mask); 38393433708SPali Rohár writew(val, addr); 38493433708SPali Rohár } 38593433708SPali Rohár 38693433708SPali Rohár /* Used for accessing lane 2 registers (SATA/USB3 PHY) */ 38793433708SPali Rohár static void comphy_set_indirect(struct mvebu_a3700_comphy_priv *priv, 38893433708SPali Rohár u32 offset, u16 data, u16 mask) 38993433708SPali Rohár { 39093433708SPali Rohár writel(offset, 39193433708SPali Rohár priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_ADDR); 39293433708SPali Rohár comphy_reg_set(priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_DATA, 39393433708SPali Rohár data, mask); 39493433708SPali Rohár } 39593433708SPali Rohár 39693433708SPali Rohár static void comphy_lane_reg_set(struct mvebu_a3700_comphy_lane *lane, 39793433708SPali Rohár u16 reg, u16 data, u16 mask) 39893433708SPali Rohár { 39993433708SPali Rohár if (lane->id == 2) { 40093433708SPali Rohár /* lane 2 PHY registers are accessed indirectly */ 40193433708SPali Rohár comphy_set_indirect(lane->priv, 40293433708SPali Rohár reg + COMPHY_LANE2_REGS_BASE, 40393433708SPali Rohár data, mask); 40493433708SPali Rohár } else { 40593433708SPali Rohár void __iomem *base = lane->id == 1 ? 40693433708SPali Rohár lane->priv->lane1_phy_regs : 40793433708SPali Rohár lane->priv->lane0_phy_regs; 40893433708SPali Rohár 40993433708SPali Rohár comphy_reg_set16(base + COMPHY_LANE_REG_DIRECT(reg), 41093433708SPali Rohár data, mask); 41193433708SPali Rohár } 41293433708SPali Rohár } 41393433708SPali Rohár 41493433708SPali Rohár static int comphy_lane_reg_poll(struct mvebu_a3700_comphy_lane *lane, 41593433708SPali Rohár u16 reg, u16 bits, 41693433708SPali Rohár ulong sleep_us, ulong timeout_us) 41793433708SPali Rohár { 41893433708SPali Rohár int ret; 41993433708SPali Rohár 42093433708SPali Rohár if (lane->id == 2) { 42193433708SPali Rohár u32 data; 42293433708SPali Rohár 42393433708SPali Rohár /* lane 2 PHY registers are accessed indirectly */ 42493433708SPali Rohár writel(reg + COMPHY_LANE2_REGS_BASE, 42593433708SPali Rohár lane->priv->lane2_phy_indirect + 42693433708SPali Rohár COMPHY_LANE2_INDIR_ADDR); 42793433708SPali Rohár 42893433708SPali Rohár ret = readl_poll_timeout(lane->priv->lane2_phy_indirect + 42993433708SPali Rohár COMPHY_LANE2_INDIR_DATA, 43093433708SPali Rohár data, (data & bits) == bits, 43193433708SPali Rohár sleep_us, timeout_us); 43293433708SPali Rohár } else { 43393433708SPali Rohár void __iomem *base = lane->id == 1 ? 43493433708SPali Rohár lane->priv->lane1_phy_regs : 43593433708SPali Rohár lane->priv->lane0_phy_regs; 43693433708SPali Rohár u16 data; 43793433708SPali Rohár 43893433708SPali Rohár ret = readw_poll_timeout(base + COMPHY_LANE_REG_DIRECT(reg), 43993433708SPali Rohár data, (data & bits) == bits, 44093433708SPali Rohár sleep_us, timeout_us); 44193433708SPali Rohár } 44293433708SPali Rohár 44393433708SPali Rohár return ret; 44493433708SPali Rohár } 44593433708SPali Rohár 44693433708SPali Rohár static void comphy_periph_reg_set(struct mvebu_a3700_comphy_lane *lane, 44793433708SPali Rohár u8 reg, u32 data, u32 mask) 44893433708SPali Rohár { 44993433708SPali Rohár comphy_reg_set(lane->priv->comphy_regs + COMPHY_PHY_REG(lane->id, reg), 45093433708SPali Rohár data, mask); 45193433708SPali Rohár } 45293433708SPali Rohár 45393433708SPali Rohár static int comphy_periph_reg_poll(struct mvebu_a3700_comphy_lane *lane, 45493433708SPali Rohár u8 reg, u32 bits, 45593433708SPali Rohár ulong sleep_us, ulong timeout_us) 45693433708SPali Rohár { 45793433708SPali Rohár u32 data; 45893433708SPali Rohár 45993433708SPali Rohár return readl_poll_timeout(lane->priv->comphy_regs + 46093433708SPali Rohár COMPHY_PHY_REG(lane->id, reg), 46193433708SPali Rohár data, (data & bits) == bits, 46293433708SPali Rohár sleep_us, timeout_us); 46393433708SPali Rohár } 46493433708SPali Rohár 46593433708SPali Rohár /* PHY selector configures with corresponding modes */ 46693433708SPali Rohár static int 46793433708SPali Rohár mvebu_a3700_comphy_set_phy_selector(struct mvebu_a3700_comphy_lane *lane) 46893433708SPali Rohár { 46993433708SPali Rohár u32 old, new, clr = 0, set = 0; 47093433708SPali Rohár unsigned long flags; 47193433708SPali Rohár 47293433708SPali Rohár switch (lane->mode) { 47393433708SPali Rohár case PHY_MODE_SATA: 47493433708SPali Rohár /* SATA must be in Lane2 */ 47593433708SPali Rohár if (lane->id == 2) 47693433708SPali Rohár clr = COMPHY_SELECTOR_USB3_PHY_SEL_BIT; 47793433708SPali Rohár else 47893433708SPali Rohár goto error; 47993433708SPali Rohár break; 48093433708SPali Rohár 48193433708SPali Rohár case PHY_MODE_ETHERNET: 48293433708SPali Rohár if (lane->id == 0) 48393433708SPali Rohár clr = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT; 48493433708SPali Rohár else if (lane->id == 1) 48593433708SPali Rohár clr = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT; 48693433708SPali Rohár else 48793433708SPali Rohár goto error; 48893433708SPali Rohár break; 48993433708SPali Rohár 49093433708SPali Rohár case PHY_MODE_USB_HOST_SS: 49193433708SPali Rohár if (lane->id == 2) 49293433708SPali Rohár set = COMPHY_SELECTOR_USB3_PHY_SEL_BIT; 49393433708SPali Rohár else if (lane->id == 0) 49493433708SPali Rohár set = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT; 49593433708SPali Rohár else 49693433708SPali Rohár goto error; 49793433708SPali Rohár break; 49893433708SPali Rohár 49993433708SPali Rohár case PHY_MODE_PCIE: 50093433708SPali Rohár /* PCIE must be in Lane1 */ 50193433708SPali Rohár if (lane->id == 1) 50293433708SPali Rohár set = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT; 50393433708SPali Rohár else 50493433708SPali Rohár goto error; 50593433708SPali Rohár break; 50693433708SPali Rohár 507ea17a0f1SPali Rohár default: 50893433708SPali Rohár goto error; 50993433708SPali Rohár } 51093433708SPali Rohár 51193433708SPali Rohár spin_lock_irqsave(&lane->priv->lock, flags); 51293433708SPali Rohár 51393433708SPali Rohár old = readl(lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG); 51493433708SPali Rohár new = (old & ~clr) | set; 51593433708SPali Rohár writel(new, lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG); 51693433708SPali Rohár 51793433708SPali Rohár spin_unlock_irqrestore(&lane->priv->lock, flags); 51893433708SPali Rohár 51993433708SPali Rohár dev_dbg(lane->dev, 52093433708SPali Rohár "COMPHY[%d] mode[%d] changed PHY selector 0x%08x -> 0x%08x\n", 52193433708SPali Rohár lane->id, lane->mode, old, new); 52293433708SPali Rohár 52393433708SPali Rohár return 0; 52493433708SPali Rohár error: 52593433708SPali Rohár dev_err(lane->dev, "COMPHY[%d] mode[%d] is invalid\n", lane->id, 52693433708SPali Rohár lane->mode); 527ea17a0f1SPali Rohár return -EINVAL; 528ea17a0f1SPali Rohár } 52993433708SPali Rohár 53093433708SPali Rohár static int 53193433708SPali Rohár mvebu_a3700_comphy_sata_power_on(struct mvebu_a3700_comphy_lane *lane) 53293433708SPali Rohár { 53393433708SPali Rohár u32 mask, data, ref_clk; 53493433708SPali Rohár int ret; 53593433708SPali Rohár 53693433708SPali Rohár /* Configure phy selector for SATA */ 53793433708SPali Rohár ret = mvebu_a3700_comphy_set_phy_selector(lane); 53893433708SPali Rohár if (ret) 53993433708SPali Rohár return ret; 54093433708SPali Rohár 54193433708SPali Rohár /* Clear phy isolation mode to make it work in normal mode */ 54293433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL, 54393433708SPali Rohár 0x0, PHY_ISOLATE_MODE); 54493433708SPali Rohár 54593433708SPali Rohár /* 0. Check the Polarity invert bits */ 54693433708SPali Rohár data = 0x0; 54793433708SPali Rohár if (lane->invert_tx) 54893433708SPali Rohár data |= TXD_INVERT_BIT; 54993433708SPali Rohár if (lane->invert_rx) 55093433708SPali Rohár data |= RXD_INVERT_BIT; 55193433708SPali Rohár mask = TXD_INVERT_BIT | RXD_INVERT_BIT; 55293433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); 55393433708SPali Rohár 55493433708SPali Rohár /* 1. Select 40-bit data width */ 55593433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, 55693433708SPali Rohár DATA_WIDTH_40BIT, SEL_DATA_WIDTH_MASK); 55793433708SPali Rohár 55893433708SPali Rohár /* 2. Select reference clock(25M) and PHY mode (SATA) */ 55993433708SPali Rohár if (lane->priv->xtal_is_40m) 56093433708SPali Rohár ref_clk = REF_FREF_SEL_SERDES_40MHZ; 56193433708SPali Rohár else 56293433708SPali Rohár ref_clk = REF_FREF_SEL_SERDES_25MHZ; 56393433708SPali Rohár 56493433708SPali Rohár data = ref_clk | COMPHY_MODE_SATA; 56593433708SPali Rohár mask = REF_FREF_SEL_MASK | COMPHY_MODE_MASK; 56693433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); 56793433708SPali Rohár 56893433708SPali Rohár /* 3. Use maximum PLL rate (no power save) */ 56993433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, 57093433708SPali Rohár USE_MAX_PLL_RATE_BIT, USE_MAX_PLL_RATE_BIT); 57193433708SPali Rohár 57293433708SPali Rohár /* 4. Reset reserved bit */ 57393433708SPali Rohár comphy_set_indirect(lane->priv, COMPHY_RESERVED_REG, 57493433708SPali Rohár 0x0, PHYCTRL_FRM_PIN_BIT); 57593433708SPali Rohár 57693433708SPali Rohár /* 5. Set vendor-specific configuration (It is done in sata driver) */ 57793433708SPali Rohár /* XXX: in U-Boot below sequence was executed in this place, in Linux 57893433708SPali Rohár * not. Now it is done only in U-Boot before this comphy 57993433708SPali Rohár * initialization - tests shows that it works ok, but in case of any 58093433708SPali Rohár * future problem it is left for reference. 58193433708SPali Rohár * reg_set(MVEBU_REGS_BASE + 0xe00a0, 0, 0xffffffff); 58293433708SPali Rohár * reg_set(MVEBU_REGS_BASE + 0xe00a4, BIT(6), BIT(6)); 58393433708SPali Rohár */ 58493433708SPali Rohár 58593433708SPali Rohár /* Wait for > 55 us to allow PLL be enabled */ 58693433708SPali Rohár udelay(PLL_SET_DELAY_US); 58793433708SPali Rohár 58893433708SPali Rohár /* Polling status */ 58993433708SPali Rohár ret = comphy_lane_reg_poll(lane, COMPHY_DIG_LOOPBACK_EN, 59093433708SPali Rohár PLL_READY_TX_BIT, COMPHY_PLL_SLEEP, 59193433708SPali Rohár COMPHY_PLL_TIMEOUT); 59293433708SPali Rohár if (ret) 59393433708SPali Rohár dev_err(lane->dev, "Failed to lock SATA PLL\n"); 59493433708SPali Rohár 59593433708SPali Rohár return ret; 5969695375aSMiquel Raynal } 5979695375aSMiquel Raynal 59893433708SPali Rohár static void comphy_gbe_phy_init(struct mvebu_a3700_comphy_lane *lane, 59993433708SPali Rohár bool is_1gbps) 60093433708SPali Rohár { 60193433708SPali Rohár int addr, fix_idx; 60293433708SPali Rohár u16 val; 60393433708SPali Rohár 60493433708SPali Rohár fix_idx = 0; 60593433708SPali Rohár for (addr = 0; addr < 512; addr++) { 60693433708SPali Rohár /* 60793433708SPali Rohár * All PHY register values are defined in full for 3.125Gbps 60893433708SPali Rohár * SERDES speed. The values required for 1.25 Gbps are almost 60993433708SPali Rohár * the same and only few registers should be "fixed" in 61093433708SPali Rohár * comparison to 3.125 Gbps values. These register values are 61193433708SPali Rohár * stored in "gbe_phy_init_fix" array. 61293433708SPali Rohár */ 61393433708SPali Rohár if (!is_1gbps && gbe_phy_init_fix[fix_idx].addr == addr) { 61493433708SPali Rohár /* Use new value */ 61593433708SPali Rohár val = gbe_phy_init_fix[fix_idx].value; 61693433708SPali Rohár if (fix_idx < ARRAY_SIZE(gbe_phy_init_fix)) 61793433708SPali Rohár fix_idx++; 61893433708SPali Rohár } else { 61993433708SPali Rohár val = gbe_phy_init[addr]; 62093433708SPali Rohár } 62193433708SPali Rohár 62293433708SPali Rohár comphy_lane_reg_set(lane, addr, val, 0xFFFF); 62393433708SPali Rohár } 62493433708SPali Rohár } 62593433708SPali Rohár 62693433708SPali Rohár static int 62793433708SPali Rohár mvebu_a3700_comphy_ethernet_power_on(struct mvebu_a3700_comphy_lane *lane) 62893433708SPali Rohár { 62993433708SPali Rohár u32 mask, data, speed_sel; 63093433708SPali Rohár int ret; 63193433708SPali Rohár 63293433708SPali Rohár /* Set selector */ 63393433708SPali Rohár ret = mvebu_a3700_comphy_set_phy_selector(lane); 63493433708SPali Rohár if (ret) 63593433708SPali Rohár return ret; 63693433708SPali Rohár 63793433708SPali Rohár /* 63893433708SPali Rohár * 1. Reset PHY by setting PHY input port PIN_RESET=1. 63993433708SPali Rohár * 2. Set PHY input port PIN_TX_IDLE=1, PIN_PU_IVREF=1 to keep 64093433708SPali Rohár * PHY TXP/TXN output to idle state during PHY initialization 64193433708SPali Rohár * 3. Set PHY input port PIN_PU_PLL=0, PIN_PU_RX=0, PIN_PU_TX=0. 64293433708SPali Rohár */ 64393433708SPali Rohár data = PIN_PU_IVREF_BIT | PIN_TX_IDLE_BIT | PIN_RESET_COMPHY_BIT; 64493433708SPali Rohár mask = data | PIN_RESET_CORE_BIT | PIN_PU_PLL_BIT | PIN_PU_RX_BIT | 64593433708SPali Rohár PIN_PU_TX_BIT | PHY_RX_INIT_BIT; 64693433708SPali Rohár comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); 64793433708SPali Rohár 64893433708SPali Rohár /* 4. Release reset to the PHY by setting PIN_RESET=0. */ 64993433708SPali Rohár data = 0x0; 65093433708SPali Rohár mask = PIN_RESET_COMPHY_BIT; 65193433708SPali Rohár comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); 65293433708SPali Rohár 65393433708SPali Rohár /* 65493433708SPali Rohár * 5. Set PIN_PHY_GEN_TX[3:0] and PIN_PHY_GEN_RX[3:0] to decide COMPHY 65593433708SPali Rohár * bit rate 65693433708SPali Rohár */ 65793433708SPali Rohár switch (lane->submode) { 65893433708SPali Rohár case PHY_INTERFACE_MODE_SGMII: 65993433708SPali Rohár case PHY_INTERFACE_MODE_1000BASEX: 66093433708SPali Rohár /* SGMII 1G, SerDes speed 1.25G */ 66193433708SPali Rohár speed_sel = SERDES_SPEED_1_25_G; 66293433708SPali Rohár break; 66393433708SPali Rohár case PHY_INTERFACE_MODE_2500BASEX: 66493433708SPali Rohár /* 2500Base-X, SerDes speed 3.125G */ 66593433708SPali Rohár speed_sel = SERDES_SPEED_3_125_G; 66693433708SPali Rohár break; 66793433708SPali Rohár default: 66893433708SPali Rohár /* Other rates are not supported */ 66993433708SPali Rohár dev_err(lane->dev, 67093433708SPali Rohár "unsupported phy speed %d on comphy lane%d\n", 67193433708SPali Rohár lane->submode, lane->id); 67293433708SPali Rohár return -EINVAL; 67393433708SPali Rohár } 67493433708SPali Rohár data = GEN_RX_SEL_VALUE(speed_sel) | GEN_TX_SEL_VALUE(speed_sel); 67593433708SPali Rohár mask = GEN_RX_SEL_MASK | GEN_TX_SEL_MASK; 67693433708SPali Rohár comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); 67793433708SPali Rohár 67893433708SPali Rohár /* 67993433708SPali Rohár * 6. Wait 10mS for bandgap and reference clocks to stabilize; then 68093433708SPali Rohár * start SW programming. 68193433708SPali Rohár */ 68293433708SPali Rohár mdelay(10); 68393433708SPali Rohár 68493433708SPali Rohár /* 7. Program COMPHY register PHY_MODE */ 68593433708SPali Rohár data = COMPHY_MODE_SERDES; 68693433708SPali Rohár mask = COMPHY_MODE_MASK; 68793433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); 68893433708SPali Rohár 68993433708SPali Rohár /* 69093433708SPali Rohár * 8. Set COMPHY register REFCLK_SEL to select the correct REFCLK 69193433708SPali Rohár * source 69293433708SPali Rohár */ 69393433708SPali Rohár data = 0x0; 69493433708SPali Rohár mask = PHY_REF_CLK_SEL; 69593433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask); 69693433708SPali Rohár 69793433708SPali Rohár /* 69893433708SPali Rohár * 9. Set correct reference clock frequency in COMPHY register 69993433708SPali Rohár * REF_FREF_SEL. 70093433708SPali Rohár */ 70193433708SPali Rohár if (lane->priv->xtal_is_40m) 70293433708SPali Rohár data = REF_FREF_SEL_SERDES_50MHZ; 70393433708SPali Rohár else 70493433708SPali Rohár data = REF_FREF_SEL_SERDES_25MHZ; 70593433708SPali Rohár 70693433708SPali Rohár mask = REF_FREF_SEL_MASK; 70793433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); 70893433708SPali Rohár 70993433708SPali Rohár /* 71093433708SPali Rohár * 10. Program COMPHY register PHY_GEN_MAX[1:0] 71193433708SPali Rohár * This step is mentioned in the flow received from verification team. 71293433708SPali Rohár * However the PHY_GEN_MAX value is only meaningful for other interfaces 71393433708SPali Rohár * (not SERDES). For instance, it selects SATA speed 1.5/3/6 Gbps or 71493433708SPali Rohár * PCIe speed 2.5/5 Gbps 71593433708SPali Rohár */ 71693433708SPali Rohár 71793433708SPali Rohár /* 71893433708SPali Rohár * 11. Program COMPHY register SEL_BITS to set correct parallel data 71993433708SPali Rohár * bus width 72093433708SPali Rohár */ 72193433708SPali Rohár data = DATA_WIDTH_10BIT; 72293433708SPali Rohár mask = SEL_DATA_WIDTH_MASK; 72393433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, data, mask); 72493433708SPali Rohár 72593433708SPali Rohár /* 72693433708SPali Rohár * 12. As long as DFE function needs to be enabled in any mode, 72793433708SPali Rohár * COMPHY register DFE_UPDATE_EN[5:0] shall be programmed to 0x3F 72893433708SPali Rohár * for real chip during COMPHY power on. 72993433708SPali Rohár * The value of the DFE_UPDATE_EN already is 0x3F, because it is the 73093433708SPali Rohár * default value after reset of the PHY. 73193433708SPali Rohár */ 73293433708SPali Rohár 73393433708SPali Rohár /* 73493433708SPali Rohár * 13. Program COMPHY GEN registers. 73593433708SPali Rohár * These registers should be programmed based on the lab testing result 73693433708SPali Rohár * to achieve optimal performance. Please contact the CEA group to get 73793433708SPali Rohár * the related GEN table during real chip bring-up. We only required to 73893433708SPali Rohár * run though the entire registers programming flow defined by 73993433708SPali Rohár * "comphy_gbe_phy_init" when the REF clock is 40 MHz. For REF clock 74093433708SPali Rohár * 25 MHz the default values stored in PHY registers are OK. 74193433708SPali Rohár */ 74293433708SPali Rohár dev_dbg(lane->dev, "Running C-DPI phy init %s mode\n", 74393433708SPali Rohár lane->submode == PHY_INTERFACE_MODE_2500BASEX ? "2G5" : "1G"); 74493433708SPali Rohár if (lane->priv->xtal_is_40m) 74593433708SPali Rohár comphy_gbe_phy_init(lane, 74693433708SPali Rohár lane->submode != PHY_INTERFACE_MODE_2500BASEX); 74793433708SPali Rohár 74893433708SPali Rohár /* 74993433708SPali Rohár * 14. Check the PHY Polarity invert bit 75093433708SPali Rohár */ 75193433708SPali Rohár data = 0x0; 75293433708SPali Rohár if (lane->invert_tx) 75393433708SPali Rohár data |= TXD_INVERT_BIT; 75493433708SPali Rohár if (lane->invert_rx) 75593433708SPali Rohár data |= RXD_INVERT_BIT; 75693433708SPali Rohár mask = TXD_INVERT_BIT | RXD_INVERT_BIT; 75793433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); 75893433708SPali Rohár 75993433708SPali Rohár /* 76093433708SPali Rohár * 15. Set PHY input ports PIN_PU_PLL, PIN_PU_TX and PIN_PU_RX to 1 to 76193433708SPali Rohár * start PHY power up sequence. All the PHY register programming should 76293433708SPali Rohár * be done before PIN_PU_PLL=1. There should be no register programming 76393433708SPali Rohár * for normal PHY operation from this point. 76493433708SPali Rohár */ 76593433708SPali Rohár data = PIN_PU_PLL_BIT | PIN_PU_RX_BIT | PIN_PU_TX_BIT; 76693433708SPali Rohár mask = data; 76793433708SPali Rohár comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); 76893433708SPali Rohár 76993433708SPali Rohár /* 77093433708SPali Rohár * 16. Wait for PHY power up sequence to finish by checking output ports 77193433708SPali Rohár * PIN_PLL_READY_TX=1 and PIN_PLL_READY_RX=1. 77293433708SPali Rohár */ 77393433708SPali Rohár ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1, 77493433708SPali Rohár PHY_PLL_READY_TX_BIT | 77593433708SPali Rohár PHY_PLL_READY_RX_BIT, 77693433708SPali Rohár COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); 77793433708SPali Rohár if (ret) { 77893433708SPali Rohár dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n", 77993433708SPali Rohár lane->id); 78093433708SPali Rohár return ret; 78193433708SPali Rohár } 78293433708SPali Rohár 78393433708SPali Rohár /* 78493433708SPali Rohár * 17. Set COMPHY input port PIN_TX_IDLE=0 78593433708SPali Rohár */ 78693433708SPali Rohár comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, 0x0, PIN_TX_IDLE_BIT); 78793433708SPali Rohár 78893433708SPali Rohár /* 78993433708SPali Rohár * 18. After valid data appear on PIN_RXDATA bus, set PIN_RX_INIT=1. To 79093433708SPali Rohár * start RX initialization. PIN_RX_INIT_DONE will be cleared to 0 by the 79193433708SPali Rohár * PHY After RX initialization is done, PIN_RX_INIT_DONE will be set to 79293433708SPali Rohár * 1 by COMPHY Set PIN_RX_INIT=0 after PIN_RX_INIT_DONE= 1. Please 79393433708SPali Rohár * refer to RX initialization part for details. 79493433708SPali Rohár */ 79593433708SPali Rohár comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, 79693433708SPali Rohár PHY_RX_INIT_BIT, PHY_RX_INIT_BIT); 79793433708SPali Rohár 79893433708SPali Rohár ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1, 79993433708SPali Rohár PHY_PLL_READY_TX_BIT | 80093433708SPali Rohár PHY_PLL_READY_RX_BIT, 80193433708SPali Rohár COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); 80293433708SPali Rohár if (ret) { 80393433708SPali Rohár dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n", 80493433708SPali Rohár lane->id); 80593433708SPali Rohár return ret; 80693433708SPali Rohár } 80793433708SPali Rohár 80893433708SPali Rohár ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1, 80993433708SPali Rohár PHY_RX_INIT_DONE_BIT, 81093433708SPali Rohár COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); 81193433708SPali Rohár if (ret) 81293433708SPali Rohár dev_err(lane->dev, "Failed to init RX of SERDES PHY %d\n", 81393433708SPali Rohár lane->id); 81493433708SPali Rohár 81593433708SPali Rohár return ret; 81693433708SPali Rohár } 81793433708SPali Rohár 81893433708SPali Rohár static int 81993433708SPali Rohár mvebu_a3700_comphy_usb3_power_on(struct mvebu_a3700_comphy_lane *lane) 82093433708SPali Rohár { 82193433708SPali Rohár u32 mask, data, cfg, ref_clk; 82293433708SPali Rohár int ret; 82393433708SPali Rohár 82493433708SPali Rohár /* Set phy seclector */ 82593433708SPali Rohár ret = mvebu_a3700_comphy_set_phy_selector(lane); 82693433708SPali Rohár if (ret) 82793433708SPali Rohár return ret; 82893433708SPali Rohár 829*b01d622dSPali Rohár /* COMPHY register reset (cleared automatically) */ 830*b01d622dSPali Rohár comphy_lane_reg_set(lane, COMPHY_SFT_RESET, SFT_RST, SFT_RST); 831*b01d622dSPali Rohár 83293433708SPali Rohár /* 83393433708SPali Rohár * 0. Set PHY OTG Control(0x5d034), bit 4, Power up OTG module The 83493433708SPali Rohár * register belong to UTMI module, so it is set in UTMI phy driver. 83593433708SPali Rohár */ 83693433708SPali Rohár 83793433708SPali Rohár /* 83893433708SPali Rohár * 1. Set PRD_TXDEEMPH (3.5db de-emph) 83993433708SPali Rohár */ 84093433708SPali Rohár data = PRD_TXDEEMPH0_MASK; 84193433708SPali Rohár mask = PRD_TXDEEMPH0_MASK | PRD_TXMARGIN_MASK | PRD_TXSWING_MASK | 84293433708SPali Rohár CFG_TX_ALIGN_POS_MASK; 84393433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG0, data, mask); 84493433708SPali Rohár 84593433708SPali Rohár /* 84693433708SPali Rohár * 2. Set BIT0: enable transmitter in high impedance mode 84793433708SPali Rohár * Set BIT[3:4]: delay 2 clock cycles for HiZ off latency 84893433708SPali Rohár * Set BIT6: Tx detect Rx at HiZ mode 84993433708SPali Rohár * Unset BIT15: set to 0 to set USB3 De-emphasize level to -3.5db 85093433708SPali Rohár * together with bit 0 of COMPHY_PIPE_LANE_CFG0 register 85193433708SPali Rohár */ 85293433708SPali Rohár data = TX_DET_RX_MODE | GEN2_TX_DATA_DLY_DEFT | TX_ELEC_IDLE_MODE_EN; 85393433708SPali Rohár mask = PRD_TXDEEMPH1_MASK | TX_DET_RX_MODE | GEN2_TX_DATA_DLY_MASK | 85493433708SPali Rohár TX_ELEC_IDLE_MODE_EN; 85593433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1, data, mask); 85693433708SPali Rohár 85793433708SPali Rohár /* 85893433708SPali Rohár * 3. Set Spread Spectrum Clock Enabled 85993433708SPali Rohár */ 86093433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG4, 86193433708SPali Rohár SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN); 86293433708SPali Rohár 86393433708SPali Rohár /* 86493433708SPali Rohár * 4. Set Override Margining Controls From the MAC: 86593433708SPali Rohár * Use margining signals from lane configuration 86693433708SPali Rohár */ 86793433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_PIPE_TEST_MODE_CTRL, 86893433708SPali Rohár MODE_MARGIN_OVERRIDE, 0xFFFF); 86993433708SPali Rohár 87093433708SPali Rohár /* 87193433708SPali Rohár * 5. Set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles 87293433708SPali Rohár * set Mode Clock Source = PCLK is generated from REFCLK 87393433708SPali Rohár */ 87493433708SPali Rohár data = 0x0; 87593433708SPali Rohár mask = MODE_CLK_SRC | BUNDLE_PERIOD_SEL | BUNDLE_PERIOD_SCALE_MASK | 87693433708SPali Rohár BUNDLE_SAMPLE_CTRL | PLL_READY_DLY_MASK; 87793433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO, data, mask); 87893433708SPali Rohár 87993433708SPali Rohár /* 88093433708SPali Rohár * 6. Set G2 Spread Spectrum Clock Amplitude at 4K 88193433708SPali Rohár */ 88293433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_GEN2_SET2, 88393433708SPali Rohár GS2_TX_SSC_AMP_4128, GS2_TX_SSC_AMP_MASK); 88493433708SPali Rohár 88593433708SPali Rohár /* 88693433708SPali Rohár * 7. Unset G3 Spread Spectrum Clock Amplitude 88793433708SPali Rohár * set G3 TX and RX Register Master Current Select 88893433708SPali Rohár */ 88993433708SPali Rohár data = GS2_VREG_RXTX_MAS_ISET_60U; 89093433708SPali Rohár mask = GS2_TX_SSC_AMP_MASK | GS2_VREG_RXTX_MAS_ISET_MASK | 89193433708SPali Rohár GS2_RSVD_6_0_MASK; 89293433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_GEN3_SET2, data, mask); 89393433708SPali Rohár 89493433708SPali Rohár /* 89593433708SPali Rohár * 8. Check crystal jumper setting and program the Power and PLL Control 89693433708SPali Rohár * accordingly Change RX wait 89793433708SPali Rohár */ 89893433708SPali Rohár if (lane->priv->xtal_is_40m) { 89993433708SPali Rohár ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ; 90093433708SPali Rohár cfg = CFG_PM_RXDLOZ_WAIT_12_UNIT; 90193433708SPali Rohár } else { 90293433708SPali Rohár ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ; 90393433708SPali Rohár cfg = CFG_PM_RXDLOZ_WAIT_7_UNIT; 90493433708SPali Rohár } 90593433708SPali Rohár 90693433708SPali Rohár data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT | 90793433708SPali Rohár PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_USB3 | ref_clk; 90893433708SPali Rohár mask = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT | 90993433708SPali Rohár PU_TX_INTP_BIT | PU_DFE_BIT | PLL_LOCK_BIT | COMPHY_MODE_MASK | 91093433708SPali Rohár REF_FREF_SEL_MASK; 91193433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); 91293433708SPali Rohár 91393433708SPali Rohár data = CFG_PM_RXDEN_WAIT_1_UNIT | cfg; 91493433708SPali Rohár mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK | 91593433708SPali Rohár CFG_PM_RXDLOZ_WAIT_MASK; 91693433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask); 91793433708SPali Rohár 91893433708SPali Rohár /* 91993433708SPali Rohár * 9. Enable idle sync 92093433708SPali Rohár */ 92193433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN, 92293433708SPali Rohár IDLE_SYNC_EN, IDLE_SYNC_EN); 92393433708SPali Rohár 92493433708SPali Rohár /* 92593433708SPali Rohár * 10. Enable the output of 500M clock 92693433708SPali Rohár */ 92793433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, CLK500M_EN, CLK500M_EN); 92893433708SPali Rohár 92993433708SPali Rohár /* 93093433708SPali Rohár * 11. Set 20-bit data width 93193433708SPali Rohár */ 93293433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, 93393433708SPali Rohár DATA_WIDTH_20BIT, 0xFFFF); 93493433708SPali Rohár 93593433708SPali Rohár /* 93693433708SPali Rohár * 12. Override Speed_PLL value and use MAC PLL 93793433708SPali Rohár */ 93893433708SPali Rohár data = SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT; 93993433708SPali Rohár mask = 0xFFFF; 94093433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, data, mask); 94193433708SPali Rohár 94293433708SPali Rohár /* 94393433708SPali Rohár * 13. Check the Polarity invert bit 94493433708SPali Rohár */ 94593433708SPali Rohár data = 0x0; 94693433708SPali Rohár if (lane->invert_tx) 94793433708SPali Rohár data |= TXD_INVERT_BIT; 94893433708SPali Rohár if (lane->invert_rx) 94993433708SPali Rohár data |= RXD_INVERT_BIT; 95093433708SPali Rohár mask = TXD_INVERT_BIT | RXD_INVERT_BIT; 95193433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); 95293433708SPali Rohár 95393433708SPali Rohár /* 95493433708SPali Rohár * 14. Set max speed generation to USB3.0 5Gbps 95593433708SPali Rohár */ 95693433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_SYNC_MASK_GEN, 95793433708SPali Rohár PHY_GEN_MAX_USB3_5G, PHY_GEN_MAX_MASK); 95893433708SPali Rohár 95993433708SPali Rohár /* 96093433708SPali Rohár * 15. Set capacitor value for FFE gain peaking to 0xF 96193433708SPali Rohár */ 96293433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_GEN2_SET3, 96393433708SPali Rohár GS3_FFE_CAP_SEL_VALUE, GS3_FFE_CAP_SEL_MASK); 96493433708SPali Rohár 96593433708SPali Rohár /* 96693433708SPali Rohár * 16. Release SW reset 96793433708SPali Rohár */ 96893433708SPali Rohár data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32 | MODE_REFDIV_BY_4; 96993433708SPali Rohár mask = 0xFFFF; 97093433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask); 97193433708SPali Rohár 97293433708SPali Rohár /* Wait for > 55 us to allow PCLK be enabled */ 97393433708SPali Rohár udelay(PLL_SET_DELAY_US); 97493433708SPali Rohár 97593433708SPali Rohár ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN, 97693433708SPali Rohár COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); 97793433708SPali Rohár if (ret) 97893433708SPali Rohár dev_err(lane->dev, "Failed to lock USB3 PLL\n"); 97993433708SPali Rohár 98093433708SPali Rohár return ret; 98193433708SPali Rohár } 98293433708SPali Rohár 98393433708SPali Rohár static int 98493433708SPali Rohár mvebu_a3700_comphy_pcie_power_on(struct mvebu_a3700_comphy_lane *lane) 98593433708SPali Rohár { 98693433708SPali Rohár u32 mask, data, ref_clk; 98793433708SPali Rohár int ret; 98893433708SPali Rohár 98993433708SPali Rohár /* Configure phy selector for PCIe */ 99093433708SPali Rohár ret = mvebu_a3700_comphy_set_phy_selector(lane); 99193433708SPali Rohár if (ret) 99293433708SPali Rohár return ret; 99393433708SPali Rohár 99493433708SPali Rohár /* 1. Enable max PLL. */ 99593433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1, 99693433708SPali Rohár USE_MAX_PLL_RATE_EN, USE_MAX_PLL_RATE_EN); 99793433708SPali Rohár 99893433708SPali Rohár /* 2. Select 20 bit SERDES interface. */ 99993433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO, 100093433708SPali Rohár CFG_SEL_20B, CFG_SEL_20B); 100193433708SPali Rohár 100293433708SPali Rohár /* 3. Force to use reg setting for PCIe mode */ 100393433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_MISC_CTRL1, 100493433708SPali Rohár SEL_BITS_PCIE_FORCE, SEL_BITS_PCIE_FORCE); 100593433708SPali Rohár 100693433708SPali Rohár /* 4. Change RX wait */ 100793433708SPali Rohár data = CFG_PM_RXDEN_WAIT_1_UNIT | CFG_PM_RXDLOZ_WAIT_12_UNIT; 100893433708SPali Rohár mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK | 100993433708SPali Rohár CFG_PM_RXDLOZ_WAIT_MASK; 101093433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask); 101193433708SPali Rohár 101293433708SPali Rohár /* 5. Enable idle sync */ 101393433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN, 101493433708SPali Rohár IDLE_SYNC_EN, IDLE_SYNC_EN); 101593433708SPali Rohár 101693433708SPali Rohár /* 6. Enable the output of 100M/125M/500M clock */ 101793433708SPali Rohár data = CLK500M_EN | TXDCLK_2X_SEL | CLK100M_125M_EN; 101893433708SPali Rohár mask = data; 101993433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask); 102093433708SPali Rohár 102193433708SPali Rohár /* 102293433708SPali Rohár * 7. Enable TX, PCIE global register, 0xd0074814, it is done in 102393433708SPali Rohár * PCI-E driver 102493433708SPali Rohár */ 102593433708SPali Rohár 102693433708SPali Rohár /* 102793433708SPali Rohár * 8. Check crystal jumper setting and program the Power and PLL 102893433708SPali Rohár * Control accordingly 102993433708SPali Rohár */ 103093433708SPali Rohár 103193433708SPali Rohár if (lane->priv->xtal_is_40m) 103293433708SPali Rohár ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ; 103393433708SPali Rohár else 103493433708SPali Rohár ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ; 103593433708SPali Rohár 103693433708SPali Rohár data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT | 103793433708SPali Rohár PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_PCIE | ref_clk; 103893433708SPali Rohár mask = 0xFFFF; 103993433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); 104093433708SPali Rohár 104193433708SPali Rohár /* 9. Override Speed_PLL value and use MAC PLL */ 104293433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, 104393433708SPali Rohár SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT, 104493433708SPali Rohár 0xFFFF); 104593433708SPali Rohár 104693433708SPali Rohár /* 10. Check the Polarity invert bit */ 104793433708SPali Rohár data = 0x0; 104893433708SPali Rohár if (lane->invert_tx) 104993433708SPali Rohár data |= TXD_INVERT_BIT; 105093433708SPali Rohár if (lane->invert_rx) 105193433708SPali Rohár data |= RXD_INVERT_BIT; 105293433708SPali Rohár mask = TXD_INVERT_BIT | RXD_INVERT_BIT; 105393433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); 105493433708SPali Rohár 105593433708SPali Rohár /* 11. Release SW reset */ 105693433708SPali Rohár data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32; 105793433708SPali Rohár mask = data | PIPE_SOFT_RESET | MODE_REFDIV_MASK; 105893433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask); 105993433708SPali Rohár 106093433708SPali Rohár /* Wait for > 55 us to allow PCLK be enabled */ 106193433708SPali Rohár udelay(PLL_SET_DELAY_US); 106293433708SPali Rohár 106393433708SPali Rohár ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN, 106493433708SPali Rohár COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); 106593433708SPali Rohár if (ret) 106693433708SPali Rohár dev_err(lane->dev, "Failed to lock PCIE PLL\n"); 106793433708SPali Rohár 106893433708SPali Rohár return ret; 106993433708SPali Rohár } 107093433708SPali Rohár 107193433708SPali Rohár static void 107293433708SPali Rohár mvebu_a3700_comphy_sata_power_off(struct mvebu_a3700_comphy_lane *lane) 107393433708SPali Rohár { 107493433708SPali Rohár /* Set phy isolation mode */ 107593433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL, 107693433708SPali Rohár PHY_ISOLATE_MODE, PHY_ISOLATE_MODE); 107793433708SPali Rohár 107893433708SPali Rohár /* Power off PLL, Tx, Rx */ 107993433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, 108093433708SPali Rohár 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT); 108193433708SPali Rohár } 108293433708SPali Rohár 108393433708SPali Rohár static void 108493433708SPali Rohár mvebu_a3700_comphy_ethernet_power_off(struct mvebu_a3700_comphy_lane *lane) 108593433708SPali Rohár { 108693433708SPali Rohár u32 mask, data; 108793433708SPali Rohár 108893433708SPali Rohár data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT | PIN_PU_IVREF_BIT | 108993433708SPali Rohár PHY_RX_INIT_BIT; 109093433708SPali Rohár mask = data; 109193433708SPali Rohár comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); 109293433708SPali Rohár } 109393433708SPali Rohár 109493433708SPali Rohár static void 109593433708SPali Rohár mvebu_a3700_comphy_pcie_power_off(struct mvebu_a3700_comphy_lane *lane) 109693433708SPali Rohár { 109793433708SPali Rohár /* Power off PLL, Tx, Rx */ 109893433708SPali Rohár comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, 109993433708SPali Rohár 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT); 110093433708SPali Rohár } 110193433708SPali Rohár 11020a6fc70dSPali Rohár static void mvebu_a3700_comphy_usb3_power_off(struct mvebu_a3700_comphy_lane *lane) 110393433708SPali Rohár { 11040a6fc70dSPali Rohár /* 11050a6fc70dSPali Rohár * The USB3 MAC sets the USB3 PHY to low state, so we do not 11060a6fc70dSPali Rohár * need to power off USB3 PHY again. 11070a6fc70dSPali Rohár */ 110893433708SPali Rohár } 110993433708SPali Rohár 111093433708SPali Rohár static bool mvebu_a3700_comphy_check_mode(int lane, 11119695375aSMiquel Raynal enum phy_mode mode, 11129695375aSMiquel Raynal int submode) 11139695375aSMiquel Raynal { 11149695375aSMiquel Raynal int i, n = ARRAY_SIZE(mvebu_a3700_comphy_modes); 11159695375aSMiquel Raynal 11169695375aSMiquel Raynal /* Unused PHY mux value is 0x0 */ 11179695375aSMiquel Raynal if (mode == PHY_MODE_INVALID) 111893433708SPali Rohár return false; 11199695375aSMiquel Raynal 11209695375aSMiquel Raynal for (i = 0; i < n; i++) { 11219695375aSMiquel Raynal if (mvebu_a3700_comphy_modes[i].lane == lane && 11229695375aSMiquel Raynal mvebu_a3700_comphy_modes[i].mode == mode && 11239695375aSMiquel Raynal mvebu_a3700_comphy_modes[i].submode == submode) 11249695375aSMiquel Raynal break; 11259695375aSMiquel Raynal } 11269695375aSMiquel Raynal 11279695375aSMiquel Raynal if (i == n) 112893433708SPali Rohár return false; 11299695375aSMiquel Raynal 113093433708SPali Rohár return true; 11319695375aSMiquel Raynal } 11329695375aSMiquel Raynal 11339695375aSMiquel Raynal static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode, 11349695375aSMiquel Raynal int submode) 11359695375aSMiquel Raynal { 11369695375aSMiquel Raynal struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); 11379695375aSMiquel Raynal 113893433708SPali Rohár if (!mvebu_a3700_comphy_check_mode(lane->id, mode, submode)) { 11399695375aSMiquel Raynal dev_err(lane->dev, "invalid COMPHY mode\n"); 114093433708SPali Rohár return -EINVAL; 11419695375aSMiquel Raynal } 11429695375aSMiquel Raynal 114393433708SPali Rohár /* Mode cannot be changed while the PHY is powered on */ 114493433708SPali Rohár if (phy->power_count && 114593433708SPali Rohár (lane->mode != mode || lane->submode != submode)) 114693433708SPali Rohár return -EBUSY; 114793433708SPali Rohár 11489695375aSMiquel Raynal /* Just remember the mode, ->power_on() will do the real setup */ 11499695375aSMiquel Raynal lane->mode = mode; 11509695375aSMiquel Raynal lane->submode = submode; 11519695375aSMiquel Raynal 11529695375aSMiquel Raynal return 0; 11539695375aSMiquel Raynal } 11549695375aSMiquel Raynal 11559695375aSMiquel Raynal static int mvebu_a3700_comphy_power_on(struct phy *phy) 11569695375aSMiquel Raynal { 11579695375aSMiquel Raynal struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); 11589695375aSMiquel Raynal 115993433708SPali Rohár if (!mvebu_a3700_comphy_check_mode(lane->id, lane->mode, 116093433708SPali Rohár lane->submode)) { 11619695375aSMiquel Raynal dev_err(lane->dev, "invalid COMPHY mode\n"); 116293433708SPali Rohár return -EINVAL; 116393433708SPali Rohár } 116493433708SPali Rohár 11659695375aSMiquel Raynal switch (lane->mode) { 11669695375aSMiquel Raynal case PHY_MODE_USB_HOST_SS: 11679695375aSMiquel Raynal dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id); 116893433708SPali Rohár return mvebu_a3700_comphy_usb3_power_on(lane); 11699695375aSMiquel Raynal case PHY_MODE_SATA: 11709695375aSMiquel Raynal dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id); 117193433708SPali Rohár return mvebu_a3700_comphy_sata_power_on(lane); 11729695375aSMiquel Raynal case PHY_MODE_ETHERNET: 117393433708SPali Rohár dev_dbg(lane->dev, "set lane %d to Ethernet mode\n", lane->id); 117493433708SPali Rohár return mvebu_a3700_comphy_ethernet_power_on(lane); 11759695375aSMiquel Raynal case PHY_MODE_PCIE: 11769695375aSMiquel Raynal dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id); 117793433708SPali Rohár return mvebu_a3700_comphy_pcie_power_on(lane); 11789695375aSMiquel Raynal default: 11799695375aSMiquel Raynal dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode); 118093433708SPali Rohár return -EOPNOTSUPP; 11819695375aSMiquel Raynal } 11829695375aSMiquel Raynal } 11839695375aSMiquel Raynal 11849695375aSMiquel Raynal static int mvebu_a3700_comphy_power_off(struct phy *phy) 11859695375aSMiquel Raynal { 11869695375aSMiquel Raynal struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); 11879695375aSMiquel Raynal 11880a6fc70dSPali Rohár switch (lane->id) { 11890a6fc70dSPali Rohár case 0: 11900a6fc70dSPali Rohár mvebu_a3700_comphy_usb3_power_off(lane); 119193433708SPali Rohár mvebu_a3700_comphy_ethernet_power_off(lane); 11920a6fc70dSPali Rohár return 0; 11930a6fc70dSPali Rohár case 1: 119493433708SPali Rohár mvebu_a3700_comphy_pcie_power_off(lane); 11950a6fc70dSPali Rohár mvebu_a3700_comphy_ethernet_power_off(lane); 11960a6fc70dSPali Rohár return 0; 11970a6fc70dSPali Rohár case 2: 11980a6fc70dSPali Rohár mvebu_a3700_comphy_usb3_power_off(lane); 11990a6fc70dSPali Rohár mvebu_a3700_comphy_sata_power_off(lane); 12000a6fc70dSPali Rohár return 0; 120193433708SPali Rohár default: 120293433708SPali Rohár dev_err(lane->dev, "invalid COMPHY mode\n"); 120393433708SPali Rohár return -EINVAL; 120493433708SPali Rohár } 12059695375aSMiquel Raynal } 12069695375aSMiquel Raynal 12079695375aSMiquel Raynal static const struct phy_ops mvebu_a3700_comphy_ops = { 12089695375aSMiquel Raynal .power_on = mvebu_a3700_comphy_power_on, 12099695375aSMiquel Raynal .power_off = mvebu_a3700_comphy_power_off, 12109695375aSMiquel Raynal .set_mode = mvebu_a3700_comphy_set_mode, 12119695375aSMiquel Raynal .owner = THIS_MODULE, 12129695375aSMiquel Raynal }; 12139695375aSMiquel Raynal 12149695375aSMiquel Raynal static struct phy *mvebu_a3700_comphy_xlate(struct device *dev, 12159695375aSMiquel Raynal struct of_phandle_args *args) 12169695375aSMiquel Raynal { 12179695375aSMiquel Raynal struct mvebu_a3700_comphy_lane *lane; 12184bf18d5aSPali Rohár unsigned int port; 12199695375aSMiquel Raynal struct phy *phy; 12209695375aSMiquel Raynal 12219695375aSMiquel Raynal phy = of_phy_simple_xlate(dev, args); 12229695375aSMiquel Raynal if (IS_ERR(phy)) 12239695375aSMiquel Raynal return phy; 12249695375aSMiquel Raynal 12259695375aSMiquel Raynal lane = phy_get_drvdata(phy); 12264bf18d5aSPali Rohár 12274bf18d5aSPali Rohár port = args->args[0]; 12284bf18d5aSPali Rohár if (port != 0 && (port != 1 || lane->id != 0)) { 12294bf18d5aSPali Rohár dev_err(lane->dev, "invalid port number %u\n", port); 12304bf18d5aSPali Rohár return ERR_PTR(-EINVAL); 12314bf18d5aSPali Rohár } 12329695375aSMiquel Raynal 123393433708SPali Rohár lane->invert_tx = args->args[1] & BIT(0); 123493433708SPali Rohár lane->invert_rx = args->args[1] & BIT(1); 123593433708SPali Rohár 12369695375aSMiquel Raynal return phy; 12379695375aSMiquel Raynal } 12389695375aSMiquel Raynal 12399695375aSMiquel Raynal static int mvebu_a3700_comphy_probe(struct platform_device *pdev) 12409695375aSMiquel Raynal { 124193433708SPali Rohár struct mvebu_a3700_comphy_priv *priv; 12429695375aSMiquel Raynal struct phy_provider *provider; 12439695375aSMiquel Raynal struct device_node *child; 124493433708SPali Rohár struct resource *res; 124593433708SPali Rohár struct clk *clk; 124693433708SPali Rohár int ret; 124793433708SPali Rohár 124893433708SPali Rohár priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 124993433708SPali Rohár if (!priv) 125093433708SPali Rohár return -ENOMEM; 125193433708SPali Rohár 125293433708SPali Rohár spin_lock_init(&priv->lock); 125393433708SPali Rohár 125493433708SPali Rohár res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "comphy"); 125593433708SPali Rohár priv->comphy_regs = devm_ioremap_resource(&pdev->dev, res); 125693433708SPali Rohár if (IS_ERR(priv->comphy_regs)) 125793433708SPali Rohár return PTR_ERR(priv->comphy_regs); 125893433708SPali Rohár 125993433708SPali Rohár res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 126093433708SPali Rohár "lane1_pcie_gbe"); 126193433708SPali Rohár priv->lane1_phy_regs = devm_ioremap_resource(&pdev->dev, res); 126293433708SPali Rohár if (IS_ERR(priv->lane1_phy_regs)) 126393433708SPali Rohár return PTR_ERR(priv->lane1_phy_regs); 126493433708SPali Rohár 126593433708SPali Rohár res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 126693433708SPali Rohár "lane0_usb3_gbe"); 126793433708SPali Rohár priv->lane0_phy_regs = devm_ioremap_resource(&pdev->dev, res); 126893433708SPali Rohár if (IS_ERR(priv->lane0_phy_regs)) 126993433708SPali Rohár return PTR_ERR(priv->lane0_phy_regs); 127093433708SPali Rohár 127193433708SPali Rohár res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 127293433708SPali Rohár "lane2_sata_usb3"); 127393433708SPali Rohár priv->lane2_phy_indirect = devm_ioremap_resource(&pdev->dev, res); 127493433708SPali Rohár if (IS_ERR(priv->lane2_phy_indirect)) 127593433708SPali Rohár return PTR_ERR(priv->lane2_phy_indirect); 127693433708SPali Rohár 127793433708SPali Rohár /* 127893433708SPali Rohár * Driver needs to know if reference xtal clock is 40MHz or 25MHz. 127993433708SPali Rohár * Old DT bindings do not have xtal clk present. So do not fail here 128093433708SPali Rohár * and expects that default 25MHz reference clock is used. 128193433708SPali Rohár */ 128293433708SPali Rohár clk = clk_get(&pdev->dev, "xtal"); 128393433708SPali Rohár if (IS_ERR(clk)) { 128493433708SPali Rohár if (PTR_ERR(clk) == -EPROBE_DEFER) 128593433708SPali Rohár return -EPROBE_DEFER; 128693433708SPali Rohár dev_warn(&pdev->dev, "missing 'xtal' clk (%ld)\n", 128793433708SPali Rohár PTR_ERR(clk)); 128893433708SPali Rohár } else { 128993433708SPali Rohár ret = clk_prepare_enable(clk); 129093433708SPali Rohár if (ret) { 129193433708SPali Rohár dev_warn(&pdev->dev, "enabling xtal clk failed (%d)\n", 129293433708SPali Rohár ret); 129393433708SPali Rohár } else { 129493433708SPali Rohár if (clk_get_rate(clk) == 40000000) 129593433708SPali Rohár priv->xtal_is_40m = true; 129693433708SPali Rohár clk_disable_unprepare(clk); 129793433708SPali Rohár } 129893433708SPali Rohár clk_put(clk); 129993433708SPali Rohár } 130093433708SPali Rohár 130193433708SPali Rohár dev_set_drvdata(&pdev->dev, priv); 13029695375aSMiquel Raynal 13039695375aSMiquel Raynal for_each_available_child_of_node(pdev->dev.of_node, child) { 13049695375aSMiquel Raynal struct mvebu_a3700_comphy_lane *lane; 13059695375aSMiquel Raynal struct phy *phy; 13069695375aSMiquel Raynal int ret; 13079695375aSMiquel Raynal u32 lane_id; 13089695375aSMiquel Raynal 13099695375aSMiquel Raynal ret = of_property_read_u32(child, "reg", &lane_id); 13109695375aSMiquel Raynal if (ret < 0) { 13119695375aSMiquel Raynal dev_err(&pdev->dev, "missing 'reg' property (%d)\n", 13129695375aSMiquel Raynal ret); 13139695375aSMiquel Raynal continue; 13149695375aSMiquel Raynal } 13159695375aSMiquel Raynal 131693433708SPali Rohár if (lane_id >= 3) { 13179695375aSMiquel Raynal dev_err(&pdev->dev, "invalid 'reg' property\n"); 13189695375aSMiquel Raynal continue; 13199695375aSMiquel Raynal } 13209695375aSMiquel Raynal 13219695375aSMiquel Raynal lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); 1322beae796dSNishka Dasgupta if (!lane) { 1323beae796dSNishka Dasgupta of_node_put(child); 13249695375aSMiquel Raynal return -ENOMEM; 1325beae796dSNishka Dasgupta } 13269695375aSMiquel Raynal 13279695375aSMiquel Raynal phy = devm_phy_create(&pdev->dev, child, 13289695375aSMiquel Raynal &mvebu_a3700_comphy_ops); 1329beae796dSNishka Dasgupta if (IS_ERR(phy)) { 1330beae796dSNishka Dasgupta of_node_put(child); 13319695375aSMiquel Raynal return PTR_ERR(phy); 1332beae796dSNishka Dasgupta } 13339695375aSMiquel Raynal 133493433708SPali Rohár lane->priv = priv; 13359695375aSMiquel Raynal lane->dev = &pdev->dev; 13369695375aSMiquel Raynal lane->mode = PHY_MODE_INVALID; 13379695375aSMiquel Raynal lane->submode = PHY_INTERFACE_MODE_NA; 13389695375aSMiquel Raynal lane->id = lane_id; 133993433708SPali Rohár lane->invert_tx = false; 134093433708SPali Rohár lane->invert_rx = false; 13419695375aSMiquel Raynal phy_set_drvdata(phy, lane); 134293433708SPali Rohár 134393433708SPali Rohár /* 134493433708SPali Rohár * To avoid relying on the bootloader/firmware configuration, 134593433708SPali Rohár * power off all comphys. 134693433708SPali Rohár */ 13470a6fc70dSPali Rohár mvebu_a3700_comphy_power_off(phy); 13489695375aSMiquel Raynal } 13499695375aSMiquel Raynal 13509695375aSMiquel Raynal provider = devm_of_phy_provider_register(&pdev->dev, 13519695375aSMiquel Raynal mvebu_a3700_comphy_xlate); 135293433708SPali Rohár 13539695375aSMiquel Raynal return PTR_ERR_OR_ZERO(provider); 13549695375aSMiquel Raynal } 13559695375aSMiquel Raynal 13569695375aSMiquel Raynal static const struct of_device_id mvebu_a3700_comphy_of_match_table[] = { 13579695375aSMiquel Raynal { .compatible = "marvell,comphy-a3700" }, 13589695375aSMiquel Raynal { }, 13599695375aSMiquel Raynal }; 13609695375aSMiquel Raynal MODULE_DEVICE_TABLE(of, mvebu_a3700_comphy_of_match_table); 13619695375aSMiquel Raynal 13629695375aSMiquel Raynal static struct platform_driver mvebu_a3700_comphy_driver = { 13639695375aSMiquel Raynal .probe = mvebu_a3700_comphy_probe, 13649695375aSMiquel Raynal .driver = { 13659695375aSMiquel Raynal .name = "mvebu-a3700-comphy", 13669695375aSMiquel Raynal .of_match_table = mvebu_a3700_comphy_of_match_table, 13679695375aSMiquel Raynal }, 13689695375aSMiquel Raynal }; 13699695375aSMiquel Raynal module_platform_driver(mvebu_a3700_comphy_driver); 13709695375aSMiquel Raynal 13719695375aSMiquel Raynal MODULE_AUTHOR("Miquèl Raynal <miquel.raynal@bootlin.com>"); 137293433708SPali Rohár MODULE_AUTHOR("Pali Rohár <pali@kernel.org>"); 137393433708SPali Rohár MODULE_AUTHOR("Marek Behún <kabel@kernel.org>"); 13749695375aSMiquel Raynal MODULE_DESCRIPTION("Common PHY driver for A3700"); 13759695375aSMiquel Raynal MODULE_LICENSE("GPL v2"); 1376