The enitial driver implementation was limited to SGMII and 1GBit/s. The new modes allow speeds up to 2.5GBit/s on current S4 SOCs and even higher speeds on upcomming SOCs. Signed-off-by: Michael Dege <michael.dege@xxxxxxxxxxx> --- drivers/phy/renesas/renesas-ether-serdes.c | 69 ++++++++++++++++++---- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/drivers/phy/renesas/renesas-ether-serdes.c b/drivers/phy/renesas/renesas-ether-serdes.c index ce4e3ebd85d2..af5f491cfab1 100644 --- a/drivers/phy/renesas/renesas-ether-serdes.c +++ b/drivers/phy/renesas/renesas-ether-serdes.c @@ -92,17 +92,17 @@ renesas_eth_serdes_common_setting(struct renesas_eth_serdes_channel *channel) { struct renesas_eth_serdes_drv_data *dd = channel->dd; - switch (channel->phy_interface) { - case PHY_INTERFACE_MODE_SGMII: - renesas_eth_serdes_write32(dd->addr, 0x0244, 0x180, 0x0097); - renesas_eth_serdes_write32(dd->addr, 0x01d0, 0x180, 0x0060); - renesas_eth_serdes_write32(dd->addr, 0x01d8, 0x180, 0x2200); - renesas_eth_serdes_write32(dd->addr, 0x01d4, 0x180, 0x0000); - renesas_eth_serdes_write32(dd->addr, 0x01e0, 0x180, 0x003d); - return 0; - default: - return -EOPNOTSUPP; - } + /* Set combination mode */ + renesas_eth_serdes_write32(dd->addr, 0x0244, 0x180, 0x00d7); + renesas_eth_serdes_write32(dd->addr, 0x01cc, 0x180, 0xc200); + renesas_eth_serdes_write32(dd->addr, 0x01c4, 0x180, 0x0042); + renesas_eth_serdes_write32(dd->addr, 0x01c8, 0x180, 0); + renesas_eth_serdes_write32(dd->addr, 0x01dc, 0x180, 0x002f); + renesas_eth_serdes_write32(dd->addr, 0x01d0, 0x180, 0x0060); + renesas_eth_serdes_write32(dd->addr, 0x01d8, 0x180, 0x2200); + renesas_eth_serdes_write32(dd->addr, 0x01d4, 0x180, 0x0000); + renesas_eth_serdes_write32(dd->addr, 0x01e0, 0x180, 0x003d); + return 0; } static int @@ -155,6 +155,43 @@ renesas_eth_serdes_chan_setting(struct renesas_eth_serdes_channel *channel) renesas_eth_serdes_write32(channel->addr, 0x0028, 0x1f80, 0x07a1); renesas_eth_serdes_write32(channel->addr, 0x0000, 0x1f80, 0x0208); break; + + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_5GBASER: + renesas_eth_serdes_write32(channel->addr, 0x001c, 0x300, 0x0); + renesas_eth_serdes_write32(channel->addr, 0x0014, 0x380, 0x50); + renesas_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2200); + renesas_eth_serdes_write32(channel->addr, 0x001c, 0x380, 0x400); + renesas_eth_serdes_write32(channel->addr, 0x01c0, 0x180, 0x1); + renesas_eth_serdes_write32(channel->addr, 0x0248, 0x180, 0x56a); + renesas_eth_serdes_write32(channel->addr, 0x0258, 0x180, 0x15); + renesas_eth_serdes_write32(channel->addr, 0x0144, 0x180, 0x1100); + renesas_eth_serdes_write32(channel->addr, 0x01a0, 0x180, 1); + renesas_eth_serdes_write32(channel->addr, 0x00d0, 0x180, 0x01); + renesas_eth_serdes_write32(channel->addr, 0x0150, 0x180, 0x01); + renesas_eth_serdes_write32(channel->addr, 0x00c8, 0x180, 0x300); + renesas_eth_serdes_write32(channel->addr, 0x0148, 0x180, 0x300); + renesas_eth_serdes_write32(channel->addr, 0x0174, 0x180, 0); + renesas_eth_serdes_write32(channel->addr, 0x0160, 0x180, 0x4); + renesas_eth_serdes_write32(channel->addr, 0x01ac, 0x180, 0); + renesas_eth_serdes_write32(channel->addr, 0x00c4, 0x180, 0x310); + renesas_eth_serdes_write32(channel->addr, 0x00c8, 0x180, 0x0301); + ret = renesas_eth_serdes_reg_wait(channel, 0x00c8, 0x180, BIT(0), 0); + if (ret) + return ret; + renesas_eth_serdes_write32(channel->addr, 0x0148, 0x180, 0x301); + ret = renesas_eth_serdes_reg_wait(channel, 0x0148, 0x180, BIT(0), 0); + if (ret) + return ret; + renesas_eth_serdes_write32(channel->addr, 0x00c4, 0x180, 0x1310); + renesas_eth_serdes_write32(channel->addr, 0x00d8, 0x180, 0x1800); + renesas_eth_serdes_write32(channel->addr, 0x00dc, 0x180, 0); + renesas_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2300); + ret = renesas_eth_serdes_reg_wait(channel, 0x0000, 0x380, BIT(8), 0); + if (ret) + return ret; + break; + default: return -EOPNOTSUPP; } @@ -179,6 +216,12 @@ renesas_eth_serdes_chan_speed(struct renesas_eth_serdes_channel *channel) return ret; renesas_eth_serdes_write32(channel->addr, 0x0008, 0x1f80, 0x0000); break; + case PHY_INTERFACE_MODE_USXGMII: + renesas_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x120); + break; + case PHY_INTERFACE_MODE_5GBASER: + renesas_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x2120); + break; default: return -EOPNOTSUPP; } @@ -192,8 +235,7 @@ static int renesas_eth_serdes_monitor_linkup(struct renesas_eth_serdes_channel * int i, ret; for (i = 0; i < RENESAS_ETH_SERDES_NUM_RETRY_LINKUP; i++) { - ret = renesas_eth_serdes_reg_wait(channel, 0x0004, 0x300, - BIT(2), BIT(2)); + ret = renesas_eth_serdes_reg_wait(channel, 0x0004, 0x300, BIT(2), BIT(2)); if (!ret) break; @@ -309,6 +351,7 @@ static int renesas_eth_serdes_set_mode(struct phy *p, enum phy_mode mode, case PHY_INTERFACE_MODE_GMII: case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_5GBASER: channel->phy_interface = submode; return 0; default: -- 2.34.1 ________________________________ Renesas Electronics Europe GmbH Registered Office: Arcadiastrasse 10 DE-40472 Duesseldorf Commercial Registry: Duesseldorf, HRB 3708 Managing Director: Carsten Jauch VAT-No.: DE 14978647 Tax-ID-No: 105/5839/1793 Legal Disclaimer: This e-mail communication (and any attachment/s) is confidential and contains proprietary information, some or all of which may be legally privileged. It is intended solely for the use of the individual or entity to which it is addressed. Access to this email by anyone else is unauthorized. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited and may be unlawful.