cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

phy-mvebu-cp110-comphy.c (36826B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2017 Marvell
      4 *
      5 * Antoine Tenart <antoine.tenart@free-electrons.com>
      6 */
      7
      8#include <linux/arm-smccc.h>
      9#include <linux/clk.h>
     10#include <linux/io.h>
     11#include <linux/iopoll.h>
     12#include <linux/mfd/syscon.h>
     13#include <linux/module.h>
     14#include <linux/phy.h>
     15#include <linux/phy/phy.h>
     16#include <linux/platform_device.h>
     17#include <linux/regmap.h>
     18
     19/* Relative to priv->base */
     20#define MVEBU_COMPHY_SERDES_CFG0(n)		(0x0 + (n) * 0x1000)
     21#define     MVEBU_COMPHY_SERDES_CFG0_PU_PLL	BIT(1)
     22#define     MVEBU_COMPHY_SERDES_CFG0_GEN_RX(n)	((n) << 3)
     23#define     MVEBU_COMPHY_SERDES_CFG0_GEN_TX(n)	((n) << 7)
     24#define     MVEBU_COMPHY_SERDES_CFG0_PU_RX	BIT(11)
     25#define     MVEBU_COMPHY_SERDES_CFG0_PU_TX	BIT(12)
     26#define     MVEBU_COMPHY_SERDES_CFG0_HALF_BUS	BIT(14)
     27#define     MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE	BIT(15)
     28#define MVEBU_COMPHY_SERDES_CFG1(n)		(0x4 + (n) * 0x1000)
     29#define     MVEBU_COMPHY_SERDES_CFG1_RESET	BIT(3)
     30#define     MVEBU_COMPHY_SERDES_CFG1_RX_INIT	BIT(4)
     31#define     MVEBU_COMPHY_SERDES_CFG1_CORE_RESET	BIT(5)
     32#define     MVEBU_COMPHY_SERDES_CFG1_RF_RESET	BIT(6)
     33#define MVEBU_COMPHY_SERDES_CFG2(n)		(0x8 + (n) * 0x1000)
     34#define     MVEBU_COMPHY_SERDES_CFG2_DFE_EN	BIT(4)
     35#define MVEBU_COMPHY_SERDES_STATUS0(n)		(0x18 + (n) * 0x1000)
     36#define     MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY	BIT(2)
     37#define     MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY	BIT(3)
     38#define     MVEBU_COMPHY_SERDES_STATUS0_RX_INIT		BIT(4)
     39#define MVEBU_COMPHY_PWRPLL_CTRL(n)		(0x804 + (n) * 0x1000)
     40#define     MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(n)	((n) << 0)
     41#define     MVEBU_COMPHY_PWRPLL_PHY_MODE(n)	((n) << 5)
     42#define MVEBU_COMPHY_IMP_CAL(n)			(0x80c + (n) * 0x1000)
     43#define     MVEBU_COMPHY_IMP_CAL_TX_EXT(n)	((n) << 10)
     44#define     MVEBU_COMPHY_IMP_CAL_TX_EXT_EN	BIT(15)
     45#define MVEBU_COMPHY_DFE_RES(n)			(0x81c + (n) * 0x1000)
     46#define     MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL	BIT(15)
     47#define MVEBU_COMPHY_COEF(n)			(0x828 + (n) * 0x1000)
     48#define     MVEBU_COMPHY_COEF_DFE_EN		BIT(14)
     49#define     MVEBU_COMPHY_COEF_DFE_CTRL		BIT(15)
     50#define MVEBU_COMPHY_GEN1_S0(n)			(0x834 + (n) * 0x1000)
     51#define     MVEBU_COMPHY_GEN1_S0_TX_AMP(n)	((n) << 1)
     52#define     MVEBU_COMPHY_GEN1_S0_TX_EMPH(n)	((n) << 7)
     53#define MVEBU_COMPHY_GEN1_S1(n)			(0x838 + (n) * 0x1000)
     54#define     MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(n)	((n) << 0)
     55#define     MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(n)	((n) << 3)
     56#define     MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(n)	((n) << 6)
     57#define     MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(n)	((n) << 8)
     58#define     MVEBU_COMPHY_GEN1_S1_RX_DFE_EN	BIT(10)
     59#define     MVEBU_COMPHY_GEN1_S1_RX_DIV(n)	((n) << 11)
     60#define MVEBU_COMPHY_GEN1_S2(n)			(0x8f4 + (n) * 0x1000)
     61#define     MVEBU_COMPHY_GEN1_S2_TX_EMPH(n)	((n) << 0)
     62#define     MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN	BIT(4)
     63#define MVEBU_COMPHY_LOOPBACK(n)		(0x88c + (n) * 0x1000)
     64#define     MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(n)	((n) << 1)
     65#define MVEBU_COMPHY_VDD_CAL0(n)		(0x908 + (n) * 0x1000)
     66#define     MVEBU_COMPHY_VDD_CAL0_CONT_MODE	BIT(15)
     67#define MVEBU_COMPHY_EXT_SELV(n)		(0x914 + (n) * 0x1000)
     68#define     MVEBU_COMPHY_EXT_SELV_RX_SAMPL(n)	((n) << 5)
     69#define MVEBU_COMPHY_MISC_CTRL0(n)		(0x93c + (n) * 0x1000)
     70#define     MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE	BIT(5)
     71#define     MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL	BIT(10)
     72#define MVEBU_COMPHY_RX_CTRL1(n)		(0x940 + (n) * 0x1000)
     73#define     MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL	BIT(11)
     74#define     MVEBU_COMPHY_RX_CTRL1_CLK8T_EN	BIT(12)
     75#define MVEBU_COMPHY_SPEED_DIV(n)		(0x954 + (n) * 0x1000)
     76#define     MVEBU_COMPHY_SPEED_DIV_TX_FORCE	BIT(7)
     77#define MVEBU_SP_CALIB(n)			(0x96c + (n) * 0x1000)
     78#define     MVEBU_SP_CALIB_SAMPLER(n)		((n) << 8)
     79#define     MVEBU_SP_CALIB_SAMPLER_EN		BIT(12)
     80#define MVEBU_COMPHY_TX_SLEW_RATE(n)		(0x974 + (n) * 0x1000)
     81#define     MVEBU_COMPHY_TX_SLEW_RATE_EMPH(n)	((n) << 5)
     82#define     MVEBU_COMPHY_TX_SLEW_RATE_SLC(n)	((n) << 10)
     83#define MVEBU_COMPHY_DTL_CTRL(n)		(0x984 + (n) * 0x1000)
     84#define     MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN	BIT(2)
     85#define MVEBU_COMPHY_FRAME_DETECT0(n)		(0xa14 + (n) * 0x1000)
     86#define     MVEBU_COMPHY_FRAME_DETECT0_PATN(n)	((n) << 7)
     87#define MVEBU_COMPHY_FRAME_DETECT3(n)		(0xa20 + (n) * 0x1000)
     88#define     MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN	BIT(12)
     89#define MVEBU_COMPHY_DME(n)			(0xa28 + (n) * 0x1000)
     90#define     MVEBU_COMPHY_DME_ETH_MODE		BIT(7)
     91#define MVEBU_COMPHY_TRAINING0(n)		(0xa68 + (n) * 0x1000)
     92#define     MVEBU_COMPHY_TRAINING0_P2P_HOLD	BIT(15)
     93#define MVEBU_COMPHY_TRAINING5(n)		(0xaa4 + (n) * 0x1000)
     94#define	    MVEBU_COMPHY_TRAINING5_RX_TIMER(n)	((n) << 0)
     95#define MVEBU_COMPHY_TX_TRAIN_PRESET(n)		(0xb1c + (n) * 0x1000)
     96#define     MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN	BIT(8)
     97#define     MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11		BIT(9)
     98#define MVEBU_COMPHY_GEN1_S3(n)			(0xc40 + (n) * 0x1000)
     99#define     MVEBU_COMPHY_GEN1_S3_FBCK_SEL	BIT(9)
    100#define MVEBU_COMPHY_GEN1_S4(n)			(0xc44 + (n) * 0x1000)
    101#define	    MVEBU_COMPHY_GEN1_S4_DFE_RES(n)	((n) << 8)
    102#define MVEBU_COMPHY_TX_PRESET(n)		(0xc68 + (n) * 0x1000)
    103#define     MVEBU_COMPHY_TX_PRESET_INDEX(n)	((n) << 0)
    104#define MVEBU_COMPHY_GEN1_S5(n)			(0xd38 + (n) * 0x1000)
    105#define     MVEBU_COMPHY_GEN1_S5_ICP(n)		((n) << 0)
    106
    107/* Relative to priv->regmap */
    108#define MVEBU_COMPHY_CONF1(n)			(0x1000 + (n) * 0x28)
    109#define     MVEBU_COMPHY_CONF1_PWRUP		BIT(1)
    110#define     MVEBU_COMPHY_CONF1_USB_PCIE		BIT(2)	/* 0: Ethernet/SATA */
    111#define MVEBU_COMPHY_CONF6(n)			(0x1014 + (n) * 0x28)
    112#define     MVEBU_COMPHY_CONF6_40B		BIT(18)
    113#define MVEBU_COMPHY_SELECTOR			0x1140
    114#define     MVEBU_COMPHY_SELECTOR_PHY(n)	((n) * 0x4)
    115#define MVEBU_COMPHY_PIPE_SELECTOR		0x1144
    116#define     MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n)	((n) * 0x4)
    117#define MVEBU_COMPHY_SD1_CTRL1			0x1148
    118#define     MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN	BIT(26)
    119#define     MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN	BIT(27)
    120
    121#define MVEBU_COMPHY_LANES	6
    122#define MVEBU_COMPHY_PORTS	3
    123
    124#define COMPHY_SIP_POWER_ON	0x82000001
    125#define COMPHY_SIP_POWER_OFF	0x82000002
    126
    127/*
    128 * A lane is described by the following bitfields:
    129 * [ 1- 0]: COMPHY polarity invertion
    130 * [ 2- 7]: COMPHY speed
    131 * [ 5-11]: COMPHY port index
    132 * [12-16]: COMPHY mode
    133 * [17]: Clock source
    134 * [18-20]: PCIe width (x1, x2, x4)
    135 */
    136#define COMPHY_FW_POL_OFFSET	0
    137#define COMPHY_FW_POL_MASK	GENMASK(1, 0)
    138#define COMPHY_FW_SPEED_OFFSET	2
    139#define COMPHY_FW_SPEED_MASK	GENMASK(7, 2)
    140#define COMPHY_FW_SPEED_MAX	COMPHY_FW_SPEED_MASK
    141#define COMPHY_FW_SPEED_1250	0
    142#define COMPHY_FW_SPEED_3125	2
    143#define COMPHY_FW_SPEED_5000	3
    144#define COMPHY_FW_SPEED_515625	4
    145#define COMPHY_FW_SPEED_103125	6
    146#define COMPHY_FW_PORT_OFFSET	8
    147#define COMPHY_FW_PORT_MASK	GENMASK(11, 8)
    148#define COMPHY_FW_MODE_OFFSET	12
    149#define COMPHY_FW_MODE_MASK	GENMASK(16, 12)
    150#define COMPHY_FW_WIDTH_OFFSET	18
    151#define COMPHY_FW_WIDTH_MASK	GENMASK(20, 18)
    152
    153#define COMPHY_FW_PARAM_FULL(mode, port, speed, pol, width)		\
    154	((((pol) << COMPHY_FW_POL_OFFSET) & COMPHY_FW_POL_MASK) |	\
    155	 (((mode) << COMPHY_FW_MODE_OFFSET) & COMPHY_FW_MODE_MASK) |	\
    156	 (((port) << COMPHY_FW_PORT_OFFSET) & COMPHY_FW_PORT_MASK) |	\
    157	 (((speed) << COMPHY_FW_SPEED_OFFSET) & COMPHY_FW_SPEED_MASK) |	\
    158	 (((width) << COMPHY_FW_WIDTH_OFFSET) & COMPHY_FW_WIDTH_MASK))
    159
    160#define COMPHY_FW_PARAM(mode, port)					\
    161	COMPHY_FW_PARAM_FULL(mode, port, COMPHY_FW_SPEED_MAX, 0, 0)
    162
    163#define COMPHY_FW_PARAM_ETH(mode, port, speed)				\
    164	COMPHY_FW_PARAM_FULL(mode, port, speed, 0, 0)
    165
    166#define COMPHY_FW_PARAM_PCIE(mode, port, width)				\
    167	COMPHY_FW_PARAM_FULL(mode, port, COMPHY_FW_SPEED_5000, 0, width)
    168
    169#define COMPHY_FW_MODE_SATA		0x1
    170#define COMPHY_FW_MODE_SGMII		0x2 /* SGMII 1G */
    171#define COMPHY_FW_MODE_2500BASEX	0x3 /* 2500BASE-X */
    172#define COMPHY_FW_MODE_USB3H		0x4
    173#define COMPHY_FW_MODE_USB3D		0x5
    174#define COMPHY_FW_MODE_PCIE		0x6
    175#define COMPHY_FW_MODE_RXAUI		0x7
    176#define COMPHY_FW_MODE_XFI		0x8 /* SFI: 0x9 (is treated like XFI) */
    177
    178struct mvebu_comphy_conf {
    179	enum phy_mode mode;
    180	int submode;
    181	unsigned lane;
    182	unsigned port;
    183	u32 mux;
    184	u32 fw_mode;
    185};
    186
    187#define ETH_CONF(_lane, _port, _submode, _mux, _fw)	\
    188	{						\
    189		.lane = _lane,				\
    190		.port = _port,				\
    191		.mode = PHY_MODE_ETHERNET,		\
    192		.submode = _submode,			\
    193		.mux = _mux,				\
    194		.fw_mode = _fw,				\
    195	}
    196
    197#define GEN_CONF(_lane, _port, _mode, _fw)		\
    198	{						\
    199		.lane = _lane,				\
    200		.port = _port,				\
    201		.mode = _mode,				\
    202		.submode = PHY_INTERFACE_MODE_NA,	\
    203		.mux = -1,				\
    204		.fw_mode = _fw,				\
    205	}
    206
    207static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = {
    208	/* lane 0 */
    209	GEN_CONF(0, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
    210	ETH_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
    211	ETH_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
    212	GEN_CONF(0, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
    213	/* lane 1 */
    214	GEN_CONF(1, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
    215	GEN_CONF(1, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D),
    216	GEN_CONF(1, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
    217	GEN_CONF(1, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
    218	ETH_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
    219	ETH_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
    220	/* lane 2 */
    221	ETH_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
    222	ETH_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
    223	ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI),
    224	ETH_CONF(2, 0, PHY_INTERFACE_MODE_5GBASER, 0x1, COMPHY_FW_MODE_XFI),
    225	ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GBASER, 0x1, COMPHY_FW_MODE_XFI),
    226	GEN_CONF(2, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
    227	GEN_CONF(2, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
    228	GEN_CONF(2, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
    229	/* lane 3 */
    230	GEN_CONF(3, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
    231	ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII),
    232	ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_2500BASEX),
    233	ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI),
    234	GEN_CONF(3, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
    235	GEN_CONF(3, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
    236	/* lane 4 */
    237	ETH_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII),
    238	ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_2500BASEX),
    239	ETH_CONF(4, 0, PHY_INTERFACE_MODE_5GBASER, 0x2, COMPHY_FW_MODE_XFI),
    240	ETH_CONF(4, 0, PHY_INTERFACE_MODE_10GBASER, 0x2, COMPHY_FW_MODE_XFI),
    241	ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI),
    242	GEN_CONF(4, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D),
    243	GEN_CONF(4, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
    244	GEN_CONF(4, 1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
    245	ETH_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
    246	ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_2500BASEX),
    247	ETH_CONF(4, 1, PHY_INTERFACE_MODE_5GBASER, -1, COMPHY_FW_MODE_XFI),
    248	ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GBASER, -1, COMPHY_FW_MODE_XFI),
    249	/* lane 5 */
    250	ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI),
    251	GEN_CONF(5, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
    252	ETH_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
    253	ETH_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
    254	GEN_CONF(5, 2, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
    255};
    256
    257struct mvebu_comphy_priv {
    258	void __iomem *base;
    259	struct regmap *regmap;
    260	struct device *dev;
    261	struct clk *mg_domain_clk;
    262	struct clk *mg_core_clk;
    263	struct clk *axi_clk;
    264	unsigned long cp_phys;
    265};
    266
    267struct mvebu_comphy_lane {
    268	struct mvebu_comphy_priv *priv;
    269	unsigned id;
    270	enum phy_mode mode;
    271	int submode;
    272	int port;
    273};
    274
    275static int mvebu_comphy_smc(unsigned long function, unsigned long phys,
    276			    unsigned long lane, unsigned long mode)
    277{
    278	struct arm_smccc_res res;
    279	s32 ret;
    280
    281	arm_smccc_smc(function, phys, lane, mode, 0, 0, 0, 0, &res);
    282	ret = res.a0;
    283
    284	switch (ret) {
    285	case SMCCC_RET_SUCCESS:
    286		return 0;
    287	case SMCCC_RET_NOT_SUPPORTED:
    288		return -EOPNOTSUPP;
    289	default:
    290		return -EINVAL;
    291	}
    292}
    293
    294static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port,
    295				 enum phy_mode mode, int submode)
    296{
    297	int i, n = ARRAY_SIZE(mvebu_comphy_cp110_modes);
    298	/* Ignore PCIe submode: it represents the width */
    299	bool ignore_submode = (mode == PHY_MODE_PCIE);
    300	const struct mvebu_comphy_conf *conf;
    301
    302	/* Unused PHY mux value is 0x0 */
    303	if (mode == PHY_MODE_INVALID)
    304		return 0;
    305
    306	for (i = 0; i < n; i++) {
    307		conf = &mvebu_comphy_cp110_modes[i];
    308		if (conf->lane == lane &&
    309		    conf->port == port &&
    310		    conf->mode == mode &&
    311		    (conf->submode == submode || ignore_submode))
    312			break;
    313	}
    314
    315	if (i == n)
    316		return -EINVAL;
    317
    318	if (fw_mode)
    319		return conf->fw_mode;
    320	else
    321		return conf->mux;
    322}
    323
    324static inline int mvebu_comphy_get_mux(int lane, int port,
    325				       enum phy_mode mode, int submode)
    326{
    327	return mvebu_comphy_get_mode(false, lane, port, mode, submode);
    328}
    329
    330static inline int mvebu_comphy_get_fw_mode(int lane, int port,
    331					   enum phy_mode mode, int submode)
    332{
    333	return mvebu_comphy_get_mode(true, lane, port, mode, submode);
    334}
    335
    336static int mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane)
    337{
    338	struct mvebu_comphy_priv *priv = lane->priv;
    339	u32 val;
    340
    341	regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val);
    342	val &= ~MVEBU_COMPHY_CONF1_USB_PCIE;
    343	val |= MVEBU_COMPHY_CONF1_PWRUP;
    344	regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val);
    345
    346	/* Select baud rates and PLLs */
    347	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
    348	val &= ~(MVEBU_COMPHY_SERDES_CFG0_PU_PLL |
    349		 MVEBU_COMPHY_SERDES_CFG0_PU_RX |
    350		 MVEBU_COMPHY_SERDES_CFG0_PU_TX |
    351		 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS |
    352		 MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xf) |
    353		 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xf) |
    354		 MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE);
    355
    356	switch (lane->submode) {
    357	case PHY_INTERFACE_MODE_10GBASER:
    358		val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) |
    359		       MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe);
    360		break;
    361	case PHY_INTERFACE_MODE_RXAUI:
    362		val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xb) |
    363		       MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xb) |
    364		       MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE;
    365		break;
    366	case PHY_INTERFACE_MODE_2500BASEX:
    367		val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) |
    368		       MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) |
    369		       MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
    370		break;
    371	case PHY_INTERFACE_MODE_SGMII:
    372		val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) |
    373		       MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) |
    374		       MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
    375		break;
    376	default:
    377		dev_err(priv->dev,
    378			"unsupported comphy submode (%d) on lane %d\n",
    379			lane->submode,
    380			lane->id);
    381		return -ENOTSUPP;
    382	}
    383
    384	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
    385
    386	if (lane->submode == PHY_INTERFACE_MODE_RXAUI) {
    387		regmap_read(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, &val);
    388
    389		switch (lane->id) {
    390		case 2:
    391		case 3:
    392			val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN;
    393			break;
    394		case 4:
    395		case 5:
    396			val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN;
    397			break;
    398		default:
    399			dev_err(priv->dev,
    400				"RXAUI is not supported on comphy lane %d\n",
    401				lane->id);
    402			return -EINVAL;
    403		}
    404
    405		regmap_write(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, val);
    406	}
    407
    408	/* reset */
    409	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    410	val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET |
    411		 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET |
    412		 MVEBU_COMPHY_SERDES_CFG1_RF_RESET);
    413	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    414
    415	/* de-assert reset */
    416	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    417	val |= MVEBU_COMPHY_SERDES_CFG1_RESET |
    418	       MVEBU_COMPHY_SERDES_CFG1_CORE_RESET;
    419	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    420
    421	/* wait until clocks are ready */
    422	mdelay(1);
    423
    424	/* exlicitly disable 40B, the bits isn't clear on reset */
    425	regmap_read(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), &val);
    426	val &= ~MVEBU_COMPHY_CONF6_40B;
    427	regmap_write(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), val);
    428
    429	/* refclk selection */
    430	val = readl(priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
    431	val &= ~MVEBU_COMPHY_MISC_CTRL0_REFCLK_SEL;
    432	if (lane->submode == PHY_INTERFACE_MODE_10GBASER)
    433		val |= MVEBU_COMPHY_MISC_CTRL0_ICP_FORCE;
    434	writel(val, priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
    435
    436	/* power and pll selection */
    437	val = readl(priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id));
    438	val &= ~(MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1f) |
    439		 MVEBU_COMPHY_PWRPLL_PHY_MODE(0x7));
    440	val |= MVEBU_COMPHY_PWRPLL_CTRL_RFREQ(0x1) |
    441	       MVEBU_COMPHY_PWRPLL_PHY_MODE(0x4);
    442	writel(val, priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id));
    443
    444	val = readl(priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
    445	val &= ~MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x7);
    446	val |= MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x1);
    447	writel(val, priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
    448
    449	return 0;
    450}
    451
    452static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane)
    453{
    454	struct mvebu_comphy_priv *priv = lane->priv;
    455	u32 val;
    456
    457	/* SERDES external config */
    458	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
    459	val |= MVEBU_COMPHY_SERDES_CFG0_PU_PLL |
    460	       MVEBU_COMPHY_SERDES_CFG0_PU_RX |
    461	       MVEBU_COMPHY_SERDES_CFG0_PU_TX;
    462	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
    463
    464	/* check rx/tx pll */
    465	readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id),
    466			   val,
    467			   val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY |
    468				  MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY),
    469			   1000, 150000);
    470	if (!(val & (MVEBU_COMPHY_SERDES_STATUS0_RX_PLL_RDY |
    471		     MVEBU_COMPHY_SERDES_STATUS0_TX_PLL_RDY)))
    472		return -ETIMEDOUT;
    473
    474	/* rx init */
    475	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    476	val |= MVEBU_COMPHY_SERDES_CFG1_RX_INIT;
    477	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    478
    479	/* check rx */
    480	readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id),
    481			   val, val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT,
    482			   1000, 10000);
    483	if (!(val & MVEBU_COMPHY_SERDES_STATUS0_RX_INIT))
    484		return -ETIMEDOUT;
    485
    486	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    487	val &= ~MVEBU_COMPHY_SERDES_CFG1_RX_INIT;
    488	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    489
    490	return 0;
    491}
    492
    493static int mvebu_comphy_set_mode_sgmii(struct phy *phy)
    494{
    495	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
    496	struct mvebu_comphy_priv *priv = lane->priv;
    497	u32 val;
    498	int err;
    499
    500	err = mvebu_comphy_ethernet_init_reset(lane);
    501	if (err)
    502		return err;
    503
    504	val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
    505	val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
    506	val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL;
    507	writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
    508
    509	val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
    510	val &= ~MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN;
    511	writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
    512
    513	regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val);
    514	val &= ~MVEBU_COMPHY_CONF1_USB_PCIE;
    515	val |= MVEBU_COMPHY_CONF1_PWRUP;
    516	regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val);
    517
    518	val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
    519	val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf);
    520	val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0x1);
    521	writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
    522
    523	return mvebu_comphy_init_plls(lane);
    524}
    525
    526static int mvebu_comphy_set_mode_rxaui(struct phy *phy)
    527{
    528	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
    529	struct mvebu_comphy_priv *priv = lane->priv;
    530	u32 val;
    531	int err;
    532
    533	err = mvebu_comphy_ethernet_init_reset(lane);
    534	if (err)
    535		return err;
    536
    537	val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
    538	val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL |
    539	       MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
    540	writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
    541
    542	val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
    543	val |= MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN;
    544	writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
    545
    546	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
    547	val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN;
    548	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
    549
    550	val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
    551	val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL;
    552	writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
    553
    554	val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
    555	val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf);
    556	val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xd);
    557	writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
    558
    559	val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
    560	val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) |
    561		 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7));
    562	val |= MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x1) |
    563	       MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x1) |
    564	       MVEBU_COMPHY_GEN1_S1_RX_DFE_EN;
    565	writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
    566
    567	val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id));
    568	val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL);
    569	writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id));
    570
    571	val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
    572	val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3);
    573	val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1);
    574	writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
    575
    576	return mvebu_comphy_init_plls(lane);
    577}
    578
    579static int mvebu_comphy_set_mode_10gbaser(struct phy *phy)
    580{
    581	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
    582	struct mvebu_comphy_priv *priv = lane->priv;
    583	u32 val;
    584	int err;
    585
    586	err = mvebu_comphy_ethernet_init_reset(lane);
    587	if (err)
    588		return err;
    589
    590	val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
    591	val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL |
    592	       MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
    593	writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
    594
    595	val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
    596	val |= MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN;
    597	writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
    598
    599	/* Speed divider */
    600	val = readl(priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id));
    601	val |= MVEBU_COMPHY_SPEED_DIV_TX_FORCE;
    602	writel(val, priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id));
    603
    604	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
    605	val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN;
    606	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
    607
    608	/* DFE resolution */
    609	val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
    610	val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL;
    611	writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
    612
    613	val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
    614	val &= ~(MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1f) |
    615		 MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf));
    616	val |= MVEBU_COMPHY_GEN1_S0_TX_AMP(0x1c) |
    617	       MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xe);
    618	writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
    619
    620	val = readl(priv->base + MVEBU_COMPHY_GEN1_S2(lane->id));
    621	val &= ~MVEBU_COMPHY_GEN1_S2_TX_EMPH(0xf);
    622	val |= MVEBU_COMPHY_GEN1_S2_TX_EMPH_EN;
    623	writel(val, priv->base + MVEBU_COMPHY_GEN1_S2(lane->id));
    624
    625	val = readl(priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id));
    626	val |= MVEBU_COMPHY_TX_SLEW_RATE_EMPH(0x3) |
    627	       MVEBU_COMPHY_TX_SLEW_RATE_SLC(0x3f);
    628	writel(val, priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id));
    629
    630	/* Impedance calibration */
    631	val = readl(priv->base + MVEBU_COMPHY_IMP_CAL(lane->id));
    632	val &= ~MVEBU_COMPHY_IMP_CAL_TX_EXT(0x1f);
    633	val |= MVEBU_COMPHY_IMP_CAL_TX_EXT(0xe) |
    634	       MVEBU_COMPHY_IMP_CAL_TX_EXT_EN;
    635	writel(val, priv->base + MVEBU_COMPHY_IMP_CAL(lane->id));
    636
    637	val = readl(priv->base + MVEBU_COMPHY_GEN1_S5(lane->id));
    638	val &= ~MVEBU_COMPHY_GEN1_S5_ICP(0xf);
    639	writel(val, priv->base + MVEBU_COMPHY_GEN1_S5(lane->id));
    640
    641	val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
    642	val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) |
    643		 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7) |
    644		 MVEBU_COMPHY_GEN1_S1_RX_MUL_FI(0x3) |
    645		 MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x3));
    646	val |= MVEBU_COMPHY_GEN1_S1_RX_DFE_EN |
    647	       MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x2) |
    648	       MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x2) |
    649	       MVEBU_COMPHY_GEN1_S1_RX_MUL_FF(0x1) |
    650	       MVEBU_COMPHY_GEN1_S1_RX_DIV(0x3);
    651	writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
    652
    653	val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id));
    654	val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL);
    655	writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id));
    656
    657	val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
    658	val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3);
    659	val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1);
    660	writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
    661
    662	val = readl(priv->base + MVEBU_COMPHY_GEN1_S3(lane->id));
    663	val |= MVEBU_COMPHY_GEN1_S3_FBCK_SEL;
    664	writel(val, priv->base + MVEBU_COMPHY_GEN1_S3(lane->id));
    665
    666	/* rx training timer */
    667	val = readl(priv->base + MVEBU_COMPHY_TRAINING5(lane->id));
    668	val &= ~MVEBU_COMPHY_TRAINING5_RX_TIMER(0x3ff);
    669	val |= MVEBU_COMPHY_TRAINING5_RX_TIMER(0x13);
    670	writel(val, priv->base + MVEBU_COMPHY_TRAINING5(lane->id));
    671
    672	/* tx train peak to peak hold */
    673	val = readl(priv->base + MVEBU_COMPHY_TRAINING0(lane->id));
    674	val |= MVEBU_COMPHY_TRAINING0_P2P_HOLD;
    675	writel(val, priv->base + MVEBU_COMPHY_TRAINING0(lane->id));
    676
    677	val = readl(priv->base + MVEBU_COMPHY_TX_PRESET(lane->id));
    678	val &= ~MVEBU_COMPHY_TX_PRESET_INDEX(0xf);
    679	val |= MVEBU_COMPHY_TX_PRESET_INDEX(0x2);	/* preset coeff */
    680	writel(val, priv->base + MVEBU_COMPHY_TX_PRESET(lane->id));
    681
    682	val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id));
    683	val &= ~MVEBU_COMPHY_FRAME_DETECT3_LOST_TIMEOUT_EN;
    684	writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id));
    685
    686	val = readl(priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id));
    687	val |= MVEBU_COMPHY_TX_TRAIN_PRESET_16B_AUTO_EN |
    688	       MVEBU_COMPHY_TX_TRAIN_PRESET_PRBS11;
    689	writel(val, priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id));
    690
    691	val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id));
    692	val &= ~MVEBU_COMPHY_FRAME_DETECT0_PATN(0x1ff);
    693	val |= MVEBU_COMPHY_FRAME_DETECT0_PATN(0x88);
    694	writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id));
    695
    696	val = readl(priv->base + MVEBU_COMPHY_DME(lane->id));
    697	val |= MVEBU_COMPHY_DME_ETH_MODE;
    698	writel(val, priv->base + MVEBU_COMPHY_DME(lane->id));
    699
    700	val = readl(priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id));
    701	val |= MVEBU_COMPHY_VDD_CAL0_CONT_MODE;
    702	writel(val, priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id));
    703
    704	val = readl(priv->base + MVEBU_SP_CALIB(lane->id));
    705	val &= ~MVEBU_SP_CALIB_SAMPLER(0x3);
    706	val |= MVEBU_SP_CALIB_SAMPLER(0x3) |
    707	       MVEBU_SP_CALIB_SAMPLER_EN;
    708	writel(val, priv->base + MVEBU_SP_CALIB(lane->id));
    709	val &= ~MVEBU_SP_CALIB_SAMPLER_EN;
    710	writel(val, priv->base + MVEBU_SP_CALIB(lane->id));
    711
    712	/* External rx regulator */
    713	val = readl(priv->base + MVEBU_COMPHY_EXT_SELV(lane->id));
    714	val &= ~MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1f);
    715	val |= MVEBU_COMPHY_EXT_SELV_RX_SAMPL(0x1a);
    716	writel(val, priv->base + MVEBU_COMPHY_EXT_SELV(lane->id));
    717
    718	return mvebu_comphy_init_plls(lane);
    719}
    720
    721static int mvebu_comphy_power_on_legacy(struct phy *phy)
    722{
    723	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
    724	struct mvebu_comphy_priv *priv = lane->priv;
    725	int ret, mux;
    726	u32 val;
    727
    728	mux = mvebu_comphy_get_mux(lane->id, lane->port,
    729				   lane->mode, lane->submode);
    730	if (mux < 0)
    731		return -ENOTSUPP;
    732
    733	regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
    734	val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
    735	regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
    736
    737	regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
    738	val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
    739	val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id);
    740	regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
    741
    742	switch (lane->submode) {
    743	case PHY_INTERFACE_MODE_SGMII:
    744	case PHY_INTERFACE_MODE_2500BASEX:
    745		ret = mvebu_comphy_set_mode_sgmii(phy);
    746		break;
    747	case PHY_INTERFACE_MODE_RXAUI:
    748		ret = mvebu_comphy_set_mode_rxaui(phy);
    749		break;
    750	case PHY_INTERFACE_MODE_10GBASER:
    751		ret = mvebu_comphy_set_mode_10gbaser(phy);
    752		break;
    753	default:
    754		return -ENOTSUPP;
    755	}
    756
    757	/* digital reset */
    758	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    759	val |= MVEBU_COMPHY_SERDES_CFG1_RF_RESET;
    760	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    761
    762	return ret;
    763}
    764
    765static int mvebu_comphy_power_on(struct phy *phy)
    766{
    767	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
    768	struct mvebu_comphy_priv *priv = lane->priv;
    769	int fw_mode, fw_speed;
    770	u32 fw_param = 0;
    771	int ret;
    772
    773	fw_mode = mvebu_comphy_get_fw_mode(lane->id, lane->port,
    774					   lane->mode, lane->submode);
    775	if (fw_mode < 0)
    776		goto try_legacy;
    777
    778	/* Try SMC flow first */
    779	switch (lane->mode) {
    780	case PHY_MODE_ETHERNET:
    781		switch (lane->submode) {
    782		case PHY_INTERFACE_MODE_RXAUI:
    783			dev_dbg(priv->dev, "set lane %d to RXAUI mode\n",
    784				lane->id);
    785			fw_speed = 0;
    786			break;
    787		case PHY_INTERFACE_MODE_SGMII:
    788			dev_dbg(priv->dev, "set lane %d to 1000BASE-X mode\n",
    789				lane->id);
    790			fw_speed = COMPHY_FW_SPEED_1250;
    791			break;
    792		case PHY_INTERFACE_MODE_2500BASEX:
    793			dev_dbg(priv->dev, "set lane %d to 2500BASE-X mode\n",
    794				lane->id);
    795			fw_speed = COMPHY_FW_SPEED_3125;
    796			break;
    797		case PHY_INTERFACE_MODE_5GBASER:
    798			dev_dbg(priv->dev, "set lane %d to 5GBASE-R mode\n",
    799				lane->id);
    800			fw_speed = COMPHY_FW_SPEED_515625;
    801			break;
    802		case PHY_INTERFACE_MODE_10GBASER:
    803			dev_dbg(priv->dev, "set lane %d to 10GBASE-R mode\n",
    804				lane->id);
    805			fw_speed = COMPHY_FW_SPEED_103125;
    806			break;
    807		default:
    808			dev_err(priv->dev, "unsupported Ethernet mode (%d)\n",
    809				lane->submode);
    810			return -ENOTSUPP;
    811		}
    812		fw_param = COMPHY_FW_PARAM_ETH(fw_mode, lane->port, fw_speed);
    813		break;
    814	case PHY_MODE_USB_HOST_SS:
    815	case PHY_MODE_USB_DEVICE_SS:
    816		dev_dbg(priv->dev, "set lane %d to USB3 mode\n", lane->id);
    817		fw_param = COMPHY_FW_PARAM(fw_mode, lane->port);
    818		break;
    819	case PHY_MODE_SATA:
    820		dev_dbg(priv->dev, "set lane %d to SATA mode\n", lane->id);
    821		fw_param = COMPHY_FW_PARAM(fw_mode, lane->port);
    822		break;
    823	case PHY_MODE_PCIE:
    824		dev_dbg(priv->dev, "set lane %d to PCIe mode (x%d)\n", lane->id,
    825			lane->submode);
    826		fw_param = COMPHY_FW_PARAM_PCIE(fw_mode, lane->port,
    827						lane->submode);
    828		break;
    829	default:
    830		dev_err(priv->dev, "unsupported PHY mode (%d)\n", lane->mode);
    831		return -ENOTSUPP;
    832	}
    833
    834	ret = mvebu_comphy_smc(COMPHY_SIP_POWER_ON, priv->cp_phys, lane->id,
    835			       fw_param);
    836	if (!ret)
    837		return ret;
    838
    839	if (ret == -EOPNOTSUPP)
    840		dev_err(priv->dev,
    841			"unsupported SMC call, try updating your firmware\n");
    842
    843	dev_warn(priv->dev,
    844		 "Firmware could not configure PHY %d with mode %d (ret: %d), trying legacy method\n",
    845		 lane->id, lane->mode, ret);
    846
    847try_legacy:
    848	/* Fallback to Linux's implementation */
    849	return mvebu_comphy_power_on_legacy(phy);
    850}
    851
    852static int mvebu_comphy_set_mode(struct phy *phy,
    853				 enum phy_mode mode, int submode)
    854{
    855	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
    856
    857	if (submode == PHY_INTERFACE_MODE_1000BASEX)
    858		submode = PHY_INTERFACE_MODE_SGMII;
    859
    860	if (mvebu_comphy_get_fw_mode(lane->id, lane->port, mode, submode) < 0)
    861		return -EINVAL;
    862
    863	lane->mode = mode;
    864	lane->submode = submode;
    865
    866	/* PCIe submode represents the width */
    867	if (mode == PHY_MODE_PCIE && !lane->submode)
    868		lane->submode = 1;
    869
    870	return 0;
    871}
    872
    873static int mvebu_comphy_power_off_legacy(struct phy *phy)
    874{
    875	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
    876	struct mvebu_comphy_priv *priv = lane->priv;
    877	u32 val;
    878
    879	val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    880	val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET |
    881		 MVEBU_COMPHY_SERDES_CFG1_CORE_RESET |
    882		 MVEBU_COMPHY_SERDES_CFG1_RF_RESET);
    883	writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
    884
    885	regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
    886	val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
    887	regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
    888
    889	regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
    890	val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
    891	regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
    892
    893	return 0;
    894}
    895
    896static int mvebu_comphy_power_off(struct phy *phy)
    897{
    898	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
    899	struct mvebu_comphy_priv *priv = lane->priv;
    900	int ret;
    901
    902	ret = mvebu_comphy_smc(COMPHY_SIP_POWER_OFF, priv->cp_phys,
    903			       lane->id, 0);
    904	if (!ret)
    905		return ret;
    906
    907	/* Fallback to Linux's implementation */
    908	return mvebu_comphy_power_off_legacy(phy);
    909}
    910
    911static const struct phy_ops mvebu_comphy_ops = {
    912	.power_on	= mvebu_comphy_power_on,
    913	.power_off	= mvebu_comphy_power_off,
    914	.set_mode	= mvebu_comphy_set_mode,
    915	.owner		= THIS_MODULE,
    916};
    917
    918static struct phy *mvebu_comphy_xlate(struct device *dev,
    919				      struct of_phandle_args *args)
    920{
    921	struct mvebu_comphy_lane *lane;
    922	struct phy *phy;
    923
    924	if (WARN_ON(args->args[0] >= MVEBU_COMPHY_PORTS))
    925		return ERR_PTR(-EINVAL);
    926
    927	phy = of_phy_simple_xlate(dev, args);
    928	if (IS_ERR(phy))
    929		return phy;
    930
    931	lane = phy_get_drvdata(phy);
    932	lane->port = args->args[0];
    933
    934	return phy;
    935}
    936
    937static int mvebu_comphy_init_clks(struct mvebu_comphy_priv *priv)
    938{
    939	int ret;
    940
    941	priv->mg_domain_clk = devm_clk_get(priv->dev, "mg_clk");
    942	if (IS_ERR(priv->mg_domain_clk))
    943		return PTR_ERR(priv->mg_domain_clk);
    944
    945	ret = clk_prepare_enable(priv->mg_domain_clk);
    946	if (ret < 0)
    947		return ret;
    948
    949	priv->mg_core_clk = devm_clk_get(priv->dev, "mg_core_clk");
    950	if (IS_ERR(priv->mg_core_clk)) {
    951		ret = PTR_ERR(priv->mg_core_clk);
    952		goto dis_mg_domain_clk;
    953	}
    954
    955	ret = clk_prepare_enable(priv->mg_core_clk);
    956	if (ret < 0)
    957		goto dis_mg_domain_clk;
    958
    959	priv->axi_clk = devm_clk_get(priv->dev, "axi_clk");
    960	if (IS_ERR(priv->axi_clk)) {
    961		ret = PTR_ERR(priv->axi_clk);
    962		goto dis_mg_core_clk;
    963	}
    964
    965	ret = clk_prepare_enable(priv->axi_clk);
    966	if (ret < 0)
    967		goto dis_mg_core_clk;
    968
    969	return 0;
    970
    971dis_mg_core_clk:
    972	clk_disable_unprepare(priv->mg_core_clk);
    973
    974dis_mg_domain_clk:
    975	clk_disable_unprepare(priv->mg_domain_clk);
    976
    977	priv->mg_domain_clk = NULL;
    978	priv->mg_core_clk = NULL;
    979	priv->axi_clk = NULL;
    980
    981	return ret;
    982};
    983
    984static void mvebu_comphy_disable_unprepare_clks(struct mvebu_comphy_priv *priv)
    985{
    986	if (priv->axi_clk)
    987		clk_disable_unprepare(priv->axi_clk);
    988
    989	if (priv->mg_core_clk)
    990		clk_disable_unprepare(priv->mg_core_clk);
    991
    992	if (priv->mg_domain_clk)
    993		clk_disable_unprepare(priv->mg_domain_clk);
    994}
    995
    996static int mvebu_comphy_probe(struct platform_device *pdev)
    997{
    998	struct mvebu_comphy_priv *priv;
    999	struct phy_provider *provider;
   1000	struct device_node *child;
   1001	struct resource *res;
   1002	int ret;
   1003
   1004	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
   1005	if (!priv)
   1006		return -ENOMEM;
   1007
   1008	priv->dev = &pdev->dev;
   1009	priv->regmap =
   1010		syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
   1011						"marvell,system-controller");
   1012	if (IS_ERR(priv->regmap))
   1013		return PTR_ERR(priv->regmap);
   1014	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
   1015	priv->base = devm_ioremap_resource(&pdev->dev, res);
   1016	if (IS_ERR(priv->base))
   1017		return PTR_ERR(priv->base);
   1018
   1019	/*
   1020	 * Ignore error if clocks have not been initialized properly for DT
   1021	 * compatibility reasons.
   1022	 */
   1023	ret = mvebu_comphy_init_clks(priv);
   1024	if (ret) {
   1025		if (ret == -EPROBE_DEFER)
   1026			return ret;
   1027		dev_warn(&pdev->dev, "cannot initialize clocks\n");
   1028	}
   1029
   1030	/*
   1031	 * Hack to retrieve a physical offset relative to this CP that will be
   1032	 * given to the firmware
   1033	 */
   1034	priv->cp_phys = res->start;
   1035
   1036	for_each_available_child_of_node(pdev->dev.of_node, child) {
   1037		struct mvebu_comphy_lane *lane;
   1038		struct phy *phy;
   1039		u32 val;
   1040
   1041		ret = of_property_read_u32(child, "reg", &val);
   1042		if (ret < 0) {
   1043			dev_err(&pdev->dev, "missing 'reg' property (%d)\n",
   1044				ret);
   1045			continue;
   1046		}
   1047
   1048		if (val >= MVEBU_COMPHY_LANES) {
   1049			dev_err(&pdev->dev, "invalid 'reg' property\n");
   1050			continue;
   1051		}
   1052
   1053		lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL);
   1054		if (!lane) {
   1055			of_node_put(child);
   1056			ret = -ENOMEM;
   1057			goto disable_clks;
   1058		}
   1059
   1060		phy = devm_phy_create(&pdev->dev, child, &mvebu_comphy_ops);
   1061		if (IS_ERR(phy)) {
   1062			of_node_put(child);
   1063			ret = PTR_ERR(phy);
   1064			goto disable_clks;
   1065		}
   1066
   1067		lane->priv = priv;
   1068		lane->mode = PHY_MODE_INVALID;
   1069		lane->submode = PHY_INTERFACE_MODE_NA;
   1070		lane->id = val;
   1071		lane->port = -1;
   1072		phy_set_drvdata(phy, lane);
   1073
   1074		/*
   1075		 * All modes are supported in this driver so we could call
   1076		 * mvebu_comphy_power_off(phy) here to avoid relying on the
   1077		 * bootloader/firmware configuration, but for compatibility
   1078		 * reasons we cannot de-configure the COMPHY without being sure
   1079		 * that the firmware is up-to-date and fully-featured.
   1080		 */
   1081	}
   1082
   1083	dev_set_drvdata(&pdev->dev, priv);
   1084	provider = devm_of_phy_provider_register(&pdev->dev,
   1085						 mvebu_comphy_xlate);
   1086
   1087	return PTR_ERR_OR_ZERO(provider);
   1088
   1089disable_clks:
   1090	mvebu_comphy_disable_unprepare_clks(priv);
   1091
   1092	return ret;
   1093}
   1094
   1095static const struct of_device_id mvebu_comphy_of_match_table[] = {
   1096	{ .compatible = "marvell,comphy-cp110" },
   1097	{ },
   1098};
   1099MODULE_DEVICE_TABLE(of, mvebu_comphy_of_match_table);
   1100
   1101static struct platform_driver mvebu_comphy_driver = {
   1102	.probe	= mvebu_comphy_probe,
   1103	.driver	= {
   1104		.name = "mvebu-comphy",
   1105		.of_match_table = mvebu_comphy_of_match_table,
   1106	},
   1107};
   1108module_platform_driver(mvebu_comphy_driver);
   1109
   1110MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>");
   1111MODULE_DESCRIPTION("Common PHY driver for mvebu SoCs");
   1112MODULE_LICENSE("GPL v2");