dp83867.c 11.9 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2 3 4 5 6 7 8 9 10 11 12 13
/*
 * Driver for the Texas Instruments DP83867 PHY
 *
 * Copyright (C) 2015 Texas Instruments Inc.
 */

#include <linux/ethtool.h>
#include <linux/kernel.h>
#include <linux/mii.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy.h>
14
#include <linux/delay.h>
15 16 17 18 19 20 21 22 23 24

#include <dt-bindings/net/ti-dp83867.h>

#define DP83867_PHY_ID		0x2000a231
#define DP83867_DEVADDR		0x1f

#define MII_DP83867_PHYCTRL	0x10
#define MII_DP83867_MICR	0x12
#define MII_DP83867_ISR		0x13
#define DP83867_CTRL		0x1f
25
#define DP83867_CFG3		0x1e
26 27

/* Extended Registers */
28
#define DP83867_CFG4            0x0031
29
#define DP83867_RGMIICTL	0x0032
30
#define DP83867_STRAP_STS1	0x006E
31
#define DP83867_STRAP_STS2	0x006f
32
#define DP83867_RGMIIDCTL	0x0086
33
#define DP83867_IO_MUX_CFG	0x0170
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

#define DP83867_SW_RESET	BIT(15)
#define DP83867_SW_RESTART	BIT(14)

/* MICR Interrupt bits */
#define MII_DP83867_MICR_AN_ERR_INT_EN		BIT(15)
#define MII_DP83867_MICR_SPEED_CHNG_INT_EN	BIT(14)
#define MII_DP83867_MICR_DUP_MODE_CHNG_INT_EN	BIT(13)
#define MII_DP83867_MICR_PAGE_RXD_INT_EN	BIT(12)
#define MII_DP83867_MICR_AUTONEG_COMP_INT_EN	BIT(11)
#define MII_DP83867_MICR_LINK_STS_CHNG_INT_EN	BIT(10)
#define MII_DP83867_MICR_FALSE_CARRIER_INT_EN	BIT(8)
#define MII_DP83867_MICR_SLEEP_MODE_CHNG_INT_EN	BIT(4)
#define MII_DP83867_MICR_WOL_INT_EN		BIT(3)
#define MII_DP83867_MICR_XGMII_ERR_INT_EN	BIT(2)
#define MII_DP83867_MICR_POL_CHNG_INT_EN	BIT(1)
#define MII_DP83867_MICR_JABBER_INT_EN		BIT(0)

/* RGMIICTL bits */
#define DP83867_RGMII_TX_CLK_DELAY_EN		BIT(1)
#define DP83867_RGMII_RX_CLK_DELAY_EN		BIT(0)

56 57 58
/* STRAP_STS1 bits */
#define DP83867_STRAP_STS1_RESERVED		BIT(11)

59 60 61 62 63 64 65
/* STRAP_STS2 bits */
#define DP83867_STRAP_STS2_CLK_SKEW_TX_MASK	GENMASK(6, 4)
#define DP83867_STRAP_STS2_CLK_SKEW_TX_SHIFT	4
#define DP83867_STRAP_STS2_CLK_SKEW_RX_MASK	GENMASK(2, 0)
#define DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT	0
#define DP83867_STRAP_STS2_CLK_SKEW_NONE	BIT(2)

66 67
/* PHY CTRL bits */
#define DP83867_PHYCR_FIFO_DEPTH_SHIFT		14
68
#define DP83867_PHYCR_FIFO_DEPTH_MASK		(3 << 14)
69
#define DP83867_PHYCR_RESERVED_MASK		BIT(11)
70 71

/* RGMIIDCTL bits */
72
#define DP83867_RGMII_TX_CLK_DELAY_MAX		0xf
73
#define DP83867_RGMII_TX_CLK_DELAY_SHIFT	4
74 75
#define DP83867_RGMII_RX_CLK_DELAY_MAX		0xf
#define DP83867_RGMII_RX_CLK_DELAY_SHIFT	0
76

77 78 79 80 81
/* IO_MUX_CFG bits */
#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL	0x1f

