Linux Audio

Check our new training course

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