uboot/arch/arm/cpu/arm926ejs/davinci/dp83848.c
<<
>>
Prefs
   1/*
   2 * National Semiconductor DP83848 PHY Driver for TI DaVinci
   3 * (TMS320DM644x) based boards.
   4 *
   5 * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
   6 *
   7 * --------------------------------------------------------
   8 *
   9 * See file CREDITS for list of people who contributed to this
  10 * project.
  11 *
  12 * This program is free software; you can redistribute it and/or
  13 * modify it under the terms of the GNU General Public License as
  14 * published by the Free Software Foundation; either version 2 of
  15 * the License, or (at your option) any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; if not, write to the Free Software
  24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25 * MA 02111-1307 USA
  26 */
  27
  28#include <common.h>
  29#include <net.h>
  30#include <dp83848.h>
  31#include <asm/arch/emac_defs.h>
  32#include "../../../../../drivers/net/davinci_emac.h"
  33
  34#ifdef CONFIG_DRIVER_TI_EMAC
  35
  36#ifdef CONFIG_CMD_NET
  37
  38int dp83848_is_phy_connected(int phy_addr)
  39{
  40        u_int16_t       id1, id2;
  41
  42        if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1))
  43                return(0);
  44        if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2))
  45                return(0);
  46
  47        if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI))
  48                return(1);
  49
  50        return(0);
  51}
  52
  53int dp83848_get_link_speed(int phy_addr)
  54{
  55        u_int16_t               tmp;
  56        volatile emac_regs*     emac = (emac_regs *)EMAC_BASE_ADDR;
  57
  58        if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
  59                return(0);
  60
  61        if (!(tmp & DP83848_LINK_STATUS))       /* link up? */
  62                return(0);
  63
  64        if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp))
  65                return(0);
  66
  67        /* Speed doesn't matter, there is no setting for it in EMAC... */
  68        if (tmp & DP83848_DUPLEX) {
  69                /* set DM644x EMAC for Full Duplex  */
  70                emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE |
  71                        EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
  72        } else {
  73                /*set DM644x EMAC for Half Duplex  */
  74                emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
  75        }
  76
  77        return(1);
  78}
  79
  80
  81int dp83848_init_phy(int phy_addr)
  82{
  83        int     ret = 1;
  84
  85        if (!dp83848_get_link_speed(phy_addr)) {
  86                /* Try another time */
  87                udelay(100000);
  88                ret = dp83848_get_link_speed(phy_addr);
  89        }
  90
  91        /* Disable PHY Interrupts */
  92        davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0);
  93
  94        return(ret);
  95}
  96
  97
  98int dp83848_auto_negotiate(int phy_addr)
  99{
 100        u_int16_t       tmp;
 101
 102
 103        if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
 104                return(0);
 105
 106        /* Restart Auto_negotiation  */
 107        tmp &= ~DP83848_AUTONEG;        /* remove autonegotiation enable */
 108        tmp |= DP83848_ISOLATE;         /* Electrically isolate PHY */
 109        davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
 110
 111        /* Set the Auto_negotiation Advertisement Register
 112         * MII advertising for Next page, 100BaseTxFD and HD,
 113         * 10BaseTFD and HD, IEEE 802.3
 114         */
 115        tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX |
 116                DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3;
 117        davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp);
 118
 119
 120        /* Read Control Register */
 121        if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp))
 122                return(0);
 123
 124        tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE;
 125        davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
 126
 127        /* Restart Auto_negotiation  */
 128        tmp |= DP83848_RESTART_AUTONEG;
 129        davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp);
 130
 131        /*check AutoNegotiate complete */
 132        udelay(10000);
 133        if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp))
 134                return(0);
 135
 136        if (!(tmp & DP83848_AUTONEG_COMP))
 137                return(0);
 138
 139        return (dp83848_get_link_speed(phy_addr));
 140}
 141
 142#endif  /* CONFIG_CMD_NET */
 143
 144#endif  /* CONFIG_DRIVER_ETHER */
 145