Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
   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");