X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fphy%2Fbroadcom.c;h=e4afa90dca02e7c6c620f9dfbeaa56c16322ec83;hb=e1541b1d7fb94ed9ac2bfe4c324afd91d77aee11;hp=427ac6013baeeff557063bbf7b376b5e82a9b976;hpb=9082eeac5de1335d663016668c9b89c290f5c79b;p=oweals%2Fu-boot.git diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 427ac6013b..e4afa90dca 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -1,24 +1,10 @@ /* * Broadcom PHY drivers * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ * * Copyright 2010-2011 Freescale Semiconductor, Inc. * author Andy Fleming - * */ #include #include @@ -44,6 +30,29 @@ #define MIIM_BCM54XX_EXP_SEL_SSD 0x0e00 /* Secondary SerDes select */ #define MIIM_BCM54XX_EXP_SEL_ER 0x0f00 /* Expansion register select */ +#define MIIM_BCM_AUXCNTL_SHDWSEL_MISC 0x0007 +#define MIIM_BCM_AUXCNTL_ACTL_SMDSP_EN 0x0800 + +#define MIIM_BCM_CHANNEL_WIDTH 0x2000 + +static void bcm_phy_write_misc(struct phy_device *phydev, + u16 reg, u16 chl, u16 value) +{ + int reg_val; + + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL, + MIIM_BCM_AUXCNTL_SHDWSEL_MISC); + + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL); + reg_val |= MIIM_BCM_AUXCNTL_ACTL_SMDSP_EN; + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL, reg_val); + + reg_val = (chl * MIIM_BCM_CHANNEL_WIDTH) | reg; + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_SEL, reg_val); + + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_DATA, value); +} + /* Broadcom BCM5461S */ static int bcm5461_config(struct phy_device *phydev) { @@ -98,11 +107,14 @@ static int bcm54xx_parse_status(struct phy_device *phydev) static int bcm54xx_startup(struct phy_device *phydev) { + int ret; + /* Read the Status (2x to make sure link is right) */ - genphy_update_link(phydev); - bcm54xx_parse_status(phydev); + ret = genphy_update_link(phydev); + if (ret) + return ret; - return 0; + return bcm54xx_parse_status(phydev); } /* Broadcom BCM5482S */ @@ -151,6 +163,66 @@ static int bcm5482_config(struct phy_device *phydev) return 0; } +static int bcm_cygnus_startup(struct phy_device *phydev) +{ + int ret; + + /* Read the Status (2x to make sure link is right) */ + ret = genphy_update_link(phydev); + if (ret) + return ret; + + return genphy_parse_link(phydev); +} + +static void bcm_cygnus_afe(struct phy_device *phydev) +{ + /* ensures smdspclk is enabled */ + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL, 0x0c30); + + /* AFE_VDAC_ICTRL_0 bit 7:4 Iq=1100 for 1g 10bt, normal modes */ + bcm_phy_write_misc(phydev, 0x39, 0x01, 0xA7C8); + + /* AFE_HPF_TRIM_OTHERS bit11=1, short cascode for all modes*/ + bcm_phy_write_misc(phydev, 0x3A, 0x00, 0x0803); + + /* AFE_TX_CONFIG_1 bit 7:4 Iq=1100 for test modes */ + bcm_phy_write_misc(phydev, 0x3A, 0x01, 0xA740); + + /* AFE TEMPSEN_OTHERS rcal_HT, rcal_LT 10000 */ + bcm_phy_write_misc(phydev, 0x3A, 0x03, 0x8400); + + /* AFE_FUTURE_RSV bit 2:0 rccal <2:0>=100 */ + bcm_phy_write_misc(phydev, 0x3B, 0x00, 0x0004); + + /* Adjust bias current trim to overcome digital offSet */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0x02); + + /* make rcal=100, since rdb default is 000 */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x00B1); + phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x0010); + + /* CORE_EXPB0, Reset R_CAL/RC_CAL Engine */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x00B0); + phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x0010); + + /* CORE_EXPB0, Disable Reset R_CAL/RC_CAL Engine */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x00B0); + phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x0000); +} + +static int bcm_cygnus_config(struct phy_device *phydev) +{ + genphy_config_aneg(phydev); + phy_reset(phydev); + /* AFE settings for PHY stability */ + bcm_cygnus_afe(phydev); + /* Forcing aneg after applying the AFE settings */ + genphy_restart_aneg(phydev); + + return 0; +} + /* * Find out if PHY is in copper or serdes mode by looking at Expansion Reg * 0x42 - "Operating Mode Status Register" @@ -235,17 +307,21 @@ static u32 bcm5482_parse_serdes_sr(struct phy_device *phydev) */ static int bcm5482_startup(struct phy_device *phydev) { + int ret; + if (bcm5482_is_serdes(phydev)) { bcm5482_parse_serdes_sr(phydev); phydev->port = PORT_FIBRE; - } else { - /* Wait for auto-negotiation to complete or fail */ - genphy_update_link(phydev); - /* Parse BCM54xx copper aux status register */ - bcm54xx_parse_status(phydev); + return 0; } - return 0; + /* Wait for auto-negotiation to complete or fail */ + ret = genphy_update_link(phydev); + if (ret) + return ret; + + /* Parse BCM54xx copper aux status register */ + return bcm54xx_parse_status(phydev); } static struct phy_driver BCM5461S_driver = { @@ -278,11 +354,22 @@ static struct phy_driver BCM5482S_driver = { .shutdown = &genphy_shutdown, }; +static struct phy_driver BCM_CYGNUS_driver = { + .name = "Broadcom CYGNUS GPHY", + .uid = 0xae025200, + .mask = 0xfffff0, + .features = PHY_GBIT_FEATURES, + .config = &bcm_cygnus_config, + .startup = &bcm_cygnus_startup, + .shutdown = &genphy_shutdown, +}; + int phy_broadcom_init(void) { phy_register(&BCM5482S_driver); phy_register(&BCM5464S_driver); phy_register(&BCM5461S_driver); + phy_register(&BCM_CYGNUS_driver); return 0; }