mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 10:26:10 +01:00 
			
		
		
		
	phy: Add phy driver support for xilinx PCS/PMA core
Add phy driver support for xilinx PCS/PMA core Signed-off-by: Siva Durga Prasad Paladugu <sivadur@xilinx.com> Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
This commit is contained in:
		
				
					committed by
					
						 Michal Simek
						Michal Simek
					
				
			
			
				
	
			
			
			
						parent
						
							563d8d9358
						
					
				
				
					commit
					ed6fad3e25
				
			| @@ -25,4 +25,5 @@ obj-$(CONFIG_PHY_REALTEK) += realtek.o | |||||||
| obj-$(CONFIG_PHY_SMSC) += smsc.o | obj-$(CONFIG_PHY_SMSC) += smsc.o | ||||||
| obj-$(CONFIG_PHY_TERANETICS) += teranetics.o | obj-$(CONFIG_PHY_TERANETICS) += teranetics.o | ||||||
| obj-$(CONFIG_PHY_TI) += ti.o | obj-$(CONFIG_PHY_TI) += ti.o | ||||||
|  | obj-$(CONFIG_PHY_XILINX) += xilinx_phy.o | ||||||
| obj-$(CONFIG_PHY_VITESSE) += vitesse.o | obj-$(CONFIG_PHY_VITESSE) += vitesse.o | ||||||
|   | |||||||
| @@ -503,6 +503,9 @@ int phy_init(void) | |||||||
| #ifdef CONFIG_PHY_VITESSE | #ifdef CONFIG_PHY_VITESSE | ||||||
| 	phy_vitesse_init(); | 	phy_vitesse_init(); | ||||||
| #endif | #endif | ||||||
|  | #ifdef CONFIG_PHY_XILINX | ||||||
|  | 	phy_xilinx_init(); | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										144
									
								
								drivers/net/phy/xilinx_phy.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								drivers/net/phy/xilinx_phy.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | |||||||
