public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH] TI: DaVinci: Updating EMAC driver for DM365 and DM646x
@ 2009-10-02  1:56 s-paulraj at ti.com
  2009-10-02 12:48 ` Tom
  0 siblings, 1 reply; 5+ messages in thread
From: s-paulraj at ti.com @ 2009-10-02  1:56 UTC (permalink / raw)
  To: u-boot

From: Sandeep Paulraj <s-paulraj@ti.com>

The EMAC IP on DM365 and DM646x is slightly different from
that on DM644x. This patch updates the DaVinci EMAC driver
so that EMAC becomes operational on DM365 in U-Boot.
A flag 'CONFIG_DAVINCI_EMAC_VERSION2' is used in the driver.
This flag will need to be defined in the DM365 config file.

Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
---
The same modifications work on DM646x in a slightly older version
of U-Boot. So when enabled this should work on the DM6467 EVM as well.
This has at this point of time not been tested on the DM6467 in the latest
version of U-Boot.
 drivers/net/davinci_emac.c |   79 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index fa8cee4..0d61c91 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -107,6 +107,33 @@ static void davinci_eth_mdio_enable(void)
 	while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
 }
 
+/* Read a PHY register via MDIO inteface */
+static int mdio_read(int phy_addr, int reg_num)
+{
+	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
+					MDIO_USERACCESS0_WRITE_READ |
+					((reg_num & 0x1F) << 21) |
+					((phy_addr & 0x1F) << 16);
+
+	/* Wait for command to complete */
+	while ((adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) != 0);
+
+	return adap_mdio->USERACCESS0 & 0xFFFF;
+}
+
+/* Write to a PHY register via MDIO inteface */
+void mdio_write(int phy_addr, int reg_num, unsigned int data)
+{
+	/* Wait for User access register to be ready */
+	while ((adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) != 0);
+
+	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
+					MDIO_USERACCESS0_WRITE_WRITE |
+					((reg_num & 0x1F) << 21) |
+					((phy_addr & 0x1F) << 16) |
+					(data & 0xFFFF);
+}
+
 /*
  * Tries to find an active connected PHY. Returns 1 if address if found.
  * If no active PHY (or more than one PHY) found returns 0.
@@ -248,6 +275,31 @@ static int davinci_mii_phy_write(char *devname, unsigned char addr, unsigned cha
 
 #endif
 
+static void emac_gigabit_enable(void)
+{
+	int temp;
+
+	temp = mdio_read(EMAC_MDIO_PHY_NUM, 0);
+
+	if (temp & (1 << 6)) {
+		/*
+		 * Check if link detected is giga-bit
+		 * If Gigabit mode detected, enable gigbit in MAC and PHY
+		 */
+		adap_emac->MACCONTROL |= EMAC_MACCONTROL_GIGFORCE |
+						EMAC_MACCONTROL_GIGABIT_ENABLE;
+
+		/*
+		 * The SYS_CLK which feeds the SOC for giga-bit operation
+		 * does not seem to be enabled after reset as expected.
+		 * Force enabling SYS_CLK by writing to the PHY
+		 */
+		temp = mdio_read(EMAC_MDIO_PHY_NUM, 22);
+		temp |= (1 << 4);
+		mdio_write(EMAC_MDIO_PHY_NUM, 22, temp);
+	}
+}
+
 
 /* Eth device open */
 static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
@@ -261,10 +313,15 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	/* Reset EMAC module and disable interrupts in wrapper */
 	adap_emac->SOFTRESET = 1;
 	while (adap_emac->SOFTRESET != 0) {;}
+#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
+	adap_ewrap->SOFTRST = 1;
+	while (adap_ewrap->SOFTRST != 0);
+#else
 	adap_ewrap->EWCTL = 0;
 	for (cnt = 0; cnt < 5; cnt++) {
 		clkdiv = adap_ewrap->EWCTL;
 	}
+#endif
 
 	rx_desc = emac_rx_desc;
 
@@ -282,6 +339,10 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	adap_emac->MACADDRLO =
 		(davinci_eth_mac_addr[5] << 8) |
 		(davinci_eth_mac_addr[4]);
+#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
+	/* Set the Match and Valid Bits */
+	adap_emac->MACADDRLO |= (1 << 19) | (1 << 20);
+#endif
 
 	adap_emac->MACHASH1 = 0;
 	adap_emac->MACHASH2 = 0;
@@ -347,8 +408,15 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
 	adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
 
+#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
+	/* We need to wait for MDIO to start */
+	udelay(1000);
+#endif
+
 	if (!phy.get_link_speed(active_phy_addr))
 		return(0);
+	else
+		emac_gigabit_enable();
 
 	/* Start receive process */
 	adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
@@ -411,7 +479,11 @@ static void davinci_eth_close(struct eth_device *dev)
 
 	/* Reset EMAC module and disable interrupts in wrapper */
 	adap_emac->SOFTRESET = 1;
+#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
+	adap_ewrap->SOFTRST = 1;
+#else
 	adap_ewrap->EWCTL = 0;
+#endif
 
 	debug_emac("- emac_close\n");
 }
@@ -433,7 +505,8 @@ static int davinci_eth_send_packet (struct eth_device *dev,
 	if (!phy.get_link_speed (active_phy_addr)) {
 		printf ("WARN: emac_send_packet: No link\n");
 		return (ret_status);
-	}
+	} else
+		emac_gigabit_enable();
 
 	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
 	if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
@@ -456,7 +529,9 @@ static int davinci_eth_send_packet (struct eth_device *dev,
 		if (!phy.get_link_speed (active_phy_addr)) {
 			davinci_eth_ch_teardown (EMAC_CH_TX);
 			return (ret_status);
-		}
+		} else
+			emac_gigabit_enable();
+
 		if (adap_emac->TXINTSTATRAW & 0x01) {
 			ret_status = length;
 			break;
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH] TI: DaVinci: Updating EMAC driver for DM365 and DM646x
  2009-10-02  1:56 s-paulraj at ti.com
@ 2009-10-02 12:48 ` Tom
  0 siblings, 0 replies; 5+ messages in thread
