forked from mirrors/linux
		
	[PATCH] ppc64: Add new PHY to sungem
This patch adds support for some new PHY models to sungem as used on some recent Apple iMac G5 models. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
		
							parent
							
								
									155ad605b3
								
							
						
					
					
						commit
						3c326fe9cb
					
				
					 3 changed files with 56 additions and 20 deletions
				
			
		| 
						 | 
					@ -3079,7 +3079,9 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 | 
				
			||||||
	gp->phy_mii.dev = dev;
 | 
						gp->phy_mii.dev = dev;
 | 
				
			||||||
	gp->phy_mii.mdio_read = _phy_read;
 | 
						gp->phy_mii.mdio_read = _phy_read;
 | 
				
			||||||
	gp->phy_mii.mdio_write = _phy_write;
 | 
						gp->phy_mii.mdio_write = _phy_write;
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_PMAC
 | 
				
			||||||
 | 
						gp->phy_mii.platform_data = gp->of_node;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	/* By default, we start with autoneg */
 | 
						/* By default, we start with autoneg */
 | 
				
			||||||
	gp->want_autoneg = 1;
 | 
						gp->want_autoneg = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,10 @@
 | 
				
			||||||
#include <linux/ethtool.h>
 | 
					#include <linux/ethtool.h>
 | 
				
			||||||
#include <linux/delay.h>
 | 
					#include <linux/delay.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_PMAC
 | 
				
			||||||
 | 
					#include <asm/prom.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "sungem_phy.h"
 | 
					#include "sungem_phy.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Link modes of the BCM5400 PHY */
 | 
					/* Link modes of the BCM5400 PHY */
 | 
				
			||||||
| 
						 | 
					@ -281,10 +285,12 @@ static int bcm5411_suspend(struct mii_phy* phy)
 | 
				
			||||||