|  | /* | ||||||
|  |  * Xilinx PCS/PMA Core phy driver | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2015 - 2016 Xilinx, Inc. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier:	GPL-2.0+ | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <config.h> | ||||||
|  | #include <common.h> | ||||||
|  | #include <phy.h> | ||||||
|  | #include <dm.h> | ||||||
|  |  | ||||||
|  | DECLARE_GLOBAL_DATA_PTR; | ||||||
|  |  | ||||||
|  | #define MII_PHY_STATUS_SPD_MASK		0x0C00 | ||||||
|  | #define MII_PHY_STATUS_FULLDUPLEX	0x1000 | ||||||
|  | #define MII_PHY_STATUS_1000		0x0800 | ||||||
|  | #define MII_PHY_STATUS_100		0x0400 | ||||||
|  | #define XPCSPMA_PHY_CTRL_ISOLATE_DISABLE 0xFBFF | ||||||
|  |  | ||||||
|  | /* Mask used for ID comparisons */ | ||||||
|  | #define XILINX_PHY_ID_MASK		0xfffffff0 | ||||||
|  |  | ||||||
|  | /* Known PHY IDs */ | ||||||
|  | #define XILINX_PHY_ID			0x01740c00 | ||||||
|  |  | ||||||
|  | /* struct phy_device dev_flags definitions */ | ||||||
|  | #define XAE_PHY_TYPE_MII		0 | ||||||
|  | #define XAE_PHY_TYPE_GMII		1 | ||||||
|  | #define XAE_PHY_TYPE_RGMII_1_3		2 | ||||||
|  | #define XAE_PHY_TYPE_RGMII_2_0		3 | ||||||
|  | #define XAE_PHY_TYPE_SGMII		4 | ||||||
|  | #define XAE_PHY_TYPE_1000BASE_X		5 | ||||||
|  |  | ||||||
|  | static int xilinxphy_startup(struct phy_device *phydev) | ||||||
|  | { | ||||||
|  | 	int err; | ||||||
|  | 	int status = 0; | ||||||
|  |  | ||||||
|  | 	debug("%s\n", __func__); | ||||||
|  | 	/* Update the link, but return if there | ||||||
|  | 	 * was an error | ||||||
|  | 	 */ | ||||||
|  | 	err = genphy_update_link(phydev); | ||||||
|  | 	if (err) | ||||||
|  | 		return err; | ||||||
|  |  | ||||||
|  | 	if (AUTONEG_ENABLE == phydev->autoneg) { | ||||||
|  | 		status = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA); | ||||||
|  | 		status = status & MII_PHY_STATUS_SPD_MASK; | ||||||
|  |  | ||||||
|  | 		if (status & MII_PHY_STATUS_FULLDUPLEX) | ||||||
|  | 			phydev->duplex = DUPLEX_FULL; | ||||||
|  | 		else | ||||||
|  | 			phydev->duplex = DUPLEX_HALF; | ||||||
|  |  | ||||||
|  | 		switch (status) { | ||||||
|  | 		case MII_PHY_STATUS_1000: | ||||||
|  | 			phydev->speed = SPEED_1000; | ||||||
|  | 			break; | ||||||
|  |  | ||||||
|  | 		case MII_PHY_STATUS_100: | ||||||
|  | 			phydev->speed = SPEED_100; | ||||||
|  | 			break; | ||||||
|  |  | ||||||
|  | 		default: | ||||||
|  | 			phydev->speed = SPEED_10; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		int bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); | ||||||
|  |  | ||||||
|  | 		if (bmcr < 0) | ||||||
|  | 			return bmcr; | ||||||
|  |  | ||||||
|  | 		if (bmcr & BMCR_FULLDPLX) | ||||||
|  | 			phydev->duplex = DUPLEX_FULL; | ||||||
|  | 		else | ||||||
|  | 			phydev->duplex = DUPLEX_HALF; | ||||||
|  |  | ||||||
|  | 		if (bmcr & BMCR_SPEED1000) | ||||||
|  | 			phydev->speed = SPEED_1000; | ||||||
|  | 		else if (bmcr & BMCR_SPEED100) | ||||||
|  | 			phydev->speed = SPEED_100; | ||||||
|  | 		else | ||||||
|  | 			phydev->speed = SPEED_10; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * For 1000BASE-X Phy Mode the speed/duplex will always be | ||||||
|  | 	 * 1000Mbps/fullduplex | ||||||
|  | 	 */ | ||||||
|  | 	if (phydev->flags == XAE_PHY_TYPE_1000BASE_X) { | ||||||
|  | 		phydev->duplex = DUPLEX_FULL; | ||||||
|  | 		phydev->speed = SPEED_1000; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int xilinxphy_of_init(struct phy_device *phydev) | ||||||
|  | { | ||||||
|  | 	struct udevice *dev = (struct udevice *)&phydev->dev; | ||||||
|  | 	u32 phytype; | ||||||
|  |  | ||||||
|  | 	debug("%s\n", __func__); | ||||||
|  | 	phytype = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "phy-type", -1); | ||||||
|  | 	if (phytype == XAE_PHY_TYPE_1000BASE_X) | ||||||
|  | 		phydev->flags |= XAE_PHY_TYPE_1000BASE_X; | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int xilinxphy_config(struct phy_device *phydev) | ||||||
|  | { | ||||||
|  | 	int temp; | ||||||
|  |  | ||||||
|  | 	debug("%s\n", __func__); | ||||||
|  | 	xilinxphy_of_init(phydev); | ||||||
|  | 	temp = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); | ||||||
|  | 	temp &= XPCSPMA_PHY_CTRL_ISOLATE_DISABLE; | ||||||
|  | 	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, temp); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static struct phy_driver xilinxphy_driver = { | ||||||
|  | 	.uid = XILINX_PHY_ID, | ||||||
|  | 	.mask = XILINX_PHY_ID_MASK, | ||||||
|  | 	.name = "Xilinx PCS/PMA PHY", | ||||||
|  | 	.features = PHY_GBIT_FEATURES, | ||||||
|  | 	.config = &xilinxphy_config, | ||||||
|  | 	.startup = &xilinxphy_startup, | ||||||
|  | 	.shutdown = &genphy_shutdown, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | int phy_xilinx_init(void) | ||||||
|  | { | ||||||
|  | 	debug("%s\n", __func__); | ||||||
|  | 	phy_register(&xilinxphy_driver); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
| @@ -264,6 +264,7 @@ int phy_smsc_init(void); | |||||||
| int phy_teranetics_init(void); | int phy_teranetics_init(void); | ||||||
| int phy_ti_init(void); | int phy_ti_init(void); | ||||||
| int phy_vitesse_init(void); | int phy_vitesse_init(void); | ||||||
|  | int phy_xilinx_init(void); | ||||||
|  |  | ||||||
| int board_phy_config(struct phy_device *phydev); | int board_phy_config(struct phy_device *phydev); | ||||||
| int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id); | int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user