]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/eth/arm/tx27karo/v1_0/include/devs_eth_arm_tx27.inl
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / devs / eth / arm / tx27karo / v1_0 / include / devs_eth_arm_tx27.inl
1 //==========================================================================
2 //
3 //      devs_eth_arm_tx27.inl
4 //
5 //      Board ethernet I/O definitions.
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
42 #include <cyg/hal/hal_intr.h>           // CYGNUM_HAL_INTERRUPT_ETHR
43 #include <cyg/hal/hal_if.h>
44
45 #ifdef CYGPKG_REDBOOT
46 #include <pkgconf/redboot.h>
47 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
48 #include <redboot.h>
49 #include <flash_config.h>
50 #endif
51 #endif
52
53
54 #ifdef __WANT_DEVS
55
56 #ifdef CYGPKG_DEVS_ETH_ARM_MXCBOARD_ETH0
57
58 #ifdef CYGPKG_DEVS_ETH_PHY
59
60 static char  mxc_fec_name[] = "mxc_fec";
61
62 #define OCR_SHIFT(bit)          (((bit) * 2) % 32)
63 #define OCR_MASK(bit)           (3 << (OCR_SHIFT(bit)))
64 #define OCR_VAL(bit,val)        (((val) << (OCR_SHIFT(bit))) & (OCR_MASK(bit)))
65 #define GPR_SHIFT(bit)          (bit)
66 #define GPR_MASK(bit)           (1 << (GPR_SHIFT(bit)))
67 #define GPR_VAL(bit,val)        (((val) << (GPR_SHIFT(bit))) & (GPR_MASK(bit)))
68
69 #ifdef CYGSEM_REDBOOT_PLF_ESA_VALIDATE
70 //
71 // Verify that the given ESA is valid for this platform
72 //
73 static char oui[3] = CYGDAT_DEVS_ETH_ARM_TX27KARO_OUI;
74
75 bool
76 cyg_plf_redboot_esa_validate(unsigned char *val)
77 {
78         return (val[0] == oui[0]) && (val[1] == oui[1]) && (val[2] == oui[2]);
79 }
80 #endif
81
82 extern int tx27_mac_addr_program(unsigned char mac_addr[ETHER_ADDR_LEN]);
83
84 static inline void tx27_set_reg(unsigned long addr, CYG_WORD32 set, CYG_WORD32 clr)
85 {
86         CYG_WORD32 val;
87         HAL_READ_UINT32(addr, val);
88         //diag_printf("Changing reg %08lx from %08x to %08x\n", addr, val, (val & ~clr) | set);
89         val = (val & ~clr) | set;
90         HAL_WRITE_UINT32(addr, val);
91 }
92
93 static inline void tx27_phy_power_off(void)
94 {
95         if (net_debug) diag_printf("Switching PHY POWER off\n");
96
97         // deassert PD0-15
98         tx27_set_reg(SOC_GPIOD_BASE + GPIO_OCR1, 0xffffffff, 0);
99         tx27_set_reg(SOC_GPIOD_BASE + GPIO_DR, 0, 0xffff);
100         tx27_set_reg(SOC_GPIOD_BASE + GPIO_DDIR, 0xffff, 0);
101         tx27_set_reg(SOC_GPIOD_BASE + GPIO_GIUS, 0xffff, 0);
102
103         // deassert PD16
104         tx27_set_reg(SOC_GPIOD_BASE + GPIO_OCR2, OCR_MASK(16), 0);
105         tx27_set_reg(SOC_GPIOD_BASE + GPIO_DR, 0, GPR_MASK(16));
106         tx27_set_reg(SOC_GPIOD_BASE + GPIO_DDIR, GPR_MASK(16), 0);
107         tx27_set_reg(SOC_GPIOD_BASE + GPIO_GIUS, GPR_MASK(16), 0);
108
109         // deassert PF23
110         tx27_set_reg(SOC_GPIOF_BASE + GPIO_OCR2, OCR_MASK(23), 0);
111         tx27_set_reg(SOC_GPIOF_BASE + GPIO_DR, 0, GPR_MASK(23));
112         tx27_set_reg(SOC_GPIOF_BASE + GPIO_DDIR, GPR_MASK(23), 0);
113         tx27_set_reg(SOC_GPIOF_BASE + GPIO_GIUS, GPR_MASK(23), 0);
114
115         tx27_set_reg(SOC_GPIOB_BASE + GPIO_DR, 0, GPR_MASK(27) | GPR_MASK(30));
116 }
117
118 static bool mxc_fec_init(struct cyg_netdevtab_entry *tab);
119 static bool tx27_fec_init(struct cyg_netdevtab_entry *tab)
120 {
121         cyg_bool esa_set;
122         int ok;
123
124         /* Check, whether MAC address is enabled */
125         ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
126                                          "fec_esa", &esa_set, CONFIG_BOOL);
127         if (!(ok && esa_set)) {
128                 diag_printf("FEC disabled; set fec_esa=true to enable networking\n");
129                 return false;
130         }
131         return mxc_fec_init(tab);
132 }
133
134 static void tx27_fec_phy_init(void)
135 {
136         int ok;
137         cyg_bool esa_set;
138         int phy_reset_delay = 100;
139
140         ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
141                                          "fec_esa", &esa_set, CONFIG_BOOL);
142         if (!(ok && esa_set)) {
143                 tx27_phy_power_off();
144                 return;
145         }
146
147         /*
148          * make sure the ETH PHY strap pins are pulled to the right voltage
149          * before deasserting the PHY reset GPIO
150          * REGOFF:   PD14
151          * RMII:     PD15
152          * nINTSEL:  PD7
153          * MODE0:    PD12
154          * MODE1:    PD5
155          * MODE2:    PD6
156          * PHYAD0:   -
157          * PHYAD1:   GND
158          * PHYAD2:   GND
159          * PHYAD3:   -
160          * PHYAD4:   PD10
161          */
162         // assert FEC PHY Reset (PB30) and switch PHY power on
163         /* PB22, PB27, PB30 => GPIO out */
164
165         if (!gpio_tst_bit(1, 27)) {
166                 if (net_debug) diag_printf("Switching PHY POWER on\n");
167                 tx27_set_reg(SOC_GPIOB_BASE + GPIO_DR, GPR_MASK(27), GPR_MASK(30));
168                 /* wait for 22ms for LAN8700 to power up */
169                 phy_reset_delay = 22000;
170         } else {
171                 if (net_debug) diag_printf("Asserting PHY RESET\n");
172                 tx27_set_reg(SOC_GPIOB_BASE + GPIO_DR, 0, GPR_MASK(30));
173         }
174
175         const unsigned int phy_mode_mask = 0x1060;
176         // deassert PD0-15 (except 5,6,12 => PHY MODE[0..2])
177         tx27_set_reg(SOC_GPIOD_BASE + GPIO_OCR1, 0xffffffff, 0);
178         tx27_set_reg(SOC_GPIOD_BASE + GPIO_DR, phy_mode_mask, ~phy_mode_mask);
179         tx27_set_reg(SOC_GPIOD_BASE + GPIO_DDIR, 0xffff, 0);
180         tx27_set_reg(SOC_GPIOD_BASE + GPIO_GIUS, 0xffff, 0);
181
182         // deassert PD16
183         tx27_set_reg(SOC_GPIOD_BASE + GPIO_OCR2, OCR_MASK(16), 0);
184         tx27_set_reg(SOC_GPIOD_BASE + GPIO_DR, 0, GPR_MASK(16));
185         tx27_set_reg(SOC_GPIOD_BASE + GPIO_DDIR, GPR_MASK(16), 0);
186         tx27_set_reg(SOC_GPIOD_BASE + GPIO_GIUS, GPR_MASK(16), 0);
187
188         // deassert PF23
189         tx27_set_reg(SOC_GPIOF_BASE + GPIO_OCR2, OCR_MASK(23), 0);
190         tx27_set_reg(SOC_GPIOF_BASE + GPIO_DR, 0, GPR_MASK(23));
191         tx27_set_reg(SOC_GPIOF_BASE + GPIO_DDIR, GPR_MASK(23), 0);
192         tx27_set_reg(SOC_GPIOF_BASE + GPIO_GIUS, GPR_MASK(23), 0);
193
194         /* wait for 100us according to LAN8700 spec. before ... */
195         HAL_DELAY_US(phy_reset_delay);
196
197         /* ... deasserting FEC PHY reset */
198         if (net_debug) diag_printf("Releasing PHY RESET\n");
199         tx27_set_reg(SOC_GPIOB_BASE + GPIO_DR, GPR_MASK(30), 0);
200
201         // program PF23 as FEC_TXEN
202         tx27_set_reg(SOC_GPIOF_BASE + GPIO_OCR2, 0, OCR_MASK(23));
203         tx27_set_reg(SOC_GPIOF_BASE + GPIO_DDIR, GPR_MASK(23), 0);
204         tx27_set_reg(SOC_GPIOF_BASE + GPIO_GIUS, GPR_MASK(23), 0);
205
206         tx27_set_reg(SOC_GPIOD_BASE + GPIO_OCR2, 0, OCR_MASK(16));
207         tx27_set_reg(SOC_GPIOD_BASE + GPIO_OCR1, 0, 0x000C00FF);
208         tx27_set_reg(SOC_GPIOD_BASE + GPIO_ICONFA1, 0, 0xFFF0FF00);
209         tx27_set_reg(SOC_GPIOD_BASE + GPIO_GPR, GPR_MASK(8), 0);
210         tx27_set_reg(SOC_GPIOD_BASE + GPIO_DDIR, 0x0001020F, 0x0001FFFF);
211         tx27_set_reg(SOC_GPIOD_BASE + GPIO_GIUS, 0x0001FEFF, 0x0001FFFF);
212 }
213
214 ETH_PHY_REG_LEVEL_ACCESS_FUNS(eth0_phy, 
215                               tx27_fec_phy_init,
216                               mxc_fec_phy_reset,
217                               mxc_fec_phy_write,
218                               mxc_fec_phy_read);
219
220 cyg_bool _tx27_provide_fec_esa(unsigned char *addr)
221 {
222         cyg_bool enabled;
223         int ok;
224
225         ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
226                                          "fec_esa", &enabled, CONFIG_BOOL);
227         if (ok && enabled) {
228 #ifdef CYGSEM_REDBOOT_PLF_ESA_VALIDATE
229                 cyg_uint8 addr2[ETHER_ADDR_LEN];
230
231                 addr[0] = readl(SOC_FEC_MAC_BASE2 + 0x0);
232                 addr[1] = readl(SOC_FEC_MAC_BASE2 + 0x4);
233                 addr[2] = readl(SOC_FEC_MAC_BASE2 + 0x8);
234                 addr[3] = readl(SOC_FEC_MAC_BASE2 + 0xC);
235                 addr[4] = readl(SOC_FEC_MAC_BASE2 + 0x10);
236                 addr[5] = readl(SOC_FEC_MAC_BASE2 + 0x14);
237
238                 if (cyg_plf_redboot_esa_validate(addr)) {
239                         diag_printf("Ethernet FEC MAC address from fuse bank: ");
240                         diag_printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
241                                     addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
242                         CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
243                                                                                 "fec_esa_data", addr2, CONFIG_ESA);
244                         if (memcmp(addr, addr2, sizeof(addr)) != 0) {
245                                 CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_SET,
246                                                                                         "fec_esa_data", addr, CONFIG_ESA);
247                         }
248 #ifdef SOC_MAC_ADDR_LOCK
249                         if ((readl(SOC_FEC_MAC_BASE2 - 0x14) & SOC_MAC_ADDR_LOCK) == 0) {
250                                 tx27_mac_addr_program(addr);
251                         }
252 #endif // SOC_MAC_ADDR_LOCK
253                         return true;
254                 }
255 #endif // CYGSEM_REDBOOT_PLF_ESA_VALIDATE
256
257                 CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
258                                                                         "fec_esa_data", addr, CONFIG_ESA);
259
260                 diag_printf("Ethernet FEC MAC address from fconfig: ");
261                 diag_printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
262                             addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
263
264 #ifdef CYGSEM_REDBOOT_PLF_ESA_VALIDATE
265                 if (cyg_plf_redboot_esa_validate(addr)) {
266                         tx27_mac_addr_program(addr);
267                         return true;
268                 }
269
270                 diag_printf("** Error: Invalid MAC address: ");
271                 diag_printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
272                             addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
273
274 #ifdef SOC_MAC_ADDR_LOCK
275                 if ((readl(SOC_FEC_MAC_BASE2 - 0x14) & SOC_MAC_ADDR_LOCK) == 0) {
276                         diag_printf("Use 'fconfig fec_esa_data' to set the MAC address\n");
277                         return false;
278                 } else {
279                         diag_printf("Using MAC address from fconfig\n");
280                 }
281 #else
282                 diag_printf("Using MAC address from fconfig\n");
283 #endif // SOC_MAC_ADDR_LOCK
284 #endif // CYGSEM_REDBOOT_PLF_ESA_VALIDATE
285                 return true;
286         }
287         return false;
288 }
289
290 static mxc_fec_priv_t mxc_fec_private = {
291         .phy = &eth0_phy,                             // PHY access routines
292         .provide_esa = _tx27_provide_fec_esa,
293 };
294
295 ETH_DRV_SC(mxc_fec_sc,
296                    &mxc_fec_private, // Driver specific data
297            mxc_fec_name,
298            mxc_fec_start,
299            mxc_fec_stop,
300            mxc_fec_control,
301            mxc_fec_can_send,
302            mxc_fec_send,
303            mxc_fec_recv,
304            mxc_fec_deliver,     // "pseudoDSR" called from fast net thread
305            mxc_fec_poll,        // poll function, encapsulates ISR and DSR
306            mxc_fec_int_vector);
307
308 NETDEVTAB_ENTRY(mxc_fec_netdev,
309                 mxc_fec_name,
310                 tx27_fec_init,
311                 &mxc_fec_sc);
312 #endif
313
314 #if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
315 RedBoot_config_option("Set FEC network hardware address [MAC]",
316                       fec_esa,
317                       ALWAYS_ENABLED, true,
318                       CONFIG_BOOL, false
319                      );
320 RedBoot_config_option("FEC network hardware address [MAC]",
321                       fec_esa_data,
322                       "fec_esa", true,
323                       CONFIG_ESA, 0
324                      );
325 #endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
326
327 #ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
328 // Note that this section *is* active in an application, outside RedBoot,
329 // where the above section is not included.
330
331 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
332 #endif // CYGPKG_DEVS_ETH_ARM_MXCBOARD_ETH0
333
334 #endif // __WANT_DEVS