From: Tom @ 2009-10-02 12:48 UTC (permalink / raw)
  To: u-boot

s-paulraj at ti.com wrote:
> From: Sandeep Paulraj <s-paulraj@ti.com>
> 
> The EMAC IP on DM365 and DM646x is slightly different from
> that on DM644x. This patch updates the DaVinci EMAC driver
> so that EMAC becomes operational on DM365 in U-Boot.
> A flag 'CONFIG_DAVINCI_EMAC_VERSION2' is used in the driver.
> This flag will need to be defined in the DM365 config file.
> 
> Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
> ---
> The same modifications work on DM646x in a slightly older version
> of U-Boot. So when enabled this should work on the DM6467 EVM as well.
> This has at this point of time not been tested on the DM6467 in the latest
> version of U-Boot.
>  drivers/net/davinci_emac.c |   79 ++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 77 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
> index fa8cee4..0d61c91 100644
> --- a/drivers/net/davinci_emac.c
> +++ b/drivers/net/davinci_emac.c
> @@ -107,6 +107,33 @@ static void davinci_eth_mdio_enable(void)
>  	while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}

checkpatch complains here.
infinite loop statement should be on the next line.

ERROR: trailing statements should be on next line
#44: FILE: drivers/net/davinci_emac.c:119:
+	while ((adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) != 0);

