xref: /rk3399_rockchip-uboot/drivers/net/phy/generic_10g.c (revision ee8fa20f54c9705218a5c21e7db7d4ba1c124b98)
15f184715SAndy Fleming /*
25f184715SAndy Fleming  * Generic PHY Management code
35f184715SAndy Fleming  *
45f184715SAndy Fleming  * This program is free software; you can redistribute it and/or
55f184715SAndy Fleming  * modify it under the terms of the GNU General Public License as
65f184715SAndy Fleming  * published by the Free Software Foundation; either version 2 of
75f184715SAndy Fleming  * the License, or (at your option) any later version.
85f184715SAndy Fleming  *
95f184715SAndy Fleming  * This program is distributed in the hope that it will be useful,
105f184715SAndy Fleming  * but WITHOUT ANY WARRANTY; without even the implied warranty of
115f184715SAndy Fleming  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
125f184715SAndy Fleming  * GNU General Public License for more details.
135f184715SAndy Fleming  *
145f184715SAndy Fleming  * You should have received a copy of the GNU General Public License
155f184715SAndy Fleming  * along with this program; if not, write to the Free Software
165f184715SAndy Fleming  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
175f184715SAndy Fleming  * MA 02111-1307 USA
185f184715SAndy Fleming  *
195f184715SAndy Fleming  *
205f184715SAndy Fleming  * Copyright 2011 Freescale Semiconductor, Inc.
215f184715SAndy Fleming  * author Andy Fleming
225f184715SAndy Fleming  *
235f184715SAndy Fleming  * Based loosely off of Linux's PHY Lib
245f184715SAndy Fleming  */
255f184715SAndy Fleming 
265f184715SAndy Fleming #include <config.h>
275f184715SAndy Fleming #include <common.h>
285f184715SAndy Fleming #include <miiphy.h>
295f184715SAndy Fleming #include <phy.h>
305f184715SAndy Fleming 
315f184715SAndy Fleming int gen10g_shutdown(struct phy_device *phydev)
325f184715SAndy Fleming {
335f184715SAndy Fleming 	return 0;
345f184715SAndy Fleming }
355f184715SAndy Fleming 
365f184715SAndy Fleming int gen10g_startup(struct phy_device *phydev)
375f184715SAndy Fleming {
385f184715SAndy Fleming 	int devad, reg;
39*ee8fa20fSAndy Fleming 	u32 mmd_mask = phydev->mmds & MDIO_DEVS_LINK;
405f184715SAndy Fleming 
415f184715SAndy Fleming 	phydev->link = 1;
425f184715SAndy Fleming 
435f184715SAndy Fleming 	/* For now just lie and say it's 10G all the time */
445f184715SAndy Fleming 	phydev->speed = SPEED_10000;
455f184715SAndy Fleming 	phydev->duplex = DUPLEX_FULL;
465f184715SAndy Fleming 
47*ee8fa20fSAndy Fleming 	/*
48*ee8fa20fSAndy Fleming 	 * Go through all the link-reporting devices, and make sure
49*ee8fa20fSAndy Fleming 	 * they're all up and happy
50*ee8fa20fSAndy Fleming 	 */
515f184715SAndy Fleming 	for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) {
52*ee8fa20fSAndy Fleming 		if (!(mmd_mask & 1))
535f184715SAndy Fleming 			continue;
545f184715SAndy Fleming 
555f184715SAndy Fleming 		/* Read twice because link state is latched and a
565f184715SAndy Fleming 		 * read moves the current state into the register */
575f184715SAndy Fleming 		phy_read(phydev, devad, MDIO_STAT1);
585f184715SAndy Fleming 		reg = phy_read(phydev, devad, MDIO_STAT1);
595f184715SAndy Fleming 		if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
605f184715SAndy Fleming 			phydev->link = 0;
615f184715SAndy Fleming 	}
625f184715SAndy Fleming 
635f184715SAndy Fleming 	return 0;
645f184715SAndy Fleming }
655f184715SAndy Fleming 
665f184715SAndy Fleming int gen10g_discover_mmds(struct phy_device *phydev)
675f184715SAndy Fleming {
685f184715SAndy Fleming 	int mmd, stat2, devs1, devs2;
695f184715SAndy Fleming 
705f184715SAndy Fleming 	/* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY
715f184715SAndy Fleming 	 * XS or DTE XS; give up if none is present. */
725f184715SAndy Fleming 	for (mmd = 1; mmd <= 5; mmd++) {
735f184715SAndy Fleming 		/* Is this MMD present? */
745f184715SAndy Fleming 		stat2 = phy_read(phydev, mmd, MDIO_STAT2);
755f184715SAndy Fleming 		if (stat2 < 0 ||
765f184715SAndy Fleming 			(stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL)
775f184715SAndy Fleming 			continue;
785f184715SAndy Fleming 
795f184715SAndy Fleming 		/* It should tell us about all the other MMDs */
805f184715SAndy Fleming 		devs1 = phy_read(phydev, mmd, MDIO_DEVS1);
815f184715SAndy Fleming 		devs2 = phy_read(phydev, mmd, MDIO_DEVS2);
825f184715SAndy Fleming 		if (devs1 < 0 || devs2 < 0)
835f184715SAndy Fleming 			continue;
845f184715SAndy Fleming 
855f184715SAndy Fleming 		phydev->mmds = devs1 | (devs2 << 16);
865f184715SAndy Fleming 		return 0;
875f184715SAndy Fleming 	}
885f184715SAndy Fleming 
895f184715SAndy Fleming 	return 0;
905f184715SAndy Fleming }
915f184715SAndy Fleming 
925f184715SAndy Fleming int gen10g_config(struct phy_device *phydev)
935f184715SAndy Fleming {
945f184715SAndy Fleming 	/* For now, assume 10000baseT. Fill in later */
955f184715SAndy Fleming 	phydev->supported = phydev->advertising = SUPPORTED_10000baseT_Full;
965f184715SAndy Fleming 
975f184715SAndy Fleming 	return gen10g_discover_mmds(phydev);
985f184715SAndy Fleming }
995f184715SAndy Fleming 
1005f184715SAndy Fleming struct phy_driver gen10g_driver = {
1015f184715SAndy Fleming 	.uid		= 0xffffffff,
1025f184715SAndy Fleming 	.mask		= 0xffffffff,
1035f184715SAndy Fleming 	.name		= "Generic 10G PHY",
1045f184715SAndy Fleming 	.features	= 0,
1055f184715SAndy Fleming 	.config		= gen10g_config,
1065f184715SAndy Fleming 	.startup	= gen10g_startup,
1075f184715SAndy Fleming 	.shutdown	= gen10g_shutdown,
1085f184715SAndy Fleming };
109