Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e5f9f28 authored by Martin Blumenstingl's avatar Martin Blumenstingl Committed by David S. Miller
Browse files

net: phy: at803x: Allow specifying the RGMII RX clock delay via phy mode



at803x currently automatically enables the RGMII TX clock delay when the
phy interface mode is PHY_INTERFACE_MODE_RGMII_TXID. The same should be
done when PHY_INTERFACE_MODE_RGMII_ID is specified.
Use a similar logic to enable the RGMII RX clock delay as well.
at803x_context_{save,restore} were not touched because these are only
used on AR8030 which is a RMII phy (RGMII clock delays are irrelevant).

Signed-off-by: default avatarMartin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e15bb4c6
Loading
Loading
Loading
Loading
+54 −9
Original line number Original line Diff line number Diff line
@@ -36,8 +36,10 @@
#define AT803X_INSR				0x0013
#define AT803X_INSR				0x0013
#define AT803X_DEBUG_ADDR			0x1D
#define AT803X_DEBUG_ADDR			0x1D
#define AT803X_DEBUG_DATA			0x1E
#define AT803X_DEBUG_DATA			0x1E
#define AT803X_DEBUG_SYSTEM_MODE_CTRL		0x05
#define AT803X_DEBUG_REG_0			0x00
#define AT803X_DEBUG_RGMII_TX_CLK_DLY		BIT(8)
#define AT803X_DEBUG_RX_CLK_DLY_EN		BIT(15)
#define AT803X_DEBUG_REG_5			0x05
#define AT803X_DEBUG_TX_CLK_DLY_EN		BIT(8)


#define ATH8030_PHY_ID 0x004dd076
#define ATH8030_PHY_ID 0x004dd076
#define ATH8031_PHY_ID 0x004dd074
#define ATH8031_PHY_ID 0x004dd074
@@ -61,6 +63,46 @@ struct at803x_context {
	u16 led_control;
	u16 led_control;
};
};


static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
{
	int ret;

	ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
	if (ret < 0)
		return ret;

	return phy_read(phydev, AT803X_DEBUG_DATA);
}

static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
				 u16 clear, u16 set)
{
	u16 val;
	int ret;

	ret = at803x_debug_reg_read(phydev, reg);
	if (ret < 0)
		return ret;

	val = ret & 0xffff;
	val &= ~clear;
	val |= set;

	return phy_write(phydev, AT803X_DEBUG_DATA, val);
}

static inline int at803x_enable_rx_delay(struct phy_device *phydev)
{
	return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
					AT803X_DEBUG_RX_CLK_DLY_EN);
}

static inline int at803x_enable_tx_delay(struct phy_device *phydev)
{
	return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
					AT803X_DEBUG_TX_CLK_DLY_EN);
}

/* save relevant PHY registers to private copy */
/* save relevant PHY registers to private copy */
static void at803x_context_save(struct phy_device *phydev,
static void at803x_context_save(struct phy_device *phydev,
				struct at803x_context *context)
				struct at803x_context *context)
@@ -217,14 +259,17 @@ static int at803x_config_init(struct phy_device *phydev)
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
		ret = phy_write(phydev, AT803X_DEBUG_ADDR,
			phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
				AT803X_DEBUG_SYSTEM_MODE_CTRL);
		ret = at803x_enable_rx_delay(phydev);
		if (ret)
		if (ret < 0)
			return ret;
			return ret;
		ret = phy_write(phydev, AT803X_DEBUG_DATA,
	}
				AT803X_DEBUG_RGMII_TX_CLK_DLY);

		if (ret)
	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
			phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
		ret = at803x_enable_tx_delay(phydev);
		if (ret < 0)
			return ret;
			return ret;
	}
	}