#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX	0x0
#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN	0x1f
82
#define DP83867_IO_MUX_CFG_CLK_O_DISABLE	BIT(6)
83 84
#define DP83867_IO_MUX_CFG_CLK_O_SEL_MASK	(0x1f << 8)
#define DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT	8
85

86 87 88 89 90 91 92 93 94
/* CFG4 bits */
#define DP83867_CFG4_PORT_MIRROR_EN              BIT(0)

enum {
	DP83867_PORT_MIRROING_KEEP,
	DP83867_PORT_MIRROING_EN,
	DP83867_PORT_MIRROING_DIS,
};

95 96 97 98
struct dp83867_private {
	int rx_id_delay;
	int tx_id_delay;
	int fifo_depth;
99
	int io_impedance;
100
	int port_mirroring;
101
	bool rxctrl_strap_quirk;
102 103
	bool set_clk_output;
	u32 clk_output_sel;
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
};

static int dp83867_ack_interrupt(struct phy_device *phydev)
{
	int err = phy_read(phydev, MII_DP83867_ISR);

	if (err < 0)
		return err;

	return 0;
}

static int dp83867_config_intr(struct phy_device *phydev)
{
	int micr_status;

	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
		micr_status = phy_read(phydev, MII_DP83867_MICR);
		if (micr_status < 0)
			return micr_status;

		micr_status |=
			(MII_DP83867_MICR_AN_ERR_INT_EN |
			MII_DP83867_MICR_SPEED_CHNG_INT_EN |
128 129
			MII_DP83867_MICR_AUTONEG_COMP_INT_EN |
			MII_DP83867_MICR_LINK_STS_CHNG_INT_EN |
130 131 132 133 134 135 136 137 138 139
			MII_DP83867_MICR_DUP_MODE_CHNG_INT_EN |
			MII_DP83867_MICR_SLEEP_MODE_CHNG_INT_EN);

		return phy_write(phydev, MII_DP83867_MICR, micr_status);
	}

	micr_status = 0x0;
	return phy_write(phydev, MII_DP83867_MICR, micr_status);
}

140 141 142 143 144 145
static int dp83867_config_port_mirroring(struct phy_device *phydev)
{
	struct dp83867_private *dp83867 =
		(struct dp83867_private *)phydev->priv;

	if (dp83867->port_mirroring == DP83867_PORT_MIRROING_EN)
146 147
		phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
				 DP83867_CFG4_PORT_MIRROR_EN);
148
	else
149 150
		phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
				   DP83867_CFG4_PORT_MIRROR_EN);
151 152 153
	return 0;
}

154 155 156 157
#ifdef CONFIG_OF_MDIO
static int dp83867_of_init(struct phy_device *phydev)
{
	struct dp83867_private *dp83867 = phydev->priv;
A
Andrew Lunn 已提交
158
	struct device *dev = &phydev->mdio.dev;
159 160 161
	struct device_node *of_node = dev->of_node;
	int ret;

162
	if (!of_node)
163 164
		return -ENODEV;

165 166 167
	dp83867->io_impedance = -EINVAL;

	/* Optional configuration */
168 169
	ret = of_property_read_u32(of_node, "ti,clk-output-sel",
				   &dp83867->clk_output_sel);
170 171 172 173 174
	/* If not set, keep default */
	if (!ret) {
		dp83867->set_clk_output = true;
		/* Valid values are 0 to DP83867_CLK_O_SEL_REF_CLK or
		 * DP83867_CLK_O_SEL_OFF.
175
		 */
176 177 178 179 180 181 182
		if (dp83867->clk_output_sel > DP83867_CLK_O_SEL_REF_CLK &&
		    dp83867->clk_output_sel != DP83867_CLK_O_SEL_OFF) {
			phydev_err(phydev, "ti,clk-output-sel value %u out of range\n",
				   dp83867->clk_output_sel);
			return -EINVAL;
		}
	}
183

184 185 186 187 188
	if (of_property_read_bool(of_node, "ti,max-output-impedance"))
		dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX;
	else if (of_property_read_bool(of_node, "ti,min-output-impedance"))
		dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN;

189 190 191
	dp83867->rxctrl_strap_quirk = of_property_read_bool(of_node,
					"ti,dp83867-rxctrl-strap-quirk");

192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
	/* Existing behavior was to use default pin strapping delay in rgmii
	 * mode, but rgmii should have meant no delay.  Warn existing users.
	 */
	if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
		const u16 val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS2);
		const u16 txskew = (val & DP83867_STRAP_STS2_CLK_SKEW_TX_MASK) >>
				   DP83867_STRAP_STS2_CLK_SKEW_TX_SHIFT;
		const u16 rxskew = (val & DP83867_STRAP_STS2_CLK_SKEW_RX_MASK) >>
				   DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT;

		if (txskew != DP83867_STRAP_STS2_CLK_SKEW_NONE ||
		    rxskew != DP83867_STRAP_STS2_CLK_SKEW_NONE)
			phydev_warn(phydev,
				    "PHY has delays via pin strapping, but phy-mode = 'rgmii'\n"
				    "Should be 'rgmii-id' to use internal delays\n");
	}