>  }
>  
> +/* Read a PHY register via MDIO inteface */
> +static int mdio_read(int phy_addr, int reg_num)
> +{
> +	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
> +					MDIO_USERACCESS0_WRITE_READ |
> +					((reg_num & 0x1F) << 21) |
> +					((phy_addr & 0x1F) << 16);
> +
> +	/* Wait for command to complete */
> +	while ((adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) != 0);
> +
> +	return adap_mdio->USERACCESS0 & 0xFFFF;
> +}
> +
> +/* Write to a PHY register via MDIO inteface */
> +void mdio_write(int phy_addr, int reg_num, unsigned int data)
> +{
> +	/* Wait for User access register to be ready */
> +	while ((adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) != 0);

checkpatch complains here.
infinite loop statement should be on the next line.

ERROR: trailing statements should be on next line
#53: FILE: drivers/net/davinci_emac.c:128:
+	while ((adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) != 0);


> +
> +	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
> +					MDIO_USERACCESS0_WRITE_WRITE |
> +					((reg_num & 0x1F) << 21) |
> +					((phy_addr & 0x1F) << 16) |
> +					(data & 0xFFFF);
> +}
> +
>  /*
>   * Tries to find an active connected PHY. Returns 1 if address if found.
>   * If no active PHY (or more than one PHY) found returns 0.
> @@ -248,6 +275,31 @@ static int davinci_mii_phy_write(char *devname, unsigned char addr, unsigned cha
>  
>  #endif
>  
> +static void emac_gigabit_enable(void)
> +{
> +	int temp;
> +
> +	temp = mdio_read(EMAC_MDIO_PHY_NUM, 0);
> +
> +	if (temp & (1 << 6)) {

Is there a logical #define bitfield that could be used here ?

> +		/*
> +		 * Check if link detected is giga-bit
> +		 * If Gigabit mode detected, enable gigbit in MAC and PHY
> +		 */
> +		adap_emac->MACCONTROL |= EMAC_MACCONTROL_GIGFORCE |
> +						EMAC_MACCONTROL_GIGABIT_ENABLE;
> +
> +		/*
> +		 * The SYS_CLK which feeds the SOC for giga-bit operation
> +		 * does not seem to be enabled after reset as expected.
> +		 * Force enabling SYS_CLK by writing to the PHY
> +		 */
> +		temp = mdio_read(EMAC_MDIO_PHY_NUM, 22);
> +		temp |= (1 << 4);
> +		mdio_write(EMAC_MDIO_PHY_NUM, 22, temp);
> +	}
> +}
> +
>  
>  /* Eth device open */
>  static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
> @@ -261,10 +313,15 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
>  	/* Reset EMAC module and disable interrupts in wrapper */
>  	adap_emac->SOFTRESET = 1;
>  	while (adap_emac->SOFTRESET != 0) {;}

checkpatch complains here.
infinite loop statement should be on the next line.

ERROR: trailing statements should be on next line
#103: FILE: drivers/net/davinci_emac.c:318:
+	while (adap_ewrap->SOFTRST != 0);


> +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> +	adap_ewrap->SOFTRST = 1;
> +	while (adap_ewrap->SOFTRST != 0);
> +#else
>  	adap_ewrap->EWCTL = 0;
>  	for (cnt = 0; cnt < 5; cnt++) {
>  		clkdiv = adap_ewrap->EWCTL;
>  	}
> +#endif

You may want to handle this like

#if defined(CONFIG_DAVINIC_EMAC_VERSION) && CONFIG_DAVINCI_EMAC_VERSION >= 2

>  
>  	rx_desc = emac_rx_desc;
>  
> @@ -282,6 +339,10 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
>  	adap_emac->MACADDRLO =
>  		(davinci_eth_mac_addr[5] << 8) |
>  		(davinci_eth_mac_addr[4]);
> +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> +	/* Set the Match and Valid Bits */
> +	adap_emac->MACADDRLO |= (1 << 19) | (1 << 20);

Are there some logical #define bitfields that could be used here ?

> +#endif
>  
>  	adap_emac->MACHASH1 = 0;
>  	adap_emac->MACHASH2 = 0;
> @@ -347,8 +408,15 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
>  	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
>  	adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
>  
> +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> +	/* We need to wait for MDIO to start */
> +	udelay(1000);
> +#endif
> +
>  	if (!phy.get_link_speed(active_phy_addr))
>  		return(0);
> +	else
> +		emac_gigabit_enable();
>  
>  	/* Start receive process */
>  	adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
> @@ -411,7 +479,11 @@ static void davinci_eth_close(struct eth_device *dev)
>  
>  	/* Reset EMAC module and disable interrupts in wrapper */
>  	adap_emac->SOFTRESET = 1;
> +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> +	adap_ewrap->SOFTRST = 1;
> +#else
>  	adap_ewrap->EWCTL = 0;
> +#endif
>  
>  	debug_emac("- emac_close\n");
>  }
> @@ -433,7 +505,8 @@ static int davinci_eth_send_packet (struct eth_device *dev,
>  	if (!phy.get_link_speed (active_phy_addr)) {
>  		printf ("WARN: emac_send_packet: No link\n");
>  		return (ret_status);
> -	}
> +	} else
> +		emac_gigabit_enable();

This is a dangling 'else'
This is not explicitly mentioned in the coding style.
My opinion is to surround with {}


>  
>  	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
>  	if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
> @@ -456,7 +529,9 @@ static int davinci_eth_send_packet (struct eth_device *dev,
>  		if (!phy.get_link_speed (active_phy_addr)) {
>  			davinci_eth_ch_teardown (EMAC_CH_TX);
>  			return (ret_status);
> -		}
> +		} else
> +			emac_gigabit_enable();
> +
Another dangling else

