]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/eth/arm/ks32c5000/v2_0/src/lxt972.c
Initial revision
[karo-tx-redboot.git] / packages / devs / eth / arm / ks32c5000 / v2_0 / src / lxt972.c
1 //==========================================================================
2 //
3 //      lxt972.c
4 //
5 //      Driver for LXT972 PHY
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):    cgarry
44 // Contributors: Based on code from: gthomas, jskov
45 //               Grant Edwards <grante@visi.com>
46 // Date:         2002-10-18
47 // Purpose:      
48 // Description:  
49 //
50 //####DESCRIPTIONEND####
51 //
52 //========================================================================*/
53
54 #include <pkgconf/devs_eth_arm_ks32c5000.h>
55
56 #include "std.h"
57 #include "phy.h"
58
59 #define Bit(n) (1<<(n))
60
61 // address of the LX972 phy
62 #ifdef CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
63 #define LX972_ADDR  CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
64 #else
65 #define LX972_ADDR  0
66 #endif
67
68 // LX972 register offsets
69 #define LX972_CTRL_REG          0x00
70 #define LX972_STATUS1_REG       0x01
71 #define LX972_PHY_ID1_REG       0x02
72 #define LX972_PHY_ID2_REG       0x03
73 #define LX972_AN_ADVRT_REG      0x04
74 #define LX972_AN_LPAR_REG       0x05
75 #define LX972_AN_EXP_REG        0x06
76 #define LX972_AN_NEXTPAGE_REG   0x07
77 #define LX972_AN_LPAR_NP_REG    0x08
78 #define LX972_PORT_CONFIG_REG   0x10
79 #define LX972_STATUS2_REG       0x11
80 #define LX972_INT_ENAB_REG      0x12
81 #define LX972_INT_STAT_REG      0x13
82 #define LX972_LED_CONFIG_REG    0x14
83 #define LX972_DIG_CONFIG_REG    0x1A
84 #define LX972_TX_CTRL2_REG      0x1E
85
86 // LX972 Control register bit defines
87 #define LX972_CTRL_RESET        0x8000
88 #define LX972_CTRL_LOOPBACK     0x4000
89 #define LX972_CTRL_SPEED        0x2000  // 1=100Meg, 0=10Meg
90 #define LX972_CTRL_AN           0x1000  // 1=Enable auto negotiation, 0=disable it
91 #define LX972_CTRL_PWRDN        0x0800  // 1=Enable power down
92 #define LX972_CTRL_ISOLATE      0x0400  // 1=Isolate from MII
93 #define LX972_CTRL_RSTRT_AN     0x0200  // 1=Restart Auto Negotioation process
94 #define LX972_CTRL_FULL_DUP     0x0100  // 1=Enable full duplex mode, 0=half dup
95 #define LX972_CTRL_TST_COLL     0x0080  // 1=Enable collision test
96
97 // LX972 Interrupt enable register bit defines
98 #define LX972_INT_ENAB_ANMSK     Bit(7)
99 #define LX972_INT_ENAB_SPEEDMSK  Bit(6)
100 #define LX972_INT_ENAB_DUPLEXMSK Bit(5)
101 #define LX972_INT_ENAB_LINKMSK   Bit(4)
102 #define LX972_INT_ENAB_INTEN     Bit(1)
103 #define LX972_INT_ENAB_TINT      Bit(0)
104
105 // Map LED values from CDL file to reg defines
106 #define LINK_SPEED                                LX972_LED_CONFIG_SPEED_STATUS
107 #define TX_ACTIVITY                               LX972_LED_CONFIG_TX_STATUS
108 #define RX_ACTIVITY                               LX972_LED_CONFIG_RX_STATUS
109 #define COLLISION_STATUS                          LX972_LED_CONFIG_COLLISION_STATUS
110 #define DUPLEX_STATUS                             LX972_LED_CONFIG_DUPLEX_STATUS
111 #define LINK_ACTIVITY                             LX972_LED_CONFIG_RXTX_ACTIVITY
112 #define LINK_STATUS_RX_STATUS_COMBINED            LX972_LED_CONFIG_LINK_RX_COMB
113 #define LINK_STATUS_LINK_ACTIVITY_COMBINED        LX972_LED_CONFIG_LINK_ACT_COMB
114 #define DUPLEX_STATUS_COLLISION_STATUS_COMBINED   LX972_LED_CONFIG_DUPLEX_COLL_COMB
115 #define LINK_STATUS                               LX972_LED_CONFIG_LINK_STATUS
116 #define TEST_ON                                   LX972_LED_CONFIG_TEST_ON
117 #define TEST_OFF                                  LX972_LED_CONFIG_TEST_OFF
118 #define TEST_BLINK_FAST                           LX972_LED_CONFIG_BLINK_FAST
119 #define TEST_BLINK_SLOW                           LX972_LED_CONFIG_BLINK_SLOW
120
121 // LX972 LED Config register bit defines
122 #define LX972_LED_CONFIG_LED1SHIFT 12
123 #define LX972_LED_CONFIG_LED2SHIFT 8
124 #define LX972_LED_CONFIG_LED3SHIFT 4
125 #define LX972_LED_CONFIG_SPEED_STATUS     0x0
126 #define LX972_LED_CONFIG_TX_STATUS        0x1
127 #define LX972_LED_CONFIG_RX_STATUS        0x2
128 #define LX972_LED_CONFIG_COLLISION_STATUS 0x3
129 #define LX972_LED_CONFIG_LINK_STATUS      0x4
130 #define LX972_LED_CONFIG_DUPLEX_STATUS    0x5
131 #define LX972_LED_CONFIG_RXTX_ACTIVITY    0x7
132 #define LX972_LED_CONFIG_TEST_ON          0x8
133 #define LX972_LED_CONFIG_TEST_OFF         0x9
134 #define LX972_LED_CONFIG_BLINK_FAST       0xA
135 #define LX972_LED_CONFIG_BLINK_SLOW       0xB
136 #define LX972_LED_CONFIG_LINK_RX_COMB     0xC
137 #define LX972_LED_CONFIG_LINK_ACT_COMB    0xD
138 #define LX972_LED_CONFIG_DUPLEX_COLL_COMB 0xE
139 #define LX972_LED_CONFIG_STRETCH_100MS    0x8
140 #define LX972_LED_CONFIG_ENAB_LED_STRETCH Bit(1)
141
142 // LX972 Auto Negotiation Advertisement register bit defines
143 #define LX972_AN_ADVRT_NEXT_PAGE    Bit(15)
144 #define LX972_AN_ADVRT_PAUSE_ENA    Bit(10)
145 #define LX972_AN_ADVRT_100T4        Bit(9)
146 #define LX972_AN_ADVRT_100TX_FULL   Bit(8)
147 #define LX972_AN_ADVRT_100TX        Bit(7)
148 #define LX972_AN_ADVRT_10T_FULL     Bit(6)
149 #define LX972_AN_ADVRT_10T          Bit(5)
150 #define LX972_AN_ADVRT_SEL_802_3    Bit(0)
151
152 // LX972 Status register #2 bit defines
153 #define LX972_STATUS2_100M          Bit(14)
154 #define LX972_STATUS2_LINKUP        Bit(10)
155 #define LX972_STATUS2_FULLDUP       Bit(9)
156 #define LX972_STATUS2_ANEG_DONE     Bit(7)
157
158 // phy functions for Level1 PHY LXT972
159
160 void PhyReset(void)
161 {
162     unsigned CtrlRegData;
163     // First software reset the LX972
164     MiiStationWrite(LX972_CTRL_REG, LX972_ADDR, LX972_CTRL_RESET);
165     MiiStationWrite(LX972_CTRL_REG, LX972_ADDR, 0);
166
167     // Wait until the LX972 reset cycle has completed
168     // The Control register will read 0x7FFF until the reset cycle has completed
169     CtrlRegData = 0x7FFF;
170     while (CtrlRegData == 0x7FFF)
171     {
172         CtrlRegData = MiiStationRead(LX972_CTRL_REG, LX972_ADDR);
173     }
174
175     // Set up the LEDs' modes
176     MiiStationWrite(LX972_LED_CONFIG_REG, LX972_ADDR,
177                     (CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_LXT972_LED1 << LX972_LED_CONFIG_LED1SHIFT)
178                   | (CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_LXT972_LED2 << LX972_LED_CONFIG_LED2SHIFT)
179                   | (CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_LXT972_LED3 << LX972_LED_CONFIG_LED3SHIFT)
180                   | LX972_LED_CONFIG_STRETCH_100MS
181                   | LX972_LED_CONFIG_ENAB_LED_STRETCH);
182
183     // Set MII drive strength
184     MiiStationWrite(LX972_DIG_CONFIG_REG, LX972_ADDR, 0);
185
186     // Enable interrupts
187     MiiStationWrite(LX972_INT_ENAB_REG, LX972_ADDR,
188                     LX972_INT_ENAB_ANMSK
189                   | LX972_INT_ENAB_SPEEDMSK
190                   | LX972_INT_ENAB_DUPLEXMSK
191                   | LX972_INT_ENAB_LINKMSK
192                   | LX972_INT_ENAB_INTEN);
193
194     // Initialize auto-negotiation capabilities
195     // Next page not enabled
196     MiiStationWrite(LX972_AN_ADVRT_REG, LX972_ADDR,
197                     LX972_AN_ADVRT_PAUSE_ENA
198                   | LX972_AN_ADVRT_100T4
199                   | LX972_AN_ADVRT_100TX_FULL
200                   | LX972_AN_ADVRT_100TX
201                   | LX972_AN_ADVRT_10T_FULL
202                   | LX972_AN_ADVRT_10T
203                   | LX972_AN_ADVRT_SEL_802_3);
204 #if 1
205     // Now start an auto negotiation
206     MiiStationWrite(LX972_CTRL_REG, LX972_ADDR,
207                     LX972_CTRL_AN
208                   | LX972_CTRL_RSTRT_AN);
209 #else
210     // force to 10M full duplex
211     MiiStationWrite(LX972_CTRL_REG, LX972_ADDR,
212                     LX972_CTRL_FULL_DUP);
213 #endif
214 }
215
216 unsigned PhyStatus(void)
217 {
218   unsigned lxt972Status = MiiStationRead(LX972_STATUS2_REG,LX972_ADDR);
219   unsigned r = 0;
220   if (lxt972Status & LX972_STATUS2_LINKUP)
221     r |= PhyStatus_LinkUp;
222   if (lxt972Status & LX972_STATUS2_FULLDUP)
223     r |= PhyStatus_FullDuplex;
224   if (lxt972Status & LX972_STATUS2_100M)
225     r |=  PhyStatus_100Mb;
226   return r;
227 }
228
229 void PhyInterruptAck(void)
230 {
231   MiiStationRead(LX972_STATUS1_REG, LX972_ADDR);
232   MiiStationRead(LX972_INT_STAT_REG, LX972_ADDR);
233 }
234
235 // EOF lxt972.c