208

209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
	/* RX delay *must* be specified if internal delay of RX is used. */
	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
	    phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
		ret = of_property_read_u32(of_node, "ti,rx-internal-delay",
					   &dp83867->rx_id_delay);
		if (ret) {
			phydev_err(phydev, "ti,rx-internal-delay must be specified\n");
			return ret;
		}
		if (dp83867->rx_id_delay > DP83867_RGMII_RX_CLK_DELAY_MAX) {
			phydev_err(phydev,
				   "ti,rx-internal-delay value of %u out of range\n",
				   dp83867->rx_id_delay);
			return -EINVAL;
		}
	}

	/* TX delay *must* be specified if internal delay of RX is used. */
	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
		ret = of_property_read_u32(of_node, "ti,tx-internal-delay",
					   &dp83867->tx_id_delay);
		if (ret) {
			phydev_err(phydev, "ti,tx-internal-delay must be specified\n");
			return ret;
		}
		if (dp83867->tx_id_delay > DP83867_RGMII_TX_CLK_DELAY_MAX) {
			phydev_err(phydev,
				   "ti,tx-internal-delay value of %u out of range\n",
				   dp83867->tx_id_delay);
			return -EINVAL;
		}
	}
242

243 244 245 246 247 248
	if (of_property_read_bool(of_node, "enet-phy-lane-swap"))
		dp83867->port_mirroring = DP83867_PORT_MIRROING_EN;

	if (of_property_read_bool(of_node, "enet-phy-lane-no-swap"))
		dp83867->port_mirroring = DP83867_PORT_MIRROING_DIS;

249
	return of_property_read_u32(of_node, "ti,fifo-depth",
250 251 252 253 254 255 256 257 258 259 260 261
				   &dp83867->fifo_depth);
}
#else
static int dp83867_of_init(struct phy_device *phydev)
{
	return 0;
}
#endif /* CONFIG_OF_MDIO */

static int dp83867_config_init(struct phy_device *phydev)
{
	struct dp83867_private *dp83867;
262
	int ret, val, bs;
263
	u16 delay;
264 265

	if (!phydev->priv) {
A
Andrew Lunn 已提交
266
		dp83867 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83867),
267 268 269 270 271 272 273 274 275 276 277 278
				       GFP_KERNEL);
		if (!dp83867)
			return -ENOMEM;

		phydev->priv = dp83867;
		ret = dp83867_of_init(phydev);
		if (ret)
			return ret;
	} else {
		dp83867 = (struct dp83867_private *)phydev->priv;
	}

279
	/* RX_DV/RX_CTRL strapped in mode 1 or mode 2 workaround */
280 281 282
	if (dp83867->rxctrl_strap_quirk)
		phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
				   BIT(7));
283

284
	if (phy_interface_is_rgmii(phydev)) {
285 286 287 288 289
		val = phy_read(phydev, MII_DP83867_PHYCTRL);
		if (val < 0)
			return val;
		val &= ~DP83867_PHYCR_FIFO_DEPTH_MASK;
		val |= (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT);
290 291 292 293 294 295 296 297 298 299 300

		/* The code below checks if "port mirroring" N/A MODE4 has been
		 * enabled during power on bootstrap.
		 *
		 * Such N/A mode enabled by mistake can put PHY IC in some
		 * internal testing mode and disable RGMII transmission.
		 *
		 * In this particular case one needs to check STRAP_STS1
		 * register's bit 11 (marked as RESERVED).
		 */

301
		bs = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS1);