>  		if (adap_emac->TXINTSTATRAW & 0x01) {
>  			ret_status = length;
>  			break;

Tom

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH] TI: DaVinci: Updating EMAC driver for DM365 and DM646x
@ 2009-11-13 20:42 s-paulraj at ti.com
  2009-11-16 16:46 ` Nick Thompson
  0 siblings, 1 reply; 5+ messages in thread
From: s-paulraj at ti.com @ 2009-11-13 20:42 UTC (permalink / raw)
  To: u-boot

From: Sandeep Paulraj <s-paulraj@ti.com>

The EMAC IP on DM365 and DM646x is slightly different from
that on DM644x. This patch updates the DaVinci EMAC driver
so that EMAC becomes operational on DM365 in U-Boot.
A flag 'CONFIG_DAVINCI_EMAC_VERSION2' is used in the driver.
This flag will need to be defined in the DM365 config file.

Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
---
The same modifications work on DM646x in a slightly older version
of U-Boot. So when enabled this should work on the DM6467 EVM as well.
This has at this point of time not been tested on the DM6467 in the latest
version of U-Boot.
 drivers/net/davinci_emac.c |   79 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index fa8cee4..1df98e9 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -107,6 +107,33 @@ static void davinci_eth_mdio_enable(void)
 	while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
 }
 
+/* Read a PHY register via MDIO inteface */
+static int mdio_read(int phy_addr, int reg_num)
+{
+	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
+					MDIO_USERACCESS0_WRITE_READ |
+					((reg_num & 0x1F) << 21) |
+					((phy_addr & 0x1F) << 16);
+
+	/* Wait for command to complete */
+	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO);
+
+	return adap_mdio->USERACCESS0 & 0xFFFF;
+}
+
+/* Write to a PHY register via MDIO inteface */
+void mdio_write(int phy_addr, int reg_num, unsigned int data)
+{
+	/* Wait for User access register to be ready */
+	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO);
+
+	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
+					MDIO_USERACCESS0_WRITE_WRITE |
+					((reg_num & 0x1F) << 21) |
+					((phy_addr & 0x1F) << 16) |
+					(data & 0xFFFF);
+}
+
 /*
  * Tries to find an active connected PHY. Returns 1 if address if found.
  * If no active PHY (or more than one PHY) found returns 0.
@@ -248,6 +275,31 @@ static int davinci_mii_phy_write(char *devname, unsigned char addr, unsigned cha
 
 #endif
 
+static void emac_gigabit_enable(void)
+{
+	int temp;
+
+	temp = mdio_read(EMAC_MDIO_PHY_NUM, 0);
+
+	if (temp & (1 << 6)) {
+		/*
+		 * Check if link detected is giga-bit
+		 * If Gigabit mode detected, enable gigbit in MAC and PHY
+		 */
+		adap_emac->MACCONTROL |= EMAC_MACCONTROL_GIGFORCE |
+						EMAC_MACCONTROL_GIGABIT_ENABLE;
+
+		/*
+		 * The SYS_CLK which feeds the SOC for giga-bit operation
+		 * does not seem to be enabled after reset as expected.
+		 * Force enabling SYS_CLK by writing to the PHY
+		 */
+		temp = mdio_read(EMAC_MDIO_PHY_NUM, 22);
+		temp |= (1 << 4);
+		mdio_write(EMAC_MDIO_PHY_NUM, 22, temp);
+	}
+}
+
 
 /* Eth device open */
 static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
@@ -261,10 +313,15 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	/* Reset EMAC module and disable interrupts in wrapper */
 	adap_emac->SOFTRESET = 1;
 	while (adap_emac->SOFTRESET != 0) {;}
+#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
+	adap_ewrap->SOFTRST = 1;
+	while (adap_ewrap->SOFTRST != 0);
+#else
 	adap_ewrap->EWCTL = 0;
 	for (cnt = 0; cnt < 5; cnt++) {
 		clkdiv = adap_ewrap->EWCTL;
 	}
+#endif
 
 	rx_desc = emac_rx_desc;
 
@@ -282,6 +339,10 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	adap_emac->MACADDRLO =
 		(davinci_eth_mac_addr[5] << 8) |
 		(davinci_eth_mac_addr[4]);
+#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
+	/* Set the Match and Valid Bits */
+	adap_emac->MACADDRLO |= (1 << 19) | (1 << 20);
+#endif
 
 	adap_emac->MACHASH1 = 0;
 	adap_emac->MACHASH2 = 0;
@@ -347,8 +408,15 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
 	adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
 
+#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
+	/* We need to wait for MDIO to start */
+	udelay(1000);
+#endif
+
 	if (!phy.get_link_speed(active_phy_addr))
 		return(0);
+	else
+		emac_gigabit_enable();
 
 	/* Start receive process */
 	adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
@@ -411,7 +479,11 @@ static void davinci_eth_close(struct eth_device *dev)
 
 	/* Reset EMAC module and disable interrupts in wrapper */
 	adap_emac->SOFTRESET = 1;
+#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
+	adap_ewrap->SOFTRST = 1;
+#else
 	adap_ewrap->EWCTL = 0;
+#endif
 
 	debug_emac("- emac_close\n");
 }
@@ -433,7 +505,8 @@ static int davinci_eth_send_packet (struct eth_device *dev,
 	if (!phy.get_link_speed (active_phy_addr)) {
 		printf ("WARN: emac_send_packet: No link\n");
 		return (ret_status);
-	}
+	} else
+		emac_gigabit_enable();
 
 	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
 	if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
@@ -456,7 +529,9 @@ static int davinci_eth_send_packet (struct eth_device *dev,
 		if (!phy.get_link_speed (active_phy_addr)) {
 			davinci_eth_ch_teardown (EMAC_CH_TX);
 			return (ret_status);
-		}
+		} else
+			emac_gigabit_enable();
+
 		if (adap_emac->TXINTSTATRAW & 0x01) {
 			ret_status = length;
 			break;
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH] TI: DaVinci: Updating EMAC driver for DM365 and DM646x
  2009-11-13 20:42 [U-Boot] [PATCH] TI: DaVinci: Updating EMAC driver for DM365 and DM646x s-paulraj at ti.com
@ 2009-11-16 16:46 ` Nick Thompson
  2009-11-16 17:39   ` Paulraj, Sandeep
  0 siblings, 1 reply; 5+ messages in thread
From: Nick Thompson @ 2009-11-16 16:46 UTC (permalink / raw)
  To: u-boot

Hi Sandeep,

On 13/11/09 20:42, s-paulraj at ti.com wrote:
> From: Sandeep Paulraj <s-paulraj@ti.com>
> 
> The EMAC IP on DM365 and DM646x is slightly different from
> that on DM644x. This patch updates the DaVinci EMAC driver
> so that EMAC becomes operational on DM365 in U-Boot.
> A flag 'CONFIG_DAVINCI_EMAC_VERSION2' is used in the driver.
> This flag will need to be defined in the DM365 config file.
> 
> Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
> ---
> The same modifications work on DM646x in a slightly older version
> of U-Boot. So when enabled this should work on the DM6467 EVM as well.
> This has at this point of time not been tested on the DM6467 in the latest
> version of U-Boot.
>  drivers/net/davinci_emac.c |   79 ++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 77 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
> index fa8cee4..1df98e9 100644
> --- a/drivers/net/davinci_emac.c
> +++ b/drivers/net/davinci_emac.c
> @@ -107,6 +107,33 @@ static void davinci_eth_mdio_enable(void)
>  	while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
>  }
>  
> +/* Read a PHY register via MDIO inteface */
> +static int mdio_read(int phy_addr, int reg_num)
> +{
> +	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
> +					MDIO_USERACCESS0_WRITE_READ |
> +					((reg_num & 0x1F) << 21) |
> +					((phy_addr & 0x1F) << 16);
> +
> +	/* Wait for command to complete */
> +	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO);
> +
> +	return adap_mdio->USERACCESS0 & 0xFFFF;
> +}
> +
> +/* Write to a PHY register via MDIO inteface */
> +void mdio_write(int phy_addr, int reg_num, unsigned int data)
> +{
> +	/* Wait for User access register to be ready */
> +	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO);
> +
> +	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
> +					MDIO_USERACCESS0_WRITE_WRITE |
> +					((reg_num & 0x1F) << 21) |
> +					((phy_addr & 0x1F) << 16) |
> +					(data & 0xFFFF);
> +}
> +
>  /*
>   * Tries to find an active connected PHY. Returns 1 if address if found.
>   * If no active PHY (or more than one PHY) found returns 0.
> @@ -248,6 +275,31 @@ static int davinci_mii_phy_write(char *devname, unsigned char addr, unsigned cha
>  
>  #endif
>  
> +static void emac_gigabit_enable(void)
> +{
> +	int temp;
> +
> +	temp = mdio_read(EMAC_MDIO_PHY_NUM, 0);
> +
> +	if (temp & (1 << 6)) {
> +		/*
> +		 * Check if link detected is giga-bit
> +		 * If Gigabit mode detected, enable gigbit in MAC and PHY
> +		 */
> +		adap_emac->MACCONTROL |= EMAC_MACCONTROL_GIGFORCE |
> +						EMAC_MACCONTROL_GIGABIT_ENABLE;
> +
> +		/*
> +		 * The SYS_CLK which feeds the SOC for giga-bit operation
> +		 * does not seem to be enabled after reset as expected.
> +		 * Force enabling SYS_CLK by writing to the PHY
> +		 */
> +		temp = mdio_read(EMAC_MDIO_PHY_NUM, 22);
> +		temp |= (1 << 4);
> +		mdio_write(EMAC_MDIO_PHY_NUM, 22, temp);
> +	}
> +}
> +

Do all DaVinci boards have gigabit? Unsurprisingly, I'm coming from the point
of view that DA830 at least doesn't have this. I wonder if it going to be safe
to modify these bits across the DaVinci range?

>  
>  /* Eth device open */
>  static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
> @@ -261,10 +313,15 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
>  	/* Reset EMAC module and disable interrupts in wrapper */
>  	adap_emac->SOFTRESET = 1;
>  	while (adap_emac->SOFTRESET != 0) {;}
> +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> +	adap_ewrap->SOFTRST = 1;
> +	while (adap_ewrap->SOFTRST != 0);
> +#else
>  	adap_ewrap->EWCTL = 0;
>  	for (cnt = 0; cnt < 5; cnt++) {
>  		clkdiv = adap_ewrap->EWCTL;
>  	}
> +#endif
>  
>  	rx_desc = emac_rx_desc;
>  
> @@ -282,6 +339,10 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
>  	adap_emac->MACADDRLO =
>  		(davinci_eth_mac_addr[5] << 8) |
>  		(davinci_eth_mac_addr[4]);
> +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> +	/* Set the Match and Valid Bits */
> +	adap_emac->MACADDRLO |= (1 << 19) | (1 << 20);
> +#endif
>  
>  	adap_emac->MACHASH1 = 0;
>  	adap_emac->MACHASH2 = 0;
> @@ -347,8 +408,15 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
>  	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
>  	adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
>  
> +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> +	/* We need to wait for MDIO to start */
> +	udelay(1000);
> +#endif
> +
>  	if (!phy.get_link_speed(active_phy_addr))
>  		return(0);
> +	else
> +		emac_gigabit_enable();
>  
>  	/* Start receive process */
>  	adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
> @@ -411,7 +479,11 @@ static void davinci_eth_close(struct eth_device *dev)
>  
>  	/* Reset EMAC module and disable interrupts in wrapper */
>  	adap_emac->SOFTRESET = 1;
> +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> +	adap_ewrap->SOFTRST = 1;
> +#else
>  	adap_ewrap->EWCTL = 0;
> +#endif
>  
>  	debug_emac("- emac_close\n");
>  }
> @@ -433,7 +505,8 @@ static int davinci_eth_send_packet (struct eth_device *dev,
>  	if (!phy.get_link_speed (active_phy_addr)) {
>  		printf ("WARN: emac_send_packet: No link\n");
>  		return (ret_status);
> -	}
> +	} else
> +		emac_gigabit_enable();

Here and below, is it a good idea to be enabling gigabit on each packet send?
It seem like a lot of overhead.

>  
>  	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
>  	if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
> @@ -456,7 +529,9 @@ static int davinci_eth_send_packet (struct eth_device *dev,
>  		if (!phy.get_link_speed (active_phy_addr)) {
>  			davinci_eth_ch_teardown (EMAC_CH_TX);
>  			return (ret_status);
> -		}
> +		} else
> +			emac_gigabit_enable();
> +
>  		if (adap_emac->TXINTSTATRAW & 0x01) {
>  			ret_status = length;
>  			break;

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [U-Boot] [PATCH] TI: DaVinci: Updating EMAC driver for DM365 and DM646x
  2009-11-16 16:46 ` Nick Thompson
