1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * National Semiconductor DP83848 PHY Driver for TI DaVinci 4 * (TMS320DM644x) based boards. 5 * 6 * Copyright (C) 2007 Sergey Kubushyn <ksi (at) koi8.net> 7 * 8 * -------------------------------------------------------- 9 */ 10 11 #include <common.h> 12 #include <net.h> 13 #include <dp83848.h> 14 #include <asm/arch/emac_defs.h> 15 #include "../../../drivers/net/davinci_emac.h" 16 17 #ifdef CONFIG_DRIVER_TI_EMAC 18 19 #ifdef CONFIG_CMD_NET 20 21 int dp83848_is_phy_connected(int phy_addr) 22 { 23 u_int16_t id1, id2; 24 25 if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1)) 26 return(0); 27 if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2)) 28 return(0); 29 30 if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI)) 31 return(1); 32 33 return(0); 34 } 35 36 int dp83848_get_link_speed(int phy_addr) 37 { 38 u_int16_t tmp; 39 volatile emac_regs* emac = (emac_regs *)EMAC_BASE_ADDR; 40 41 if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) 42 return(0); 43 44 if (!(tmp & DP83848_LINK_STATUS)) /* link up? */ 45 return(0); 46 47 if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp)) 48 return(0); 49 50 /* Speed doesn't matter, there is no setting for it in EMAC... */ 51 if (tmp & DP83848_DUPLEX) { 52 /* set DM644x EMAC for Full Duplex */ 53 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | 54 EMAC_MACCONTROL_FULLDUPLEX_ENABLE; 55 } else { 56 /*set DM644x EMAC for Half Duplex */ 57 emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; 58 } 59 60 return(1); 61 } 62 63 64 int dp83848_init_phy(int phy_addr) 65 { 66 int ret = 1; 67 68 if (!dp83848_get_link_speed(phy_addr)) { 69 /* Try another time */ 70 udelay(100000); 71 ret = dp83848_get_link_speed(phy_addr); 72 } 73 74 /* Disable PHY Interrupts */ 75 davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0); 76 77 return(ret); 78 } 79 80 81 int dp83848_auto_negotiate(int phy_addr) 82 { 83 u_int16_t tmp; 84 85 86 if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) 87 return(0); 88 89 /* Restart Auto_negotiation */ 90 tmp &= ~DP83848_AUTONEG; /* remove autonegotiation enable */ 91 tmp |= DP83848_ISOLATE; /* Electrically isolate PHY */ 92 davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); 93 94 /* Set the Auto_negotiation Advertisement Register 95 * MII advertising for Next page, 100BaseTxFD and HD, 96 * 10BaseTFD and HD, IEEE 802.3 97 */ 98 tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX | 99 DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3; 100 davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp); 101 102 103 /* Read Control Register */ 104 if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) 105 return(0); 106 107 tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE; 108 davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); 109 110 /* Restart Auto_negotiation */ 111 tmp |= DP83848_RESTART_AUTONEG; 112 davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); 113 114 /*check AutoNegotiate complete */ 115 udelay(10000); 116 if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) 117 return(0); 118 119 if (!(tmp & DP83848_AUTONEG_COMP)) 120 return(0); 121 122 return (dp83848_get_link_speed(phy_addr)); 123 } 124 125 #endif /* CONFIG_CMD_NET */ 126 127 #endif /* CONFIG_DRIVER_ETHER */ 128