[U-Boot-Users] [RFC PATCH] TSEC internal TBI and SGMII support.

Ed Swarthout ed.swarthout at hwdebug.com
Fri Aug 3 10:23:00 CEST 2007


From: Ed Swarthout <Ed.Swarthout at freescale.com>

Only register one miiphy device and attach all phy's to it.

Option CONFIG_TSEC_TBI adds support to configure the internal TBI phy.
The first TBI phy address is TBIPA_VALUE=0x11 and incremented for each tsec.

CONFIG_MII_DEFAULT_TSEC will allow any phy connected to the default MII bus
to be read or written without being tied to a specific tsec.

Add vsc8234 phy support.

The FSL boards use a sgmii riser card with a 4-port phy at address
range 0x1c-0x1f.  The CONFIG_SGMII_RISER option adds
TSEC1_SGMII_PHY_ADDR_OFFSET to phyaddr when that tsec is configured to
sgmii mode by the por config switches.

Signed-off-by: Ed Swarthout <Ed.Swarthout at freescale.com>
---

This version makes all the phys appear to be on a single miiphy bus so
"mii info" will find and shows all the phys.

 drivers/tsec.c |  117 ++++++++++++++++++++++++++++++++++++++++++++++---------
 drivers/tsec.h |   22 ++++++++++-
 2 files changed, 119 insertions(+), 20 deletions(-)

diff --git a/drivers/tsec.c b/drivers/tsec.c
index 55334d6..0074630 100644
--- a/drivers/tsec.c
+++ b/drivers/tsec.c
@@ -97,11 +97,13 @@ static struct tsec_info_struct tsec_info[] = {
 #endif
 };
 
-#define MAXCONTROLLERS	(4)
+#define MAXCONTROLLERS	(8)	/* 4 external phys and 4 internal tbi phys */
 
 static int relocated = 0;
+static int miiphy_registered = 0; /* Only register one miiphy device */
 
 static struct tsec_private *privlist[MAXCONTROLLERS];
+static int privlist_next = 0;	/* next entry to use */
 
 #ifdef __GNUC__
 static RTXBD rtx __attribute__ ((aligned(8)));
@@ -128,6 +130,20 @@ static int tsec_miiphy_write(char *devname, unsigned char addr,
 static int tsec_miiphy_read(char *devname, unsigned char addr,
 			    unsigned char reg, unsigned short *value);
 
+#ifdef CONFIG_TSEC_TBI
+static struct phy_cmd tbi_phy_config[] = (struct phy_cmd[]) {
+	{TBI_ANA,
+	 TBIANA_ASYMMETRIC_PAUSE|TBIANA_SYMMETRIC_PAUSE|TBIANA_FULL_DUPLEX,
+	 NULL},
+	{TBI_TBICON,
+	 TBICON_CLK_SELECT, NULL},
+	{TBI_CR,
+	 TBICR_PHY_RESET|TBICR_ANEG_ENABLE|TBICR_FULL_DUPLEX|TBICR_SPEED1_SET,
+	 NULL},
+	{miim_end,}
+};
+#endif
+
 /* Initialize device structure. Returns success if PHY
  * initialization succeeded (i.e. if it recognizes the PHY)
  */
@@ -149,13 +165,20 @@ int tsec_initialize(bd_t * bis, int index, char *devname)
 	if (NULL == priv)
 		return 0;
 
-	privlist[index] = priv;
+	privlist[privlist_next++] = priv;
 	priv->regs = (volatile tsec_t *)(TSEC_BASE_ADDR + index * TSEC_SIZE);
 	priv->phyregs = (volatile tsec_t *)(TSEC_BASE_ADDR +
 					    tsec_info[index].phyregidx *
 					    TSEC_SIZE);
 
 	priv->phyaddr = tsec_info[index].phyaddr;
+#ifdef CONFIG_SGMII_RISER
+	/* 8544DS board has two phys.  rgmii at 0-1 and sgmii at 1c-1d.
+	 * Pick based on POR configuration reflected in ecntrl
+	 */
+	if (priv->regs->ecntrl & ECNTRL_SGMII_MODE)
+		priv->phyaddr += TSEC1_SGMII_PHY_ADDR_OFFSET;
+#endif
 	priv->flags = tsec_info[index].flags;
 
 	sprintf(dev->name, devname);
@@ -172,15 +195,36 @@ int tsec_initialize(bd_t * bis, int index, char *devname)
 
 	eth_register(dev);
 
-	/* Reset the MAC */
-	priv->regs->maccfg1 |= MACCFG1_SOFT_RESET;
-	priv->regs->maccfg1 &= ~(MACCFG1_SOFT_RESET);
+	/* Assign a Physical address to the internal TBI phy */
+	priv->regs->tbipa = TBIPA_VALUE + index;
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
 	&& !defined(BITBANGMII)
-	miiphy_register(dev->name, tsec_miiphy_read, tsec_miiphy_write);
+	if (!miiphy_registered++)
+		miiphy_register(dev->name, tsec_miiphy_read, tsec_miiphy_write);
+#endif
+
+#ifdef CONFIG_TSEC_TBI
+	/* Add a private structure for internal TBI devices to list */
+	struct tsec_private *priv_tbi = \
+		(struct tsec_private *)malloc(sizeof(struct tsec_private));
+	privlist[privlist_next++] = priv_tbi;
+	priv_tbi->phyregs = priv->regs;
+	priv_tbi->phyaddr = TBIPA_VALUE + index; /* phyaddr must be unique */
+	priv_tbi->flags = 0;
+
+	/* for sgmii mode, this must be done before external mac reset */
+	debug("Initialize TBI phy %x\n", priv_tbi->phyaddr);
+	phy_run_commands(priv_tbi, tbi_phy_config);
 #endif
 
+	/* Init MACCFG2.  Defaults to GMII */
+	priv->regs->maccfg2 = MACCFG2_INIT_SETTINGS;
+
+	/* Reset the MAC */
+	priv->regs->maccfg1 |= MACCFG1_SOFT_RESET;
+	priv->regs->maccfg1 &= ~(MACCFG1_SOFT_RESET);
+
 	/* Try to initialize PHY here, and return */
 	return init_phy(dev);
 }
