]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/eth/arm/tx37karo/v1_0/include/devs_eth_arm_tx37.inl
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / devs / eth / arm / tx37karo / v1_0 / include / devs_eth_arm_tx37.inl
1 //==========================================================================
2 //
3 //      devs_eth_arm_tx37.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 IOMUXC_CSPI1_MISO                               0x138
63 #define IOMUXC_AUD5_WB_FS                               0x130
64 #define IOMUXC_EIM_CS1                                  0x058
65 #define IOMUXC_EIM_BCLK                                 0x064
66 #define IOMUXC_UART1_RI                                 0x174
67 #define IOMUXC_CSPI1_SS1                                0x140
68 #define IOMUXC_CSPI2_MOSI                               0x148
69 #define IOMUXC_CSPI2_MISO                               0x14c
70 #define IOMUXC_CSPI1_MOSI                               0x134
71 #define IOMUXC_EIM_RW                                   0x068
72 #define IOMUXC_EIM_OE                                   0x050
73 #define IOMUXC_UART1_DCD                                0x178
74 #define IOMUXC_CSPI2_SS0                                0x150
75 #define IOMUXC_CSPI2_SS1                                0x154
76 #define IOMUXC_CSPI2_SCLK                               0x158
77 #define IOMUXC_EIM_CS0                                  0x054
78 #define IOMUXC_CSPI1_SS0                                0x13c
79 #define IOMUXC_CSPI1_SCLK                               0x144
80
81 #define IOMUXC_GPIO1_7                                  0x22c
82 #define IOMUXC_NANDF_CS1                                0x088
83
84 #define SW_PAD_CTL_CSPI1_MISO                   0x398
85 #define SW_PAD_CTL_AUD5_WB_FS                   0x390
86 #define SW_PAD_CTL_EIM_CS1                              0x2b8
87 #define SW_PAD_CTL_EIM_BCLK                             0x2c4
88 #define SW_PAD_CTL_UART1_RI                             0x3d4
89 #define SW_PAD_CTL_CSPI1_SS1                    0x3a0
90 #define SW_PAD_CTL_CSPI2_MOSI                   0x3a8
91 #define SW_PAD_CTL_CSPI2_MISO                   0x3ac
92 #define SW_PAD_CTL_CSPI1_MOSI                   0x394
93 #define SW_PAD_CTL_EIM_RW                               0x2c8
94 #define SW_PAD_CTL_EIM_OE                               0x2b0
95 #define SW_PAD_CTL_UART1_DCD                    0x3d8
96 #define SW_PAD_CTL_CSPI2_SS0                    0x3b0
97 #define SW_PAD_CTL_CSPI2_SS1                    0x3b4
98 #define SW_PAD_CTL_CSPI2_SCLK                   0x3b8
99 #define SW_PAD_CTL_EIM_CS0                              0x2b4
100 #define SW_PAD_CTL_CSPI1_SS0                    0x39c
101 #define SW_PAD_CTL_CSPI1_SCLK                   0x3a4
102
103 #define SW_PAD_CTL_GPIO1_7                              0x484
104 #define SW_PAD_CTL_NANDF_CS1                    0x2e8
105
106 #define SW_PAD_MUX_CSPI3_IPP_IND_MISO   0x518
107
108 #define MX37_GPIO_ADDR(bank)                    (GPIO1_BASE_ADDR + (((bank) - 1) << 14))
109
110 /*
111 TX37 -> TX27 GPIO cross reference
112                 TX27    Funktion    GPIO        Pad      IOMUXC SW_PAD  SW_PAD mode   strap
113                 GPIO    ALT     ALT                      OFFSET  CTRL    MUX          option
114 FEC_MDC         PD9     5       4   GPIO3_1  CSPI1_MISO  0x138   0x398
115 FEC_MDIO        PD8     5       4   GPIO2_23 AUD5_WB_FS  0x130   0x390  0x5a8   0
116 FEC_RX_CLK      PD14    2       1   GPIO2_1  EIM_CS1     0x058   0x2b8  0x5b0   0     REGOFF: 0
117 FEC_RX_DV       PD13    2       3   GPIO1_10 EIM_BCLK    0x064   0x2c4  0x5b4   0
118 FEC_RXD0        PD12    5       4   GPIO2_30 UART1_RI    0x174   0x3d4  0x5ac   1     MODE0:  1
119 FEC_RXD1        PD5     2       4   GPIO3_3  CSPI1_SS1   0x140   0x3a0                MODE1:  1
120 FEC_RXD2        PD6     2       4   GPIO3_5  CSPI2_MOSI  0x148   0x3a8                MODE2:  1
121 FEC_RXD3        PD7     2       4   GPIO3_6  CSPI2_MISO  0x14c   0x3ac                INTSEL: 0
122 FEC_RX_ER       PD4     5       4   GPIO3_0  CSPI1_MOSI  0x134   0x394  0x5b8   1
123 FEC_TX_CLK      PD11    2       3   GPIO1_9  EIM_RW      0x068   0x2c8  0x5bc   0
124 FEC_TX_EN       PF23    2       3   GPIO1_13 EIM_OE      0x050   0x2b0
125 FEC_TXD0        PD0     5       4   GPIO2_31 UART1_DCD   0x178   0x3d8
126 FEC_TXD1        PD1     2       4   GPIO3_7  CSPI2_SS0   0x150   0x3b0
127 FEC_TXD2        PD2     2       4   GPIO3_8  CSPI2_SS1   0x154   0x3b4 :( reference Manual says: 0xBASE_
128 FEC_TXD3        PD3     2       4   GPIO3_9  CSPI2_SCLK  0x158   0x3b8
129 FEC_COL         PD15    2       1   GPIO2_0  EIM_CS0     0x054   0x2b4  0x5a0   0     RMII:   0
130 FEC_CRS         PD10    5       4   GPIO3_2  CSPI1_SS0   0x13c   0x39c  0x5a4   1     PHYAD4: 0
131 FEC_TX_ER       PD16    5       4   GPIO3_4  CSPI1_SCLK  0x144   0x3a4
132
133 OSC26M_ENABLE   PB22                GPIO2 vom PMIC        ---     ---
134 FEC_RESET~      PB30        1       GPIO1_7  GPIO1_7     0x22c   0x484
135 FEC_ENABLE      PB27        4       GPIO2_9  NANDF_CS1   0x088   0x2e8
136 */
137
138 #ifdef CYGSEM_REDBOOT_PLF_ESA_VALIDATE
139 //
140 // Verify that the given ESA is valid for this platform
141 //
142 static char oui[3] = CYGDAT_DEVS_ETH_ARM_TX37KARO_OUI;
143
144 bool
145 cyg_plf_redboot_esa_validate(unsigned char *val)
146 {
147         return (val[0] == oui[0]) && (val[1] == oui[1]) && (val[2] == oui[2]);
148 }
149 #endif
150
151 #ifdef SOC_MAC_ADDR_BASE
152 extern int tx37_mac_addr_program(unsigned char mac_addr[ETHER_ADDR_LEN]);
153 #else
154 static inline int tx37_mac_addr_program(unsigned char mac_addr[ETHER_ADDR_LEN])
155 {
156         return 0;
157 }
158 #endif // SOC_MAC_ADDR_BASE
159
160 static inline void tx37_write_reg(CYG_ADDRWORD base_addr, CYG_WORD32 offset, CYG_WORD32 val)
161 {
162         if (net_debug) {
163                 diag_printf("Changing reg %08x from %08x to %08x\n",
164                                         base_addr + offset, readl(base_addr + offset), val);
165         }
166         HAL_WRITE_UINT32(base_addr + offset, val);
167 }
168
169 static inline CYG_WORD32 tx37_read_reg(CYG_ADDRWORD base_addr, CYG_WORD32 offset)
170 {
171         CYG_WORD32 val;
172         HAL_READ_UINT32(base_addr + offset, val);
173         if (net_debug) diag_printf("Read %08x from reg %08x\n", val, base_addr + offset);
174         return val;
175 }
176
177 static inline void tx37_set_reg(CYG_ADDRWORD base_addr, CYG_WORD32 offset,
178                                 CYG_WORD32 set_mask, CYG_WORD32 clr_mask)
179 {
180         CYG_WORD32 val;
181         HAL_READ_UINT32(base_addr + offset, val);
182         if (net_debug) diag_printf("Changing reg %08x from %08x to %08x\n", base_addr + offset, val,
183                                    (val & ~clr_mask) | set_mask);
184         val = (val & ~clr_mask) | set_mask;
185         HAL_WRITE_UINT32(base_addr + offset, val);
186 }
187
188 static struct tx37_gpio_setup {
189         cyg_uint16 iomux_addr;
190         cyg_uint8 on_func;
191         cyg_uint8 off_func;
192         cyg_uint8 grp;
193         cyg_uint8 shift;
194 } tx37_fec_gpio_data[] = {
195         /* iomux reg offset, func,      gpgrp */
196         /*                       gpiofn,  gpshift */
197         { IOMUXC_CSPI1_MISO, 0x15, 0x14,        3,      1, },
198         { IOMUXC_AUD5_WB_FS, 0x15, 0x14,        2, 23, },
199         { IOMUXC_EIM_CS1,        0x12, 0x11,    2,      1, },
200         { IOMUXC_EIM_BCLK,       0x12, 0x13,    1, 10, },
201         { IOMUXC_UART1_RI,       0x15, 0x14,    2, 30, },
202         { IOMUXC_CSPI1_SS1,      0x12, 0x14,    3,      3, },
203         { IOMUXC_CSPI2_MOSI, 0x12, 0x14,        3,      5, },
204         { IOMUXC_CSPI2_MISO, 0x12, 0x14,        3,      6, },
205         { IOMUXC_CSPI1_MOSI, 0x15, 0x14,        3,      0, },
206         { IOMUXC_EIM_RW,         0x12, 0x13,    1,      9, },
207         { IOMUXC_EIM_OE,         0x12, 0x13,    1, 13, },
208         { IOMUXC_UART1_DCD,      0x15, 0x14,    2, 31, },
209         { IOMUXC_CSPI2_SS0,      0x12, 0x14,    3,      7, },
210         { IOMUXC_CSPI2_SS1,      0x12, 0x14,    3,      8, },
211         { IOMUXC_CSPI2_SCLK, 0x12, 0x14,        3,      9, },
212         { IOMUXC_EIM_CS0,        0x12, 0x11,    2,      0, },
213         { IOMUXC_CSPI1_SS0,      0x15, 0x14,    3,      2, },
214         { IOMUXC_CSPI1_SCLK, 0x15, 0x14,        3,      4, },
215         { IOMUXC_GPIO1_7,    0x11, 0x11,        1,      7, },
216         { IOMUXC_NANDF_CS1,  0x14, 0x14,        2,      9, },
217 };
218
219 static struct tx37_gpio_setup tx37_fec_strap_pins[] = {
220         { IOMUXC_NANDF_CS1,  0x14, 0x14,        2,      9, },
221         { IOMUXC_UART1_RI,       0x15, 0x14,    2, 30, },
222         { IOMUXC_CSPI1_SS1,      0x12, 0x14,    3,      3, },
223         { IOMUXC_CSPI2_MOSI, 0x12, 0x14,        3,      5, },
224 };
225
226 static struct tx37_gpio_setup tx37_fec_mux_table[] = {
227         { 0x5a0,                0, },   /* FEC_COL via EIM_CS0 */
228         { 0x5a4,                1, },   /* FEC_CRS via CSPI1_SS0 */
229         { 0x5a8,                0, },   /* FEC_MDIO via AUD5_WB_FS */
230         { 0x5ac,                1, },   /* FEC_RXD0 via UART1_RI */
231         { 0x5b0,                0, },   /* FEC_RX_CLK via EIM_CS1 */
232         { 0x5b4,                0, },   /* FEC_RX_DV via EIM_BCLK */
233         { 0x5b8,                1, },   /* FEC_RX_ER via CSPI1_MOSI */
234         { 0x5bc,                0, },   /* FEC_TX_CLK via EIM_RW */
235 };
236
237 static inline void tx37_phy_power_off(void)
238 {
239         int i;
240
241         if (net_debug) diag_printf("Switching PHY POWER off\n");
242
243 #if 1
244         for (i = 0; i < NUM_ELEMS(tx37_fec_gpio_data); i++) {
245                 struct tx37_gpio_setup *gs = &tx37_fec_gpio_data[i];
246
247                 if (net_debug) diag_printf("%s: GPIO%d_%d[%d] is %d\n", __FUNCTION__,
248                                                                    gs->grp, gs->shift, i,
249                                                                    gpio_tst_bit(gs->grp, gs->shift));
250         }
251 #endif
252         /* deassert all pins attached to the PHY */
253         for (i = 0; i < NUM_ELEMS(tx37_fec_gpio_data); i++) {
254                 struct tx37_gpio_setup *gs = &tx37_fec_gpio_data[i];
255
256                 tx37_set_reg(MX37_GPIO_ADDR(gs->grp),
257                                          GPIO_DR, 0, 1 << gs->shift);
258                 tx37_set_reg(MX37_GPIO_ADDR(gs->grp),
259                                          GPIO_GDIR, 1 << gs->shift, 0);
260                 tx37_write_reg(IOMUXC_BASE_ADDR, gs->iomux_addr,
261                                            gs->off_func);
262         }
263         /* setup pin mux */
264         for (i = 0; i < NUM_ELEMS(tx37_fec_mux_table); i++) {
265                 struct tx37_gpio_setup *gs = &tx37_fec_mux_table[i];
266
267                 tx37_write_reg(IOMUXC_BASE_ADDR, gs->iomux_addr, gs->on_func);
268         }
269 #ifdef DEBUG
270         for (i = 0; i < NUM_ELEMS(tx37_fec_gpio_data); i++) {
271                 struct tx37_gpio_setup *gs = &tx37_fec_gpio_data[i];
272
273                 if (gpio_tst_bit(gs->grp, gs->shift)) {
274                         if (net_debug) diag_printf("%s: GPIO%d_%d[%d] is not low\n", __FUNCTION__,
275                                                                            gs->grp, gs->shift, i);
276                 }
277         }
278 #endif
279         if (net_debug) diag_printf("PHY POWER off done\n");
280 }
281
282 static bool mxc_fec_init(struct cyg_netdevtab_entry *tab);
283 static bool tx37_fec_init(struct cyg_netdevtab_entry *tab)
284 {
285         cyg_bool esa_set;
286         int ok;
287
288         /* Check, whether MAC address is enabled */
289         ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
290                                          "fec_esa", &esa_set, CONFIG_BOOL);
291         if (!(ok && esa_set)) {
292                 diag_printf("FEC disabled; set fec_esa=true to enable networking\n");
293                 return false;
294         }
295         return mxc_fec_init(tab);
296 }
297
298 static void tx37_fec_phy_init(void)
299 {
300         int i;
301         int phy_reset_delay = 100;
302
303         /*
304          * make sure the ETH PHY strap pins are pulled to the right voltage
305          * before deasserting the PHY reset GPIO
306          * REGOFF:   PD14
307          * RMII:     PD15
308          * nINTSEL:  PD7
309          * MODE0:    PD12
310          * MODE1:    PD5
311          * MODE2:    PD6
312          * PHYAD0:   -
313          * PHYAD1:   GND
314          * PHYAD2:   GND
315          * PHYAD3:   -
316          * PHYAD4:   PD10
317          */
318         // assert FEC PHY Reset (PB30) and switch PHY power on
319         /* PB22, PB27, PB30 => GPIO out */
320 #if 0
321         tx37_phy_power_off();
322 #endif
323         if (!gpio_tst_bit(2, 9)) {
324                 if (net_debug) diag_printf("Switching PHY POWER on\n");
325                 /* switch FEC power off and assert FEC_RESET~ (low) */
326                 tx37_read_reg(MX37_GPIO_ADDR(1), GPIO_PSR);
327                 gpio_clr_bit(1, 7);
328                 gpio_set_bit(2, 9);
329                 tx37_read_reg(MX37_GPIO_ADDR(1), GPIO_PSR);
330
331                 /* wait for 22ms for LAN8700 to power up */
332                 phy_reset_delay = 22000 * 5;
333 #if 1
334                 if (!gpio_tst_bit(2, 9)) {
335                         diag_printf("**Failed to switch PHY power on: GPIO2_PSR[%08lx]=%08x\n",
336                                     MX37_GPIO_ADDR(2) + GPIO_PSR,
337                                     tx37_read_reg(MX37_GPIO_ADDR(2), GPIO_PSR));
338                 }
339 #endif
340 #if 1
341                 if (gpio_tst_bit(1, 7)) {
342                         diag_printf("**Failed to assert PHY reset: GPIO1_PSR[%08lx]=%08x\n",
343                                     MX37_GPIO_ADDR(1) + GPIO_PSR,
344                                     tx37_read_reg(MX37_GPIO_ADDR(1), GPIO_PSR));
345                 }
346 #endif
347         } else {
348                 if (net_debug) diag_printf("Asserting PHY RESET\n");
349                 tx37_read_reg(MX37_GPIO_ADDR(1), GPIO_PSR);
350                 gpio_clr_bit(1, 7);
351                 if (gpio_tst_bit(1, 7)) {
352                         diag_printf("**Failed to assert PHY reset: GPIO1_PSR[%08lx]=%08x\n",
353                                     MX37_GPIO_ADDR(1) + GPIO_PSR,
354                                     tx37_read_reg(MX37_GPIO_ADDR(1), GPIO_PSR));
355                 }
356                 tx37_read_reg(MX37_GPIO_ADDR(1), GPIO_PSR);
357         }
358
359         /* configure FEC strap pins to their required values */
360         for (i = 0; i < NUM_ELEMS(tx37_fec_strap_pins); i++) {
361                 struct tx37_gpio_setup *gs = &tx37_fec_strap_pins[i];
362
363                 if (net_debug) diag_printf("Asserting GPIO%d_%d\n", gs->grp,
364                                                                    gs->shift);
365                 tx37_set_reg(MX37_GPIO_ADDR(gs->grp),
366                                          GPIO_GDIR, 1 << gs->shift, 0);
367                 tx37_set_reg(MX37_GPIO_ADDR(gs->grp),
368                                          GPIO_DR, 1 << gs->shift, 0);
369                 tx37_write_reg(IOMUXC_BASE_ADDR, gs->iomux_addr,
370                                            gs->off_func);
371                 gpio_set_bit(gs->grp, gs->shift);
372                 if (!gpio_tst_bit(gs->grp, gs->shift)) {
373                         diag_printf("**Failed to assert GPIO%d_%d: GPIO%d_PSR[%08lx]=%08x\n",
374                                                 gs->grp, gs->shift, gs->grp,
375                                                 MX37_GPIO_ADDR(gs->grp) + GPIO_PSR,
376                                                 tx37_read_reg(MX37_GPIO_ADDR(gs->grp), GPIO_PSR));
377                 }
378         }
379         for (i = 0; i < NUM_ELEMS(tx37_fec_gpio_data); i++) {
380                 struct tx37_gpio_setup *gs = &tx37_fec_gpio_data[i];
381                 int j;
382                 int strap = 0;
383
384                 for (j = 0; j < NUM_ELEMS(tx37_fec_strap_pins); j++) {
385                         struct tx37_gpio_setup *sp = &tx37_fec_strap_pins[j];
386
387                         if (gs->grp == sp->grp && gs->shift == sp->shift) {
388                                 strap = 1;
389                                 break;
390                         }
391                 }
392                 if (strap) {
393                         if (!gpio_tst_bit(gs->grp, gs->shift)) {
394                                 if (net_debug) diag_printf("GPIO%d_%d[%d] is low instead of high\n",
395                                                                                    gs->grp, gs->shift, i);
396                         }
397                 } else {
398                         if (gpio_tst_bit(gs->grp, gs->shift)) {
399                                 if (net_debug) diag_printf("GPIO%d_%d[%d] is high instead of low\n",
400                                                                                    gs->grp, gs->shift, i);
401                         }
402                 }
403         }
404         /* wait for 100us according to LAN8700 spec. before ... */
405         HAL_DELAY_US(phy_reset_delay);
406
407         /* ... deasserting FEC PHY reset */
408         if (net_debug) diag_printf("Releasing PHY RESET\n");
409         gpio_set_bit(1, 7);
410         if (!gpio_tst_bit(1, 7)) {
411                 diag_printf("**Failed to release PHY reset\n");
412         }
413
414         /* configure all FEC pins to their required functions */
415         for (i = 0; i < NUM_ELEMS(tx37_fec_gpio_data); i++) {
416                 struct tx37_gpio_setup *gs = &tx37_fec_gpio_data[i];
417
418                 tx37_write_reg(IOMUXC_BASE_ADDR, gs->iomux_addr,
419                                            gs->on_func);
420         }
421 }
422
423 ETH_PHY_REG_LEVEL_ACCESS_FUNS(eth0_phy,
424                               tx37_fec_phy_init,
425                               mxc_fec_phy_reset,
426                               mxc_fec_phy_write,
427                               mxc_fec_phy_read);
428
429 cyg_bool _tx37_provide_fec_esa(unsigned char *addr)
430 {
431         cyg_bool enabled;
432         int ok;
433
434 #if 0
435         addr[0] = 0x00;
436         addr[1] = 0x0c;
437         addr[2] = 0xc6;
438         addr[3] = 0x76;
439         addr[4] = 0x6e;
440         addr[5] = 0x02;
441         return true;
442 #endif
443
444         ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
445                                          "fec_esa", &enabled, CONFIG_BOOL);
446         if (ok && enabled) {
447 #ifdef CYGSEM_REDBOOT_PLF_ESA_VALIDATE
448 #ifdef SOC_MAC_ADDR_BASE
449                 cyg_uint8 addr2[ETHER_ADDR_LEN];
450
451                 addr[0] = readl(SOC_FEC_MAC_BASE2 + 0x0);
452                 addr[1] = readl(SOC_FEC_MAC_BASE2 + 0x4);
453                 addr[2] = readl(SOC_FEC_MAC_BASE2 + 0x8);
454                 addr[3] = readl(SOC_FEC_MAC_BASE2 + 0xC);
455                 addr[4] = readl(SOC_FEC_MAC_BASE2 + 0x10);
456                 addr[5] = readl(SOC_FEC_MAC_BASE2 + 0x14);
457
458                 if (cyg_plf_redboot_esa_validate(addr)) {
459                         diag_printf("Ethernet FEC MAC address from fuse bank: ");
460                         diag_printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
461                                     addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
462                         CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
463                                                                                 "fec_esa_data", addr2, CONFIG_ESA);
464                         if (memcmp(addr, addr2, sizeof(addr)) != 0) {
465                                 CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_SET,
466                                                                                         "fec_esa_data", addr, CONFIG_ESA);
467                         }
468 #ifdef SOC_MAC_ADDR_LOCK
469                         if ((readl(SOC_FEC_MAC_BASE2 - 0x14) & SOC_MAC_ADDR_LOCK) == 0) {
470                                 tx37_mac_addr_program(addr);
471                         }
472 #endif // SOC_MAC_ADDR_LOCK
473                         return true;
474                 }
475 #endif // SOC_MAC_ADDR_BASE
476 #endif // CYGSEM_REDBOOT_PLF_ESA_VALIDATE
477
478                 CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
479                                                                         "fec_esa_data", addr, CONFIG_ESA);
480 #ifdef SOC_MAC_ADDR_BASE
481                 writel(addr[0], SOC_FEC_MAC_BASE2 + 0x0);
482                 writel(addr[1], SOC_FEC_MAC_BASE2 + 0x4);
483                 writel(addr[2], SOC_FEC_MAC_BASE2 + 0x8);
484                 writel(addr[3], SOC_FEC_MAC_BASE2 + 0xC);
485                 writel(addr[4], SOC_FEC_MAC_BASE2 + 0x10);
486                 writel(addr[5], SOC_FEC_MAC_BASE2 + 0x14);
487 #endif // SOC_MAC_ADDR_BASE
488
489                 diag_printf("Ethernet FEC MAC address from fconfig: ");
490                 diag_printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
491                             addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
492
493 #ifdef CYGSEM_REDBOOT_PLF_ESA_VALIDATE
494                 if (cyg_plf_redboot_esa_validate(addr)) {
495                         tx37_mac_addr_program(addr);
496                         return true;
497                 }
498                 diag_printf("** Error: Invalid MAC address: ");
499                 diag_printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
500                             addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
501
502 #ifdef SOC_MAC_ADDR_LOCK
503                 if ((readl(SOC_FEC_MAC_BASE2 - 0x14) & SOC_MAC_ADDR_LOCK) == 0) {
504                         diag_printf("Use 'fconfig fec_esa_data' to set the MAC address\n");
505                         return false;
506                 } else {
507                         diag_printf("Using MAC address from fconfig\n");
508                 }
509 #else
510                 diag_printf("Using MAC address from fconfig\n");
511 #endif // SOC_MAC_ADDR_LOCK
512 #endif // CYGSEM_REDBOOT_PLF_ESA_VALIDATE
513                 return true;
514         }
515         return false;
516 }
517
518 static mxc_fec_priv_t mxc_fec_private = {
519         .phy = &eth0_phy,                             // PHY access routines
520         .provide_esa = _tx37_provide_fec_esa,
521 };
522
523 ETH_DRV_SC(mxc_fec_sc,
524                    &mxc_fec_private, // Driver specific data
525            mxc_fec_name,
526            mxc_fec_start,
527            mxc_fec_stop,
528            mxc_fec_control,
529            mxc_fec_can_send,
530            mxc_fec_send,
531            mxc_fec_recv,
532            mxc_fec_deliver,     // "pseudoDSR" called from fast net thread
533            mxc_fec_poll,        // poll function, encapsulates ISR and DSR
534            mxc_fec_int_vector);
535
536 NETDEVTAB_ENTRY(mxc_fec_netdev,
537                 mxc_fec_name,
538                 tx37_fec_init,
539                 &mxc_fec_sc);
540 #endif
541
542 #if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
543 RedBoot_config_option("Set FEC network hardware address [MAC]",
544                       fec_esa,
545                       ALWAYS_ENABLED, true,
546                       CONFIG_BOOL, false
547                      );
548 RedBoot_config_option("FEC network hardware address [MAC]",
549                       fec_esa_data,
550                       "fec_esa", true,
551                       CONFIG_ESA, 0
552                      );
553 #endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
554
555 #ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
556 // Note that this section *is* active in an application, outside RedBoot,
557 // where the above section is not included.
558
559 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
560 #endif // CYGPKG_DEVS_ETH_ARM_MXCBOARD_ETH0
561
562 #endif // __WANT_DEVS