uboot/arch/arm/mach-davinci/lxt972.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Intel LXT971/LXT972 PHY Driver for TI DaVinci
   4 * (TMS320DM644x) based boards.
   5 *
   6 * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
   7 *
   8 * --------------------------------------------------------
   9 */
  10
  11#include <common.h>
  12#include <net.h>
  13#include <miiphy.h>
  14#include <lxt971a.h>
  15#include <asm/arch/emac_defs.h>
  16#include "../../../drivers/net/ti/davinci_emac.h"
  17
  18#ifdef CONFIG_DRIVER_TI_EMAC
  19
  20#ifdef CONFIG_CMD_NET
  21
  22int lxt972_is_phy_connected(int phy_addr)
  23{
  24        u_int16_t id1, id2;
  25
  26        if (!davinci_eth_phy_read(phy_addr, MII_PHYSID1, &id1))
  27                return(0);
  28        if (!davinci_eth_phy_read(phy_addr, MII_PHYSID2, &id2))
  29                return(0);
  30
  31        if ((id1 == (0x0013)) && ((id2  & 0xfff0) == 0x78e0))
  32                return(1);
  33
  34        return(0);
  35}
  36
  37int lxt972_get_link_speed(int phy_addr)
  38{
  39        u_int16_t stat1, tmp;
  40        volatile emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR;
  41
  42        if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1))
  43                return(0);
  44
  45        if (!(stat1 & PHY_LXT971_STAT2_LINK))   /* link up? */
  46                return(0);
  47
  48        if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp))
  49                return(0);
  50
  51        tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE;
  52
  53        davinci_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp);
  54        /* Read back */
  55        if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp))
  56                return(0);
  57
  58        /* Speed doesn't matter, there is no setting for it in EMAC... */
  59        if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) {
  60                /* set DM644x EMAC for Full Duplex  */
  61                emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE |
  62                        EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
  63        } else {
  64                /*set DM644x EMAC for Half Duplex  */
  65                emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
  66        }
  67
  68        return(1);
  69}
  70
  71
  72int lxt972_init_phy(int phy_addr)
  73{
  74        int ret = 1;
  75
  76        if (!lxt972_get_link_speed(phy_addr)) {
  77                /* Try another time */
  78                ret = lxt972_get_link_speed(phy_addr);
  79        }
  80
  81        /* Disable PHY Interrupts */
  82        davinci_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0);
  83
  84        return(ret);
  85}
  86
  87
  88int lxt972_auto_negotiate(int phy_addr)
  89{
  90        u_int16_t tmp;
  91
  92        if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
  93                return(0);
  94
  95        /* Restart Auto_negotiation  */
  96        tmp |= BMCR_ANRESTART;
  97        davinci_eth_phy_write(phy_addr, MII_BMCR, tmp);
  98
  99        /*check AutoNegotiate complete */
 100        udelay (10000);
 101        if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
 102                return(0);
 103
 104        if (!(tmp & BMSR_ANEGCOMPLETE))
 105                return(0);
 106
 107        return (lxt972_get_link_speed(phy_addr));
 108}
 109
 110#endif  /* CONFIG_CMD_NET */
 111
 112#endif  /* CONFIG_DRIVER_ETHER */
 113