@@ -293,13 +337,6 @@ static int init_phy(struct eth_device *dev)
 {
 	struct tsec_private *priv = (struct tsec_private *)dev->priv;
 	struct phy_info *curphy;
-	volatile tsec_t *regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
-
-	/* Assign a Physical address to the TBI */
-	regs->tbipa = TBIPA_VALUE;
-	regs = (volatile tsec_t *)(TSEC_BASE_ADDR + TSEC_SIZE);
-	regs->tbipa = TBIPA_VALUE;
-	asm("sync");
 
 	/* Reset MII (due to new addresses) */
 	priv->phyregs->miimcfg = MIIMCFG_RESET;
@@ -592,10 +629,10 @@ uint mii_parse_cis8201(uint mii_reg, struct tsec_private * priv)
 	return 0;
 }
 
-/* Parse the vsc8244's status register for speed and duplex
+/* Parse the vsc8244/vsc8234's status register for speed and duplex
  * information
  */
-uint mii_parse_vsc8244(uint mii_reg, struct tsec_private * priv)
+uint mii_parse_vsc82x4(uint mii_reg, struct tsec_private *priv)
 {
 	uint speed;
 
@@ -740,7 +777,8 @@ static void adjust_link(struct eth_device *dev)
 			/* Set R100 bit in all modes although
 			 * it is only used in RGMII mode
 			 */
-			if (priv->speed == 100)
+			if ((priv->speed == 100)
+			    && (priv->flags & TSEC_REDUCED))
 				regs->ecntrl |= ECNTRL_R100;
 			else
 				regs->ecntrl &= ~(ECNTRL_R100);
@@ -1149,7 +1187,29 @@ struct phy_info phy_info_VSC8244 = {
 			   {MIIM_STATUS, miim_read, &mii_parse_sr},
 			   /* Read the status */
 			   {MIIM_VSC8244_AUX_CONSTAT, miim_read,
-			    &mii_parse_vsc8244},
+			    &mii_parse_vsc82x4},
+			   {miim_end,}
+			   },
+	(struct phy_cmd[]){	/* shutdown */
+			   {miim_end,}
+			   },
+};
+
+struct phy_info phy_info_VSC8234 = {
+	0xfc623 >> 6,  /* 0x3f18 */
+	"Vitesse VSC8234",
+	6,
+	(struct phy_cmd[]){	/* config */
+			   {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+			   {MIIM_CONTROL, MIIM_CONTROL_INIT, NULL},
+			   {miim_end,}
+			   },
+	(struct phy_cmd[]){	/* startup */
+			   /* Auto-negotiate */
+			   {MIIM_STATUS, miim_read, &mii_parse_sr},
+			   /* Read the status */
+			   {MIIM_VSC8244_AUX_CONSTAT, miim_read,
+			    &mii_parse_vsc82x4},
 			   {miim_end,}
 			   },
 	(struct phy_cmd[]){	/* shutdown */
@@ -1324,6 +1384,7 @@ struct phy_info *phy_info[] = {
 	&phy_info_dm9161,
 	&phy_info_lxt971,
 	&phy_info_VSC8244,
+	&phy_info_VSC8234,
 	&phy_info_dp83865,
 	&phy_info_generic,
 	NULL
@@ -1471,8 +1532,17 @@ static int tsec_miiphy_read(char *devname, unsigned char addr,
 	struct tsec_private *priv = get_priv_for_phy(addr);
 
 	if (NULL == priv) {
-		printf("Can't read PHY at address %d\n", addr);
+#ifdef CONFIG_MII_DEFAULT_TSEC
+		struct tsec_private temp_private;
+		priv = &temp_private;
+		priv->phyregs = (volatile tsec_t *)(TSEC_BASE_ADDR);
+		priv->phyaddr = addr;
+		priv->flags = 0;
+#else
+		printf("No controller registered for PHY at address %d\n",
+			addr);
 		return -1;
+#endif
 	}
 
 	ret = (unsigned short)read_phy_reg(priv, reg);
@@ -1493,8 +1563,17 @@ static int tsec_miiphy_write(char *devname, unsigned char addr,
 	struct tsec_private *priv = get_priv_for_phy(addr);
 
 	if (NULL == priv) {
-		printf("Can't write PHY at address %d\n", addr);
+#ifdef CONFIG_MII_DEFAULT_TSEC
+		struct tsec_private temp_private;
+		priv = &temp_private;
+		priv->phyregs = (volatile tsec_t *)(TSEC_BASE_ADDR);
+		priv->phyaddr = addr;
+		priv->flags = 0;
+#else
+		printf("No controller registered for PHY at address %d\n",
+			addr);
 		return -1;
+#endif
 	}
 
 	write_phy_reg(priv, reg, value);
diff --git a/drivers/tsec.h b/drivers/tsec.h
index 7bf3dee..c4b507b 100644
--- a/drivers/tsec.h
+++ b/drivers/tsec.h
@@ -42,6 +42,26 @@
 
 #define PHY_AUTONEGOTIATE_TIMEOUT	5000 /* in ms */
 
+/* TBI register addresses */
+#define TBI_CR			0x00
+#define TBI_SR			0x01
+#define TBI_ANA			0x04
+#define TBI_ANLPBPA		0x05
+#define TBI_ANEX		0x06
+#define TBI_TBICON		0x11
+
+/* TBI MDIO register bit fields*/
+#define TBICON_CLK_SELECT	0x0020
+#define TBIANA_ASYMMETRIC_PAUSE 0x0100
+#define TBIANA_SYMMETRIC_PAUSE  0x0080
+#define TBIANA_HALF_DUPLEX	0x0040
+#define TBIANA_FULL_DUPLEX	0x0020
+#define TBICR_PHY_RESET		0x8000
+#define TBICR_ANEG_ENABLE	0x1000
+#define TBICR_RESTART_ANEG	0x0200
+#define TBICR_FULL_DUPLEX	0x0100
+#define TBICR_SPEED1_SET	0x0040
+
 /* MAC register bits */
 #define MACCFG1_SOFT_RESET	0x80000000
 #define MACCFG1_RESET_RX_MC	0x00080000
@@ -70,7 +90,7 @@
 #define miim_end -2
 #define miim_read -1
 
-#define TBIPA_VALUE		0x1f
+#define TBIPA_VALUE		0x11	/* assigns 0x11-0x14 */
 #define MIIMCFG_INIT_VALUE	0x00000003
 #define MIIMCFG_RESET		0x80000000
 
-- 
1.5.2.2.279.gf366





More information about the U-Boot mailing list