@ 2009-11-16 17:39   ` Paulraj, Sandeep
  0 siblings, 0 replies; 5+ messages in thread
From: Paulraj, Sandeep @ 2009-11-16 17:39 UTC (permalink / raw)
  To: u-boot

Hi Nick,

> -----Original Message-----
> From: Nick Thompson [mailto:nick.thompson at gefanuc.com]
> Sent: Monday, November 16, 2009 11:47 AM
> To: Paulraj, Sandeep
> Cc: u-boot at lists.denx.de; biggerbadderben at gmail.com
> Subject: Re: [U-Boot] [PATCH] TI: DaVinci: Updating EMAC driver for DM365
> and DM646x
> 
> Hi Sandeep,
> 
> On 13/11/09 20:42, s-paulraj at ti.com wrote:
> > From: Sandeep Paulraj <s-paulraj@ti.com>
> >
> > The EMAC IP on DM365 and DM646x is slightly different from
> > that on DM644x. This patch updates the DaVinci EMAC driver
> > so that EMAC becomes operational on DM365 in U-Boot.
> > A flag 'CONFIG_DAVINCI_EMAC_VERSION2' is used in the driver.
> > This flag will need to be defined in the DM365 config file.
> >
> > Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
> > ---
> > The same modifications work on DM646x in a slightly older version
> > of U-Boot. So when enabled this should work on the DM6467 EVM as well.
> > This has at this point of time not been tested on the DM6467 in the
> latest
> > version of U-Boot.
> >  drivers/net/davinci_emac.c |   79
> ++++++++++++++++++++++++++++++++++++++++++-
> >  1 files changed, 77 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
> > index fa8cee4..1df98e9 100644
> > --- a/drivers/net/davinci_emac.c
> > +++ b/drivers/net/davinci_emac.c
> > @@ -107,6 +107,33 @@ static void davinci_eth_mdio_enable(void)
> >  	while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
> >  }
> >
> > +/* Read a PHY register via MDIO inteface */
> > +static int mdio_read(int phy_addr, int reg_num)
> > +{
> > +	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
> > +					MDIO_USERACCESS0_WRITE_READ |
> > +					((reg_num & 0x1F) << 21) |
> > +					((phy_addr & 0x1F) << 16);
> > +
> > +	/* Wait for command to complete */
> > +	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO);
> > +
> > +	return adap_mdio->USERACCESS0 & 0xFFFF;
> > +}
> > +
> > +/* Write to a PHY register via MDIO inteface */
> > +void mdio_write(int phy_addr, int reg_num, unsigned int data)
> > +{
> > +	/* Wait for User access register to be ready */
> > +	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO);
> > +
> > +	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
> > +					MDIO_USERACCESS0_WRITE_WRITE |
> > +					((reg_num & 0x1F) << 21) |
> > +					((phy_addr & 0x1F) << 16) |
> > +					(data & 0xFFFF);
> > +}
> > +
> >  /*
> >   * Tries to find an active connected PHY. Returns 1 if address if
> found.
> >   * If no active PHY (or more than one PHY) found returns 0.
> > @@ -248,6 +275,31 @@ static int davinci_mii_phy_write(char *devname,
> unsigned char addr, unsigned cha
> >
> >  #endif
> >
> > +static void emac_gigabit_enable(void)
> > +{
> > +	int temp;
> > +
> > +	temp = mdio_read(EMAC_MDIO_PHY_NUM, 0);
> > +
> > +	if (temp & (1 << 6)) {
> > +		/*
> > +		 * Check if link detected is giga-bit
> > +		 * If Gigabit mode detected, enable gigbit in MAC and PHY
> > +		 */
> > +		adap_emac->MACCONTROL |= EMAC_MACCONTROL_GIGFORCE |
> > +						EMAC_MACCONTROL_GIGABIT_ENABLE;
> > +
> > +		/*
> > +		 * The SYS_CLK which feeds the SOC for giga-bit operation
> > +		 * does not seem to be enabled after reset as expected.
> > +		 * Force enabling SYS_CLK by writing to the PHY
> > +		 */
> > +		temp = mdio_read(EMAC_MDIO_PHY_NUM, 22);
> > +		temp |= (1 << 4);
> > +		mdio_write(EMAC_MDIO_PHY_NUM, 22, temp);
> > +	}
> > +}
> > +
> 
> Do all DaVinci boards have gigabit? 
No they do not
> Unsurprisingly, I'm coming from the
> point
> of view that DA830 at least doesn't have this. I wonder if it going to be
> safe
> to modify these bits across the DaVinci range?
This function will be called by only those that have this feature.

This function will be called by only DM365 and DM6467.
> 
> >
> >  /* Eth device open */
> >  static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
> > @@ -261,10 +313,15 @@ static int davinci_eth_open(struct eth_device
> *dev, bd_t *bis)
> >  	/* Reset EMAC module and disable interrupts in wrapper */
> >  	adap_emac->SOFTRESET = 1;
> >  	while (adap_emac->SOFTRESET != 0) {;}
> > +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> > +	adap_ewrap->SOFTRST = 1;
> > +	while (adap_ewrap->SOFTRST != 0);
> > +#else
> >  	adap_ewrap->EWCTL = 0;
> >  	for (cnt = 0; cnt < 5; cnt++) {
> >  		clkdiv = adap_ewrap->EWCTL;
> >  	}
> > +#endif
> >
> >  	rx_desc = emac_rx_desc;
> >
> > @@ -282,6 +339,10 @@ static int davinci_eth_open(struct eth_device *dev,
> bd_t *bis)
> >  	adap_emac->MACADDRLO =
> >  		(davinci_eth_mac_addr[5] << 8) |
> >  		(davinci_eth_mac_addr[4]);
> > +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> > +	/* Set the Match and Valid Bits */
> > +	adap_emac->MACADDRLO |= (1 << 19) | (1 << 20);
> > +#endif
> >
> >  	adap_emac->MACHASH1 = 0;
> >  	adap_emac->MACHASH2 = 0;
> > @@ -347,8 +408,15 @@ static int davinci_eth_open(struct eth_device *dev,
> bd_t *bis)
> >  	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
> >  	adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE |
> MDIO_CONTROL_FAULT);
> >
> > +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> > +	/* We need to wait for MDIO to start */
> > +	udelay(1000);
> > +#endif
> > +
> >  	if (!phy.get_link_speed(active_phy_addr))
> >  		return(0);
> > +	else
> > +		emac_gigabit_enable();
> >
> >  	/* Start receive process */
> >  	adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
> > @@ -411,7 +479,11 @@ static void davinci_eth_close(struct eth_device
> *dev)
> >
> >  	/* Reset EMAC module and disable interrupts in wrapper */
> >  	adap_emac->SOFTRESET = 1;
> > +#if defined(CONFIG_DAVINCI_EMAC_VERSION2)
> > +	adap_ewrap->SOFTRST = 1;
> > +#else
> >  	adap_ewrap->EWCTL = 0;
> > +#endif
> >
> >  	debug_emac("- emac_close\n");
> >  }
> > @@ -433,7 +505,8 @@ static int davinci_eth_send_packet (struct
> eth_device *dev,
> >  	if (!phy.get_link_speed (active_phy_addr)) {
> >  		printf ("WARN: emac_send_packet: No link\n");
> >  		return (ret_status);
> > -	}
> > +	} else
> > +		emac_gigabit_enable();
> 
> Here and below, is it a good idea to be enabling gigabit on each packet
> send?
> It seem like a lot of overhead.
I see the issue.

> 
> >
> >  	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up
> */
> >  	if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
> > @@ -456,7 +529,9 @@ static int davinci_eth_send_packet (struct
> eth_device *dev,
> >  		if (!phy.get_link_speed (active_phy_addr)) {
> >  			davinci_eth_ch_teardown (EMAC_CH_TX);
> >  			return (ret_status);
> > -		}
> > +		} else
> > +			emac_gigabit_enable();
> > +
> >  		if (adap_emac->TXINTSTATRAW & 0x01) {
> >  			ret_status = length;
> >  			break;

I am also open to collaborating with you on submitting just 1 patch with updates to this driver so that we start supporting DM365, DM6467 and DA8xx.

Let me know your thoughts.

Sandeep

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-11-16 17:39 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-13 20:42 [U-Boot] [PATCH] TI: DaVinci: Updating EMAC driver for DM365 and DM646x s-paulraj at ti.com
2009-11-16 16:46 ` Nick Thompson
2009-11-16 17:39   ` Paulraj, Sandeep
  -- strict thread matches above, loose matches on Subject: below --
2009-10-02  1:56 s-paulraj at ti.com
2009-10-02 12:48 ` Tom

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox