Merge branch 'master' of git://git.denx.de/u-boot-net
- Various PHY fixes / enhancements. - TI K2G fixes
This commit is contained in:
commit
eb511984e9
@ -44,28 +44,28 @@
|
||||
reg = <0x1>;
|
||||
interrupt-parent = <&pioB>;
|
||||
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
|
||||
txen-skew-ps = <800>;
|
||||
txc-skew-ps = <3000>;
|
||||
rxdv-skew-ps = <400>;
|
||||
rxc-skew-ps = <3000>;
|
||||
rxd0-skew-ps = <400>;
|
||||
rxd1-skew-ps = <400>;
|
||||
rxd2-skew-ps = <400>;
|
||||
rxd3-skew-ps = <400>;
|
||||
txen-skew-ps = <480>;
|
||||
txc-skew-ps = <1800>;
|
||||
rxdv-skew-ps = <240>;
|
||||
rxc-skew-ps = <1800>;
|
||||
rxd0-skew-ps = <240>;
|
||||
rxd1-skew-ps = <240>;
|
||||
rxd2-skew-ps = <240>;
|
||||
rxd3-skew-ps = <240>;
|
||||
};
|
||||
|
||||
ethernet-phy@7 {
|
||||
reg = <0x7>;
|
||||
interrupt-parent = <&pioB>;
|
||||
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
|
||||
txen-skew-ps = <800>;
|
||||
txc-skew-ps = <3000>;
|
||||
rxdv-skew-ps = <400>;
|
||||
rxc-skew-ps = <3000>;
|
||||
rxd0-skew-ps = <400>;
|
||||
rxd1-skew-ps = <400>;
|
||||
rxd2-skew-ps = <400>;
|
||||
rxd3-skew-ps = <400>;
|
||||
txen-skew-ps = <480>;
|
||||
txc-skew-ps = <1800>;
|
||||
rxdv-skew-ps = <240>;
|
||||
rxc-skew-ps = <1800>;
|
||||
rxd0-skew-ps = <240>;
|
||||
rxd1-skew-ps = <240>;
|
||||
rxd2-skew-ps = <240>;
|
||||
rxd3-skew-ps = <240>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -43,28 +43,28 @@
|
||||
reg = <0x1>;
|
||||
interrupt-parent = <&pioB>;
|
||||
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
|
||||
txen-skew-ps = <800>;
|
||||
txc-skew-ps = <3000>;
|
||||
rxdv-skew-ps = <400>;
|
||||
rxc-skew-ps = <3000>;
|
||||
rxd0-skew-ps = <400>;
|
||||
rxd1-skew-ps = <400>;
|
||||
rxd2-skew-ps = <400>;
|
||||
rxd3-skew-ps = <400>;
|
||||
txen-skew-ps = <480>;
|
||||
txc-skew-ps = <1800>;
|
||||
rxdv-skew-ps = <240>;
|
||||
rxc-skew-ps = <1800>;
|
||||
rxd0-skew-ps = <240>;
|
||||
rxd1-skew-ps = <240>;
|
||||
rxd2-skew-ps = <240>;
|
||||
rxd3-skew-ps = <240>;
|
||||
};
|
||||
|
||||
ethernet-phy@7 {
|
||||
reg = <0x7>;
|
||||
interrupt-parent = <&pioB>;
|
||||
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
|
||||
txen-skew-ps = <800>;
|
||||
txc-skew-ps = <3000>;
|
||||
rxdv-skew-ps = <400>;
|
||||
rxc-skew-ps = <3000>;
|
||||
rxd0-skew-ps = <400>;
|
||||
rxd1-skew-ps = <400>;
|
||||
rxd2-skew-ps = <400>;
|
||||
rxd3-skew-ps = <400>;
|
||||
txen-skew-ps = <480>;
|
||||
txc-skew-ps = <1800>;
|
||||
rxdv-skew-ps = <240>;
|
||||
rxc-skew-ps = <1800>;
|
||||
rxd0-skew-ps = <240>;
|
||||
rxd1-skew-ps = <240>;
|
||||
rxd2-skew-ps = <240>;
|
||||
rxd3-skew-ps = <240>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -67,9 +67,9 @@
|
||||
rxd2-skew-ps = <0>;
|
||||
rxd3-skew-ps = <0>;
|
||||
txen-skew-ps = <0>;
|
||||
txc-skew-ps = <2600>;
|
||||
txc-skew-ps = <1560>;
|
||||
rxdv-skew-ps = <0>;
|
||||
rxc-skew-ps = <2000>;
|
||||
rxc-skew-ps = <1200>;
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
|
@ -43,9 +43,9 @@
|
||||
rxd2-skew-ps = <0>;
|
||||
rxd3-skew-ps = <0>;
|
||||
txen-skew-ps = <0>;
|
||||
txc-skew-ps = <2600>;
|
||||
txc-skew-ps = <1560>;
|
||||
rxdv-skew-ps = <0>;
|
||||
rxc-skew-ps = <2000>;
|
||||
rxc-skew-ps = <1200>;
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
|
@ -71,9 +71,9 @@
|
||||
rxd2-skew-ps = <0>;
|
||||
rxd3-skew-ps = <0>;
|
||||
txen-skew-ps = <0>;
|
||||
txc-skew-ps = <2600>;
|
||||
txc-skew-ps = <1560>;
|
||||
rxdv-skew-ps = <0>;
|
||||
rxc-skew-ps = <2000>;
|
||||
rxc-skew-ps = <1200>;
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
|
@ -128,9 +128,9 @@
|
||||
rxd2-skew-ps = <0>;
|
||||
rxd3-skew-ps = <0>;
|
||||
txen-skew-ps = <0>;
|
||||
txc-skew-ps = <2600>;
|
||||
txc-skew-ps = <1560>;
|
||||
rxdv-skew-ps = <0>;
|
||||
rxc-skew-ps = <2000>;
|
||||
rxc-skew-ps = <1200>;
|
||||
};
|
||||
|
||||
&gpio0 { /* GPIO 0..29 */
|
||||
|
@ -85,9 +85,9 @@
|
||||
rxd2-skew-ps = <0>;
|
||||
rxd3-skew-ps = <0>;
|
||||
txen-skew-ps = <0>;
|
||||
txc-skew-ps = <2600>;
|
||||
txc-skew-ps = <1560>;
|
||||
rxdv-skew-ps = <0>;
|
||||
rxc-skew-ps = <2000>;
|
||||
rxc-skew-ps = <1200>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -126,22 +126,22 @@ struct pin_cfg k2g_evm_pin_cfg[] = {
|
||||
{ 71, MODE(0) }, /* MMC1POW TP124 */
|
||||
|
||||
/* EMAC */
|
||||
{ 79, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD1 */
|
||||
{ 78, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD2 */
|
||||
{ 77, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD3 */
|
||||
{ 80, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD0 */
|
||||
{ 94, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD0 */
|
||||
{ 93, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD1 */
|
||||
{ 92, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD2 */
|
||||
{ 91, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD3 */
|
||||
{ 85, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXC */
|
||||
{ 95, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXCTL */
|
||||
{ 72, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXC */
|
||||
{ 77, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD3 */
|
||||
{ 78, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD2 */
|
||||
{ 79, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD1 */
|
||||
{ 80, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD0 */
|
||||
{ 81, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXCTL */
|
||||
{ 85, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXC */
|
||||
{ 91, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD3 */
|
||||
{ 92, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD2 */
|
||||
{ 93, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD1 */
|
||||
{ 94, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD0 */
|
||||
{ 95, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXCTL */
|
||||
|
||||
/* MDIO */
|
||||
{ 99, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_CLK */
|
||||
{ 98, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_DATA */
|
||||
{ 99, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_CLK */
|
||||
|
||||
/* PWM */
|
||||
{ 73, MODE(4) }, /* SOC_EHRPWM3A */
|
||||
@ -350,22 +350,22 @@ struct pin_cfg k2g_ice_evm_pin_cfg[] = {
|
||||
{ 135, MODE(0) }, /* SOC_QSPI_CSN0 */
|
||||
|
||||
/* EMAC */
|
||||
{ 79, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD1 */
|
||||
{ 78, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD2 */
|
||||
{ 77, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD3 */
|
||||
{ 80, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD0 */
|
||||
{ 94, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD0 */
|
||||
{ 93, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD1 */
|
||||
{ 92, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD2 */
|
||||
{ 91, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD3 */
|
||||
{ 85, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXC */
|
||||
{ 95, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXCTL */
|
||||
{ 72, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXC */
|
||||
{ 77, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD3 */
|
||||
{ 78, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD2 */
|
||||
{ 79, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD1 */
|
||||
{ 80, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD0 */
|
||||
{ 81, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXCTL */
|
||||
{ 85, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXC */
|
||||
{ 91, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD3 */
|
||||
{ 92, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD2 */
|
||||
{ 93, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD1 */
|
||||
{ 94, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD0 */
|
||||
{ 95, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXCTL */
|
||||
|
||||
/* MDIO */
|
||||
{ 99, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_CLK */
|
||||
{ 98, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_DATA */
|
||||
{ 99, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_CLK */
|
||||
|
||||
{ MAX_PIN_N, }
|
||||
};
|
||||
|
27
cmd/mdio.c
27
cmd/mdio.c
@ -39,21 +39,24 @@ static int extract_range(char *input, int *plo, int *phi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mdio_write_ranges(struct phy_device *phydev, struct mii_dev *bus,
|
||||
static int mdio_write_ranges(struct mii_dev *bus,
|
||||
int addrlo,
|
||||
int addrhi, int devadlo, int devadhi,
|
||||
int reglo, int reghi, unsigned short data,
|
||||
int extended)
|
||||
{
|
||||
struct phy_device *phydev;
|
||||
int addr, devad, reg;
|
||||
int err = 0;
|
||||
|
||||
for (addr = addrlo; addr <= addrhi; addr++) {
|
||||
phydev = bus->phymap[addr];
|
||||
|
||||
for (devad = devadlo; devad <= devadhi; devad++) {
|
||||
for (reg = reglo; reg <= reghi; reg++) {
|
||||
if (!extended)
|
||||
err = bus->write(bus, addr, devad,
|
||||
reg, data);
|
||||
err = phy_write_mmd(phydev, devad,
|
||||
reg, data);
|
||||
else
|
||||
err = phydev->drv->writeext(phydev,
|
||||
addr, devad, reg, data);
|
||||
@ -68,15 +71,17 @@ err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mdio_read_ranges(struct phy_device *phydev, struct mii_dev *bus,
|
||||
static int mdio_read_ranges(struct mii_dev *bus,
|
||||
int addrlo,
|
||||
int addrhi, int devadlo, int devadhi,
|
||||
int reglo, int reghi, int extended)
|
||||
{
|
||||
int addr, devad, reg;
|
||||
struct phy_device *phydev;
|
||||
|
||||
printf("Reading from bus %s\n", bus->name);
|
||||
for (addr = addrlo; addr <= addrhi; addr++) {
|
||||
phydev = bus->phymap[addr];
|
||||
printf("PHY at address %x:\n", addr);
|
||||
|
||||
for (devad = devadlo; devad <= devadhi; devad++) {
|
||||
@ -84,7 +89,7 @@ static int mdio_read_ranges(struct phy_device *phydev, struct mii_dev *bus,
|
||||
int val;
|
||||
|
||||
if (!extended)
|
||||
val = bus->read(bus, addr, devad, reg);
|
||||
val = phy_read_mmd(phydev, devad, reg);
|
||||
else
|
||||
val = phydev->drv->readext(phydev, addr,
|
||||
devad, reg);
|
||||
@ -222,14 +227,14 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
bus = phydev->bus;
|
||||
extended = 1;
|
||||
} else {
|
||||
return -1;
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
if (!phydev->drv ||
|
||||
(!phydev->drv->writeext && (op[0] == 'w')) ||
|
||||
(!phydev->drv->readext && (op[0] == 'r'))) {
|
||||
puts("PHY does not have extended functions\n");
|
||||
return -1;
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -242,13 +247,13 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
if (pos > 1)
|
||||
if (extract_reg_range(argv[pos--], &devadlo, &devadhi,
|
||||
®lo, ®hi))
|
||||
return -1;
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
default:
|
||||
if (pos > 1)
|
||||
if (extract_phy_range(&argv[2], pos - 1, &bus,
|
||||
&phydev, &addrlo, &addrhi))
|
||||
return -1;
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -264,12 +269,12 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
|
||||
switch (op[0]) {
|
||||
case 'w':
|
||||
mdio_write_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi,
|
||||
mdio_write_ranges(bus, addrlo, addrhi, devadlo, devadhi,
|
||||
reglo, reghi, data, extended);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
mdio_read_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi,
|
||||
mdio_read_ranges(bus, addrlo, addrhi, devadlo, devadhi,
|
||||
reglo, reghi, extended);
|
||||
break;
|
||||
}
|
||||
|
@ -14,6 +14,33 @@ KSZ9021:
|
||||
value is 0, the maximum value is 1800, and it is incremented by 120ps
|
||||
steps.
|
||||
|
||||
The KSZ9021 hardware supports a range of skew values from negative to
|
||||
positive, where the specific range is property dependent. All values
|
||||
specified in the devicetree are offset by the minimum value so they
|
||||
can be represented as positive integers in the devicetree since it's
|
||||
difficult to represent a negative number in the devictree.
|
||||
|
||||
The following 4-bit values table applies to all the skew properties:
|
||||
|
||||
Pad Skew Value Delay (ps) Devicetree Value
|
||||
------------------------------------------------------
|
||||
0000 -840ps 0
|
||||
0001 -720ps 120
|
||||
0010 -600ps 240
|
||||
0011 -480ps 360
|
||||
0100 -360ps 480
|
||||
0101 -240ps 600
|
||||
0110 -120ps 720
|
||||
0111 0ps 840
|
||||
1000 120ps 960
|
||||
1001 240ps 1080
|
||||
1010 360ps 1200
|
||||
1011 480ps 1320
|
||||
1100 600ps 1440
|
||||
1101 720ps 1560
|
||||
1110 840ps 1680
|
||||
1111 960ps 1800
|
||||
|
||||
Optional properties:
|
||||
|
||||
- rxc-skew-ps : Skew control of RXC pad
|
||||
|
@ -1074,6 +1074,7 @@ int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if)
|
||||
priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
|
||||
if (!priv) {
|
||||
printf("ldpaa_eth_priv malloc() failed\n");
|
||||
free(net_dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(priv, 0, sizeof(struct ldpaa_eth_priv));
|
||||
|
@ -202,6 +202,26 @@ config RTL8211X_PHY_FORCE_MASTER
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config RTL8211F_PHY_FORCE_EEE_RXC_ON
|
||||
bool "Ethernet PHY RTL8211F: do not stop receiving the xMII clock during LPI"
|
||||
depends on PHY_REALTEK
|
||||
default n
|
||||
help
|
||||
The IEEE 802.3az-2010 (EEE) standard provides a protocol to coordinate
|
||||
transitions to/from a lower power consumption level (Low Power Idle
|
||||
mode) based on link utilization. When no packets are being
|
||||
transmitted, the system goes to Low Power Idle mode to save power.
|
||||
|
||||
Under particular circumstances this setting can cause issues where
|
||||
the PHY is unable to transmit or receive any packet when in LPI mode.
|
||||
The problem is caused when the PHY is configured to stop receiving
|
||||
the xMII clock while it is signaling LPI. For some PHYs the bit
|
||||
configuring this behavior is set by the Linux kernel, causing the
|
||||
issue in U-Boot on reboot if the PHY retains the register value.
|
||||
|
||||
Default n, which means that the PHY state is not changed. To work
|
||||
around the issues, change this setting to y.
|
||||
|
||||
config PHY_SMSC
|
||||
bool "Microchip(SMSC) Ethernet PHYs support"
|
||||
|
||||
|
@ -303,9 +303,14 @@ int aquantia_config(struct phy_device *phydev)
|
||||
AQUANTIA_SYSTEM_INTERFACE_SR);
|
||||
/* If SI is USXGMII then start USXGMII autoneg */
|
||||
if ((val & AQUANTIA_SI_IN_USE_MASK) == AQUANTIA_SI_USXGMII) {
|
||||
reg_val1 = phy_read(phydev, MDIO_MMD_PHYXS,
|
||||
AQUANTIA_VENDOR_PROVISIONING_REG);
|
||||
|
||||
reg_val1 |= AQUANTIA_USX_AUTONEG_CONTROL_ENA;
|
||||
|
||||
phy_write(phydev, MDIO_MMD_PHYXS,
|
||||
AQUANTIA_VENDOR_PROVISIONING_REG,
|
||||
AQUANTIA_USX_AUTONEG_CONTROL_ENA);
|
||||
reg_val1);
|
||||
printf("%s: system interface USXGMII\n",
|
||||
phydev->dev->name);
|
||||
} else {
|
||||
|
@ -33,10 +33,14 @@
|
||||
#define CTRL1000_CONFIG_MASTER (1 << 11)
|
||||
#define CTRL1000_MANUAL_CONFIG (1 << 12)
|
||||
|
||||
#define KSZ9021_PS_TO_REG 120
|
||||
|
||||
/* KSZ9031 PHY Registers */
|
||||
#define MII_KSZ9031_MMD_ACCES_CTRL 0x0d
|
||||
#define MII_KSZ9031_MMD_REG_DATA 0x0e
|
||||
|
||||
#define KSZ9031_PS_TO_REG 60
|
||||
|
||||
static int ksz90xx_startup(struct phy_device *phydev)
|
||||
{
|
||||
unsigned phy_ctl;
|
||||
@ -102,20 +106,28 @@ static const struct ksz90x1_reg_field ksz9031_clk_grp[] = {
|
||||
};
|
||||
|
||||
static int ksz90x1_of_config_group(struct phy_device *phydev,
|
||||
struct ksz90x1_ofcfg *ofcfg)
|
||||
struct ksz90x1_ofcfg *ofcfg,
|
||||
int ps_to_regval)
|
||||
{
|
||||
struct udevice *dev = phydev->dev;
|
||||
struct phy_driver *drv = phydev->drv;
|
||||
const int ps_to_regval = 60;
|
||||
int val[4];
|
||||
int i, changed = 0, offset, max;
|
||||
u16 regval = 0;
|
||||
ofnode node;
|
||||
|
||||
if (!drv || !drv->writeext)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Look for a PHY node under the Ethernet node */
|
||||
node = dev_read_subnode(dev, "ethernet-phy");
|
||||
if (!ofnode_valid(node)) {
|
||||
/* No node found, look in the Ethernet node */
|
||||
node = dev_ofnode(dev);
|
||||
}
|
||||
|
||||
for (i = 0; i < ofcfg->grpsz; i++) {
|
||||
val[i] = dev_read_u32_default(dev, ofcfg->grp[i].name, ~0);
|
||||
val[i] = ofnode_read_u32_default(node, ofcfg->grp[i].name, ~0);
|
||||
offset = ofcfg->grp[i].off;
|
||||
if (val[i] == -1) {
|
||||
/* Default register value for KSZ9021 */
|
||||
@ -148,7 +160,8 @@ static int ksz9021_of_config(struct phy_device *phydev)
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ofcfg); i++) {
|
||||
ret = ksz90x1_of_config_group(phydev, &(ofcfg[i]));
|
||||
ret = ksz90x1_of_config_group(phydev, &ofcfg[i],
|
||||
KSZ9021_PS_TO_REG);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -167,7 +180,8 @@ static int ksz9031_of_config(struct phy_device *phydev)
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ofcfg); i++) {
|
||||
ret = ksz90x1_of_config_group(phydev, &(ofcfg[i]));
|
||||
ret = ksz90x1_of_config_group(phydev, &ofcfg[i],
|
||||
KSZ9031_PS_TO_REG);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -462,6 +462,18 @@ static LIST_HEAD(phy_drivers);
|
||||
|
||||
int phy_init(void)
|
||||
{
|
||||
#ifdef CONFIG_NEEDS_MANUAL_RELOC
|
||||
/*
|
||||
* The pointers inside phy_drivers also needs to be updated incase of
|
||||
* manual reloc, without which these points to some invalid
|
||||
* pre reloc address and leads to invalid accesses, hangs.
|
||||
*/
|
||||
struct list_head *head = &phy_drivers;
|
||||
|
||||
head->next = (void *)head->next + gd->reloc_off;
|
||||
head->prev = (void *)head->prev + gd->reloc_off;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_B53_SWITCH
|
||||
phy_b53_init();
|
||||
#endif
|
||||
@ -549,6 +561,10 @@ int phy_register(struct phy_driver *drv)
|
||||
drv->readext += gd->reloc_off;
|
||||
if (drv->writeext)
|
||||
drv->writeext += gd->reloc_off;
|
||||
if (drv->read_mmd)
|
||||
drv->read_mmd += gd->reloc_off;
|
||||
if (drv->write_mmd)
|
||||
drv->write_mmd += gd->reloc_off;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -655,7 +671,10 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
|
||||
|
||||
dev->drv = get_phy_driver(dev, interface);
|
||||
|
||||
phy_probe(dev);
|
||||
if (phy_probe(dev)) {
|
||||
printf("%s, PHY probe failed\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (addr >= 0 && addr < PHY_MAX_ADDR)
|
||||
bus->phymap[addr] = dev;
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#define PHY_RTL8211x_FORCE_MASTER BIT(1)
|
||||
#define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2)
|
||||
#define PHY_RTL8211F_FORCE_EEE_RXC_ON BIT(3)
|
||||
|
||||
#define PHY_AUTONEGOTIATE_TIMEOUT 5000
|
||||
|
||||
@ -102,6 +103,15 @@ static int rtl8211e_probe(struct phy_device *phydev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl8211f_probe(struct phy_device *phydev)
|
||||
{
|
||||
#ifdef CONFIG_RTL8211F_PHY_FORCE_EEE_RXC_ON
|
||||
phydev->flags |= PHY_RTL8211F_FORCE_EEE_RXC_ON;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RealTek RTL8211x */
|
||||
static int rtl8211x_config(struct phy_device *phydev)
|
||||
{
|
||||
@ -151,6 +161,14 @@ static int rtl8211f_config(struct phy_device *phydev)
|
||||
{
|
||||
u16 reg;
|
||||
|
||||
if (phydev->flags & PHY_RTL8211F_FORCE_EEE_RXC_ON) {
|
||||
unsigned int reg;
|
||||
|
||||
reg = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
|
||||
reg &= ~MDIO_PCS_CTRL1_CLKSTOP_EN;
|
||||
phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, reg);
|
||||
}
|
||||
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
|
||||
|
||||
phy_write(phydev, MDIO_DEVAD_NONE,
|
||||
@ -360,6 +378,7 @@ static struct phy_driver RTL8211F_driver = {
|
||||
.uid = 0x1cc916,
|
||||
.mask = 0xffffff,
|
||||
.features = PHY_GBIT_FEATURES,
|
||||
.probe = &rtl8211f_probe,
|
||||
.config = &rtl8211f_config,
|
||||
.startup = &rtl8211f_startup,
|
||||
.shutdown = &genphy_shutdown,
|
||||
|
@ -73,16 +73,6 @@
|
||||
#define MII_DP83867_CFG2_SPEEDOPT_INTLOW 0x2000
|
||||
#define MII_DP83867_CFG2_MASK 0x003F
|
||||
|
||||
#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */
|
||||
#define MII_MMD_DATA 0x0e /* MMD Access Data Register */
|
||||
|
||||
/* MMD Access Control register fields */
|
||||
#define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/
|
||||
#define MII_MMD_CTRL_ADDR 0x0000 /* Address */
|
||||
#define MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */
|
||||
#define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */
|
||||
#define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */
|
||||
|
||||
/* User setting - can be taken from DTS */
|
||||
#define DEFAULT_RX_ID_DELAY DP83867_RGMIIDCTL_2_25_NS
|
||||
#define DEFAULT_TX_ID_DELAY DP83867_RGMIIDCTL_2_75_NS
|
||||
@ -116,88 +106,20 @@ struct dp83867_private {
|
||||
int clk_output_sel;
|
||||
};
|
||||
|
||||
/**
|
||||
* phy_read_mmd_indirect - reads data from the MMD registers
|
||||
* @phydev: The PHY device bus
|
||||
* @prtad: MMD Address
|
||||
* @devad: MMD DEVAD
|
||||
* @addr: PHY address on the MII bus
|
||||
*
|
||||
* Description: it reads data from the MMD registers (clause 22 to access to
|
||||
* clause 45) of the specified phy address.
|
||||
* To read these registers we have:
|
||||
* 1) Write reg 13 // DEVAD
|
||||
* 2) Write reg 14 // MMD Address
|
||||
* 3) Write reg 13 // MMD Data Command for MMD DEVAD
|
||||
* 3) Read reg 14 // Read MMD data
|
||||
*/
|
||||
int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
|
||||
int devad, int addr)
|
||||
{
|
||||
int value = -1;
|
||||
|
||||
/* Write the desired MMD Devad */
|
||||
phy_write(phydev, addr, MII_MMD_CTRL, devad);
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
phy_write(phydev, addr, MII_MMD_DATA, prtad);
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
|
||||
|
||||
/* Read the content of the MMD's selected register */
|
||||
value = phy_read(phydev, addr, MII_MMD_DATA);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* phy_write_mmd_indirect - writes data to the MMD registers
|
||||
* @phydev: The PHY device
|
||||
* @prtad: MMD Address
|
||||
* @devad: MMD DEVAD
|
||||
* @addr: PHY address on the MII bus
|
||||
* @data: data to write in the MMD register
|
||||
*
|
||||
* Description: Write data from the MMD registers of the specified
|
||||
* phy address.
|
||||
* To write these registers we have:
|
||||
* 1) Write reg 13 // DEVAD
|
||||
* 2) Write reg 14 // MMD Address
|
||||
* 3) Write reg 13 // MMD Data Command for MMD DEVAD
|
||||
* 3) Write reg 14 // Write MMD data
|
||||
*/
|
||||
void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
|
||||
int devad, int addr, u32 data)
|
||||
{
|
||||
/* Write the desired MMD Devad */
|
||||
phy_write(phydev, addr, MII_MMD_CTRL, devad);
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
phy_write(phydev, addr, MII_MMD_DATA, prtad);
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
|
||||
|
||||
/* Write the data into MMD's selected register */
|
||||
phy_write(phydev, addr, MII_MMD_DATA, data);
|
||||
}
|
||||
|
||||
static int dp83867_config_port_mirroring(struct phy_device *phydev)
|
||||
{
|
||||
struct dp83867_private *dp83867 =
|
||||
(struct dp83867_private *)phydev->priv;
|
||||
u16 val;
|
||||
|
||||
val = phy_read_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR,
|
||||
phydev->addr);
|
||||
val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4);
|
||||
|
||||
if (dp83867->port_mirroring == DP83867_PORT_MIRRORING_EN)
|
||||
val |= DP83867_CFG4_PORT_MIRROR_EN;
|
||||
else
|
||||
val &= ~DP83867_CFG4_PORT_MIRROR_EN;
|
||||
|
||||
phy_write_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR,
|
||||
phydev->addr, val);
|
||||
phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -257,13 +179,13 @@ static int dp83867_of_init(struct phy_device *phydev)
|
||||
|
||||
/* Clock output selection if muxing property is set */
|
||||
if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) {
|
||||
val = phy_read_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
|
||||
DP83867_DEVADDR, phydev->addr);
|
||||
val = phy_read_mmd(phydev, DP83867_DEVADDR,
|
||||
DP83867_IO_MUX_CFG);
|
||||
val &= ~DP83867_IO_MUX_CFG_CLK_O_SEL_MASK;
|
||||
val |= (dp83867->clk_output_sel <<
|
||||
DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT);
|
||||
phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
|
||||
DP83867_DEVADDR, phydev->addr, val);
|
||||
phy_write_mmd(phydev, DP83867_DEVADDR,
|
||||
DP83867_IO_MUX_CFG, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -308,11 +230,11 @@ static int dp83867_config(struct phy_device *phydev)
|
||||
|
||||
/* Mode 1 or 2 workaround */
|
||||
if (dp83867->rxctrl_strap_quirk) {
|
||||
val = phy_read_mmd_indirect(phydev, DP83867_CFG4,
|
||||
DP83867_DEVADDR, phydev->addr);
|
||||
val = phy_read_mmd(phydev, DP83867_DEVADDR,
|
||||
DP83867_CFG4);
|
||||
val &= ~BIT(7);
|
||||
phy_write_mmd_indirect(phydev, DP83867_CFG4,
|
||||
DP83867_DEVADDR, phydev->addr, val);
|
||||
phy_write_mmd(phydev, DP83867_DEVADDR,
|
||||
DP83867_CFG4, val);
|
||||
}
|
||||
|
||||
if (phy_interface_is_rgmii(phydev)) {
|
||||
@ -332,8 +254,8 @@ static int dp83867_config(struct phy_device *phydev)
|
||||
* register's bit 11 (marked as RESERVED).
|
||||
*/
|
||||
|
||||
bs = phy_read_mmd_indirect(phydev, DP83867_STRAP_STS1,
|
||||
DP83867_DEVADDR, phydev->addr);
|
||||
bs = phy_read_mmd(phydev, DP83867_DEVADDR,
|
||||
DP83867_STRAP_STS1);
|
||||
val = phy_read(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL);
|
||||
if (bs & DP83867_STRAP_STS1_RESERVED) {
|
||||
val &= ~DP83867_PHYCR_RESERVED_MASK;
|
||||
@ -354,8 +276,8 @@ static int dp83867_config(struct phy_device *phydev)
|
||||
MII_DP83867_CFG2_SPEEDOPT_INTLOW);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_CFG2, cfg2);
|
||||
|
||||
phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
|
||||
DP83867_DEVADDR, phydev->addr, 0x0);
|
||||
phy_write_mmd(phydev, DP83867_DEVADDR,
|
||||
DP83867_RGMIICTL, 0x0);
|
||||
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
|
||||
DP83867_PHYCTRL_SGMIIEN |
|
||||
@ -367,8 +289,8 @@ static int dp83867_config(struct phy_device *phydev)
|
||||
}
|
||||
|
||||
if (phy_interface_is_rgmii(phydev)) {
|
||||
val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL,
|
||||
DP83867_DEVADDR, phydev->addr);
|
||||
val = phy_read_mmd(phydev, DP83867_DEVADDR,
|
||||
DP83867_RGMIICTL);
|
||||
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
|
||||
val |= (DP83867_RGMII_TX_CLK_DELAY_EN |
|
||||
@ -380,26 +302,24 @@ static int dp83867_config(struct phy_device *phydev)
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
|
||||
val |= DP83867_RGMII_RX_CLK_DELAY_EN;
|
||||
|
||||
phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
|
||||
DP83867_DEVADDR, phydev->addr, val);
|
||||
phy_write_mmd(phydev, DP83867_DEVADDR,
|
||||
DP83867_RGMIICTL, val);
|
||||
|
||||
delay = (dp83867->rx_id_delay |
|
||||
(dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
|
||||
|
||||
phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL,
|
||||
DP83867_DEVADDR, phydev->addr, delay);
|
||||
phy_write_mmd(phydev, DP83867_DEVADDR,
|
||||
DP83867_RGMIIDCTL, delay);
|
||||
|
||||
if (dp83867->io_impedance >= 0) {
|
||||
val = phy_read_mmd_indirect(phydev,
|
||||
DP83867_IO_MUX_CFG,
|
||||
DP83867_DEVADDR,
|
||||
phydev->addr);
|
||||
val = phy_read_mmd(phydev,
|
||||
DP83867_DEVADDR,
|
||||
DP83867_IO_MUX_CFG);
|
||||
val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
|
||||
val |= dp83867->io_impedance &
|
||||
DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
|
||||
phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
|
||||
DP83867_DEVADDR, phydev->addr,
|
||||
val);
|
||||
phy_write_mmd(phydev, DP83867_DEVADDR,
|
||||
DP83867_IO_MUX_CFG, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,14 @@ struct phy_driver {
|
||||
int (*readext)(struct phy_device *phydev, int addr, int devad, int reg);
|
||||
int (*writeext)(struct phy_device *phydev, int addr, int devad, int reg,
|
||||
u16 val);
|
||||
|
||||
/* Phy specific driver override for reading a MMD register */
|
||||
int (*read_mmd)(struct phy_device *phydev, int devad, int reg);
|
||||
|
||||
/* Phy specific driver override for writing a MMD register */
|
||||
int (*write_mmd)(struct phy_device *phydev, int devad, int reg,
|
||||
u16 val);
|
||||
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
@ -165,6 +173,68 @@ static inline int phy_write(struct phy_device *phydev, int devad, int regnum,
|
||||
return bus->write(bus, phydev->addr, devad, regnum, val);
|
||||
}
|
||||
|
||||
static inline void phy_mmd_start_indirect(struct phy_device *phydev, int devad,
|
||||
int regnum)
|
||||
{
|
||||
/* Write the desired MMD Devad */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, devad);
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, regnum);
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL,
|
||||
(devad | MII_MMD_CTRL_NOINCR));
|
||||
}
|
||||
|
||||
static inline int phy_read_mmd(struct phy_device *phydev, int devad,
|
||||
int regnum)
|
||||
{
|
||||
struct phy_driver *drv = phydev->drv;
|
||||
|
||||
if (regnum > (u16)~0 || devad > 32)
|
||||
return -EINVAL;
|
||||
|
||||
/* driver-specific access */
|
||||
if (drv->read_mmd)
|
||||
return drv->read_mmd(phydev, devad, regnum);
|
||||
|
||||
/* direct C45 / C22 access */
|
||||
if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES ||
|
||||
devad == MDIO_DEVAD_NONE || !devad)
|
||||
return phy_read(phydev, devad, regnum);
|
||||
|
||||
/* indirect C22 access */
|
||||
phy_mmd_start_indirect(phydev, devad, regnum);
|
||||
|
||||
/* Read the content of the MMD's selected register */
|
||||
return phy_read(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA);
|
||||
}
|
||||
|
||||
static inline int phy_write_mmd(struct phy_device *phydev, int devad,
|
||||
int regnum, u16 val)
|
||||
{
|
||||
struct phy_driver *drv = phydev->drv;
|
||||
|
||||
if (regnum > (u16)~0 || devad > 32)
|
||||
return -EINVAL;
|
||||
|
||||
/* driver-specific access */
|
||||
if (drv->write_mmd)
|
||||
return drv->write_mmd(phydev, devad, regnum, val);
|
||||
|
||||
/* direct C45 / C22 access */
|
||||
if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES ||
|
||||
devad == MDIO_DEVAD_NONE || !devad)
|
||||
return phy_write(phydev, devad, regnum, val);
|
||||
|
||||
/* indirect C22 access */
|
||||
phy_mmd_start_indirect(phydev, devad, regnum);
|
||||
|
||||
/* Write the data into MMD's selected register */
|
||||
return phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, val);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PHYLIB_10G
|
||||
extern struct phy_driver gen10g_driver;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user