[U-Boot] [PATCH] TI: DaVinci: Updating EMAC driver for DM365 and DM646x
Paulraj, Sandeep
s-paulraj at ti.com
Mon Nov 16 18:39:00 CET 2009
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 at 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 at 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
More information about the U-Boot
mailing list