302 303 304
		if (bs & DP83867_STRAP_STS1_RESERVED)
			val &= ~DP83867_PHYCR_RESERVED_MASK;

305
		ret = phy_write(phydev, MII_DP83867_PHYCTRL, val);
306 307 308 309
		if (ret)
			return ret;
	}

310 311 312 313 314
	/* If rgmii mode with no internal delay is selected, we do NOT use
	 * aligned mode as one might expect.  Instead we use the PHY's default
	 * based on pin strapping.  And the "mode 0" default is to *use*
	 * internal delay with a value of 7 (2.00 ns).
	 */
315
	if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) &&
316
	    (phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) {
317
		val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL);
318

319
		val &= ~(DP83867_RGMII_TX_CLK_DELAY_EN | DP83867_RGMII_RX_CLK_DELAY_EN);
320 321 322 323 324 325 326 327 328
		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
			val |= (DP83867_RGMII_TX_CLK_DELAY_EN | DP83867_RGMII_RX_CLK_DELAY_EN);

		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
			val |= DP83867_RGMII_TX_CLK_DELAY_EN;

		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
			val |= DP83867_RGMII_RX_CLK_DELAY_EN;

329
		phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL, val);
330 331 332 333

		delay = (dp83867->rx_id_delay |
			(dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT));

334 335
		phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIIDCTL,
			      delay);
336

337 338 339 340 341
		if (dp83867->io_impedance >= 0)
			phy_modify_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG,
				       DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL,
				       dp83867->io_impedance &
				       DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL);
342 343
	}

344 345 346 347 348 349 350
	/* Enable Interrupt output INT_OE in CFG3 register */
	if (phy_interrupt_is_valid(phydev)) {
		val = phy_read(phydev, DP83867_CFG3);
		val |= BIT(7);
		phy_write(phydev, DP83867_CFG3, val);
	}

351 352 353
	if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP)
		dp83867_config_port_mirroring(phydev);

354
	/* Clock output selection if muxing property is set */
355 356 357 358 359 360 361 362 363 364 365
	if (dp83867->set_clk_output) {
		u16 mask = DP83867_IO_MUX_CFG_CLK_O_DISABLE;

		if (dp83867->clk_output_sel == DP83867_CLK_O_SEL_OFF) {
			val = DP83867_IO_MUX_CFG_CLK_O_DISABLE;
		} else {
			mask |= DP83867_IO_MUX_CFG_CLK_O_SEL_MASK;
			val = dp83867->clk_output_sel <<
			      DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT;
		}

366
		phy_modify_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG,
367 368
			       mask, val);
	}
369

370 371 372 373 374 375 376 377 378 379 380
	return 0;
}

static int dp83867_phy_reset(struct phy_device *phydev)
{
	int err;

	err = phy_write(phydev, DP83867_CTRL, DP83867_SW_RESET);
	if (err < 0)
		return err;

381 382
	usleep_range(10, 20);

383 384 385 386 387 388 389 390
	return dp83867_config_init(phydev);
}

static struct phy_driver dp83867_driver[] = {
	{
		.phy_id		= DP83867_PHY_ID,
		.phy_id_mask	= 0xfffffff0,
		.name		= "TI DP83867",
391
		/* PHY_GBIT_FEATURES */
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414

		.config_init	= dp83867_config_init,
		.soft_reset	= dp83867_phy_reset,

		/* IRQ related */
		.ack_interrupt	= dp83867_ack_interrupt,
		.config_intr	= dp83867_config_intr,

		.suspend	= genphy_suspend,
		.resume		= genphy_resume,
	},
};
module_phy_driver(dp83867_driver);

static struct mdio_device_id __maybe_unused dp83867_tbl[] = {
	{ DP83867_PHY_ID, 0xfffffff0 },
	{ }
};

MODULE_DEVICE_TABLE(mdio, dp83867_tbl);

MODULE_DESCRIPTION("Texas Instruments DP83867 PHY driver");
MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com");
415
MODULE_LICENSE("GPL v2");