static int bcm5421_init(struct mii_phy* phy)
 | 
					static int bcm5421_init(struct mii_phy* phy)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 data;
 | 
						u16 data;
 | 
				
			||||||
	int rev;
 | 
						unsigned int id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rev = phy_read(phy, MII_PHYSID2) & 0x000f;
 | 
						id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2));
 | 
				
			||||||
	if (rev == 0) {
 | 
					
 | 
				
			||||||
 | 
						/* Revision 0 of 5421 needs some fixups */
 | 
				
			||||||
 | 
						if (id == 0x002060e0) {
 | 
				
			||||||
		/* This is borrowed from MacOS
 | 
							/* This is borrowed from MacOS
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		phy_write(phy, 0x18, 0x1007);
 | 
							phy_write(phy, 0x18, 0x1007);
 | 
				
			||||||
| 
						 | 
					@ -297,21 +303,28 @@ static int bcm5421_init(struct mii_phy* phy)
 | 
				
			||||||
		data = phy_read(phy, 0x15);
 | 
							data = phy_read(phy, 0x15);
 | 
				
			||||||
		phy_write(phy, 0x15, data | 0x0200);
 | 
							phy_write(phy, 0x15, data | 0x0200);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
	/* This has to be verified before I enable it */
 | 
					 | 
				
			||||||
	/* Enable automatic low-power */
 | 
					 | 
				
			||||||
	phy_write(phy, 0x1c, 0x9002);
 | 
					 | 
				
			||||||
	phy_write(phy, 0x1c, 0xa821);
 | 
					 | 
				
			||||||
	phy_write(phy, 0x1c, 0x941d);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int bcm5421k2_init(struct mii_phy* phy)
 | 
						/* Pick up some init code from OF for K2 version */
 | 
				
			||||||
{
 | 
						if ((id & 0xfffffff0) == 0x002062e0) {
 | 
				
			||||||
	/* Init code borrowed from OF */
 | 
							phy_write(phy, 4, 0x01e1);
 | 
				
			||||||
	phy_write(phy, 4, 0x01e1);
 | 
							phy_write(phy, 9, 0x0300);
 | 
				
			||||||
	phy_write(phy, 9, 0x0300);
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Check if we can enable automatic low power */
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_PMAC
 | 
				
			||||||
 | 
						if (phy->platform_data) {
 | 
				
			||||||
 | 
							struct device_node *np = of_get_parent(phy->platform_data);
 | 
				
			||||||
 | 
							int can_low_power = 1;
 | 
				
			||||||
 | 
							if (np == NULL || get_property(np, "no-autolowpower", NULL))
 | 
				
			||||||
 | 
								can_low_power = 0;
 | 
				
			||||||
 | 
							if (can_low_power) {
 | 
				
			||||||
 | 
								/* Enable automatic low-power */
 | 
				
			||||||
 | 
								phy_write(phy, 0x1c, 0x9002);
 | 
				
			||||||
 | 
								phy_write(phy, 0x1c, 0xa821);
 | 
				
			||||||
 | 
								phy_write(phy, 0x1c, 0x941d);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif /* CONFIG_PPC_PMAC */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -762,7 +775,7 @@ static struct mii_phy_def bcm5421_phy_def = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Broadcom BCM 5421 built-in K2 */
 | 
					/* Broadcom BCM 5421 built-in K2 */
 | 
				
			||||||
static struct mii_phy_ops bcm5421k2_phy_ops = {
 | 
					static struct mii_phy_ops bcm5421k2_phy_ops = {
 | 
				
			||||||
	.init		= bcm5421k2_init,
 | 
						.init		= bcm5421_init,
 | 
				
			||||||
	.suspend	= bcm5411_suspend,
 | 
						.suspend	= bcm5411_suspend,
 | 
				
			||||||
	.setup_aneg	= bcm54xx_setup_aneg,
 | 
						.setup_aneg	= bcm54xx_setup_aneg,
 | 
				
			||||||
	.setup_forced	= bcm54xx_setup_forced,
 | 
						.setup_forced	= bcm54xx_setup_forced,
 | 
				
			||||||
| 
						 | 
					@ -779,6 +792,25 @@ static struct mii_phy_def bcm5421k2_phy_def = {
 | 
				
			||||||
	.ops		= &bcm5421k2_phy_ops
 | 
						.ops		= &bcm5421k2_phy_ops
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Broadcom BCM 5462 built-in Vesta */
 | 
				
			||||||
 | 
					static struct mii_phy_ops bcm5462V_phy_ops = {
 | 
				
			||||||
 | 
						.init		= bcm5421_init,
 | 
				
			||||||
 | 
						.suspend	= bcm5411_suspend,
 | 
				
			||||||
 | 
						.setup_aneg	= bcm54xx_setup_aneg,
 | 
				
			||||||
 | 
						.setup_forced	= bcm54xx_setup_forced,
 | 
				
			||||||
 | 
						.poll_link	= genmii_poll_link,
 | 
				
			||||||
 | 
						.read_link	= bcm54xx_read_link,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct mii_phy_def bcm5462V_phy_def = {
 | 
				
			||||||
 | 
						.phy_id		= 0x002060d0,
 | 
				
			||||||
 | 
						.phy_id_mask	= 0xfffffff0,
 | 
				
			||||||
 | 
						.name		= "BCM5462-Vesta",
 | 
				
			||||||
 | 
						.features	= MII_GBIT_FEATURES,
 | 
				
			||||||
 | 
						.magic_aneg	= 1,
 | 
				
			||||||
 | 
						.ops		= &bcm5462V_phy_ops
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Marvell 88E1101 (Apple seem to deal with 2 different revs,
 | 
					/* Marvell 88E1101 (Apple seem to deal with 2 different revs,
 | 
				
			||||||
 * I masked out the 8 last bits to get both, but some specs
 | 
					 * I masked out the 8 last bits to get both, but some specs
 | 
				
			||||||
 * would be useful here) --BenH.
 | 
					 * would be useful here) --BenH.
 | 
				
			||||||
| 
						 | 
					@ -824,6 +856,7 @@ static struct mii_phy_def* mii_phy_table[] = {
 | 
				
			||||||
	&bcm5411_phy_def,
 | 
						&bcm5411_phy_def,
 | 
				
			||||||
	&bcm5421_phy_def,
 | 
						&bcm5421_phy_def,
 | 
				
			||||||
	&bcm5421k2_phy_def,
 | 
						&bcm5421k2_phy_def,
 | 
				
			||||||
 | 
						&bcm5462V_phy_def,
 | 
				
			||||||
	&marvell_phy_def,
 | 
						&marvell_phy_def,
 | 
				
			||||||
	&genmii_phy_def,
 | 
						&genmii_phy_def,
 | 
				
			||||||
	NULL
 | 
						NULL
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,9 +43,10 @@ struct mii_phy
 | 
				
			||||||
	int			pause;
 | 
						int			pause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Provided by host chip */
 | 
						/* Provided by host chip */
 | 
				
			||||||
	struct net_device*	dev;
 | 
						struct net_device	*dev;
 | 
				
			||||||
	int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
 | 
						int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
 | 
				
			||||||
	void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
 | 
						void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
 | 
				
			||||||
 | 
						void			*platform_data;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Pass in a struct mii_phy with dev, mdio_read and mdio_write
 | 
					/* Pass in a struct mii_phy with dev, mdio_read and mdio_write
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue